[libcxx-commits] [libcxx] 2194bca - [libc++] Granularize `range_format` and `format_kind` declarations (#148876)
via libcxx-commits
libcxx-commits at lists.llvm.org
Thu Jul 17 00:43:16 PDT 2025
Author: William Tran-Viet
Date: 2025-07-17T09:43:12+02:00
New Revision: 2194bca2b78cf1ada2aa539e2a3ad8128a80f63a
URL: https://github.com/llvm/llvm-project/commit/2194bca2b78cf1ada2aa539e2a3ad8128a80f63a
DIFF: https://github.com/llvm/llvm-project/commit/2194bca2b78cf1ada2aa539e2a3ad8128a80f63a.diff
LOG: [libc++] Granularize `range_format` and `format_kind` declarations (#148876)
While working on #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.
Added:
libcxx/include/__format/range_format.h
Modified:
libcxx/include/CMakeLists.txt
libcxx/include/__format/range_default_formatter.h
libcxx/include/module.modulemap.in
Removed:
################################################################################
diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index d729fa81e2b2f..25b567df2dd33 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -403,6 +403,7 @@ set(files
__format/indic_conjunct_break_table.h
__format/parser_std_format_spec.h
__format/range_default_formatter.h
+ __format/range_format.h
__format/range_formatter.h
__format/unicode.h
__format/width_estimation_table.h
diff --git a/libcxx/include/__format/range_default_formatter.h b/libcxx/include/__format/range_default_formatter.h
index 7149debb2f141..2769647ad527e 100644
--- a/libcxx/include/__format/range_default_formatter.h
+++ b/libcxx/include/__format/range_default_formatter.h
@@ -16,10 +16,10 @@
#include <__algorithm/ranges_copy.h>
#include <__chrono/statically_widen.h>
-#include <__concepts/same_as.h>
#include <__config>
#include <__format/concepts.h>
#include <__format/formatter.h>
+#include <__format/range_format.h>
#include <__format/range_formatter.h>
#include <__iterator/back_insert_iterator.h>
#include <__ranges/concepts.h>
@@ -42,51 +42,11 @@ concept __const_formattable_range =
template <class _Rp, class _CharT>
using __fmt_maybe_const _LIBCPP_NODEBUG = conditional_t<__const_formattable_range<_Rp, _CharT>, const _Rp, _Rp>;
-_LIBCPP_DIAGNOSTIC_PUSH
-_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wshadow")
-_LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wshadow")
-// This shadows map, set, and string.
-enum class range_format { disabled, map, set, sequence, string, debug_string };
-_LIBCPP_DIAGNOSTIC_POP
-
// There is no definition of this struct, it's purely intended to be used to
// generate diagnostics.
template <class _Rp>
struct __instantiated_the_primary_template_of_format_kind;
-template <class _Rp>
-constexpr range_format format_kind = [] {
- // [format.range.fmtkind]/1
- // A program that instantiates the primary template of format_kind is ill-formed.
- static_assert(sizeof(_Rp) != sizeof(_Rp), "create a template specialization of format_kind for your type");
- return range_format::disabled;
-}();
-
-template <ranges::input_range _Rp>
- requires same_as<_Rp, remove_cvref_t<_Rp>>
-inline constexpr range_format format_kind<_Rp> = [] {
- // [format.range.fmtkind]/2
-
- // 2.1 If same_as<remove_cvref_t<ranges::range_reference_t<R>>, R> is true,
- // Otherwise format_kind<R> is range_format::disabled.
- if constexpr (same_as<remove_cvref_t<ranges::range_reference_t<_Rp>>, _Rp>)
- return range_format::disabled;
- // 2.2 Otherwise, if the qualified-id R::key_type is valid and denotes a type:
- else if constexpr (requires { typename _Rp::key_type; }) {
- // 2.2.1 If the qualified-id R::mapped_type is valid and denotes a type ...
- if constexpr (requires { typename _Rp::mapped_type; } &&
- // 2.2.1 ... If either U is a specialization of pair or U is a specialization
- // of tuple and tuple_size_v<U> == 2
- __fmt_pair_like<remove_cvref_t<ranges::range_reference_t<_Rp>>>)
- return range_format::map;
- else
- // 2.2.2 Otherwise format_kind<R> is range_format::set.
- return range_format::set;
- } else
- // 2.3 Otherwise, format_kind<R> is range_format::sequence.
- return range_format::sequence;
-}();
-
template <range_format _Kp, ranges::input_range _Rp, class _CharT>
struct __range_default_formatter;
diff --git a/libcxx/include/__format/range_format.h b/libcxx/include/__format/range_format.h
new file mode 100644
index 0000000000000..139cfd92ee32b
--- /dev/null
+++ b/libcxx/include/__format/range_format.h
@@ -0,0 +1,71 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___FORMAT_RANGE_FORMAT_H
+#define _LIBCPP___FORMAT_RANGE_FORMAT_H
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+#include <__concepts/same_as.h>
+#include <__config>
+#include <__format/concepts.h>
+#include <__ranges/concepts.h>
+#include <__type_traits/remove_cvref.h>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER >= 23
+
+_LIBCPP_DIAGNOSTIC_PUSH
+_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wshadow")
+_LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wshadow")
+// This shadows map, set, and string.
+enum class range_format { disabled, map, set, sequence, string, debug_string };
+_LIBCPP_DIAGNOSTIC_POP
+
+template <class _Rp>
+constexpr range_format format_kind = [] {
+ // [format.range.fmtkind]/1
+ // A program that instantiates the primary template of format_kind is ill-formed.
+ static_assert(sizeof(_Rp) != sizeof(_Rp), "create a template specialization of format_kind for your type");
+ return range_format::disabled;
+}();
+
+template <ranges::input_range _Rp>
+ requires same_as<_Rp, remove_cvref_t<_Rp>>
+inline constexpr range_format format_kind<_Rp> = [] {
+ // [format.range.fmtkind]/2
+
+ // 2.1 If same_as<remove_cvref_t<ranges::range_reference_t<R>>, R> is true,
+ // Otherwise format_kind<R> is range_format::disabled.
+ if constexpr (same_as<remove_cvref_t<ranges::range_reference_t<_Rp>>, _Rp>)
+ return range_format::disabled;
+ // 2.2 Otherwise, if the qualified-id R::key_type is valid and denotes a type:
+ else if constexpr (requires { typename _Rp::key_type; }) {
+ // 2.2.1 If the qualified-id R::mapped_type is valid and denotes a type ...
+ if constexpr (requires { typename _Rp::mapped_type; } &&
+ // 2.2.1 ... If either U is a specialization of pair or U is a specialization
+ // of tuple and tuple_size_v<U> == 2
+ __fmt_pair_like<remove_cvref_t<ranges::range_reference_t<_Rp>>>)
+ return range_format::map;
+ else
+ // 2.2.2 Otherwise format_kind<R> is range_format::set.
+ return range_format::set;
+ } else
+ // 2.3 Otherwise, format_kind<R> is range_format::sequence.
+ return range_format::sequence;
+}();
+
+#endif // _LIBCPP_STD_VER >= 23
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif
diff --git a/libcxx/include/module.modulemap.in b/libcxx/include/module.modulemap.in
index 602e72bbf5b01..78607f2c1301d 100644
--- a/libcxx/include/module.modulemap.in
+++ b/libcxx/include/module.modulemap.in
@@ -1369,6 +1369,7 @@ module std [system] {
module indic_conjunct_break_table { header "__format/indic_conjunct_break_table.h" }
module parser_std_format_spec { header "__format/parser_std_format_spec.h" }
module range_default_formatter { header "__format/range_default_formatter.h" }
+ module range_format { header "__format/range_format.h" }
module range_formatter { header "__format/range_formatter.h" }
module unicode { header "__format/unicode.h" }
module width_estimation_table { header "__format/width_estimation_table.h" }
More information about the libcxx-commits
mailing list