Skip to content

Commit ef29eab

Browse files
author
Tomasz Kamiński
committed
libstdc++: Adjust enable_nonlocking_formatter_optimization specializations [PR121790]
This patch addresses several issues related to the additional specializations for enable_nonlocking_formatter_optimization fomr P3235R3 proposal: * LWG4399 [1]: Apply remove_cvref_t to tuple and pair elements when checking if the direct printing optimization is enabled. * LWG4398 [2]: Disable the direct printing optimization for the standard library container adaptors: queue, priority_queue, and stack. * LWG4400 [3]: Enable the direct printing optimization only for durations that use standard arithmetic types. Conditionally enable it for hh_mm_ss and time_points based on their underlying Duration template argument. [1] https://cplusplus.github.io/LWG/issue4399 [2] https://cplusplus.github.io/LWG/issue4398 [3] https://cplusplus.github.io/LWG/issue4400 PR libstdc++/121790 libstdc++-v3/ChangeLog: * include/bits/chrono_io.h (enable_nonlocking_formatter_optimization): Adjust specializations for duration, hh_mm_ss and time_points. * include/std/format (enable_nonlocking_formatter_optimization): Apply remove_cvref_t on pair and tuple elements. * include/std/queue (enable_nonlocking_formatter_optimization): Change specialization value to false. * include/std/stack (enable_nonlocking_formatter_optimization): Change specialization value to false. * testsuite/std/format/ranges/adaptors.cc: Adjusted tests. * testsuite/std/format/tuple.cc: Adjusted tests. * testsuite/std/time/format/nonlocking.cc: Adjusted tests. Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
1 parent c8b388a commit ef29eab

File tree

7 files changed

+102
-77
lines changed

7 files changed

+102
-77
lines changed

libstdc++-v3/include/bits/chrono_io.h

Lines changed: 60 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -561,7 +561,7 @@ namespace __format
561561
__formatter_chrono(_ChronoSpec<_CharT> __spec) noexcept
562562
: _M_spec(__spec)
563563
{ }
564-
564+
565565
constexpr typename basic_format_parse_context<_CharT>::iterator
566566
_M_parse(basic_format_parse_context<_CharT>& __pc, _ChronoParts __parts,
567567
const _ChronoSpec<_CharT>& __def)
@@ -2235,10 +2235,12 @@ namespace __format
22352235
};
22362236

22372237
#if __glibcxx_print >= 202406L
2238+
// _GLIBCXX_RESOLVE_LIB_DEFECTS
2239+
// 4400. enable_nonlocking_formatter_optimization for durations with custom rep
22382240
template<typename _Rep, typename _Period>
22392241
constexpr bool
22402242
enable_nonlocking_formatter_optimization<chrono::duration<_Rep, _Period>>
2241-
= enable_nonlocking_formatter_optimization<_Rep>;
2243+
= is_arithmetic_v<_Rep>;
22422244
#endif
22432245

22442246
template<__format::__char _CharT>
@@ -2988,10 +2990,12 @@ namespace __format
29882990
};
29892991

29902992
#if __glibcxx_print >= 202406L
2991-
template<typename _Duration>
2992-
constexpr bool
2993-
enable_nonlocking_formatter_optimization<chrono::hh_mm_ss<_Duration>>
2994-
= true;
2993+
// _GLIBCXX_RESOLVE_LIB_DEFECTS
2994+
// 4400. enable_nonlocking_formatter_optimization for durations with custom rep
2995+
template<typename _Duration>
2996+
constexpr bool
2997+
enable_nonlocking_formatter_optimization<chrono::hh_mm_ss<_Duration>>
2998+
= enable_nonlocking_formatter_optimization<_Duration>;
29952999
#endif
29963000

29973001
#if _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
@@ -3079,10 +3083,12 @@ namespace __format
30793083
};
30803084

30813085
#if __glibcxx_print >= 202406L
3082-
template<typename _Duration>
3083-
constexpr bool
3084-
enable_nonlocking_formatter_optimization<chrono::sys_time<_Duration>>
3085-
= true;
3086+
// _GLIBCXX_RESOLVE_LIB_DEFECTS
3087+
// 4400. enable_nonlocking_formatter_optimization for durations with custom rep
3088+
template<typename _Duration>
3089+
constexpr bool
3090+
enable_nonlocking_formatter_optimization<chrono::sys_time<_Duration>>
3091+
= enable_nonlocking_formatter_optimization<_Duration>;
30863092
#endif
30873093

30883094
template<typename _Duration, __format::__char _CharT>
@@ -3130,10 +3136,12 @@ namespace __format
31303136
};
31313137

31323138
#if __glibcxx_print >= 202406L
3133-
template<typename _Duration>
3134-
constexpr bool
3135-
enable_nonlocking_formatter_optimization<chrono::utc_time<_Duration>>
3136-
= true;
3139+
// _GLIBCXX_RESOLVE_LIB_DEFECTS
3140+
// 4400. enable_nonlocking_formatter_optimization for durations with custom rep
3141+
template<typename _Duration>
3142+
constexpr bool
3143+
enable_nonlocking_formatter_optimization<chrono::utc_time<_Duration>>
3144+
= enable_nonlocking_formatter_optimization<_Duration>;
31373145
#endif
31383146

31393147
template<typename _Duration, __format::__char _CharT>
@@ -3172,10 +3180,12 @@ namespace __format
31723180
};
31733181

31743182
#if __glibcxx_print >= 202406L
3175-
template<typename _Duration>
3176-
constexpr bool
3177-
enable_nonlocking_formatter_optimization<chrono::tai_time<_Duration>>
3178-
= true;
3183+
// _GLIBCXX_RESOLVE_LIB_DEFECTS
3184+
// 4400. enable_nonlocking_formatter_optimization for durations with custom rep
3185+
template<typename _Duration>
3186+
constexpr bool
3187+
enable_nonlocking_formatter_optimization<chrono::tai_time<_Duration>>
3188+
= enable_nonlocking_formatter_optimization<_Duration>;
31793189
#endif
31803190

31813191
template<typename _Duration, __format::__char _CharT>
@@ -3214,10 +3224,12 @@ namespace __format
32143224
};
32153225

32163226
#if __glibcxx_print >= 202406L
3217-
template<typename _Duration>
3218-
constexpr bool
3219-
enable_nonlocking_formatter_optimization<chrono::gps_time<_Duration>>
3220-
= true;
3227+
// _GLIBCXX_RESOLVE_LIB_DEFECTS
3228+
// 4400. enable_nonlocking_formatter_optimization for durations with custom rep
3229+
template<typename _Duration>
3230+
constexpr bool
3231+
enable_nonlocking_formatter_optimization<chrono::gps_time<_Duration>>
3232+
= enable_nonlocking_formatter_optimization<_Duration>;
32213233
#endif
32223234

32233235
template<typename _Duration, __format::__char _CharT>
@@ -3256,10 +3268,12 @@ namespace __format
32563268
};
32573269

32583270
#if __glibcxx_print >= 202406L
3259-
template<typename _Duration>
3260-
constexpr bool
3261-
enable_nonlocking_formatter_optimization<chrono::file_time<_Duration>>
3262-
= true;
3271+
// _GLIBCXX_RESOLVE_LIB_DEFECTS
3272+
// 4400. enable_nonlocking_formatter_optimization for durations with custom rep
3273+
template<typename _Duration>
3274+
constexpr bool
3275+
enable_nonlocking_formatter_optimization<chrono::file_time<_Duration>>
3276+
= enable_nonlocking_formatter_optimization<_Duration>;
32633277
#endif
32643278

32653279
template<typename _Duration, __format::__char _CharT>
@@ -3297,10 +3311,12 @@ namespace __format
32973311
};
32983312

32993313
#if __glibcxx_print >= 202406L
3300-
template<typename _Duration>
3301-
constexpr bool
3302-
enable_nonlocking_formatter_optimization<chrono::local_time<_Duration>>
3303-
= true;
3314+
// _GLIBCXX_RESOLVE_LIB_DEFECTS
3315+
// 4400. enable_nonlocking_formatter_optimization for durations with custom rep
3316+
template<typename _Duration>
3317+
constexpr bool
3318+
enable_nonlocking_formatter_optimization<chrono::local_time<_Duration>>
3319+
= enable_nonlocking_formatter_optimization<_Duration>;
33043320
#endif
33053321

33063322
template<typename _Duration, __format::__char _CharT>
@@ -3364,10 +3380,13 @@ namespace __format
33643380
};
33653381

33663382
#if __glibcxx_print >= 202406L
3367-
template<typename _Duration>
3368-
constexpr bool
3369-
enable_nonlocking_formatter_optimization<
3370-
chrono::__detail::__local_time_fmt<_Duration>> = true;
3383+
// _GLIBCXX_RESOLVE_LIB_DEFECTS
3384+
// 4400. enable_nonlocking_formatter_optimization for durations with custom rep
3385+
template<typename _Duration>
3386+
constexpr bool
3387+
enable_nonlocking_formatter_optimization<
3388+
chrono::__detail::__local_time_fmt<_Duration>>
3389+
= enable_nonlocking_formatter_optimization<_Duration>;
33713390
#endif
33723391

33733392
#if _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
@@ -3391,10 +3410,13 @@ namespace __format
33913410
};
33923411

33933412
#if __glibcxx_print >= 202406L
3394-
template<typename _Duration>
3395-
constexpr bool
3396-
enable_nonlocking_formatter_optimization<
3397-
chrono::zoned_time<_Duration, const chrono::time_zone*>> = true;
3413+
// _GLIBCXX_RESOLVE_LIB_DEFECTS
3414+
// 4400. enable_nonlocking_formatter_optimization for durations with custom rep
3415+
template<typename _Duration>
3416+
constexpr bool
3417+
enable_nonlocking_formatter_optimization<
3418+
chrono::zoned_time<_Duration, const chrono::time_zone*>>
3419+
= enable_nonlocking_formatter_optimization<_Duration>;
33983420
#endif
33993421
#endif
34003422

libstdc++-v3/include/std/format

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5873,11 +5873,12 @@ namespace __format
58735873
};
58745874

58755875
#if __glibcxx_print >= 202406L
5876+
// _GLIBCXX_RESOLVE_LIB_DEFECTS
5877+
// 4399. enable_nonlocking_formatter_optimization for pair and tuple needs remove_cvref_t
58765878
template<typename _Fp, typename _Sp>
58775879
constexpr bool enable_nonlocking_formatter_optimization<pair<_Fp, _Sp>>
5878-
// TODO this should have remove_cvref_t.
5879-
= enable_nonlocking_formatter_optimization<_Fp>
5880-
&& enable_nonlocking_formatter_optimization<_Sp>;
5880+
= enable_nonlocking_formatter_optimization<remove_cvref_t<_Fp>>
5881+
&& enable_nonlocking_formatter_optimization<remove_cvref_t<_Sp>>;
58815882
#endif
58825883

58835884
template<__format::__char _CharT, formattable<_CharT>... _Tps>
@@ -5899,10 +5900,11 @@ namespace __format
58995900
};
59005901

59015902
#if __glibcxx_print >= 202406L
5903+
// _GLIBCXX_RESOLVE_LIB_DEFECTS
5904+
// 4399. enable_nonlocking_formatter_optimization for pair and tuple needs remove_cvref_t
59025905
template<typename... _Tps>
5903-
// TODO this should have remove_cvref_t.
59045906
constexpr bool enable_nonlocking_formatter_optimization<tuple<_Tps...>>
5905-
= (enable_nonlocking_formatter_optimization<_Tps> && ...);
5907+
= (enable_nonlocking_formatter_optimization<remove_cvref_t<_Tps>> && ...);
59065908
#endif
59075909

59085910
// [format.range.formatter], class template range_formatter

libstdc++-v3/include/std/queue

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -113,10 +113,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
113113
};
114114

115115
#if __glibcxx_print >= 202406L
116+
// _GLIBCXX_RESOLVE_LIB_DEFECTS
117+
// 4398. enable_nonlocking_formatter_optimization should be disabled for container adaptors
116118
template<typename _Tp, typename _Container>
117119
constexpr bool
118-
// TODO should be false
119-
enable_nonlocking_formatter_optimization<queue<_Tp, _Container>> = true;
120+
enable_nonlocking_formatter_optimization<queue<_Tp, _Container>> = false;
120121
#endif
121122

122123
template<__format::__char _CharT, typename _Tp,
@@ -154,11 +155,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
154155
};
155156

156157
#if __glibcxx_print >= 202406L
158+
// _GLIBCXX_RESOLVE_LIB_DEFECTS
159+
// 4398. enable_nonlocking_formatter_optimization should be disabled for container adaptors
157160
template<typename _Tp, typename _Container, typename _Comparator>
158161
constexpr bool
159-
// TODO should be false
160162
enable_nonlocking_formatter_optimization<
161-
priority_queue<_Tp, _Container, _Comparator>> = true;
163+
priority_queue<_Tp, _Container, _Comparator>> = false;
162164
#endif
163165

164166
_GLIBCXX_END_NAMESPACE_VERSION

libstdc++-v3/include/std/stack

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,10 +107,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
107107
};
108108

109109
#if __glibcxx_print >= 202406L
110+
// _GLIBCXX_RESOLVE_LIB_DEFECTS
111+
// 4398. enable_nonlocking_formatter_optimization should be disabled for container adaptors
110112
template<typename _Tp, typename _Container>
111113
constexpr bool
112-
// TODO should be false
113-
enable_nonlocking_formatter_optimization<stack<_Tp, _Container>> = true;
114+
enable_nonlocking_formatter_optimization<stack<_Tp, _Container>> = false;
114115
#endif
115116
_GLIBCXX_END_NAMESPACE_VERSION
116117
} // namespace std

libstdc++-v3/testsuite/std/format/ranges/adaptors.cc

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -122,14 +122,13 @@ test_output()
122122
// Formatter check if container is formattable, not container elements.
123123
static_assert(!std::formattable<Adaptor<int, NotFormattableCont<int>>, CharT>);
124124

125-
// TODO should be false
126-
static_assert(std::enable_nonlocking_formatter_optimization<
125+
static_assert(!std::enable_nonlocking_formatter_optimization<
127126
Adaptor<int>>);
128-
static_assert(std::enable_nonlocking_formatter_optimization<
127+
static_assert(!std::enable_nonlocking_formatter_optimization<
129128
Adaptor<MutFormat>>);
130-
static_assert(std::enable_nonlocking_formatter_optimization<
129+
static_assert(!std::enable_nonlocking_formatter_optimization<
131130
Adaptor<int, std::deque<int>>>);
132-
static_assert(std::enable_nonlocking_formatter_optimization<
131+
static_assert(!std::enable_nonlocking_formatter_optimization<
133132
Adaptor<int, NotFormattableCont<int>>>);
134133
}
135134

libstdc++-v3/testsuite/std/format/tuple.cc

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -361,10 +361,9 @@ void test_nonblocking()
361361
{
362362
static_assert(std::enable_nonlocking_formatter_optimization<
363363
Tuple<int, float>>);
364-
// TODO missing remove_cv_ref
365-
static_assert(!std::enable_nonlocking_formatter_optimization<
364+
static_assert(std::enable_nonlocking_formatter_optimization<
366365
Tuple<const int, const float>>);
367-
static_assert(!std::enable_nonlocking_formatter_optimization<
366+
static_assert(std::enable_nonlocking_formatter_optimization<
368367
Tuple<int&, float&>>);
369368

370369
static_assert(!std::enable_nonlocking_formatter_optimization<

libstdc++-v3/testsuite/std/time/format/nonlocking.cc

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,9 @@ static_assert(std::enable_nonlocking_formatter_optimization<
4343
#endif
4444

4545
template<typename Duration>
46-
using local_time_fmt
46+
using local_time_fmt
4747
= decltype(std::chrono::local_time_format(std::chrono::local_time<Duration>{}));
48-
48+
4949
static_assert(std::enable_nonlocking_formatter_optimization<
5050
std::chrono::seconds>);
5151
static_assert(std::enable_nonlocking_formatter_optimization<
@@ -71,19 +71,19 @@ using BufferedDuration = std::chrono::duration<Rep<void, int>>;
7171

7272
static_assert(!std::enable_nonlocking_formatter_optimization<
7373
BufferedDuration>);
74-
static_assert(std::enable_nonlocking_formatter_optimization<
74+
static_assert(!std::enable_nonlocking_formatter_optimization<
7575
std::chrono::local_time<BufferedDuration>>);
76-
static_assert(std::enable_nonlocking_formatter_optimization<
76+
static_assert(!std::enable_nonlocking_formatter_optimization<
7777
std::chrono::sys_time<BufferedDuration>>);
78-
static_assert(std::enable_nonlocking_formatter_optimization<
78+
static_assert(!std::enable_nonlocking_formatter_optimization<
7979
std::chrono::utc_time<BufferedDuration>>);
80-
static_assert(std::enable_nonlocking_formatter_optimization<
80+
static_assert(!std::enable_nonlocking_formatter_optimization<
8181
std::chrono::gps_time<BufferedDuration>>);
82-
static_assert(std::enable_nonlocking_formatter_optimization<
82+
static_assert(!std::enable_nonlocking_formatter_optimization<
8383
std::chrono::tai_time<BufferedDuration>>);
84-
static_assert(std::enable_nonlocking_formatter_optimization<
84+
static_assert(!std::enable_nonlocking_formatter_optimization<
8585
std::chrono::file_time<BufferedDuration>>);
86-
static_assert(std::enable_nonlocking_formatter_optimization<
86+
static_assert(!std::enable_nonlocking_formatter_optimization<
8787
local_time_fmt<BufferedDuration>>);
8888

8989
template<>
@@ -92,21 +92,21 @@ inline constexpr bool
9292

9393
using NonBufferedRep = std::chrono::duration<Rep<void, long>>;
9494

95-
static_assert(std::enable_nonlocking_formatter_optimization<
95+
static_assert(!std::enable_nonlocking_formatter_optimization<
9696
NonBufferedRep>);
97-
static_assert(std::enable_nonlocking_formatter_optimization<
97+
static_assert(!std::enable_nonlocking_formatter_optimization<
9898
std::chrono::local_time<NonBufferedRep>>);
99-
static_assert(std::enable_nonlocking_formatter_optimization<
99+
static_assert(!std::enable_nonlocking_formatter_optimization<
100100
std::chrono::sys_time<NonBufferedRep>>);
101-
static_assert(std::enable_nonlocking_formatter_optimization<
101+
static_assert(!std::enable_nonlocking_formatter_optimization<
102102
std::chrono::utc_time<NonBufferedRep>>);
103-
static_assert(std::enable_nonlocking_formatter_optimization<
103+
static_assert(!std::enable_nonlocking_formatter_optimization<
104104
std::chrono::gps_time<NonBufferedRep>>);
105-
static_assert(std::enable_nonlocking_formatter_optimization<
105+
static_assert(!std::enable_nonlocking_formatter_optimization<
106106
std::chrono::tai_time<NonBufferedRep>>);
107-
static_assert(std::enable_nonlocking_formatter_optimization<
107+
static_assert(!std::enable_nonlocking_formatter_optimization<
108108
std::chrono::file_time<NonBufferedRep>>);
109-
static_assert(std::enable_nonlocking_formatter_optimization<
109+
static_assert(!std::enable_nonlocking_formatter_optimization<
110110
local_time_fmt<NonBufferedRep>>);
111111

112112
using NonBufferedDuration = std::chrono::duration<Rep<void, short>>;
@@ -135,9 +135,9 @@ static_assert(std::enable_nonlocking_formatter_optimization<
135135
#if _GLIBCXX_USE_CXX11_ABI || !_GLIBCXX_USE_DUAL_ABI
136136
static_assert(std::enable_nonlocking_formatter_optimization<
137137
std::chrono::zoned_time<std::chrono::seconds>>);
138-
static_assert(std::enable_nonlocking_formatter_optimization<
138+
static_assert(!std::enable_nonlocking_formatter_optimization<
139139
std::chrono::zoned_time<BufferedDuration>>);
140-
static_assert(std::enable_nonlocking_formatter_optimization<
140+
static_assert(!std::enable_nonlocking_formatter_optimization<
141141
std::chrono::zoned_time<NonBufferedRep>>);
142142
static_assert(std::enable_nonlocking_formatter_optimization<
143143
std::chrono::zoned_time<NonBufferedDuration>>);
@@ -150,7 +150,7 @@ struct std::chrono::zoned_traits<MyTimeZone>
150150
{
151151
static const MyTimeZone* default_zone();
152152
static const MyTimeZone* locate_zone(std::string_view name);
153-
};
153+
};
154154

155155
static_assert(!std::enable_nonlocking_formatter_optimization<
156156
std::chrono::zoned_time<std::chrono::seconds, MyTimeZone>>);

0 commit comments

Comments
 (0)