146035553Spatrick#!/usr/bin/env python 246035553Spatrick 346035553Spatrickimport os 476d0caaeSpatrickfrom builtins import range 546035553Spatrickfrom functools import reduce 646035553Spatrick 746035553Spatrickdef get_libcxx_paths(): 846035553Spatrick utils_path = os.path.dirname(os.path.abspath(__file__)) 946035553Spatrick script_name = os.path.basename(__file__) 1046035553Spatrick assert os.path.exists(utils_path) 1146035553Spatrick src_root = os.path.dirname(utils_path) 1246035553Spatrick include_path = os.path.join(src_root, 'include') 1346035553Spatrick assert os.path.exists(include_path) 1446035553Spatrick docs_path = os.path.join(src_root, 'docs') 1546035553Spatrick assert os.path.exists(docs_path) 1646035553Spatrick macro_test_path = os.path.join(src_root, 'test', 'std', 'language.support', 1746035553Spatrick 'support.limits', 'support.limits.general') 1846035553Spatrick assert os.path.exists(macro_test_path) 19*4bdff4beSrobert assert os.path.exists(os.path.join(macro_test_path, 'version.version.compile.pass.cpp')) 2046035553Spatrick return script_name, src_root, include_path, docs_path, macro_test_path 2146035553Spatrick 2246035553Spatrickscript_name, source_root, include_path, docs_path, macro_test_path = get_libcxx_paths() 2346035553Spatrick 2446035553Spatrickdef has_header(h): 2546035553Spatrick h_path = os.path.join(include_path, h) 2646035553Spatrick return os.path.exists(h_path) 2746035553Spatrick 2846035553Spatrickdef add_version_header(tc): 2946035553Spatrick tc["headers"].append("version") 3046035553Spatrick return tc 3146035553Spatrick 3276d0caaeSpatrick# ================ ============================================================ 3376d0caaeSpatrick# Field Description 3476d0caaeSpatrick# ================ ============================================================ 3576d0caaeSpatrick# name The name of the feature-test macro. 3676d0caaeSpatrick# values A dict whose keys are C++ versions and whose values are the 3776d0caaeSpatrick# value of the feature-test macro for that C++ version. 3876d0caaeSpatrick# (TODO: This isn't a very clean model for feature-test 3976d0caaeSpatrick# macros affected by multiple papers.) 4076d0caaeSpatrick# headers An array with the headers that should provide the 4176d0caaeSpatrick# feature-test macro. 4276d0caaeSpatrick# test_suite_guard An optional string field. When this field is provided, 4376d0caaeSpatrick# `libcxx_guard` must also be provided. This field is used 4476d0caaeSpatrick# only to generate the unit tests for the feature-test macros. 4576d0caaeSpatrick# It can't depend on macros defined in <__config> because the 4676d0caaeSpatrick# `test/std/` parts of the test suite are intended to be 4776d0caaeSpatrick# portable to any C++ standard library implementation, not 4876d0caaeSpatrick# just libc++. It may depend on 4976d0caaeSpatrick# * macros defined by the compiler itself, or 5076d0caaeSpatrick# * macros generated by CMake. 5176d0caaeSpatrick# In some cases we add 5276d0caaeSpatrick# `&& !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM_...)` 5376d0caaeSpatrick# in order to make libc++ pass the tests on OSX; see D94983. 5476d0caaeSpatrick# libcxx_guard An optional string field. When this field is provided, 5576d0caaeSpatrick# `test_suite_guard` must also be provided. This field is used 5676d0caaeSpatrick# only to guard the feature-test macro in <version>. It may 5776d0caaeSpatrick# be the same as `test_suite_guard`, or it may depend on 5876d0caaeSpatrick# macros defined in <__config>. 5976d0caaeSpatrick# unimplemented An optional Boolean field with the value `True`. This field 6076d0caaeSpatrick# is only used when a feature isn't fully implemented. Once 6176d0caaeSpatrick# you've fully implemented the feature, you should remove 6276d0caaeSpatrick# this field. 6376d0caaeSpatrick# ================ ============================================================ 6476d0caaeSpatrickfeature_test_macros = [ add_version_header(x) for x in [ 6576d0caaeSpatrick { 66*4bdff4beSrobert "name": "__cpp_lib_adaptor_iterator_pair_constructor", 67*4bdff4beSrobert "values": { "c++2b": 202106 }, 68*4bdff4beSrobert "headers": ["queue", "stack"], 69*4bdff4beSrobert }, { 7076d0caaeSpatrick "name": "__cpp_lib_addressof_constexpr", 7176d0caaeSpatrick "values": { "c++17": 201603 }, 7246035553Spatrick "headers": ["memory"], 73*4bdff4beSrobert }, { 74*4bdff4beSrobert "name": "__cpp_lib_allocate_at_least", 75*4bdff4beSrobert "values": { "c++2b": 202106 }, 76*4bdff4beSrobert "headers": ["memory"], 7776d0caaeSpatrick }, { 7876d0caaeSpatrick "name": "__cpp_lib_allocator_traits_is_always_equal", 7976d0caaeSpatrick "values": { "c++17": 201411 }, 8076d0caaeSpatrick "headers": ["deque", "forward_list", "list", "map", "memory", "scoped_allocator", "set", "string", "unordered_map", "unordered_set", "vector"], 8176d0caaeSpatrick }, { 8276d0caaeSpatrick "name": "__cpp_lib_any", 8376d0caaeSpatrick "values": { "c++17": 201606 }, 8446035553Spatrick "headers": ["any"], 8576d0caaeSpatrick }, { 8676d0caaeSpatrick "name": "__cpp_lib_apply", 8776d0caaeSpatrick "values": { "c++17": 201603 }, 8876d0caaeSpatrick "headers": ["tuple"], 8976d0caaeSpatrick }, { 9076d0caaeSpatrick "name": "__cpp_lib_array_constexpr", 9176d0caaeSpatrick "values": { "c++17": 201603, "c++20": 201811 }, 9276d0caaeSpatrick "headers": ["array", "iterator"], 9376d0caaeSpatrick }, { 9476d0caaeSpatrick "name": "__cpp_lib_as_const", 9576d0caaeSpatrick "values": { "c++17": 201510 }, 9676d0caaeSpatrick "headers": ["utility"], 9776d0caaeSpatrick }, { 98*4bdff4beSrobert "name": "__cpp_lib_associative_heterogeneous_erasure", 99*4bdff4beSrobert "values": { "c++2b": 202110 }, 100*4bdff4beSrobert "headers": ["map", "set", "unordered_map", "unordered_set"], 101*4bdff4beSrobert "unimplemented": True, 102*4bdff4beSrobert }, { 10376d0caaeSpatrick "name": "__cpp_lib_assume_aligned", 10476d0caaeSpatrick "values": { "c++20": 201811 }, 10546035553Spatrick "headers": ["memory"], 10676d0caaeSpatrick }, { 10776d0caaeSpatrick "name": "__cpp_lib_atomic_flag_test", 10876d0caaeSpatrick "values": { "c++20": 201907 }, 10976d0caaeSpatrick "headers": ["atomic"], 11076d0caaeSpatrick }, { 11176d0caaeSpatrick "name": "__cpp_lib_atomic_float", 11276d0caaeSpatrick "values": { "c++20": 201711 }, 11376d0caaeSpatrick "headers": ["atomic"], 11476d0caaeSpatrick "unimplemented": True, 11576d0caaeSpatrick }, { 11676d0caaeSpatrick "name": "__cpp_lib_atomic_is_always_lock_free", 11776d0caaeSpatrick "values": { "c++17": 201603 }, 11876d0caaeSpatrick "headers": ["atomic"], 11976d0caaeSpatrick }, { 12076d0caaeSpatrick "name": "__cpp_lib_atomic_lock_free_type_aliases", 12176d0caaeSpatrick "values": { "c++20": 201907 }, 12276d0caaeSpatrick "headers": ["atomic"], 12376d0caaeSpatrick }, { 12476d0caaeSpatrick "name": "__cpp_lib_atomic_ref", 12576d0caaeSpatrick "values": { "c++20": 201806 }, 12676d0caaeSpatrick "headers": ["atomic"], 12776d0caaeSpatrick "unimplemented": True, 12876d0caaeSpatrick }, { 12976d0caaeSpatrick "name": "__cpp_lib_atomic_shared_ptr", 13076d0caaeSpatrick "values": { "c++20": 201711 }, 13176d0caaeSpatrick "headers": ["atomic"], 13276d0caaeSpatrick "unimplemented": True, 13376d0caaeSpatrick }, { 13476d0caaeSpatrick "name": "__cpp_lib_atomic_value_initialization", 13576d0caaeSpatrick "values": { "c++20": 201911 }, 13676d0caaeSpatrick "headers": ["atomic", "memory"], 13776d0caaeSpatrick }, { 13876d0caaeSpatrick "name": "__cpp_lib_atomic_wait", 13976d0caaeSpatrick "values": { "c++20": 201907 }, 14076d0caaeSpatrick "headers": ["atomic"], 141*4bdff4beSrobert "test_suite_guard": "!defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_atomic_wait)", 142*4bdff4beSrobert "libcxx_guard": "!defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_atomic_wait)", 14376d0caaeSpatrick }, { 14476d0caaeSpatrick "name": "__cpp_lib_barrier", 14576d0caaeSpatrick "values": { "c++20": 201907 }, 14676d0caaeSpatrick "headers": ["barrier"], 14776d0caaeSpatrick "test_suite_guard": "!defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_barrier)", 14876d0caaeSpatrick "libcxx_guard": "!defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_barrier)", 14976d0caaeSpatrick }, { 150*4bdff4beSrobert "name": "__cpp_lib_bind_back", 151*4bdff4beSrobert "values": { "c++2b": 202202 }, 152*4bdff4beSrobert "headers": ["functional"], 153*4bdff4beSrobert "unimplemented": True, 154*4bdff4beSrobert }, { 15576d0caaeSpatrick "name": "__cpp_lib_bind_front", 15676d0caaeSpatrick "values": { "c++20": 201907 }, 15776d0caaeSpatrick "headers": ["functional"], 15876d0caaeSpatrick }, { 15976d0caaeSpatrick "name": "__cpp_lib_bit_cast", 16076d0caaeSpatrick "values": { "c++20": 201806 }, 16176d0caaeSpatrick "headers": ["bit"], 16276d0caaeSpatrick }, { 16376d0caaeSpatrick "name": "__cpp_lib_bitops", 16476d0caaeSpatrick "values": { "c++20": 201907 }, 16576d0caaeSpatrick "headers": ["bit"], 16676d0caaeSpatrick "unimplemented": True, 16776d0caaeSpatrick }, { 16876d0caaeSpatrick "name": "__cpp_lib_bool_constant", 16976d0caaeSpatrick "values": { "c++17": 201505 }, 17076d0caaeSpatrick "headers": ["type_traits"], 17176d0caaeSpatrick }, { 17276d0caaeSpatrick "name": "__cpp_lib_bounded_array_traits", 17376d0caaeSpatrick "values": { "c++20": 201902 }, 17476d0caaeSpatrick "headers": ["type_traits"], 17576d0caaeSpatrick }, { 17676d0caaeSpatrick "name": "__cpp_lib_boyer_moore_searcher", 17776d0caaeSpatrick "values": { "c++17": 201603 }, 17876d0caaeSpatrick "headers": ["functional"], 17976d0caaeSpatrick }, { 18076d0caaeSpatrick "name": "__cpp_lib_byte", 18176d0caaeSpatrick "values": { "c++17": 201603 }, 18276d0caaeSpatrick "headers": ["cstddef"], 18376d0caaeSpatrick }, { 184*4bdff4beSrobert "name": "__cpp_lib_byteswap", 185*4bdff4beSrobert "values": { "c++2b": 202110 }, 186*4bdff4beSrobert "headers": ["bit"], 187*4bdff4beSrobert }, { 18876d0caaeSpatrick "name": "__cpp_lib_char8_t", 189*4bdff4beSrobert "values": { "c++20": 201907 }, 19076d0caaeSpatrick "headers": ["atomic", "filesystem", "istream", "limits", "locale", "ostream", "string", "string_view"], 19176d0caaeSpatrick "test_suite_guard": "defined(__cpp_char8_t)", 19276d0caaeSpatrick "libcxx_guard": "!defined(_LIBCPP_HAS_NO_CHAR8_T)", 19376d0caaeSpatrick }, { 19476d0caaeSpatrick "name": "__cpp_lib_chrono", 19576d0caaeSpatrick "values": { "c++17": 201611 }, 19676d0caaeSpatrick "headers": ["chrono"], 19776d0caaeSpatrick }, { 19876d0caaeSpatrick "name": "__cpp_lib_chrono_udls", 19976d0caaeSpatrick "values": { "c++14": 201304 }, 20076d0caaeSpatrick "headers": ["chrono"], 20176d0caaeSpatrick }, { 20276d0caaeSpatrick "name": "__cpp_lib_clamp", 20376d0caaeSpatrick "values": { "c++17": 201603 }, 20476d0caaeSpatrick "headers": ["algorithm"], 20576d0caaeSpatrick }, { 20676d0caaeSpatrick "name": "__cpp_lib_complex_udls", 20776d0caaeSpatrick "values": { "c++14": 201309 }, 20876d0caaeSpatrick "headers": ["complex"], 20976d0caaeSpatrick }, { 21076d0caaeSpatrick "name": "__cpp_lib_concepts", 21176d0caaeSpatrick "values": { "c++20": 202002 }, 21276d0caaeSpatrick "headers": ["concepts"], 21376d0caaeSpatrick }, { 21476d0caaeSpatrick "name": "__cpp_lib_constexpr_algorithms", 21576d0caaeSpatrick "values": { "c++20": 201806 }, 216*4bdff4beSrobert "headers": ["algorithm", "utility"], 217*4bdff4beSrobert }, { 218*4bdff4beSrobert "name": "__cpp_lib_constexpr_bitset", 219*4bdff4beSrobert "values": { "c++2b": 202207 }, 220*4bdff4beSrobert "headers": ["bitset"], 221*4bdff4beSrobert }, { 222*4bdff4beSrobert "name": "__cpp_lib_constexpr_charconv", 223*4bdff4beSrobert "values": { "c++2b": 202207 }, 224*4bdff4beSrobert "headers": ["charconv"], 225*4bdff4beSrobert }, { 226*4bdff4beSrobert "name": "__cpp_lib_constexpr_cmath", 227*4bdff4beSrobert "values": { "c++2b": 202202 }, 228*4bdff4beSrobert "headers": ["cmath", "cstdlib"], 229*4bdff4beSrobert "unimplemented": True, 23076d0caaeSpatrick }, { 23176d0caaeSpatrick "name": "__cpp_lib_constexpr_complex", 23276d0caaeSpatrick "values": { "c++20": 201711 }, 23376d0caaeSpatrick "headers": ["complex"], 23476d0caaeSpatrick }, { 23576d0caaeSpatrick "name": "__cpp_lib_constexpr_dynamic_alloc", 23676d0caaeSpatrick "values": { "c++20": 201907 }, 23776d0caaeSpatrick "headers": ["memory"], 23876d0caaeSpatrick }, { 23976d0caaeSpatrick "name": "__cpp_lib_constexpr_functional", 24076d0caaeSpatrick "values": { "c++20": 201907 }, 24176d0caaeSpatrick "headers": ["functional"], 24276d0caaeSpatrick }, { 24376d0caaeSpatrick "name": "__cpp_lib_constexpr_iterator", 24476d0caaeSpatrick "values": { "c++20": 201811 }, 24576d0caaeSpatrick "headers": ["iterator"], 24676d0caaeSpatrick }, { 24776d0caaeSpatrick "name": "__cpp_lib_constexpr_memory", 248*4bdff4beSrobert "values": { "c++20": 201811, "c++2b": 202202 }, 24976d0caaeSpatrick "headers": ["memory"], 25076d0caaeSpatrick }, { 25176d0caaeSpatrick "name": "__cpp_lib_constexpr_numeric", 25276d0caaeSpatrick "values": { "c++20": 201911 }, 25376d0caaeSpatrick "headers": ["numeric"], 25476d0caaeSpatrick }, { 25576d0caaeSpatrick "name": "__cpp_lib_constexpr_string", 256*4bdff4beSrobert "values": { "c++20": 201907 }, 25776d0caaeSpatrick "headers": ["string"], 25876d0caaeSpatrick }, { 25976d0caaeSpatrick "name": "__cpp_lib_constexpr_string_view", 26076d0caaeSpatrick "values": { "c++20": 201811 }, 26176d0caaeSpatrick "headers": ["string_view"], 26276d0caaeSpatrick }, { 26376d0caaeSpatrick "name": "__cpp_lib_constexpr_tuple", 26476d0caaeSpatrick "values": { "c++20": 201811 }, 26576d0caaeSpatrick "headers": ["tuple"], 26676d0caaeSpatrick }, { 267*4bdff4beSrobert "name": "__cpp_lib_constexpr_typeinfo", 268*4bdff4beSrobert "values": { "c++2b": 202106 }, 269*4bdff4beSrobert "headers": ["typeinfo"], 270*4bdff4beSrobert "unimplemented": True, 271*4bdff4beSrobert }, { 27276d0caaeSpatrick "name": "__cpp_lib_constexpr_utility", 27376d0caaeSpatrick "values": { "c++20": 201811 }, 27476d0caaeSpatrick "headers": ["utility"], 27576d0caaeSpatrick }, { 27676d0caaeSpatrick "name": "__cpp_lib_constexpr_vector", 27776d0caaeSpatrick "values": { "c++20": 201907 }, 27876d0caaeSpatrick "headers": ["vector"], 27976d0caaeSpatrick }, { 28076d0caaeSpatrick "name": "__cpp_lib_coroutine", 28176d0caaeSpatrick "values": { "c++20": 201902 }, 28276d0caaeSpatrick "headers": ["coroutine"], 28376d0caaeSpatrick }, { 28476d0caaeSpatrick "name": "__cpp_lib_destroying_delete", 28576d0caaeSpatrick "values": { "c++20": 201806 }, 28676d0caaeSpatrick "headers": ["new"], 28776d0caaeSpatrick "test_suite_guard": "TEST_STD_VER > 17 && defined(__cpp_impl_destroying_delete) && __cpp_impl_destroying_delete >= 201806L", 28876d0caaeSpatrick "libcxx_guard": "_LIBCPP_STD_VER > 17 && defined(__cpp_impl_destroying_delete) && __cpp_impl_destroying_delete >= 201806L", 28976d0caaeSpatrick }, { 29076d0caaeSpatrick "name": "__cpp_lib_enable_shared_from_this", 29176d0caaeSpatrick "values": { "c++17": 201603 }, 29276d0caaeSpatrick "headers": ["memory"], 29376d0caaeSpatrick }, { 29476d0caaeSpatrick "name": "__cpp_lib_endian", 29576d0caaeSpatrick "values": { "c++20": 201907 }, 29676d0caaeSpatrick "headers": ["bit"], 29776d0caaeSpatrick }, { 29876d0caaeSpatrick "name": "__cpp_lib_erase_if", 29976d0caaeSpatrick "values": { "c++20": 202002 }, 30076d0caaeSpatrick "headers": ["deque", "forward_list", "list", "map", "set", "string", "unordered_map", "unordered_set", "vector"], 30176d0caaeSpatrick }, { 30276d0caaeSpatrick "name": "__cpp_lib_exchange_function", 30376d0caaeSpatrick "values": { "c++14": 201304 }, 30476d0caaeSpatrick "headers": ["utility"], 30576d0caaeSpatrick }, { 30676d0caaeSpatrick "name": "__cpp_lib_execution", 30776d0caaeSpatrick "values": { "c++17": 201603, "c++20": 201902 }, 30876d0caaeSpatrick "headers": ["execution"], 30976d0caaeSpatrick "unimplemented": True, 31076d0caaeSpatrick }, { 311*4bdff4beSrobert "name": "__cpp_lib_expected", 312*4bdff4beSrobert "values": { "c++2b": 202202 }, 313*4bdff4beSrobert "headers": ["expected"], 314*4bdff4beSrobert }, { 31576d0caaeSpatrick "name": "__cpp_lib_filesystem", 31676d0caaeSpatrick "values": { "c++17": 201703 }, 31776d0caaeSpatrick "headers": ["filesystem"], 31876d0caaeSpatrick "test_suite_guard": "!defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_filesystem)", 31976d0caaeSpatrick "libcxx_guard": "!defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_filesystem)" 32076d0caaeSpatrick }, { 32176d0caaeSpatrick "name": "__cpp_lib_format", 322*4bdff4beSrobert "values": { 323*4bdff4beSrobert # "c++20": 201907 Not implemented P1361R2 Integration of chrono with text formatting 324*4bdff4beSrobert # "c++20": 202106 Fully implemented 325*4bdff4beSrobert # "c++20": 202110 Not implemented P2372R3 Fixing locale handling in chrono formatters 326*4bdff4beSrobert "c++20": 202106, 327*4bdff4beSrobert # "c++23": 202207, Not implemented P2419R2 Clarify handling of encodings in localized formatting of chrono types 328*4bdff4beSrobert }, 32976d0caaeSpatrick "headers": ["format"], 330*4bdff4beSrobert "test_suite_guard": "!defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_format) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT)", 331*4bdff4beSrobert "libcxx_guard": "!defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_format) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT)", 33276d0caaeSpatrick "unimplemented": True, 33376d0caaeSpatrick }, { 334*4bdff4beSrobert "name": "__cpp_lib_forward_like", 335*4bdff4beSrobert "values": { "c++2b": 202207 }, 336*4bdff4beSrobert "headers": ["utility"], 337*4bdff4beSrobert }, { 33876d0caaeSpatrick "name": "__cpp_lib_gcd_lcm", 33976d0caaeSpatrick "values": { "c++17": 201606 }, 34076d0caaeSpatrick "headers": ["numeric"], 34176d0caaeSpatrick }, { 34276d0caaeSpatrick "name": "__cpp_lib_generic_associative_lookup", 34376d0caaeSpatrick "values": { "c++14": 201304 }, 34476d0caaeSpatrick "headers": ["map", "set"], 34576d0caaeSpatrick }, { 34676d0caaeSpatrick "name": "__cpp_lib_generic_unordered_lookup", 34776d0caaeSpatrick "values": { "c++20": 201811 }, 34876d0caaeSpatrick "headers": ["unordered_map", "unordered_set"], 34976d0caaeSpatrick }, { 35076d0caaeSpatrick "name": "__cpp_lib_hardware_interference_size", 35176d0caaeSpatrick "values": { "c++17": 201703 }, 352*4bdff4beSrobert "test_suite_guard": "defined(__GCC_DESTRUCTIVE_SIZE) && defined(__GCC_CONSTRUCTIVE_SIZE)", 353*4bdff4beSrobert "libcxx_guard": "defined(__GCC_DESTRUCTIVE_SIZE) && defined(__GCC_CONSTRUCTIVE_SIZE)", 35476d0caaeSpatrick "headers": ["new"], 35576d0caaeSpatrick }, { 35676d0caaeSpatrick "name": "__cpp_lib_has_unique_object_representations", 35776d0caaeSpatrick "values": { "c++17": 201606 }, 35876d0caaeSpatrick "headers": ["type_traits"], 35976d0caaeSpatrick }, { 36076d0caaeSpatrick "name": "__cpp_lib_hypot", 36176d0caaeSpatrick "values": { "c++17": 201603 }, 36276d0caaeSpatrick "headers": ["cmath"], 36376d0caaeSpatrick }, { 36476d0caaeSpatrick "name": "__cpp_lib_incomplete_container_elements", 36576d0caaeSpatrick "values": { "c++17": 201505 }, 36676d0caaeSpatrick "headers": ["forward_list", "list", "vector"], 36776d0caaeSpatrick }, { 36876d0caaeSpatrick "name": "__cpp_lib_int_pow2", 36976d0caaeSpatrick "values": { "c++20": 202002 }, 37076d0caaeSpatrick "headers": ["bit"], 37176d0caaeSpatrick }, { 37276d0caaeSpatrick "name": "__cpp_lib_integer_comparison_functions", 37376d0caaeSpatrick "values": { "c++20": 202002 }, 37476d0caaeSpatrick "headers": ["utility"], 37576d0caaeSpatrick }, { 37676d0caaeSpatrick "name": "__cpp_lib_integer_sequence", 37776d0caaeSpatrick "values": { "c++14": 201304 }, 37876d0caaeSpatrick "headers": ["utility"], 37976d0caaeSpatrick }, { 38076d0caaeSpatrick "name": "__cpp_lib_integral_constant_callable", 38176d0caaeSpatrick "values": { "c++14": 201304 }, 38276d0caaeSpatrick "headers": ["type_traits"], 38376d0caaeSpatrick }, { 38476d0caaeSpatrick "name": "__cpp_lib_interpolate", 38576d0caaeSpatrick "values": { "c++20": 201902 }, 38676d0caaeSpatrick "headers": ["cmath", "numeric"], 38776d0caaeSpatrick }, { 38876d0caaeSpatrick "name": "__cpp_lib_invoke", 38976d0caaeSpatrick "values": { "c++17": 201411 }, 39076d0caaeSpatrick "headers": ["functional"], 39176d0caaeSpatrick }, { 392*4bdff4beSrobert "name": "__cpp_lib_invoke_r", 393*4bdff4beSrobert "values": { "c++2b": 202106 }, 394*4bdff4beSrobert "headers": ["functional"], 395*4bdff4beSrobert "unimplemented": True, 396*4bdff4beSrobert }, { 39776d0caaeSpatrick "name": "__cpp_lib_is_aggregate", 39876d0caaeSpatrick "values": { "c++17": 201703 }, 39976d0caaeSpatrick "headers": ["type_traits"], 40076d0caaeSpatrick }, { 40176d0caaeSpatrick "name": "__cpp_lib_is_constant_evaluated", 40276d0caaeSpatrick "values": { "c++20": 201811 }, 40376d0caaeSpatrick "headers": ["type_traits"], 40476d0caaeSpatrick }, { 40576d0caaeSpatrick "name": "__cpp_lib_is_final", 40676d0caaeSpatrick "values": { "c++14": 201402 }, 40776d0caaeSpatrick "headers": ["type_traits"], 40876d0caaeSpatrick }, { 40976d0caaeSpatrick "name": "__cpp_lib_is_invocable", 41076d0caaeSpatrick "values": { "c++17": 201703 }, 41176d0caaeSpatrick "headers": ["type_traits"], 41276d0caaeSpatrick }, { 41376d0caaeSpatrick "name": "__cpp_lib_is_layout_compatible", 41476d0caaeSpatrick "values": { "c++20": 201907 }, 41576d0caaeSpatrick "headers": ["type_traits"], 41676d0caaeSpatrick "unimplemented": True, 41776d0caaeSpatrick }, { 41876d0caaeSpatrick "name": "__cpp_lib_is_nothrow_convertible", 41976d0caaeSpatrick "values": { "c++20": 201806 }, 42076d0caaeSpatrick "headers": ["type_traits"], 42176d0caaeSpatrick }, { 42276d0caaeSpatrick "name": "__cpp_lib_is_null_pointer", 42376d0caaeSpatrick "values": { "c++14": 201309 }, 42476d0caaeSpatrick "headers": ["type_traits"], 42576d0caaeSpatrick }, { 42676d0caaeSpatrick "name": "__cpp_lib_is_pointer_interconvertible", 42776d0caaeSpatrick "values": { "c++20": 201907 }, 42876d0caaeSpatrick "headers": ["type_traits"], 42976d0caaeSpatrick "unimplemented": True, 43076d0caaeSpatrick }, { 43176d0caaeSpatrick "name": "__cpp_lib_is_scoped_enum", 43276d0caaeSpatrick "values": { "c++2b": 202011 }, 43376d0caaeSpatrick "headers": ["type_traits"], 43476d0caaeSpatrick }, { 43576d0caaeSpatrick "name": "__cpp_lib_is_swappable", 43676d0caaeSpatrick "values": { "c++17": 201603 }, 43776d0caaeSpatrick "headers": ["type_traits"], 43876d0caaeSpatrick }, { 43976d0caaeSpatrick "name": "__cpp_lib_jthread", 44076d0caaeSpatrick "values": { "c++20": 201911 }, 44176d0caaeSpatrick "headers": ["stop_token", "thread"], 44276d0caaeSpatrick "test_suite_guard": "!defined(_LIBCPP_HAS_NO_THREADS)", 44376d0caaeSpatrick "libcxx_guard": "!defined(_LIBCPP_HAS_NO_THREADS)", 44476d0caaeSpatrick "unimplemented": True, 44576d0caaeSpatrick }, { 44676d0caaeSpatrick "name": "__cpp_lib_latch", 44776d0caaeSpatrick "values": { "c++20": 201907 }, 44876d0caaeSpatrick "headers": ["latch"], 44976d0caaeSpatrick "test_suite_guard": "!defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_latch)", 45076d0caaeSpatrick "libcxx_guard": "!defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_latch)", 45176d0caaeSpatrick }, { 45276d0caaeSpatrick "name": "__cpp_lib_launder", 45376d0caaeSpatrick "values": { "c++17": 201606 }, 45476d0caaeSpatrick "headers": ["new"], 45576d0caaeSpatrick }, { 45676d0caaeSpatrick "name": "__cpp_lib_list_remove_return_type", 45776d0caaeSpatrick "values": { "c++20": 201806 }, 45876d0caaeSpatrick "headers": ["forward_list", "list"], 45976d0caaeSpatrick }, { 46076d0caaeSpatrick "name": "__cpp_lib_logical_traits", 46176d0caaeSpatrick "values": { "c++17": 201510 }, 46276d0caaeSpatrick "headers": ["type_traits"], 46376d0caaeSpatrick }, { 46476d0caaeSpatrick "name": "__cpp_lib_make_from_tuple", 46576d0caaeSpatrick "values": { "c++17": 201606 }, 46676d0caaeSpatrick "headers": ["tuple"], 46776d0caaeSpatrick }, { 46876d0caaeSpatrick "name": "__cpp_lib_make_reverse_iterator", 46976d0caaeSpatrick "values": { "c++14": 201402 }, 47076d0caaeSpatrick "headers": ["iterator"], 47176d0caaeSpatrick }, { 47276d0caaeSpatrick "name": "__cpp_lib_make_unique", 47376d0caaeSpatrick "values": { "c++14": 201304 }, 47476d0caaeSpatrick "headers": ["memory"], 47576d0caaeSpatrick }, { 47676d0caaeSpatrick "name": "__cpp_lib_map_try_emplace", 47776d0caaeSpatrick "values": { "c++17": 201411 }, 47876d0caaeSpatrick "headers": ["map"], 47976d0caaeSpatrick }, { 48076d0caaeSpatrick "name": "__cpp_lib_math_constants", 48176d0caaeSpatrick "values": { "c++20": 201907 }, 48276d0caaeSpatrick "headers": ["numbers"], 48376d0caaeSpatrick }, { 48476d0caaeSpatrick "name": "__cpp_lib_math_special_functions", 48576d0caaeSpatrick "values": { "c++17": 201603 }, 48676d0caaeSpatrick "headers": ["cmath"], 48776d0caaeSpatrick "unimplemented": True, 48876d0caaeSpatrick }, { 48976d0caaeSpatrick "name": "__cpp_lib_memory_resource", 49076d0caaeSpatrick "values": { "c++17": 201603 }, 49146035553Spatrick "headers": ["memory_resource"], 492*4bdff4beSrobert }, { 493*4bdff4beSrobert "name": "__cpp_lib_move_only_function", 494*4bdff4beSrobert "values": { "c++2b": 202110 }, 495*4bdff4beSrobert "headers": ["functional"], 49646035553Spatrick "unimplemented": True, 49776d0caaeSpatrick }, { 49876d0caaeSpatrick "name": "__cpp_lib_node_extract", 49976d0caaeSpatrick "values": { "c++17": 201606 }, 50076d0caaeSpatrick "headers": ["map", "set", "unordered_map", "unordered_set"], 50176d0caaeSpatrick }, { 50276d0caaeSpatrick "name": "__cpp_lib_nonmember_container_access", 50376d0caaeSpatrick "values": { "c++17": 201411 }, 50476d0caaeSpatrick "headers": ["array", "deque", "forward_list", "iterator", "list", "map", "regex", "set", "string", "unordered_map", "unordered_set", "vector"], 50576d0caaeSpatrick }, { 50676d0caaeSpatrick "name": "__cpp_lib_not_fn", 50776d0caaeSpatrick "values": { "c++17": 201603 }, 50846035553Spatrick "headers": ["functional"], 50976d0caaeSpatrick }, { 51076d0caaeSpatrick "name": "__cpp_lib_null_iterators", 51176d0caaeSpatrick "values": { "c++14": 201304 }, 51276d0caaeSpatrick "headers": ["iterator"], 51376d0caaeSpatrick }, { 51476d0caaeSpatrick "name": "__cpp_lib_optional", 515*4bdff4beSrobert "values": { "c++17": 201606, "c++2b": 202110 }, 51676d0caaeSpatrick "headers": ["optional"], 51776d0caaeSpatrick }, { 518*4bdff4beSrobert "name": "__cpp_lib_out_ptr", 519*4bdff4beSrobert "values": { "c++2b": 202106 }, 520*4bdff4beSrobert "headers": ["memory"], 521*4bdff4beSrobert "unimplemented": True, 522*4bdff4beSrobert }, { 52376d0caaeSpatrick "name": "__cpp_lib_parallel_algorithm", 52476d0caaeSpatrick "values": { "c++17": 201603 }, 52546035553Spatrick "headers": ["algorithm", "numeric"], 52646035553Spatrick "unimplemented": True, 52776d0caaeSpatrick }, { 52876d0caaeSpatrick "name": "__cpp_lib_polymorphic_allocator", 52976d0caaeSpatrick "values": { "c++20": 201902 }, 530*4bdff4beSrobert "headers": ["memory_resource"], 53176d0caaeSpatrick }, { 53276d0caaeSpatrick "name": "__cpp_lib_quoted_string_io", 53376d0caaeSpatrick "values": { "c++14": 201304 }, 53476d0caaeSpatrick "headers": ["iomanip"], 53576d0caaeSpatrick }, { 53676d0caaeSpatrick "name": "__cpp_lib_ranges", 537*4bdff4beSrobert "values": { "c++20": 202106 }, 53846035553Spatrick "headers": ["algorithm", "functional", "iterator", "memory", "ranges"], 539*4bdff4beSrobert }, { 540*4bdff4beSrobert "name": "__cpp_lib_ranges_as_rvalue", 541*4bdff4beSrobert "values": { "c++2b": 202207 }, 542*4bdff4beSrobert "headers": ["ranges"], 543*4bdff4beSrobert }, { 544*4bdff4beSrobert "name": "__cpp_lib_ranges_chunk", 545*4bdff4beSrobert "values": { "c++2b": 202202 }, 546*4bdff4beSrobert "headers": ["ranges"], 547*4bdff4beSrobert "unimplemented": True, 548*4bdff4beSrobert }, { 549*4bdff4beSrobert "name": "__cpp_lib_ranges_chunk_by", 550*4bdff4beSrobert "values": { "c++2b": 202202 }, 551*4bdff4beSrobert "headers": ["ranges"], 552*4bdff4beSrobert "unimplemented": True, 553*4bdff4beSrobert }, { 554*4bdff4beSrobert "name": "__cpp_lib_ranges_iota", 555*4bdff4beSrobert "values": { "c++2b": 202202 }, 556*4bdff4beSrobert "headers": ["numeric"], 557*4bdff4beSrobert "unimplemented": True, 558*4bdff4beSrobert }, { 559*4bdff4beSrobert "name": "__cpp_lib_ranges_join_with", 560*4bdff4beSrobert "values": { "c++2b": 202202 }, 561*4bdff4beSrobert "headers": ["ranges"], 562*4bdff4beSrobert "unimplemented": True, 563*4bdff4beSrobert }, { 564*4bdff4beSrobert "name": "__cpp_lib_ranges_slide", 565*4bdff4beSrobert "values": { "c++2b": 202202 }, 566*4bdff4beSrobert "headers": ["ranges"], 567*4bdff4beSrobert "unimplemented": True, 568*4bdff4beSrobert }, { 569*4bdff4beSrobert "name": "__cpp_lib_ranges_starts_ends_with", 570*4bdff4beSrobert "values": { "c++2b": 202106 }, 571*4bdff4beSrobert "headers": ["algorithm"], 572*4bdff4beSrobert "unimplemented": True, 573*4bdff4beSrobert }, { 574*4bdff4beSrobert "name": "__cpp_lib_ranges_to_container", 575*4bdff4beSrobert "values": { "c++2b": 202202 }, 576*4bdff4beSrobert "headers": ["deque", "forward_list", "list", "map", "priority_queue", "queue", "set", "stack", "string", "unordered_map", "unordered_set", "vector"], 577*4bdff4beSrobert "unimplemented": True, 578*4bdff4beSrobert }, { 579*4bdff4beSrobert "name": "__cpp_lib_ranges_zip", 580*4bdff4beSrobert "values": { "c++2b": 202110 }, 581*4bdff4beSrobert "headers": ["ranges", "tuple", "utility"], 58246035553Spatrick "unimplemented": True, 58376d0caaeSpatrick }, { 58476d0caaeSpatrick "name": "__cpp_lib_raw_memory_algorithms", 58576d0caaeSpatrick "values": { "c++17": 201606 }, 58676d0caaeSpatrick "headers": ["memory"], 58776d0caaeSpatrick }, { 588*4bdff4beSrobert "name": "__cpp_lib_reference_from_temporary", 589*4bdff4beSrobert "values": { "c++2b": 202202 }, 590*4bdff4beSrobert "headers": ["type_traits"], 591*4bdff4beSrobert "unimplemented": True, 592*4bdff4beSrobert }, { 59376d0caaeSpatrick "name": "__cpp_lib_remove_cvref", 59476d0caaeSpatrick "values": { "c++20": 201711 }, 59576d0caaeSpatrick "headers": ["type_traits"], 59676d0caaeSpatrick }, { 59776d0caaeSpatrick "name": "__cpp_lib_result_of_sfinae", 59876d0caaeSpatrick "values": { "c++14": 201210 }, 59976d0caaeSpatrick "headers": ["functional", "type_traits"], 60076d0caaeSpatrick }, { 60176d0caaeSpatrick "name": "__cpp_lib_robust_nonmodifying_seq_ops", 60276d0caaeSpatrick "values": { "c++14": 201304 }, 60376d0caaeSpatrick "headers": ["algorithm"], 60476d0caaeSpatrick }, { 60576d0caaeSpatrick "name": "__cpp_lib_sample", 60676d0caaeSpatrick "values": { "c++17": 201603 }, 60776d0caaeSpatrick "headers": ["algorithm"], 60876d0caaeSpatrick }, { 60976d0caaeSpatrick "name": "__cpp_lib_scoped_lock", 61076d0caaeSpatrick "values": { "c++17": 201703 }, 61176d0caaeSpatrick "headers": ["mutex"], 61276d0caaeSpatrick }, { 61376d0caaeSpatrick "name": "__cpp_lib_semaphore", 61476d0caaeSpatrick "values": { "c++20": 201907 }, 61576d0caaeSpatrick "headers": ["semaphore"], 61676d0caaeSpatrick "test_suite_guard": "!defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_semaphore)", 61776d0caaeSpatrick "libcxx_guard": "!defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_semaphore)", 61876d0caaeSpatrick }, { 61976d0caaeSpatrick "name": "__cpp_lib_shared_mutex", 62076d0caaeSpatrick "values": { "c++17": 201505 }, 62176d0caaeSpatrick "headers": ["shared_mutex"], 62276d0caaeSpatrick "test_suite_guard": "!defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_shared_mutex)", 62376d0caaeSpatrick "libcxx_guard": "!defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_shared_mutex)", 62476d0caaeSpatrick }, { 62576d0caaeSpatrick "name": "__cpp_lib_shared_ptr_arrays", 626*4bdff4beSrobert "values": { "c++17": 201611, "c++20": 201707 }, 62776d0caaeSpatrick "headers": ["memory"], 62876d0caaeSpatrick }, { 62976d0caaeSpatrick "name": "__cpp_lib_shared_ptr_weak_type", 63076d0caaeSpatrick "values": { "c++17": 201606 }, 63176d0caaeSpatrick "headers": ["memory"], 63276d0caaeSpatrick }, { 63376d0caaeSpatrick "name": "__cpp_lib_shared_timed_mutex", 63476d0caaeSpatrick "values": { "c++14": 201402 }, 63576d0caaeSpatrick "headers": ["shared_mutex"], 63676d0caaeSpatrick "test_suite_guard": "!defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_shared_timed_mutex)", 63776d0caaeSpatrick "libcxx_guard": "!defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_shared_timed_mutex)", 63876d0caaeSpatrick }, { 63976d0caaeSpatrick "name": "__cpp_lib_shift", 64076d0caaeSpatrick "values": { "c++20": 201806 }, 64176d0caaeSpatrick "headers": ["algorithm"], 64276d0caaeSpatrick }, { 64376d0caaeSpatrick "name": "__cpp_lib_smart_ptr_for_overwrite", 64476d0caaeSpatrick "values": { "c++20": 202002 }, 64576d0caaeSpatrick "headers": ["memory"], 64646035553Spatrick "unimplemented": True, 64776d0caaeSpatrick }, { 64876d0caaeSpatrick "name": "__cpp_lib_source_location", 64976d0caaeSpatrick "values": { "c++20": 201907 }, 65076d0caaeSpatrick "headers": ["source_location"], 651*4bdff4beSrobert "test_suite_guard": "__has_builtin(__builtin_source_location) && !(defined(TEST_APPLE_CLANG_VER) && TEST_APPLE_CLANG_VER <= 1403)", 652*4bdff4beSrobert "libcxx_guard": "__has_builtin(__builtin_source_location) && !(defined(_LIBCPP_APPLE_CLANG_VER) && _LIBCPP_APPLE_CLANG_VER <= 1403)", 65376d0caaeSpatrick }, { 65476d0caaeSpatrick "name": "__cpp_lib_span", 65576d0caaeSpatrick "values": { "c++20": 202002 }, 656037e7968Spatrick "headers": ["span"], 65776d0caaeSpatrick }, { 658*4bdff4beSrobert "name": "__cpp_lib_spanstream", 659*4bdff4beSrobert "values": { "c++2b": 202106 }, 660*4bdff4beSrobert "headers": ["spanstream"], 661*4bdff4beSrobert "unimplemented": True, 662*4bdff4beSrobert }, { 66376d0caaeSpatrick "name": "__cpp_lib_ssize", 66476d0caaeSpatrick "values": { "c++20": 201902 }, 66576d0caaeSpatrick "headers": ["iterator"], 66676d0caaeSpatrick }, { 66776d0caaeSpatrick "name": "__cpp_lib_stacktrace", 66876d0caaeSpatrick "values": { "c++2b": 202011 }, 66976d0caaeSpatrick "headers": ["stacktrace"], 67076d0caaeSpatrick "unimplemented": True, 67176d0caaeSpatrick }, { 67276d0caaeSpatrick "name": "__cpp_lib_starts_ends_with", 67376d0caaeSpatrick "values": { "c++20": 201711 }, 67476d0caaeSpatrick "headers": ["string", "string_view"], 67576d0caaeSpatrick }, { 67676d0caaeSpatrick "name": "__cpp_lib_stdatomic_h", 67776d0caaeSpatrick "values": { "c++2b": 202011 }, 67876d0caaeSpatrick "headers": ["stdatomic.h"], 67976d0caaeSpatrick }, { 68076d0caaeSpatrick "name": "__cpp_lib_string_contains", 68176d0caaeSpatrick "values": { "c++2b": 202011 }, 68276d0caaeSpatrick "headers": ["string", "string_view"], 68376d0caaeSpatrick }, { 684*4bdff4beSrobert "name": "__cpp_lib_string_resize_and_overwrite", 685*4bdff4beSrobert "values": { "c++2b": 202110 }, 686*4bdff4beSrobert "headers": ["string"], 687*4bdff4beSrobert }, { 68876d0caaeSpatrick "name": "__cpp_lib_string_udls", 68976d0caaeSpatrick "values": { "c++14": 201304 }, 69076d0caaeSpatrick "headers": ["string"], 69176d0caaeSpatrick }, { 69276d0caaeSpatrick "name": "__cpp_lib_string_view", 69376d0caaeSpatrick "values": { "c++17": 201606, "c++20": 201803 }, 69476d0caaeSpatrick "headers": ["string", "string_view"], 69576d0caaeSpatrick }, { 69676d0caaeSpatrick "name": "__cpp_lib_syncbuf", 69776d0caaeSpatrick "values": { "c++20": 201803 }, 69876d0caaeSpatrick "headers": ["syncstream"], 69976d0caaeSpatrick "unimplemented": True, 70076d0caaeSpatrick }, { 70176d0caaeSpatrick "name": "__cpp_lib_three_way_comparison", 70276d0caaeSpatrick "values": { "c++20": 201907 }, 70376d0caaeSpatrick "headers": ["compare"], 70476d0caaeSpatrick "unimplemented": True, 70576d0caaeSpatrick }, { 70676d0caaeSpatrick "name": "__cpp_lib_to_address", 70776d0caaeSpatrick "values": { "c++20": 201711 }, 70876d0caaeSpatrick "headers": ["memory"], 70976d0caaeSpatrick }, { 71076d0caaeSpatrick "name": "__cpp_lib_to_array", 71176d0caaeSpatrick "values": { "c++20": 201907 }, 71276d0caaeSpatrick "headers": ["array"], 71376d0caaeSpatrick }, { 71476d0caaeSpatrick "name": "__cpp_lib_to_chars", 71576d0caaeSpatrick "values": { "c++17": 201611 }, 716*4bdff4beSrobert "headers": ["charconv"], 71776d0caaeSpatrick "unimplemented": True, 71876d0caaeSpatrick }, { 71976d0caaeSpatrick "name": "__cpp_lib_to_underlying", 72076d0caaeSpatrick "values": { "c++2b": 202102 }, 72176d0caaeSpatrick "headers": ["utility"], 72276d0caaeSpatrick }, { 72376d0caaeSpatrick "name": "__cpp_lib_transformation_trait_aliases", 72476d0caaeSpatrick "values": { "c++14": 201304 }, 72576d0caaeSpatrick "headers": ["type_traits"], 72676d0caaeSpatrick }, { 72776d0caaeSpatrick "name": "__cpp_lib_transparent_operators", 72876d0caaeSpatrick "values": { "c++14": 201210, "c++17": 201510 }, 72976d0caaeSpatrick "headers": ["functional", "memory"], 73076d0caaeSpatrick }, { 73176d0caaeSpatrick "name": "__cpp_lib_tuple_element_t", 73276d0caaeSpatrick "values": { "c++14": 201402 }, 73376d0caaeSpatrick "headers": ["tuple"], 73476d0caaeSpatrick }, { 73576d0caaeSpatrick "name": "__cpp_lib_tuples_by_type", 73676d0caaeSpatrick "values": { "c++14": 201304 }, 73776d0caaeSpatrick "headers": ["tuple", "utility"], 73876d0caaeSpatrick }, { 739*4bdff4beSrobert "name": "__cpp_lib_type_identity", 740*4bdff4beSrobert "values": { "c++20": 201806 }, 741*4bdff4beSrobert "headers": ["type_traits"], 742*4bdff4beSrobert }, { 74376d0caaeSpatrick "name": "__cpp_lib_type_trait_variable_templates", 74476d0caaeSpatrick "values": { "c++17": 201510 }, 74576d0caaeSpatrick "headers": ["type_traits"], 74676d0caaeSpatrick }, { 74776d0caaeSpatrick "name": "__cpp_lib_uncaught_exceptions", 74876d0caaeSpatrick "values": { "c++17": 201411 }, 74976d0caaeSpatrick "headers": ["exception"], 75076d0caaeSpatrick }, { 75176d0caaeSpatrick "name": "__cpp_lib_unordered_map_try_emplace", 75276d0caaeSpatrick "values": { "c++17": 201411 }, 75376d0caaeSpatrick "headers": ["unordered_map"], 75476d0caaeSpatrick }, { 755*4bdff4beSrobert "name": "__cpp_lib_unreachable", 756*4bdff4beSrobert "values": { "c++2b": 202202 }, 757*4bdff4beSrobert "headers": ["utility"], 758*4bdff4beSrobert }, { 75976d0caaeSpatrick "name": "__cpp_lib_unwrap_ref", 76076d0caaeSpatrick "values": { "c++20": 201811 }, 76176d0caaeSpatrick "headers": ["functional"], 76276d0caaeSpatrick }, { 76376d0caaeSpatrick "name": "__cpp_lib_variant", 76476d0caaeSpatrick "values": { "c++17": 202102 }, 76576d0caaeSpatrick "headers": ["variant"], 76676d0caaeSpatrick }, { 76776d0caaeSpatrick "name": "__cpp_lib_void_t", 76876d0caaeSpatrick "values": { "c++17": 201411 }, 76976d0caaeSpatrick "headers": ["type_traits"], 77076d0caaeSpatrick } 77176d0caaeSpatrick]] 77276d0caaeSpatrick 77376d0caaeSpatrickassert feature_test_macros == sorted(feature_test_macros, key=lambda tc: tc["name"]) 77476d0caaeSpatrickassert all(tc["headers"] == sorted(tc["headers"]) for tc in feature_test_macros) 77576d0caaeSpatrickassert all(("libcxx_guard" in tc) == ("test_suite_guard" in tc) for tc in feature_test_macros) 77676d0caaeSpatrickassert all(all(key in ["name", "values", "headers", "libcxx_guard", "test_suite_guard", "unimplemented"] for key in tc.keys()) for tc in feature_test_macros) 77776d0caaeSpatrick 77876d0caaeSpatrick# Map from each header to the Lit annotations that should be used for 77976d0caaeSpatrick# tests that include that header. 78076d0caaeSpatrick# 781*4bdff4beSrobert# For example, when threads are not supported, any test that includes 782*4bdff4beSrobert# <thread> should be marked as UNSUPPORTED, because including <thread> 783*4bdff4beSrobert# is a hard error in that case. 78476d0caaeSpatricklit_markup = { 785*4bdff4beSrobert "barrier": ["UNSUPPORTED: no-threads"], 786*4bdff4beSrobert "filesystem": ["UNSUPPORTED: no-filesystem"], 78776d0caaeSpatrick "format": ["UNSUPPORTED: libcpp-has-no-incomplete-format"], 788*4bdff4beSrobert "iomanip": ["UNSUPPORTED: no-localization"], 789*4bdff4beSrobert "ios": ["UNSUPPORTED: no-localization"], 790*4bdff4beSrobert "iostream": ["UNSUPPORTED: no-localization"], 791*4bdff4beSrobert "istream": ["UNSUPPORTED: no-localization"], 792*4bdff4beSrobert "latch": ["UNSUPPORTED: no-threads"], 793*4bdff4beSrobert "locale": ["UNSUPPORTED: no-localization"], 794*4bdff4beSrobert "mutex": ["UNSUPPORTED: no-threads"], 795*4bdff4beSrobert "ostream": ["UNSUPPORTED: no-localization"], 796*4bdff4beSrobert "regex": ["UNSUPPORTED: no-localization"], 797*4bdff4beSrobert "semaphore": ["UNSUPPORTED: no-threads"], 798*4bdff4beSrobert "shared_mutex": ["UNSUPPORTED: no-threads"], 799*4bdff4beSrobert "stdatomic.h": ["UNSUPPORTED: no-threads"], 800*4bdff4beSrobert "thread": ["UNSUPPORTED: no-threads"], 80176d0caaeSpatrick} 80246035553Spatrick 80346035553Spatrickdef get_std_dialects(): 80476d0caaeSpatrick std_dialects = ['c++14', 'c++17', 'c++20', 'c++2b'] 80546035553Spatrick return list(std_dialects) 80646035553Spatrick 80746035553Spatrickdef get_first_std(d): 80846035553Spatrick for s in get_std_dialects(): 80946035553Spatrick if s in d.keys(): 81046035553Spatrick return s 81146035553Spatrick return None 81246035553Spatrick 81346035553Spatrickdef get_last_std(d): 81446035553Spatrick rev_dialects = get_std_dialects() 81546035553Spatrick rev_dialects.reverse() 81646035553Spatrick for s in rev_dialects: 81746035553Spatrick if s in d.keys(): 81846035553Spatrick return s 81946035553Spatrick return None 82046035553Spatrick 82146035553Spatrickdef get_std_before(d, std): 82246035553Spatrick std_dialects = get_std_dialects() 82346035553Spatrick candidates = std_dialects[0:std_dialects.index(std)] 82446035553Spatrick candidates.reverse() 82546035553Spatrick for cand in candidates: 82646035553Spatrick if cand in d.keys(): 82746035553Spatrick return cand 82846035553Spatrick return None 82946035553Spatrick 83046035553Spatrickdef get_value_before(d, std): 83146035553Spatrick new_std = get_std_before(d, std) 83246035553Spatrick if new_std is None: 83346035553Spatrick return None 83446035553Spatrick return d[new_std] 83546035553Spatrick 83646035553Spatrickdef get_for_std(d, std): 83746035553Spatrick # This catches the C++11 case for which there should be no defined feature 83846035553Spatrick # test macros. 83946035553Spatrick std_dialects = get_std_dialects() 84046035553Spatrick if std not in std_dialects: 84146035553Spatrick return None 84246035553Spatrick # Find the value for the newest C++ dialect between C++14 and std 84346035553Spatrick std_list = list(std_dialects[0:std_dialects.index(std)+1]) 84446035553Spatrick std_list.reverse() 84546035553Spatrick for s in std_list: 84646035553Spatrick if s in d.keys(): 84746035553Spatrick return d[s] 84846035553Spatrick return None 84946035553Spatrick 85076d0caaeSpatrickdef get_std_number(std): 85176d0caaeSpatrick return std.replace('c++', '') 85246035553Spatrick 85346035553Spatrick""" 85446035553Spatrick Functions to produce the <version> header 85546035553Spatrick""" 85646035553Spatrick 85746035553Spatrickdef produce_macros_definition_for_std(std): 85846035553Spatrick result = "" 85976d0caaeSpatrick indent = 55 86046035553Spatrick for tc in feature_test_macros: 86146035553Spatrick if std not in tc["values"]: 86246035553Spatrick continue 86346035553Spatrick inner_indent = 1 86476d0caaeSpatrick if 'test_suite_guard' in tc.keys(): 86576d0caaeSpatrick result += "# if %s\n" % tc["libcxx_guard"] 86646035553Spatrick inner_indent += 2 86746035553Spatrick if get_value_before(tc["values"], std) is not None: 86876d0caaeSpatrick assert 'test_suite_guard' not in tc.keys() 86946035553Spatrick result += "# undef %s\n" % tc["name"] 87046035553Spatrick line = "#%sdefine %s" % ((" " * inner_indent), tc["name"]) 87146035553Spatrick line += " " * (indent - len(line)) 87246035553Spatrick line += " %sL" % tc["values"][std] 87346035553Spatrick if 'unimplemented' in tc.keys(): 87446035553Spatrick line = "// " + line 87546035553Spatrick result += line 87646035553Spatrick result += "\n" 87776d0caaeSpatrick if 'test_suite_guard' in tc.keys(): 87846035553Spatrick result += "# endif\n" 87976d0caaeSpatrick return result.strip() 88076d0caaeSpatrick 88176d0caaeSpatrickdef produce_macros_definitions(): 88276d0caaeSpatrick macro_definition_template = """#if _LIBCPP_STD_VER > {previous_std_number} 88376d0caaeSpatrick{macro_definition} 88476d0caaeSpatrick#endif""" 88576d0caaeSpatrick 88676d0caaeSpatrick macros_definitions = [] 88776d0caaeSpatrick previous_std_number = '11' 88876d0caaeSpatrick for std in get_std_dialects(): 88976d0caaeSpatrick macros_definitions.append( 89076d0caaeSpatrick macro_definition_template.format(previous_std_number=previous_std_number, 89176d0caaeSpatrick macro_definition=produce_macros_definition_for_std(std))) 89276d0caaeSpatrick previous_std_number = get_std_number(std) 89376d0caaeSpatrick 89476d0caaeSpatrick return '\n\n'.join(macros_definitions) 89546035553Spatrick 89646035553Spatrickdef chunks(l, n): 89746035553Spatrick """Yield successive n-sized chunks from l.""" 89846035553Spatrick for i in range(0, len(l), n): 89946035553Spatrick yield l[i:i + n] 90046035553Spatrick 90146035553Spatrickdef produce_version_synopsis(): 90246035553Spatrick indent = 56 90346035553Spatrick header_indent = 56 + len("20XXYYL ") 90446035553Spatrick result = "" 90546035553Spatrick def indent_to(s, val): 90646035553Spatrick if len(s) >= val: 90746035553Spatrick return s 90846035553Spatrick s += " " * (val - len(s)) 90946035553Spatrick return s 91046035553Spatrick line = indent_to("Macro name", indent) + "Value" 91146035553Spatrick line = indent_to(line, header_indent) + "Headers" 91246035553Spatrick result += line + "\n" 91346035553Spatrick for tc in feature_test_macros: 91446035553Spatrick prev_defined_std = get_last_std(tc["values"]) 91546035553Spatrick line = "{name: <{indent}}{value}L ".format(name=tc['name'], indent=indent, 91646035553Spatrick value=tc["values"][prev_defined_std]) 91746035553Spatrick headers = list(tc["headers"]) 91846035553Spatrick headers.remove("version") 91946035553Spatrick for chunk in chunks(headers, 3): 92046035553Spatrick line = indent_to(line, header_indent) 92146035553Spatrick chunk = ['<%s>' % header for header in chunk] 92246035553Spatrick line += ' '.join(chunk) 92346035553Spatrick result += line 92446035553Spatrick result += "\n" 92546035553Spatrick line = "" 92646035553Spatrick while True: 92746035553Spatrick prev_defined_std = get_std_before(tc["values"], prev_defined_std) 92846035553Spatrick if prev_defined_std is None: 92946035553Spatrick break 93046035553Spatrick result += "%s%sL // %s\n" % (indent_to("", indent), tc["values"][prev_defined_std], 93146035553Spatrick prev_defined_std.replace("c++", "C++")) 93246035553Spatrick return result 93346035553Spatrick 93446035553Spatrick 93546035553Spatrickdef produce_version_header(): 93646035553Spatrick template="""// -*- C++ -*- 937*4bdff4beSrobert//===----------------------------------------------------------------------===// 93846035553Spatrick// 93946035553Spatrick// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 94046035553Spatrick// See https://llvm.org/LICENSE.txt for license information. 94146035553Spatrick// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 94246035553Spatrick// 94346035553Spatrick//===----------------------------------------------------------------------===// 94446035553Spatrick 94546035553Spatrick#ifndef _LIBCPP_VERSIONH 94646035553Spatrick#define _LIBCPP_VERSIONH 94746035553Spatrick 94846035553Spatrick/* 94946035553Spatrick version synopsis 95046035553Spatrick 95146035553Spatrick{synopsis} 95246035553Spatrick 95346035553Spatrick*/ 95446035553Spatrick 955*4bdff4beSrobert#include <__assert> // all public C++ headers provide the assertion handler 95646035553Spatrick#include <__config> 95746035553Spatrick 95846035553Spatrick#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 95946035553Spatrick# pragma GCC system_header 96046035553Spatrick#endif 96146035553Spatrick 96276d0caaeSpatrick// clang-format off 96346035553Spatrick 96476d0caaeSpatrick{cxx_macros} 96546035553Spatrick 96676d0caaeSpatrick// clang-format on 96746035553Spatrick 96846035553Spatrick#endif // _LIBCPP_VERSIONH 96946035553Spatrick""" 97076d0caaeSpatrick 97176d0caaeSpatrick version_str = template.format( 97246035553Spatrick synopsis=produce_version_synopsis().strip(), 97376d0caaeSpatrick cxx_macros=produce_macros_definitions()) 97476d0caaeSpatrick version_header_path = os.path.join(include_path, 'version') 97576d0caaeSpatrick with open(version_header_path, 'w', newline='\n') as f: 97676d0caaeSpatrick f.write(version_str) 97776d0caaeSpatrick 97846035553Spatrick 97946035553Spatrick""" 98046035553Spatrick Functions to produce test files 98146035553Spatrick""" 98246035553Spatrick 98346035553Spatricktest_types = { 98446035553Spatrick "undefined": """ 98546035553Spatrick# ifdef {name} 98646035553Spatrick# error "{name} should not be defined before {std_first}" 98746035553Spatrick# endif 98846035553Spatrick""", 98946035553Spatrick 99076d0caaeSpatrick "test_suite_guard": """ 99176d0caaeSpatrick# if {test_suite_guard} 99246035553Spatrick# ifndef {name} 99346035553Spatrick# error "{name} should be defined in {std}" 99446035553Spatrick# endif 99546035553Spatrick# if {name} != {value} 99646035553Spatrick# error "{name} should have the value {value} in {std}" 99746035553Spatrick# endif 99846035553Spatrick# else 99946035553Spatrick# ifdef {name} 1000*4bdff4beSrobert# error "{name} should not be defined when the requirement '{test_suite_guard}' is not met!" 100146035553Spatrick# endif 100246035553Spatrick# endif 100346035553Spatrick""", 100446035553Spatrick 100546035553Spatrick "unimplemented": """ 100646035553Spatrick# if !defined(_LIBCPP_VERSION) 100746035553Spatrick# ifndef {name} 100846035553Spatrick# error "{name} should be defined in {std}" 100946035553Spatrick# endif 101046035553Spatrick# if {name} != {value} 101146035553Spatrick# error "{name} should have the value {value} in {std}" 101246035553Spatrick# endif 101346035553Spatrick# else // _LIBCPP_VERSION 101446035553Spatrick# ifdef {name} 101546035553Spatrick# error "{name} should not be defined because it is unimplemented in libc++!" 101646035553Spatrick# endif 101746035553Spatrick# endif 101846035553Spatrick""", 101946035553Spatrick 102046035553Spatrick "defined": """ 102146035553Spatrick# ifndef {name} 102246035553Spatrick# error "{name} should be defined in {std}" 102346035553Spatrick# endif 102446035553Spatrick# if {name} != {value} 102546035553Spatrick# error "{name} should have the value {value} in {std}" 102646035553Spatrick# endif 102746035553Spatrick""" 102846035553Spatrick} 102946035553Spatrick 103046035553Spatrickdef generate_std_test(test_list, std): 103146035553Spatrick result = "" 103246035553Spatrick for tc in test_list: 103346035553Spatrick val = get_for_std(tc["values"], std) 103446035553Spatrick if val is not None: 103546035553Spatrick val = "%sL" % val 103646035553Spatrick if val is None: 103746035553Spatrick result += test_types["undefined"].format(name=tc["name"], std_first=get_first_std(tc["values"])) 103846035553Spatrick elif 'unimplemented' in tc.keys(): 103946035553Spatrick result += test_types["unimplemented"].format(name=tc["name"], value=val, std=std) 104076d0caaeSpatrick elif "test_suite_guard" in tc.keys(): 104176d0caaeSpatrick result += test_types["test_suite_guard"].format(name=tc["name"], value=val, std=std, test_suite_guard=tc["test_suite_guard"]) 104246035553Spatrick else: 104346035553Spatrick result += test_types["defined"].format(name=tc["name"], value=val, std=std) 104476d0caaeSpatrick return result.strip() 104576d0caaeSpatrick 104676d0caaeSpatrickdef generate_std_tests(test_list): 104776d0caaeSpatrick std_tests_template = """#if TEST_STD_VER < {first_std_number} 104876d0caaeSpatrick 104976d0caaeSpatrick{pre_std_test} 105076d0caaeSpatrick 105176d0caaeSpatrick{other_std_tests} 105276d0caaeSpatrick 105376d0caaeSpatrick#elif TEST_STD_VER > {penultimate_std_number} 105476d0caaeSpatrick 105576d0caaeSpatrick{last_std_test} 105676d0caaeSpatrick 105776d0caaeSpatrick#endif // TEST_STD_VER > {penultimate_std_number}""" 105876d0caaeSpatrick 105976d0caaeSpatrick std_dialects = get_std_dialects() 106076d0caaeSpatrick assert not get_std_number(std_dialects[-1]).isnumeric() 106176d0caaeSpatrick 106276d0caaeSpatrick other_std_tests = [] 106376d0caaeSpatrick for std in std_dialects[:-1]: 106476d0caaeSpatrick other_std_tests.append('#elif TEST_STD_VER == ' + get_std_number(std)) 106576d0caaeSpatrick other_std_tests.append(generate_std_test(test_list, std)) 106676d0caaeSpatrick 106776d0caaeSpatrick std_tests = std_tests_template.format(first_std_number=get_std_number(std_dialects[0]), 106876d0caaeSpatrick pre_std_test=generate_std_test(test_list, 'c++11'), 106976d0caaeSpatrick other_std_tests='\n\n'.join(other_std_tests), 107076d0caaeSpatrick penultimate_std_number=get_std_number(std_dialects[-2]), 107176d0caaeSpatrick last_std_test=generate_std_test(test_list, std_dialects[-1])) 107276d0caaeSpatrick 107376d0caaeSpatrick return std_tests 107446035553Spatrick 107546035553Spatrickdef generate_synopsis(test_list): 107646035553Spatrick max_name_len = max([len(tc["name"]) for tc in test_list]) 107746035553Spatrick indent = max_name_len + 8 107846035553Spatrick def mk_line(prefix, suffix): 107946035553Spatrick return "{prefix: <{max_len}}{suffix}\n".format(prefix=prefix, suffix=suffix, 108046035553Spatrick max_len=indent) 108146035553Spatrick result = "" 108246035553Spatrick result += mk_line("/* Constant", "Value") 108346035553Spatrick for tc in test_list: 108446035553Spatrick prefix = " %s" % tc["name"] 108546035553Spatrick for std in [s for s in get_std_dialects() if s in tc["values"].keys()]: 108646035553Spatrick result += mk_line(prefix, "%sL [%s]" % (tc["values"][std], std.replace("c++", "C++"))) 108746035553Spatrick prefix = "" 108846035553Spatrick result += "*/" 108946035553Spatrick return result 109046035553Spatrick 109146035553Spatrickdef produce_tests(): 109246035553Spatrick headers = set([h for tc in feature_test_macros for h in tc["headers"]]) 109346035553Spatrick for h in headers: 109446035553Spatrick test_list = [tc for tc in feature_test_macros if h in tc["headers"]] 109546035553Spatrick if not has_header(h): 109646035553Spatrick for tc in test_list: 109746035553Spatrick assert 'unimplemented' in tc.keys() 109846035553Spatrick continue 109976d0caaeSpatrick markup = '\n'.join('// ' + tag for tag in lit_markup.get(h, [])) 110046035553Spatrick test_body = \ 110146035553Spatrick"""//===----------------------------------------------------------------------===// 110246035553Spatrick// 110346035553Spatrick// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 110446035553Spatrick// See https://llvm.org/LICENSE.txt for license information. 110546035553Spatrick// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 110646035553Spatrick// 110746035553Spatrick//===----------------------------------------------------------------------===// 110846035553Spatrick// 110946035553Spatrick// WARNING: This test was generated by {script_name} 111046035553Spatrick// and should not be edited manually. 111176d0caaeSpatrick// 111276d0caaeSpatrick// clang-format off 111376d0caaeSpatrick{markup} 111446035553Spatrick// <{header}> 111546035553Spatrick 111646035553Spatrick// Test the feature test macros defined by <{header}> 111746035553Spatrick 111846035553Spatrick{synopsis} 111946035553Spatrick 112046035553Spatrick#include <{header}> 112146035553Spatrick#include "test_macros.h" 112246035553Spatrick 112376d0caaeSpatrick{cxx_tests} 112446035553Spatrick 112546035553Spatrick""".format(script_name=script_name, 112646035553Spatrick header=h, 112776d0caaeSpatrick markup=('\n{}\n'.format(markup) if markup else ''), 112846035553Spatrick synopsis=generate_synopsis(test_list), 112976d0caaeSpatrick cxx_tests=generate_std_tests(test_list)) 1130*4bdff4beSrobert test_name = "{header}.version.compile.pass.cpp".format(header=h) 113146035553Spatrick out_path = os.path.join(macro_test_path, test_name) 113276d0caaeSpatrick with open(out_path, 'w', newline='\n') as f: 113346035553Spatrick f.write(test_body) 113446035553Spatrick 113546035553Spatrick""" 113646035553Spatrick Produce documentation for the feature test macros 113746035553Spatrick""" 113846035553Spatrick 113946035553Spatrickdef make_widths(grid): 114046035553Spatrick widths = [] 114146035553Spatrick for i in range(0, len(grid[0])): 114246035553Spatrick cell_width = 2 + max(reduce(lambda x,y: x+y, [[len(row[i])] for row in grid], [])) 114346035553Spatrick widths += [cell_width] 114446035553Spatrick return widths 114546035553Spatrick 114646035553Spatrickdef create_table(grid, indent): 114746035553Spatrick indent_str = ' '*indent 114846035553Spatrick col_widths = make_widths(grid) 114976d0caaeSpatrick result = [indent_str + add_divider(col_widths, 2)] 115046035553Spatrick header_flag = 2 115146035553Spatrick for row_i in range(0, len(grid)): 115246035553Spatrick row = grid[row_i] 115376d0caaeSpatrick line = indent_str + ' '.join([pad_cell(row[i], col_widths[i]) for i in range(0, len(row))]) 115476d0caaeSpatrick result.append(line.rstrip()) 115546035553Spatrick is_cxx_header = row[0].startswith('**') 115646035553Spatrick if row_i == len(grid) - 1: 115746035553Spatrick header_flag = 2 115876d0caaeSpatrick separator = indent_str + add_divider(col_widths, 1 if is_cxx_header else header_flag) 115976d0caaeSpatrick result.append(separator.rstrip()) 116046035553Spatrick header_flag = 0 116176d0caaeSpatrick return '\n'.join(result) 116246035553Spatrick 116346035553Spatrickdef add_divider(widths, header_flag): 116446035553Spatrick if header_flag == 2: 116576d0caaeSpatrick return ' '.join(['='*w for w in widths]) 116646035553Spatrick if header_flag == 1: 116776d0caaeSpatrick return '-'.join(['-'*w for w in widths]) 116846035553Spatrick else: 116976d0caaeSpatrick return ' '.join(['-'*w for w in widths]) 117046035553Spatrick 117146035553Spatrickdef pad_cell(s, length, left_align=True): 117246035553Spatrick padding = ((length - len(s)) * ' ') 117346035553Spatrick return s + padding 117446035553Spatrick 117546035553Spatrick 117646035553Spatrickdef get_status_table(): 117746035553Spatrick table = [["Macro Name", "Value"]] 117846035553Spatrick for std in get_std_dialects(): 117946035553Spatrick table += [["**" + std.replace("c++", "C++ ") + "**", ""]] 118046035553Spatrick for tc in feature_test_macros: 118146035553Spatrick if std not in tc["values"].keys(): 118246035553Spatrick continue 118346035553Spatrick value = "``%sL``" % tc["values"][std] 118446035553Spatrick if 'unimplemented' in tc.keys(): 118546035553Spatrick value = '*unimplemented*' 118646035553Spatrick table += [["``%s``" % tc["name"], value]] 118746035553Spatrick return table 118846035553Spatrick 118946035553Spatrickdef produce_docs(): 119046035553Spatrick doc_str = """.. _FeatureTestMacroTable: 119146035553Spatrick 119246035553Spatrick========================== 119346035553SpatrickFeature Test Macro Support 119446035553Spatrick========================== 119546035553Spatrick 119646035553Spatrick.. contents:: 119746035553Spatrick :local: 119846035553Spatrick 119946035553SpatrickOverview 120046035553Spatrick======== 120146035553Spatrick 120246035553SpatrickThis file documents the feature test macros currently supported by libc++. 120346035553Spatrick 120446035553Spatrick.. _feature-status: 120546035553Spatrick 120646035553SpatrickStatus 120746035553Spatrick====== 120846035553Spatrick 120946035553Spatrick.. table:: Current Status 121046035553Spatrick :name: feature-status-table 121146035553Spatrick :widths: auto 121246035553Spatrick 121346035553Spatrick{status_tables} 121446035553Spatrick 121546035553Spatrick""".format(status_tables=create_table(get_status_table(), 4)) 121646035553Spatrick 121746035553Spatrick table_doc_path = os.path.join(docs_path, 'FeatureTestMacroTable.rst') 121876d0caaeSpatrick with open(table_doc_path, 'w', newline='\n') as f: 121946035553Spatrick f.write(doc_str) 122046035553Spatrick 122146035553Spatrickdef main(): 122276d0caaeSpatrick produce_version_header() 122346035553Spatrick produce_tests() 122446035553Spatrick produce_docs() 122546035553Spatrick 122646035553Spatrick 122746035553Spatrickif __name__ == '__main__': 122846035553Spatrick main() 1229