${bits_srcdir}/cow_string.h \
${bits_srcdir}/deque.tcc \
${bits_srcdir}/erase_if.h \
+ ${bits_srcdir}/formatfwd.h \
${bits_srcdir}/forward_list.h \
${bits_srcdir}/forward_list.tcc \
${bits_srcdir}/fs_dir.h \
@GLIBCXX_HOSTED_TRUE@ ${bits_srcdir}/cow_string.h \
@GLIBCXX_HOSTED_TRUE@ ${bits_srcdir}/deque.tcc \
@GLIBCXX_HOSTED_TRUE@ ${bits_srcdir}/erase_if.h \
+@GLIBCXX_HOSTED_TRUE@ ${bits_srcdir}/formatfwd.h \
@GLIBCXX_HOSTED_TRUE@ ${bits_srcdir}/forward_list.h \
@GLIBCXX_HOSTED_TRUE@ ${bits_srcdir}/forward_list.tcc \
@GLIBCXX_HOSTED_TRUE@ ${bits_srcdir}/fs_dir.h \
--- /dev/null
+// <format> Formatting -*- C++ -*-
+
+// Copyright The GNU Toolchain Authors.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+// <http://www.gnu.org/licenses/>.
+
+/** @file bits/formatfwd.h
+ * This is an internal header file, included by other library headers.
+ * Do not attempt to use it directly. @headername{format}
+ */
+
+#ifndef _GLIBCXX_FORMAT_FWD_H
+#define _GLIBCXX_FORMAT_FWD_H 1
+
+#ifdef _GLIBCXX_SYSHDR
+#pragma GCC system_header
+#endif
+
+// <bits/version.h> must have been included before this header:
+#ifdef __glibcxx_format // C++ >= 20 && HOSTED
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+ // [format.context], class template basic_format_context
+ template<typename _Out, typename _CharT> class basic_format_context;
+
+ // [format.parse.ctx], class template basic_format_parse_context
+ template<typename _CharT> class basic_format_parse_context;
+
+ // [format.formatter], formatter
+ template<typename _Tp, typename _CharT = char> struct formatter;
+
+namespace __format
+{
+#ifdef _GLIBCXX_USE_WCHAR_T
+ template<typename _CharT>
+ concept __char = same_as<_CharT, char> || same_as<_CharT, wchar_t>;
+#else
+ template<typename _CharT>
+ concept __char = same_as<_CharT, char>;
+#endif
+
+ template<__char _CharT>
+ struct __formatter_int;
+}
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace std
+#endif // __glibcxx_format
+#pragma GCC diagnostic pop
+#endif // _GLIBCXX_FORMAT_FWD_H
};
};
-// ftms = {
- // name = format_ranges;
+ftms = {
+ name = format_ranges;
// 202207 P2286R8 Formatting Ranges
// 202207 P2585R1 Improving default container formatting
// LWG3750 Too many papers bump __cpp_lib_format
- // TODO: #define __cpp_lib_format_ranges 202207L
- // values = {
- // v = 202207;
- // cxxmin = 23;
- // hosted = yes;
- // };
-// };
+ no_stdname = true; // TODO remove
+ values = {
+ v = 1; // TODO 202207
+ cxxmin = 23;
+ hosted = yes;
+ };
+};
ftms = {
name = freestanding_algorithm;
#endif /* !defined(__cpp_lib_expected) && defined(__glibcxx_want_expected) */
#undef __glibcxx_want_expected
+#if !defined(__cpp_lib_format_ranges)
+# if (__cplusplus >= 202100L) && _GLIBCXX_HOSTED
+# define __glibcxx_format_ranges 1L
+# if defined(__glibcxx_want_all) || defined(__glibcxx_want_format_ranges)
+# endif
+# endif
+#endif /* !defined(__cpp_lib_format_ranges) && defined(__glibcxx_want_format_ranges) */
+#undef __glibcxx_want_format_ranges
+
#if !defined(__cpp_lib_freestanding_algorithm)
# if (__cplusplus >= 202100L)
# define __glibcxx_freestanding_algorithm 202311L
#include <string_view>
#include <string>
#include <bits/monostate.h>
+#include <bits/formatfwd.h>
#include <bits/ranges_base.h> // input_range, range_reference_t
#include <bits/ranges_util.h> // subrange
#include <bits/ranges_algobase.h> // ranges::copy
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
- // [format.context], class template basic_format_context
- template<typename _Out, typename _CharT> class basic_format_context;
-
// [format.fmt.string], class template basic_format_string
template<typename _CharT, typename... _Args> struct basic_format_string;
// [format.formatter], formatter
/// The primary template of std::formatter is disabled.
- template<typename _Tp, typename _CharT = char>
+ template<typename _Tp, typename _CharT>
struct formatter
{
formatter() = delete; // No std::formatter specialization for this type.
bool _M_hasval = false;
};
-#ifdef _GLIBCXX_USE_WCHAR_T
- template<typename _CharT>
- concept __char = same_as<_CharT, char> || same_as<_CharT, wchar_t>;
-#else
- template<typename _CharT>
- concept __char = same_as<_CharT, char>;
-#endif
-
template<__char _CharT>
struct __formatter_str
{
} // namespace std
#endif // __cpp_lib_erase_if
+#ifdef __glibcxx_format_ranges // C++ >= 20 && HOSTED
+#include <bits/formatfwd.h>
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+ // Standard does not constrain accepted _CharT and declares it as formatter
+ // of Tp that statisfies is-vector-bool-reference<T>,
+ template<__format::__char _CharT>
+ struct formatter<_GLIBCXX_STD_C::_Bit_reference, _CharT>
+ {
+ // Standard declares this as template accepting unconstrained
+ // ParseContext type.
+ constexpr typename basic_format_parse_context<_CharT>::iterator
+ parse(basic_format_parse_context<_CharT>& __pc)
+ { return _M_f.template _M_parse<bool>(__pc); }
+
+ // Standard declares this as template accepting unconstrained
+ // FormatContext type.
+ template<typename _Out>
+ typename basic_format_context<_Out, _CharT>::iterator
+ format(const _GLIBCXX_STD_C::_Bit_reference& __u,
+ basic_format_context<_Out, _CharT>& __fc) const
+ { return _M_f.format(static_cast<bool>(__u), __fc); }
+
+ private:
+ __format::__formatter_int<_CharT> _M_f;
+ };
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace std
+#endif // __glibcxx_format_ranges
+
#endif /* _GLIBCXX_VECTOR */
--- /dev/null
+// { dg-do run { target c++23 } }
+// { dg-timeout-factor 2 }
+
+#include <format>
+#include <vector>
+#include <chrono> // For _Widen
+#include <testsuite_hooks.h>
+
+static_assert(!std::formattable<std::vector<bool>::reference, int>);
+static_assert(!std::formattable<std::vector<bool>::reference, char32_t>);
+
+template<typename... Args>
+bool
+is_format_string_for(const char* str, Args&&... args)
+{
+ try {
+ (void) std::vformat(str, std::make_format_args(args...));
+ return true;
+ } catch (const std::format_error&) {
+ return false;
+ }
+}
+
+#define WIDEN_(C, S) ::std::chrono::__detail::_Widen<C>(S, L##S)
+#define WIDEN(S) WIDEN_(_CharT, S)
+
+void
+test_format_string()
+{
+ std::vector<bool> v(1, true);
+ VERIFY( !is_format_string_for("{:?}", v[0]) );
+ VERIFY( !is_format_string_for("{:P}", v[0]) );
+
+ // width needs to be integer type
+ VERIFY( !is_format_string_for("{:{}}", v[0], 1.0f) );
+}
+
+template<typename _CharT>
+void
+test_output()
+{
+ std::basic_string<_CharT> res;
+ size_t size = 0;
+ std::vector<bool> v{true, false};
+
+ res = std::format(WIDEN("{}"), v[0]);
+ VERIFY( res == WIDEN("true") );
+
+ res = std::format(WIDEN("{:s}"), v[1]);
+ VERIFY( res == WIDEN("false") );
+
+ res = std::format(WIDEN("{:d} {:#B} {:#o} {:#x}"), v[0], v[1], v[0], v[1]);
+ VERIFY( res == WIDEN("1 0B0 01 0x0") );
+
+ res = std::format(WIDEN("{:{}}"), v[0], 6);
+ VERIFY( res == WIDEN("true ") );
+
+ res = std::format(WIDEN("{:=^#7X}"), v[1]);
+ VERIFY( res == WIDEN("==0X0==") );
+}
+
+int main()
+{
+ test_format_string();
+ test_output<char>();
+ test_output<wchar_t>();
+}