aboutsummaryrefslogtreecommitdiff
path: root/libstdc++-v3/include
diff options
context:
space:
mode:
Diffstat (limited to 'libstdc++-v3/include')
-rw-r--r--libstdc++-v3/include/bits/chrono_io.h912
-rw-r--r--libstdc++-v3/include/bits/formatfwd.h26
-rw-r--r--libstdc++-v3/include/bits/ranges_algo.h64
-rw-r--r--libstdc++-v3/include/bits/stl_algo.h4
-rw-r--r--libstdc++-v3/include/bits/stl_construct.h72
-rw-r--r--libstdc++-v3/include/bits/stl_tempbuf.h2
-rw-r--r--libstdc++-v3/include/bits/stl_uninitialized.h48
-rw-r--r--libstdc++-v3/include/bits/version.def8
-rw-r--r--libstdc++-v3/include/bits/version.h10
-rw-r--r--libstdc++-v3/include/std/format44
-rw-r--r--libstdc++-v3/include/std/mdspan726
-rw-r--r--libstdc++-v3/include/std/optional47
-rw-r--r--libstdc++-v3/include/std/sstream12
-rw-r--r--libstdc++-v3/include/std/type_traits3
14 files changed, 1586 insertions, 392 deletions
diff --git a/libstdc++-v3/include/bits/chrono_io.h b/libstdc++-v3/include/bits/chrono_io.h
index c5c5e4b..abbf4efc 100644
--- a/libstdc++-v3/include/bits/chrono_io.h
+++ b/libstdc++-v3/include/bits/chrono_io.h
@@ -238,6 +238,108 @@ namespace __format
operator|=(_ChronoParts& __x, _ChronoParts __y) noexcept
{ return __x = __x | __y; }
+ template<typename _CharT>
+ struct _ChronoFormats
+ {
+ using _String_view = basic_string_view<_CharT>;
+
+ static consteval
+ _String_view
+ _S_ftz() noexcept
+ { return _GLIBCXX_WIDEN("%F %T %Z"); }
+
+ static consteval
+ _String_view
+ _S_ft() noexcept
+ { return _S_ftz().substr(0, 5); }
+
+ static consteval
+ _String_view
+ _S_f() noexcept
+ { return _S_ftz().substr(0, 2); }
+
+ static consteval
+ _String_view
+ _S_t() noexcept
+ { return _S_ftz().substr(3, 2); }
+
+ static consteval
+ _String_view
+ _S_ymd() noexcept
+ { return _GLIBCXX_WIDEN("%Y/%b/%d"); }
+
+ static consteval
+ _String_view
+ _S_ym() noexcept
+ { return _S_ymd().substr(0, 5); }
+
+ static consteval
+ _String_view
+ _S_md() noexcept
+ { return _S_ymd().substr(3); }
+
+ static consteval
+ _String_view
+ _S_y() noexcept
+ { return _S_ymd().substr(0, 2); }
+
+ static consteval
+ _String_view
+ _S_m() noexcept
+ { return _S_ymd().substr(3, 2); }
+
+ static consteval
+ _String_view
+ _S_d() noexcept
+ { return _S_ymd().substr(6, 2); }
+
+ static consteval
+ _String_view
+ _S_ymwi() noexcept
+ // %\0 is extension for handling weekday index
+ { return _String_view(_GLIBCXX_WIDEN("%Y/%b/%a[%\0]"), 12); }
+
+ static consteval
+ _String_view
+ _S_mwi() noexcept
+ { return _S_ymwi().substr(3); }
+
+ static consteval
+ _String_view
+ _S_wi() noexcept
+ { return _S_ymwi().substr(6); }
+
+ static consteval
+ _String_view
+ _S_w() noexcept
+ { return _S_ymwi().substr(6, 2); }
+
+ static consteval
+ _String_view
+ _S_ymwl() noexcept
+ { return _GLIBCXX_WIDEN("%Y/%b/%a[last]"); }
+
+ static consteval
+ _String_view
+ _S_mwl() noexcept
+ { return _S_ymwl().substr(3); }
+
+ static consteval
+ _String_view
+ _S_wl() noexcept
+ { return _S_ymwl().substr(6); }
+
+ static consteval
+ _String_view
+ _S_yml() noexcept
+ { return _GLIBCXX_WIDEN("%Y/%b/last"); }
+
+ static consteval
+ _String_view
+ _S_ml() noexcept
+ { return _S_yml().substr(3); }
+ };
+
// TODO rename this to chrono::__formatter? or chrono::__detail::__formatter?
template<typename _CharT>
struct __formatter_chrono
@@ -245,14 +347,22 @@ namespace __format
using __string_view = basic_string_view<_CharT>;
using __string = basic_string<_CharT>;
+ __formatter_chrono() = default;
+
+ constexpr explicit
+ __formatter_chrono(_ChronoSpec<_CharT> __spec) noexcept
+ : _M_spec(__spec)
+ { }
+
template<typename _ParseContext>
constexpr typename _ParseContext::iterator
- _M_parse(_ParseContext& __pc, _ChronoParts __parts)
+ _M_parse(_ParseContext& __pc, _ChronoParts __parts,
+ const _ChronoSpec<_CharT>& __def = {})
{
auto __first = __pc.begin();
auto __last = __pc.end();
- _ChronoSpec<_CharT> __spec{};
+ _ChronoSpec<_CharT> __spec = __def;
auto __finalize = [this, &__spec] {
_M_spec = __spec;
@@ -285,6 +395,7 @@ namespace __format
return __first;
}
+ __spec._M_localized = false;
__first = __spec._M_parse_locale(__first, __last);
if (__finished())
return __first;
@@ -306,6 +417,9 @@ namespace __format
// Parse chrono-specs in [first,last), checking each conversion-spec
// against __parts (so fail for %Y if no year in parts).
// Save range in __spec._M_chrono_specs.
+ __spec._M_debug = false;
+ __spec._M_locale_specific = true;
+ __spec._M_chrono_specs = __string_view();
const auto __chrono_specs = __first++; // Skip leading '%'
if (*__chrono_specs != '%')
@@ -492,14 +606,12 @@ namespace __format
// that we instantiate fewer different specializations. Similar to
// _Sink_iter for std::format. Replace each _S_year, _S_day etc. with
// member functions of that type.
+ // pre: !_M_spec._M_chrono_specs.empty()
template<typename _Tp, typename _FormatContext>
typename _FormatContext::iterator
_M_format(const _Tp& __t, _FormatContext& __fc,
bool __is_neg = false) const
{
- if (_M_spec._M_chrono_specs.empty())
- return _M_format_to_ostream(__t, __fc, __is_neg);
-
#if defined _GLIBCXX_USE_NL_LANGINFO_L && __CHAR_BIT__ == 8
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 3565. Handling of encodings in localized formatting
@@ -562,6 +674,10 @@ namespace __format
_CharT __c = *__first++;
switch (__c)
{
+ // %\0 is extension for handling weekday index
+ case '\0':
+ __out = _M_wi(__t, std::move(__out), __fc);
+ break;
case 'a':
case 'A':
__out = _M_a_A(__t, std::move(__out), __fc, __c == 'A');
@@ -572,7 +688,10 @@ namespace __format
__out = _M_b_B(__t, std::move(__out), __fc, __c == 'B');
break;
case 'c':
- __out = _M_c(__t, std::move(__out), __fc, __mod == 'E');
+ case 'r':
+ case 'x':
+ case 'X':
+ __out = _M_c_r_x_X(__t, std::move(__out), __fc, __c, __mod);
break;
case 'C':
case 'y':
@@ -623,9 +742,6 @@ namespace __format
__throw_format_error("chrono format error: argument is "
"not a duration");
break;
- case 'r':
- __out = _M_r(__t, __print_sign(), __fc);
- break;
case 'R':
case 'T':
__out = _M_R_T(__t, __print_sign(), __fc, __c == 'T');
@@ -643,12 +759,6 @@ namespace __format
__out = _M_U_V_W(__t, std::move(__out), __fc, __c,
__mod == 'O');
break;
- case 'x':
- __out = _M_x(__t, std::move(__out), __fc, __mod == 'E');
- break;
- case 'X':
- __out = _M_X(__t, __print_sign(), __fc, __mod == 'E');
- break;
case 'z':
__out = _M_z(__t, std::move(__out), __fc, (bool)__mod);
break;
@@ -694,6 +804,24 @@ namespace __format
return std::move(__out);
}
+ // Format duration for empty chrono-specs, e.g. "{}" (C++20 [time.format] p6).
+ template<typename _Rep, typename _Period, typename _FormatContext>
+ typename _FormatContext::iterator
+ _M_format_to_ostream(const chrono::duration<_Rep, _Period>& __d,
+ bool __is_neg, _FormatContext& __fc) const
+ {
+ basic_ostringstream<_CharT> __os;
+ __os.imbue(_M_locale(__fc));
+
+ if (__is_neg) [[unlikely]]
+ __os << _S_plus_minus[1];
+ __os << __d;
+
+ auto __str = std::move(__os).str();
+ return __format::__write_padded_as_spec(__str, __str.size(),
+ __fc, _M_spec);
+ }
+
_ChronoSpec<_CharT> _M_spec;
private:
@@ -708,82 +836,6 @@ namespace __format
return __fc.locale();
}
- // Format for empty chrono-specs, e.g. "{}" (C++20 [time.format] p6).
- // TODO: consider moving body of every operator<< into this function
- // and use std::format("{}", t) to implement those operators. That
- // would avoid std::format("{}", t) calling operator<< which calls
- // std::format again.
- template<typename _Tp, typename _FormatContext>
- typename _FormatContext::iterator
- _M_format_to_ostream(const _Tp& __t, _FormatContext& __fc,
- bool __is_neg) const
- {
- using ::std::chrono::__detail::__utc_leap_second;
- using ::std::chrono::__detail::__local_time_fmt;
-
- basic_ostringstream<_CharT> __os;
- __os.imbue(_M_locale(__fc));
-
- if constexpr (__is_specialization_of<_Tp, __local_time_fmt>)
- {
- // Format as "{:L%F %T}"
- auto __days = chrono::floor<chrono::days>(__t._M_time);
- __os << chrono::year_month_day(__days) << ' '
- << chrono::hh_mm_ss(__t._M_time - __days);
-
- // For __local_time_fmt the __is_neg flags says whether to
- // append " %Z" to the result.
- if (__is_neg)
- {
- if (!__t._M_abbrev) [[unlikely]]
- __format::__no_timezone_available();
- else if constexpr (is_same_v<_CharT, char>)
- __os << ' ' << *__t._M_abbrev;
- else
- {
- __os << L' ';
- for (char __c : *__t._M_abbrev)
- __os << __c;
- }
- }
- }
- else
- {
- if constexpr (__is_specialization_of<_Tp, __utc_leap_second>)
- __os << __t._M_date << ' ' << __t._M_time;
- else if constexpr (chrono::__is_time_point_v<_Tp>)
- {
- // Need to be careful here because not all specializations
- // of chrono::sys_time can be written to an ostream.
- // For the specializations of time_point that can be
- // formatted with an empty chrono-specs, either it's a
- // sys_time with period greater or equal to days:
- if constexpr (is_convertible_v<_Tp, chrono::sys_days>)
- __os << _S_date(__t);
- // Or a local_time with period greater or equal to days:
- else if constexpr (is_convertible_v<_Tp, chrono::local_days>)
- __os << _S_date(__t);
- else // Or it's formatted as "{:L%F %T}":
- {
- auto __days = chrono::floor<chrono::days>(__t);
- __os << chrono::year_month_day(__days) << ' '
- << chrono::hh_mm_ss(__t - __days);
- }
- }
- else
- {
- if constexpr (chrono::__is_duration_v<_Tp>)
- if (__is_neg) [[unlikely]]
- __os << _S_plus_minus[1];
- __os << __t;
- }
- }
-
- auto __str = std::move(__os).str();
- return __format::__write_padded_as_spec(__str, __str.size(),
- __fc, _M_spec);
- }
-
static constexpr const _CharT* _S_chars
= _GLIBCXX_WIDEN("0123456789:/ +-{}");
static constexpr _CharT _S_colon = _S_chars[10];
@@ -818,6 +870,22 @@ namespace __format
template<typename _Tp, typename _FormatContext>
typename _FormatContext::iterator
+ _M_wi(const _Tp& __t, typename _FormatContext::iterator __out,
+ _FormatContext& __ctx) const
+ {
+ // %\0 Extension to format weekday index, used only by empty format spec
+ unsigned __wi = _S_weekday_index(__t);
+
+ _CharT __buf[3];
+ __out = __format::__write(std::move(__out), _S_str_d1(__buf, __wi));
+ if (_M_spec._M_debug && (__wi < 1 || __wi > 5))
+ __out = __format::__write(std::move(__out),
+ __string_view(_GLIBCXX_WIDEN(" is not a valid index")));
+ return std::move(__out);
+ }
+
+ template<typename _Tp, typename _FormatContext>
+ typename _FormatContext::iterator
_M_a_A(const _Tp& __t, typename _FormatContext::iterator __out,
_FormatContext& __ctx, bool __full) const
{
@@ -825,7 +893,16 @@ namespace __format
// %A Locale's full weekday name.
chrono::weekday __wd = _S_weekday(__t);
if (!__wd.ok())
- __throw_format_error("format error: invalid weekday");
+ {
+ if (!_M_spec._M_debug)
+ __throw_format_error("format error: invalid weekday");
+
+ _CharT __buf[3];
+ __out = __format::__write(std::move(__out),
+ _S_str_d1(__buf, __wd.c_encoding()));
+ return __format::__write(std::move(__out),
+ __string_view(_GLIBCXX_WIDEN(" is not a valid weekday")));
+ }
locale __loc = _M_locale(__ctx);
const auto& __tp = use_facet<__timepunct<_CharT>>(__loc);
@@ -847,7 +924,17 @@ namespace __format
// %B Locale's full month name.
chrono::month __m = _S_month(__t);
if (!__m.ok())
- __throw_format_error("format error: invalid month");
+ {
+ if (!_M_spec._M_debug)
+ __throw_format_error("format error: invalid month");
+
+ _CharT __buf[3];
+ __out = __format::__write(std::move(__out),
+ _S_str_d1(__buf, (unsigned)__m));
+ return __format::__write(std::move(__out),
+ __string_view(_GLIBCXX_WIDEN(" is not a valid month")));
+ }
+
locale __loc = _M_locale(__ctx);
const auto& __tp = use_facet<__timepunct<_CharT>>(__loc);
const _CharT* __months[12];
@@ -861,11 +948,16 @@ namespace __format
template<typename _Tp, typename _FormatContext>
typename _FormatContext::iterator
- _M_c(const _Tp& __t, typename _FormatContext::iterator __out,
- _FormatContext& __ctx, bool __mod = false) const
+ _M_c_r_x_X(const _Tp& __t, typename _FormatContext::iterator __out,
+ _FormatContext& __ctx, _CharT __conv, _CharT __mod) const
{
// %c Locale's date and time representation.
// %Ec Locale's alternate date and time representation.
+ // %r Locale's 12-hour clock time.
+ // %x Locale's date rep
+ // %Ex Locale's alternative date representation.
+ // %X Locale's time rep
+ // %EX Locale's alternative time representation.
using namespace chrono;
using ::std::chrono::__detail::__utc_leap_second;
@@ -899,23 +991,30 @@ namespace __format
__tm.tm_zone = const_cast<char*>("UTC");
#endif
- auto __d = _S_days(__t); // Either sys_days or local_days.
- using _TDays = decltype(__d);
- const year_month_day __ymd(__d);
- const auto __y = __ymd.year();
- const auto __hms = _S_hms(__t);
+ if (__conv == 'c' || __conv == 'x')
+ {
+ auto __d = _S_days(__t); // Either sys_days or local_days.
+ using _TDays = decltype(__d);
+ const year_month_day __ymd(__d);
+ const auto __y = __ymd.year();
+
+ __tm.tm_year = (int)__y - 1900;
+ __tm.tm_yday = (__d - _TDays(__y/January/1)).count();
+ __tm.tm_mon = (unsigned)__ymd.month() - 1;
+ __tm.tm_mday = (unsigned)__ymd.day();
+ __tm.tm_wday = weekday(__d).c_encoding();
+ }
- __tm.tm_year = (int)__y - 1900;
- __tm.tm_yday = (__d - _TDays(__y/January/1)).count();
- __tm.tm_mon = (unsigned)__ymd.month() - 1;
- __tm.tm_mday = (unsigned)__ymd.day();
- __tm.tm_wday = weekday(__d).c_encoding();
- __tm.tm_hour = __hms.hours().count();
- __tm.tm_min = __hms.minutes().count();
- __tm.tm_sec = __hms.seconds().count();
-
- return _M_locale_fmt(std::move(__out), _M_locale(__ctx), __tm, 'c',
- __mod ? 'E' : '\0');
+ if (__conv != 'x')
+ {
+ const auto __hms = _S_hms(__t);
+ __tm.tm_hour = __hms.hours().count();
+ __tm.tm_min = __hms.minutes().count();
+ __tm.tm_sec = __hms.seconds().count();
+ }
+
+ return _M_locale_fmt(std::move(__out), _M_locale(__ctx), __tm,
+ __conv, __mod);
}
template<typename _Tp, typename _FormatContext>
@@ -974,7 +1073,11 @@ namespace __format
}
__out = __format::__write(std::move(__out), __sv);
}
- return std::move(__out);
+
+ if (_M_spec._M_debug && __conv == 'Y' && !__y.ok()) [[unlikely]]
+ __out = __format::__write(std::move(__out),
+ __string_view(_GLIBCXX_WIDEN(" is not a valid year")));
+ return __out;
}
template<typename _Tp, typename _FormatContext>
@@ -1039,7 +1142,12 @@ namespace __format
__buf[0] = _S_space;
__sv = {__buf, 2};
}
- return __format::__write(std::move(__out), __sv);
+
+ __out = __format::__write(std::move(__out), __sv);
+ if (_M_spec._M_debug && !__d.ok()) [[unlikely]]
+ __out = __format::__write(std::move(__out),
+ __string_view(_GLIBCXX_WIDEN(" is not a valid day")));
+ return std::move(__out);
}
template<typename _Tp, typename _FormatContext>
@@ -1076,6 +1184,10 @@ namespace __format
_S_fill_two_digits(__buf + 9, __di);
__out = __format::__write(std::move(__out), __sv);
}
+
+ if (_M_spec._M_debug && !__ymd.ok())
+ __out = __format::__write(std::move(__out),
+ __string_view(_GLIBCXX_WIDEN(" is not a valid date")));
return std::move(__out);
}
@@ -1243,25 +1355,6 @@ namespace __format
template<typename _Tp, typename _FormatContext>
typename _FormatContext::iterator
- _M_r(const _Tp& __tt, typename _FormatContext::iterator __out,
- _FormatContext& __ctx) const
- {
- // %r locale's 12-hour clock time.
- auto __t = _S_floor_seconds(__tt);
- locale __loc = _M_locale(__ctx);
- const auto& __tp = use_facet<__timepunct<_CharT>>(__loc);
- const _CharT* __ampm_fmt;
- __tp._M_am_pm_format(&__ampm_fmt);
- basic_string<_CharT> __fmt(_S_empty_spec);
- __fmt.insert(1u, 1u, _S_colon);
- __fmt.insert(2u, __ampm_fmt);
- using _FmtStr = _Runtime_format_string<_CharT>;
- return _M_write(std::move(__out), __loc,
- std::format(__loc, _FmtStr(__fmt), __t));
- }
-
- template<typename _Tp, typename _FormatContext>
- typename _FormatContext::iterator
_M_R_T(const _Tp& __t, typename _FormatContext::iterator __out,
_FormatContext& __ctx, bool __secs) const
{
@@ -1441,53 +1534,6 @@ namespace __format
template<typename _Tp, typename _FormatContext>
typename _FormatContext::iterator
- _M_x(const _Tp& __t, typename _FormatContext::iterator __out,
- _FormatContext& __ctx, bool __mod = false) const
- {
- // %x Locale's date rep
- // %Ex Locale's alternative date representation.
- locale __loc = _M_locale(__ctx);
- const auto& __tp = use_facet<__timepunct<_CharT>>(__loc);
- const _CharT* __date_reps[2];
- __tp._M_date_formats(__date_reps);
- const _CharT* __rep = __date_reps[__mod];
- if (!*__rep)
- return _M_D(__t, std::move(__out), __ctx);
-
- basic_string<_CharT> __fmt(_S_empty_spec);
- __fmt.insert(1u, 1u, _S_colon);
- __fmt.insert(2u, __rep);
- using _FmtStr = _Runtime_format_string<_CharT>;
- return _M_write(std::move(__out), __loc,
- std::format(__loc, _FmtStr(__fmt), __t));
- }
-
- template<typename _Tp, typename _FormatContext>
- typename _FormatContext::iterator
- _M_X(const _Tp& __tt, typename _FormatContext::iterator __out,
- _FormatContext& __ctx, bool __mod = false) const
- {
- // %X Locale's time rep
- // %EX Locale's alternative time representation.
- auto __t = _S_floor_seconds(__tt);
- locale __loc = _M_locale(__ctx);
- const auto& __tp = use_facet<__timepunct<_CharT>>(__loc);
- const _CharT* __time_reps[2];
- __tp._M_time_formats(__time_reps);
- const _CharT* __rep = __time_reps[__mod];
- if (!*__rep)
- return _M_R_T(__t, std::move(__out), __ctx, true);
-
- basic_string<_CharT> __fmt(_S_empty_spec);
- __fmt.insert(1u, 1u, _S_colon);
- __fmt.insert(2u, __rep);
- using _FmtStr = _Runtime_format_string<_CharT>;
- return _M_write(std::move(__out), __loc,
- std::format(__loc, _FmtStr(__fmt), __t));
- }
-
- template<typename _Tp, typename _FormatContext>
- typename _FormatContext::iterator
_M_z(const _Tp& __t, typename _FormatContext::iterator __out,
_FormatContext&, bool __mod = false) const
{
@@ -1757,6 +1803,20 @@ namespace __format
return weekday(_S_days(__t));
}
+ template<typename _Tp>
+ static unsigned
+ _S_weekday_index(const _Tp& __t)
+ {
+ using namespace ::std::chrono;
+
+ if constexpr (is_same_v<_Tp, weekday_indexed>)
+ return __t.index();
+ else if constexpr (requires { __t.weekday_indexed(); })
+ return __t.weekday_indexed().index();
+ else
+ return ((unsigned)_S_day(__t) + 6) / 7;
+ }
+
// Remove subsecond precision from a time_point.
template<typename _Tp>
static auto
@@ -1801,6 +1861,84 @@ namespace __format
}
};
+#if _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
+ template<typename _CharT>
+ struct __formatter_chrono_info
+ {
+ constexpr typename basic_format_parse_context<_CharT>::iterator
+ parse(basic_format_parse_context<_CharT>& __pc)
+ { return _M_f._M_parse(__pc, _ChronoParts(), {}); }
+
+ template<typename _Info, typename _Out>
+ typename basic_format_context<_Out, _CharT>::iterator
+ format(const _Info& __i,
+ basic_format_context<_Out, _CharT>& __fc) const
+ {
+ // n.b. only acceptable chrono-spec for info is one containing
+ // only whitespaces and %%, that do not depend on formatted object.
+ if (!_M_f._M_spec._M_chrono_specs.empty()) [[unlikely]]
+ return _M_f._M_format(chrono::day(1), __fc);
+
+ const size_t __padwidth = _M_f._M_spec._M_get_width(__fc);
+ if (__padwidth == 0)
+ return _M_format_to(__fc.out(), __i);
+
+ _Padding_sink<_Out, _CharT> __sink(__fc.out(), __padwidth);
+ _M_format_to(__sink.out(), __i);
+ return __sink._M_finish(_M_f._M_spec._M_align, _M_f._M_spec._M_fill);
+ }
+
+ private:
+ template<typename _Out>
+ _Out
+ _M_format_to(_Out __out, const chrono::sys_info& __si) const
+ {
+ using _FmtStr = _Runtime_format_string<_CharT>;
+ // n.b. only decimal separator is locale dependent for specifiers
+ // used below, as sys_info uses seconds and minutes duration, the
+ // output is locale-independent.
+ constexpr auto* __fs
+ = _GLIBCXX_WIDEN("[{0:%F %T},{1:%F %T},{2:%T},{3:%Q%q},{0:%Z}]");
+ const chrono::local_seconds __lb(__si.begin.time_since_epoch());
+ return std::format_to(std::move(__out), _FmtStr(__fs),
+ chrono::local_time_format(__lb, &__si.abbrev),
+ __si.end, __si.offset, __si.save);
+ }
+
+ template<typename _Out>
+ _Out
+ _M_format_to(_Out __out, const chrono::local_info& __li) const
+ {
+ *__out = _Separators<_CharT>::_S_squares()[0];
+ ++__out;
+ if (__li.result == chrono::local_info::unique)
+ __out = _M_format_to(std::move(__out), __li.first);
+ else
+ {
+ basic_string_view<_CharT> __sv;
+ if (__li.result == chrono::local_info::nonexistent)
+ __sv =_GLIBCXX_WIDEN("nonexistent");
+ else
+ __sv = _GLIBCXX_WIDEN("ambiguous");
+ __out = __format::__write(std::move(__out), __sv);
+
+ __sv = _GLIBCXX_WIDEN(" local time between ");
+ __out = __format::__write(std::move(__out), __sv);
+ __out = _M_format_to(std::move(__out), __li.first);
+
+ __sv = _GLIBCXX_WIDEN(" and ");
+ __out = __format::__write(std::move(__out), __sv);
+ __out = _M_format_to(std::move(__out), __li.second);
+ }
+ *__out = _Separators<_CharT>::_S_squares()[1];
+ ++__out;
+ return std::move(__out);
+ }
+
+ __formatter_chrono<_CharT> _M_f;
+ };
+#endif
+
} // namespace __format
/// @endcond
@@ -1812,7 +1950,7 @@ namespace __format
parse(basic_format_parse_context<_CharT>& __pc)
{
using namespace __format;
- auto __it = _M_f._M_parse(__pc, _Duration|_TimeOfDay);
+ auto __it = _M_f._M_parse(__pc, _Duration|_TimeOfDay, __defSpec);
if constexpr (!is_floating_point_v<_Rep>)
if (_M_f._M_spec._M_prec_kind != __format::_WP_none)
__throw_format_error("format error: invalid precision for duration");
@@ -1834,16 +1972,37 @@ namespace __format
using _URep = make_unsigned_t<_Rep>;
auto __ucnt = -static_cast<_URep>(__d.count());
auto __ud = chrono::duration<_URep, _Period>(__ucnt);
- return _M_f._M_format(__ud, __fc, true);
+ return _M_format(__ud, true, __fc);
}
else
- return _M_f._M_format(-__d, __fc, true);
+ return _M_format(-__d, true, __fc);
}
- return _M_f._M_format(__d, __fc, false);
+ return _M_format(__d, false, __fc);
}
private:
- __format::__formatter_chrono<_CharT> _M_f;
+ static constexpr __format::_ChronoSpec<_CharT> __defSpec = []
+ {
+ __format::_ChronoSpec<_CharT> __res{};
+ __res._M_localized = !is_integral_v<_Rep>;
+ if constexpr (is_integral_v<_Rep>)
+ __res._M_chrono_specs = _GLIBCXX_WIDEN("%Q%q");
+ return __res;
+ }();
+
+ template<typename _Rep2, typename _Out>
+ typename basic_format_context<_Out, _CharT>::iterator
+ _M_format(const chrono::duration<_Rep2, _Period>& __d,
+ bool __is_neg,
+ basic_format_context<_Out, _CharT>& __fc) const
+ {
+ if constexpr (!is_integral_v<_Rep>)
+ if (_M_f._M_spec._M_chrono_specs.empty())
+ return _M_f._M_format_to_ostream(__d, __is_neg, __fc);
+ return _M_f._M_format(__d, __fc, __is_neg);
+ }
+
+ __format::__formatter_chrono<_CharT> _M_f{__defSpec};
};
template<__format::__char _CharT>
@@ -1851,7 +2010,7 @@ namespace __format
{
constexpr typename basic_format_parse_context<_CharT>::iterator
parse(basic_format_parse_context<_CharT>& __pc)
- { return _M_f._M_parse(__pc, __format::_Day); }
+ { return _M_f._M_parse(__pc, __format::_Day, __defSpec); }
template<typename _Out>
typename basic_format_context<_Out, _CharT>::iterator
@@ -1860,7 +2019,15 @@ namespace __format
{ return _M_f._M_format(__t, __fc); }
private:
- __format::__formatter_chrono<_CharT> _M_f;
+ static constexpr __format::_ChronoSpec<_CharT> __defSpec = []
+ {
+ __format::_ChronoSpec<_CharT> __res{};
+ __res._M_debug = true;
+ __res._M_chrono_specs = __format::_ChronoFormats<_CharT>::_S_d();
+ return __res;
+ }();
+
+ __format::__formatter_chrono<_CharT> _M_f{__defSpec};
};
template<__format::__char _CharT>
@@ -1868,7 +2035,7 @@ namespace __format
{
constexpr typename basic_format_parse_context<_CharT>::iterator
parse(basic_format_parse_context<_CharT>& __pc)
- { return _M_f._M_parse(__pc, __format::_Month); }
+ { return _M_f._M_parse(__pc, __format::_Month, __defSpec); }
template<typename _Out>
typename basic_format_context<_Out, _CharT>::iterator
@@ -1877,7 +2044,17 @@ namespace __format
{ return _M_f._M_format(__t, __fc); }
private:
- __format::__formatter_chrono<_CharT> _M_f;
+ static constexpr __format::_ChronoSpec<_CharT> __defSpec = []
+ {
+ __format::_ChronoSpec<_CharT> __res{};
+ __res._M_debug = true;
+ __res._M_localized = true;
+ __res._M_locale_specific = true;
+ __res._M_chrono_specs = __format::_ChronoFormats<_CharT>::_S_m();
+ return __res;
+ }();
+
+ __format::__formatter_chrono<_CharT> _M_f{__defSpec};
};
template<__format::__char _CharT>
@@ -1885,7 +2062,7 @@ namespace __format
{
constexpr typename basic_format_parse_context<_CharT>::iterator
parse(basic_format_parse_context<_CharT>& __pc)
- { return _M_f._M_parse(__pc, __format::_Year); }
+ { return _M_f._M_parse(__pc, __format::_Year, __defSpec); }
template<typename _Out>
typename basic_format_context<_Out, _CharT>::iterator
@@ -1894,7 +2071,15 @@ namespace __format
{ return _M_f._M_format(__t, __fc); }
private:
- __format::__formatter_chrono<_CharT> _M_f;
+ static constexpr __format::_ChronoSpec<_CharT> __defSpec = []
+ {
+ __format::_ChronoSpec<_CharT> __res{};
+ __res._M_debug = true;
+ __res._M_chrono_specs = __format::_ChronoFormats<_CharT>::_S_y();
+ return __res;
+ }();
+
+ __format::__formatter_chrono<_CharT> _M_f{__defSpec};
};
template<__format::__char _CharT>
@@ -1902,7 +2087,7 @@ namespace __format
{
constexpr typename basic_format_parse_context<_CharT>::iterator
parse(basic_format_parse_context<_CharT>& __pc)
- { return _M_f._M_parse(__pc, __format::_Weekday); }
+ { return _M_f._M_parse(__pc, __format::_Weekday, __defSpec); }
template<typename _Out>
typename basic_format_context<_Out, _CharT>::iterator
@@ -1911,7 +2096,17 @@ namespace __format
{ return _M_f._M_format(__t, __fc); }
private:
- __format::__formatter_chrono<_CharT> _M_f;
+ static constexpr __format::_ChronoSpec<_CharT> __defSpec = []
+ {
+ __format::_ChronoSpec<_CharT> __res{};
+ __res._M_debug = true;
+ __res._M_localized = true;
+ __res._M_locale_specific = true;
+ __res._M_chrono_specs = __format::_ChronoFormats<_CharT>::_S_w();
+ return __res;
+ }();
+
+ __format::__formatter_chrono<_CharT> _M_f{__defSpec};
};
template<__format::__char _CharT>
@@ -1919,7 +2114,7 @@ namespace __format
{
constexpr typename basic_format_parse_context<_CharT>::iterator
parse(basic_format_parse_context<_CharT>& __pc)
- { return _M_f._M_parse(__pc, __format::_Weekday); }
+ { return _M_f._M_parse(__pc, __format::_Weekday, __defSpec); }
template<typename _Out>
typename basic_format_context<_Out, _CharT>::iterator
@@ -1928,7 +2123,17 @@ namespace __format
{ return _M_f._M_format(__t, __fc); }
private:
- __format::__formatter_chrono<_CharT> _M_f;
+ static constexpr __format::_ChronoSpec<_CharT> __defSpec = []
+ {
+ __format::_ChronoSpec<_CharT> __res{};
+ __res._M_debug = true;
+ __res._M_localized = true;
+ __res._M_locale_specific = true;
+ __res._M_chrono_specs = __format::_ChronoFormats<_CharT>::_S_wi();
+ return __res;
+ }();
+
+ __format::__formatter_chrono<_CharT> _M_f{__defSpec};
};
template<__format::__char _CharT>
@@ -1936,7 +2141,7 @@ namespace __format
{
constexpr typename basic_format_parse_context<_CharT>::iterator
parse(basic_format_parse_context<_CharT>& __pc)
- { return _M_f._M_parse(__pc, __format::_Weekday); }
+ { return _M_f._M_parse(__pc, __format::_Weekday, __defSpec); }
template<typename _Out>
typename basic_format_context<_Out, _CharT>::iterator
@@ -1945,7 +2150,17 @@ namespace __format
{ return _M_f._M_format(__t, __fc); }
private:
- __format::__formatter_chrono<_CharT> _M_f;
+ static constexpr __format::_ChronoSpec<_CharT> __defSpec = []
+ {
+ __format::_ChronoSpec<_CharT> __res{};
+ __res._M_debug = true;
+ __res._M_localized = true;
+ __res._M_locale_specific = true;
+ __res._M_chrono_specs = __format::_ChronoFormats<_CharT>::_S_wl();
+ return __res;
+ }();
+
+ __format::__formatter_chrono<_CharT> _M_f{__defSpec};
};
template<__format::__char _CharT>
@@ -1953,7 +2168,10 @@ namespace __format
{
constexpr typename basic_format_parse_context<_CharT>::iterator
parse(basic_format_parse_context<_CharT>& __pc)
- { return _M_f._M_parse(__pc, __format::_Month|__format::_Day); }
+ {
+ return _M_f._M_parse(__pc, __format::_Month|__format::_Day,
+ __defSpec);
+ }
template<typename _Out>
typename basic_format_context<_Out, _CharT>::iterator
@@ -1962,7 +2180,17 @@ namespace __format
{ return _M_f._M_format(__t, __fc); }
private:
- __format::__formatter_chrono<_CharT> _M_f;
+ static constexpr __format::_ChronoSpec<_CharT> __defSpec = []
+ {
+ __format::_ChronoSpec<_CharT> __res{};
+ __res._M_debug = true;
+ __res._M_localized = true;
+ __res._M_locale_specific = true;
+ __res._M_chrono_specs = __format::_ChronoFormats<_CharT>::_S_md();
+ return __res;
+ }();
+
+ __format::__formatter_chrono<_CharT> _M_f{__defSpec};
};
template<__format::__char _CharT>
@@ -1970,7 +2198,10 @@ namespace __format
{
constexpr typename basic_format_parse_context<_CharT>::iterator
parse(basic_format_parse_context<_CharT>& __pc)
- { return _M_f._M_parse(__pc, __format::_Month|__format::_Day); }
+ {
+ return _M_f._M_parse(__pc, __format::_Month|__format::_Day,
+ __defSpec);
+ }
template<typename _Out>
typename basic_format_context<_Out, _CharT>::iterator
@@ -1979,7 +2210,17 @@ namespace __format
{ return _M_f._M_format(__t, __fc); }
private:
- __format::__formatter_chrono<_CharT> _M_f;
+ static constexpr __format::_ChronoSpec<_CharT> __defSpec = []
+ {
+ __format::_ChronoSpec<_CharT> __res{};
+ __res._M_debug = true;
+ __res._M_localized = true;
+ __res._M_locale_specific = true;
+ __res._M_chrono_specs = __format::_ChronoFormats<_CharT>::_S_ml();
+ return __res;
+ }();
+
+ __format::__formatter_chrono<_CharT> _M_f{__defSpec};
};
template<__format::__char _CharT>
@@ -1987,7 +2228,10 @@ namespace __format
{
constexpr typename basic_format_parse_context<_CharT>::iterator
parse(basic_format_parse_context<_CharT>& __pc)
- { return _M_f._M_parse(__pc, __format::_Month|__format::_Weekday); }
+ {
+ return _M_f._M_parse(__pc, __format::_Month|__format::_Weekday,
+ __defSpec);
+ }
template<typename _Out>
typename basic_format_context<_Out, _CharT>::iterator
@@ -1996,7 +2240,17 @@ namespace __format
{ return _M_f._M_format(__t, __fc); }
private:
- __format::__formatter_chrono<_CharT> _M_f;
+ static constexpr __format::_ChronoSpec<_CharT> __defSpec = []
+ {
+ __format::_ChronoSpec<_CharT> __res{};
+ __res._M_debug = true;
+ __res._M_localized = true;
+ __res._M_locale_specific = true;
+ __res._M_chrono_specs = __format::_ChronoFormats<_CharT>::_S_mwi();
+ return __res;
+ }();
+
+ __format::__formatter_chrono<_CharT> _M_f{__defSpec};
};
template<__format::__char _CharT>
@@ -2004,7 +2258,10 @@ namespace __format
{
constexpr typename basic_format_parse_context<_CharT>::iterator
parse(basic_format_parse_context<_CharT>& __pc)
- { return _M_f._M_parse(__pc, __format::_Month|__format::_Weekday); }
+ {
+ return _M_f._M_parse(__pc, __format::_Month|__format::_Weekday,
+ __defSpec);
+ }
template<typename _Out>
typename basic_format_context<_Out, _CharT>::iterator
@@ -2013,7 +2270,17 @@ namespace __format
{ return _M_f._M_format(__t, __fc); }
private:
- __format::__formatter_chrono<_CharT> _M_f;
+ static constexpr __format::_ChronoSpec<_CharT> __defSpec = []
+ {
+ __format::_ChronoSpec<_CharT> __res{};
+ __res._M_debug = true;
+ __res._M_localized = true;
+ __res._M_locale_specific = true;
+ __res._M_chrono_specs = __format::_ChronoFormats<_CharT>::_S_mwl();
+ return __res;
+ }();
+
+ __format::__formatter_chrono<_CharT> _M_f{__defSpec};
};
template<__format::__char _CharT>
@@ -2021,7 +2288,10 @@ namespace __format
{
constexpr typename basic_format_parse_context<_CharT>::iterator
parse(basic_format_parse_context<_CharT>& __pc)
- { return _M_f._M_parse(__pc, __format::_Year|__format::_Month); }
+ {
+ return _M_f._M_parse(__pc, __format::_Year|__format::_Month,
+ __defSpec);
+ }
template<typename _Out>
typename basic_format_context<_Out, _CharT>::iterator
@@ -2030,7 +2300,17 @@ namespace __format
{ return _M_f._M_format(__t, __fc); }
private:
- __format::__formatter_chrono<_CharT> _M_f;
+ static constexpr __format::_ChronoSpec<_CharT> __defSpec = []
+ {
+ __format::_ChronoSpec<_CharT> __res{};
+ __res._M_debug = true;
+ __res._M_localized = true;
+ __res._M_locale_specific = true;
+ __res._M_chrono_specs = __format::_ChronoFormats<_CharT>::_S_ym();
+ return __res;
+ }();
+
+ __format::__formatter_chrono<_CharT> _M_f{__defSpec};
};
template<__format::__char _CharT>
@@ -2038,7 +2318,7 @@ namespace __format
{
constexpr typename basic_format_parse_context<_CharT>::iterator
parse(basic_format_parse_context<_CharT>& __pc)
- { return _M_f._M_parse(__pc, __format::_Date); }
+ { return _M_f._M_parse(__pc, __format::_Date, __defSpec); }
template<typename _Out>
typename basic_format_context<_Out, _CharT>::iterator
@@ -2047,7 +2327,15 @@ namespace __format
{ return _M_f._M_format(__t, __fc); }
private:
- __format::__formatter_chrono<_CharT> _M_f;
+ static constexpr __format::_ChronoSpec<_CharT> __defSpec = []
+ {
+ __format::_ChronoSpec<_CharT> __res{};
+ __res._M_debug = true;
+ __res._M_chrono_specs = __format::_ChronoFormats<_CharT>::_S_f();
+ return __res;
+ }();
+
+ __format::__formatter_chrono<_CharT> _M_f{__defSpec};
};
template<__format::__char _CharT>
@@ -2055,7 +2343,7 @@ namespace __format
{
constexpr typename basic_format_parse_context<_CharT>::iterator
parse(basic_format_parse_context<_CharT>& __pc)
- { return _M_f._M_parse(__pc, __format::_Date); }
+ { return _M_f._M_parse(__pc, __format::_Date, __defSpec); }
template<typename _Out>
typename basic_format_context<_Out, _CharT>::iterator
@@ -2064,7 +2352,17 @@ namespace __format
{ return _M_f._M_format(__t, __fc); }
private:
- __format::__formatter_chrono<_CharT> _M_f;
+ static constexpr __format::_ChronoSpec<_CharT> __defSpec = []
+ {
+ __format::_ChronoSpec<_CharT> __res{};
+ __res._M_debug = true;
+ __res._M_localized = true;
+ __res._M_locale_specific = true;
+ __res._M_chrono_specs = __format::_ChronoFormats<_CharT>::_S_yml();
+ return __res;
+ }();
+
+ __format::__formatter_chrono<_CharT> _M_f{__defSpec};
};
template<__format::__char _CharT>
@@ -2072,7 +2370,7 @@ namespace __format
{
constexpr typename basic_format_parse_context<_CharT>::iterator
parse(basic_format_parse_context<_CharT>& __pc)
- { return _M_f._M_parse(__pc, __format::_Date); }
+ { return _M_f._M_parse(__pc, __format::_Date, __defSpec); }
template<typename _Out>
typename basic_format_context<_Out, _CharT>::iterator
@@ -2081,7 +2379,17 @@ namespace __format
{ return _M_f._M_format(__t, __fc); }
private:
- __format::__formatter_chrono<_CharT> _M_f;
+ static constexpr __format::_ChronoSpec<_CharT> __defSpec = []
+ {
+ __format::_ChronoSpec<_CharT> __res{};
+ __res._M_debug = true;
+ __res._M_localized = true;
+ __res._M_locale_specific = true;
+ __res._M_chrono_specs = __format::_ChronoFormats<_CharT>::_S_ymwi();
+ return __res;
+ }();
+
+ __format::__formatter_chrono<_CharT> _M_f{__defSpec};
};
template<__format::__char _CharT>
@@ -2089,7 +2397,7 @@ namespace __format
{
constexpr typename basic_format_parse_context<_CharT>::iterator
parse(basic_format_parse_context<_CharT>& __pc)
- { return _M_f._M_parse(__pc, __format::_Date); }
+ { return _M_f._M_parse(__pc, __format::_Date, __defSpec); }
template<typename _Out>
typename basic_format_context<_Out, _CharT>::iterator
@@ -2098,7 +2406,17 @@ namespace __format
{ return _M_f._M_format(__t, __fc); }
private:
- __format::__formatter_chrono<_CharT> _M_f;
+ static constexpr __format::_ChronoSpec<_CharT> __defSpec = []
+ {
+ __format::_ChronoSpec<_CharT> __res{};
+ __res._M_debug = true;
+ __res._M_localized = true;
+ __res._M_locale_specific = true;
+ __res._M_chrono_specs = __format::_ChronoFormats<_CharT>::_S_ymwl();
+ return __res;
+ }();
+
+ __format::__formatter_chrono<_CharT> _M_f{__defSpec};
};
template<typename _Rep, typename _Period, __format::__char _CharT>
@@ -2106,7 +2424,7 @@ namespace __format
{
constexpr typename basic_format_parse_context<_CharT>::iterator
parse(basic_format_parse_context<_CharT>& __pc)
- { return _M_f._M_parse(__pc, __format::_TimeOfDay); }
+ { return _M_f._M_parse(__pc, __format::_TimeOfDay, __defSpec); }
template<typename _Out>
typename basic_format_context<_Out, _CharT>::iterator
@@ -2115,7 +2433,15 @@ namespace __format
{ return _M_f._M_format(__t, __fc); }
private:
- __format::__formatter_chrono<_CharT> _M_f;
+ static constexpr __format::_ChronoSpec<_CharT> __defSpec = []
+ {
+ __format::_ChronoSpec<_CharT> __res{};
+ __res._M_localized = true;
+ __res._M_chrono_specs = __format::_ChronoFormats<_CharT>::_S_t();
+ return __res;
+ }();
+
+ __format::__formatter_chrono<_CharT> _M_f{__defSpec};
};
#if _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
@@ -2124,16 +2450,16 @@ namespace __format
{
constexpr typename basic_format_parse_context<_CharT>::iterator
parse(basic_format_parse_context<_CharT>& __pc)
- { return _M_f._M_parse(__pc, __format::_ChronoParts{}); }
+ { return _M_f.parse(__pc); }
template<typename _Out>
typename basic_format_context<_Out, _CharT>::iterator
format(const chrono::sys_info& __i,
basic_format_context<_Out, _CharT>& __fc) const
- { return _M_f._M_format(__i, __fc); }
+ { return _M_f.format(__i, __fc); }
private:
- __format::__formatter_chrono<_CharT> _M_f;
+ __format::__formatter_chrono_info<_CharT> _M_f;
};
template<__format::__char _CharT>
@@ -2141,16 +2467,16 @@ namespace __format
{
constexpr typename basic_format_parse_context<_CharT>::iterator
parse(basic_format_parse_context<_CharT>& __pc)
- { return _M_f._M_parse(__pc, __format::_ChronoParts{}); }
+ { return _M_f.parse(__pc); }
template<typename _Out>
typename basic_format_context<_Out, _CharT>::iterator
format(const chrono::local_info& __i,
basic_format_context<_Out, _CharT>& __fc) const
- { return _M_f._M_format(__i, __fc); }
+ { return _M_f.format(__i, __fc); }
private:
- __format::__formatter_chrono<_CharT> _M_f;
+ __format::__formatter_chrono_info<_CharT> _M_f;
};
#endif
@@ -2160,7 +2486,7 @@ namespace __format
constexpr typename basic_format_parse_context<_CharT>::iterator
parse(basic_format_parse_context<_CharT>& __pc)
{
- auto __next = _M_f._M_parse(__pc, __format::_ZonedDateTime);
+ auto __next = _M_f._M_parse(__pc, __format::_ZonedDateTime, __defSpec);
if constexpr (!__stream_insertable)
if (_M_f._M_spec._M_chrono_specs.empty())
__format::__invalid_chrono_spec(); // chrono-specs can't be empty
@@ -2178,7 +2504,22 @@ namespace __format
= requires (basic_ostream<_CharT>& __os,
chrono::sys_time<_Duration> __t) { __os << __t; };
- __format::__formatter_chrono<_CharT> _M_f;
+ static constexpr __format::_ChronoSpec<_CharT> __defSpec = []
+ {
+ __format::_ChronoSpec<_CharT> __res{};
+ if constexpr (!__stream_insertable)
+ return __res;
+ else if constexpr (is_convertible_v<_Duration, chrono::days>)
+ __res._M_chrono_specs = __format::_ChronoFormats<_CharT>::_S_f();
+ else
+ {
+ __res._M_localized = true;
+ __res._M_chrono_specs = __format::_ChronoFormats<_CharT>::_S_ft();
+ }
+ return __res;
+ }();
+
+ __format::__formatter_chrono<_CharT> _M_f{__defSpec};
};
template<typename _Duration, __format::__char _CharT>
@@ -2187,11 +2528,11 @@ namespace __format
{
constexpr typename basic_format_parse_context<_CharT>::iterator
parse(basic_format_parse_context<_CharT>& __pc)
- { return _M_f._M_parse(__pc, __format::_ZonedDateTime); }
+ { return _M_f._M_parse(__pc, __format::_ZonedDateTime, __defSpec); }
template<typename _Out>
- typename basic_format_context<_Out, _CharT>::iterator
- format(const chrono::utc_time<_Duration>& __t,
+ typename basic_format_context<_Out, _CharT>::iterator
+ format(const chrono::utc_time<_Duration>& __t,
basic_format_context<_Out, _CharT>& __fc) const
{
// Adjust by removing leap seconds to get equivalent sys_time.
@@ -2212,7 +2553,15 @@ namespace __format
private:
friend formatter<chrono::__detail::__utc_leap_second<_Duration>, _CharT>;
- __format::__formatter_chrono<_CharT> _M_f;
+ static constexpr __format::_ChronoSpec<_CharT> __defSpec = []
+ {
+ __format::_ChronoSpec<_CharT> __res{};
+ __res._M_localized = true;
+ __res._M_chrono_specs = __format::_ChronoFormats<_CharT>::_S_ft();
+ return __res;
+ }();
+
+ __format::__formatter_chrono<_CharT> _M_f{__defSpec};
};
template<typename _Duration, __format::__char _CharT>
@@ -2221,11 +2570,11 @@ namespace __format
{
constexpr typename basic_format_parse_context<_CharT>::iterator
parse(basic_format_parse_context<_CharT>& __pc)
- { return _M_f._M_parse(__pc, __format::_ZonedDateTime); }
+ { return _M_f._M_parse(__pc, __format::_ZonedDateTime, __defSpec); }
template<typename _Out>
- typename basic_format_context<_Out, _CharT>::iterator
- format(const chrono::tai_time<_Duration>& __t,
+ typename basic_format_context<_Out, _CharT>::iterator
+ format(const chrono::tai_time<_Duration>& __t,
basic_format_context<_Out, _CharT>& __fc) const
{
// Convert to __local_time_fmt with abbrev "TAI" and offset 0s.
@@ -2243,7 +2592,15 @@ namespace __format
}
private:
- __format::__formatter_chrono<_CharT> _M_f;
+ static constexpr __format::_ChronoSpec<_CharT> __defSpec = []
+ {
+ __format::_ChronoSpec<_CharT> __res{};
+ __res._M_localized = true;
+ __res._M_chrono_specs = __format::_ChronoFormats<_CharT>::_S_ft();
+ return __res;
+ }();
+
+ __format::__formatter_chrono<_CharT> _M_f{__defSpec};
};
template<typename _Duration, __format::__char _CharT>
@@ -2252,11 +2609,11 @@ namespace __format
{
constexpr typename basic_format_parse_context<_CharT>::iterator
parse(basic_format_parse_context<_CharT>& __pc)
- { return _M_f._M_parse(__pc, __format::_ZonedDateTime); }
+ { return _M_f._M_parse(__pc, __format::_ZonedDateTime, __defSpec); }
template<typename _Out>
- typename basic_format_context<_Out, _CharT>::iterator
- format(const chrono::gps_time<_Duration>& __t,
+ typename basic_format_context<_Out, _CharT>::iterator
+ format(const chrono::gps_time<_Duration>& __t,
basic_format_context<_Out, _CharT>& __fc) const
{
// Convert to __local_time_fmt with abbrev "GPS" and offset 0s.
@@ -2274,7 +2631,15 @@ namespace __format
}
private:
- __format::__formatter_chrono<_CharT> _M_f;
+ static constexpr __format::_ChronoSpec<_CharT> __defSpec = []
+ {
+ __format::_ChronoSpec<_CharT> __res{};
+ __res._M_localized = true;
+ __res._M_chrono_specs = __format::_ChronoFormats<_CharT>::_S_ft();
+ return __res;
+ }();
+
+ __format::__formatter_chrono<_CharT> _M_f{__defSpec};
};
template<typename _Duration, __format::__char _CharT>
@@ -2282,11 +2647,11 @@ namespace __format
{
constexpr typename basic_format_parse_context<_CharT>::iterator
parse(basic_format_parse_context<_CharT>& __pc)
- { return _M_f._M_parse(__pc, __format::_ZonedDateTime); }
+ { return _M_f._M_parse(__pc, __format::_ZonedDateTime, __defSpec); }
template<typename _Out>
- typename basic_format_context<_Out, _CharT>::iterator
- format(const chrono::file_time<_Duration>& __t,
+ typename basic_format_context<_Out, _CharT>::iterator
+ format(const chrono::file_time<_Duration>& __t,
basic_format_context<_Out, _CharT>& __fc) const
{
using namespace chrono;
@@ -2294,24 +2659,45 @@ namespace __format
}
private:
- __format::__formatter_chrono<_CharT> _M_f;
- };
+ static constexpr __format::_ChronoSpec<_CharT> __defSpec = []
+ {
+ __format::_ChronoSpec<_CharT> __res{};
+ __res._M_localized = true;
+ __res._M_chrono_specs = __format::_ChronoFormats<_CharT>::_S_ft();
+ return __res;
+ }();
+
+ __format::__formatter_chrono<_CharT> _M_f{__defSpec};
+ };
template<typename _Duration, __format::__char _CharT>
struct formatter<chrono::local_time<_Duration>, _CharT>
{
constexpr typename basic_format_parse_context<_CharT>::iterator
parse(basic_format_parse_context<_CharT>& __pc)
- { return _M_f._M_parse(__pc, __format::_DateTime); }
+ { return _M_f._M_parse(__pc, __format::_DateTime, __defSpec); }
template<typename _Out>
- typename basic_format_context<_Out, _CharT>::iterator
- format(const chrono::local_time<_Duration>& __t,
+ typename basic_format_context<_Out, _CharT>::iterator
+ format(const chrono::local_time<_Duration>& __t,
basic_format_context<_Out, _CharT>& __fc) const
{ return _M_f._M_format(__t, __fc); }
private:
- __format::__formatter_chrono<_CharT> _M_f;
+ static constexpr __format::_ChronoSpec<_CharT> __defSpec = []
+ {
+ __format::_ChronoSpec<_CharT> __res{};
+ if constexpr (is_convertible_v<_Duration, chrono::days>)
+ __res._M_chrono_specs = __format::_ChronoFormats<_CharT>::_S_f();
+ else
+ {
+ __res._M_localized = true;
+ __res._M_chrono_specs = __format::_ChronoFormats<_CharT>::_S_ft();
+ }
+ return __res;
+ }();
+
+ __format::__formatter_chrono<_CharT> _M_f{__defSpec};
};
template<typename _Duration, __format::__char _CharT>
@@ -2319,16 +2705,24 @@ namespace __format
{
constexpr typename basic_format_parse_context<_CharT>::iterator
parse(basic_format_parse_context<_CharT>& __pc)
- { return _M_f._M_parse(__pc, __format::_ZonedDateTime); }
+ { return _M_f._M_parse(__pc, __format::_ZonedDateTime, __defSpec); }
template<typename _Out>
- typename basic_format_context<_Out, _CharT>::iterator
- format(const chrono::__detail::__local_time_fmt<_Duration>& __t,
+ typename basic_format_context<_Out, _CharT>::iterator
+ format(const chrono::__detail::__local_time_fmt<_Duration>& __t,
basic_format_context<_Out, _CharT>& __fc) const
- { return _M_f._M_format(__t, __fc, /* use %Z for {} */ true); }
+ { return _M_f._M_format(__t, __fc); }
private:
- __format::__formatter_chrono<_CharT> _M_f;
+ static constexpr __format::_ChronoSpec<_CharT> __defSpec = []
+ {
+ __format::_ChronoSpec<_CharT> __res{};
+ __res._M_localized = true;
+ __res._M_chrono_specs = __format::_ChronoFormats<_CharT>::_S_ftz();
+ return __res;
+ }();
+
+ __format::__formatter_chrono<_CharT> _M_f{__defSpec};
};
#if _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
@@ -2337,8 +2731,8 @@ namespace __format
: formatter<chrono::__detail::__local_time_fmt_for<_Duration>, _CharT>
{
template<typename _Out>
- typename basic_format_context<_Out, _CharT>::iterator
- format(const chrono::zoned_time<_Duration, _TimeZonePtr>& __tp,
+ typename basic_format_context<_Out, _CharT>::iterator
+ format(const chrono::zoned_time<_Duration, _TimeZonePtr>& __tp,
basic_format_context<_Out, _CharT>& __fc) const
{
using _Ltf = chrono::__detail::__local_time_fmt_for<_Duration>;
@@ -2358,8 +2752,8 @@ namespace __format
: formatter<chrono::utc_time<_Duration>, _CharT>
{
template<typename _Out>
- typename basic_format_context<_Out, _CharT>::iterator
- format(const chrono::__detail::__utc_leap_second<_Duration>& __t,
+ typename basic_format_context<_Out, _CharT>::iterator
+ format(const chrono::__detail::__utc_leap_second<_Duration>& __t,
basic_format_context<_Out, _CharT>& __fc) const
{ return this->_M_f._M_format(__t, __fc); }
};
@@ -2944,15 +3338,7 @@ namespace __detail
basic_ostream<_CharT, _Traits>&
operator<<(basic_ostream<_CharT, _Traits>& __os, const sys_info& __i)
{
- // n.b. only decimal separator is locale dependent for specifiers
- // used below, as sys_info uses seconds and minutes duration, the
- // output is locale-independent.
- constexpr auto* __fs
- = _GLIBCXX_WIDEN("[{0:%F %T},{1:%F %T},{2:%T},{3:%Q%q},{0:%Z}]");
- local_seconds __lb(__i.begin.time_since_epoch());
- __os << std::format(__fs, local_time_format(__lb, &__i.abbrev),
- __i.end, __i.offset, __i.save);
- return __os;
+ return __os << std::format(__os.getloc(), _GLIBCXX_WIDEN("{}"), __i);
}
/// Writes a local_info object to an ostream in an unspecified format.
diff --git a/libstdc++-v3/include/bits/formatfwd.h b/libstdc++-v3/include/bits/formatfwd.h
index 777e629..314b55d 100644
--- a/libstdc++-v3/include/bits/formatfwd.h
+++ b/libstdc++-v3/include/bits/formatfwd.h
@@ -162,6 +162,32 @@ namespace __format
using __maybe_const
= __conditional_t<formattable<const _Tp, _CharT>, const _Tp, _Tp>;
}
+
+ // [format.range], formatting of ranges
+ // [format.range.fmtkind], variable template format_kind
+ enum class range_format {
+ disabled,
+ map,
+ set,
+ sequence,
+ string,
+ debug_string
+ };
+
+ /** @brief A constant determining how a range should be formatted.
+ *
+ * The primary template of `std::format_kind` cannot be instantiated.
+ * There is a partial specialization for input ranges and you can
+ * specialize the variable template for your own cv-unqualified types
+ * that satisfy the `ranges::input_range` concept.
+ *
+ * @since C++23
+ */
+ template<typename _Rg>
+ constexpr auto format_kind = []{
+ static_assert(false, "cannot use primary template of 'std::format_kind'");
+ return type_identity<_Rg>{};
+ }();
#endif // format_ranges
_GLIBCXX_END_NAMESPACE_VERSION
diff --git a/libstdc++-v3/include/bits/ranges_algo.h b/libstdc++-v3/include/bits/ranges_algo.h
index a62c3cd..5aca6e8 100644
--- a/libstdc++-v3/include/bits/ranges_algo.h
+++ b/libstdc++-v3/include/bits/ranges_algo.h
@@ -47,28 +47,60 @@ namespace ranges
{
namespace __detail
{
+ template<typename _Fp>
+ using __by_ref_or_value_fn
+ = __conditional_t<is_scalar_v<_Fp> || is_empty_v<_Fp>, _Fp, _Fp&>;
+
template<typename _Comp, typename _Proj>
- constexpr auto
+ struct _Comp_proj
+ {
+ [[no_unique_address]] __by_ref_or_value_fn<_Comp> _M_comp;
+ [[no_unique_address]] __by_ref_or_value_fn<_Proj> _M_proj;
+
+ constexpr
+ _Comp_proj(_Comp& __comp, _Proj& __proj)
+ : _M_comp(__comp), _M_proj(__proj)
+ { }
+
+ template<typename _Tp, typename _Up>
+ constexpr bool
+ operator()(_Tp&& __x, _Up&& __y)
+ {
+ return std::__invoke(_M_comp,
+ std::__invoke(_M_proj, std::forward<_Tp>(__x)),
+ std::__invoke(_M_proj, std::forward<_Up>(__y)));
+ }
+ };
+
+ template<typename _Comp, typename _Proj>
+ constexpr _Comp_proj<_Comp, _Proj>
__make_comp_proj(_Comp& __comp, _Proj& __proj)
+ { return {__comp, __proj}; }
+
+ template<typename _Pred, typename _Proj>
+ struct _Pred_proj
{
- return [&] (auto&& __lhs, auto&& __rhs) -> bool {
- using _TL = decltype(__lhs);
- using _TR = decltype(__rhs);
- return std::__invoke(__comp,
- std::__invoke(__proj, std::forward<_TL>(__lhs)),
- std::__invoke(__proj, std::forward<_TR>(__rhs)));
- };
- }
+ [[no_unique_address]] __by_ref_or_value_fn<_Pred> _M_pred;
+ [[no_unique_address]] __by_ref_or_value_fn<_Proj> _M_proj;
+
+ constexpr
+ _Pred_proj(_Pred& __pred, _Proj& __proj)
+ : _M_pred(__pred), _M_proj(__proj)
+ { }
+
+ template<typename _Tp>
+ constexpr bool
+ operator()(_Tp&& __x)
+ {
+ return std::__invoke(_M_pred,
+ std::__invoke(_M_proj, std::forward<_Tp>(__x)));
+ }
+ };
template<typename _Pred, typename _Proj>
- constexpr auto
+ constexpr _Pred_proj<_Pred, _Proj>
__make_pred_proj(_Pred& __pred, _Proj& __proj)
- {
- return [&] <typename _Tp> (_Tp&& __arg) -> bool {
- return std::__invoke(__pred,
- std::__invoke(__proj, std::forward<_Tp>(__arg)));
- };
- }
+ { return {__pred, __proj}; }
} // namespace __detail
struct __all_of_fn
diff --git a/libstdc++-v3/include/bits/stl_algo.h b/libstdc++-v3/include/bits/stl_algo.h
index 98c2249..3f4674d 100644
--- a/libstdc++-v3/include/bits/stl_algo.h
+++ b/libstdc++-v3/include/bits/stl_algo.h
@@ -2511,7 +2511,7 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
// [first,middle) and [middle,last).
_TmpBuf __buf(__first, std::min(__len1, __len2));
- if (__builtin_expect(__buf.size() == __buf.requested_size(), true))
+ if (__builtin_expect(__buf.size() == __buf._M_requested_size(), true))
std::__merge_adaptive
(__first, __middle, __last, __len1, __len2, __buf.begin(), __comp);
else if (__builtin_expect(__buf.begin() == 0, false))
@@ -5024,7 +5024,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
// so the buffer only needs to fit half the range at once.
_TmpBuf __buf(__first, (__last - __first + 1) / 2);
- if (__builtin_expect(__buf.requested_size() == __buf.size(), true))
+ if (__builtin_expect(__buf._M_requested_size() == __buf.size(), true))
std::__stable_sort_adaptive(__first,
__first + _DistanceType(__buf.size()),
__last, __buf.begin(), __comp);
diff --git a/libstdc++-v3/include/bits/stl_construct.h b/libstdc++-v3/include/bits/stl_construct.h
index 23b8fb7..217a041 100644
--- a/libstdc++-v3/include/bits/stl_construct.h
+++ b/libstdc++-v3/include/bits/stl_construct.h
@@ -82,7 +82,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
if constexpr (__cplusplus > 201703L && is_array_v<_Tp>)
{
for (auto& __x : *__location)
- std::destroy_at(std::__addressof(__x));
+ std::destroy_at(std::addressof(__x));
}
else
__location->~_Tp();
@@ -123,7 +123,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_Construct(_Tp* __p, _Args&&... __args)
{
#if __cpp_constexpr_dynamic_alloc // >= C++20
- if (std::__is_constant_evaluated())
+ if (std::is_constant_evaluated())
{
// Allow std::_Construct to be used in constant expressions.
std::construct_at(__p, std::forward<_Args>(__args)...);
@@ -181,6 +181,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
for (; __first != __last; ++__first)
std::_Destroy(std::__addressof(*__first));
}
+
+ template<typename _ForwardIterator, typename _Size>
+ static _GLIBCXX20_CONSTEXPR _ForwardIterator
+ __destroy_n(_ForwardIterator __first, _Size __count)
+ {
+ for (; __count > 0; (void)++__first, --__count)
+ std::_Destroy(std::__addressof(*__first));
+ return __first;
+ }
};
template<>
@@ -189,6 +198,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _ForwardIterator>
static void
__destroy(_ForwardIterator, _ForwardIterator) { }
+
+ template<typename _ForwardIterator, typename _Size>
+ static _ForwardIterator
+ __destroy_n(_ForwardIterator __first, _Size __count)
+ {
+ std::advance(__first, __count);
+ return __first;
+ }
};
#endif
@@ -204,16 +221,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
typedef typename iterator_traits<_ForwardIterator>::value_type
_Value_type;
#if __cplusplus >= 201103L
- // A deleted destructor is trivial, this ensures we reject such types:
- static_assert(is_destructible<_Value_type>::value,
- "value type is destructible");
- if constexpr (!__has_trivial_destructor(_Value_type))
+ if constexpr (!is_trivially_destructible<_Value_type>::value)
for (; __first != __last; ++__first)
- std::_Destroy(std::__addressof(*__first));
+ std::_Destroy(std::addressof(*__first));
#if __cpp_constexpr_dynamic_alloc // >= C++20
- else if (std::__is_constant_evaluated())
+ else if (std::is_constant_evaluated())
for (; __first != __last; ++__first)
- std::destroy_at(std::__addressof(*__first));
+ std::destroy_at(std::addressof(*__first));
#endif
#else
std::_Destroy_aux<__has_trivial_destructor(_Value_type)>::
@@ -221,33 +235,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
#endif
}
-#if __cplusplus < 201103L
- template<bool>
- struct _Destroy_n_aux
- {
- template<typename _ForwardIterator, typename _Size>
- static _GLIBCXX20_CONSTEXPR _ForwardIterator
- __destroy_n(_ForwardIterator __first, _Size __count)
- {
- for (; __count > 0; (void)++__first, --__count)
- std::_Destroy(std::__addressof(*__first));
- return __first;
- }
- };
-
- template<>
- struct _Destroy_n_aux<true>
- {
- template<typename _ForwardIterator, typename _Size>
- static _ForwardIterator
- __destroy_n(_ForwardIterator __first, _Size __count)
- {
- std::advance(__first, __count);
- return __first;
- }
- };
-#endif
-
/**
* Destroy a range of objects. If the value_type of the object has
* a trivial destructor, the compiler should optimize all of this
@@ -260,22 +247,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
typedef typename iterator_traits<_ForwardIterator>::value_type
_Value_type;
#if __cplusplus >= 201103L
- // A deleted destructor is trivial, this ensures we reject such types:
- static_assert(is_destructible<_Value_type>::value,
- "value type is destructible");
- if constexpr (!__has_trivial_destructor(_Value_type))
+ if constexpr (!is_trivially_destructible<_Value_type>::value)
for (; __count > 0; (void)++__first, --__count)
- std::_Destroy(std::__addressof(*__first));
+ std::_Destroy(std::addressof(*__first));
#if __cpp_constexpr_dynamic_alloc // >= C++20
- else if (std::__is_constant_evaluated())
+ else if (std::is_constant_evaluated())
for (; __count > 0; (void)++__first, --__count)
- std::destroy_at(std::__addressof(*__first));
+ std::destroy_at(std::addressof(*__first));
#endif
else
std::advance(__first, __count);
return __first;
#else
- return std::_Destroy_n_aux<__has_trivial_destructor(_Value_type)>::
+ return std::_Destroy_aux<__has_trivial_destructor(_Value_type)>::
__destroy_n(__first, __count);
#endif
}
diff --git a/libstdc++-v3/include/bits/stl_tempbuf.h b/libstdc++-v3/include/bits/stl_tempbuf.h
index 7a7619e..8cc7b11 100644
--- a/libstdc++-v3/include/bits/stl_tempbuf.h
+++ b/libstdc++-v3/include/bits/stl_tempbuf.h
@@ -227,7 +227,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
/// Returns the size requested by the constructor; may be >size().
size_type
- requested_size() const
+ _M_requested_size() const
{ return _M_original_len; }
/// As per Table mumble.
diff --git a/libstdc++-v3/include/bits/stl_uninitialized.h b/libstdc++-v3/include/bits/stl_uninitialized.h
index b1428db..f4b26cc 100644
--- a/libstdc++-v3/include/bits/stl_uninitialized.h
+++ b/libstdc++-v3/include/bits/stl_uninitialized.h
@@ -118,7 +118,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
~_UninitDestroyGuard()
{
if (__builtin_expect(_M_cur != 0, 0))
+#if __cplusplus == 201703L
+ // std::uninitialized_{value,default}{,_n} can construct array types,
+ // but std::_Destroy cannot handle them until C++20 (PR 120397).
+ _S_destroy(_M_first, *_M_cur);
+#else
std::_Destroy(_M_first, *_M_cur);
+#endif
}
_GLIBCXX20_CONSTEXPR
@@ -129,6 +135,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
private:
_UninitDestroyGuard(const _UninitDestroyGuard&);
+
+#if __cplusplus == 201703L
+ template<typename _Iter>
+ static void
+ _S_destroy(_Iter __first, _Iter __last)
+ {
+ using _ValT = typename iterator_traits<_Iter>::value_type;
+ if constexpr (is_array<_ValT>::value)
+ for (; __first != __last; ++__first)
+ _S_destroy(*__first, *__first + extent<_ValT>::value);
+ else
+ std::_Destroy(__first, __last);
+ }
+#endif
};
// This is the default implementation of std::uninitialized_copy.
@@ -839,7 +859,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{
_UninitDestroyGuard<_ForwardIterator> __guard(__first);
for (; __first != __last; ++__first)
- std::_Construct(std::__addressof(*__first));
+ std::_Construct(std::addressof(*__first));
__guard.release();
}
};
@@ -856,7 +876,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return;
typename iterator_traits<_ForwardIterator>::value_type* __val
- = std::__addressof(*__first);
+ = std::addressof(*__first);
std::_Construct(__val);
if (++__first != __last)
std::fill(__first, __last, *__val);
@@ -873,7 +893,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{
_UninitDestroyGuard<_ForwardIterator> __guard(__first);
for (; __n > 0; --__n, (void) ++__first)
- std::_Construct(std::__addressof(*__first));
+ std::_Construct(std::addressof(*__first));
__guard.release();
return __first;
}
@@ -890,7 +910,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
if (__n > 0)
{
typename iterator_traits<_ForwardIterator>::value_type* __val
- = std::__addressof(*__first);
+ = std::addressof(*__first);
std::_Construct(__val);
++__first;
__first = std::fill_n(__first, __n - 1, *__val);
@@ -955,7 +975,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__alloc);
typedef __gnu_cxx::__alloc_traits<_Allocator> __traits;
for (; __first != __last; ++__first)
- __traits::construct(__alloc, std::__addressof(*__first));
+ __traits::construct(__alloc, std::addressof(*__first));
__guard.release();
}
@@ -980,7 +1000,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__alloc);
typedef __gnu_cxx::__alloc_traits<_Allocator> __traits;
for (; __n > 0; --__n, (void) ++__first)
- __traits::construct(__alloc, std::__addressof(*__first));
+ __traits::construct(__alloc, std::addressof(*__first));
__guard.release();
return __first;
}
@@ -1007,7 +1027,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{
_UninitDestroyGuard<_ForwardIterator> __guard(__first);
for (; __first != __last; ++__first)
- std::_Construct_novalue(std::__addressof(*__first));
+ std::_Construct_novalue(std::addressof(*__first));
__guard.release();
}
};
@@ -1033,7 +1053,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{
_UninitDestroyGuard<_ForwardIterator> __guard(__first);
for (; __n > 0; --__n, (void) ++__first)
- std::_Construct_novalue(std::__addressof(*__first));
+ std::_Construct_novalue(std::addressof(*__first));
__guard.release();
return __first;
}
@@ -1089,7 +1109,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{
_UninitDestroyGuard<_ForwardIterator> __guard(__result);
for (; __n > 0; --__n, (void) ++__first, ++__result)
- std::_Construct(std::__addressof(*__result), *__first);
+ std::_Construct(std::addressof(*__result), *__first);
__guard.release();
return __result;
}
@@ -1112,7 +1132,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{
_UninitDestroyGuard<_ForwardIterator> __guard(__result);
for (; __n > 0; --__n, (void) ++__first, ++__result)
- std::_Construct(std::__addressof(*__result), *__first);
+ std::_Construct(std::addressof(*__result), *__first);
__guard.release();
return {__first, __result};
}
@@ -1276,11 +1296,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
noexcept(noexcept(std::allocator_traits<_Allocator>::construct(__alloc,
__dest, std::move(*__orig)))
&& noexcept(std::allocator_traits<_Allocator>::destroy(
- __alloc, std::__addressof(*__orig))))
+ __alloc, std::addressof(*__orig))))
{
typedef std::allocator_traits<_Allocator> __traits;
__traits::construct(__alloc, __dest, std::move(*__orig));
- __traits::destroy(__alloc, std::__addressof(*__orig));
+ __traits::destroy(__alloc, std::addressof(*__orig));
}
// This class may be specialized for specific types.
@@ -1308,8 +1328,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
"relocation is only possible for values of the same type");
_ForwardIterator __cur = __result;
for (; __first != __last; ++__first, (void)++__cur)
- std::__relocate_object_a(std::__addressof(*__cur),
- std::__addressof(*__first), __alloc);
+ std::__relocate_object_a(std::addressof(*__cur),
+ std::addressof(*__first), __alloc);
return __cur;
}
diff --git a/libstdc++-v3/include/bits/version.def b/libstdc++-v3/include/bits/version.def
index 7cf62e9..880586e 100644
--- a/libstdc++-v3/include/bits/version.def
+++ b/libstdc++-v3/include/bits/version.def
@@ -852,6 +852,14 @@ ftms = {
};
ftms = {
+ name = optional_range_support;
+ values = {
+ v = 202406;
+ cxxmin = 26;
+ };
+};
+
+ftms = {
name = destroying_delete;
values = {
v = 201806;
diff --git a/libstdc++-v3/include/bits/version.h b/libstdc++-v3/include/bits/version.h
index 9f4cf9a..4300adb 100644
--- a/libstdc++-v3/include/bits/version.h
+++ b/libstdc++-v3/include/bits/version.h
@@ -955,6 +955,16 @@
#endif /* !defined(__cpp_lib_optional) && defined(__glibcxx_want_optional) */
#undef __glibcxx_want_optional
+#if !defined(__cpp_lib_optional_range_support)
+# if (__cplusplus > 202302L)
+# define __glibcxx_optional_range_support 202406L
+# if defined(__glibcxx_want_all) || defined(__glibcxx_want_optional_range_support)
+# define __cpp_lib_optional_range_support 202406L
+# endif
+# endif
+#endif /* !defined(__cpp_lib_optional_range_support) && defined(__glibcxx_want_optional_range_support) */
+#undef __glibcxx_want_optional_range_support
+
#if !defined(__cpp_lib_destroying_delete)
# if (__cplusplus >= 202002L) && (__cpp_impl_destroying_delete)
# define __glibcxx_destroying_delete 201806L
diff --git a/libstdc++-v3/include/std/format b/libstdc++-v3/include/std/format
index ec76ab0..46bd5d5 100644
--- a/libstdc++-v3/include/std/format
+++ b/libstdc++-v3/include/std/format
@@ -3114,24 +3114,28 @@ namespace __format
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 3944. Formatters converting sequences of char to sequences of wchar_t
- namespace __format { struct __disabled; }
+ struct __formatter_disabled
+ {
+ __formatter_disabled() = delete; // Cannot format char sequence to wchar_t
+ __formatter_disabled(const __formatter_disabled&) = delete;
+ __formatter_disabled& operator=(const __formatter_disabled&) = delete;
+ };
- // std::formatter<__disabled, C> uses the primary template, which is disabled.
template<>
struct formatter<char*, wchar_t>
- : private formatter<__format::__disabled, wchar_t> { };
+ : private __formatter_disabled { };
template<>
struct formatter<const char*, wchar_t>
- : private formatter<__format::__disabled, wchar_t> { };
+ : private __formatter_disabled { };
template<size_t _Nm>
struct formatter<char[_Nm], wchar_t>
- : private formatter<__format::__disabled, wchar_t> { };
+ : private __formatter_disabled { };
template<class _Traits, class _Allocator>
struct formatter<basic_string<char, _Traits, _Allocator>, wchar_t>
- : private formatter<__format::__disabled, wchar_t> { };
+ : private __formatter_disabled { };
template<class _Traits>
struct formatter<basic_string_view<char, _Traits>, wchar_t>
- : private formatter<__format::__disabled, wchar_t> { };
+ : private __formatter_disabled { };
#endif
/// An iterator after the last character written, and the number of
@@ -5479,32 +5483,6 @@ namespace __format
#endif
#if __glibcxx_format_ranges // C++ >= 23 && HOSTED
- // [format.range], formatting of ranges
- // [format.range.fmtkind], variable template format_kind
- enum class range_format {
- disabled,
- map,
- set,
- sequence,
- string,
- debug_string
- };
-
- /** @brief A constant determining how a range should be formatted.
- *
- * The primary template of `std::format_kind` cannot be instantiated.
- * There is a partial specialization for input ranges and you can
- * specialize the variable template for your own cv-unqualified types
- * that satisfy the `ranges::input_range` concept.
- *
- * @since C++23
- */
- template<typename _Rg>
- constexpr auto format_kind = []{
- static_assert(false, "cannot use primary template of 'std::format_kind'");
- return type_identity<_Rg>{};
- }();
-
/// @cond undocumented
template<typename _Tp>
consteval range_format
diff --git a/libstdc++-v3/include/std/mdspan b/libstdc++-v3/include/std/mdspan
index bcf2fa6..6dc2441 100644
--- a/libstdc++-v3/include/std/mdspan
+++ b/libstdc++-v3/include/std/mdspan
@@ -69,12 +69,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
//
// If __r is the index of a dynamic extent, then
// _S_dynamic_index[__r] is the index of that extent in
- // _M_dynamic_extents.
+ // _M_dyn_exts.
static constexpr auto _S_dynamic_index = [] consteval
{
array<size_t, _S_rank+1> __ret;
size_t __dyn = 0;
- for(size_t __i = 0; __i < _S_rank; ++__i)
+ for (size_t __i = 0; __i < _S_rank; ++__i)
{
__ret[__i] = __dyn;
__dyn += _S_is_dyn(_Extents[__i]);
@@ -105,7 +105,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{
auto __se = _Extents[__r];
if (__se == dynamic_extent)
- return _M_dynamic_extents[_S_dynamic_index[__r]];
+ return _M_dyn_exts[_S_dynamic_index[__r]];
else
return __se;
}
@@ -114,12 +114,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
constexpr void
_M_init_dynamic_extents(_GetOtherExtent __get_extent) noexcept
{
- for(size_t __i = 0; __i < _S_rank_dynamic; ++__i)
+ for (size_t __i = 0; __i < _S_rank_dynamic; ++__i)
{
size_t __di = __i;
if constexpr (_OtherRank != _S_rank_dynamic)
__di = _S_dynamic_index_inv[__i];
- _M_dynamic_extents[__i] = _S_int_cast(__get_extent(__di));
+ _M_dyn_exts[__i] = _S_int_cast(__get_extent(__di));
}
}
@@ -144,9 +144,23 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ return __exts[__i]; });
}
+ static constexpr span<const size_t>
+ _S_static_extents(size_t __begin, size_t __end) noexcept
+ {
+ return {_Extents.data() + __begin, _Extents.data() + __end};
+ }
+
+ constexpr span<const _IndexType>
+ _M_dynamic_extents(size_t __begin, size_t __end) const noexcept
+ requires (_Extents.size() > 0)
+ {
+ return {_M_dyn_exts + _S_dynamic_index[__begin],
+ _M_dyn_exts + _S_dynamic_index[__end]};
+ }
+
private:
using _S_storage = __array_traits<_IndexType, _S_rank_dynamic>::_Type;
- [[no_unique_address]] _S_storage _M_dynamic_extents{};
+ [[no_unique_address]] _S_storage _M_dyn_exts{};
};
template<typename _OIndexType, typename _SIndexType>
@@ -160,6 +174,23 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|| _Extent <= numeric_limits<_IndexType>::max();
}
+ namespace __mdspan
+ {
+ template<typename _Extents>
+ constexpr span<const size_t>
+ __static_extents(size_t __begin = 0, size_t __end = _Extents::rank())
+ noexcept
+ { return _Extents::_S_storage::_S_static_extents(__begin, __end); }
+
+ template<typename _Extents>
+ constexpr span<const typename _Extents::index_type>
+ __dynamic_extents(const _Extents& __exts, size_t __begin = 0,
+ size_t __end = _Extents::rank()) noexcept
+ {
+ return __exts._M_exts._M_dynamic_extents(__begin, __end);
+ }
+ }
+
template<typename _IndexType, size_t... _Extents>
class extents
{
@@ -197,7 +228,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
if constexpr (rank() == 0)
__builtin_trap();
else
- return _M_dynamic_extents._M_extent(__r);
+ return _M_exts._M_extent(__r);
}
constexpr
@@ -233,14 +264,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
requires (_S_is_compatible_extents<_OExtents...>())
constexpr explicit(_S_ctor_explicit<_OIndexType, _OExtents...>())
extents(const extents<_OIndexType, _OExtents...>& __other) noexcept
- : _M_dynamic_extents(__other._M_dynamic_extents)
+ : _M_exts(__other._M_exts)
{ }
template<__mdspan::__valid_index_type<index_type>... _OIndexTypes>
requires (sizeof...(_OIndexTypes) == rank()
|| sizeof...(_OIndexTypes) == rank_dynamic())
constexpr explicit extents(_OIndexTypes... __exts) noexcept
- : _M_dynamic_extents(span<const _IndexType, sizeof...(_OIndexTypes)>(
+ : _M_exts(span<const _IndexType, sizeof...(_OIndexTypes)>(
initializer_list{_S_storage::_S_int_cast(__exts)...}))
{ }
@@ -248,15 +279,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
requires (_Nm == rank() || _Nm == rank_dynamic())
constexpr explicit(_Nm != rank_dynamic())
extents(span<_OIndexType, _Nm> __exts) noexcept
- : _M_dynamic_extents(span<const _OIndexType, _Nm>(__exts))
+ : _M_exts(span<const _OIndexType, _Nm>(__exts))
{ }
-
template<__mdspan::__valid_index_type<index_type> _OIndexType, size_t _Nm>
requires (_Nm == rank() || _Nm == rank_dynamic())
constexpr explicit(_Nm != rank_dynamic())
extents(const array<_OIndexType, _Nm>& __exts) noexcept
- : _M_dynamic_extents(span<const _OIndexType, _Nm>(__exts))
+ : _M_exts(span<const _OIndexType, _Nm>(__exts))
{ }
template<typename _OIndexType, size_t... _OExtents>
@@ -276,9 +306,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
private:
+ friend span<const size_t>
+ __mdspan::__static_extents<extents>(size_t, size_t);
+
+ friend span<const index_type>
+ __mdspan::__dynamic_extents<extents>(const extents&, size_t, size_t);
+
using _S_storage = __mdspan::_ExtentsStorage<
_IndexType, array<size_t, sizeof...(_Extents)>{_Extents...}>;
- [[no_unique_address]] _S_storage _M_dynamic_extents;
+ [[no_unique_address]] _S_storage _M_exts;
template<typename _OIndexType, size_t... _OExtents>
friend class extents;
@@ -286,6 +322,69 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
namespace __mdspan
{
+ template<typename _Tp, size_t _Nm>
+ constexpr bool
+ __contains_zero(span<_Tp, _Nm> __exts) noexcept
+ {
+ for (size_t __i = 0; __i < __exts.size(); ++__i)
+ if (__exts[__i] == 0)
+ return true;
+ return false;
+ }
+
+ template<typename _Extents>
+ constexpr bool
+ __empty(const _Extents& __exts) noexcept
+ {
+ if constexpr (__contains_zero(__static_extents<_Extents>()))
+ return true;
+ else if constexpr (_Extents::rank_dynamic() > 0)
+ return __contains_zero(__dynamic_extents(__exts));
+ else
+ return false;
+ }
+
+ constexpr size_t
+ __static_extents_prod(const auto& __sta_exts) noexcept
+ {
+ size_t __ret = 1;
+ for (auto __factor : __sta_exts)
+ if (__factor != dynamic_extent)
+ __ret *= __factor;
+ return __ret;
+ }
+
+ template<typename _Extents>
+ constexpr typename _Extents::index_type
+ __exts_prod(const _Extents& __exts, size_t __begin, size_t __end) noexcept
+ {
+ using _IndexType = typename _Extents::index_type;
+
+ size_t __ret = 1;
+ if constexpr (_Extents::rank_dynamic() != _Extents::rank())
+ {
+ auto __sta_exts = __static_extents<_Extents>(__begin, __end);
+ __ret = __static_extents_prod(__sta_exts);
+ if (__ret == 0)
+ return 0;
+ }
+
+ if constexpr (_Extents::rank_dynamic() > 0)
+ for (auto __factor : __dynamic_extents(__exts, __begin, __end))
+ __ret *= size_t(__factor);
+ return _IndexType(__ret);
+ }
+
+ template<typename _Extents>
+ constexpr typename _Extents::index_type
+ __fwd_prod(const _Extents& __exts, size_t __r) noexcept
+ { return __exts_prod(__exts, 0, __r); }
+
+ template<typename _Extents>
+ constexpr typename _Extents::index_type
+ __rev_prod(const _Extents& __exts, size_t __r) noexcept
+ { return __exts_prod(__exts, __r + 1, __exts.rank()); }
+
template<typename _IndexType, size_t... _Counts>
auto __build_dextents_type(integer_sequence<size_t, _Counts...>)
-> extents<_IndexType, ((void) _Counts, dynamic_extent)...>;
@@ -304,6 +403,607 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
explicit extents(_Integrals...) ->
extents<size_t, __mdspan::__dynamic_extent<_Integrals>()...>;
+ struct layout_left
+ {
+ template<typename _Extents>
+ class mapping;
+ };
+
+ struct layout_right
+ {
+ template<typename _Extents>
+ class mapping;
+ };
+
+ struct layout_stride
+ {
+ template<typename _Extents>
+ class mapping;
+ };
+
+ namespace __mdspan
+ {
+ template<typename _Tp>
+ constexpr bool __is_extents = false;
+
+ template<typename _IndexType, size_t... _Extents>
+ constexpr bool __is_extents<extents<_IndexType, _Extents...>> = true;
+
+ template<typename _Extents, typename... _Indices>
+ constexpr typename _Extents::index_type
+ __linear_index_left(const _Extents& __exts, _Indices... __indices)
+ noexcept
+ {
+ using _IndexType = typename _Extents::index_type;
+ _IndexType __res = 0;
+ if constexpr (sizeof...(__indices) > 0)
+ {
+ _IndexType __mult = 1;
+ auto __update = [&, __pos = 0u](_IndexType __idx) mutable
+ {
+ __res += __idx * __mult;
+ __mult *= __exts.extent(__pos);
+ ++__pos;
+ };
+ (__update(__indices), ...);
+ }
+ return __res;
+ }
+
+ template<typename _Extents,
+ typename _IndexType = typename _Extents::index_type>
+ consteval _IndexType
+ __static_quotient(_IndexType __nom = numeric_limits<_IndexType>::max())
+ {
+ auto __sta_exts = __static_extents<_Extents>();
+ for (auto __factor : __sta_exts)
+ {
+ if (__factor != dynamic_extent)
+ __nom /= _IndexType(__factor);
+ if (__nom == 0)
+ break;
+ }
+ return __nom;
+ }
+
+ template<typename _Extents>
+ constexpr bool
+ __is_representable_extents(const _Extents& __exts) noexcept
+ {
+ using _IndexType = _Extents::index_type;
+
+ if constexpr (__contains_zero(__static_extents<_Extents>()))
+ return true;
+ else
+ {
+ constexpr auto __sta_quo = __static_quotient<_Extents>();
+ if constexpr (_Extents::rank_dynamic() == 0)
+ return __sta_quo != 0;
+ else
+ {
+ auto __dyn_exts = __dynamic_extents(__exts);
+ if (__contains_zero(__dyn_exts))
+ return true;
+
+ if constexpr (__sta_quo == 0)
+ return false;
+ else
+ {
+ auto __dyn_quo = _IndexType(__sta_quo);
+ for (auto __factor : __dyn_exts)
+ {
+ __dyn_quo /= __factor;
+ if (__dyn_quo == 0)
+ return false;
+ }
+ return true;
+ }
+ }
+ }
+ }
+
+ template<typename _Extents, typename _IndexType>
+ concept __representable_size = _Extents::rank_dynamic() != 0
+ || __contains_zero(__static_extents<_Extents>())
+ || (__static_quotient<_Extents, _IndexType>() != 0);
+
+ template<typename _Layout, typename _Mapping>
+ concept __mapping_of =
+ is_same_v<typename _Layout::mapping<typename _Mapping::extents_type>,
+ _Mapping>;
+
+ template<typename _Mapping>
+ concept __standardized_mapping = __mapping_of<layout_left, _Mapping>
+ || __mapping_of<layout_right, _Mapping>
+ || __mapping_of<layout_stride, _Mapping>;
+
+ // A tag type to create internal ctors.
+ class __internal_ctor
+ { };
+ }
+
+ template<typename _Extents>
+ class layout_left::mapping
+ {
+ public:
+ using extents_type = _Extents;
+ using index_type = typename extents_type::index_type;
+ using size_type = typename extents_type::size_type;
+ using rank_type = typename extents_type::rank_type;
+ using layout_type = layout_left;
+
+ static_assert(__mdspan::__representable_size<extents_type, index_type>,
+ "The size of extents_type must be representable as index_type");
+
+ constexpr
+ mapping() noexcept = default;
+
+ constexpr
+ mapping(const mapping&) noexcept = default;
+
+ constexpr
+ mapping(const extents_type& __extents) noexcept
+ : _M_extents(__extents)
+ { __glibcxx_assert(__mdspan::__is_representable_extents(_M_extents)); }
+
+ template<typename _OExtents>
+ requires is_constructible_v<extents_type, _OExtents>
+ constexpr explicit(!is_convertible_v<_OExtents, extents_type>)
+ mapping(const mapping<_OExtents>& __other) noexcept
+ : mapping(__other.extents(), __mdspan::__internal_ctor{})
+ { }
+
+ template<typename _OExtents>
+ requires (extents_type::rank() <= 1)
+ && is_constructible_v<extents_type, _OExtents>
+ constexpr explicit(!is_convertible_v<_OExtents, extents_type>)
+ mapping(const layout_right::mapping<_OExtents>& __other) noexcept
+ : mapping(__other.extents(), __mdspan::__internal_ctor{})
+ { }
+
+ // noexcept for consistency with other layouts.
+ template<typename _OExtents>
+ requires is_constructible_v<extents_type, _OExtents>
+ constexpr explicit(extents_type::rank() > 0)
+ mapping(const layout_stride::mapping<_OExtents>& __other) noexcept
+ : mapping(__other.extents(), __mdspan::__internal_ctor{})
+ { __glibcxx_assert(*this == __other); }
+
+ constexpr mapping&
+ operator=(const mapping&) noexcept = default;
+
+ constexpr const extents_type&
+ extents() const noexcept { return _M_extents; }
+
+ constexpr index_type
+ required_span_size() const noexcept
+ { return __mdspan::__fwd_prod(_M_extents, extents_type::rank()); }
+
+ template<__mdspan::__valid_index_type<index_type>... _Indices>
+ requires (sizeof...(_Indices) == extents_type::rank())
+ constexpr index_type
+ operator()(_Indices... __indices) const noexcept
+ {
+ return __mdspan::__linear_index_left(_M_extents,
+ static_cast<index_type>(__indices)...);
+ }
+
+ static constexpr bool
+ is_always_unique() noexcept { return true; }
+
+ static constexpr bool
+ is_always_exhaustive() noexcept { return true; }
+
+ static constexpr bool
+ is_always_strided() noexcept { return true; }
+
+ static constexpr bool
+ is_unique() noexcept { return true; }
+
+ static constexpr bool
+ is_exhaustive() noexcept { return true; }
+
+ static constexpr bool
+ is_strided() noexcept { return true; }
+
+ constexpr index_type
+ stride(rank_type __i) const noexcept
+ requires (extents_type::rank() > 0)
+ {
+ __glibcxx_assert(__i < extents_type::rank());
+ return __mdspan::__fwd_prod(_M_extents, __i);
+ }
+
+ template<typename _OExtents>
+ requires (extents_type::rank() == _OExtents::rank())
+ friend constexpr bool
+ operator==(const mapping& __self, const mapping<_OExtents>& __other)
+ noexcept
+ { return __self.extents() == __other.extents(); }
+
+ private:
+ template<typename _OExtents>
+ constexpr explicit
+ mapping(const _OExtents& __oexts, __mdspan::__internal_ctor) noexcept
+ : _M_extents(__oexts)
+ {
+ static_assert(__mdspan::__representable_size<_OExtents, index_type>,
+ "The size of OtherExtents must be representable as index_type");
+ __glibcxx_assert(__mdspan::__is_representable_extents(_M_extents));
+ }
+
+ [[no_unique_address]] extents_type _M_extents{};
+ };
+
+ namespace __mdspan
+ {
+ template<typename _Extents, typename... _Indices>
+ constexpr typename _Extents::index_type
+ __linear_index_right(const _Extents& __exts, _Indices... __indices)
+ noexcept
+ {
+ using _IndexType = typename _Extents::index_type;
+ array<_IndexType, sizeof...(__indices)> __ind_arr{__indices...};
+ _IndexType __res = 0;
+ if constexpr (sizeof...(__indices) > 0)
+ {
+ _IndexType __mult = 1;
+ auto __update = [&, __pos = __exts.rank()](_IndexType) mutable
+ {
+ --__pos;
+ __res += __ind_arr[__pos] * __mult;
+ __mult *= __exts.extent(__pos);
+ };
+ (__update(__indices), ...);
+ }
+ return __res;
+ }
+ }
+
+ template<typename _Extents>
+ class layout_right::mapping
+ {
+ public:
+ using extents_type = _Extents;
+ using index_type = typename extents_type::index_type;
+ using size_type = typename extents_type::size_type;
+ using rank_type = typename extents_type::rank_type;
+ using layout_type = layout_right;
+
+ static_assert(__mdspan::__representable_size<extents_type, index_type>,
+ "The size of extents_type must be representable as index_type");
+
+ constexpr
+ mapping() noexcept = default;
+
+ constexpr
+ mapping(const mapping&) noexcept = default;
+
+ constexpr
+ mapping(const extents_type& __extents) noexcept
+ : _M_extents(__extents)
+ { __glibcxx_assert(__mdspan::__is_representable_extents(_M_extents)); }
+
+ template<typename _OExtents>
+ requires is_constructible_v<extents_type, _OExtents>
+ constexpr explicit(!is_convertible_v<_OExtents, extents_type>)
+ mapping(const mapping<_OExtents>& __other) noexcept
+ : mapping(__other.extents(), __mdspan::__internal_ctor{})
+ { }
+
+ template<typename _OExtents>
+ requires (extents_type::rank() <= 1)
+ && is_constructible_v<extents_type, _OExtents>
+ constexpr explicit(!is_convertible_v<_OExtents, extents_type>)
+ mapping(const layout_left::mapping<_OExtents>& __other) noexcept
+ : mapping(__other.extents(), __mdspan::__internal_ctor{})
+ { }
+
+ template<typename _OExtents>
+ requires is_constructible_v<extents_type, _OExtents>
+ constexpr explicit(extents_type::rank() > 0)
+ mapping(const layout_stride::mapping<_OExtents>& __other) noexcept
+ : mapping(__other.extents(), __mdspan::__internal_ctor{})
+ { __glibcxx_assert(*this == __other); }
+
+ constexpr mapping&
+ operator=(const mapping&) noexcept = default;
+
+ constexpr const extents_type&
+ extents() const noexcept { return _M_extents; }
+
+ constexpr index_type
+ required_span_size() const noexcept
+ { return __mdspan::__fwd_prod(_M_extents, extents_type::rank()); }
+
+ template<__mdspan::__valid_index_type<index_type>... _Indices>
+ requires (sizeof...(_Indices) == extents_type::rank())
+ constexpr index_type
+ operator()(_Indices... __indices) const noexcept
+ {
+ return __mdspan::__linear_index_right(
+ _M_extents, static_cast<index_type>(__indices)...);
+ }
+
+ static constexpr bool
+ is_always_unique() noexcept
+ { return true; }
+
+ static constexpr bool
+ is_always_exhaustive() noexcept
+ { return true; }
+
+ static constexpr bool
+ is_always_strided() noexcept
+ { return true; }
+
+ static constexpr bool
+ is_unique() noexcept
+ { return true; }
+
+ static constexpr bool
+ is_exhaustive() noexcept
+ { return true; }
+
+ static constexpr bool
+ is_strided() noexcept
+ { return true; }
+
+ constexpr index_type
+ stride(rank_type __i) const noexcept
+ requires (extents_type::rank() > 0)
+ {
+ __glibcxx_assert(__i < extents_type::rank());
+ return __mdspan::__rev_prod(_M_extents, __i);
+ }
+
+ template<typename _OExtents>
+ requires (extents_type::rank() == _OExtents::rank())
+ friend constexpr bool
+ operator==(const mapping& __self, const mapping<_OExtents>& __other)
+ noexcept
+ { return __self.extents() == __other.extents(); }
+
+ private:
+ template<typename _OExtents>
+ constexpr explicit
+ mapping(const _OExtents& __oexts, __mdspan::__internal_ctor) noexcept
+ : _M_extents(__oexts)
+ {
+ static_assert(__mdspan::__representable_size<_OExtents, index_type>,
+ "The size of OtherExtents must be representable as index_type");
+ __glibcxx_assert(__mdspan::__is_representable_extents(_M_extents));
+ }
+
+ [[no_unique_address]] extents_type _M_extents{};
+ };
+
+ namespace __mdspan
+ {
+ template<typename _Mp>
+ concept __mapping_alike = requires
+ {
+ requires __is_extents<typename _Mp::extents_type>;
+ { _Mp::is_always_strided() } -> same_as<bool>;
+ { _Mp::is_always_exhaustive() } -> same_as<bool>;
+ { _Mp::is_always_unique() } -> same_as<bool>;
+ bool_constant<_Mp::is_always_strided()>::value;
+ bool_constant<_Mp::is_always_exhaustive()>::value;
+ bool_constant<_Mp::is_always_unique()>::value;
+ };
+
+ template<typename _Mapping>
+ constexpr typename _Mapping::index_type
+ __offset(const _Mapping& __m) noexcept
+ {
+ using _IndexType = typename _Mapping::index_type;
+ constexpr auto __rank = _Mapping::extents_type::rank();
+
+ if constexpr (__standardized_mapping<_Mapping>)
+ return 0;
+ else if (__empty(__m.extents()))
+ return 0;
+ else
+ {
+ auto __impl = [&__m]<size_t... _Counts>(index_sequence<_Counts...>)
+ { return __m(((void) _Counts, _IndexType(0))...); };
+ return __impl(make_index_sequence<__rank>());
+ }
+ }
+
+ template<typename _Mapping, typename... _Indices>
+ constexpr typename _Mapping::index_type
+ __linear_index_strides(const _Mapping& __m, _Indices... __indices)
+ noexcept
+ {
+ using _IndexType = typename _Mapping::index_type;
+ _IndexType __res = 0;
+ if constexpr (sizeof...(__indices) > 0)
+ {
+ auto __update = [&, __pos = 0u](_IndexType __idx) mutable
+ {
+ __res += __idx * __m.stride(__pos++);
+ };
+ (__update(__indices), ...);
+ }
+ return __res;
+ }
+ }
+
+ template<typename _Extents>
+ class layout_stride::mapping
+ {
+ public:
+ using extents_type = _Extents;
+ using index_type = typename extents_type::index_type;
+ using size_type = typename extents_type::size_type;
+ using rank_type = typename extents_type::rank_type;
+ using layout_type = layout_stride;
+
+ static_assert(__mdspan::__representable_size<extents_type, index_type>,
+ "The size of extents_type must be representable as index_type");
+
+ constexpr
+ mapping() noexcept
+ {
+ // The precondition is either statically asserted, or automatically
+ // satisfied because dynamic extents are zero-initialized.
+ size_t __stride = 1;
+ for (size_t __i = extents_type::rank(); __i > 0; --__i)
+ {
+ _M_strides[__i - 1] = index_type(__stride);
+ __stride *= size_t(_M_extents.extent(__i - 1));
+ }
+ }
+
+ constexpr
+ mapping(const mapping&) noexcept = default;
+
+ template<__mdspan::__valid_index_type<index_type> _OIndexType>
+ constexpr
+ mapping(const extents_type& __exts,
+ span<_OIndexType, extents_type::rank()> __strides) noexcept
+ : _M_extents(__exts)
+ {
+ for (size_t __i = 0; __i < extents_type::rank(); ++__i)
+ _M_strides[__i] = index_type(as_const(__strides[__i]));
+ }
+
+ template<__mdspan::__valid_index_type<index_type> _OIndexType>
+ constexpr
+ mapping(const extents_type& __exts,
+ const array<_OIndexType, extents_type::rank()>& __strides)
+ noexcept
+ : mapping(__exts,
+ span<const _OIndexType, extents_type::rank()>(__strides))
+ { }
+
+ template<__mdspan::__mapping_alike _StridedMapping>
+ requires (is_constructible_v<extents_type,
+ typename _StridedMapping::extents_type>
+ && _StridedMapping::is_always_unique()
+ && _StridedMapping::is_always_strided())
+ constexpr explicit(!(
+ is_convertible_v<typename _StridedMapping::extents_type, extents_type>
+ && __mdspan::__standardized_mapping<_StridedMapping>))
+ mapping(const _StridedMapping& __other) noexcept
+ : _M_extents(__other.extents())
+ {
+ using _OIndexType = _StridedMapping::index_type;
+ using _OExtents = _StridedMapping::extents_type;
+
+ __glibcxx_assert(__mdspan::__offset(__other) == 0);
+ static_assert(__mdspan::__representable_size<_OExtents, index_type>,
+ "The size of StridedMapping::extents_type must be representable as"
+ " index_type");
+ if constexpr (cmp_greater(numeric_limits<_OIndexType>::max(),
+ numeric_limits<index_type>::max()))
+ __glibcxx_assert(!cmp_less(numeric_limits<index_type>::max(),
+ __other.required_span_size())
+ && "other.required_span_size() must be representable"
+ " as index_type");
+ if constexpr (extents_type::rank() > 0)
+ for (size_t __i = 0; __i < extents_type::rank(); ++__i)
+ _M_strides[__i] = index_type(__other.stride(__i));
+ }
+
+ constexpr mapping&
+ operator=(const mapping&) noexcept = default;
+
+ constexpr const extents_type&
+ extents() const noexcept { return _M_extents; }
+
+ constexpr array<index_type, extents_type::rank()>
+ strides() const noexcept
+ {
+ array<index_type, extents_type::rank()> __ret;
+ for (size_t __i = 0; __i < extents_type::rank(); ++__i)
+ __ret[__i] = _M_strides[__i];
+ return __ret;
+ }
+
+ constexpr index_type
+ required_span_size() const noexcept
+ {
+ if (__mdspan::__empty(_M_extents))
+ return 0;
+
+ index_type __ret = 1;
+ for (size_t __i = 0; __i < extents_type::rank(); ++__i)
+ __ret += (_M_extents.extent(__i) - 1) * _M_strides[__i];
+ return __ret;
+ }
+
+ template<__mdspan::__valid_index_type<index_type>... _Indices>
+ requires (sizeof...(_Indices) == extents_type::rank())
+ constexpr index_type
+ operator()(_Indices... __indices) const noexcept
+ {
+ return __mdspan::__linear_index_strides(*this,
+ static_cast<index_type>(__indices)...);
+ }
+
+ static constexpr bool
+ is_always_unique() noexcept { return true; }
+
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 4266. layout_stride::mapping should treat empty mappings as exhaustive
+ static constexpr bool
+ is_always_exhaustive() noexcept
+ {
+ return (_Extents::rank() == 0) || __mdspan::__contains_zero(
+ __mdspan::__static_extents<extents_type>());
+ }
+
+ static constexpr bool
+ is_always_strided() noexcept { return true; }
+
+ static constexpr bool
+ is_unique() noexcept { return true; }
+
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 4266. layout_stride::mapping should treat empty mappings as exhaustive
+ constexpr bool
+ is_exhaustive() const noexcept
+ {
+ if constexpr (!is_always_exhaustive())
+ {
+ constexpr auto __rank = extents_type::rank();
+ auto __size = __mdspan::__fwd_prod(_M_extents, __rank);
+ if(__size > 0)
+ return __size == required_span_size();
+ }
+ return true;
+ }
+
+ static constexpr bool
+ is_strided() noexcept { return true; }
+
+ constexpr index_type
+ stride(rank_type __r) const noexcept { return _M_strides[__r]; }
+
+ template<__mdspan::__mapping_alike _OMapping>
+ requires ((extents_type::rank() == _OMapping::extents_type::rank())
+ && _OMapping::is_always_strided())
+ friend constexpr bool
+ operator==(const mapping& __self, const _OMapping& __other) noexcept
+ {
+ if (__self.extents() != __other.extents())
+ return false;
+ if constexpr (extents_type::rank() > 0)
+ for (size_t __i = 0; __i < extents_type::rank(); ++__i)
+ if (!cmp_equal(__self.stride(__i), __other.stride(__i)))
+ return false;
+ return __mdspan::__offset(__other) == 0;
+ }
+
+ private:
+ using _S_strides_t = typename __array_traits<index_type,
+ extents_type::rank()>::_Type;
+ [[no_unique_address]] extents_type _M_extents;
+ [[no_unique_address]] _S_strides_t _M_strides;
+ };
+
_GLIBCXX_END_NAMESPACE_VERSION
}
#endif
diff --git a/libstdc++-v3/include/std/optional b/libstdc++-v3/include/std/optional
index a616dc0..cc7af5b 100644
--- a/libstdc++-v3/include/std/optional
+++ b/libstdc++-v3/include/std/optional
@@ -36,6 +36,7 @@
#define __glibcxx_want_freestanding_optional
#define __glibcxx_want_optional
+#define __glibcxx_want_optional_range_support
#define __glibcxx_want_constrained_equality
#include <bits/version.h>
@@ -57,6 +58,11 @@
#if __cplusplus > 202002L
# include <concepts>
#endif
+#ifdef __cpp_lib_optional_range_support // C++ >= 26
+# include <bits/formatfwd.h>
+# include <bits/ranges_base.h>
+# include <bits/stl_iterator.h>
+#endif
namespace std _GLIBCXX_VISIBILITY(default)
{
@@ -858,6 +864,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
public:
using value_type = _Tp;
+#ifdef __cpp_lib_optional_range_support // >= C++26
+ using iterator = __gnu_cxx::__normal_iterator<_Tp*, optional>;
+ using const_iterator = __gnu_cxx::__normal_iterator<const _Tp*, optional>;
+#endif
constexpr optional() noexcept { }
@@ -1158,6 +1168,33 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
}
+#ifdef __cpp_lib_optional_range_support // >= C++26
+ // Iterator support.
+ constexpr iterator begin() noexcept
+ {
+ return iterator(
+ this->_M_is_engaged() ? std::addressof(this->_M_get()) : nullptr
+ );
+ }
+
+ constexpr const_iterator begin() const noexcept
+ {
+ return const_iterator(
+ this->_M_is_engaged() ? std::addressof(this->_M_get()) : nullptr
+ );
+ }
+
+ constexpr iterator end() noexcept
+ {
+ return begin() + has_value();
+ }
+
+ constexpr const_iterator end() const noexcept
+ {
+ return begin() + has_value();
+ }
+#endif // __cpp_lib_optional_range_support
+
// Observers.
constexpr const _Tp*
operator->() const noexcept
@@ -1772,6 +1809,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template <typename _Tp> optional(_Tp) -> optional<_Tp>;
#endif
+#ifdef __cpp_lib_optional_range_support // >= C++26
+ template<typename _Tp>
+ inline constexpr bool
+ ranges::enable_view<optional<_Tp>> = true;
+
+ template<typename _Tp>
+ inline constexpr range_format
+ format_kind<optional<_Tp>> = range_format::disabled;
+#endif // __cpp_lib_optional_range_support
+
#undef _GLIBCXX_USE_CONSTRAINTS_FOR_OPTIONAL
_GLIBCXX_END_NAMESPACE_VERSION
diff --git a/libstdc++-v3/include/std/sstream b/libstdc++-v3/include/std/sstream
index aee0986..b1b4126 100644
--- a/libstdc++-v3/include/std/sstream
+++ b/libstdc++-v3/include/std/sstream
@@ -165,7 +165,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
{ __rhs._M_sync(const_cast<char_type*>(__rhs._M_string.data()), 0, 0); }
#if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI
- // P0408 Efficient access to basic_stringbuf buffer
+ // P0408 Efficient access to basic_stringbuf buffer
explicit
basic_stringbuf(const allocator_type& __a)
: basic_stringbuf(ios_base::in | std::ios_base::out, __a)
@@ -233,7 +233,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
#endif // C++26
#if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI
- // P0408 Efficient access to basic_stringbuf buffer
+ // P0408 Efficient access to basic_stringbuf buffer
basic_stringbuf(basic_stringbuf&& __rhs, const allocator_type& __a)
: basic_stringbuf(std::move(__rhs), __a, __xfer_bufptrs(__rhs, this))
{ __rhs._M_sync(const_cast<char_type*>(__rhs._M_string.data()), 0, 0); }
@@ -572,7 +572,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
{ }
#if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI
- // P0408 Efficient access to basic_stringbuf buffer
+ // P0408 Efficient access to basic_stringbuf buffer
// The move constructor initializes an __xfer_bufptrs temporary then
// delegates to this constructor to performs moves during its lifetime.
@@ -693,7 +693,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
{ __istream_type::set_rdbuf(std::__addressof(_M_stringbuf)); }
#if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI
- // P0408 Efficient access to basic_stringbuf buffer
+ // P0408 Efficient access to basic_stringbuf buffer
basic_istringstream(ios_base::openmode __mode, const allocator_type& __a)
: __istream_type(), _M_stringbuf(__mode | ios_base::in, __a)
{ this->init(std::__addressof(_M_stringbuf)); }
@@ -959,7 +959,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
{ __ostream_type::set_rdbuf(std::__addressof(_M_stringbuf)); }
#if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI
- // P0408 Efficient access to basic_stringbuf buffer
+ // P0408 Efficient access to basic_stringbuf buffer
basic_ostringstream(ios_base::openmode __mode, const allocator_type& __a)
: __ostream_type(), _M_stringbuf(__mode | ios_base::out, __a)
{ this->init(std::__addressof(_M_stringbuf)); }
@@ -1221,7 +1221,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
{ __iostream_type::set_rdbuf(std::__addressof(_M_stringbuf)); }
#if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI
- // P0408 Efficient access to basic_stringbuf buffer
+ // P0408 Efficient access to basic_stringbuf buffer
basic_stringstream(ios_base::openmode __mode, const allocator_type& __a)
: __iostream_type(), _M_stringbuf(__mode, __a)
{ this->init(std::__addressof(_M_stringbuf)); }
diff --git a/libstdc++-v3/include/std/type_traits b/libstdc++-v3/include/std/type_traits
index c8907fe..abff9f8 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -1036,6 +1036,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
struct __is_array_unknown_bounds<_Tp[]>
: public true_type
{ };
+ /// @endcond
// Destructible and constructible type properties.
@@ -1046,6 +1047,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
: public __bool_constant<__is_destructible(_Tp)>
{ };
#else
+ /// @cond undocumented
+
// In N3290 is_destructible does not say anything about function
// types and abstract types, see LWG 2049. This implementation
// describes function types as non-destructible and all complete