Skip to content

Commit 2194bca

Browse files
authored
[libc++] Granularize range_format and format_kind declarations (llvm#148876)
While working on llvm#105430 I ran into an issue implementing [[optional.syn]](https://eel.is/c++draft/optional.syn) because of a circular include that looked like the following: `optional -> __format/range_default_formatter.h -> __format/range_formatter.h -> __format/format_context.h -> optional`. Only `format_kind` and `range_format` are needed, and so they looked like candidates to be put into an internal header.
1 parent 1653a09 commit 2194bca

File tree

4 files changed

+74
-41
lines changed

4 files changed

+74
-41
lines changed

libcxx/include/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,7 @@ set(files
403403
__format/indic_conjunct_break_table.h
404404
__format/parser_std_format_spec.h
405405
__format/range_default_formatter.h
406+
__format/range_format.h
406407
__format/range_formatter.h
407408
__format/unicode.h
408409
__format/width_estimation_table.h

libcxx/include/__format/range_default_formatter.h

Lines changed: 1 addition & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,10 @@
1616

1717
#include <__algorithm/ranges_copy.h>
1818
#include <__chrono/statically_widen.h>
19-
#include <__concepts/same_as.h>
2019
#include <__config>
2120
#include <__format/concepts.h>
2221
#include <__format/formatter.h>
22+
#include <__format/range_format.h>
2323
#include <__format/range_formatter.h>
2424
#include <__iterator/back_insert_iterator.h>
2525
#include <__ranges/concepts.h>
@@ -42,51 +42,11 @@ concept __const_formattable_range =
4242
template <class _Rp, class _CharT>
4343
using __fmt_maybe_const _LIBCPP_NODEBUG = conditional_t<__const_formattable_range<_Rp, _CharT>, const _Rp, _Rp>;
4444

45-
_LIBCPP_DIAGNOSTIC_PUSH
46-
_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wshadow")
47-
_LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wshadow")
48-
// This shadows map, set, and string.
49-
enum class range_format { disabled, map, set, sequence, string, debug_string };
50-
_LIBCPP_DIAGNOSTIC_POP
51-
5245
// There is no definition of this struct, it's purely intended to be used to
5346
// generate diagnostics.
5447
template <class _Rp>
5548
struct __instantiated_the_primary_template_of_format_kind;
5649

57-
template <class _Rp>
58-
constexpr range_format format_kind = [] {
59-
// [format.range.fmtkind]/1
60-
// A program that instantiates the primary template of format_kind is ill-formed.
61-
static_assert(sizeof(_Rp) != sizeof(_Rp), "create a template specialization of format_kind for your type");
62-
return range_format::disabled;
63-
}();
64-
65-
template <ranges::input_range _Rp>
66-
requires same_as<_Rp, remove_cvref_t<_Rp>>
67-
inline constexpr range_format format_kind<_Rp> = [] {
68-
// [format.range.fmtkind]/2
69-
70-
// 2.1 If same_as<remove_cvref_t<ranges::range_reference_t<R>>, R> is true,
71-
// Otherwise format_kind<R> is range_format::disabled.
72-
if constexpr (same_as<remove_cvref_t<ranges::range_reference_t<_Rp>>, _Rp>)
73-
return range_format::disabled;
74-
// 2.2 Otherwise, if the qualified-id R::key_type is valid and denotes a type:
75-
else if constexpr (requires { typename _Rp::key_type; }) {
76-
// 2.2.1 If the qualified-id R::mapped_type is valid and denotes a type ...
77-
if constexpr (requires { typename _Rp::mapped_type; } &&
78-
// 2.2.1 ... If either U is a specialization of pair or U is a specialization
79-
// of tuple and tuple_size_v<U> == 2
80-
__fmt_pair_like<remove_cvref_t<ranges::range_reference_t<_Rp>>>)
81-
return range_format::map;
82-
else
83-
// 2.2.2 Otherwise format_kind<R> is range_format::set.
84-
return range_format::set;
85-
} else
86-
// 2.3 Otherwise, format_kind<R> is range_format::sequence.
87-
return range_format::sequence;
88-
}();
89-
9050
template <range_format _Kp, ranges::input_range _Rp, class _CharT>
9151
struct __range_default_formatter;
9252

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
// -*- C++ -*-
2+
//===----------------------------------------------------------------------===//
3+
//
4+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5+
// See https://llvm.org/LICENSE.txt for license information.
6+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7+
//
8+
//===----------------------------------------------------------------------===//
9+
10+
#ifndef _LIBCPP___FORMAT_RANGE_FORMAT_H
11+
#define _LIBCPP___FORMAT_RANGE_FORMAT_H
12+
13+
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
14+
# pragma GCC system_header
15+
#endif
16+
17+
#include <__concepts/same_as.h>
18+
#include <__config>
19+
#include <__format/concepts.h>
20+
#include <__ranges/concepts.h>
21+
#include <__type_traits/remove_cvref.h>
22+
23+
_LIBCPP_BEGIN_NAMESPACE_STD
24+
25+
#if _LIBCPP_STD_VER >= 23
26+
27+
_LIBCPP_DIAGNOSTIC_PUSH
28+
_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wshadow")
29+
_LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wshadow")
30+
// This shadows map, set, and string.
31+
enum class range_format { disabled, map, set, sequence, string, debug_string };
32+
_LIBCPP_DIAGNOSTIC_POP
33+
34+
template <class _Rp>
35+
constexpr range_format format_kind = [] {
36+
// [format.range.fmtkind]/1
37+
// A program that instantiates the primary template of format_kind is ill-formed.
38+
static_assert(sizeof(_Rp) != sizeof(_Rp), "create a template specialization of format_kind for your type");
39+
return range_format::disabled;
40+
}();
41+
42+
template <ranges::input_range _Rp>
43+
requires same_as<_Rp, remove_cvref_t<_Rp>>
44+
inline constexpr range_format format_kind<_Rp> = [] {
45+
// [format.range.fmtkind]/2
46+
47+
// 2.1 If same_as<remove_cvref_t<ranges::range_reference_t<R>>, R> is true,
48+
// Otherwise format_kind<R> is range_format::disabled.
49+
if constexpr (same_as<remove_cvref_t<ranges::range_reference_t<_Rp>>, _Rp>)
50+
return range_format::disabled;
51+
// 2.2 Otherwise, if the qualified-id R::key_type is valid and denotes a type:
52+
else if constexpr (requires { typename _Rp::key_type; }) {
53+
// 2.2.1 If the qualified-id R::mapped_type is valid and denotes a type ...
54+
if constexpr (requires { typename _Rp::mapped_type; } &&
55+
// 2.2.1 ... If either U is a specialization of pair or U is a specialization
56+
// of tuple and tuple_size_v<U> == 2
57+
__fmt_pair_like<remove_cvref_t<ranges::range_reference_t<_Rp>>>)
58+
return range_format::map;
59+
else
60+
// 2.2.2 Otherwise format_kind<R> is range_format::set.
61+
return range_format::set;
62+
} else
63+
// 2.3 Otherwise, format_kind<R> is range_format::sequence.
64+
return range_format::sequence;
65+
}();
66+
67+
#endif // _LIBCPP_STD_VER >= 23
68+
69+
_LIBCPP_END_NAMESPACE_STD
70+
71+
#endif

libcxx/include/module.modulemap.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1369,6 +1369,7 @@ module std [system] {
13691369
module indic_conjunct_break_table { header "__format/indic_conjunct_break_table.h" }
13701370
module parser_std_format_spec { header "__format/parser_std_format_spec.h" }
13711371
module range_default_formatter { header "__format/range_default_formatter.h" }
1372+
module range_format { header "__format/range_format.h" }
13721373
module range_formatter { header "__format/range_formatter.h" }
13731374
module unicode { header "__format/unicode.h" }
13741375
module width_estimation_table { header "__format/width_estimation_table.h" }

0 commit comments

Comments
 (0)