@@ -29,13 +29,45 @@ def add_version_header(tc):
29
29
tc ["headers" ].append ("version" )
30
30
return tc
31
31
32
+ # ================ ============================================================
33
+ # Field Description
34
+ # ================ ============================================================
35
+ # name The name of the feature-test macro.
36
+ # values A dict whose keys are C++ versions and whose values are the
37
+ # value of the feature-test macro for that C++ version.
38
+ # (TODO: This isn't a very clean model for feature-test
39
+ # macros affected by multiple papers.)
40
+ # headers An array with the headers that should provide the
41
+ # feature-test macro.
42
+ # test_suite_guard An optional string field. When this field is provided,
43
+ # `libcxx_guard` must also be provided. This field is used
44
+ # only to generate the unit tests for the feature-test macros.
45
+ # It can't depend on macros defined in <__config> because the
46
+ # `test/std/` parts of the test suite are intended to be
47
+ # portable to any C++ standard library implementation, not
48
+ # just libc++. It may depend on
49
+ # * macros defined by the compiler itself, or
50
+ # * macros generated by CMake.
51
+ # In some cases we add
52
+ # `&& !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM_...)`
53
+ # in order to make libc++ pass the tests on OSX; see D94983.
54
+ # libcxx_guard An optional string field. When this field is provided,
55
+ # `test_suite_guard` must also be provided. This field is used
56
+ # only to guard the feature-test macro in <version>. It may
57
+ # be the same as `test_suite_guard`, or it may depend on
58
+ # macros defined in <__config>.
59
+ # unimplemented An optional Boolean field with the value `True`. This field
60
+ # is only used when a feature isn't fully implemented. Once
61
+ # you've fully implemented the feature, you should remove
62
+ # this field.
63
+ # ================ ============================================================
32
64
feature_test_macros = [ add_version_header (x ) for x in [
33
65
{
34
66
"name" : "__cpp_lib_addressof_constexpr" ,
35
67
"values" : { "c++17" : 201603 },
36
68
"headers" : ["memory" ],
37
- "depends " : "TEST_HAS_BUILTIN(__builtin_addressof) || TEST_GCC_VER >= 700" ,
38
- "internal_depends " : "!defined(_LIBCPP_HAS_NO_BUILTIN_ADDRESSOF)" ,
69
+ "test_suite_guard " : "TEST_HAS_BUILTIN(__builtin_addressof) || TEST_GCC_VER >= 700" ,
70
+ "libcxx_guard " : "!defined(_LIBCPP_HAS_NO_BUILTIN_ADDRESSOF)" ,
39
71
}, {
40
72
"name" : "__cpp_lib_allocator_traits_is_always_equal" ,
41
73
"values" : { "c++17" : 201411 },
@@ -65,60 +97,60 @@ def add_version_header(tc):
65
97
"name" : "__cpp_lib_atomic_flag_test" ,
66
98
"values" : { "c++20" : 201907 },
67
99
"headers" : ["atomic" ],
68
- "depends " : "!defined(_LIBCPP_HAS_NO_THREADS)" ,
69
- "internal_depends " : "!defined(_LIBCPP_HAS_NO_THREADS)" ,
100
+ "test_suite_guard " : "!defined(_LIBCPP_HAS_NO_THREADS)" ,
101
+ "libcxx_guard " : "!defined(_LIBCPP_HAS_NO_THREADS)" ,
70
102
}, {
71
103
"name" : "__cpp_lib_atomic_float" ,
72
104
"values" : { "c++20" : 201711 },
73
105
"headers" : ["atomic" ],
74
- "depends " : "!defined(_LIBCPP_HAS_NO_THREADS)" ,
75
- "internal_depends " : "!defined(_LIBCPP_HAS_NO_THREADS)" ,
106
+ "test_suite_guard " : "!defined(_LIBCPP_HAS_NO_THREADS)" ,
107
+ "libcxx_guard " : "!defined(_LIBCPP_HAS_NO_THREADS)" ,
76
108
"unimplemented" : True ,
77
109
}, {
78
110
"name" : "__cpp_lib_atomic_is_always_lock_free" ,
79
111
"values" : { "c++17" : 201603 },
80
112
"headers" : ["atomic" ],
81
- "depends " : "!defined(_LIBCPP_HAS_NO_THREADS)" ,
82
- "internal_depends " : "!defined(_LIBCPP_HAS_NO_THREADS)" ,
113
+ "test_suite_guard " : "!defined(_LIBCPP_HAS_NO_THREADS)" ,
114
+ "libcxx_guard " : "!defined(_LIBCPP_HAS_NO_THREADS)" ,
83
115
}, {
84
116
"name" : "__cpp_lib_atomic_lock_free_type_aliases" ,
85
117
"values" : { "c++20" : 201907 },
86
118
"headers" : ["atomic" ],
87
- "depends " : "!defined(_LIBCPP_HAS_NO_THREADS)" ,
88
- "internal_depends " : "!defined(_LIBCPP_HAS_NO_THREADS)" ,
119
+ "test_suite_guard " : "!defined(_LIBCPP_HAS_NO_THREADS)" ,
120
+ "libcxx_guard " : "!defined(_LIBCPP_HAS_NO_THREADS)" ,
89
121
}, {
90
122
"name" : "__cpp_lib_atomic_ref" ,
91
123
"values" : { "c++20" : 201806 },
92
124
"headers" : ["atomic" ],
93
- "depends " : "!defined(_LIBCPP_HAS_NO_THREADS)" ,
94
- "internal_depends " : "!defined(_LIBCPP_HAS_NO_THREADS)" ,
125
+ "test_suite_guard " : "!defined(_LIBCPP_HAS_NO_THREADS)" ,
126
+ "libcxx_guard " : "!defined(_LIBCPP_HAS_NO_THREADS)" ,
95
127
"unimplemented" : True ,
96
128
}, {
97
129
"name" : "__cpp_lib_atomic_shared_ptr" ,
98
130
"values" : { "c++20" : 201711 },
99
131
"headers" : ["atomic" ],
100
- "depends " : "!defined(_LIBCPP_HAS_NO_THREADS)" ,
101
- "internal_depends " : "!defined(_LIBCPP_HAS_NO_THREADS)" ,
132
+ "test_suite_guard " : "!defined(_LIBCPP_HAS_NO_THREADS)" ,
133
+ "libcxx_guard " : "!defined(_LIBCPP_HAS_NO_THREADS)" ,
102
134
"unimplemented" : True ,
103
135
}, {
104
136
"name" : "__cpp_lib_atomic_value_initialization" ,
105
137
"values" : { "c++20" : 201911 },
106
138
"headers" : ["atomic" , "memory" ],
107
- "depends " : "!defined(_LIBCPP_HAS_NO_THREADS)" ,
108
- "internal_depends " : "!defined(_LIBCPP_HAS_NO_THREADS)" ,
139
+ "test_suite_guard " : "!defined(_LIBCPP_HAS_NO_THREADS)" ,
140
+ "libcxx_guard " : "!defined(_LIBCPP_HAS_NO_THREADS)" ,
109
141
"unimplemented" : True ,
110
142
}, {
111
143
"name" : "__cpp_lib_atomic_wait" ,
112
144
"values" : { "c++20" : 201907 },
113
145
"headers" : ["atomic" ],
114
- "depends " : "!defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_atomic_wait)" ,
115
- "internal_depends " : "!defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_atomic_wait)" ,
146
+ "test_suite_guard " : "!defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_atomic_wait)" ,
147
+ "libcxx_guard " : "!defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_atomic_wait)" ,
116
148
}, {
117
149
"name" : "__cpp_lib_barrier" ,
118
150
"values" : { "c++20" : 201907 },
119
151
"headers" : ["barrier" ],
120
- "depends " : "!defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_barrier)" ,
121
- "internal_depends " : "!defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_barrier)" ,
152
+ "test_suite_guard " : "!defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_barrier)" ,
153
+ "libcxx_guard " : "!defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_barrier)" ,
122
154
}, {
123
155
"name" : "__cpp_lib_bind_front" ,
124
156
"values" : { "c++20" : 201907 },
@@ -154,8 +186,8 @@ def add_version_header(tc):
154
186
"name" : "__cpp_lib_char8_t" ,
155
187
"values" : { "c++20" : 201811 },
156
188
"headers" : ["atomic" , "filesystem" , "istream" , "limits" , "locale" , "ostream" , "string" , "string_view" ],
157
- "depends " : "defined(__cpp_char8_t)" ,
158
- "internal_depends " : "!defined(_LIBCPP_NO_HAS_CHAR8_T)" ,
189
+ "test_suite_guard " : "defined(__cpp_char8_t)" ,
190
+ "libcxx_guard " : "!defined(_LIBCPP_NO_HAS_CHAR8_T)" ,
159
191
}, {
160
192
"name" : "__cpp_lib_chrono" ,
161
193
"values" : { "c++17" : 201611 },
@@ -236,8 +268,8 @@ def add_version_header(tc):
236
268
"name" : "__cpp_lib_destroying_delete" ,
237
269
"values" : { "c++20" : 201806 },
238
270
"headers" : ["new" ],
239
- "depends " : "TEST_STD_VER > 17 && defined(__cpp_impl_destroying_delete) && __cpp_impl_destroying_delete >= 201806L" ,
240
- "internal_depends " : "_LIBCPP_STD_VER > 17 && defined(__cpp_impl_destroying_delete) && __cpp_impl_destroying_delete >= 201806L" ,
271
+ "test_suite_guard " : "TEST_STD_VER > 17 && defined(__cpp_impl_destroying_delete) && __cpp_impl_destroying_delete >= 201806L" ,
272
+ "libcxx_guard " : "_LIBCPP_STD_VER > 17 && defined(__cpp_impl_destroying_delete) && __cpp_impl_destroying_delete >= 201806L" ,
241
273
}, {
242
274
"name" : "__cpp_lib_enable_shared_from_this" ,
243
275
"values" : { "c++17" : 201603 },
@@ -263,8 +295,8 @@ def add_version_header(tc):
263
295
"name" : "__cpp_lib_filesystem" ,
264
296
"values" : { "c++17" : 201703 },
265
297
"headers" : ["filesystem" ],
266
- "depends " : "!defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_filesystem)" ,
267
- "internal_depends " : "!defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_filesystem)"
298
+ "test_suite_guard " : "!defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_filesystem)" ,
299
+ "libcxx_guard " : "!defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_filesystem)"
268
300
}, {
269
301
"name" : "__cpp_lib_format" ,
270
302
"values" : { "c++20" : 201907 },
@@ -291,8 +323,8 @@ def add_version_header(tc):
291
323
"name" : "__cpp_lib_has_unique_object_representations" ,
292
324
"values" : { "c++17" : 201606 },
293
325
"headers" : ["type_traits" ],
294
- "depends " : "TEST_HAS_BUILTIN_IDENTIFIER(__has_unique_object_representations) || TEST_GCC_VER >= 700" ,
295
- "internal_depends " : "defined(_LIBCPP_HAS_UNIQUE_OBJECT_REPRESENTATIONS)" ,
326
+ "test_suite_guard " : "TEST_HAS_BUILTIN_IDENTIFIER(__has_unique_object_representations) || TEST_GCC_VER >= 700" ,
327
+ "libcxx_guard " : "defined(_LIBCPP_HAS_UNIQUE_OBJECT_REPRESENTATIONS)" ,
296
328
}, {
297
329
"name" : "__cpp_lib_hypot" ,
298
330
"values" : { "c++17" : 201603 },
@@ -330,14 +362,14 @@ def add_version_header(tc):
330
362
"name" : "__cpp_lib_is_aggregate" ,
331
363
"values" : { "c++17" : 201703 },
332
364
"headers" : ["type_traits" ],
333
- "depends " : "TEST_HAS_BUILTIN_IDENTIFIER(__is_aggregate) || TEST_GCC_VER_NEW >= 7001" ,
334
- "internal_depends " : "!defined(_LIBCPP_HAS_NO_IS_AGGREGATE)" ,
365
+ "test_suite_guard " : "TEST_HAS_BUILTIN_IDENTIFIER(__is_aggregate) || TEST_GCC_VER_NEW >= 7001" ,
366
+ "libcxx_guard " : "!defined(_LIBCPP_HAS_NO_IS_AGGREGATE)" ,
335
367
}, {
336
368
"name" : "__cpp_lib_is_constant_evaluated" ,
337
369
"values" : { "c++20" : 201811 },
338
370
"headers" : ["type_traits" ],
339
- "depends " : "TEST_HAS_BUILTIN(__builtin_is_constant_evaluated) || TEST_GCC_VER >= 900" ,
340
- "internal_depends " : "!defined(_LIBCPP_HAS_NO_BUILTIN_IS_CONSTANT_EVALUATED)" ,
371
+ "test_suite_guard " : "TEST_HAS_BUILTIN(__builtin_is_constant_evaluated) || TEST_GCC_VER >= 900" ,
372
+ "libcxx_guard " : "!defined(_LIBCPP_HAS_NO_BUILTIN_IS_CONSTANT_EVALUATED)" ,
341
373
}, {
342
374
"name" : "__cpp_lib_is_final" ,
343
375
"values" : { "c++14" : 201402 },
@@ -376,15 +408,15 @@ def add_version_header(tc):
376
408
"name" : "__cpp_lib_jthread" ,
377
409
"values" : { "c++20" : 201911 },
378
410
"headers" : ["stop_token" , "thread" ],
379
- "depends " : "!defined(_LIBCPP_HAS_NO_THREADS)" ,
380
- "internal_depends " : "!defined(_LIBCPP_HAS_NO_THREADS)" ,
411
+ "test_suite_guard " : "!defined(_LIBCPP_HAS_NO_THREADS)" ,
412
+ "libcxx_guard " : "!defined(_LIBCPP_HAS_NO_THREADS)" ,
381
413
"unimplemented" : True ,
382
414
}, {
383
415
"name" : "__cpp_lib_latch" ,
384
416
"values" : { "c++20" : 201907 },
385
417
"headers" : ["latch" ],
386
- "depends " : "!defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_latch)" ,
387
- "internal_depends " : "!defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_latch)" ,
418
+ "test_suite_guard " : "!defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_latch)" ,
419
+ "libcxx_guard " : "!defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_latch)" ,
388
420
}, {
389
421
"name" : "__cpp_lib_launder" ,
390
422
"values" : { "c++17" : 201606 },
@@ -417,8 +449,8 @@ def add_version_header(tc):
417
449
"name" : "__cpp_lib_math_constants" ,
418
450
"values" : { "c++20" : 201907 },
419
451
"headers" : ["numbers" ],
420
- "depends " : "defined(__cpp_concepts) && __cpp_concepts >= 201907L" ,
421
- "internal_depends " : "!defined(_LIBCPP_HAS_NO_CONCEPTS)" ,
452
+ "test_suite_guard " : "defined(__cpp_concepts) && __cpp_concepts >= 201907L" ,
453
+ "libcxx_guard " : "!defined(_LIBCPP_HAS_NO_CONCEPTS)" ,
422
454
}, {
423
455
"name" : "__cpp_lib_math_special_functions" ,
424
456
"values" : { "c++17" : 201603 },
@@ -496,14 +528,14 @@ def add_version_header(tc):
496
528
"name" : "__cpp_lib_semaphore" ,
497
529
"values" : { "c++20" : 201907 },
498
530
"headers" : ["semaphore" ],
499
- "depends " : "!defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_semaphore)" ,
500
- "internal_depends " : "!defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_semaphore)" ,
531
+ "test_suite_guard " : "!defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_semaphore)" ,
532
+ "libcxx_guard " : "!defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_semaphore)" ,
501
533
}, {
502
534
"name" : "__cpp_lib_shared_mutex" ,
503
535
"values" : { "c++17" : 201505 },
504
536
"headers" : ["shared_mutex" ],
505
- "depends " : "!defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_shared_mutex)" ,
506
- "internal_depends " : "!defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_shared_mutex)" ,
537
+ "test_suite_guard " : "!defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_shared_mutex)" ,
538
+ "libcxx_guard " : "!defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_shared_mutex)" ,
507
539
}, {
508
540
"name" : "__cpp_lib_shared_ptr_arrays" ,
509
541
"values" : { "c++17" : 201611 },
@@ -516,8 +548,8 @@ def add_version_header(tc):
516
548
"name" : "__cpp_lib_shared_timed_mutex" ,
517
549
"values" : { "c++14" : 201402 },
518
550
"headers" : ["shared_mutex" ],
519
- "depends " : "!defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_shared_timed_mutex)" ,
520
- "internal_depends " : "!defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_shared_timed_mutex)" ,
551
+ "test_suite_guard " : "!defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_shared_timed_mutex)" ,
552
+ "libcxx_guard " : "!defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_shared_timed_mutex)" ,
521
553
}, {
522
554
"name" : "__cpp_lib_shift" ,
523
555
"values" : { "c++20" : 201806 },
@@ -638,6 +670,8 @@ def add_version_header(tc):
638
670
639
671
assert feature_test_macros == sorted (feature_test_macros , key = lambda tc : tc ["name" ])
640
672
assert all (tc ["headers" ] == sorted (tc ["headers" ]) for tc in feature_test_macros )
673
+ assert all (("libcxx_guard" in tc ) == ("test_suite_guard" in tc ) for tc in feature_test_macros )
674
+ assert all (all (key in ["name" , "values" , "headers" , "libcxx_guard" , "test_suite_guard" , "unimplemented" ] for key in tc .keys ()) for tc in feature_test_macros )
641
675
642
676
# Map from each header to the Lit annotations that should be used for
643
677
# tests that include that header.
@@ -721,12 +755,11 @@ def produce_macros_definition_for_std(std):
721
755
if std not in tc ["values" ]:
722
756
continue
723
757
inner_indent = 1
724
- if 'depends' in tc .keys ():
725
- assert 'internal_depends' in tc .keys ()
726
- result += "# if %s\n " % tc ["internal_depends" ]
758
+ if 'test_suite_guard' in tc .keys ():
759
+ result += "# if %s\n " % tc ["libcxx_guard" ]
727
760
inner_indent += 2
728
761
if get_value_before (tc ["values" ], std ) is not None :
729
- assert 'depends ' not in tc .keys ()
762
+ assert 'test_suite_guard ' not in tc .keys ()
730
763
result += "# undef %s\n " % tc ["name" ]
731
764
line = "#%sdefine %s" % ((" " * inner_indent ), tc ["name" ])
732
765
line += " " * (indent - len (line ))
@@ -735,7 +768,7 @@ def produce_macros_definition_for_std(std):
735
768
line = "// " + line
736
769
result += line
737
770
result += "\n "
738
- if 'depends ' in tc .keys ():
771
+ if 'test_suite_guard ' in tc .keys ():
739
772
result += "# endif\n "
740
773
return result .strip ()
741
774
@@ -847,8 +880,8 @@ def produce_version_header():
847
880
# endif
848
881
""" ,
849
882
850
- "depends " : """
851
- # if {depends }
883
+ "test_suite_guard " : """
884
+ # if {test_suite_guard }
852
885
# ifndef {name}
853
886
# error "{name} should be defined in {std}"
854
887
# endif
@@ -857,7 +890,7 @@ def produce_version_header():
857
890
# endif
858
891
# else
859
892
# ifdef {name}
860
- # error "{name} should not be defined when {depends } is not defined!"
893
+ # error "{name} should not be defined when {test_suite_guard } is not defined!"
861
894
# endif
862
895
# endif
863
896
""" ,
@@ -897,8 +930,8 @@ def generate_std_test(test_list, std):
897
930
result += test_types ["undefined" ].format (name = tc ["name" ], std_first = get_first_std (tc ["values" ]))
898
931
elif 'unimplemented' in tc .keys ():
899
932
result += test_types ["unimplemented" ].format (name = tc ["name" ], value = val , std = std )
900
- elif "depends " in tc .keys ():
901
- result += test_types ["depends " ].format (name = tc ["name" ], value = val , std = std , depends = tc ["depends " ])
933
+ elif "test_suite_guard " in tc .keys ():
934
+ result += test_types ["test_suite_guard " ].format (name = tc ["name" ], value = val , std = std , test_suite_guard = tc ["test_suite_guard " ])
902
935
else :
903
936
result += test_types ["defined" ].format (name = tc ["name" ], value = val , std = std )
904
937
return result .strip ()
0 commit comments