1508da415SEric Fiselier#!/usr/bin/env python 2508da415SEric Fiselier 3508da415SEric Fiselierimport os 4ff1b6f9fSArthur O'Dwyerfrom builtins import range 5fd02a468SLouis Dionnefrom functools import reduce 6d2dd4b55SMark de Weverfrom typing import Any, Dict, List # Needed for python 3.8 compatibility. 7d2dd4b55SMark de Weverimport functools 8d2dd4b55SMark de Weverimport json 9508da415SEric Fiselier 107bfaa0f0STobias Hieta 11508da415SEric Fiselierdef get_libcxx_paths(): 12508da415SEric Fiselier utils_path = os.path.dirname(os.path.abspath(__file__)) 13508da415SEric Fiselier script_name = os.path.basename(__file__) 14508da415SEric Fiselier assert os.path.exists(utils_path) 15508da415SEric Fiselier src_root = os.path.dirname(utils_path) 167bfaa0f0STobias Hieta include_path = os.path.join(src_root, "include") 17508da415SEric Fiselier assert os.path.exists(include_path) 187bfaa0f0STobias Hieta docs_path = os.path.join(src_root, "docs") 19508da415SEric Fiselier assert os.path.exists(docs_path) 207bfaa0f0STobias Hieta macro_test_path = os.path.join( 217bfaa0f0STobias Hieta src_root, 227bfaa0f0STobias Hieta "test", 237bfaa0f0STobias Hieta "std", 247bfaa0f0STobias Hieta "language.support", 257bfaa0f0STobias Hieta "support.limits", 267bfaa0f0STobias Hieta "support.limits.general", 277bfaa0f0STobias Hieta ) 28508da415SEric Fiselier assert os.path.exists(macro_test_path) 297bfaa0f0STobias Hieta assert os.path.exists( 307bfaa0f0STobias Hieta os.path.join(macro_test_path, "version.version.compile.pass.cpp") 317bfaa0f0STobias Hieta ) 32508da415SEric Fiselier return script_name, src_root, include_path, docs_path, macro_test_path 33508da415SEric Fiselier 347bfaa0f0STobias Hieta 35508da415SEric Fiselierscript_name, source_root, include_path, docs_path, macro_test_path = get_libcxx_paths() 36508da415SEric Fiselier 377bfaa0f0STobias Hieta 38508da415SEric Fiselierdef has_header(h): 39508da415SEric Fiselier h_path = os.path.join(include_path, h) 40508da415SEric Fiselier return os.path.exists(h_path) 41508da415SEric Fiselier 427bfaa0f0STobias Hieta 43508da415SEric Fiselierdef add_version_header(tc): 44508da415SEric Fiselier tc["headers"].append("version") 45508da415SEric Fiselier return tc 46508da415SEric Fiselier 477bfaa0f0STobias Hieta 48c2c68a59SMark de Wever# ================ ============================================================ 49c2c68a59SMark de Wever# Field Description 50c2c68a59SMark de Wever# ================ ============================================================ 51c2c68a59SMark de Wever# name The name of the feature-test macro. 52c2c68a59SMark de Wever# values A dict whose keys are C++ versions and whose values are the 53c2c68a59SMark de Wever# value of the feature-test macro for that C++ version. 54c2c68a59SMark de Wever# (TODO: This isn't a very clean model for feature-test 55c2c68a59SMark de Wever# macros affected by multiple papers.) 56c2c68a59SMark de Wever# headers An array with the headers that should provide the 57c2c68a59SMark de Wever# feature-test macro. 58c2c68a59SMark de Wever# test_suite_guard An optional string field. When this field is provided, 59c2c68a59SMark de Wever# `libcxx_guard` must also be provided. This field is used 60c2c68a59SMark de Wever# only to generate the unit tests for the feature-test macros. 61c2c68a59SMark de Wever# It can't depend on macros defined in <__config> because the 62c2c68a59SMark de Wever# `test/std/` parts of the test suite are intended to be 63c2c68a59SMark de Wever# portable to any C++ standard library implementation, not 64c2c68a59SMark de Wever# just libc++. It may depend on 65c2c68a59SMark de Wever# * macros defined by the compiler itself, or 66c2c68a59SMark de Wever# * macros generated by CMake. 6704f01a2bSLouis Dionne# In some cases we add also depend on macros defined in 6804f01a2bSLouis Dionne# <__configuration/availability.h>. 69c2c68a59SMark de Wever# libcxx_guard An optional string field. When this field is provided, 70c2c68a59SMark de Wever# `test_suite_guard` must also be provided. This field is used 71c2c68a59SMark de Wever# only to guard the feature-test macro in <version>. It may 72c2c68a59SMark de Wever# be the same as `test_suite_guard`, or it may depend on 73c2c68a59SMark de Wever# macros defined in <__config>. 74c2c68a59SMark de Wever# unimplemented An optional Boolean field with the value `True`. This field 75c2c68a59SMark de Wever# is only used when a feature isn't fully implemented. Once 76c2c68a59SMark de Wever# you've fully implemented the feature, you should remove 77c2c68a59SMark de Wever# this field. 78c2c68a59SMark de Wever# ================ ============================================================ 797bfaa0f0STobias Hietafeature_test_macros = [ 807bfaa0f0STobias Hieta add_version_header(x) 817bfaa0f0STobias Hieta for x in [ 827656dd33SLouis Dionne { 83f3aed369SNikolas Klauser "name": "__cpp_lib_adaptor_iterator_pair_constructor", 8471400505SMark de Wever "values": {"c++23": 202106}, 85f3aed369SNikolas Klauser "headers": ["queue", "stack"], 867bfaa0f0STobias Hieta }, 877bfaa0f0STobias Hieta { 887656dd33SLouis Dionne "name": "__cpp_lib_addressof_constexpr", 89ff1b6f9fSArthur O'Dwyer "values": {"c++17": 201603}, 90508da415SEric Fiselier "headers": ["memory"], 917bfaa0f0STobias Hieta }, 927bfaa0f0STobias Hieta { 93855d7bedSArthur O'Dwyer "name": "__cpp_lib_allocate_at_least", 943f05d044SMark de Wever "values": { 953f05d044SMark de Wever # Note LWG3887 Version macro for allocate_at_least 967d78ccf7SHristo Hristov "c++23": 202302, # P2652R2 Disallow User Specialization of allocator_traits 973f05d044SMark de Wever }, 98855d7bedSArthur O'Dwyer "headers": ["memory"], 997bfaa0f0STobias Hieta }, 1007bfaa0f0STobias Hieta { 1017656dd33SLouis Dionne "name": "__cpp_lib_allocator_traits_is_always_equal", 102ff1b6f9fSArthur O'Dwyer "values": {"c++17": 201411}, 1037bfaa0f0STobias Hieta "headers": [ 1047bfaa0f0STobias Hieta "deque", 1057bfaa0f0STobias Hieta "forward_list", 1067bfaa0f0STobias Hieta "list", 1077bfaa0f0STobias Hieta "map", 1087bfaa0f0STobias Hieta "memory", 1097bfaa0f0STobias Hieta "scoped_allocator", 1107bfaa0f0STobias Hieta "set", 1117bfaa0f0STobias Hieta "string", 1127bfaa0f0STobias Hieta "unordered_map", 1137bfaa0f0STobias Hieta "unordered_set", 1147bfaa0f0STobias Hieta "vector", 1157bfaa0f0STobias Hieta ], 1167bfaa0f0STobias Hieta }, 1177bfaa0f0STobias Hieta { 118ff1b6f9fSArthur O'Dwyer "name": "__cpp_lib_any", 119ff1b6f9fSArthur O'Dwyer "values": {"c++17": 201606}, 120ff1b6f9fSArthur O'Dwyer "headers": ["any"], 1217bfaa0f0STobias Hieta }, 1227bfaa0f0STobias Hieta { 123ff1b6f9fSArthur O'Dwyer "name": "__cpp_lib_apply", 124ff1b6f9fSArthur O'Dwyer "values": {"c++17": 201603}, 125ff1b6f9fSArthur O'Dwyer "headers": ["tuple"], 1267bfaa0f0STobias Hieta }, 1277bfaa0f0STobias Hieta { 1287656dd33SLouis Dionne "name": "__cpp_lib_array_constexpr", 129ff1b6f9fSArthur O'Dwyer "values": {"c++17": 201603, "c++20": 201811}, 130ff1b6f9fSArthur O'Dwyer "headers": ["array", "iterator"], 1317bfaa0f0STobias Hieta }, 1327bfaa0f0STobias Hieta { 133ff1b6f9fSArthur O'Dwyer "name": "__cpp_lib_as_const", 134ff1b6f9fSArthur O'Dwyer "values": {"c++17": 201510}, 135737a4501SMichael Schellenberger Costa "headers": ["utility"], 1367bfaa0f0STobias Hieta }, 1377bfaa0f0STobias Hieta { 138855d7bedSArthur O'Dwyer "name": "__cpp_lib_associative_heterogeneous_erasure", 13971400505SMark de Wever "values": {"c++23": 202110}, 140855d7bedSArthur O'Dwyer "headers": ["map", "set", "unordered_map", "unordered_set"], 141855d7bedSArthur O'Dwyer "unimplemented": True, 1427bfaa0f0STobias Hieta }, 1437bfaa0f0STobias Hieta { 1443f05d044SMark de Wever "name": "__cpp_lib_associative_heterogeneous_insertion", 145f49ccca8SMark de Wever "values": { 146f49ccca8SMark de Wever "c++26": 202306 # P2363R5 Extending associative containers with the remaining heterogeneous overloads 147f49ccca8SMark de Wever }, 1483f05d044SMark de Wever "headers": ["map", "set", "unordered_map", "unordered_set"], 1493f05d044SMark de Wever "unimplemented": True, 1503f05d044SMark de Wever }, 1513f05d044SMark de Wever { 152466df171SArthur O'Dwyer "name": "__cpp_lib_assume_aligned", 153466df171SArthur O'Dwyer "values": {"c++20": 201811}, 154466df171SArthur O'Dwyer "headers": ["memory"], 1557bfaa0f0STobias Hieta }, 1567bfaa0f0STobias Hieta { 1577656dd33SLouis Dionne "name": "__cpp_lib_atomic_flag_test", 158ff1b6f9fSArthur O'Dwyer "values": {"c++20": 201907}, 159fc4bff0cSOlivier Giroux "headers": ["atomic"], 1607bfaa0f0STobias Hieta }, 1617bfaa0f0STobias Hieta { 1627656dd33SLouis Dionne "name": "__cpp_lib_atomic_float", 163ff1b6f9fSArthur O'Dwyer "values": {"c++20": 201711}, 164fc4bff0cSOlivier Giroux "headers": ["atomic"], 165ff1b6f9fSArthur O'Dwyer "unimplemented": True, 1667bfaa0f0STobias Hieta }, 1677bfaa0f0STobias Hieta { 168ff1b6f9fSArthur O'Dwyer "name": "__cpp_lib_atomic_is_always_lock_free", 169ff1b6f9fSArthur O'Dwyer "values": {"c++17": 201603}, 170ff1b6f9fSArthur O'Dwyer "headers": ["atomic"], 1717bfaa0f0STobias Hieta }, 1727bfaa0f0STobias Hieta { 173ff1b6f9fSArthur O'Dwyer "name": "__cpp_lib_atomic_lock_free_type_aliases", 174ff1b6f9fSArthur O'Dwyer "values": {"c++20": 201907}, 175ff1b6f9fSArthur O'Dwyer "headers": ["atomic"], 1767bfaa0f0STobias Hieta }, 1777bfaa0f0STobias Hieta { 178b699a9baSLouis Dionne "name": "__cpp_lib_atomic_min_max", 179b699a9baSLouis Dionne "values": {"c++26": 202403}, # P0493R5: Atomic minimum/maximum 180b699a9baSLouis Dionne "headers": ["atomic"], 181b699a9baSLouis Dionne "unimplemented": True, 182b699a9baSLouis Dionne }, 183b699a9baSLouis Dionne { 184ff1b6f9fSArthur O'Dwyer "name": "__cpp_lib_atomic_ref", 185ff1b6f9fSArthur O'Dwyer "values": {"c++20": 201806}, 186ff1b6f9fSArthur O'Dwyer "headers": ["atomic"], 1877bfaa0f0STobias Hieta }, 1887bfaa0f0STobias Hieta { 1897656dd33SLouis Dionne "name": "__cpp_lib_atomic_shared_ptr", 190ff1b6f9fSArthur O'Dwyer "values": {"c++20": 201711}, 191fc4bff0cSOlivier Giroux "headers": ["atomic"], 192ff1b6f9fSArthur O'Dwyer "unimplemented": True, 1937bfaa0f0STobias Hieta }, 1947bfaa0f0STobias Hieta { 1957656dd33SLouis Dionne "name": "__cpp_lib_atomic_value_initialization", 196ff1b6f9fSArthur O'Dwyer "values": {"c++20": 201911}, 197fc4bff0cSOlivier Giroux "headers": ["atomic", "memory"], 1987bfaa0f0STobias Hieta }, 1997bfaa0f0STobias Hieta { 200ff1b6f9fSArthur O'Dwyer "name": "__cpp_lib_atomic_wait", 201ff1b6f9fSArthur O'Dwyer "values": {"c++20": 201907}, 202ff1b6f9fSArthur O'Dwyer "headers": ["atomic"], 20312563ea6Sphilnik777 "test_suite_guard": "!defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_SYNC", 20412563ea6Sphilnik777 "libcxx_guard": "_LIBCPP_AVAILABILITY_HAS_SYNC", 2057bfaa0f0STobias Hieta }, 2067bfaa0f0STobias Hieta { 207466df171SArthur O'Dwyer "name": "__cpp_lib_barrier", 208466df171SArthur O'Dwyer "values": {"c++20": 201907}, 209466df171SArthur O'Dwyer "headers": ["barrier"], 210c6f3b7bcSNikolas Klauser "test_suite_guard": "!defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC)", 211c6f3b7bcSNikolas Klauser "libcxx_guard": "_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC", 2127bfaa0f0STobias Hieta }, 2137bfaa0f0STobias Hieta { 214a5b4479dSNikolas Klauser "name": "__cpp_lib_bind_back", 2153f05d044SMark de Wever "values": { 2163f05d044SMark de Wever "c++23": 202202, 217c8917048SJakub Mazurkiewicz # "c++26": 202306, # P2714R1 Bind front and back to NTTP callables 2183f05d044SMark de Wever }, 219a5b4479dSNikolas Klauser "headers": ["functional"], 2207bfaa0f0STobias Hieta }, 2217bfaa0f0STobias Hieta { 222ff1b6f9fSArthur O'Dwyer "name": "__cpp_lib_bind_front", 2233f05d044SMark de Wever "values": { 2243f05d044SMark de Wever "c++20": 201907, 2253f05d044SMark de Wever "c++26": 202306, # P2714R1 Bind front and back to NTTP callables 2263f05d044SMark de Wever }, 227ff1b6f9fSArthur O'Dwyer "headers": ["functional"], 2287bfaa0f0STobias Hieta }, 2297bfaa0f0STobias Hieta { 230ff1b6f9fSArthur O'Dwyer "name": "__cpp_lib_bit_cast", 231ff1b6f9fSArthur O'Dwyer "values": {"c++20": 201806}, 232ff1b6f9fSArthur O'Dwyer "headers": ["bit"], 2337bfaa0f0STobias Hieta }, 2347bfaa0f0STobias Hieta { 235466df171SArthur O'Dwyer "name": "__cpp_lib_bitops", 236466df171SArthur O'Dwyer "values": {"c++20": 201907}, 237466df171SArthur O'Dwyer "headers": ["bit"], 2387bfaa0f0STobias Hieta }, 2397bfaa0f0STobias Hieta { 2403f05d044SMark de Wever "name": "__cpp_lib_bitset", 2413f05d044SMark de Wever "values": {"c++26": 202306}, # P2697R1 Interfacing bitset with string_view 2423f05d044SMark de Wever "headers": ["bitset"], 2433f05d044SMark de Wever }, 2443f05d044SMark de Wever { 245ff1b6f9fSArthur O'Dwyer "name": "__cpp_lib_bool_constant", 246ff1b6f9fSArthur O'Dwyer "values": {"c++17": 201505}, 247ff1b6f9fSArthur O'Dwyer "headers": ["type_traits"], 2487bfaa0f0STobias Hieta }, 2497bfaa0f0STobias Hieta { 250466df171SArthur O'Dwyer "name": "__cpp_lib_bounded_array_traits", 251466df171SArthur O'Dwyer "values": {"c++20": 201902}, 252466df171SArthur O'Dwyer "headers": ["type_traits"], 2537bfaa0f0STobias Hieta }, 2547bfaa0f0STobias Hieta { 255ff1b6f9fSArthur O'Dwyer "name": "__cpp_lib_boyer_moore_searcher", 256ff1b6f9fSArthur O'Dwyer "values": {"c++17": 201603}, 257ff1b6f9fSArthur O'Dwyer "headers": ["functional"], 2587bfaa0f0STobias Hieta }, 2597bfaa0f0STobias Hieta { 260ff1b6f9fSArthur O'Dwyer "name": "__cpp_lib_byte", 261ff1b6f9fSArthur O'Dwyer "values": {"c++17": 201603}, 262ff1b6f9fSArthur O'Dwyer "headers": ["cstddef"], 2637bfaa0f0STobias Hieta }, 2647bfaa0f0STobias Hieta { 2651dc62f26SNikolas Klauser "name": "__cpp_lib_byteswap", 26671400505SMark de Wever "values": {"c++23": 202110}, 2671dc62f26SNikolas Klauser "headers": ["bit"], 2687bfaa0f0STobias Hieta }, 2697bfaa0f0STobias Hieta { 270ff1b6f9fSArthur O'Dwyer "name": "__cpp_lib_char8_t", 271309aed30SNikolas Klauser "values": {"c++20": 201907}, 2727bfaa0f0STobias Hieta "headers": [ 2737bfaa0f0STobias Hieta "atomic", 2747bfaa0f0STobias Hieta "filesystem", 2757bfaa0f0STobias Hieta "istream", 2767bfaa0f0STobias Hieta "limits", 2777bfaa0f0STobias Hieta "locale", 2787bfaa0f0STobias Hieta "ostream", 2797bfaa0f0STobias Hieta "string", 2807bfaa0f0STobias Hieta "string_view", 2817bfaa0f0STobias Hieta ], 282c2c68a59SMark de Wever "test_suite_guard": "defined(__cpp_char8_t)", 283ba87515fSNikolas Klauser "libcxx_guard": "_LIBCPP_HAS_CHAR8_T", 2847bfaa0f0STobias Hieta }, 2857bfaa0f0STobias Hieta { 286ff1b6f9fSArthur O'Dwyer "name": "__cpp_lib_chrono", 2873f05d044SMark de Wever "values": { 2883f05d044SMark de Wever "c++17": 201611, 2893f05d044SMark de Wever # "c++26": 202306, # P2592R3 Hashing support for std::chrono value classes 2903f05d044SMark de Wever }, 291ff1b6f9fSArthur O'Dwyer "headers": ["chrono"], 2927bfaa0f0STobias Hieta }, 2937bfaa0f0STobias Hieta { 294ff1b6f9fSArthur O'Dwyer "name": "__cpp_lib_chrono_udls", 295ff1b6f9fSArthur O'Dwyer "values": {"c++14": 201304}, 296ff1b6f9fSArthur O'Dwyer "headers": ["chrono"], 2977bfaa0f0STobias Hieta }, 2987bfaa0f0STobias Hieta { 299ff1b6f9fSArthur O'Dwyer "name": "__cpp_lib_clamp", 300ff1b6f9fSArthur O'Dwyer "values": {"c++17": 201603}, 301ff1b6f9fSArthur O'Dwyer "headers": ["algorithm"], 3027bfaa0f0STobias Hieta }, 3037bfaa0f0STobias Hieta { 304ff1b6f9fSArthur O'Dwyer "name": "__cpp_lib_complex_udls", 305ff1b6f9fSArthur O'Dwyer "values": {"c++14": 201309}, 306ff1b6f9fSArthur O'Dwyer "headers": ["complex"], 3077bfaa0f0STobias Hieta }, 3087bfaa0f0STobias Hieta { 309ff1b6f9fSArthur O'Dwyer "name": "__cpp_lib_concepts", 310466df171SArthur O'Dwyer "values": {"c++20": 202002}, 311ff1b6f9fSArthur O'Dwyer "headers": ["concepts"], 3127bfaa0f0STobias Hieta }, 3137bfaa0f0STobias Hieta { 314466df171SArthur O'Dwyer "name": "__cpp_lib_constexpr_algorithms", 3153f05d044SMark de Wever "values": { 3163f05d044SMark de Wever "c++20": 201806, 3173f05d044SMark de Wever # "c++26": 202306, # P2562R1 constexpr Stable Sorting 3183f05d044SMark de Wever }, 3192b6ce25aSMark de Wever "headers": ["algorithm", "utility"], 3207bfaa0f0STobias Hieta }, 3217bfaa0f0STobias Hieta { 322f02120fbSNikolas Klauser "name": "__cpp_lib_constexpr_bitset", 32371400505SMark de Wever "values": {"c++23": 202207}, 324f02120fbSNikolas Klauser "headers": ["bitset"], 3257bfaa0f0STobias Hieta }, 3267bfaa0f0STobias Hieta { 327a1e13a80SMark de Wever "name": "__cpp_lib_constexpr_charconv", 32871400505SMark de Wever "values": {"c++23": 202207}, 329a1e13a80SMark de Wever "headers": ["charconv"], 3307bfaa0f0STobias Hieta }, 3317bfaa0f0STobias Hieta { 332a5b4479dSNikolas Klauser "name": "__cpp_lib_constexpr_cmath", 33371400505SMark de Wever "values": {"c++23": 202202}, 334a5b4479dSNikolas Klauser "headers": ["cmath", "cstdlib"], 335a5b4479dSNikolas Klauser "unimplemented": True, 3367bfaa0f0STobias Hieta }, 3377bfaa0f0STobias Hieta { 338466df171SArthur O'Dwyer "name": "__cpp_lib_constexpr_complex", 339466df171SArthur O'Dwyer "values": {"c++20": 201711}, 340466df171SArthur O'Dwyer "headers": ["complex"], 3417bfaa0f0STobias Hieta }, 3427bfaa0f0STobias Hieta { 3437656dd33SLouis Dionne "name": "__cpp_lib_constexpr_dynamic_alloc", 344ff1b6f9fSArthur O'Dwyer "values": {"c++20": 201907}, 345ff1b6f9fSArthur O'Dwyer "headers": ["memory"], 3467bfaa0f0STobias Hieta }, 3477bfaa0f0STobias Hieta { 348ff1b6f9fSArthur O'Dwyer "name": "__cpp_lib_constexpr_functional", 349ff1b6f9fSArthur O'Dwyer "values": {"c++20": 201907}, 350ff1b6f9fSArthur O'Dwyer "headers": ["functional"], 3517bfaa0f0STobias Hieta }, 3527bfaa0f0STobias Hieta { 353466df171SArthur O'Dwyer "name": "__cpp_lib_constexpr_iterator", 354466df171SArthur O'Dwyer "values": {"c++20": 201811}, 355466df171SArthur O'Dwyer "headers": ["iterator"], 3567bfaa0f0STobias Hieta }, 3577bfaa0f0STobias Hieta { 358466df171SArthur O'Dwyer "name": "__cpp_lib_constexpr_memory", 35971400505SMark de Wever "values": {"c++20": 201811, "c++23": 202202}, 360466df171SArthur O'Dwyer "headers": ["memory"], 3617bfaa0f0STobias Hieta }, 3627bfaa0f0STobias Hieta { 3632dadf8d7SMark de Wever "name": "__cpp_lib_constexpr_new", 3642dadf8d7SMark de Wever "values": {"c++26": 202406}, # P2747R2 constexpr placement new 3652dadf8d7SMark de Wever "headers": ["new"], 3667808541fSA. Jiang "test_suite_guard": "!defined(_LIBCPP_ABI_VCRUNTIME)", 3677808541fSA. Jiang "libcxx_guard": "!defined(_LIBCPP_ABI_VCRUNTIME)", 3682dadf8d7SMark de Wever }, 3692dadf8d7SMark de Wever { 370ff1b6f9fSArthur O'Dwyer "name": "__cpp_lib_constexpr_numeric", 371ff1b6f9fSArthur O'Dwyer "values": {"c++20": 201911}, 372ff1b6f9fSArthur O'Dwyer "headers": ["numeric"], 3737bfaa0f0STobias Hieta }, 3747bfaa0f0STobias Hieta { 375466df171SArthur O'Dwyer "name": "__cpp_lib_constexpr_string", 376425620ccSNikolas Klauser "values": {"c++20": 201907}, 377466df171SArthur O'Dwyer "headers": ["string"], 3787bfaa0f0STobias Hieta }, 3797bfaa0f0STobias Hieta { 380466df171SArthur O'Dwyer "name": "__cpp_lib_constexpr_string_view", 381466df171SArthur O'Dwyer "values": {"c++20": 201811}, 382466df171SArthur O'Dwyer "headers": ["string_view"], 3837bfaa0f0STobias Hieta }, 3847bfaa0f0STobias Hieta { 385466df171SArthur O'Dwyer "name": "__cpp_lib_constexpr_tuple", 386466df171SArthur O'Dwyer "values": {"c++20": 201811}, 387466df171SArthur O'Dwyer "headers": ["tuple"], 3887bfaa0f0STobias Hieta }, 3897bfaa0f0STobias Hieta { 390855d7bedSArthur O'Dwyer "name": "__cpp_lib_constexpr_typeinfo", 39171400505SMark de Wever "values": {"c++23": 202106}, 392855d7bedSArthur O'Dwyer "headers": ["typeinfo"], 3937bfaa0f0STobias Hieta }, 3947bfaa0f0STobias Hieta { 395ff1b6f9fSArthur O'Dwyer "name": "__cpp_lib_constexpr_utility", 396ff1b6f9fSArthur O'Dwyer "values": {"c++20": 201811}, 397ff1b6f9fSArthur O'Dwyer "headers": ["utility"], 3987bfaa0f0STobias Hieta }, 3997bfaa0f0STobias Hieta { 400466df171SArthur O'Dwyer "name": "__cpp_lib_constexpr_vector", 401466df171SArthur O'Dwyer "values": {"c++20": 201907}, 402466df171SArthur O'Dwyer "headers": ["vector"], 4037bfaa0f0STobias Hieta }, 4047bfaa0f0STobias Hieta { 405b699a9baSLouis Dionne "name": "__cpp_lib_constrained_equality", 406b699a9baSLouis Dionne "values": {"c++26": 202403}, # P2944R3: Comparisons for reference_wrapper 407b699a9baSLouis Dionne "headers": ["optional", "tuple", "utility", "variant"], 408b699a9baSLouis Dionne "unimplemented": True, 409b699a9baSLouis Dionne }, 410b699a9baSLouis Dionne { 411028f1b07Skrzysdz "name": "__cpp_lib_containers_ranges", 412028f1b07Skrzysdz "values": {"c++23": 202202}, 413028f1b07Skrzysdz "headers": [ 414028f1b07Skrzysdz "deque", 415028f1b07Skrzysdz "forward_list", 416028f1b07Skrzysdz "list", 417028f1b07Skrzysdz "map", 418028f1b07Skrzysdz "queue", 419028f1b07Skrzysdz "set", 420028f1b07Skrzysdz "stack", 421028f1b07Skrzysdz "string", 422028f1b07Skrzysdz "unordered_map", 423028f1b07Skrzysdz "unordered_set", 424028f1b07Skrzysdz "vector", 425028f1b07Skrzysdz ], 426028f1b07Skrzysdz }, 427028f1b07Skrzysdz { 4283f05d044SMark de Wever "name": "__cpp_lib_copyable_function", 4293f05d044SMark de Wever "values": {"c++26": 202306}, # P2548R6 copyable_function 4303f05d044SMark de Wever "headers": ["functional"], 4313f05d044SMark de Wever "unimplemented": True, 4323f05d044SMark de Wever }, 4333f05d044SMark de Wever { 434466df171SArthur O'Dwyer "name": "__cpp_lib_coroutine", 435466df171SArthur O'Dwyer "values": {"c++20": 201902}, 436466df171SArthur O'Dwyer "headers": ["coroutine"], 4377bfaa0f0STobias Hieta }, 4387bfaa0f0STobias Hieta { 439f49ccca8SMark de Wever "name": "__cpp_lib_debugging", 440b699a9baSLouis Dionne "values": { 441b699a9baSLouis Dionne "c++26": 202311, # P2546R5 Debugging Support 442b699a9baSLouis Dionne # "c++26": 202403, # P2810R4: is_debugger_present is_replaceable 443b699a9baSLouis Dionne }, 444f49ccca8SMark de Wever "headers": ["debugging"], 445f49ccca8SMark de Wever "unimplemented": True, 446f49ccca8SMark de Wever }, 447f49ccca8SMark de Wever { 448b699a9baSLouis Dionne "name": "__cpp_lib_default_template_type_for_algorithm_values", 449b699a9baSLouis Dionne "values": {"c++26": 202403}, # P2248R8: Enabling list-initialization for algorithms 450b699a9baSLouis Dionne "headers": ["algorithm", "deque", "forward_list", "list", "ranges", "string", "vector"], 451b699a9baSLouis Dionne "unimplemented": True, 452b699a9baSLouis Dionne }, 453b699a9baSLouis Dionne { 454ff1b6f9fSArthur O'Dwyer "name": "__cpp_lib_destroying_delete", 455ff1b6f9fSArthur O'Dwyer "values": {"c++20": 201806}, 456ff1b6f9fSArthur O'Dwyer "headers": ["new"], 457c2c68a59SMark de Wever "test_suite_guard": "TEST_STD_VER > 17 && defined(__cpp_impl_destroying_delete) && __cpp_impl_destroying_delete >= 201806L", 4584f15267dSNikolas Klauser "libcxx_guard": "_LIBCPP_STD_VER >= 20 && defined(__cpp_impl_destroying_delete) && __cpp_impl_destroying_delete >= 201806L", 4597bfaa0f0STobias Hieta }, 4607bfaa0f0STobias Hieta { 461ff1b6f9fSArthur O'Dwyer "name": "__cpp_lib_enable_shared_from_this", 462ff1b6f9fSArthur O'Dwyer "values": {"c++17": 201603}, 463ff1b6f9fSArthur O'Dwyer "headers": ["memory"], 4647bfaa0f0STobias Hieta }, 4657bfaa0f0STobias Hieta { 466ff1b6f9fSArthur O'Dwyer "name": "__cpp_lib_endian", 467ff1b6f9fSArthur O'Dwyer "values": {"c++20": 201907}, 468ff1b6f9fSArthur O'Dwyer "headers": ["bit"], 4697bfaa0f0STobias Hieta }, 4707bfaa0f0STobias Hieta { 471ff1b6f9fSArthur O'Dwyer "name": "__cpp_lib_erase_if", 472ff1b6f9fSArthur O'Dwyer "values": {"c++20": 202002}, 4737bfaa0f0STobias Hieta "headers": [ 4747bfaa0f0STobias Hieta "deque", 4757bfaa0f0STobias Hieta "forward_list", 4767bfaa0f0STobias Hieta "list", 4777bfaa0f0STobias Hieta "map", 4787bfaa0f0STobias Hieta "set", 4797bfaa0f0STobias Hieta "string", 4807bfaa0f0STobias Hieta "unordered_map", 4817bfaa0f0STobias Hieta "unordered_set", 4827bfaa0f0STobias Hieta "vector", 4837bfaa0f0STobias Hieta ], 4847bfaa0f0STobias Hieta }, 4857bfaa0f0STobias Hieta { 486ff1b6f9fSArthur O'Dwyer "name": "__cpp_lib_exchange_function", 487ff1b6f9fSArthur O'Dwyer "values": {"c++14": 201304}, 488ff1b6f9fSArthur O'Dwyer "headers": ["utility"], 4897bfaa0f0STobias Hieta }, 4907bfaa0f0STobias Hieta { 491ff1b6f9fSArthur O'Dwyer "name": "__cpp_lib_execution", 492466df171SArthur O'Dwyer "values": {"c++17": 201603, "c++20": 201902}, 493ff1b6f9fSArthur O'Dwyer "headers": ["execution"], 494ff1b6f9fSArthur O'Dwyer "unimplemented": True, 4957bfaa0f0STobias Hieta }, 4967bfaa0f0STobias Hieta { 497e356f681SHui Xie "name": "__cpp_lib_expected", 49871400505SMark de Wever "values": {"c++23": 202211}, 499e356f681SHui Xie "headers": ["expected"], 5007bfaa0f0STobias Hieta }, 5017bfaa0f0STobias Hieta { 502ff1b6f9fSArthur O'Dwyer "name": "__cpp_lib_filesystem", 503ff1b6f9fSArthur O'Dwyer "values": {"c++17": 201703}, 504ff1b6f9fSArthur O'Dwyer "headers": ["filesystem"], 505c6f3b7bcSNikolas Klauser "test_suite_guard": "!defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_FILESYSTEM && _LIBCPP_AVAILABILITY_HAS_FILESYSTEM_LIBRARY)", 506c6f3b7bcSNikolas Klauser "libcxx_guard": "_LIBCPP_HAS_FILESYSTEM && _LIBCPP_AVAILABILITY_HAS_FILESYSTEM_LIBRARY", 5077bfaa0f0STobias Hieta }, 5087bfaa0f0STobias Hieta { 509*def50f70SHui "name": "__cpp_lib_flat_map", 510*def50f70SHui "values": {"c++23": 202207}, 511*def50f70SHui "headers": ["flat_map"], 512*def50f70SHui }, 513*def50f70SHui { 514*def50f70SHui "name": "__cpp_lib_flat_set", 515*def50f70SHui "values": {"c++23": 202207}, 516*def50f70SHui "headers": ["flat_set"], 517*def50f70SHui "unimplemented": True, 518*def50f70SHui }, 519*def50f70SHui { 520081c1db0SMark de Wever "name": "__cpp_lib_format", 521b490c8a6SMark de Wever "values": { 522deeb9368SMark de Wever "c++20": 202110, 523b490c8a6SMark de Wever # "c++23": 202207, Not implemented P2419R2 Clarify handling of encodings in localized formatting of chrono types 52427e67cdbSHristo Hristov # "c++26": 202306, P2637R3 Member Visit (implemented) 52592d9f232SMark de Wever # "c++26": 202311, P2918R2 Runtime format strings II (implemented) 526b490c8a6SMark de Wever }, 5273f05d044SMark de Wever # Note these three papers are adopted at the June 2023 meeting and have sequential numbering 528a9e5773fSMark de Wever # 202304 P2510R3 Formatting pointers (Implemented) 5293f05d044SMark de Wever # 202305 P2757R3 Type-checking format args 5303f05d044SMark de Wever # 202306 P2637R3 Member Visit 531081c1db0SMark de Wever "headers": ["format"], 5327bfaa0f0STobias Hieta }, 5337bfaa0f0STobias Hieta { 534b699a9baSLouis Dionne "name": "__cpp_lib_format_path", 535a4bef0caSStephan T. Lavavej "values": {"c++26": 202403}, # P2845R8: Formatting of std::filesystem::path 536b699a9baSLouis Dionne "headers": ["filesystem"], 537b699a9baSLouis Dionne "unimplemented": True, 538b699a9baSLouis Dionne }, 539b699a9baSLouis Dionne { 540b2373540SMark de Wever "name": "__cpp_lib_format_ranges", 54171400505SMark de Wever "values": {"c++23": 202207}, 542b2373540SMark de Wever "headers": ["format"], 5437bfaa0f0STobias Hieta }, 5447bfaa0f0STobias Hieta { 545f49ccca8SMark de Wever "name": "__cpp_lib_format_uchar", 546f49ccca8SMark de Wever "values": { 547f49ccca8SMark de Wever "c++20": 202311 # DR P2909R4 Fix formatting of code units as integers 548f49ccca8SMark de Wever }, 5499c18f031SMark de Wever "headers": [ 5509c18f031SMark de Wever "format" # TODO verify this entry since the paper was underspecified. 5519c18f031SMark de Wever ], 552f49ccca8SMark de Wever }, 553f49ccca8SMark de Wever { 55488622aabSMark de Wever "name": "__cpp_lib_formatters", 55571400505SMark de Wever "values": {"c++23": 202302}, 55688622aabSMark de Wever "headers": ["stacktrace", "thread"], 55788622aabSMark de Wever "unimplemented": True, 5587bfaa0f0STobias Hieta }, 5597bfaa0f0STobias Hieta { 5603a49cffeSIgor Zhukov "name": "__cpp_lib_forward_like", 56171400505SMark de Wever "values": {"c++23": 202207}, 5623a49cffeSIgor Zhukov "headers": ["utility"], 5637bfaa0f0STobias Hieta }, 5647bfaa0f0STobias Hieta { 565f49ccca8SMark de Wever "name": "__cpp_lib_freestanding_algorithm", 566f49ccca8SMark de Wever "values": { 567f49ccca8SMark de Wever "c++26": 202311 # P2407R5 Freestanding Library: Partial Classes 568f49ccca8SMark de Wever }, 569f49ccca8SMark de Wever "headers": ["algorithm"], 570f49ccca8SMark de Wever "unimplemented": True, 571f49ccca8SMark de Wever }, 572f49ccca8SMark de Wever { 573f49ccca8SMark de Wever "name": "__cpp_lib_freestanding_array", 574f49ccca8SMark de Wever "values": { 575f49ccca8SMark de Wever "c++26": 202311 # P2407R5 Freestanding Library: Partial Classes 576f49ccca8SMark de Wever }, 577f49ccca8SMark de Wever "headers": ["array"], 578f49ccca8SMark de Wever "unimplemented": True, 579f49ccca8SMark de Wever }, 580f49ccca8SMark de Wever { 581f49ccca8SMark de Wever "name": "__cpp_lib_freestanding_cstring", 582f49ccca8SMark de Wever "values": { 583f49ccca8SMark de Wever "c++26": 202306 # P2338R4 Freestanding Library: Character primitives and the C library 584f49ccca8SMark de Wever # 202311 # P2407R5 Freestanding Library: Partial Classes 585f49ccca8SMark de Wever }, 586f49ccca8SMark de Wever "headers": ["cstring"], 587f49ccca8SMark de Wever "unimplemented": True, 588f49ccca8SMark de Wever }, 589f49ccca8SMark de Wever { 590f49ccca8SMark de Wever "name": "__cpp_lib_freestanding_expected", 591f49ccca8SMark de Wever "values": { 592f49ccca8SMark de Wever "c++26": 202311 # P2833R2 Freestanding Library: inout expected span 593f49ccca8SMark de Wever }, 594f49ccca8SMark de Wever "headers": ["expected"], 595f49ccca8SMark de Wever "unimplemented": True, 596f49ccca8SMark de Wever }, 597f49ccca8SMark de Wever { 598f49ccca8SMark de Wever "name": "__cpp_lib_freestanding_mdspan", 599f49ccca8SMark de Wever "values": { 600f49ccca8SMark de Wever "c++26": 202311 # P2833R2 Freestanding Library: inout expected span 601f49ccca8SMark de Wever }, 602f49ccca8SMark de Wever "headers": ["mdspan"], 603f49ccca8SMark de Wever "unimplemented": True, 604f49ccca8SMark de Wever }, 605f49ccca8SMark de Wever { 606f49ccca8SMark de Wever "name": "__cpp_lib_freestanding_optional", 607f49ccca8SMark de Wever "values": { 608f49ccca8SMark de Wever "c++26": 202311 # P2407R5 Freestanding Library: Partial Classes 609f49ccca8SMark de Wever }, 610f49ccca8SMark de Wever "headers": ["optional"], 611f49ccca8SMark de Wever "unimplemented": True, 612f49ccca8SMark de Wever }, 613f49ccca8SMark de Wever { 614f49ccca8SMark de Wever "name": "__cpp_lib_freestanding_string_view", 615f49ccca8SMark de Wever "values": { 616f49ccca8SMark de Wever "c++26": 202311 # P2407R5 Freestanding Library: Partial Classes 617f49ccca8SMark de Wever }, 618f49ccca8SMark de Wever "headers": ["string_view"], 619f49ccca8SMark de Wever "unimplemented": True, 620f49ccca8SMark de Wever }, 621f49ccca8SMark de Wever { 622f49ccca8SMark de Wever "name": "__cpp_lib_freestanding_variant", 623f49ccca8SMark de Wever "values": { 624f49ccca8SMark de Wever "c++26": 202311 # P2407R5 Freestanding Library: Partial Classes 625f49ccca8SMark de Wever }, 626f49ccca8SMark de Wever "headers": ["variant"], 627f49ccca8SMark de Wever "unimplemented": True, 628f49ccca8SMark de Wever }, 629f49ccca8SMark de Wever { 6303f05d044SMark de Wever "name": "__cpp_lib_fstream_native_handle", 6313f05d044SMark de Wever "values": {"c++26": 202306}, # P1759R6 Native handles and file streams 6323f05d044SMark de Wever "headers": ["fstream"], 633c6f3b7bcSNikolas Klauser "test_suite_guard": "!defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_FILESYSTEM && _LIBCPP_HAS_LOCALIZATION)", 634c6f3b7bcSNikolas Klauser "libcxx_guard": "_LIBCPP_HAS_FILESYSTEM && _LIBCPP_HAS_LOCALIZATION", 6353f05d044SMark de Wever }, 6363f05d044SMark de Wever { 6373f05d044SMark de Wever "name": "__cpp_lib_function_ref", 638f49ccca8SMark de Wever "values": { 639f49ccca8SMark de Wever "c++26": 202306 # P0792R14 function_ref: a type-erased callable reference 640f49ccca8SMark de Wever }, 6413f05d044SMark de Wever "headers": ["functional"], 6423f05d044SMark de Wever "unimplemented": True, 6433f05d044SMark de Wever }, 6443f05d044SMark de Wever { 645ff1b6f9fSArthur O'Dwyer "name": "__cpp_lib_gcd_lcm", 646ff1b6f9fSArthur O'Dwyer "values": {"c++17": 201606}, 647ff1b6f9fSArthur O'Dwyer "headers": ["numeric"], 6487bfaa0f0STobias Hieta }, 6497bfaa0f0STobias Hieta { 650b699a9baSLouis Dionne "name": "__cpp_lib_generate_random", 651b699a9baSLouis Dionne "values": {"c++26": 202403}, # P1068R11: Vector API for random number generation 652b699a9baSLouis Dionne "headers": ["random"], 653b699a9baSLouis Dionne "unimplemented": True, 654b699a9baSLouis Dionne }, 655b699a9baSLouis Dionne { 656ff1b6f9fSArthur O'Dwyer "name": "__cpp_lib_generic_associative_lookup", 657ff1b6f9fSArthur O'Dwyer "values": {"c++14": 201304}, 658ff1b6f9fSArthur O'Dwyer "headers": ["map", "set"], 6597bfaa0f0STobias Hieta }, 6607bfaa0f0STobias Hieta { 661ff1b6f9fSArthur O'Dwyer "name": "__cpp_lib_generic_unordered_lookup", 662ff1b6f9fSArthur O'Dwyer "values": {"c++20": 201811}, 663ff1b6f9fSArthur O'Dwyer "headers": ["unordered_map", "unordered_set"], 6647bfaa0f0STobias Hieta }, 6657bfaa0f0STobias Hieta { 666ff1b6f9fSArthur O'Dwyer "name": "__cpp_lib_hardware_interference_size", 667ff1b6f9fSArthur O'Dwyer "values": {"c++17": 201703}, 6688f018d3cSStephan T. Lavavej "test_suite_guard": "!defined(_LIBCPP_VERSION) || (defined(__GCC_DESTRUCTIVE_SIZE) && defined(__GCC_CONSTRUCTIVE_SIZE))", 66956a33ba3SNikolas Klauser "libcxx_guard": "defined(__GCC_DESTRUCTIVE_SIZE) && defined(__GCC_CONSTRUCTIVE_SIZE)", 670ff1b6f9fSArthur O'Dwyer "headers": ["new"], 6717bfaa0f0STobias Hieta }, 6727bfaa0f0STobias Hieta { 673ff1b6f9fSArthur O'Dwyer "name": "__cpp_lib_has_unique_object_representations", 674ff1b6f9fSArthur O'Dwyer "values": {"c++17": 201606}, 675ff1b6f9fSArthur O'Dwyer "headers": ["type_traits"], 6767bfaa0f0STobias Hieta }, 6777bfaa0f0STobias Hieta { 6783f05d044SMark de Wever "name": "__cpp_lib_hazard_pointer", 6793f05d044SMark de Wever "values": {"c++26": 202306}, # P2530R3 Hazard Pointers for C++26 680f49ccca8SMark de Wever "headers": [ 681f49ccca8SMark de Wever "hazard_pointer" # TODO verify this entry since the paper was underspecified. 682f49ccca8SMark de Wever ], 6833f05d044SMark de Wever "unimplemented": True, 6843f05d044SMark de Wever }, 6853f05d044SMark de Wever { 686ff1b6f9fSArthur O'Dwyer "name": "__cpp_lib_hypot", 687ff1b6f9fSArthur O'Dwyer "values": {"c++17": 201603}, 688ff1b6f9fSArthur O'Dwyer "headers": ["cmath"], 6897bfaa0f0STobias Hieta }, 6907bfaa0f0STobias Hieta { 691ff1b6f9fSArthur O'Dwyer "name": "__cpp_lib_incomplete_container_elements", 692ff1b6f9fSArthur O'Dwyer "values": {"c++17": 201505}, 693ff1b6f9fSArthur O'Dwyer "headers": ["forward_list", "list", "vector"], 6947bfaa0f0STobias Hieta }, 6957bfaa0f0STobias Hieta { 6962dadf8d7SMark de Wever "name": "__cpp_lib_inplace_vector", 6972dadf8d7SMark de Wever "values": {"c++26": 202406}, # P0843R14 inplace_vector 6982dadf8d7SMark de Wever "headers": ["inplace_vector"], 6992dadf8d7SMark de Wever "unimplemented": True, 7002dadf8d7SMark de Wever }, 7012dadf8d7SMark de Wever { 702ff1b6f9fSArthur O'Dwyer "name": "__cpp_lib_int_pow2", 703ff1b6f9fSArthur O'Dwyer "values": {"c++20": 202002}, 704ff1b6f9fSArthur O'Dwyer "headers": ["bit"], 7057bfaa0f0STobias Hieta }, 7067bfaa0f0STobias Hieta { 707466df171SArthur O'Dwyer "name": "__cpp_lib_integer_comparison_functions", 708466df171SArthur O'Dwyer "values": {"c++20": 202002}, 709466df171SArthur O'Dwyer "headers": ["utility"], 7107bfaa0f0STobias Hieta }, 7117bfaa0f0STobias Hieta { 712ff1b6f9fSArthur O'Dwyer "name": "__cpp_lib_integer_sequence", 713ff1b6f9fSArthur O'Dwyer "values": {"c++14": 201304}, 714ff1b6f9fSArthur O'Dwyer "headers": ["utility"], 7157bfaa0f0STobias Hieta }, 7167bfaa0f0STobias Hieta { 717ff1b6f9fSArthur O'Dwyer "name": "__cpp_lib_integral_constant_callable", 718ff1b6f9fSArthur O'Dwyer "values": {"c++14": 201304}, 719ff1b6f9fSArthur O'Dwyer "headers": ["type_traits"], 7207bfaa0f0STobias Hieta }, 7217bfaa0f0STobias Hieta { 722ff1b6f9fSArthur O'Dwyer "name": "__cpp_lib_interpolate", 723ff1b6f9fSArthur O'Dwyer "values": {"c++20": 201902}, 724466df171SArthur O'Dwyer "headers": ["cmath", "numeric"], 7257bfaa0f0STobias Hieta }, 7267bfaa0f0STobias Hieta { 727ff1b6f9fSArthur O'Dwyer "name": "__cpp_lib_invoke", 728ff1b6f9fSArthur O'Dwyer "values": {"c++17": 201411}, 729ff1b6f9fSArthur O'Dwyer "headers": ["functional"], 7307bfaa0f0STobias Hieta }, 7317bfaa0f0STobias Hieta { 732855d7bedSArthur O'Dwyer "name": "__cpp_lib_invoke_r", 73371400505SMark de Wever "values": {"c++23": 202106}, 734855d7bedSArthur O'Dwyer "headers": ["functional"], 7357bfaa0f0STobias Hieta }, 7367bfaa0f0STobias Hieta { 737a3f17ba3SPragmaTwice "name": "__cpp_lib_ios_noreplace", 738a3f17ba3SPragmaTwice "values": {"c++23": 202207}, 739a3f17ba3SPragmaTwice "headers": ["ios"], 740a3f17ba3SPragmaTwice }, 741a3f17ba3SPragmaTwice { 742ff1b6f9fSArthur O'Dwyer "name": "__cpp_lib_is_aggregate", 743ff1b6f9fSArthur O'Dwyer "values": {"c++17": 201703}, 744ff1b6f9fSArthur O'Dwyer "headers": ["type_traits"], 7457bfaa0f0STobias Hieta }, 7467bfaa0f0STobias Hieta { 747ff1b6f9fSArthur O'Dwyer "name": "__cpp_lib_is_constant_evaluated", 748ff1b6f9fSArthur O'Dwyer "values": {"c++20": 201811}, 749ff1b6f9fSArthur O'Dwyer "headers": ["type_traits"], 7507bfaa0f0STobias Hieta }, 7517bfaa0f0STobias Hieta { 752ff1b6f9fSArthur O'Dwyer "name": "__cpp_lib_is_final", 753ff1b6f9fSArthur O'Dwyer "values": {"c++14": 201402}, 754ff1b6f9fSArthur O'Dwyer "headers": ["type_traits"], 7557bfaa0f0STobias Hieta }, 7567bfaa0f0STobias Hieta { 757a06591b4SHristo Hristov "name": "__cpp_lib_is_implicit_lifetime", 758a06591b4SHristo Hristov "values": {"c++23": 202302}, 759a06591b4SHristo Hristov "headers": ["type_traits"], 760a06591b4SHristo Hristov "test_suite_guard": "__has_builtin(__builtin_is_implicit_lifetime)", 761a06591b4SHristo Hristov "libcxx_guard": "__has_builtin(__builtin_is_implicit_lifetime)", 762a06591b4SHristo Hristov }, 763a06591b4SHristo Hristov { 764ff1b6f9fSArthur O'Dwyer "name": "__cpp_lib_is_invocable", 765ff1b6f9fSArthur O'Dwyer "values": {"c++17": 201703}, 766ff1b6f9fSArthur O'Dwyer "headers": ["type_traits"], 7677bfaa0f0STobias Hieta }, 7687bfaa0f0STobias Hieta { 769466df171SArthur O'Dwyer "name": "__cpp_lib_is_layout_compatible", 770466df171SArthur O'Dwyer "values": {"c++20": 201907}, 771466df171SArthur O'Dwyer "headers": ["type_traits"], 772466df171SArthur O'Dwyer "unimplemented": True, 7737bfaa0f0STobias Hieta }, 7747bfaa0f0STobias Hieta { 775466df171SArthur O'Dwyer "name": "__cpp_lib_is_nothrow_convertible", 776466df171SArthur O'Dwyer "values": {"c++20": 201806}, 777466df171SArthur O'Dwyer "headers": ["type_traits"], 7787bfaa0f0STobias Hieta }, 7797bfaa0f0STobias Hieta { 780ff1b6f9fSArthur O'Dwyer "name": "__cpp_lib_is_null_pointer", 781ff1b6f9fSArthur O'Dwyer "values": {"c++14": 201309}, 782ff1b6f9fSArthur O'Dwyer "headers": ["type_traits"], 7837bfaa0f0STobias Hieta }, 7847bfaa0f0STobias Hieta { 785466df171SArthur O'Dwyer "name": "__cpp_lib_is_pointer_interconvertible", 786466df171SArthur O'Dwyer "values": {"c++20": 201907}, 787466df171SArthur O'Dwyer "headers": ["type_traits"], 788466df171SArthur O'Dwyer "unimplemented": True, 7897bfaa0f0STobias Hieta }, 7907bfaa0f0STobias Hieta { 79195729f95SMarek Kurdej "name": "__cpp_lib_is_scoped_enum", 79271400505SMark de Wever "values": {"c++23": 202011}, 79395729f95SMarek Kurdej "headers": ["type_traits"], 7947bfaa0f0STobias Hieta }, 7957bfaa0f0STobias Hieta { 796ff1b6f9fSArthur O'Dwyer "name": "__cpp_lib_is_swappable", 797ff1b6f9fSArthur O'Dwyer "values": {"c++17": 201603}, 798ff1b6f9fSArthur O'Dwyer "headers": ["type_traits"], 7997bfaa0f0STobias Hieta }, 8007bfaa0f0STobias Hieta { 8012dadf8d7SMark de Wever "name": "__cpp_lib_is_virtual_base_of", 8022dadf8d7SMark de Wever "values": { 8032dadf8d7SMark de Wever "c++26": 202406 # P2985R0 A type trait for detecting virtual base classes 8042dadf8d7SMark de Wever }, 8052dadf8d7SMark de Wever "headers": ["type_traits"], 8061c48c9ccSLouis Dionne "test_suite_guard": "__has_builtin(__builtin_is_virtual_base_of)", 8071c48c9ccSLouis Dionne "libcxx_guard": "__has_builtin(__builtin_is_virtual_base_of)", 8082dadf8d7SMark de Wever }, 8092dadf8d7SMark de Wever { 8108f711aa3SMital Ashok "name": "__cpp_lib_is_within_lifetime", 8118f711aa3SMital Ashok # Note this name was changed from "__cpp_lib_within_lifetime" when the paper was adopted 8128f711aa3SMital Ashok # https://github.com/cplusplus/draft/commit/0facada4cadd97e1ba15bfaea76a804f1dc5c309 8138f711aa3SMital Ashok "values": { 8148f711aa3SMital Ashok "c++26": 202306 # P2641R4 Checking if a union alternative is active 8158f711aa3SMital Ashok }, 8168f711aa3SMital Ashok "headers": ["type_traits"], 8178f711aa3SMital Ashok "unimplemented": True, 8188f711aa3SMital Ashok }, 8198f711aa3SMital Ashok { 820466df171SArthur O'Dwyer "name": "__cpp_lib_jthread", 821466df171SArthur O'Dwyer "values": {"c++20": 201911}, 822466df171SArthur O'Dwyer "headers": ["stop_token", "thread"], 823c6f3b7bcSNikolas Klauser "test_suite_guard": "!defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC)", 824c6f3b7bcSNikolas Klauser "libcxx_guard": "_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC", 8257bfaa0f0STobias Hieta }, 8267bfaa0f0STobias Hieta { 827466df171SArthur O'Dwyer "name": "__cpp_lib_latch", 828466df171SArthur O'Dwyer "values": {"c++20": 201907}, 829466df171SArthur O'Dwyer "headers": ["latch"], 830c6f3b7bcSNikolas Klauser "test_suite_guard": "!defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC)", 831c6f3b7bcSNikolas Klauser "libcxx_guard": "_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC", 8327bfaa0f0STobias Hieta }, 8337bfaa0f0STobias Hieta { 834ff1b6f9fSArthur O'Dwyer "name": "__cpp_lib_launder", 835ff1b6f9fSArthur O'Dwyer "values": {"c++17": 201606}, 836ff1b6f9fSArthur O'Dwyer "headers": ["new"], 8377bfaa0f0STobias Hieta }, 8387bfaa0f0STobias Hieta { 839f49ccca8SMark de Wever "name": "__cpp_lib_linalg", 840f49ccca8SMark de Wever "values": { 841f49ccca8SMark de Wever "c++26": 202311 # P1673 A free function linear algebra interface based on the BLAS 842f49ccca8SMark de Wever }, 843f49ccca8SMark de Wever "headers": ["linalg"], 844f49ccca8SMark de Wever "unimplemented": True, 845f49ccca8SMark de Wever }, 846f49ccca8SMark de Wever { 847ff1b6f9fSArthur O'Dwyer "name": "__cpp_lib_list_remove_return_type", 848ff1b6f9fSArthur O'Dwyer "values": {"c++20": 201806}, 849ff1b6f9fSArthur O'Dwyer "headers": ["forward_list", "list"], 8507bfaa0f0STobias Hieta }, 8517bfaa0f0STobias Hieta { 852ff1b6f9fSArthur O'Dwyer "name": "__cpp_lib_logical_traits", 853ff1b6f9fSArthur O'Dwyer "values": {"c++17": 201510}, 854ff1b6f9fSArthur O'Dwyer "headers": ["type_traits"], 8557bfaa0f0STobias Hieta }, 8567bfaa0f0STobias Hieta { 857ff1b6f9fSArthur O'Dwyer "name": "__cpp_lib_make_from_tuple", 858ff1b6f9fSArthur O'Dwyer "values": {"c++17": 201606}, 859ff1b6f9fSArthur O'Dwyer "headers": ["tuple"], 8607bfaa0f0STobias Hieta }, 8617bfaa0f0STobias Hieta { 862ff1b6f9fSArthur O'Dwyer "name": "__cpp_lib_make_reverse_iterator", 863ff1b6f9fSArthur O'Dwyer "values": {"c++14": 201402}, 864ff1b6f9fSArthur O'Dwyer "headers": ["iterator"], 8657bfaa0f0STobias Hieta }, 8667bfaa0f0STobias Hieta { 867ff1b6f9fSArthur O'Dwyer "name": "__cpp_lib_make_unique", 868ff1b6f9fSArthur O'Dwyer "values": {"c++14": 201304}, 869ff1b6f9fSArthur O'Dwyer "headers": ["memory"], 8707bfaa0f0STobias Hieta }, 8717bfaa0f0STobias Hieta { 872ff1b6f9fSArthur O'Dwyer "name": "__cpp_lib_map_try_emplace", 873ff1b6f9fSArthur O'Dwyer "values": {"c++17": 201411}, 874ff1b6f9fSArthur O'Dwyer "headers": ["map"], 8757bfaa0f0STobias Hieta }, 8767bfaa0f0STobias Hieta { 877ff1b6f9fSArthur O'Dwyer "name": "__cpp_lib_math_constants", 878ff1b6f9fSArthur O'Dwyer "values": {"c++20": 201907}, 879ff1b6f9fSArthur O'Dwyer "headers": ["numbers"], 8807bfaa0f0STobias Hieta }, 8817bfaa0f0STobias Hieta { 882ff1b6f9fSArthur O'Dwyer "name": "__cpp_lib_math_special_functions", 883ff1b6f9fSArthur O'Dwyer "values": {"c++17": 201603}, 884ff1b6f9fSArthur O'Dwyer "headers": ["cmath"], 885ff1b6f9fSArthur O'Dwyer "unimplemented": True, 8867bfaa0f0STobias Hieta }, 8877bfaa0f0STobias Hieta { 888fcaccf81SChristian Trott "name": "__cpp_lib_mdspan", 8892dadf8d7SMark de Wever "values": { 8902dadf8d7SMark de Wever "c++23": 202207, 8914e338dceSXiaoyang Liu "c++26": 202406, # P2389R2 dextents Index Type Parameter 8922dadf8d7SMark de Wever }, 893fcaccf81SChristian Trott "headers": ["mdspan"], 8947bfaa0f0STobias Hieta }, 8957bfaa0f0STobias Hieta { 896ff1b6f9fSArthur O'Dwyer "name": "__cpp_lib_memory_resource", 897ff1b6f9fSArthur O'Dwyer "values": {"c++17": 201603}, 898ff1b6f9fSArthur O'Dwyer "headers": ["memory_resource"], 89912563ea6Sphilnik777 "test_suite_guard": "!defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_PMR", 90012563ea6Sphilnik777 "libcxx_guard": "_LIBCPP_AVAILABILITY_HAS_PMR", 9017bfaa0f0STobias Hieta }, 9027bfaa0f0STobias Hieta { 903759fb590SMark de Wever "name": "__cpp_lib_modules", 904759fb590SMark de Wever "values": {"c++23": 202207}, 905759fb590SMark de Wever "headers": [], 906759fb590SMark de Wever }, 907759fb590SMark de Wever { 908813e1da9SShivam kunwar "name": "__cpp_lib_move_iterator_concept", 909813e1da9SShivam kunwar "values": {"c++20": 202207}, 910813e1da9SShivam kunwar "headers": ["iterator"], 9117bfaa0f0STobias Hieta }, 9127bfaa0f0STobias Hieta { 913855d7bedSArthur O'Dwyer "name": "__cpp_lib_move_only_function", 91471400505SMark de Wever "values": {"c++23": 202110}, 915855d7bedSArthur O'Dwyer "headers": ["functional"], 916855d7bedSArthur O'Dwyer "unimplemented": True, 9177bfaa0f0STobias Hieta }, 9187bfaa0f0STobias Hieta { 919ff1b6f9fSArthur O'Dwyer "name": "__cpp_lib_node_extract", 920ff1b6f9fSArthur O'Dwyer "values": {"c++17": 201606}, 921ff1b6f9fSArthur O'Dwyer "headers": ["map", "set", "unordered_map", "unordered_set"], 9227bfaa0f0STobias Hieta }, 9237bfaa0f0STobias Hieta { 924ff1b6f9fSArthur O'Dwyer "name": "__cpp_lib_nonmember_container_access", 925ff1b6f9fSArthur O'Dwyer "values": {"c++17": 201411}, 9267bfaa0f0STobias Hieta "headers": [ 9277bfaa0f0STobias Hieta "array", 9287bfaa0f0STobias Hieta "deque", 9297bfaa0f0STobias Hieta "forward_list", 9307bfaa0f0STobias Hieta "iterator", 9317bfaa0f0STobias Hieta "list", 9327bfaa0f0STobias Hieta "map", 9337bfaa0f0STobias Hieta "regex", 9347bfaa0f0STobias Hieta "set", 9357bfaa0f0STobias Hieta "string", 9367bfaa0f0STobias Hieta "unordered_map", 9377bfaa0f0STobias Hieta "unordered_set", 9387bfaa0f0STobias Hieta "vector", 9397bfaa0f0STobias Hieta ], 9407bfaa0f0STobias Hieta }, 9417bfaa0f0STobias Hieta { 942ff1b6f9fSArthur O'Dwyer "name": "__cpp_lib_not_fn", 9433f05d044SMark de Wever "values": { 9443f05d044SMark de Wever "c++17": 201603, 945c91d805eSJakub Mazurkiewicz "c++26": 202306, # P2714R1 Bind front and back to NTTP callables 9463f05d044SMark de Wever }, 947ff1b6f9fSArthur O'Dwyer "headers": ["functional"], 9487bfaa0f0STobias Hieta }, 9497bfaa0f0STobias Hieta { 950ff1b6f9fSArthur O'Dwyer "name": "__cpp_lib_null_iterators", 951ff1b6f9fSArthur O'Dwyer "values": {"c++14": 201304}, 952ff1b6f9fSArthur O'Dwyer "headers": ["iterator"], 9537bfaa0f0STobias Hieta }, 9547bfaa0f0STobias Hieta { 955ff1b6f9fSArthur O'Dwyer "name": "__cpp_lib_optional", 956cae351f3SA. Jiang "values": { 957cae351f3SA. Jiang "c++17": 201606, 958cae351f3SA. Jiang "c++20": 202106, # P2231R1 Missing constexpr in std::optional and std::variant 959cae351f3SA. Jiang "c++23": 202110, # P0798R8 Monadic operations for std::optional + LWG3621 Remove feature-test macro __cpp_lib_monadic_optional 960cae351f3SA. Jiang }, 961ff1b6f9fSArthur O'Dwyer "headers": ["optional"], 9627bfaa0f0STobias Hieta }, 9637bfaa0f0STobias Hieta { 9642dadf8d7SMark de Wever "name": "__cpp_lib_optional_range_support", 9652dadf8d7SMark de Wever "values": {"c++26": 202406}, # P3168R2 Give std::optional Range Support 9662dadf8d7SMark de Wever "headers": ["optional"], 9672dadf8d7SMark de Wever "unimplemented": True, 9682dadf8d7SMark de Wever }, 9692dadf8d7SMark de Wever { 970855d7bedSArthur O'Dwyer "name": "__cpp_lib_out_ptr", 971f49ccca8SMark de Wever "values": { 972f49ccca8SMark de Wever "c++23": 202106, 973f49ccca8SMark de Wever "c++26": 202311, # P2833R2 Freestanding Library: inout expected span 974f49ccca8SMark de Wever }, 975855d7bedSArthur O'Dwyer "headers": ["memory"], 9767bfaa0f0STobias Hieta }, 9777bfaa0f0STobias Hieta { 978ff1b6f9fSArthur O'Dwyer "name": "__cpp_lib_parallel_algorithm", 979ff1b6f9fSArthur O'Dwyer "values": {"c++17": 201603}, 980ff1b6f9fSArthur O'Dwyer "headers": ["algorithm", "numeric"], 981ff1b6f9fSArthur O'Dwyer "unimplemented": True, 9827bfaa0f0STobias Hieta }, 9837bfaa0f0STobias Hieta { 9842dadf8d7SMark de Wever "name": "__cpp_lib_philox_engine", 9852dadf8d7SMark de Wever "values": { 9862dadf8d7SMark de Wever "c++26": 202406 9872dadf8d7SMark de Wever }, # P2075R6 Philox as an extension of the C++ RNG engines 9882dadf8d7SMark de Wever # Note the paper mentions 202310L as value, which differs from the typical procedure. 9892dadf8d7SMark de Wever "headers": ["random"], 9902dadf8d7SMark de Wever "unimplemented": True, 9912dadf8d7SMark de Wever }, 9922dadf8d7SMark de Wever { 993466df171SArthur O'Dwyer "name": "__cpp_lib_polymorphic_allocator", 994466df171SArthur O'Dwyer "values": {"c++20": 201902}, 9955d78fef6SArthur O'Dwyer "headers": ["memory_resource"], 99612563ea6Sphilnik777 "test_suite_guard": "!defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_PMR", 99712563ea6Sphilnik777 "libcxx_guard": "_LIBCPP_AVAILABILITY_HAS_PMR", 9987bfaa0f0STobias Hieta }, 9997bfaa0f0STobias Hieta { 10003f65f718SMark de Wever "name": "__cpp_lib_print", 1001b699a9baSLouis Dionne "values": { 1002b699a9baSLouis Dionne "c++23": 202207, 1003b699a9baSLouis Dionne # "c++26": 202403, # P3107R5: Permit an efficient implementation of std::print 10042dadf8d7SMark de Wever # "c++26": 202406, # P3235R3 std::print more types faster with less memory 1005b699a9baSLouis Dionne }, 10063f65f718SMark de Wever "headers": ["ostream", "print"], 10073f65f718SMark de Wever }, 10083f65f718SMark de Wever { 1009ff1b6f9fSArthur O'Dwyer "name": "__cpp_lib_quoted_string_io", 1010ff1b6f9fSArthur O'Dwyer "values": {"c++14": 201304}, 1011ff1b6f9fSArthur O'Dwyer "headers": ["iomanip"], 1012c6f3b7bcSNikolas Klauser "test_suite_guard": "!defined(_LIBCPP_VERSION) || _LIBCPP_HAS_LOCALIZATION", 1013c6f3b7bcSNikolas Klauser "libcxx_guard": "_LIBCPP_HAS_LOCALIZATION", 10147bfaa0f0STobias Hieta }, 10157bfaa0f0STobias Hieta { 1016ff1b6f9fSArthur O'Dwyer "name": "__cpp_lib_ranges", 10172dadf8d7SMark de Wever "values": { 1018026210e8SA. Jiang "c++20": 202110, # P2415R2 What is a view? 1019026210e8SA. Jiang "c++23": 202406, # P2997R1 Removing the common reference requirement from the indirectly invocable concepts (implemented as a DR against C++20) 10202dadf8d7SMark de Wever }, 1021ff1b6f9fSArthur O'Dwyer "headers": ["algorithm", "functional", "iterator", "memory", "ranges"], 10227bfaa0f0STobias Hieta }, 10237bfaa0f0STobias Hieta { 1024f49ccca8SMark de Wever "name": "__cpp_lib_ranges_as_const", 1025f49ccca8SMark de Wever "values": { 1026f49ccca8SMark de Wever "c++23": 202207 # P2278R4 cbegin should always return a constant iterator 1027f49ccca8SMark de Wever # 202311 # DR P2836R1 std::basic_const_iterator should follow its underlying type’s convertibility 1028f49ccca8SMark de Wever }, 1029f49ccca8SMark de Wever "headers": ["ranges"], 1030f49ccca8SMark de Wever "unimplemented": True, 1031f49ccca8SMark de Wever }, 1032f49ccca8SMark de Wever { 10333d4b7a6fSNikolas Klauser "name": "__cpp_lib_ranges_as_rvalue", 103471400505SMark de Wever "values": {"c++23": 202207}, 10353d4b7a6fSNikolas Klauser "headers": ["ranges"], 10367bfaa0f0STobias Hieta }, 10377bfaa0f0STobias Hieta { 1038a5b4479dSNikolas Klauser "name": "__cpp_lib_ranges_chunk", 103971400505SMark de Wever "values": {"c++23": 202202}, 1040a5b4479dSNikolas Klauser "headers": ["ranges"], 1041a5b4479dSNikolas Klauser "unimplemented": True, 10427bfaa0f0STobias Hieta }, 10437bfaa0f0STobias Hieta { 1044a5b4479dSNikolas Klauser "name": "__cpp_lib_ranges_chunk_by", 104571400505SMark de Wever "values": {"c++23": 202202}, 1046a5b4479dSNikolas Klauser "headers": ["ranges"], 10477bfaa0f0STobias Hieta }, 10487bfaa0f0STobias Hieta { 1049b699a9baSLouis Dionne "name": "__cpp_lib_ranges_concat", 1050b699a9baSLouis Dionne "values": {"c++26": 202403}, # P2542R8: views::concat 1051b699a9baSLouis Dionne "headers": ["ranges"], 1052b699a9baSLouis Dionne "unimplemented": True, 1053b699a9baSLouis Dionne }, 1054b699a9baSLouis Dionne { 10557d7d4752SZijunZhaoCCK "name": "__cpp_lib_ranges_contains", 10567d7d4752SZijunZhaoCCK "values": {"c++23": 202207}, 10577d7d4752SZijunZhaoCCK "headers": ["algorithm"], 10587d7d4752SZijunZhaoCCK }, 10597d7d4752SZijunZhaoCCK { 106004760bfaSnicole mazzuca "name": "__cpp_lib_ranges_find_last", 106104760bfaSnicole mazzuca "values": {"c++23": 202207}, 106204760bfaSnicole mazzuca "headers": ["algorithm"], 106304760bfaSnicole mazzuca }, 106404760bfaSnicole mazzuca { 1065a5b4479dSNikolas Klauser "name": "__cpp_lib_ranges_iota", 106671400505SMark de Wever "values": {"c++23": 202202}, 1067a5b4479dSNikolas Klauser "headers": ["numeric"], 1068a5b4479dSNikolas Klauser "unimplemented": True, 10697bfaa0f0STobias Hieta }, 10707bfaa0f0STobias Hieta { 1071a5b4479dSNikolas Klauser "name": "__cpp_lib_ranges_join_with", 107271400505SMark de Wever "values": {"c++23": 202202}, 1073a5b4479dSNikolas Klauser "headers": ["ranges"], 1074a5b4479dSNikolas Klauser "unimplemented": True, 10757bfaa0f0STobias Hieta }, 10767bfaa0f0STobias Hieta { 1077a2160dd3Syrong "name": "__cpp_lib_ranges_repeat", 1078a2160dd3Syrong "values": {"c++23": 202207}, 1079a2160dd3Syrong "headers": ["ranges"], 1080a2160dd3Syrong }, 1081a2160dd3Syrong { 1082a5b4479dSNikolas Klauser "name": "__cpp_lib_ranges_slide", 108371400505SMark de Wever "values": {"c++23": 202202}, 1084a5b4479dSNikolas Klauser "headers": ["ranges"], 1085a5b4479dSNikolas Klauser "unimplemented": True, 10867bfaa0f0STobias Hieta }, 10877bfaa0f0STobias Hieta { 1088855d7bedSArthur O'Dwyer "name": "__cpp_lib_ranges_starts_ends_with", 108971400505SMark de Wever "values": {"c++23": 202106}, 1090855d7bedSArthur O'Dwyer "headers": ["algorithm"], 10917bfaa0f0STobias Hieta }, 10927bfaa0f0STobias Hieta { 1093a5b4479dSNikolas Klauser "name": "__cpp_lib_ranges_to_container", 109471400505SMark de Wever "values": {"c++23": 202202}, 1095028f1b07Skrzysdz "headers": ["ranges"], 10967bfaa0f0STobias Hieta }, 10977bfaa0f0STobias Hieta { 1098855d7bedSArthur O'Dwyer "name": "__cpp_lib_ranges_zip", 109971400505SMark de Wever "values": {"c++23": 202110}, 1100855d7bedSArthur O'Dwyer "headers": ["ranges", "tuple", "utility"], 1101855d7bedSArthur O'Dwyer "unimplemented": True, 11027bfaa0f0STobias Hieta }, 11037bfaa0f0STobias Hieta { 11043f05d044SMark de Wever "name": "__cpp_lib_ratio", 11053f05d044SMark de Wever "values": {"c++26": 202306}, # P2734R0 Adding the new SI prefixes 11063f05d044SMark de Wever "headers": ["ratio"], 11073f05d044SMark de Wever }, 11083f05d044SMark de Wever { 1109ff1b6f9fSArthur O'Dwyer "name": "__cpp_lib_raw_memory_algorithms", 1110ff1b6f9fSArthur O'Dwyer "values": {"c++17": 201606}, 1111ff1b6f9fSArthur O'Dwyer "headers": ["memory"], 11127bfaa0f0STobias Hieta }, 11137bfaa0f0STobias Hieta { 11143f05d044SMark de Wever "name": "__cpp_lib_rcu", 11153f05d044SMark de Wever "values": {"c++26": 202306}, # P2545R4 Read-Copy Update (RCU) 1116f49ccca8SMark de Wever "headers": [ 1117f49ccca8SMark de Wever "rcu" # TODO verify this entry since the paper was underspecified. 1118f49ccca8SMark de Wever ], 11193f05d044SMark de Wever "unimplemented": True, 11203f05d044SMark de Wever }, 11213f05d044SMark de Wever { 1122a5b4479dSNikolas Klauser "name": "__cpp_lib_reference_from_temporary", 112371400505SMark de Wever "values": {"c++23": 202202}, 1124a5b4479dSNikolas Klauser "headers": ["type_traits"], 1125a5b4479dSNikolas Klauser "unimplemented": True, 11267bfaa0f0STobias Hieta }, 11277bfaa0f0STobias Hieta { 1128b699a9baSLouis Dionne "name": "__cpp_lib_reference_wrapper", 1129b699a9baSLouis Dionne "values": {"c++26": 202403}, # P2944R3: Comparisons for reference_wrapper 1130b699a9baSLouis Dionne "headers": ["functional"], 1131b699a9baSLouis Dionne }, 1132b699a9baSLouis Dionne { 1133466df171SArthur O'Dwyer "name": "__cpp_lib_remove_cvref", 1134466df171SArthur O'Dwyer "values": {"c++20": 201711}, 1135466df171SArthur O'Dwyer "headers": ["type_traits"], 11367bfaa0f0STobias Hieta }, 11377bfaa0f0STobias Hieta { 1138ff1b6f9fSArthur O'Dwyer "name": "__cpp_lib_result_of_sfinae", 1139ff1b6f9fSArthur O'Dwyer "values": {"c++14": 201210}, 1140ff1b6f9fSArthur O'Dwyer "headers": ["functional", "type_traits"], 11417bfaa0f0STobias Hieta }, 11427bfaa0f0STobias Hieta { 1143ff1b6f9fSArthur O'Dwyer "name": "__cpp_lib_robust_nonmodifying_seq_ops", 1144ff1b6f9fSArthur O'Dwyer "values": {"c++14": 201304}, 1145ff1b6f9fSArthur O'Dwyer "headers": ["algorithm"], 11467bfaa0f0STobias Hieta }, 11477bfaa0f0STobias Hieta { 1148ff1b6f9fSArthur O'Dwyer "name": "__cpp_lib_sample", 1149ff1b6f9fSArthur O'Dwyer "values": {"c++17": 201603}, 1150ff1b6f9fSArthur O'Dwyer "headers": ["algorithm"], 11517bfaa0f0STobias Hieta }, 11527bfaa0f0STobias Hieta { 1153f49ccca8SMark de Wever "name": "__cpp_lib_saturation_arithmetic", 1154f49ccca8SMark de Wever "values": {"c++26": 202311}, # P0543R3 Saturation arithmetic 115503c19e91SHristo Hristov "headers": ["numeric"], 1156f49ccca8SMark de Wever }, 1157f49ccca8SMark de Wever { 1158ff1b6f9fSArthur O'Dwyer "name": "__cpp_lib_scoped_lock", 1159ff1b6f9fSArthur O'Dwyer "values": {"c++17": 201703}, 1160ff1b6f9fSArthur O'Dwyer "headers": ["mutex"], 1161c6f3b7bcSNikolas Klauser "test_suite_guard": "!defined(_LIBCPP_VERSION) || _LIBCPP_HAS_THREADS", 1162c6f3b7bcSNikolas Klauser "libcxx_guard": "_LIBCPP_HAS_THREADS", 11637bfaa0f0STobias Hieta }, 11647bfaa0f0STobias Hieta { 1165466df171SArthur O'Dwyer "name": "__cpp_lib_semaphore", 1166466df171SArthur O'Dwyer "values": {"c++20": 201907}, 1167466df171SArthur O'Dwyer "headers": ["semaphore"], 1168c6f3b7bcSNikolas Klauser "test_suite_guard": "!defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC)", 1169c6f3b7bcSNikolas Klauser "libcxx_guard": "_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC", 11707bfaa0f0STobias Hieta }, 11717bfaa0f0STobias Hieta { 11722dadf8d7SMark de Wever "name": "__cpp_lib_senders", 11732dadf8d7SMark de Wever "values": {"c++26": 202406}, # P2300R10 std::execution 11742dadf8d7SMark de Wever "headers": ["execution"], 11752dadf8d7SMark de Wever "unimplemented": True, 11762dadf8d7SMark de Wever }, 11772dadf8d7SMark de Wever { 1178ff1b6f9fSArthur O'Dwyer "name": "__cpp_lib_shared_mutex", 1179ff1b6f9fSArthur O'Dwyer "values": {"c++17": 201505}, 1180ff1b6f9fSArthur O'Dwyer "headers": ["shared_mutex"], 1181c6f3b7bcSNikolas Klauser "test_suite_guard": "_LIBCPP_HAS_THREADS", 1182c6f3b7bcSNikolas Klauser "libcxx_guard": "_LIBCPP_HAS_THREADS", 11837bfaa0f0STobias Hieta }, 11847bfaa0f0STobias Hieta { 1185ff1b6f9fSArthur O'Dwyer "name": "__cpp_lib_shared_ptr_arrays", 1186e27a122bSLouis Dionne "values": {"c++17": 201611, "c++20": 201707}, 1187ff1b6f9fSArthur O'Dwyer "headers": ["memory"], 11887bfaa0f0STobias Hieta }, 11897bfaa0f0STobias Hieta { 1190ff1b6f9fSArthur O'Dwyer "name": "__cpp_lib_shared_ptr_weak_type", 1191ff1b6f9fSArthur O'Dwyer "values": {"c++17": 201606}, 1192ff1b6f9fSArthur O'Dwyer "headers": ["memory"], 11937bfaa0f0STobias Hieta }, 11947bfaa0f0STobias Hieta { 1195ff1b6f9fSArthur O'Dwyer "name": "__cpp_lib_shared_timed_mutex", 1196ff1b6f9fSArthur O'Dwyer "values": {"c++14": 201402}, 1197ff1b6f9fSArthur O'Dwyer "headers": ["shared_mutex"], 1198c6f3b7bcSNikolas Klauser "test_suite_guard": "_LIBCPP_HAS_THREADS", 1199c6f3b7bcSNikolas Klauser "libcxx_guard": "_LIBCPP_HAS_THREADS", 12007bfaa0f0STobias Hieta }, 12017bfaa0f0STobias Hieta { 1202466df171SArthur O'Dwyer "name": "__cpp_lib_shift", 1203466df171SArthur O'Dwyer "values": {"c++20": 201806}, 1204466df171SArthur O'Dwyer "headers": ["algorithm"], 12057bfaa0f0STobias Hieta }, 12067bfaa0f0STobias Hieta { 1207466df171SArthur O'Dwyer "name": "__cpp_lib_smart_ptr_for_overwrite", 1208466df171SArthur O'Dwyer "values": {"c++20": 202002}, 1209466df171SArthur O'Dwyer "headers": ["memory"], 12107bfaa0f0STobias Hieta }, 12117bfaa0f0STobias Hieta { 12123f05d044SMark de Wever "name": "__cpp_lib_smart_ptr_owner_equality", 1213f49ccca8SMark de Wever "values": { 1214f49ccca8SMark de Wever "c++26": 202306 # P1901R2 Enabling the Use of weak_ptr as Keys in Unordered Associative Containers 1215f49ccca8SMark de Wever }, 12163f05d044SMark de Wever "headers": ["memory"], 12173f05d044SMark de Wever "unimplemented": True, 12183f05d044SMark de Wever }, 12193f05d044SMark de Wever { 1220466df171SArthur O'Dwyer "name": "__cpp_lib_source_location", 1221466df171SArthur O'Dwyer "values": {"c++20": 201907}, 1222466df171SArthur O'Dwyer "headers": ["source_location"], 12237bfaa0f0STobias Hieta }, 12247bfaa0f0STobias Hieta { 1225ff1b6f9fSArthur O'Dwyer "name": "__cpp_lib_span", 1226f49ccca8SMark de Wever "values": { 1227f49ccca8SMark de Wever "c++20": 202002, 1228f49ccca8SMark de Wever # "c++26": 202311, # P2821R5 span.at() 1229f49ccca8SMark de Wever # 202311 # P2833R2 Freestanding Library: inout expected span 1230f49ccca8SMark de Wever }, 1231ff1b6f9fSArthur O'Dwyer "headers": ["span"], 12327bfaa0f0STobias Hieta }, 12337bfaa0f0STobias Hieta { 1234a72ab9c1SHristo Hristov "name": "__cpp_lib_span_at", 1235a72ab9c1SHristo Hristov "values": {"c++26": 202311}, # P2821R3 span.at() 1236a72ab9c1SHristo Hristov "headers": ["span"], 1237a72ab9c1SHristo Hristov }, 1238a72ab9c1SHristo Hristov { 1239f49ccca8SMark de Wever "name": "__cpp_lib_span_initializer_list", 1240f49ccca8SMark de Wever "values": {"c++26": 202311}, # P2447R6 std::span over an initializer list 1241f49ccca8SMark de Wever "headers": ["span"], 1242f49ccca8SMark de Wever }, 1243f49ccca8SMark de Wever { 1244855d7bedSArthur O'Dwyer "name": "__cpp_lib_spanstream", 124571400505SMark de Wever "values": {"c++23": 202106}, 1246855d7bedSArthur O'Dwyer "headers": ["spanstream"], 1247855d7bedSArthur O'Dwyer "unimplemented": True, 12487bfaa0f0STobias Hieta }, 12497bfaa0f0STobias Hieta { 1250466df171SArthur O'Dwyer "name": "__cpp_lib_ssize", 1251466df171SArthur O'Dwyer "values": {"c++20": 201902}, 1252466df171SArthur O'Dwyer "headers": ["iterator"], 12537bfaa0f0STobias Hieta }, 12547bfaa0f0STobias Hieta { 12553f05d044SMark de Wever "name": "__cpp_lib_sstream_from_string_view", 1256f49ccca8SMark de Wever "values": { 1257f49ccca8SMark de Wever "c++26": 202306 # P2495R3 Interfacing stringstreams with string_view 1258f49ccca8SMark de Wever }, 12593f05d044SMark de Wever "headers": ["sstream"], 12603f05d044SMark de Wever }, 12613f05d044SMark de Wever { 126295729f95SMarek Kurdej "name": "__cpp_lib_stacktrace", 126371400505SMark de Wever "values": {"c++23": 202011}, 126495729f95SMarek Kurdej "headers": ["stacktrace"], 126595729f95SMarek Kurdej "unimplemented": True, 12667bfaa0f0STobias Hieta }, 12677bfaa0f0STobias Hieta { 1268466df171SArthur O'Dwyer "name": "__cpp_lib_starts_ends_with", 1269466df171SArthur O'Dwyer "values": {"c++20": 201711}, 1270466df171SArthur O'Dwyer "headers": ["string", "string_view"], 12717bfaa0f0STobias Hieta }, 12727bfaa0f0STobias Hieta { 127395729f95SMarek Kurdej "name": "__cpp_lib_stdatomic_h", 127471400505SMark de Wever "values": {"c++23": 202011}, 127595729f95SMarek Kurdej "headers": ["stdatomic.h"], 12767bfaa0f0STobias Hieta }, 12777bfaa0f0STobias Hieta { 127895729f95SMarek Kurdej "name": "__cpp_lib_string_contains", 127971400505SMark de Wever "values": {"c++23": 202011}, 128095729f95SMarek Kurdej "headers": ["string", "string_view"], 12817bfaa0f0STobias Hieta }, 12827bfaa0f0STobias Hieta { 1283bec50db2SNikolas Klauser "name": "__cpp_lib_string_resize_and_overwrite", 128471400505SMark de Wever "values": {"c++23": 202110}, 1285bec50db2SNikolas Klauser "headers": ["string"], 12867bfaa0f0STobias Hieta }, 12877bfaa0f0STobias Hieta { 1288ff1b6f9fSArthur O'Dwyer "name": "__cpp_lib_string_udls", 1289ff1b6f9fSArthur O'Dwyer "values": {"c++14": 201304}, 1290ff1b6f9fSArthur O'Dwyer "headers": ["string"], 12917bfaa0f0STobias Hieta }, 12927bfaa0f0STobias Hieta { 1293ff1b6f9fSArthur O'Dwyer "name": "__cpp_lib_string_view", 1294b699a9baSLouis Dionne "values": { 1295b699a9baSLouis Dionne "c++17": 201606, 1296b699a9baSLouis Dionne "c++20": 201803, 12974a19be5dSHristo Hristov "c++26": 202403, # P2591R5: Concatenation of strings and string views 1298b699a9baSLouis Dionne }, 1299ff1b6f9fSArthur O'Dwyer "headers": ["string", "string_view"], 13007bfaa0f0STobias Hieta }, 13017bfaa0f0STobias Hieta { 13023f05d044SMark de Wever "name": "__cpp_lib_submdspan", 1303b699a9baSLouis Dionne "values": { 1304b699a9baSLouis Dionne "c++26": 202306, # P2630R4: submdspan 1305b699a9baSLouis Dionne # "c++26": 202403, # P2642R6: Padded mdspan layouts 1306b699a9baSLouis Dionne }, 13073f05d044SMark de Wever "headers": ["mdspan"], 13083f05d044SMark de Wever "unimplemented": True, 13093f05d044SMark de Wever }, 13103f05d044SMark de Wever { 1311466df171SArthur O'Dwyer "name": "__cpp_lib_syncbuf", 1312466df171SArthur O'Dwyer "values": {"c++20": 201803}, 1313466df171SArthur O'Dwyer "headers": ["syncstream"], 131424e70e39SNikolas Klauser "test_suite_guard": "!defined(_LIBCPP_VERSION) || _LIBCPP_HAS_EXPERIMENTAL_SYNCSTREAM", 131524e70e39SNikolas Klauser "libcxx_guard": "_LIBCPP_HAS_EXPERIMENTAL_SYNCSTREAM", 13167bfaa0f0STobias Hieta }, 13177bfaa0f0STobias Hieta { 13183f05d044SMark de Wever "name": "__cpp_lib_text_encoding", 1319f49ccca8SMark de Wever "values": { 1320f49ccca8SMark de Wever "c++26": 202306 # P1885R12 Naming Text Encodings to Demystify Them 1321f49ccca8SMark de Wever }, 13223f05d044SMark de Wever "headers": ["text_encoding"], 13233f05d044SMark de Wever "unimplemented": True, 13243f05d044SMark de Wever }, 13253f05d044SMark de Wever { 1326ff1b6f9fSArthur O'Dwyer "name": "__cpp_lib_three_way_comparison", 13273ce6f68eSMark de Wever "values": {"c++20": 201907}, 1328ff1b6f9fSArthur O'Dwyer "headers": ["compare"], 13297bfaa0f0STobias Hieta }, 13307bfaa0f0STobias Hieta { 1331466df171SArthur O'Dwyer "name": "__cpp_lib_to_address", 1332466df171SArthur O'Dwyer "values": {"c++20": 201711}, 1333466df171SArthur O'Dwyer "headers": ["memory"], 13347bfaa0f0STobias Hieta }, 13357bfaa0f0STobias Hieta { 1336ff1b6f9fSArthur O'Dwyer "name": "__cpp_lib_to_array", 1337ff1b6f9fSArthur O'Dwyer "values": {"c++20": 201907}, 1338ff1b6f9fSArthur O'Dwyer "headers": ["array"], 13397bfaa0f0STobias Hieta }, 13407bfaa0f0STobias Hieta { 1341ff1b6f9fSArthur O'Dwyer "name": "__cpp_lib_to_chars", 13423f05d044SMark de Wever "values": { 13433f05d044SMark de Wever "c++17": 201611, 134492ac3600SMark de Wever "c++26": 202306, # P2497R0 Testing for success or failure of <charconv> functions 13453f05d044SMark de Wever }, 1346e0f58444SLouis Dionne "headers": ["charconv"], 1347ff1b6f9fSArthur O'Dwyer "unimplemented": True, 13487bfaa0f0STobias Hieta }, 13497bfaa0f0STobias Hieta { 13503f05d044SMark de Wever "name": "__cpp_lib_to_string", 1351a4bef0caSStephan T. Lavavej "values": {"c++26": 202306}, # P2587R3 to_string or not to_string 13523f05d044SMark de Wever "headers": ["string"], 13533f05d044SMark de Wever "unimplemented": True, 13543f05d044SMark de Wever }, 13553f05d044SMark de Wever { 135643e42141SMarek Kurdej "name": "__cpp_lib_to_underlying", 135771400505SMark de Wever "values": {"c++23": 202102}, 135843e42141SMarek Kurdej "headers": ["utility"], 13597bfaa0f0STobias Hieta }, 13607bfaa0f0STobias Hieta { 1361ff1b6f9fSArthur O'Dwyer "name": "__cpp_lib_transformation_trait_aliases", 1362ff1b6f9fSArthur O'Dwyer "values": {"c++14": 201304}, 1363ff1b6f9fSArthur O'Dwyer "headers": ["type_traits"], 13647bfaa0f0STobias Hieta }, 13657bfaa0f0STobias Hieta { 1366ff1b6f9fSArthur O'Dwyer "name": "__cpp_lib_transparent_operators", 1367ff1b6f9fSArthur O'Dwyer "values": {"c++14": 201210, "c++17": 201510}, 1368466df171SArthur O'Dwyer "headers": ["functional", "memory"], 13697bfaa0f0STobias Hieta }, 13707bfaa0f0STobias Hieta { 1371ff1b6f9fSArthur O'Dwyer "name": "__cpp_lib_tuple_element_t", 1372ff1b6f9fSArthur O'Dwyer "values": {"c++14": 201402}, 1373ff1b6f9fSArthur O'Dwyer "headers": ["tuple"], 13747bfaa0f0STobias Hieta }, 13757bfaa0f0STobias Hieta { 1376f49ccca8SMark de Wever "name": "__cpp_lib_tuple_like", 1377f49ccca8SMark de Wever "values": { 1378f49ccca8SMark de Wever "c++23": 202207, # P2165R4 Compatibility between tuple, pair and tuple-like objects 13792ea5d167SHristo Hristov "c++26": 202311, # P2819R2 Add tuple protocol to complex (implemented) 1380f49ccca8SMark de Wever }, 1381f49ccca8SMark de Wever "headers": ["map", "tuple", "unordered_map", "utility"], 1382f49ccca8SMark de Wever "unimplemented": True, 1383f49ccca8SMark de Wever }, 1384f49ccca8SMark de Wever { 1385ff1b6f9fSArthur O'Dwyer "name": "__cpp_lib_tuples_by_type", 1386ff1b6f9fSArthur O'Dwyer "values": {"c++14": 201304}, 1387ff1b6f9fSArthur O'Dwyer "headers": ["tuple", "utility"], 13887bfaa0f0STobias Hieta }, 13897bfaa0f0STobias Hieta { 1390855d7bedSArthur O'Dwyer "name": "__cpp_lib_type_identity", 1391855d7bedSArthur O'Dwyer "values": {"c++20": 201806}, 1392855d7bedSArthur O'Dwyer "headers": ["type_traits"], 13937bfaa0f0STobias Hieta }, 13947bfaa0f0STobias Hieta { 1395ff1b6f9fSArthur O'Dwyer "name": "__cpp_lib_type_trait_variable_templates", 1396ff1b6f9fSArthur O'Dwyer "values": {"c++17": 201510}, 1397ff1b6f9fSArthur O'Dwyer "headers": ["type_traits"], 13987bfaa0f0STobias Hieta }, 13997bfaa0f0STobias Hieta { 1400ff1b6f9fSArthur O'Dwyer "name": "__cpp_lib_uncaught_exceptions", 1401ff1b6f9fSArthur O'Dwyer "values": {"c++17": 201411}, 1402ff1b6f9fSArthur O'Dwyer "headers": ["exception"], 14037bfaa0f0STobias Hieta }, 14047bfaa0f0STobias Hieta { 1405ff1b6f9fSArthur O'Dwyer "name": "__cpp_lib_unordered_map_try_emplace", 1406ff1b6f9fSArthur O'Dwyer "values": {"c++17": 201411}, 1407ff1b6f9fSArthur O'Dwyer "headers": ["unordered_map"], 14087bfaa0f0STobias Hieta }, 14097bfaa0f0STobias Hieta { 1410a5b4479dSNikolas Klauser "name": "__cpp_lib_unreachable", 141171400505SMark de Wever "values": {"c++23": 202202}, 1412a5b4479dSNikolas Klauser "headers": ["utility"], 14137bfaa0f0STobias Hieta }, 14147bfaa0f0STobias Hieta { 1415466df171SArthur O'Dwyer "name": "__cpp_lib_unwrap_ref", 1416466df171SArthur O'Dwyer "values": {"c++20": 201811}, 1417466df171SArthur O'Dwyer "headers": ["functional"], 14187bfaa0f0STobias Hieta }, 14197bfaa0f0STobias Hieta { 1420ff1b6f9fSArthur O'Dwyer "name": "__cpp_lib_variant", 14213412bc76SHristo Hristov "values": { 14223412bc76SHristo Hristov "c++17": 202102, # std::visit for classes derived from std::variant 1423cae351f3SA. Jiang "c++20": 202106, # P2231R1 Missing constexpr in std::optional and std::variant 1424cae351f3SA. Jiang "c++26": 202306, # P2637R3 Member visit 14253412bc76SHristo Hristov }, 1426ff1b6f9fSArthur O'Dwyer "headers": ["variant"], 14277bfaa0f0STobias Hieta }, 14287bfaa0f0STobias Hieta { 1429ff1b6f9fSArthur O'Dwyer "name": "__cpp_lib_void_t", 1430ff1b6f9fSArthur O'Dwyer "values": {"c++17": 201411}, 1431ff1b6f9fSArthur O'Dwyer "headers": ["type_traits"], 14327bfaa0f0STobias Hieta }, 14337bfaa0f0STobias Hieta ] 14347bfaa0f0STobias Hieta] 1435ff1b6f9fSArthur O'Dwyer 1436ff1b6f9fSArthur O'Dwyerassert feature_test_macros == sorted(feature_test_macros, key=lambda tc: tc["name"]) 1437b699a9baSLouis Dionnefor tc in feature_test_macros: 1438b699a9baSLouis Dionne assert tc["headers"] == sorted(tc["headers"]), tc 1439b699a9baSLouis Dionne assert ("libcxx_guard" in tc) == ("test_suite_guard" in tc), tc 1440b699a9baSLouis Dionne valid_keys = ["name", "values", "headers", "libcxx_guard", "test_suite_guard", "unimplemented"] 1441b699a9baSLouis Dionne assert all(key in valid_keys for key in tc.keys()), tc 1442508da415SEric Fiselier 1443c2279b26SLouis Dionne# Map from each header to the Lit annotations that should be used for 1444c2279b26SLouis Dionne# tests that include that header. 1445c2279b26SLouis Dionne# 1446e1ce3dabSLouis Dionne# For example, when threads are not supported, any test that includes 1447e1ce3dabSLouis Dionne# <thread> should be marked as UNSUPPORTED, because including <thread> 1448e1ce3dabSLouis Dionne# is a hard error in that case. 1449c2279b26SLouis Dionnelit_markup = { 1450a7f9895cSLouis Dionne "barrier": ["UNSUPPORTED: no-threads"], 1451a7f9895cSLouis Dionne "filesystem": ["UNSUPPORTED: no-filesystem"], 14523f05d044SMark de Wever "fstream": ["UNSUPPORTED: no-localization"], 1453a7f9895cSLouis Dionne "iomanip": ["UNSUPPORTED: no-localization"], 1454a7f9895cSLouis Dionne "ios": ["UNSUPPORTED: no-localization"], 1455a7f9895cSLouis Dionne "iostream": ["UNSUPPORTED: no-localization"], 1456a7f9895cSLouis Dionne "istream": ["UNSUPPORTED: no-localization"], 1457a7f9895cSLouis Dionne "latch": ["UNSUPPORTED: no-threads"], 1458a7f9895cSLouis Dionne "locale": ["UNSUPPORTED: no-localization"], 1459a7f9895cSLouis Dionne "mutex": ["UNSUPPORTED: no-threads"], 1460a7f9895cSLouis Dionne "ostream": ["UNSUPPORTED: no-localization"], 14611cf970dbSKonstantin Varlamov "print": ["UNSUPPORTED: no-filesystem"], 1462a7f9895cSLouis Dionne "regex": ["UNSUPPORTED: no-localization"], 1463a7f9895cSLouis Dionne "semaphore": ["UNSUPPORTED: no-threads"], 1464a7f9895cSLouis Dionne "shared_mutex": ["UNSUPPORTED: no-threads"], 14653f05d044SMark de Wever "sstream": ["UNSUPPORTED: no-localization"], 14667cc72a0aSMark de Wever "syncstream": ["UNSUPPORTED: no-localization"], 1467a7f9895cSLouis Dionne "stdatomic.h": ["UNSUPPORTED: no-threads"], 1468b77e50e6SHui "stop_token": ["UNSUPPORTED: no-threads"], 1469a7f9895cSLouis Dionne "thread": ["UNSUPPORTED: no-threads"], 1470c2279b26SLouis Dionne} 1471c2279b26SLouis Dionne 14727bfaa0f0STobias Hieta 1473508da415SEric Fiselierdef get_std_dialects(): 14747bfaa0f0STobias Hieta std_dialects = ["c++14", "c++17", "c++20", "c++23", "c++26"] 1475508da415SEric Fiselier return list(std_dialects) 1476508da415SEric Fiselier 14777bfaa0f0STobias Hieta 1478508da415SEric Fiselierdef get_first_std(d): 1479508da415SEric Fiselier for s in get_std_dialects(): 1480508da415SEric Fiselier if s in d.keys(): 1481508da415SEric Fiselier return s 1482508da415SEric Fiselier return None 1483508da415SEric Fiselier 14847bfaa0f0STobias Hieta 1485508da415SEric Fiselierdef get_last_std(d): 1486508da415SEric Fiselier rev_dialects = get_std_dialects() 1487508da415SEric Fiselier rev_dialects.reverse() 1488508da415SEric Fiselier for s in rev_dialects: 1489508da415SEric Fiselier if s in d.keys(): 1490508da415SEric Fiselier return s 1491508da415SEric Fiselier return None 1492508da415SEric Fiselier 14937bfaa0f0STobias Hieta 1494508da415SEric Fiselierdef get_std_before(d, std): 1495508da415SEric Fiselier std_dialects = get_std_dialects() 1496508da415SEric Fiselier candidates = std_dialects[0 : std_dialects.index(std)] 1497508da415SEric Fiselier candidates.reverse() 1498508da415SEric Fiselier for cand in candidates: 1499508da415SEric Fiselier if cand in d.keys(): 1500508da415SEric Fiselier return cand 1501508da415SEric Fiselier return None 1502508da415SEric Fiselier 15037bfaa0f0STobias Hieta 1504508da415SEric Fiselierdef get_value_before(d, std): 1505508da415SEric Fiselier new_std = get_std_before(d, std) 1506508da415SEric Fiselier if new_std is None: 1507508da415SEric Fiselier return None 1508508da415SEric Fiselier return d[new_std] 1509508da415SEric Fiselier 15107bfaa0f0STobias Hieta 1511508da415SEric Fiselierdef get_for_std(d, std): 1512508da415SEric Fiselier # This catches the C++11 case for which there should be no defined feature 1513508da415SEric Fiselier # test macros. 1514508da415SEric Fiselier std_dialects = get_std_dialects() 1515508da415SEric Fiselier if std not in std_dialects: 1516508da415SEric Fiselier return None 1517508da415SEric Fiselier # Find the value for the newest C++ dialect between C++14 and std 1518508da415SEric Fiselier std_list = list(std_dialects[0 : std_dialects.index(std) + 1]) 1519508da415SEric Fiselier std_list.reverse() 1520508da415SEric Fiselier for s in std_list: 1521508da415SEric Fiselier if s in d.keys(): 1522508da415SEric Fiselier return d[s] 1523508da415SEric Fiselier return None 1524508da415SEric Fiselier 15257bfaa0f0STobias Hieta 15262776be43SWim Lefleredef get_std_number(std): 15277bfaa0f0STobias Hieta return std.replace("c++", "") 15287bfaa0f0STobias Hieta 1529508da415SEric Fiselier 1530508da415SEric Fiselier""" 1531508da415SEric Fiselier Functions to produce the <version> header 1532508da415SEric Fiselier""" 1533508da415SEric Fiselier 15347bfaa0f0STobias Hieta 1535508da415SEric Fiselierdef produce_macros_definition_for_std(std): 1536508da415SEric Fiselier result = "" 1537eb37d354SArthur O'Dwyer indent = 55 1538508da415SEric Fiselier for tc in feature_test_macros: 1539508da415SEric Fiselier if std not in tc["values"]: 1540508da415SEric Fiselier continue 1541508da415SEric Fiselier inner_indent = 1 15427bfaa0f0STobias Hieta if "test_suite_guard" in tc.keys(): 1543c2c68a59SMark de Wever result += "# if %s\n" % tc["libcxx_guard"] 1544508da415SEric Fiselier inner_indent += 2 1545508da415SEric Fiselier if get_value_before(tc["values"], std) is not None: 15467bfaa0f0STobias Hieta assert "test_suite_guard" not in tc.keys() 1547508da415SEric Fiselier result += "# undef %s\n" % tc["name"] 1548508da415SEric Fiselier line = "#%sdefine %s" % ((" " * inner_indent), tc["name"]) 1549508da415SEric Fiselier line += " " * (indent - len(line)) 1550508da415SEric Fiselier line += " %sL" % tc["values"][std] 15517bfaa0f0STobias Hieta if "unimplemented" in tc.keys(): 1552508da415SEric Fiselier line = "// " + line 1553508da415SEric Fiselier result += line 1554508da415SEric Fiselier result += "\n" 15557bfaa0f0STobias Hieta if "test_suite_guard" in tc.keys(): 1556508da415SEric Fiselier result += "# endif\n" 15572776be43SWim Leflere return result.strip() 15582776be43SWim Leflere 15597bfaa0f0STobias Hieta 15602776be43SWim Lefleredef produce_macros_definitions(): 15614f15267dSNikolas Klauser macro_definition_template = """#if _LIBCPP_STD_VER >= {std_number} 15622776be43SWim Leflere{macro_definition} 15632776be43SWim Leflere#endif""" 15642776be43SWim Leflere 15652776be43SWim Leflere macros_definitions = [] 15662776be43SWim Leflere for std in get_std_dialects(): 15672776be43SWim Leflere macros_definitions.append( 15687bfaa0f0STobias Hieta macro_definition_template.format( 15697bfaa0f0STobias Hieta std_number=get_std_number(std), 15707bfaa0f0STobias Hieta macro_definition=produce_macros_definition_for_std(std), 15717bfaa0f0STobias Hieta ) 15727bfaa0f0STobias Hieta ) 15732776be43SWim Leflere 15747bfaa0f0STobias Hieta return "\n\n".join(macros_definitions) 15757bfaa0f0STobias Hieta 1576508da415SEric Fiselier 1577508da415SEric Fiselierdef chunks(l, n): 1578508da415SEric Fiselier """Yield successive n-sized chunks from l.""" 1579508da415SEric Fiselier for i in range(0, len(l), n): 1580508da415SEric Fiselier yield l[i : i + n] 1581508da415SEric Fiselier 15827bfaa0f0STobias Hieta 1583508da415SEric Fiselierdef produce_version_synopsis(): 1584508da415SEric Fiselier indent = 56 1585508da415SEric Fiselier header_indent = 56 + len("20XXYYL ") 1586508da415SEric Fiselier result = "" 15877bfaa0f0STobias Hieta 1588508da415SEric Fiselier def indent_to(s, val): 1589508da415SEric Fiselier if len(s) >= val: 1590508da415SEric Fiselier return s 1591508da415SEric Fiselier s += " " * (val - len(s)) 1592508da415SEric Fiselier return s 15937bfaa0f0STobias Hieta 1594508da415SEric Fiselier line = indent_to("Macro name", indent) + "Value" 1595508da415SEric Fiselier line = indent_to(line, header_indent) + "Headers" 1596508da415SEric Fiselier result += line + "\n" 1597508da415SEric Fiselier for tc in feature_test_macros: 1598508da415SEric Fiselier prev_defined_std = get_last_std(tc["values"]) 15997bfaa0f0STobias Hieta line = "{name: <{indent}}{value}L ".format( 16007bfaa0f0STobias Hieta name=tc["name"], indent=indent, value=tc["values"][prev_defined_std] 16017bfaa0f0STobias Hieta ) 1602508da415SEric Fiselier headers = list(tc["headers"]) 1603508da415SEric Fiselier headers.remove("version") 1604508da415SEric Fiselier for chunk in chunks(headers, 3): 1605508da415SEric Fiselier line = indent_to(line, header_indent) 16067bfaa0f0STobias Hieta chunk = ["<%s>" % header for header in chunk] 16077bfaa0f0STobias Hieta line += " ".join(chunk) 1608508da415SEric Fiselier result += line 1609508da415SEric Fiselier result += "\n" 1610508da415SEric Fiselier line = "" 1611508da415SEric Fiselier while True: 1612508da415SEric Fiselier prev_defined_std = get_std_before(tc["values"], prev_defined_std) 1613508da415SEric Fiselier if prev_defined_std is None: 1614508da415SEric Fiselier break 16157bfaa0f0STobias Hieta result += "%s%sL // %s\n" % ( 16167bfaa0f0STobias Hieta indent_to("", indent), 16177bfaa0f0STobias Hieta tc["values"][prev_defined_std], 16187bfaa0f0STobias Hieta prev_defined_std.replace("c++", "C++"), 16197bfaa0f0STobias Hieta ) 1620508da415SEric Fiselier return result 1621508da415SEric Fiselier 1622508da415SEric Fiselier 1623508da415SEric Fiselierdef produce_version_header(): 16242a6b99d5SArthur O'Dwyer template = """// -*- C++ -*- 16252e934531SLouis Dionne//===----------------------------------------------------------------------===// 1626508da415SEric Fiselier// 1627508da415SEric Fiselier// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 1628508da415SEric Fiselier// See https://llvm.org/LICENSE.txt for license information. 1629508da415SEric Fiselier// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 1630508da415SEric Fiselier// 1631508da415SEric Fiselier//===----------------------------------------------------------------------===// 1632508da415SEric Fiselier 1633508da415SEric Fiselier#ifndef _LIBCPP_VERSIONH 1634508da415SEric Fiselier#define _LIBCPP_VERSIONH 1635508da415SEric Fiselier 1636508da415SEric Fiselier/* 1637508da415SEric Fiselier version synopsis 1638508da415SEric Fiselier 1639508da415SEric Fiselier{synopsis} 1640508da415SEric Fiselier 1641508da415SEric Fiselier*/ 1642508da415SEric Fiselier 1643b9a2658aSNikolas Klauser#if __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS) 1644b9a2658aSNikolas Klauser# include <__cxx03/version> 1645b9a2658aSNikolas Klauser#else 1646508da415SEric Fiselier# include <__config> 1647508da415SEric Fiselier 1648508da415SEric Fiselier# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 1649508da415SEric Fiselier# pragma GCC system_header 1650508da415SEric Fiselier# endif 1651508da415SEric Fiselier 1652bcb5a124SMarek Kurdej// clang-format off 1653bcb5a124SMarek Kurdej 16542776be43SWim Leflere{cxx_macros} 165595729f95SMarek Kurdej 1656b9a2658aSNikolas Klauser#endif // __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS) 1657b9a2658aSNikolas Klauser 1658bcb5a124SMarek Kurdej// clang-format on 1659bcb5a124SMarek Kurdej 1660508da415SEric Fiselier#endif // _LIBCPP_VERSIONH 16612a6b99d5SArthur O'Dwyer""" 1662647fb6b3SLouis Dionne 1663647fb6b3SLouis Dionne version_str = template.format( 1664508da415SEric Fiselier synopsis=produce_version_synopsis().strip(), 16657bfaa0f0STobias Hieta cxx_macros=produce_macros_definitions(), 16667bfaa0f0STobias Hieta ) 16677bfaa0f0STobias Hieta version_header_path = os.path.join(include_path, "version") 16687bfaa0f0STobias Hieta with open(version_header_path, "w", newline="\n") as f: 1669647fb6b3SLouis Dionne f.write(version_str) 1670647fb6b3SLouis Dionne 1671647fb6b3SLouis Dionne 1672508da415SEric Fiselier""" 1673508da415SEric Fiselier Functions to produce test files 1674508da415SEric Fiselier""" 1675508da415SEric Fiselier 1676508da415SEric Fiseliertest_types = { 1677508da415SEric Fiselier "undefined": """ 1678508da415SEric Fiselier# ifdef {name} 1679508da415SEric Fiselier# error "{name} should not be defined before {std_first}" 1680508da415SEric Fiselier# endif 1681508da415SEric Fiselier""", 1682c2c68a59SMark de Wever "test_suite_guard": """ 1683c2c68a59SMark de Wever# if {test_suite_guard} 1684508da415SEric Fiselier# ifndef {name} 1685508da415SEric Fiselier# error "{name} should be defined in {std}" 1686508da415SEric Fiselier# endif 1687508da415SEric Fiselier# if {name} != {value} 1688508da415SEric Fiselier# error "{name} should have the value {value} in {std}" 1689508da415SEric Fiselier# endif 1690508da415SEric Fiselier# else 1691508da415SEric Fiselier# ifdef {name} 1692a72f6b03SMark de Wever# error "{name} should not be defined when the requirement '{test_suite_guard}' is not met!" 1693508da415SEric Fiselier# endif 1694508da415SEric Fiselier# endif 1695508da415SEric Fiselier""", 1696508da415SEric Fiselier "unimplemented": """ 1697508da415SEric Fiselier# if !defined(_LIBCPP_VERSION) 1698508da415SEric Fiselier# ifndef {name} 1699508da415SEric Fiselier# error "{name} should be defined in {std}" 1700508da415SEric Fiselier# endif 1701508da415SEric Fiselier# if {name} != {value} 1702508da415SEric Fiselier# error "{name} should have the value {value} in {std}" 1703508da415SEric Fiselier# endif 1704508da415SEric Fiselier# else // _LIBCPP_VERSION 1705508da415SEric Fiselier# ifdef {name} 1706508da415SEric Fiselier# error "{name} should not be defined because it is unimplemented in libc++!" 1707508da415SEric Fiselier# endif 1708508da415SEric Fiselier# endif 1709508da415SEric Fiselier""", 1710508da415SEric Fiselier "defined": """ 1711508da415SEric Fiselier# ifndef {name} 1712508da415SEric Fiselier# error "{name} should be defined in {std}" 1713508da415SEric Fiselier# endif 1714508da415SEric Fiselier# if {name} != {value} 1715508da415SEric Fiselier# error "{name} should have the value {value} in {std}" 1716508da415SEric Fiselier# endif 17177bfaa0f0STobias Hieta""", 1718508da415SEric Fiselier} 1719508da415SEric Fiselier 17207bfaa0f0STobias Hieta 1721508da415SEric Fiselierdef generate_std_test(test_list, std): 1722508da415SEric Fiselier result = "" 1723508da415SEric Fiselier for tc in test_list: 1724508da415SEric Fiselier val = get_for_std(tc["values"], std) 1725508da415SEric Fiselier if val is not None: 1726508da415SEric Fiselier val = "%sL" % val 1727508da415SEric Fiselier if val is None: 17287bfaa0f0STobias Hieta result += test_types["undefined"].format( 17297bfaa0f0STobias Hieta name=tc["name"], std_first=get_first_std(tc["values"]) 17307bfaa0f0STobias Hieta ) 17317bfaa0f0STobias Hieta elif "unimplemented" in tc.keys(): 17327bfaa0f0STobias Hieta result += test_types["unimplemented"].format( 17337bfaa0f0STobias Hieta name=tc["name"], value=val, std=std 17347bfaa0f0STobias Hieta ) 1735c2c68a59SMark de Wever elif "test_suite_guard" in tc.keys(): 17367bfaa0f0STobias Hieta result += test_types["test_suite_guard"].format( 17377bfaa0f0STobias Hieta name=tc["name"], 17387bfaa0f0STobias Hieta value=val, 17397bfaa0f0STobias Hieta std=std, 17407bfaa0f0STobias Hieta test_suite_guard=tc["test_suite_guard"], 17417bfaa0f0STobias Hieta ) 1742508da415SEric Fiselier else: 1743508da415SEric Fiselier result += test_types["defined"].format(name=tc["name"], value=val, std=std) 17442776be43SWim Leflere return result.strip() 17452776be43SWim Leflere 17467bfaa0f0STobias Hieta 17472776be43SWim Lefleredef generate_std_tests(test_list): 17482776be43SWim Leflere std_tests_template = """#if TEST_STD_VER < {first_std_number} 17492776be43SWim Leflere 17502776be43SWim Leflere{pre_std_test} 17512776be43SWim Leflere 17522776be43SWim Leflere{other_std_tests} 17532776be43SWim Leflere 17542776be43SWim Leflere#elif TEST_STD_VER > {penultimate_std_number} 17552776be43SWim Leflere 17562776be43SWim Leflere{last_std_test} 17572776be43SWim Leflere 17582776be43SWim Leflere#endif // TEST_STD_VER > {penultimate_std_number}""" 17592776be43SWim Leflere 17602776be43SWim Leflere std_dialects = get_std_dialects() 17612776be43SWim Leflere 17622776be43SWim Leflere other_std_tests = [] 17632776be43SWim Leflere for std in std_dialects[:-1]: 17647bfaa0f0STobias Hieta other_std_tests.append("#elif TEST_STD_VER == " + get_std_number(std)) 17652776be43SWim Leflere other_std_tests.append(generate_std_test(test_list, std)) 17662776be43SWim Leflere 17677bfaa0f0STobias Hieta std_tests = std_tests_template.format( 17687bfaa0f0STobias Hieta first_std_number=get_std_number(std_dialects[0]), 17697bfaa0f0STobias Hieta pre_std_test=generate_std_test(test_list, "c++11"), 17707bfaa0f0STobias Hieta other_std_tests="\n\n".join(other_std_tests), 17712776be43SWim Leflere penultimate_std_number=get_std_number(std_dialects[-2]), 17727bfaa0f0STobias Hieta last_std_test=generate_std_test(test_list, std_dialects[-1]), 17737bfaa0f0STobias Hieta ) 17742776be43SWim Leflere 17752776be43SWim Leflere return std_tests 1776508da415SEric Fiselier 17777bfaa0f0STobias Hieta 1778508da415SEric Fiselierdef generate_synopsis(test_list): 1779508da415SEric Fiselier max_name_len = max([len(tc["name"]) for tc in test_list]) 1780508da415SEric Fiselier indent = max_name_len + 8 17817bfaa0f0STobias Hieta 1782508da415SEric Fiselier def mk_line(prefix, suffix): 17837bfaa0f0STobias Hieta return "{prefix: <{max_len}}{suffix}\n".format( 17847bfaa0f0STobias Hieta prefix=prefix, suffix=suffix, max_len=indent 17857bfaa0f0STobias Hieta ) 17867bfaa0f0STobias Hieta 1787508da415SEric Fiselier result = "" 1788508da415SEric Fiselier result += mk_line("/* Constant", "Value") 1789508da415SEric Fiselier for tc in test_list: 1790508da415SEric Fiselier prefix = " %s" % tc["name"] 1791508da415SEric Fiselier for std in [s for s in get_std_dialects() if s in tc["values"].keys()]: 17927bfaa0f0STobias Hieta result += mk_line( 17937bfaa0f0STobias Hieta prefix, "%sL [%s]" % (tc["values"][std], std.replace("c++", "C++")) 17947bfaa0f0STobias Hieta ) 1795508da415SEric Fiselier prefix = "" 1796508da415SEric Fiselier result += "*/" 1797508da415SEric Fiselier return result 1798508da415SEric Fiselier 17997bfaa0f0STobias Hieta 1800508da415SEric Fiselierdef produce_tests(): 1801508da415SEric Fiselier headers = set([h for tc in feature_test_macros for h in tc["headers"]]) 1802508da415SEric Fiselier for h in headers: 1803508da415SEric Fiselier test_list = [tc for tc in feature_test_macros if h in tc["headers"]] 1804508da415SEric Fiselier if not has_header(h): 1805508da415SEric Fiselier for tc in test_list: 18067bfaa0f0STobias Hieta assert "unimplemented" in tc.keys() 1807508da415SEric Fiselier continue 18087bfaa0f0STobias Hieta markup = "\n".join("// " + tag for tag in lit_markup.get(h, [])) 18097bfaa0f0STobias Hieta test_body = """//===----------------------------------------------------------------------===// 1810508da415SEric Fiselier// 1811508da415SEric Fiselier// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 1812508da415SEric Fiselier// See https://llvm.org/LICENSE.txt for license information. 1813508da415SEric Fiselier// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 1814508da415SEric Fiselier// 1815508da415SEric Fiselier//===----------------------------------------------------------------------===// 1816508da415SEric Fiselier// 1817508da415SEric Fiselier// WARNING: This test was generated by {script_name} 1818508da415SEric Fiselier// and should not be edited manually. 181930a7d430SMarek Kurdej// 182030a7d430SMarek Kurdej// clang-format off 1821c2279b26SLouis Dionne{markup} 1822508da415SEric Fiselier// <{header}> 1823508da415SEric Fiselier 1824508da415SEric Fiselier// Test the feature test macros defined by <{header}> 1825508da415SEric Fiselier 1826508da415SEric Fiselier{synopsis} 1827508da415SEric Fiselier 1828508da415SEric Fiselier#include <{header}> 1829508da415SEric Fiselier#include "test_macros.h" 1830508da415SEric Fiselier 18312776be43SWim Leflere{cxx_tests} 1832508da415SEric Fiselier 18337bfaa0f0STobias Hieta""".format( 18347bfaa0f0STobias Hieta script_name=script_name, 1835508da415SEric Fiselier header=h, 18367bfaa0f0STobias Hieta markup=("\n{}\n".format(markup) if markup else ""), 1837508da415SEric Fiselier synopsis=generate_synopsis(test_list), 18387bfaa0f0STobias Hieta cxx_tests=generate_std_tests(test_list), 18397bfaa0f0STobias Hieta ) 18402c6217f2SLouis Dionne test_name = "{header}.version.compile.pass.cpp".format(header=h) 1841508da415SEric Fiselier out_path = os.path.join(macro_test_path, test_name) 18427bfaa0f0STobias Hieta with open(out_path, "w", newline="\n") as f: 1843508da415SEric Fiselier f.write(test_body) 1844508da415SEric Fiselier 18457bfaa0f0STobias Hieta 1846508da415SEric Fiselier""" 1847508da415SEric Fiselier Produce documentation for the feature test macros 1848508da415SEric Fiselier""" 1849508da415SEric Fiselier 18507bfaa0f0STobias Hieta 1851508da415SEric Fiselierdef make_widths(grid): 1852508da415SEric Fiselier widths = [] 1853508da415SEric Fiselier for i in range(0, len(grid[0])): 18547bfaa0f0STobias Hieta cell_width = 2 + max( 18557bfaa0f0STobias Hieta reduce(lambda x, y: x + y, [[len(row[i])] for row in grid], []) 18567bfaa0f0STobias Hieta ) 1857508da415SEric Fiselier widths += [cell_width] 1858508da415SEric Fiselier return widths 1859508da415SEric Fiselier 18607bfaa0f0STobias Hieta 1861508da415SEric Fiselierdef create_table(grid, indent): 18627bfaa0f0STobias Hieta indent_str = " " * indent 1863508da415SEric Fiselier col_widths = make_widths(grid) 18640451ed96SLouis Dionne result = [indent_str + add_divider(col_widths, 2)] 1865508da415SEric Fiselier header_flag = 2 1866fd02a468SLouis Dionne for row_i in range(0, len(grid)): 1867508da415SEric Fiselier row = grid[row_i] 18687bfaa0f0STobias Hieta line = indent_str + " ".join( 18697bfaa0f0STobias Hieta [pad_cell(row[i], col_widths[i]) for i in range(0, len(row))] 18707bfaa0f0STobias Hieta ) 18710451ed96SLouis Dionne result.append(line.rstrip()) 1872508da415SEric Fiselier if row_i == len(grid) - 1: 1873508da415SEric Fiselier header_flag = 2 18747bfaa0f0STobias Hieta if row[0].startswith("**"): 187500c97cbcSMark de Wever header_flag += 1 187600c97cbcSMark de Wever separator = indent_str + add_divider(col_widths, header_flag) 18770451ed96SLouis Dionne result.append(separator.rstrip()) 1878508da415SEric Fiselier header_flag = 0 18797bfaa0f0STobias Hieta return "\n".join(result) 18807bfaa0f0STobias Hieta 1881508da415SEric Fiselier 1882508da415SEric Fiselierdef add_divider(widths, header_flag): 188300c97cbcSMark de Wever if header_flag == 3: 18847bfaa0f0STobias Hieta return "=".join(["=" * w for w in widths]) 1885508da415SEric Fiselier if header_flag == 2: 18867bfaa0f0STobias Hieta return " ".join(["=" * w for w in widths]) 1887508da415SEric Fiselier if header_flag == 1: 18887bfaa0f0STobias Hieta return "-".join(["-" * w for w in widths]) 1889508da415SEric Fiselier else: 18907bfaa0f0STobias Hieta return " ".join(["-" * w for w in widths]) 18917bfaa0f0STobias Hieta 1892508da415SEric Fiselier 1893508da415SEric Fiselierdef pad_cell(s, length, left_align=True): 18947bfaa0f0STobias Hieta padding = (length - len(s)) * " " 1895508da415SEric Fiselier return s + padding 1896508da415SEric Fiselier 1897508da415SEric Fiselier 1898508da415SEric Fiselierdef get_status_table(): 1899508da415SEric Fiselier table = [["Macro Name", "Value"]] 1900508da415SEric Fiselier for std in get_std_dialects(): 1901508da415SEric Fiselier table += [["**" + std.replace("c++", "C++") + "**", ""]] 1902508da415SEric Fiselier for tc in feature_test_macros: 1903508da415SEric Fiselier if std not in tc["values"].keys(): 1904508da415SEric Fiselier continue 1905508da415SEric Fiselier value = "``%sL``" % tc["values"][std] 19067bfaa0f0STobias Hieta if "unimplemented" in tc.keys(): 19077bfaa0f0STobias Hieta value = "*unimplemented*" 1908508da415SEric Fiselier table += [["``%s``" % tc["name"], value]] 1909508da415SEric Fiselier return table 1910508da415SEric Fiselier 19117bfaa0f0STobias Hieta 1912508da415SEric Fiselierdef produce_docs(): 1913508da415SEric Fiselier doc_str = """.. _FeatureTestMacroTable: 1914508da415SEric Fiselier 1915508da415SEric Fiselier========================== 1916508da415SEric FiselierFeature Test Macro Support 1917508da415SEric Fiselier========================== 1918508da415SEric Fiselier 1919508da415SEric Fiselier.. contents:: 1920508da415SEric Fiselier :local: 1921508da415SEric Fiselier 1922508da415SEric FiselierOverview 1923508da415SEric Fiselier======== 1924508da415SEric Fiselier 1925508da415SEric FiselierThis file documents the feature test macros currently supported by libc++. 1926508da415SEric Fiselier 1927508da415SEric Fiselier.. _feature-status: 1928508da415SEric Fiselier 1929508da415SEric FiselierStatus 1930508da415SEric Fiselier====== 1931508da415SEric Fiselier 1932508da415SEric Fiselier.. table:: Current Status 1933508da415SEric Fiselier :name: feature-status-table 1934508da415SEric Fiselier :widths: auto 1935508da415SEric Fiselier 1936508da415SEric Fiselier{status_tables} 1937508da415SEric Fiselier 19387bfaa0f0STobias Hieta""".format( 19397bfaa0f0STobias Hieta status_tables=create_table(get_status_table(), 4) 19407bfaa0f0STobias Hieta ) 1941508da415SEric Fiselier 19427bfaa0f0STobias Hieta table_doc_path = os.path.join(docs_path, "FeatureTestMacroTable.rst") 19437bfaa0f0STobias Hieta with open(table_doc_path, "w", newline="\n") as f: 1944508da415SEric Fiselier f.write(doc_str) 1945508da415SEric Fiselier 19467bfaa0f0STobias Hieta 1947d2dd4b55SMark de Weverdef get_ftms( 1948d2dd4b55SMark de Wever data, std_dialects: List[str], use_implemented_status: bool 1949d2dd4b55SMark de Wever) -> Dict[str, Dict[str, Any]]: 1950d2dd4b55SMark de Wever """Impementation for FeatureTestMacros.(standard|implemented)_ftms().""" 1951d2dd4b55SMark de Wever result = dict() 1952d2dd4b55SMark de Wever for feature in data: 1953d2dd4b55SMark de Wever last = None 1954d2dd4b55SMark de Wever entry = dict() 1955d2dd4b55SMark de Wever implemented = True 1956d2dd4b55SMark de Wever for std in std_dialects: 1957d2dd4b55SMark de Wever if std not in feature["values"].keys(): 1958d2dd4b55SMark de Wever if last == None: 1959d2dd4b55SMark de Wever continue 1960d2dd4b55SMark de Wever else: 1961d2dd4b55SMark de Wever entry[std] = last 1962d2dd4b55SMark de Wever else: 1963d2dd4b55SMark de Wever if implemented: 1964d2dd4b55SMark de Wever values = feature["values"][std] 1965d2dd4b55SMark de Wever assert len(values) > 0, f"{feature['name']}[{std}] has no entries" 1966d2dd4b55SMark de Wever for value in values: 1967d2dd4b55SMark de Wever papers = list(values[value]) 1968d2dd4b55SMark de Wever assert ( 1969d2dd4b55SMark de Wever len(papers) > 0 1970d2dd4b55SMark de Wever ), f"{feature['name']}[{std}][{value}] has no entries" 1971d2dd4b55SMark de Wever for paper in papers: 1972d2dd4b55SMark de Wever if use_implemented_status and not paper["implemented"]: 1973d2dd4b55SMark de Wever implemented = False 1974d2dd4b55SMark de Wever break 1975d2dd4b55SMark de Wever if implemented: 1976d2dd4b55SMark de Wever last = f"{value}L" 1977d2dd4b55SMark de Wever else: 1978d2dd4b55SMark de Wever break 1979d2dd4b55SMark de Wever 1980d2dd4b55SMark de Wever entry[std] = last 1981d2dd4b55SMark de Wever result[feature["name"]] = entry 1982d2dd4b55SMark de Wever 1983d2dd4b55SMark de Wever return result 1984d2dd4b55SMark de Wever 1985d2dd4b55SMark de Wever 1986879640cbSMark de Weverdef generate_version_header_dialect_block(data: Dict[str, Any]) -> str: 1987879640cbSMark de Wever """Generates the contents of the version header for a dialect. 1988879640cbSMark de Wever 1989879640cbSMark de Wever This generates the contents of a 1990879640cbSMark de Wever #if _LIBCPP_STD_VER >= XY 1991879640cbSMark de Wever #endif // _LIBCPP_STD_VER >= XY 1992879640cbSMark de Wever block. 1993879640cbSMark de Wever """ 1994879640cbSMark de Wever result = "" 1995879640cbSMark de Wever for element in data: 1996879640cbSMark de Wever for ftm, entry in element.items(): 1997879640cbSMark de Wever if not entry["implemented"]: 1998879640cbSMark de Wever # When a FTM is not implemented don't add the guards 1999879640cbSMark de Wever # or undefine the (possibly) defined macro. 2000879640cbSMark de Wever result += f'// define {ftm} {entry["value"]}\n' 2001879640cbSMark de Wever else: 2002879640cbSMark de Wever need_undef = entry["need_undef"] 2003879640cbSMark de Wever if entry["condition"]: 2004879640cbSMark de Wever result += f'# if {entry["condition"]}\n' 2005879640cbSMark de Wever if entry["need_undef"]: 2006879640cbSMark de Wever result += f"# undef {ftm}\n" 2007879640cbSMark de Wever result += f'# define {ftm} {entry["value"]}\n' 2008879640cbSMark de Wever result += f"# endif\n" 2009879640cbSMark de Wever else: 2010879640cbSMark de Wever if entry["need_undef"]: 2011879640cbSMark de Wever result += f"# undef {ftm}\n" 2012879640cbSMark de Wever result += f'# define {ftm} {entry["value"]}\n' 2013879640cbSMark de Wever 2014879640cbSMark de Wever return result 2015879640cbSMark de Wever 2016879640cbSMark de Wever 2017879640cbSMark de Weverdef generate_version_header_implementation(data: Dict[str, Dict[str, Any]]) -> str: 2018879640cbSMark de Wever """Generates the body of the version header.""" 2019879640cbSMark de Wever 2020879640cbSMark de Wever template = """#if _LIBCPP_STD_VER >= {dialect} 2021879640cbSMark de Wever{feature_test_macros}#endif // _LIBCPP_STD_VER >= {dialect}""" 2022879640cbSMark de Wever 2023879640cbSMark de Wever result = [] 2024879640cbSMark de Wever for std, ftms in data.items(): 2025879640cbSMark de Wever result.append( 2026879640cbSMark de Wever template.format( 2027879640cbSMark de Wever dialect=std, 2028879640cbSMark de Wever feature_test_macros=generate_version_header_dialect_block(ftms), 2029879640cbSMark de Wever ) 2030879640cbSMark de Wever ) 2031879640cbSMark de Wever 2032879640cbSMark de Wever return "\n\n".join(result) 2033879640cbSMark de Wever 2034879640cbSMark de Wever 2035d2dd4b55SMark de Weverclass FeatureTestMacros: 2036d2dd4b55SMark de Wever """Provides all feature-test macro (FTM) output components. 2037d2dd4b55SMark de Wever 2038d2dd4b55SMark de Wever The class has several generators to use the feature-test macros in libc++: 2039d2dd4b55SMark de Wever - FTM status page 2040d2dd4b55SMark de Wever - The version header and its tests 2041d2dd4b55SMark de Wever 2042d2dd4b55SMark de Wever This class is not intended to duplicate 2043d2dd4b55SMark de Wever https://isocpp.org/std/standing-documents/sd-6-sg10-feature-test-recommendations#library-feature-test-macros 2044d2dd4b55SMark de Wever SD-FeatureTest: Feature-Test Macros and Policies 2045d2dd4b55SMark de Wever 2046d2dd4b55SMark de Wever Historically libc++ did not list all papers affecting a FTM, the new data 2047d2dd4b55SMark de Wever structure is able to do that. However there is no intention to add the 2048d2dd4b55SMark de Wever historical data. After papers have been implemented this information can be 2049d2dd4b55SMark de Wever removed. For example, __cpp_lib_format's value 201907 requires 3 papers, 2050d2dd4b55SMark de Wever once implemented it can be reduced to 1 paper and remove the paper number 2051d2dd4b55SMark de Wever and title. This would reduce the size of the data. 2052d2dd4b55SMark de Wever 2053d2dd4b55SMark de Wever The input data is stored in the following JSON format: 2054d2dd4b55SMark de Wever [ # A list with multiple feature-test macro entries. 2055d2dd4b55SMark de Wever { 2056d2dd4b55SMark de Wever # required 2057d2dd4b55SMark de Wever # The name of the feature test macro. These names should be unique and 2058d2dd4b55SMark de Wever # sorted in the list. 2059d2dd4b55SMark de Wever "name": "__cpp_lib_any", 2060d2dd4b55SMark de Wever 2061d2dd4b55SMark de Wever # required 2062d2dd4b55SMark de Wever # A map with the value of the FTM based on the language standard. Only 2063d2dd4b55SMark de Wever # the versions in which the value of the FTM changes are listed. For 2064d2dd4b55SMark de Wever # example, this macro's value does not change in C++20 so it does not 2065d2dd4b55SMark de Wever # list C++20. If it changes in C++26, it will have entries for C++17 and 2066d2dd4b55SMark de Wever # C++26. 2067d2dd4b55SMark de Wever "values": { 2068d2dd4b55SMark de Wever 2069d2dd4b55SMark de Wever # required 2070d2dd4b55SMark de Wever # The language standard, also named dialect in this class. 2071d2dd4b55SMark de Wever "c++17": { 2072d2dd4b55SMark de Wever 2073d2dd4b55SMark de Wever # required 2074d2dd4b55SMark de Wever # The value of the feature test macro. This contains an array with 2075d2dd4b55SMark de Wever # one or more papers that need to be implemented before this value 2076d2dd4b55SMark de Wever # is considered implemented. 2077d2dd4b55SMark de Wever "201606": [ 2078d2dd4b55SMark de Wever { 2079d2dd4b55SMark de Wever # optional 2080d2dd4b55SMark de Wever # Contains the paper number that is part of the FTM version. 2081d2dd4b55SMark de Wever "number": "P0220R1", 2082d2dd4b55SMark de Wever 2083d2dd4b55SMark de Wever # optional 2084d2dd4b55SMark de Wever # Contains the title of the paper that is part of the FTM 2085d2dd4b55SMark de Wever # version. 2086d2dd4b55SMark de Wever "title": "Adopt Library Fundamentals V1 TS Components for C++17" 2087d2dd4b55SMark de Wever 2088d2dd4b55SMark de Wever # required 2089d2dd4b55SMark de Wever # The implementation status of the paper. 2090d2dd4b55SMark de Wever "implemented": true 2091d2dd4b55SMark de Wever } 2092d2dd4b55SMark de Wever ] 2093d2dd4b55SMark de Wever } 2094d2dd4b55SMark de Wever }, 2095d2dd4b55SMark de Wever 2096d2dd4b55SMark de Wever # required 2097d2dd4b55SMark de Wever # A sorted list of headers that should provide the FTM. The header 2098d2dd4b55SMark de Wever # <version> is automatically added to this list. This list could be 2099d2dd4b55SMark de Wever # empty. For example, __cpp_lib_modules is only present in version. 2100d2dd4b55SMark de Wever # Requiring the field makes it easier to detect accidental omission. 2101d2dd4b55SMark de Wever "headers": [ 2102d2dd4b55SMark de Wever "any" 2103d2dd4b55SMark de Wever ], 2104d2dd4b55SMark de Wever 2105d2dd4b55SMark de Wever # optional, required when libcxx_guard is present 2106d2dd4b55SMark de Wever # This field is used only to generate the unit tests for the 2107d2dd4b55SMark de Wever # feature-test macros. It can't depend on macros defined in <__config> 2108d2dd4b55SMark de Wever # because the `test/std/` parts of the test suite are intended to be 2109d2dd4b55SMark de Wever # portable to any C++ standard library implementation, not just libc++. 2110d2dd4b55SMark de Wever # It may depend on 2111d2dd4b55SMark de Wever # * macros defined by the compiler itself, or 2112d2dd4b55SMark de Wever # * macros generated by CMake. 2113d2dd4b55SMark de Wever # In some cases we add also depend on macros defined in 2114d2dd4b55SMark de Wever # <__availability>. 2115d2dd4b55SMark de Wever "test_suite_guard": "!defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_PMR" 2116d2dd4b55SMark de Wever 2117d2dd4b55SMark de Wever # optional, required when test_suite_guard is present 2118d2dd4b55SMark de Wever # This field is used only to guard the feature-test macro in 2119d2dd4b55SMark de Wever # <version>. It may be the same as `test_suite_guard`, or it may 2120d2dd4b55SMark de Wever # depend on macros defined in <__config>. 2121d2dd4b55SMark de Wever "libcxx_guard": "_LIBCPP_AVAILABILITY_HAS_PMR" 2122d2dd4b55SMark de Wever }, 2123d2dd4b55SMark de Wever ] 2124d2dd4b55SMark de Wever """ 2125d2dd4b55SMark de Wever 2126d2dd4b55SMark de Wever # The JSON data structure. 2127d2dd4b55SMark de Wever __data = None 2128d2dd4b55SMark de Wever 2129d2dd4b55SMark de Wever def __init__(self, filename: str): 2130d2dd4b55SMark de Wever """Initializes the class with the JSON data in the file 'filename'.""" 2131c4a42f61SLouis Dionne with open(filename) as f: 2132c4a42f61SLouis Dionne self.__data = json.load(f) 2133d2dd4b55SMark de Wever 2134d2dd4b55SMark de Wever @functools.cached_property 2135d2dd4b55SMark de Wever def std_dialects(self) -> List[str]: 2136d2dd4b55SMark de Wever """Returns the C++ dialects avaiable. 2137d2dd4b55SMark de Wever 2138d2dd4b55SMark de Wever The available dialects are based on the 'c++xy' keys found the 'values' 2139d2dd4b55SMark de Wever entries in '__data'. So when WG21 starts to feature-test macros for a 2140d2dd4b55SMark de Wever future C++ Standard this dialect will automatically be available. 2141d2dd4b55SMark de Wever 2142d2dd4b55SMark de Wever The return value is a sorted list with the C++ dialects used. Since FTM 2143d2dd4b55SMark de Wever were added in C++14 the list will not contain C++03 or C++11. 2144d2dd4b55SMark de Wever """ 2145d2dd4b55SMark de Wever dialects = set() 2146d2dd4b55SMark de Wever for feature in self.__data: 2147d2dd4b55SMark de Wever keys = feature["values"].keys() 2148d2dd4b55SMark de Wever assert len(keys) > 0, "'values' is empty" 2149d2dd4b55SMark de Wever dialects |= keys 2150d2dd4b55SMark de Wever 2151d2dd4b55SMark de Wever return sorted(list(dialects)) 2152d2dd4b55SMark de Wever 2153d2dd4b55SMark de Wever @functools.cached_property 2154d2dd4b55SMark de Wever def standard_ftms(self) -> Dict[str, Dict[str, Any]]: 2155d2dd4b55SMark de Wever """Returns the FTM versions per dialect in the Standard. 2156d2dd4b55SMark de Wever 2157d2dd4b55SMark de Wever This function does not use the 'implemented' flag. The output contains 2158d2dd4b55SMark de Wever the versions used in the Standard. When a FTM in libc++ is not 2159d2dd4b55SMark de Wever implemented according to the Standard to output may opt to show the 2160d2dd4b55SMark de Wever expected value. 2161d2dd4b55SMark de Wever 2162d2dd4b55SMark de Wever The result is a dict with the following content 2163d2dd4b55SMark de Wever - key: Name of the feature test macro. 2164d2dd4b55SMark de Wever - value: A dict with the following content: 2165d2dd4b55SMark de Wever * key: The version of the C++ dialect. 2166d2dd4b55SMark de Wever * value: The value of the feature-test macro. 2167d2dd4b55SMark de Wever """ 2168d2dd4b55SMark de Wever return get_ftms(self.__data, self.std_dialects, False) 2169d2dd4b55SMark de Wever 2170d2dd4b55SMark de Wever @functools.cached_property 2171d2dd4b55SMark de Wever def implemented_ftms(self) -> Dict[str, Dict[str, Any]]: 2172d2dd4b55SMark de Wever """Returns the FTM versions per dialect implemented in libc++. 2173d2dd4b55SMark de Wever 2174d2dd4b55SMark de Wever Unlike `get_std_dialect_versions` this function uses the 'implemented' 2175d2dd4b55SMark de Wever flag. This returns the actual implementation status in libc++. 2176d2dd4b55SMark de Wever 2177d2dd4b55SMark de Wever The result is a dict with the following content 2178d2dd4b55SMark de Wever - key: Name of the feature test macro. 2179d2dd4b55SMark de Wever - value: A dict with the following content: 2180d2dd4b55SMark de Wever * key: The version of the C++ dialect. 2181d2dd4b55SMark de Wever * value: The value of the feature-test macro. When a feature-test 2182d2dd4b55SMark de Wever macro is not implemented its value is None. 2183d2dd4b55SMark de Wever """ 2184d2dd4b55SMark de Wever 2185d2dd4b55SMark de Wever return get_ftms(self.__data, self.std_dialects, True) 2186d2dd4b55SMark de Wever 2187879640cbSMark de Wever @functools.cached_property 2188879640cbSMark de Wever def ftm_metadata(self) -> Dict[str, Dict[str, Any]]: 2189879640cbSMark de Wever """Returns the metadata of the FTMs defined in the Standard. 2190879640cbSMark de Wever 2191879640cbSMark de Wever The metadata does not depend on the C++ dialect used. 2192879640cbSMark de Wever The result is a dict with the following contents: 2193879640cbSMark de Wever - key: Name of the feature test macro. 2194879640cbSMark de Wever - value: A dict with the following content: 2195879640cbSMark de Wever * headers: The list of headers that should provide the FTM 2196879640cbSMark de Wever * test_suite_guard: The condition for testing the FTM in the test suite. 2197879640cbSMark de Wever * test_suite_guard: The condition for testing the FTM in the version header. 2198879640cbSMark de Wever """ 2199879640cbSMark de Wever result = dict() 2200879640cbSMark de Wever for feature in self.__data: 2201879640cbSMark de Wever entry = dict() 2202879640cbSMark de Wever entry["headers"] = feature["headers"] 2203879640cbSMark de Wever entry["test_suite_guard"] = feature.get("test_suite_guard", None) 2204879640cbSMark de Wever entry["libcxx_guard"] = feature.get("libcxx_guard", None) 2205879640cbSMark de Wever result[feature["name"]] = entry 2206879640cbSMark de Wever 2207879640cbSMark de Wever return result 2208879640cbSMark de Wever 2209879640cbSMark de Wever @property 2210879640cbSMark de Wever def version_header_implementation(self) -> Dict[str, List[Dict[str, Any]]]: 2211879640cbSMark de Wever """Generates the body of the version header.""" 2212879640cbSMark de Wever result = dict() 2213879640cbSMark de Wever for std in self.std_dialects: 2214879640cbSMark de Wever result[get_std_number(std)] = list() 2215879640cbSMark de Wever 2216879640cbSMark de Wever for ftm, values in self.standard_ftms.items(): 2217879640cbSMark de Wever last_value = None 2218c4a42f61SLouis Dionne last_entry = None 2219879640cbSMark de Wever for std, value in values.items(): 2220879640cbSMark de Wever # When a newer Standard does not change the value of the macro 2221879640cbSMark de Wever # there is no need to redefine it with the same value. 2222879640cbSMark de Wever if last_value and value == last_value: 2223879640cbSMark de Wever continue 2224879640cbSMark de Wever last_value = value 2225879640cbSMark de Wever 2226879640cbSMark de Wever entry = dict() 2227879640cbSMark de Wever entry["value"] = value 2228c4a42f61SLouis Dionne entry["implemented"] = self.implemented_ftms[ftm][std] == self.standard_ftms[ftm][std] 2229c4a42f61SLouis Dionne entry["need_undef"] = last_entry is not None and last_entry["implemented"] and entry["implemented"] 2230879640cbSMark de Wever entry["condition"] = self.ftm_metadata[ftm]["libcxx_guard"] 2231879640cbSMark de Wever 2232c4a42f61SLouis Dionne last_entry = entry 2233879640cbSMark de Wever result[get_std_number(std)].append(dict({ftm: entry})) 2234879640cbSMark de Wever 2235879640cbSMark de Wever return result 2236879640cbSMark de Wever 2237879640cbSMark de Wever @property 2238879640cbSMark de Wever def version_header(self) -> str: 2239879640cbSMark de Wever """Generates the version header.""" 2240879640cbSMark de Wever template = """// -*- C++ -*- 2241879640cbSMark de Wever//===----------------------------------------------------------------------===// 2242879640cbSMark de Wever// 2243879640cbSMark de Wever// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 2244879640cbSMark de Wever// See https://llvm.org/LICENSE.txt for license information. 2245879640cbSMark de Wever// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 2246879640cbSMark de Wever// 2247879640cbSMark de Wever//===----------------------------------------------------------------------===// 2248879640cbSMark de Wever 22497b2d592aSLouis Dionne#ifndef _LIBCPP_VERSIONH 22507b2d592aSLouis Dionne#define _LIBCPP_VERSIONH 2251879640cbSMark de Wever 2252879640cbSMark de Wever#include <__config> 2253879640cbSMark de Wever 2254879640cbSMark de Wever#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 2255879640cbSMark de Wever# pragma GCC system_header 2256879640cbSMark de Wever#endif 2257879640cbSMark de Wever 2258879640cbSMark de Wever{feature_test_macros} 2259879640cbSMark de Wever 22607b2d592aSLouis Dionne#endif // _LIBCPP_VERSIONH 2261879640cbSMark de Wever""" 2262879640cbSMark de Wever return template.format( 2263879640cbSMark de Wever feature_test_macros=generate_version_header_implementation( 2264879640cbSMark de Wever self.version_header_implementation 2265879640cbSMark de Wever ) 2266879640cbSMark de Wever ) 2267879640cbSMark de Wever 2268d2dd4b55SMark de Wever 2269508da415SEric Fiselierdef main(): 2270647fb6b3SLouis Dionne produce_version_header() 2271508da415SEric Fiselier produce_tests() 2272508da415SEric Fiselier produce_docs() 2273508da415SEric Fiselier 2274879640cbSMark de Wever # Example how to use the new version header generation function to generate 2275879640cbSMark de Wever # the file. 2276879640cbSMark de Wever if False: 2277879640cbSMark de Wever ftm = FeatureTestMacros( 2278879640cbSMark de Wever os.path.join( 2279879640cbSMark de Wever source_root, "test", "libcxx", "feature_test_macro", "test_data.json" 2280879640cbSMark de Wever ) 2281879640cbSMark de Wever ) 2282879640cbSMark de Wever version_header_path = os.path.join(include_path, "version") 2283879640cbSMark de Wever with open(version_header_path, "w", newline="\n") as f: 2284879640cbSMark de Wever f.write(ftm.version_header) 2285879640cbSMark de Wever 2286508da415SEric Fiselier 22877bfaa0f0STobias Hietaif __name__ == "__main__": 2288508da415SEric Fiselier main() 2289