2019-01-16 01:37:43 +00:00
|
|
|
|
#!/usr/bin/env python
|
|
|
|
|
|
|
|
|
|
import os
|
2021-01-07 18:04:41 -05:00
|
|
|
|
from builtins import range
|
2025-02-10 18:03:44 +01:00
|
|
|
|
from dataclasses import dataclass
|
2019-11-06 16:44:14 +00:00
|
|
|
|
from functools import reduce
|
2025-02-10 18:03:44 +01:00
|
|
|
|
from typing import (
|
|
|
|
|
Any,
|
|
|
|
|
Dict,
|
|
|
|
|
List, # Needed for python 3.8 compatibility.
|
|
|
|
|
NewType,
|
|
|
|
|
Optional,
|
|
|
|
|
)
|
2024-07-05 07:54:34 +02:00
|
|
|
|
import functools
|
|
|
|
|
import json
|
2025-04-11 17:05:30 +02:00
|
|
|
|
from libcxx.header_information import module_c_headers, module_headers, header_restrictions, headers_not_available, libcxx_root
|
2019-01-16 01:37:43 +00:00
|
|
|
|
|
2023-05-17 11:09:29 +02:00
|
|
|
|
|
2019-01-16 01:37:43 +00:00
|
|
|
|
def get_libcxx_paths():
|
2019-02-02 23:13:49 +00:00
|
|
|
|
utils_path = os.path.dirname(os.path.abspath(__file__))
|
2019-01-16 05:43:02 +00:00
|
|
|
|
script_name = os.path.basename(__file__)
|
2019-02-02 23:13:49 +00:00
|
|
|
|
assert os.path.exists(utils_path)
|
|
|
|
|
src_root = os.path.dirname(utils_path)
|
2019-01-16 01:37:43 +00:00
|
|
|
|
include_path = os.path.join(src_root, "include")
|
|
|
|
|
assert os.path.exists(include_path)
|
|
|
|
|
docs_path = os.path.join(src_root, "docs")
|
|
|
|
|
assert os.path.exists(docs_path)
|
2019-02-02 23:13:49 +00:00
|
|
|
|
macro_test_path = os.path.join(
|
|
|
|
|
src_root,
|
|
|
|
|
"test",
|
|
|
|
|
"std",
|
|
|
|
|
"language.support",
|
|
|
|
|
"support.limits",
|
|
|
|
|
"support.limits.general",
|
|
|
|
|
)
|
|
|
|
|
assert os.path.exists(macro_test_path)
|
2022-04-11 10:38:26 -04:00
|
|
|
|
assert os.path.exists(
|
|
|
|
|
os.path.join(macro_test_path, "version.version.compile.pass.cpp")
|
2023-05-17 11:09:29 +02:00
|
|
|
|
)
|
2019-02-02 23:13:49 +00:00
|
|
|
|
return script_name, src_root, include_path, docs_path, macro_test_path
|
2023-05-17 11:09:29 +02:00
|
|
|
|
|
2019-01-16 01:37:43 +00:00
|
|
|
|
|
2019-02-02 23:13:49 +00:00
|
|
|
|
script_name, source_root, include_path, docs_path, macro_test_path = get_libcxx_paths()
|
2019-01-16 01:37:43 +00:00
|
|
|
|
|
2023-05-17 11:09:29 +02:00
|
|
|
|
|
2019-01-16 01:37:43 +00:00
|
|
|
|
def has_header(h):
|
|
|
|
|
h_path = os.path.join(include_path, h)
|
|
|
|
|
return os.path.exists(h_path)
|
2023-05-17 11:09:29 +02:00
|
|
|
|
|
2019-01-16 01:37:43 +00:00
|
|
|
|
|
|
|
|
|
def add_version_header(tc):
|
2021-01-07 18:04:41 -05:00
|
|
|
|
tc["headers"].append("version")
|
|
|
|
|
return tc
|
2023-05-17 11:09:29 +02:00
|
|
|
|
|
2019-01-16 01:37:43 +00:00
|
|
|
|
|
2021-03-30 20:19:12 +02:00
|
|
|
|
# ================ ============================================================
|
|
|
|
|
# Field Description
|
|
|
|
|
# ================ ============================================================
|
|
|
|
|
# name The name of the feature-test macro.
|
|
|
|
|
# values A dict whose keys are C++ versions and whose values are the
|
|
|
|
|
# value of the feature-test macro for that C++ version.
|
|
|
|
|
# (TODO: This isn't a very clean model for feature-test
|
|
|
|
|
# macros affected by multiple papers.)
|
|
|
|
|
# headers An array with the headers that should provide the
|
|
|
|
|
# feature-test macro.
|
|
|
|
|
# test_suite_guard An optional string field. When this field is provided,
|
|
|
|
|
# `libcxx_guard` must also be provided. This field is used
|
|
|
|
|
# only to generate the unit tests for the feature-test macros.
|
|
|
|
|
# It can't depend on macros defined in <__config> because the
|
|
|
|
|
# `test/std/` parts of the test suite are intended to be
|
|
|
|
|
# portable to any C++ standard library implementation, not
|
|
|
|
|
# just libc++. It may depend on
|
|
|
|
|
# * macros defined by the compiler itself, or
|
|
|
|
|
# * macros generated by CMake.
|
2024-05-28 18:29:11 -07:00
|
|
|
|
# In some cases we add also depend on macros defined in
|
|
|
|
|
# <__configuration/availability.h>.
|
2021-03-30 20:19:12 +02:00
|
|
|
|
# libcxx_guard An optional string field. When this field is provided,
|
|
|
|
|
# `test_suite_guard` must also be provided. This field is used
|
|
|
|
|
# only to guard the feature-test macro in <version>. It may
|
|
|
|
|
# be the same as `test_suite_guard`, or it may depend on
|
|
|
|
|
# macros defined in <__config>.
|
|
|
|
|
# unimplemented An optional Boolean field with the value `True`. This field
|
|
|
|
|
# is only used when a feature isn't fully implemented. Once
|
|
|
|
|
# you've fully implemented the feature, you should remove
|
|
|
|
|
# this field.
|
|
|
|
|
# ================ ============================================================
|
2021-01-07 18:04:41 -05:00
|
|
|
|
feature_test_macros = [
|
|
|
|
|
add_version_header(x)
|
|
|
|
|
for x in [
|
2020-09-21 10:54:16 -04:00
|
|
|
|
{
|
2022-01-06 12:36:07 +01:00
|
|
|
|
"name": "__cpp_lib_adaptor_iterator_pair_constructor",
|
2023-05-17 17:54:53 +02:00
|
|
|
|
"values": {"c++23": 202106},
|
2022-01-06 12:36:07 +01:00
|
|
|
|
"headers": ["queue", "stack"],
|
|
|
|
|
},
|
|
|
|
|
{
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"name": "__cpp_lib_addressof_constexpr",
|
|
|
|
|
"values": {"c++17": 201603},
|
2020-09-21 10:54:16 -04:00
|
|
|
|
"headers": ["memory"],
|
2021-12-30 23:28:12 -05:00
|
|
|
|
},
|
2025-04-14 17:33:57 -04:00
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_aligned_accessor",
|
|
|
|
|
"values": {"c++26": 202411},
|
|
|
|
|
"headers": ["mdspan"],
|
|
|
|
|
},
|
2021-12-30 23:28:12 -05:00
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_allocate_at_least",
|
2023-06-17 12:00:23 +02:00
|
|
|
|
"values": {
|
2023-11-16 10:17:19 +01:00
|
|
|
|
# Note LWG3887 Version macro for allocate_at_least
|
2024-02-01 13:31:25 +02:00
|
|
|
|
"c++23": 202302, # P2652R2 Disallow User Specialization of allocator_traits
|
2023-11-16 10:17:19 +01:00
|
|
|
|
},
|
2021-12-30 23:28:12 -05:00
|
|
|
|
"headers": ["memory"],
|
2020-09-21 10:54:16 -04:00
|
|
|
|
},
|
|
|
|
|
{
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"name": "__cpp_lib_allocator_traits_is_always_equal",
|
|
|
|
|
"values": {"c++17": 201411},
|
|
|
|
|
"headers": [
|
|
|
|
|
"deque",
|
|
|
|
|
"forward_list",
|
|
|
|
|
"list",
|
|
|
|
|
"map",
|
|
|
|
|
"memory",
|
|
|
|
|
"scoped_allocator",
|
|
|
|
|
"set",
|
|
|
|
|
"string",
|
|
|
|
|
"unordered_map",
|
|
|
|
|
"unordered_set",
|
|
|
|
|
"vector",
|
|
|
|
|
],
|
2020-09-21 10:54:16 -04:00
|
|
|
|
},
|
|
|
|
|
{
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"name": "__cpp_lib_any",
|
|
|
|
|
"values": {"c++17": 201606},
|
|
|
|
|
"headers": ["any"],
|
2020-09-21 10:54:16 -04:00
|
|
|
|
},
|
|
|
|
|
{
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"name": "__cpp_lib_apply",
|
|
|
|
|
"values": {"c++17": 201603},
|
|
|
|
|
"headers": ["tuple"],
|
2020-09-21 10:54:16 -04:00
|
|
|
|
},
|
|
|
|
|
{
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"name": "__cpp_lib_array_constexpr",
|
|
|
|
|
"values": {"c++17": 201603, "c++20": 201811},
|
|
|
|
|
"headers": ["array", "iterator"],
|
2020-09-21 10:54:16 -04:00
|
|
|
|
},
|
|
|
|
|
{
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"name": "__cpp_lib_as_const",
|
|
|
|
|
"values": {"c++17": 201510},
|
|
|
|
|
"headers": ["utility"],
|
2021-12-30 23:28:12 -05:00
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_associative_heterogeneous_erasure",
|
2023-05-17 17:54:53 +02:00
|
|
|
|
"values": {"c++23": 202110},
|
2021-12-30 23:28:12 -05:00
|
|
|
|
"headers": ["map", "set", "unordered_map", "unordered_set"],
|
|
|
|
|
"unimplemented": True,
|
2021-01-07 18:21:07 -05:00
|
|
|
|
},
|
2023-06-17 12:00:23 +02:00
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_associative_heterogeneous_insertion",
|
2023-11-16 10:17:19 +01:00
|
|
|
|
"values": {
|
|
|
|
|
"c++26": 202306 # P2363R5 Extending associative containers with the remaining heterogeneous overloads
|
|
|
|
|
},
|
2023-06-17 12:00:23 +02:00
|
|
|
|
"headers": ["map", "set", "unordered_map", "unordered_set"],
|
|
|
|
|
"unimplemented": True,
|
|
|
|
|
},
|
2021-01-07 18:21:07 -05:00
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_assume_aligned",
|
|
|
|
|
"values": {"c++20": 201811},
|
|
|
|
|
"headers": ["memory"],
|
2020-09-21 10:54:16 -04:00
|
|
|
|
},
|
|
|
|
|
{
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"name": "__cpp_lib_atomic_flag_test",
|
|
|
|
|
"values": {"c++20": 201907},
|
|
|
|
|
"headers": ["atomic"],
|
2020-09-21 10:54:16 -04:00
|
|
|
|
},
|
|
|
|
|
{
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"name": "__cpp_lib_atomic_float",
|
|
|
|
|
"values": {"c++20": 201711},
|
|
|
|
|
"headers": ["atomic"],
|
2020-09-21 10:54:16 -04:00
|
|
|
|
},
|
|
|
|
|
{
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"name": "__cpp_lib_atomic_is_always_lock_free",
|
|
|
|
|
"values": {"c++17": 201603},
|
|
|
|
|
"headers": ["atomic"],
|
2020-09-21 10:54:16 -04:00
|
|
|
|
},
|
|
|
|
|
{
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"name": "__cpp_lib_atomic_lock_free_type_aliases",
|
|
|
|
|
"values": {"c++20": 201907},
|
|
|
|
|
"headers": ["atomic"],
|
2020-09-21 10:54:16 -04:00
|
|
|
|
},
|
2024-04-03 08:21:11 -04:00
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_atomic_min_max",
|
|
|
|
|
"values": {"c++26": 202403}, # P0493R5: Atomic minimum/maximum
|
|
|
|
|
"headers": ["atomic"],
|
|
|
|
|
"unimplemented": True,
|
|
|
|
|
},
|
2020-09-21 10:54:16 -04:00
|
|
|
|
{
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"name": "__cpp_lib_atomic_ref",
|
|
|
|
|
"values": {"c++20": 201806},
|
|
|
|
|
"headers": ["atomic"],
|
2020-09-21 10:54:16 -04:00
|
|
|
|
},
|
|
|
|
|
{
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"name": "__cpp_lib_atomic_shared_ptr",
|
|
|
|
|
"values": {"c++20": 201711},
|
|
|
|
|
"headers": ["atomic"],
|
|
|
|
|
"unimplemented": True,
|
2020-09-21 10:54:16 -04:00
|
|
|
|
},
|
|
|
|
|
{
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"name": "__cpp_lib_atomic_value_initialization",
|
|
|
|
|
"values": {"c++20": 201911},
|
|
|
|
|
"headers": ["atomic", "memory"],
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_atomic_wait",
|
|
|
|
|
"values": {"c++20": 201907},
|
2020-09-21 10:54:16 -04:00
|
|
|
|
"headers": ["atomic"],
|
2023-11-24 23:45:17 +01:00
|
|
|
|
"test_suite_guard": "!defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_SYNC",
|
|
|
|
|
"libcxx_guard": "_LIBCPP_AVAILABILITY_HAS_SYNC",
|
2021-01-07 18:21:07 -05:00
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_barrier",
|
|
|
|
|
"values": {"c++20": 201907},
|
|
|
|
|
"headers": ["barrier"],
|
2024-11-06 10:39:19 +01:00
|
|
|
|
"test_suite_guard": "!defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC)",
|
|
|
|
|
"libcxx_guard": "_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC",
|
2022-02-09 00:07:14 +01:00
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_bind_back",
|
2023-06-17 12:00:23 +02:00
|
|
|
|
"values": {
|
2023-11-16 10:17:19 +01:00
|
|
|
|
"c++23": 202202,
|
2024-04-09 17:10:20 +02:00
|
|
|
|
# "c++26": 202306, # P2714R1 Bind front and back to NTTP callables
|
2023-11-16 10:17:19 +01:00
|
|
|
|
},
|
2022-02-09 00:07:14 +01:00
|
|
|
|
"headers": ["functional"],
|
2020-09-21 10:54:16 -04:00
|
|
|
|
},
|
|
|
|
|
{
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"name": "__cpp_lib_bind_front",
|
2023-06-17 12:00:23 +02:00
|
|
|
|
"values": {
|
2023-11-16 10:17:19 +01:00
|
|
|
|
"c++20": 201907,
|
|
|
|
|
"c++26": 202306, # P2714R1 Bind front and back to NTTP callables
|
|
|
|
|
},
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"headers": ["functional"],
|
2020-09-21 10:54:16 -04:00
|
|
|
|
},
|
|
|
|
|
{
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"name": "__cpp_lib_bit_cast",
|
|
|
|
|
"values": {"c++20": 201806},
|
|
|
|
|
"headers": ["bit"],
|
2021-01-07 18:21:07 -05:00
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_bitops",
|
|
|
|
|
"values": {"c++20": 201907},
|
|
|
|
|
"headers": ["bit"],
|
2020-09-21 10:54:16 -04:00
|
|
|
|
},
|
2023-06-17 12:00:23 +02:00
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_bitset",
|
2023-11-16 10:17:19 +01:00
|
|
|
|
"values": {"c++26": 202306}, # P2697R1 Interfacing bitset with string_view
|
2023-06-17 12:00:23 +02:00
|
|
|
|
"headers": ["bitset"],
|
|
|
|
|
},
|
2020-09-21 10:54:16 -04:00
|
|
|
|
{
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"name": "__cpp_lib_bool_constant",
|
|
|
|
|
"values": {"c++17": 201505},
|
|
|
|
|
"headers": ["type_traits"],
|
2021-01-07 18:21:07 -05:00
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_bounded_array_traits",
|
|
|
|
|
"values": {"c++20": 201902},
|
|
|
|
|
"headers": ["type_traits"],
|
2020-09-21 10:54:16 -04:00
|
|
|
|
},
|
|
|
|
|
{
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"name": "__cpp_lib_boyer_moore_searcher",
|
|
|
|
|
"values": {"c++17": 201603},
|
|
|
|
|
"headers": ["functional"],
|
2020-09-21 10:54:16 -04:00
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_byte",
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"values": {"c++17": 201603},
|
2020-09-21 10:54:16 -04:00
|
|
|
|
"headers": ["cstddef"],
|
2021-11-22 00:22:55 +01:00
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_byteswap",
|
2023-05-17 17:54:53 +02:00
|
|
|
|
"values": {"c++23": 202110},
|
2021-11-22 00:22:55 +01:00
|
|
|
|
"headers": ["bit"],
|
2020-12-08 15:42:33 -05:00
|
|
|
|
},
|
|
|
|
|
{
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"name": "__cpp_lib_char8_t",
|
2022-07-19 02:03:10 +02:00
|
|
|
|
"values": {"c++20": 201907},
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"headers": [
|
|
|
|
|
"atomic",
|
|
|
|
|
"filesystem",
|
|
|
|
|
"istream",
|
|
|
|
|
"limits",
|
|
|
|
|
"locale",
|
|
|
|
|
"ostream",
|
|
|
|
|
"string",
|
|
|
|
|
"string_view",
|
|
|
|
|
],
|
2021-03-30 20:19:12 +02:00
|
|
|
|
"test_suite_guard": "defined(__cpp_char8_t)",
|
2024-10-12 09:49:52 +02:00
|
|
|
|
"libcxx_guard": "_LIBCPP_HAS_CHAR8_T",
|
2020-12-08 15:42:33 -05:00
|
|
|
|
},
|
|
|
|
|
{
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"name": "__cpp_lib_chrono",
|
2023-06-17 12:00:23 +02:00
|
|
|
|
"values": {
|
2023-11-16 10:17:19 +01:00
|
|
|
|
"c++17": 201611,
|
|
|
|
|
# "c++26": 202306, # P2592R3 Hashing support for std::chrono value classes
|
|
|
|
|
},
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"headers": ["chrono"],
|
2020-12-08 15:42:33 -05:00
|
|
|
|
},
|
|
|
|
|
{
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"name": "__cpp_lib_chrono_udls",
|
|
|
|
|
"values": {"c++14": 201304},
|
|
|
|
|
"headers": ["chrono"],
|
2020-12-08 15:42:33 -05:00
|
|
|
|
},
|
|
|
|
|
{
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"name": "__cpp_lib_clamp",
|
|
|
|
|
"values": {"c++17": 201603},
|
|
|
|
|
"headers": ["algorithm"],
|
2020-12-08 15:42:33 -05:00
|
|
|
|
},
|
|
|
|
|
{
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"name": "__cpp_lib_complex_udls",
|
|
|
|
|
"values": {"c++14": 201309},
|
|
|
|
|
"headers": ["complex"],
|
2020-12-08 15:42:33 -05:00
|
|
|
|
},
|
|
|
|
|
{
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"name": "__cpp_lib_concepts",
|
2021-01-07 18:21:07 -05:00
|
|
|
|
"values": {"c++20": 202002},
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"headers": ["concepts"],
|
2021-01-07 18:21:07 -05:00
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_constexpr_algorithms",
|
2023-06-17 12:00:23 +02:00
|
|
|
|
"values": {
|
2023-11-16 10:17:19 +01:00
|
|
|
|
"c++20": 201806,
|
2025-03-21 07:33:52 +08:00
|
|
|
|
"c++26": 202306,
|
2023-11-16 10:17:19 +01:00
|
|
|
|
},
|
2022-12-20 18:02:36 +01:00
|
|
|
|
"headers": ["algorithm", "utility"],
|
2022-08-13 13:52:35 +02:00
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_constexpr_bitset",
|
2023-05-17 17:54:53 +02:00
|
|
|
|
"values": {"c++23": 202207},
|
2022-08-13 13:52:35 +02:00
|
|
|
|
"headers": ["bitset"],
|
2022-08-06 10:47:53 +02:00
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_constexpr_charconv",
|
2023-05-17 17:54:53 +02:00
|
|
|
|
"values": {"c++23": 202207},
|
2022-08-06 10:47:53 +02:00
|
|
|
|
"headers": ["charconv"],
|
2022-02-09 00:07:14 +01:00
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_constexpr_cmath",
|
2023-05-17 17:54:53 +02:00
|
|
|
|
"values": {"c++23": 202202},
|
2022-02-09 00:07:14 +01:00
|
|
|
|
"headers": ["cmath", "cstdlib"],
|
|
|
|
|
"unimplemented": True,
|
2021-01-07 18:21:07 -05:00
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_constexpr_complex",
|
|
|
|
|
"values": {"c++20": 201711},
|
|
|
|
|
"headers": ["complex"],
|
2020-12-08 15:42:33 -05:00
|
|
|
|
},
|
|
|
|
|
{
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"name": "__cpp_lib_constexpr_dynamic_alloc",
|
|
|
|
|
"values": {"c++20": 201907},
|
|
|
|
|
"headers": ["memory"],
|
2020-12-08 15:42:33 -05:00
|
|
|
|
},
|
|
|
|
|
{
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"name": "__cpp_lib_constexpr_functional",
|
|
|
|
|
"values": {"c++20": 201907},
|
|
|
|
|
"headers": ["functional"],
|
2021-01-07 18:21:07 -05:00
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_constexpr_iterator",
|
|
|
|
|
"values": {"c++20": 201811},
|
|
|
|
|
"headers": ["iterator"],
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_constexpr_memory",
|
2023-05-17 17:54:53 +02:00
|
|
|
|
"values": {"c++20": 201811, "c++23": 202202},
|
2021-01-07 18:21:07 -05:00
|
|
|
|
"headers": ["memory"],
|
2020-12-08 15:42:33 -05:00
|
|
|
|
},
|
2024-07-08 19:35:31 +02:00
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_constexpr_new",
|
|
|
|
|
"values": {"c++26": 202406}, # P2747R2 constexpr placement new
|
|
|
|
|
"headers": ["new"],
|
2024-08-28 21:35:57 +08:00
|
|
|
|
"test_suite_guard": "!defined(_LIBCPP_ABI_VCRUNTIME)",
|
|
|
|
|
"libcxx_guard": "!defined(_LIBCPP_ABI_VCRUNTIME)",
|
2024-07-08 19:35:31 +02:00
|
|
|
|
},
|
2020-12-08 15:42:33 -05:00
|
|
|
|
{
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"name": "__cpp_lib_constexpr_numeric",
|
|
|
|
|
"values": {"c++20": 201911},
|
|
|
|
|
"headers": ["numeric"],
|
2020-12-08 15:42:33 -05:00
|
|
|
|
},
|
|
|
|
|
{
|
2021-01-07 18:21:07 -05:00
|
|
|
|
"name": "__cpp_lib_constexpr_string",
|
[libc++] Implement P0980R1 (constexpr std::string)
Reviewed By: #libc, ldionne
Spies: daltenty, sdasgup3, ldionne, arichardson, MTC, ChuanqiXu, mehdi_amini, shauheen, antiagainst, nicolasvasilache, arpith-jacob, mgester, lucyrfox, aartbik, liufengdb, stephenneuendorffer, Joonsoo, grosul1, Kayjukh, jurahul, msifontes, tatianashp, rdzhabarov, teijeong, cota, dcaballe, Chia-hungDuan, wrengr, wenzhicui, arphaman, Mordante, miscco, Quuxplusone, smeenai, libcxx-commits
Differential Revision: https://reviews.llvm.org/D110598
2022-04-27 10:11:44 +02:00
|
|
|
|
"values": {"c++20": 201907},
|
2021-01-07 18:21:07 -05:00
|
|
|
|
"headers": ["string"],
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_constexpr_string_view",
|
|
|
|
|
"values": {"c++20": 201811},
|
|
|
|
|
"headers": ["string_view"],
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_constexpr_tuple",
|
|
|
|
|
"values": {"c++20": 201811},
|
|
|
|
|
"headers": ["tuple"],
|
2021-12-30 23:28:12 -05:00
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_constexpr_typeinfo",
|
2023-05-17 17:54:53 +02:00
|
|
|
|
"values": {"c++23": 202106},
|
2021-12-30 23:28:12 -05:00
|
|
|
|
"headers": ["typeinfo"],
|
2020-12-08 15:42:33 -05:00
|
|
|
|
},
|
|
|
|
|
{
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"name": "__cpp_lib_constexpr_utility",
|
|
|
|
|
"values": {"c++20": 201811},
|
|
|
|
|
"headers": ["utility"],
|
2021-01-07 18:21:07 -05:00
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_constexpr_vector",
|
|
|
|
|
"values": {"c++20": 201907},
|
|
|
|
|
"headers": ["vector"],
|
|
|
|
|
},
|
2024-04-03 08:21:11 -04:00
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_constrained_equality",
|
|
|
|
|
"values": {"c++26": 202403}, # P2944R3: Comparisons for reference_wrapper
|
|
|
|
|
"headers": ["optional", "tuple", "utility", "variant"],
|
|
|
|
|
"unimplemented": True,
|
|
|
|
|
},
|
2024-05-04 16:23:49 +00:00
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_containers_ranges",
|
|
|
|
|
"values": {"c++23": 202202},
|
|
|
|
|
"headers": [
|
|
|
|
|
"deque",
|
|
|
|
|
"forward_list",
|
|
|
|
|
"list",
|
|
|
|
|
"map",
|
|
|
|
|
"queue",
|
|
|
|
|
"set",
|
|
|
|
|
"stack",
|
|
|
|
|
"string",
|
|
|
|
|
"unordered_map",
|
|
|
|
|
"unordered_set",
|
|
|
|
|
"vector",
|
|
|
|
|
],
|
|
|
|
|
},
|
2023-06-17 12:00:23 +02:00
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_copyable_function",
|
2023-11-16 10:17:19 +01:00
|
|
|
|
"values": {"c++26": 202306}, # P2548R6 copyable_function
|
2023-06-17 12:00:23 +02:00
|
|
|
|
"headers": ["functional"],
|
|
|
|
|
"unimplemented": True,
|
|
|
|
|
},
|
2021-01-07 18:21:07 -05:00
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_coroutine",
|
|
|
|
|
"values": {"c++20": 201902},
|
|
|
|
|
"headers": ["coroutine"],
|
2021-01-07 18:04:41 -05:00
|
|
|
|
},
|
2023-11-16 10:17:19 +01:00
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_debugging",
|
2024-04-03 08:21:11 -04:00
|
|
|
|
"values": {
|
|
|
|
|
"c++26": 202311, # P2546R5 Debugging Support
|
|
|
|
|
# "c++26": 202403, # P2810R4: is_debugger_present is_replaceable
|
|
|
|
|
},
|
2023-11-16 10:17:19 +01:00
|
|
|
|
"headers": ["debugging"],
|
|
|
|
|
"unimplemented": True,
|
|
|
|
|
},
|
2024-04-03 08:21:11 -04:00
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_default_template_type_for_algorithm_values",
|
|
|
|
|
"values": {"c++26": 202403}, # P2248R8: Enabling list-initialization for algorithms
|
|
|
|
|
"headers": ["algorithm", "deque", "forward_list", "list", "ranges", "string", "vector"],
|
|
|
|
|
"unimplemented": True,
|
|
|
|
|
},
|
2021-01-07 18:04:41 -05:00
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_destroying_delete",
|
|
|
|
|
"values": {"c++20": 201806},
|
|
|
|
|
"headers": ["new"],
|
2021-03-30 20:19:12 +02:00
|
|
|
|
"test_suite_guard": "TEST_STD_VER > 17 && defined(__cpp_impl_destroying_delete) && __cpp_impl_destroying_delete >= 201806L",
|
2023-02-14 00:56:09 +01:00
|
|
|
|
"libcxx_guard": "_LIBCPP_STD_VER >= 20 && defined(__cpp_impl_destroying_delete) && __cpp_impl_destroying_delete >= 201806L",
|
2020-12-08 15:42:33 -05:00
|
|
|
|
},
|
|
|
|
|
{
|
2020-09-21 10:54:16 -04:00
|
|
|
|
"name": "__cpp_lib_enable_shared_from_this",
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"values": {"c++17": 201603},
|
2020-09-21 10:54:16 -04:00
|
|
|
|
"headers": ["memory"],
|
2020-12-08 15:42:33 -05:00
|
|
|
|
},
|
|
|
|
|
{
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"name": "__cpp_lib_endian",
|
|
|
|
|
"values": {"c++20": 201907},
|
|
|
|
|
"headers": ["bit"],
|
2020-12-08 15:42:33 -05:00
|
|
|
|
},
|
|
|
|
|
{
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"name": "__cpp_lib_erase_if",
|
|
|
|
|
"values": {"c++20": 202002},
|
|
|
|
|
"headers": [
|
|
|
|
|
"deque",
|
|
|
|
|
"forward_list",
|
|
|
|
|
"list",
|
|
|
|
|
"map",
|
|
|
|
|
"set",
|
|
|
|
|
"string",
|
|
|
|
|
"unordered_map",
|
|
|
|
|
"unordered_set",
|
|
|
|
|
"vector",
|
|
|
|
|
],
|
2020-12-08 15:42:33 -05:00
|
|
|
|
},
|
|
|
|
|
{
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"name": "__cpp_lib_exchange_function",
|
2021-01-07 18:21:07 -05:00
|
|
|
|
"values": {"c++14": 201304},
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"headers": ["utility"],
|
2023-05-17 11:09:29 +02:00
|
|
|
|
},
|
|
|
|
|
{
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"name": "__cpp_lib_execution",
|
2021-01-07 18:21:07 -05:00
|
|
|
|
"values": {"c++17": 201603, "c++20": 201902},
|
2021-12-30 23:28:12 -05:00
|
|
|
|
"headers": ["execution"],
|
2020-09-21 10:54:16 -04:00
|
|
|
|
"unimplemented": True,
|
2022-11-04 11:42:42 +00:00
|
|
|
|
},
|
2023-05-17 17:54:53 +02:00
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_expected",
|
|
|
|
|
"values": {"c++23": 202211},
|
2022-11-04 11:42:42 +00:00
|
|
|
|
"headers": ["expected"],
|
2020-12-08 15:42:33 -05:00
|
|
|
|
},
|
2023-05-17 11:09:29 +02:00
|
|
|
|
{
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"name": "__cpp_lib_filesystem",
|
|
|
|
|
"values": {"c++17": 201703},
|
|
|
|
|
"headers": ["filesystem"],
|
2024-11-06 10:39:19 +01:00
|
|
|
|
"test_suite_guard": "!defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_FILESYSTEM && _LIBCPP_AVAILABILITY_HAS_FILESYSTEM_LIBRARY)",
|
|
|
|
|
"libcxx_guard": "_LIBCPP_HAS_FILESYSTEM && _LIBCPP_AVAILABILITY_HAS_FILESYSTEM_LIBRARY",
|
2020-11-26 19:12:18 +01:00
|
|
|
|
},
|
2025-01-25 18:30:00 +00:00
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_flat_map",
|
|
|
|
|
"values": {"c++23": 202207},
|
|
|
|
|
"headers": ["flat_map"],
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_flat_set",
|
|
|
|
|
"values": {"c++23": 202207},
|
|
|
|
|
"headers": ["flat_set"],
|
|
|
|
|
},
|
2020-11-26 19:12:18 +01:00
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_format",
|
2022-09-04 13:56:36 +02:00
|
|
|
|
"values": {
|
2024-07-10 17:52:43 +02:00
|
|
|
|
"c++20": 202110,
|
2022-09-04 13:56:36 +02:00
|
|
|
|
# "c++23": 202207, Not implemented P2419R2 Clarify handling of encodings in localized formatting of chrono types
|
2024-01-29 20:57:12 +02:00
|
|
|
|
# "c++26": 202306, P2637R3 Member Visit (implemented)
|
2023-11-24 17:30:33 +01:00
|
|
|
|
# "c++26": 202311, P2918R2 Runtime format strings II (implemented)
|
2022-09-04 13:56:36 +02:00
|
|
|
|
},
|
2023-06-17 12:00:23 +02:00
|
|
|
|
# Note these three papers are adopted at the June 2023 meeting and have sequential numbering
|
2022-04-03 17:43:52 +02:00
|
|
|
|
# 202304 P2510R3 Formatting pointers (Implemented)
|
2023-06-17 12:00:23 +02:00
|
|
|
|
# 202305 P2757R3 Type-checking format args
|
|
|
|
|
# 202306 P2637R3 Member Visit
|
2020-11-26 19:12:18 +01:00
|
|
|
|
"headers": ["format"],
|
2025-02-14 18:27:54 +01:00
|
|
|
|
# Trying to use `std::format` where to_chars floating-point is not
|
|
|
|
|
# available causes compilation errors, even with non floating-point types.
|
|
|
|
|
# https://github.com/llvm/llvm-project/issues/125353
|
|
|
|
|
"test_suite_guard": "!defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_TO_CHARS_FLOATING_POINT",
|
|
|
|
|
"libcxx_guard": "_LIBCPP_AVAILABILITY_HAS_TO_CHARS_FLOATING_POINT",
|
2023-04-09 13:24:21 +02:00
|
|
|
|
},
|
2024-04-03 08:21:11 -04:00
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_format_path",
|
2024-05-28 12:15:50 -07:00
|
|
|
|
"values": {"c++26": 202403}, # P2845R8: Formatting of std::filesystem::path
|
2024-04-03 08:21:11 -04:00
|
|
|
|
"headers": ["filesystem"],
|
|
|
|
|
"unimplemented": True,
|
|
|
|
|
},
|
2023-04-09 13:24:21 +02:00
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_format_ranges",
|
2023-05-17 17:54:53 +02:00
|
|
|
|
"values": {"c++23": 202207},
|
2023-04-09 13:24:21 +02:00
|
|
|
|
"headers": ["format"],
|
2023-02-18 18:30:56 +01:00
|
|
|
|
},
|
2023-11-16 10:17:19 +01:00
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_format_uchar",
|
|
|
|
|
"values": {
|
|
|
|
|
"c++20": 202311 # DR P2909R4 Fix formatting of code units as integers
|
|
|
|
|
},
|
2023-12-18 12:43:10 +01:00
|
|
|
|
"headers": [
|
|
|
|
|
"format" # TODO verify this entry since the paper was underspecified.
|
|
|
|
|
],
|
2023-11-16 10:17:19 +01:00
|
|
|
|
},
|
2023-02-18 18:30:56 +01:00
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_formatters",
|
2023-05-17 17:54:53 +02:00
|
|
|
|
"values": {"c++23": 202302},
|
2023-02-18 18:30:56 +01:00
|
|
|
|
"headers": ["stacktrace", "thread"],
|
|
|
|
|
"unimplemented": True,
|
2022-08-21 22:21:08 +07:00
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_forward_like",
|
2023-05-17 17:54:53 +02:00
|
|
|
|
"values": {"c++23": 202207},
|
2022-08-21 22:21:08 +07:00
|
|
|
|
"headers": ["utility"],
|
2020-12-08 15:42:33 -05:00
|
|
|
|
},
|
2023-11-16 10:17:19 +01:00
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_freestanding_algorithm",
|
|
|
|
|
"values": {
|
|
|
|
|
"c++26": 202311 # P2407R5 Freestanding Library: Partial Classes
|
|
|
|
|
},
|
|
|
|
|
"headers": ["algorithm"],
|
|
|
|
|
"unimplemented": True,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_freestanding_array",
|
|
|
|
|
"values": {
|
|
|
|
|
"c++26": 202311 # P2407R5 Freestanding Library: Partial Classes
|
|
|
|
|
},
|
|
|
|
|
"headers": ["array"],
|
|
|
|
|
"unimplemented": True,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_freestanding_cstring",
|
|
|
|
|
"values": {
|
|
|
|
|
"c++26": 202306 # P2338R4 Freestanding Library: Character primitives and the C library
|
|
|
|
|
# 202311 # P2407R5 Freestanding Library: Partial Classes
|
|
|
|
|
},
|
|
|
|
|
"headers": ["cstring"],
|
|
|
|
|
"unimplemented": True,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_freestanding_expected",
|
|
|
|
|
"values": {
|
|
|
|
|
"c++26": 202311 # P2833R2 Freestanding Library: inout expected span
|
|
|
|
|
},
|
|
|
|
|
"headers": ["expected"],
|
|
|
|
|
"unimplemented": True,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_freestanding_mdspan",
|
|
|
|
|
"values": {
|
|
|
|
|
"c++26": 202311 # P2833R2 Freestanding Library: inout expected span
|
|
|
|
|
},
|
|
|
|
|
"headers": ["mdspan"],
|
|
|
|
|
"unimplemented": True,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_freestanding_optional",
|
|
|
|
|
"values": {
|
|
|
|
|
"c++26": 202311 # P2407R5 Freestanding Library: Partial Classes
|
|
|
|
|
},
|
|
|
|
|
"headers": ["optional"],
|
|
|
|
|
"unimplemented": True,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_freestanding_string_view",
|
|
|
|
|
"values": {
|
|
|
|
|
"c++26": 202311 # P2407R5 Freestanding Library: Partial Classes
|
|
|
|
|
},
|
|
|
|
|
"headers": ["string_view"],
|
|
|
|
|
"unimplemented": True,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_freestanding_variant",
|
|
|
|
|
"values": {
|
|
|
|
|
"c++26": 202311 # P2407R5 Freestanding Library: Partial Classes
|
|
|
|
|
},
|
|
|
|
|
"headers": ["variant"],
|
|
|
|
|
"unimplemented": True,
|
|
|
|
|
},
|
2023-06-17 12:00:23 +02:00
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_fstream_native_handle",
|
2023-11-16 10:17:19 +01:00
|
|
|
|
"values": {"c++26": 202306}, # P1759R6 Native handles and file streams
|
2023-06-17 12:00:23 +02:00
|
|
|
|
"headers": ["fstream"],
|
2024-11-06 10:39:19 +01:00
|
|
|
|
"test_suite_guard": "!defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_FILESYSTEM && _LIBCPP_HAS_LOCALIZATION)",
|
|
|
|
|
"libcxx_guard": "_LIBCPP_HAS_FILESYSTEM && _LIBCPP_HAS_LOCALIZATION",
|
2023-06-17 12:00:23 +02:00
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_function_ref",
|
2023-11-16 10:17:19 +01:00
|
|
|
|
"values": {
|
|
|
|
|
"c++26": 202306 # P0792R14 function_ref: a type-erased callable reference
|
|
|
|
|
},
|
2023-06-17 12:00:23 +02:00
|
|
|
|
"headers": ["functional"],
|
|
|
|
|
"unimplemented": True,
|
|
|
|
|
},
|
2020-12-08 15:42:33 -05:00
|
|
|
|
{
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"name": "__cpp_lib_gcd_lcm",
|
|
|
|
|
"values": {"c++17": 201606},
|
|
|
|
|
"headers": ["numeric"],
|
2020-12-08 15:42:33 -05:00
|
|
|
|
},
|
2024-04-03 08:21:11 -04:00
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_generate_random",
|
|
|
|
|
"values": {"c++26": 202403}, # P1068R11: Vector API for random number generation
|
|
|
|
|
"headers": ["random"],
|
|
|
|
|
"unimplemented": True,
|
|
|
|
|
},
|
2020-12-08 15:42:33 -05:00
|
|
|
|
{
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"name": "__cpp_lib_generic_associative_lookup",
|
|
|
|
|
"values": {"c++14": 201304},
|
|
|
|
|
"headers": ["map", "set"],
|
2020-12-08 15:42:33 -05:00
|
|
|
|
},
|
|
|
|
|
{
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"name": "__cpp_lib_generic_unordered_lookup",
|
|
|
|
|
"values": {"c++20": 201811},
|
|
|
|
|
"headers": ["unordered_map", "unordered_set"],
|
2020-12-08 15:42:33 -05:00
|
|
|
|
},
|
|
|
|
|
{
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"name": "__cpp_lib_hardware_interference_size",
|
|
|
|
|
"values": {"c++17": 201703},
|
2023-12-02 17:41:23 -08:00
|
|
|
|
"test_suite_guard": "!defined(_LIBCPP_VERSION) || (defined(__GCC_DESTRUCTIVE_SIZE) && defined(__GCC_CONSTRUCTIVE_SIZE))",
|
2022-06-22 21:10:57 +02:00
|
|
|
|
"libcxx_guard": "defined(__GCC_DESTRUCTIVE_SIZE) && defined(__GCC_CONSTRUCTIVE_SIZE)",
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"headers": ["new"],
|
2020-12-08 15:42:33 -05:00
|
|
|
|
},
|
|
|
|
|
{
|
2020-09-21 10:54:16 -04:00
|
|
|
|
"name": "__cpp_lib_has_unique_object_representations",
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"values": {"c++17": 201606},
|
2020-09-21 10:54:16 -04:00
|
|
|
|
"headers": ["type_traits"],
|
2021-01-07 18:04:41 -05:00
|
|
|
|
},
|
2023-06-17 12:00:23 +02:00
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_hazard_pointer",
|
|
|
|
|
"values": {"c++26": 202306}, # P2530R3 Hazard Pointers for C++26
|
2023-11-16 10:17:19 +01:00
|
|
|
|
"headers": [
|
|
|
|
|
"hazard_pointer" # TODO verify this entry since the paper was underspecified.
|
|
|
|
|
],
|
2023-06-17 12:00:23 +02:00
|
|
|
|
"unimplemented": True,
|
|
|
|
|
},
|
2021-01-07 18:04:41 -05:00
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_hypot",
|
|
|
|
|
"values": {"c++17": 201603},
|
|
|
|
|
"headers": ["cmath"],
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_incomplete_container_elements",
|
|
|
|
|
"values": {"c++17": 201505},
|
|
|
|
|
"headers": ["forward_list", "list", "vector"],
|
|
|
|
|
},
|
2024-07-08 19:35:31 +02:00
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_inplace_vector",
|
|
|
|
|
"values": {"c++26": 202406}, # P0843R14 inplace_vector
|
|
|
|
|
"headers": ["inplace_vector"],
|
|
|
|
|
"unimplemented": True,
|
|
|
|
|
},
|
2021-01-07 18:04:41 -05:00
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_int_pow2",
|
|
|
|
|
"values": {"c++20": 202002},
|
|
|
|
|
"headers": ["bit"],
|
2021-01-07 18:21:07 -05:00
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_integer_comparison_functions",
|
|
|
|
|
"values": {"c++20": 202002},
|
|
|
|
|
"headers": ["utility"],
|
2021-01-07 18:04:41 -05:00
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_integer_sequence",
|
|
|
|
|
"values": {"c++14": 201304},
|
|
|
|
|
"headers": ["utility"],
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_integral_constant_callable",
|
|
|
|
|
"values": {"c++14": 201304},
|
|
|
|
|
"headers": ["type_traits"],
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_interpolate",
|
|
|
|
|
"values": {"c++20": 201902},
|
2021-01-07 18:21:07 -05:00
|
|
|
|
"headers": ["cmath", "numeric"],
|
2021-01-07 18:04:41 -05:00
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_invoke",
|
|
|
|
|
"values": {"c++17": 201411},
|
|
|
|
|
"headers": ["functional"],
|
2021-12-30 23:28:12 -05:00
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_invoke_r",
|
2023-05-17 17:54:53 +02:00
|
|
|
|
"values": {"c++23": 202106},
|
2021-12-30 23:28:12 -05:00
|
|
|
|
"headers": ["functional"],
|
2020-12-08 15:42:33 -05:00
|
|
|
|
},
|
2023-09-18 16:32:02 -04:00
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_ios_noreplace",
|
2023-12-18 12:43:10 +01:00
|
|
|
|
"values": {"c++23": 202207},
|
2023-09-18 16:32:02 -04:00
|
|
|
|
"headers": ["ios"],
|
|
|
|
|
},
|
2020-12-08 15:42:33 -05:00
|
|
|
|
{
|
2020-09-21 10:54:16 -04:00
|
|
|
|
"name": "__cpp_lib_is_aggregate",
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"values": {"c++17": 201703},
|
2020-09-21 10:54:16 -04:00
|
|
|
|
"headers": ["type_traits"],
|
2020-12-08 15:42:33 -05:00
|
|
|
|
},
|
|
|
|
|
{
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"name": "__cpp_lib_is_constant_evaluated",
|
|
|
|
|
"values": {"c++20": 201811},
|
|
|
|
|
"headers": ["type_traits"],
|
2020-12-08 15:42:33 -05:00
|
|
|
|
},
|
|
|
|
|
{
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"name": "__cpp_lib_is_final",
|
|
|
|
|
"values": {"c++14": 201402},
|
|
|
|
|
"headers": ["type_traits"],
|
2020-12-08 15:42:33 -05:00
|
|
|
|
},
|
2024-10-09 09:19:14 +03:00
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_is_implicit_lifetime",
|
|
|
|
|
"values": {"c++23": 202302},
|
|
|
|
|
"headers": ["type_traits"],
|
|
|
|
|
"test_suite_guard": "__has_builtin(__builtin_is_implicit_lifetime)",
|
|
|
|
|
"libcxx_guard": "__has_builtin(__builtin_is_implicit_lifetime)",
|
|
|
|
|
},
|
2020-12-08 15:42:33 -05:00
|
|
|
|
{
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"name": "__cpp_lib_is_invocable",
|
|
|
|
|
"values": {"c++17": 201703},
|
|
|
|
|
"headers": ["type_traits"],
|
2021-01-07 18:21:07 -05:00
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_is_layout_compatible",
|
|
|
|
|
"values": {"c++20": 201907},
|
|
|
|
|
"headers": ["type_traits"],
|
|
|
|
|
"unimplemented": True,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_is_nothrow_convertible",
|
|
|
|
|
"values": {"c++20": 201806},
|
|
|
|
|
"headers": ["type_traits"],
|
2020-12-08 15:42:33 -05:00
|
|
|
|
},
|
|
|
|
|
{
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"name": "__cpp_lib_is_null_pointer",
|
|
|
|
|
"values": {"c++14": 201309},
|
|
|
|
|
"headers": ["type_traits"],
|
2021-01-07 18:21:07 -05:00
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_is_pointer_interconvertible",
|
|
|
|
|
"values": {"c++20": 201907},
|
|
|
|
|
"headers": ["type_traits"],
|
|
|
|
|
"unimplemented": True,
|
2021-01-08 18:40:42 +01:00
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_is_scoped_enum",
|
2023-05-17 17:54:53 +02:00
|
|
|
|
"values": {"c++23": 202011},
|
2021-01-08 18:40:42 +01:00
|
|
|
|
"headers": ["type_traits"],
|
2020-12-08 15:42:33 -05:00
|
|
|
|
},
|
2025-04-14 17:33:57 -04:00
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_is_sufficiently_aligned",
|
|
|
|
|
"values": {"c++26": 202411},
|
|
|
|
|
"headers": ["memory"],
|
|
|
|
|
},
|
2020-12-08 15:42:33 -05:00
|
|
|
|
{
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"name": "__cpp_lib_is_swappable",
|
|
|
|
|
"values": {"c++17": 201603},
|
|
|
|
|
"headers": ["type_traits"],
|
2021-01-07 18:21:07 -05:00
|
|
|
|
},
|
2024-07-08 19:35:31 +02:00
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_is_virtual_base_of",
|
|
|
|
|
"values": {
|
|
|
|
|
"c++26": 202406 # P2985R0 A type trait for detecting virtual base classes
|
|
|
|
|
},
|
|
|
|
|
"headers": ["type_traits"],
|
2024-08-26 09:58:19 -04:00
|
|
|
|
"test_suite_guard": "__has_builtin(__builtin_is_virtual_base_of)",
|
|
|
|
|
"libcxx_guard": "__has_builtin(__builtin_is_virtual_base_of)",
|
2024-07-08 19:35:31 +02:00
|
|
|
|
},
|
2024-05-16 08:45:45 +01:00
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_is_within_lifetime",
|
|
|
|
|
# Note this name was changed from "__cpp_lib_within_lifetime" when the paper was adopted
|
|
|
|
|
# https://github.com/cplusplus/draft/commit/0facada4cadd97e1ba15bfaea76a804f1dc5c309
|
|
|
|
|
"values": {
|
|
|
|
|
"c++26": 202306 # P2641R4 Checking if a union alternative is active
|
|
|
|
|
},
|
|
|
|
|
"headers": ["type_traits"],
|
|
|
|
|
"unimplemented": True,
|
|
|
|
|
},
|
2021-01-07 18:21:07 -05:00
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_jthread",
|
|
|
|
|
"values": {"c++20": 201911},
|
|
|
|
|
"headers": ["stop_token", "thread"],
|
2024-11-06 10:39:19 +01:00
|
|
|
|
"test_suite_guard": "!defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC)",
|
|
|
|
|
"libcxx_guard": "_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC",
|
2021-01-07 18:21:07 -05:00
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_latch",
|
|
|
|
|
"values": {"c++20": 201907},
|
|
|
|
|
"headers": ["latch"],
|
2024-11-06 10:39:19 +01:00
|
|
|
|
"test_suite_guard": "!defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC)",
|
|
|
|
|
"libcxx_guard": "_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC",
|
2020-12-08 15:42:33 -05:00
|
|
|
|
},
|
|
|
|
|
{
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"name": "__cpp_lib_launder",
|
|
|
|
|
"values": {"c++17": 201606},
|
|
|
|
|
"headers": ["new"],
|
2020-12-08 15:42:33 -05:00
|
|
|
|
},
|
2023-11-16 10:17:19 +01:00
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_linalg",
|
|
|
|
|
"values": {
|
|
|
|
|
"c++26": 202311 # P1673 A free function linear algebra interface based on the BLAS
|
|
|
|
|
},
|
|
|
|
|
"headers": ["linalg"],
|
|
|
|
|
"unimplemented": True,
|
|
|
|
|
},
|
2020-12-08 15:42:33 -05:00
|
|
|
|
{
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"name": "__cpp_lib_list_remove_return_type",
|
|
|
|
|
"values": {"c++20": 201806},
|
|
|
|
|
"headers": ["forward_list", "list"],
|
2020-12-08 15:42:33 -05:00
|
|
|
|
},
|
|
|
|
|
{
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"name": "__cpp_lib_logical_traits",
|
|
|
|
|
"values": {"c++17": 201510},
|
|
|
|
|
"headers": ["type_traits"],
|
2020-12-08 15:42:33 -05:00
|
|
|
|
},
|
|
|
|
|
{
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"name": "__cpp_lib_make_from_tuple",
|
|
|
|
|
"values": {"c++17": 201606},
|
|
|
|
|
"headers": ["tuple"],
|
2020-12-08 15:42:33 -05:00
|
|
|
|
},
|
|
|
|
|
{
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"name": "__cpp_lib_make_reverse_iterator",
|
|
|
|
|
"values": {"c++14": 201402},
|
|
|
|
|
"headers": ["iterator"],
|
2020-12-08 15:42:33 -05:00
|
|
|
|
},
|
|
|
|
|
{
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"name": "__cpp_lib_make_unique",
|
|
|
|
|
"values": {"c++14": 201304},
|
|
|
|
|
"headers": ["memory"],
|
2020-12-08 15:42:33 -05:00
|
|
|
|
},
|
|
|
|
|
{
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"name": "__cpp_lib_map_try_emplace",
|
|
|
|
|
"values": {"c++17": 201411},
|
|
|
|
|
"headers": ["map"],
|
2020-12-08 15:42:33 -05:00
|
|
|
|
},
|
|
|
|
|
{
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"name": "__cpp_lib_math_constants",
|
|
|
|
|
"values": {"c++20": 201907},
|
|
|
|
|
"headers": ["numbers"],
|
2020-12-08 15:42:33 -05:00
|
|
|
|
},
|
|
|
|
|
{
|
2020-09-21 10:54:16 -04:00
|
|
|
|
"name": "__cpp_lib_math_special_functions",
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"values": {"c++17": 201603},
|
2020-09-21 10:54:16 -04:00
|
|
|
|
"headers": ["cmath"],
|
|
|
|
|
"unimplemented": True,
|
[libcxx] Add mdspan/extents
This patch adds std::extents. extents is one of the core classes used by std::mdspan. It describes a multi-dimensional index space with a mix of compile time and runtime sizes. Furthermore, it is templated on the index type used to describe the multi-dimensional index space.
The class is designed to be highly optimizable in performance critical code sections, and is fully useable in constant expressions contexts.
Testing of this class tends to be somewhat combinatorical, due to the large number of possible corner cases involved in situations where we have both runtime and compile time extents. To add to this, the class is designed to be interoperable (in particular constructible) from arguments which only need to be convertible to the index_type, but are otherwise arbitrary user types. For a larger discussion on the design of this class refer to: https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p0009r18.html
Co-authored-by: Damien L-G <dalg24@gmail.com>
Reviewed By: ldionne, #libc
Spies: libcxx-commits, H-G-Hristov, tschuett, philnik, arichardson, Mordante, crtrott
Differential Revision: https://reviews.llvm.org/D148067
2023-05-16 12:38:11 -07:00
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_mdspan",
|
2024-07-08 19:35:31 +02:00
|
|
|
|
"values": {
|
|
|
|
|
"c++23": 202207,
|
2024-07-15 23:23:34 +08:00
|
|
|
|
"c++26": 202406, # P2389R2 dextents Index Type Parameter
|
2024-07-08 19:35:31 +02:00
|
|
|
|
},
|
[libcxx] Add mdspan/extents
This patch adds std::extents. extents is one of the core classes used by std::mdspan. It describes a multi-dimensional index space with a mix of compile time and runtime sizes. Furthermore, it is templated on the index type used to describe the multi-dimensional index space.
The class is designed to be highly optimizable in performance critical code sections, and is fully useable in constant expressions contexts.
Testing of this class tends to be somewhat combinatorical, due to the large number of possible corner cases involved in situations where we have both runtime and compile time extents. To add to this, the class is designed to be interoperable (in particular constructible) from arguments which only need to be convertible to the index_type, but are otherwise arbitrary user types. For a larger discussion on the design of this class refer to: https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p0009r18.html
Co-authored-by: Damien L-G <dalg24@gmail.com>
Reviewed By: ldionne, #libc
Spies: libcxx-commits, H-G-Hristov, tschuett, philnik, arichardson, Mordante, crtrott
Differential Revision: https://reviews.llvm.org/D148067
2023-05-16 12:38:11 -07:00
|
|
|
|
"headers": ["mdspan"],
|
2020-12-08 15:42:33 -05:00
|
|
|
|
},
|
|
|
|
|
{
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"name": "__cpp_lib_memory_resource",
|
|
|
|
|
"values": {"c++17": 201603},
|
|
|
|
|
"headers": ["memory_resource"],
|
2023-11-24 23:45:17 +01:00
|
|
|
|
"test_suite_guard": "!defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_PMR",
|
|
|
|
|
"libcxx_guard": "_LIBCPP_AVAILABILITY_HAS_PMR",
|
2021-12-30 23:28:12 -05:00
|
|
|
|
},
|
2024-06-12 19:01:27 +02:00
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_modules",
|
|
|
|
|
"values": {"c++23": 202207},
|
|
|
|
|
"headers": [],
|
|
|
|
|
},
|
2021-12-30 23:28:12 -05:00
|
|
|
|
{
|
2023-03-01 23:41:36 +05:30
|
|
|
|
"name": "__cpp_lib_move_iterator_concept",
|
|
|
|
|
"values": {"c++20": 202207},
|
|
|
|
|
"headers": ["iterator"],
|
|
|
|
|
},
|
|
|
|
|
{
|
2021-12-30 23:28:12 -05:00
|
|
|
|
"name": "__cpp_lib_move_only_function",
|
2023-05-17 17:54:53 +02:00
|
|
|
|
"values": {"c++23": 202110},
|
2021-12-30 23:28:12 -05:00
|
|
|
|
"headers": ["functional"],
|
|
|
|
|
"unimplemented": True,
|
2020-12-08 15:42:33 -05:00
|
|
|
|
},
|
|
|
|
|
{
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"name": "__cpp_lib_node_extract",
|
|
|
|
|
"values": {"c++17": 201606},
|
|
|
|
|
"headers": ["map", "set", "unordered_map", "unordered_set"],
|
2020-12-08 15:42:33 -05:00
|
|
|
|
},
|
|
|
|
|
{
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"name": "__cpp_lib_nonmember_container_access",
|
|
|
|
|
"values": {"c++17": 201411},
|
|
|
|
|
"headers": [
|
|
|
|
|
"array",
|
|
|
|
|
"deque",
|
|
|
|
|
"forward_list",
|
|
|
|
|
"iterator",
|
|
|
|
|
"list",
|
|
|
|
|
"map",
|
|
|
|
|
"regex",
|
|
|
|
|
"set",
|
|
|
|
|
"string",
|
|
|
|
|
"unordered_map",
|
|
|
|
|
"unordered_set",
|
|
|
|
|
"vector",
|
|
|
|
|
],
|
2020-09-21 10:54:16 -04:00
|
|
|
|
},
|
|
|
|
|
{
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"name": "__cpp_lib_not_fn",
|
2023-06-17 12:00:23 +02:00
|
|
|
|
"values": {
|
2023-11-16 10:17:19 +01:00
|
|
|
|
"c++17": 201603,
|
2025-01-10 20:14:14 +01:00
|
|
|
|
"c++26": 202306, # P2714R1 Bind front and back to NTTP callables
|
2023-11-16 10:17:19 +01:00
|
|
|
|
},
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"headers": ["functional"],
|
2020-12-08 15:42:33 -05:00
|
|
|
|
},
|
|
|
|
|
{
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"name": "__cpp_lib_null_iterators",
|
|
|
|
|
"values": {"c++14": 201304},
|
|
|
|
|
"headers": ["iterator"],
|
2020-12-08 15:42:33 -05:00
|
|
|
|
},
|
|
|
|
|
{
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"name": "__cpp_lib_optional",
|
2024-10-26 07:38:52 +08:00
|
|
|
|
"values": {
|
|
|
|
|
"c++17": 201606,
|
|
|
|
|
"c++20": 202106, # P2231R1 Missing constexpr in std::optional and std::variant
|
|
|
|
|
"c++23": 202110, # P0798R8 Monadic operations for std::optional + LWG3621 Remove feature-test macro __cpp_lib_monadic_optional
|
|
|
|
|
},
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"headers": ["optional"],
|
2021-12-30 23:28:12 -05:00
|
|
|
|
},
|
2024-07-08 19:35:31 +02:00
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_optional_range_support",
|
|
|
|
|
"values": {"c++26": 202406}, # P3168R2 Give std::optional Range Support
|
|
|
|
|
"headers": ["optional"],
|
|
|
|
|
"unimplemented": True,
|
|
|
|
|
},
|
2021-12-30 23:28:12 -05:00
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_out_ptr",
|
2023-11-16 10:17:19 +01:00
|
|
|
|
"values": {
|
|
|
|
|
"c++23": 202106,
|
|
|
|
|
"c++26": 202311, # P2833R2 Freestanding Library: inout expected span
|
|
|
|
|
},
|
2021-12-30 23:28:12 -05:00
|
|
|
|
"headers": ["memory"],
|
2021-01-07 18:04:41 -05:00
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_parallel_algorithm",
|
|
|
|
|
"values": {"c++17": 201603},
|
|
|
|
|
"headers": ["algorithm", "numeric"],
|
2020-09-21 10:54:16 -04:00
|
|
|
|
"unimplemented": True,
|
2021-01-07 18:21:07 -05:00
|
|
|
|
},
|
2024-07-08 19:35:31 +02:00
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_philox_engine",
|
|
|
|
|
"values": {
|
|
|
|
|
"c++26": 202406
|
|
|
|
|
}, # P2075R6 Philox as an extension of the C++ RNG engines
|
|
|
|
|
# Note the paper mentions 202310L as value, which differs from the typical procedure.
|
|
|
|
|
"headers": ["random"],
|
|
|
|
|
"unimplemented": True,
|
|
|
|
|
},
|
2021-01-07 18:21:07 -05:00
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_polymorphic_allocator",
|
|
|
|
|
"values": {"c++20": 201902},
|
2022-01-22 15:24:53 -05:00
|
|
|
|
"headers": ["memory_resource"],
|
2023-11-24 23:45:17 +01:00
|
|
|
|
"test_suite_guard": "!defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_PMR",
|
|
|
|
|
"libcxx_guard": "_LIBCPP_AVAILABILITY_HAS_PMR",
|
2020-12-08 15:42:33 -05:00
|
|
|
|
},
|
2023-04-21 08:09:06 +02:00
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_print",
|
2024-04-03 08:21:11 -04:00
|
|
|
|
"values": {
|
|
|
|
|
"c++23": 202207,
|
|
|
|
|
# "c++26": 202403, # P3107R5: Permit an efficient implementation of std::print
|
2024-07-08 19:35:31 +02:00
|
|
|
|
# "c++26": 202406, # P3235R3 std::print more types faster with less memory
|
2024-04-03 08:21:11 -04:00
|
|
|
|
},
|
2023-04-21 08:09:06 +02:00
|
|
|
|
"headers": ["ostream", "print"],
|
2025-02-14 18:27:54 +01:00
|
|
|
|
# Trying to use `std::print` where to_chars floating-point is not
|
|
|
|
|
# available causes compilation errors, even with non floating-point types.
|
|
|
|
|
# https://github.com/llvm/llvm-project/issues/125353
|
|
|
|
|
"test_suite_guard": "!defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_TO_CHARS_FLOATING_POINT",
|
|
|
|
|
"libcxx_guard": "_LIBCPP_AVAILABILITY_HAS_TO_CHARS_FLOATING_POINT",
|
2023-04-21 08:09:06 +02:00
|
|
|
|
},
|
2020-12-08 15:42:33 -05:00
|
|
|
|
{
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"name": "__cpp_lib_quoted_string_io",
|
|
|
|
|
"values": {"c++14": 201304},
|
|
|
|
|
"headers": ["iomanip"],
|
2024-11-06 10:39:19 +01:00
|
|
|
|
"test_suite_guard": "!defined(_LIBCPP_VERSION) || _LIBCPP_HAS_LOCALIZATION",
|
|
|
|
|
"libcxx_guard": "_LIBCPP_HAS_LOCALIZATION",
|
2021-01-07 18:04:41 -05:00
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_ranges",
|
2024-07-08 19:35:31 +02:00
|
|
|
|
"values": {
|
2024-08-28 20:55:44 +08:00
|
|
|
|
"c++20": 202110, # P2415R2 What is a view?
|
|
|
|
|
"c++23": 202406, # P2997R1 Removing the common reference requirement from the indirectly invocable concepts (implemented as a DR against C++20)
|
2024-07-08 19:35:31 +02:00
|
|
|
|
},
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"headers": ["algorithm", "functional", "iterator", "memory", "ranges"],
|
2023-02-25 10:26:28 +01:00
|
|
|
|
},
|
2023-11-16 10:17:19 +01:00
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_ranges_as_const",
|
|
|
|
|
"values": {
|
|
|
|
|
"c++23": 202207 # P2278R4 cbegin should always return a constant iterator
|
|
|
|
|
# 202311 # DR P2836R1 std::basic_const_iterator should follow its underlying type’s convertibility
|
|
|
|
|
},
|
|
|
|
|
"headers": ["ranges"],
|
|
|
|
|
"unimplemented": True,
|
|
|
|
|
},
|
2023-02-25 10:26:28 +01:00
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_ranges_as_rvalue",
|
2023-05-17 17:54:53 +02:00
|
|
|
|
"values": {"c++23": 202207},
|
2023-02-25 10:26:28 +01:00
|
|
|
|
"headers": ["ranges"],
|
2022-02-09 00:07:14 +01:00
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_ranges_chunk",
|
2023-05-17 17:54:53 +02:00
|
|
|
|
"values": {"c++23": 202202},
|
2022-02-09 00:07:14 +01:00
|
|
|
|
"headers": ["ranges"],
|
|
|
|
|
"unimplemented": True,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_ranges_chunk_by",
|
2023-05-17 17:54:53 +02:00
|
|
|
|
"values": {"c++23": 202202},
|
2022-02-09 00:07:14 +01:00
|
|
|
|
"headers": ["ranges"],
|
|
|
|
|
},
|
2024-04-03 08:21:11 -04:00
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_ranges_concat",
|
|
|
|
|
"values": {"c++26": 202403}, # P2542R8: views::concat
|
|
|
|
|
"headers": ["ranges"],
|
|
|
|
|
"unimplemented": True,
|
|
|
|
|
},
|
2024-02-29 16:06:32 -08:00
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_ranges_contains",
|
|
|
|
|
"values": {"c++23": 202207},
|
|
|
|
|
"headers": ["algorithm"],
|
2024-07-19 09:42:16 -07:00
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_ranges_find_last",
|
|
|
|
|
"values": {"c++23": 202207},
|
|
|
|
|
"headers": ["algorithm"],
|
2024-02-29 16:06:32 -08:00
|
|
|
|
},
|
2022-02-09 00:07:14 +01:00
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_ranges_iota",
|
2023-05-17 17:54:53 +02:00
|
|
|
|
"values": {"c++23": 202202},
|
2022-02-09 00:07:14 +01:00
|
|
|
|
"headers": ["numeric"],
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_ranges_join_with",
|
2023-05-17 17:54:53 +02:00
|
|
|
|
"values": {"c++23": 202202},
|
2022-02-09 00:07:14 +01:00
|
|
|
|
"headers": ["ranges"],
|
|
|
|
|
"unimplemented": True,
|
|
|
|
|
},
|
2023-07-20 20:00:10 +08:00
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_ranges_repeat",
|
2023-11-16 10:17:19 +01:00
|
|
|
|
"values": {"c++23": 202207},
|
2023-07-20 20:00:10 +08:00
|
|
|
|
"headers": ["ranges"],
|
|
|
|
|
},
|
2022-02-09 00:07:14 +01:00
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_ranges_slide",
|
2023-05-17 17:54:53 +02:00
|
|
|
|
"values": {"c++23": 202202},
|
2022-02-09 00:07:14 +01:00
|
|
|
|
"headers": ["ranges"],
|
|
|
|
|
"unimplemented": True,
|
2021-12-30 23:28:12 -05:00
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_ranges_starts_ends_with",
|
2023-05-17 17:54:53 +02:00
|
|
|
|
"values": {"c++23": 202106},
|
2021-12-30 23:28:12 -05:00
|
|
|
|
"headers": ["algorithm"],
|
2022-02-09 00:07:14 +01:00
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_ranges_to_container",
|
2023-05-17 17:54:53 +02:00
|
|
|
|
"values": {"c++23": 202202},
|
2024-05-04 16:23:49 +00:00
|
|
|
|
"headers": ["ranges"],
|
2020-12-08 15:42:33 -05:00
|
|
|
|
},
|
|
|
|
|
{
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"name": "__cpp_lib_ranges_zip",
|
|
|
|
|
"values": {"c++23": 202110},
|
|
|
|
|
"headers": ["ranges", "tuple", "utility"],
|
|
|
|
|
"unimplemented": True,
|
2022-02-09 00:07:14 +01:00
|
|
|
|
},
|
2023-06-17 12:00:23 +02:00
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_ratio",
|
2023-11-16 10:17:19 +01:00
|
|
|
|
"values": {"c++26": 202306}, # P2734R0 Adding the new SI prefixes
|
2023-06-17 12:00:23 +02:00
|
|
|
|
"headers": ["ratio"],
|
|
|
|
|
},
|
2022-02-09 00:07:14 +01:00
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_raw_memory_algorithms",
|
2023-05-17 17:54:53 +02:00
|
|
|
|
"values": {"c++17": 201606},
|
2022-02-09 00:07:14 +01:00
|
|
|
|
"headers": ["memory"],
|
2021-01-07 18:21:07 -05:00
|
|
|
|
},
|
2023-06-17 12:00:23 +02:00
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_rcu",
|
2023-11-16 10:17:19 +01:00
|
|
|
|
"values": {"c++26": 202306}, # P2545R4 Read-Copy Update (RCU)
|
|
|
|
|
"headers": [
|
|
|
|
|
"rcu" # TODO verify this entry since the paper was underspecified.
|
|
|
|
|
],
|
2023-06-17 12:00:23 +02:00
|
|
|
|
"unimplemented": True,
|
|
|
|
|
},
|
2021-01-07 18:21:07 -05:00
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_reference_from_temporary",
|
|
|
|
|
"values": {"c++23": 202202},
|
|
|
|
|
"headers": ["type_traits"],
|
2022-02-09 00:07:14 +01:00
|
|
|
|
"unimplemented": True,
|
2021-01-07 18:21:07 -05:00
|
|
|
|
},
|
2024-04-03 08:21:11 -04:00
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_reference_wrapper",
|
|
|
|
|
"values": {"c++26": 202403}, # P2944R3: Comparisons for reference_wrapper
|
|
|
|
|
"headers": ["functional"],
|
|
|
|
|
},
|
2021-01-07 18:21:07 -05:00
|
|
|
|
{
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"name": "__cpp_lib_remove_cvref",
|
2023-05-17 17:54:53 +02:00
|
|
|
|
"values": {"c++20": 201711},
|
2021-01-07 18:21:07 -05:00
|
|
|
|
"headers": ["type_traits"],
|
2020-12-08 15:42:33 -05:00
|
|
|
|
},
|
2021-01-07 18:04:41 -05:00
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_result_of_sfinae",
|
|
|
|
|
"values": {"c++14": 201210},
|
|
|
|
|
"headers": ["functional", "type_traits"],
|
2020-12-08 15:42:33 -05:00
|
|
|
|
},
|
2023-05-17 11:09:29 +02:00
|
|
|
|
{
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"name": "__cpp_lib_robust_nonmodifying_seq_ops",
|
|
|
|
|
"values": {"c++14": 201304},
|
|
|
|
|
"headers": ["algorithm"],
|
2020-12-08 15:42:33 -05:00
|
|
|
|
},
|
|
|
|
|
{
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"name": "__cpp_lib_sample",
|
|
|
|
|
"values": {"c++17": 201603},
|
|
|
|
|
"headers": ["algorithm"],
|
2020-12-08 15:42:33 -05:00
|
|
|
|
},
|
2023-11-16 10:17:19 +01:00
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_saturation_arithmetic",
|
|
|
|
|
"values": {"c++26": 202311}, # P0543R3 Saturation arithmetic
|
2024-01-22 06:57:45 +02:00
|
|
|
|
"headers": ["numeric"],
|
2023-11-16 10:17:19 +01:00
|
|
|
|
},
|
2020-12-08 15:42:33 -05:00
|
|
|
|
{
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"name": "__cpp_lib_scoped_lock",
|
|
|
|
|
"values": {"c++17": 201703},
|
|
|
|
|
"headers": ["mutex"],
|
2024-11-06 10:39:19 +01:00
|
|
|
|
"test_suite_guard": "!defined(_LIBCPP_VERSION) || _LIBCPP_HAS_THREADS",
|
|
|
|
|
"libcxx_guard": "_LIBCPP_HAS_THREADS",
|
2021-01-07 18:21:07 -05:00
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_semaphore",
|
|
|
|
|
"values": {"c++20": 201907},
|
|
|
|
|
"headers": ["semaphore"],
|
2024-11-06 10:39:19 +01:00
|
|
|
|
"test_suite_guard": "!defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC)",
|
|
|
|
|
"libcxx_guard": "_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC",
|
2020-12-08 15:42:33 -05:00
|
|
|
|
},
|
2024-07-08 19:35:31 +02:00
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_senders",
|
|
|
|
|
"values": {"c++26": 202406}, # P2300R10 std::execution
|
|
|
|
|
"headers": ["execution"],
|
|
|
|
|
"unimplemented": True,
|
|
|
|
|
},
|
2020-12-08 15:42:33 -05:00
|
|
|
|
{
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"name": "__cpp_lib_shared_mutex",
|
|
|
|
|
"values": {"c++17": 201505},
|
|
|
|
|
"headers": ["shared_mutex"],
|
2025-03-21 11:36:36 +08:00
|
|
|
|
"test_suite_guard": "!defined(_LIBCPP_VERSION) || _LIBCPP_HAS_THREADS",
|
2024-11-06 10:39:19 +01:00
|
|
|
|
"libcxx_guard": "_LIBCPP_HAS_THREADS",
|
2020-12-08 15:42:33 -05:00
|
|
|
|
},
|
|
|
|
|
{
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"name": "__cpp_lib_shared_ptr_arrays",
|
2021-10-26 13:12:12 -04:00
|
|
|
|
"values": {"c++17": 201611, "c++20": 201707},
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"headers": ["memory"],
|
2020-12-08 15:42:33 -05:00
|
|
|
|
},
|
|
|
|
|
{
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"name": "__cpp_lib_shared_ptr_weak_type",
|
|
|
|
|
"values": {"c++17": 201606},
|
|
|
|
|
"headers": ["memory"],
|
2020-12-08 15:42:33 -05:00
|
|
|
|
},
|
|
|
|
|
{
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"name": "__cpp_lib_shared_timed_mutex",
|
|
|
|
|
"values": {"c++14": 201402},
|
|
|
|
|
"headers": ["shared_mutex"],
|
2025-03-21 11:36:36 +08:00
|
|
|
|
"test_suite_guard": "!defined(_LIBCPP_VERSION) || _LIBCPP_HAS_THREADS",
|
2024-11-06 10:39:19 +01:00
|
|
|
|
"libcxx_guard": "_LIBCPP_HAS_THREADS",
|
2021-01-07 18:21:07 -05:00
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_shift",
|
|
|
|
|
"values": {"c++20": 201806},
|
|
|
|
|
"headers": ["algorithm"],
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_smart_ptr_for_overwrite",
|
|
|
|
|
"values": {"c++20": 202002},
|
|
|
|
|
"headers": ["memory"],
|
|
|
|
|
},
|
2023-06-17 12:00:23 +02:00
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_smart_ptr_owner_equality",
|
2023-11-16 10:17:19 +01:00
|
|
|
|
"values": {
|
|
|
|
|
"c++26": 202306 # P1901R2 Enabling the Use of weak_ptr as Keys in Unordered Associative Containers
|
|
|
|
|
},
|
2023-06-17 12:00:23 +02:00
|
|
|
|
"headers": ["memory"],
|
|
|
|
|
"unimplemented": True,
|
|
|
|
|
},
|
2021-01-07 18:21:07 -05:00
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_source_location",
|
|
|
|
|
"values": {"c++20": 201907},
|
|
|
|
|
"headers": ["source_location"],
|
2020-12-08 15:42:33 -05:00
|
|
|
|
},
|
|
|
|
|
{
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"name": "__cpp_lib_span",
|
2023-11-16 10:17:19 +01:00
|
|
|
|
"values": {
|
|
|
|
|
"c++20": 202002,
|
|
|
|
|
# "c++26": 202311, # P2821R5 span.at()
|
|
|
|
|
# 202311 # P2833R2 Freestanding Library: inout expected span
|
|
|
|
|
},
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"headers": ["span"],
|
2021-12-30 23:28:12 -05:00
|
|
|
|
},
|
2024-01-05 11:41:22 +02:00
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_span_at",
|
|
|
|
|
"values": {"c++26": 202311}, # P2821R3 span.at()
|
|
|
|
|
"headers": ["span"],
|
|
|
|
|
},
|
2023-11-16 10:17:19 +01:00
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_span_initializer_list",
|
|
|
|
|
"values": {"c++26": 202311}, # P2447R6 std::span over an initializer list
|
|
|
|
|
"headers": ["span"],
|
|
|
|
|
},
|
2021-12-30 23:28:12 -05:00
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_spanstream",
|
2023-05-17 17:54:53 +02:00
|
|
|
|
"values": {"c++23": 202106},
|
2021-12-30 23:28:12 -05:00
|
|
|
|
"headers": ["spanstream"],
|
|
|
|
|
"unimplemented": True,
|
2021-01-07 18:21:07 -05:00
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_ssize",
|
|
|
|
|
"values": {"c++20": 201902},
|
|
|
|
|
"headers": ["iterator"],
|
2021-01-08 18:40:42 +01:00
|
|
|
|
},
|
2023-06-17 12:00:23 +02:00
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_sstream_from_string_view",
|
2023-11-16 10:17:19 +01:00
|
|
|
|
"values": {
|
|
|
|
|
"c++26": 202306 # P2495R3 Interfacing stringstreams with string_view
|
|
|
|
|
},
|
2023-06-17 12:00:23 +02:00
|
|
|
|
"headers": ["sstream"],
|
|
|
|
|
},
|
2021-01-08 18:40:42 +01:00
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_stacktrace",
|
2023-05-17 17:54:53 +02:00
|
|
|
|
"values": {"c++23": 202011},
|
2021-01-08 18:40:42 +01:00
|
|
|
|
"headers": ["stacktrace"],
|
|
|
|
|
"unimplemented": True,
|
2021-01-07 18:21:07 -05:00
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_starts_ends_with",
|
|
|
|
|
"values": {"c++20": 201711},
|
|
|
|
|
"headers": ["string", "string_view"],
|
2021-01-08 18:40:42 +01:00
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_stdatomic_h",
|
2023-05-17 17:54:53 +02:00
|
|
|
|
"values": {"c++23": 202011},
|
2021-01-08 18:40:42 +01:00
|
|
|
|
"headers": ["stdatomic.h"],
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_string_contains",
|
2023-05-17 17:54:53 +02:00
|
|
|
|
"values": {"c++23": 202011},
|
2021-01-08 18:40:42 +01:00
|
|
|
|
"headers": ["string", "string_view"],
|
2022-01-06 21:43:26 +01:00
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_string_resize_and_overwrite",
|
2023-05-17 17:54:53 +02:00
|
|
|
|
"values": {"c++23": 202110},
|
2022-01-06 21:43:26 +01:00
|
|
|
|
"headers": ["string"],
|
2020-12-08 15:42:33 -05:00
|
|
|
|
},
|
|
|
|
|
{
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"name": "__cpp_lib_string_udls",
|
|
|
|
|
"values": {"c++14": 201304},
|
|
|
|
|
"headers": ["string"],
|
2020-12-08 15:42:33 -05:00
|
|
|
|
},
|
|
|
|
|
{
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"name": "__cpp_lib_string_view",
|
2024-04-03 08:21:11 -04:00
|
|
|
|
"values": {
|
|
|
|
|
"c++17": 201606,
|
|
|
|
|
"c++20": 201803,
|
2024-07-18 13:26:37 +03:00
|
|
|
|
"c++26": 202403, # P2591R5: Concatenation of strings and string views
|
2024-04-03 08:21:11 -04:00
|
|
|
|
},
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"headers": ["string", "string_view"],
|
2021-01-07 18:21:07 -05:00
|
|
|
|
},
|
2023-06-17 12:00:23 +02:00
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_submdspan",
|
2024-04-03 08:21:11 -04:00
|
|
|
|
"values": {
|
|
|
|
|
"c++26": 202306, # P2630R4: submdspan
|
|
|
|
|
# "c++26": 202403, # P2642R6: Padded mdspan layouts
|
|
|
|
|
},
|
2023-06-17 12:00:23 +02:00
|
|
|
|
"headers": ["mdspan"],
|
|
|
|
|
"unimplemented": True,
|
|
|
|
|
},
|
2021-01-07 18:21:07 -05:00
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_syncbuf",
|
|
|
|
|
"values": {"c++20": 201803},
|
|
|
|
|
"headers": ["syncstream"],
|
2025-01-24 09:34:42 +01:00
|
|
|
|
"test_suite_guard": "!defined(_LIBCPP_VERSION) || _LIBCPP_HAS_EXPERIMENTAL_SYNCSTREAM",
|
|
|
|
|
"libcxx_guard": "_LIBCPP_HAS_EXPERIMENTAL_SYNCSTREAM",
|
2021-01-07 18:04:41 -05:00
|
|
|
|
},
|
2023-06-17 12:00:23 +02:00
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_text_encoding",
|
2023-11-16 10:17:19 +01:00
|
|
|
|
"values": {
|
|
|
|
|
"c++26": 202306 # P1885R12 Naming Text Encodings to Demystify Them
|
|
|
|
|
},
|
2023-06-17 12:00:23 +02:00
|
|
|
|
"headers": ["text_encoding"],
|
|
|
|
|
"unimplemented": True,
|
|
|
|
|
},
|
2021-01-07 18:04:41 -05:00
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_three_way_comparison",
|
2024-07-25 18:37:36 +02:00
|
|
|
|
"values": {"c++20": 201907},
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"headers": ["compare"],
|
2021-01-07 18:21:07 -05:00
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_to_address",
|
|
|
|
|
"values": {"c++20": 201711},
|
|
|
|
|
"headers": ["memory"],
|
2020-12-08 15:42:33 -05:00
|
|
|
|
},
|
|
|
|
|
{
|
2020-09-21 10:54:16 -04:00
|
|
|
|
"name": "__cpp_lib_to_array",
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"values": {"c++20": 201907},
|
2020-09-21 10:54:16 -04:00
|
|
|
|
"headers": ["array"],
|
2020-12-08 15:42:33 -05:00
|
|
|
|
},
|
|
|
|
|
{
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"name": "__cpp_lib_to_chars",
|
2023-06-17 12:00:23 +02:00
|
|
|
|
"values": {
|
2023-11-16 10:17:19 +01:00
|
|
|
|
"c++17": 201611,
|
|
|
|
|
"c++26": 202306, # P2497R0 Testing for success or failure of <charconv> functions
|
|
|
|
|
},
|
2021-11-19 09:52:28 -05:00
|
|
|
|
"headers": ["charconv"],
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"unimplemented": True,
|
2021-03-05 09:19:39 +01:00
|
|
|
|
},
|
2023-06-17 12:00:23 +02:00
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_to_string",
|
2024-05-28 12:15:50 -07:00
|
|
|
|
"values": {"c++26": 202306}, # P2587R3 to_string or not to_string
|
2023-06-17 12:00:23 +02:00
|
|
|
|
"headers": ["string"],
|
|
|
|
|
"unimplemented": True,
|
|
|
|
|
},
|
2021-03-05 09:19:39 +01:00
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_to_underlying",
|
2023-05-17 17:54:53 +02:00
|
|
|
|
"values": {"c++23": 202102},
|
2021-03-05 09:19:39 +01:00
|
|
|
|
"headers": ["utility"],
|
2020-12-08 15:42:33 -05:00
|
|
|
|
},
|
|
|
|
|
{
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"name": "__cpp_lib_transformation_trait_aliases",
|
|
|
|
|
"values": {"c++14": 201304},
|
|
|
|
|
"headers": ["type_traits"],
|
2020-12-08 15:42:33 -05:00
|
|
|
|
},
|
|
|
|
|
{
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"name": "__cpp_lib_transparent_operators",
|
|
|
|
|
"values": {"c++14": 201210, "c++17": 201510},
|
2021-01-07 18:21:07 -05:00
|
|
|
|
"headers": ["functional", "memory"],
|
2020-12-08 15:42:33 -05:00
|
|
|
|
},
|
|
|
|
|
{
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"name": "__cpp_lib_tuple_element_t",
|
|
|
|
|
"values": {"c++14": 201402},
|
|
|
|
|
"headers": ["tuple"],
|
2020-12-08 15:42:33 -05:00
|
|
|
|
},
|
2023-11-16 10:17:19 +01:00
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_tuple_like",
|
|
|
|
|
"values": {
|
|
|
|
|
"c++23": 202207, # P2165R4 Compatibility between tuple, pair and tuple-like objects
|
2024-02-19 09:56:06 +02:00
|
|
|
|
"c++26": 202311, # P2819R2 Add tuple protocol to complex (implemented)
|
2023-11-16 10:17:19 +01:00
|
|
|
|
},
|
|
|
|
|
"headers": ["map", "tuple", "unordered_map", "utility"],
|
|
|
|
|
"unimplemented": True,
|
|
|
|
|
},
|
2020-12-08 15:42:33 -05:00
|
|
|
|
{
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"name": "__cpp_lib_tuples_by_type",
|
|
|
|
|
"values": {"c++14": 201304},
|
|
|
|
|
"headers": ["tuple", "utility"],
|
2021-12-30 23:28:12 -05:00
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_type_identity",
|
|
|
|
|
"values": {"c++20": 201806},
|
|
|
|
|
"headers": ["type_traits"],
|
2020-12-08 15:42:33 -05:00
|
|
|
|
},
|
|
|
|
|
{
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"name": "__cpp_lib_type_trait_variable_templates",
|
|
|
|
|
"values": {"c++17": 201510},
|
|
|
|
|
"headers": ["type_traits"],
|
2020-12-08 15:42:33 -05:00
|
|
|
|
},
|
|
|
|
|
{
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"name": "__cpp_lib_uncaught_exceptions",
|
|
|
|
|
"values": {"c++17": 201411},
|
|
|
|
|
"headers": ["exception"],
|
2020-12-08 15:42:33 -05:00
|
|
|
|
},
|
|
|
|
|
{
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"name": "__cpp_lib_unordered_map_try_emplace",
|
|
|
|
|
"values": {"c++17": 201411},
|
|
|
|
|
"headers": ["unordered_map"],
|
2022-02-09 00:07:14 +01:00
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_unreachable",
|
2023-05-17 17:54:53 +02:00
|
|
|
|
"values": {"c++23": 202202},
|
2022-02-09 00:07:14 +01:00
|
|
|
|
"headers": ["utility"],
|
2021-01-07 18:21:07 -05:00
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"name": "__cpp_lib_unwrap_ref",
|
|
|
|
|
"values": {"c++20": 201811},
|
|
|
|
|
"headers": ["functional"],
|
2020-12-08 15:42:33 -05:00
|
|
|
|
},
|
|
|
|
|
{
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"name": "__cpp_lib_variant",
|
2024-01-21 07:16:51 +02:00
|
|
|
|
"values": {
|
|
|
|
|
"c++17": 202102, # std::visit for classes derived from std::variant
|
2024-10-26 07:38:52 +08:00
|
|
|
|
"c++20": 202106, # P2231R1 Missing constexpr in std::optional and std::variant
|
|
|
|
|
"c++26": 202306, # P2637R3 Member visit
|
2024-01-21 07:16:51 +02:00
|
|
|
|
},
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"headers": ["variant"],
|
2020-12-08 15:42:33 -05:00
|
|
|
|
},
|
|
|
|
|
{
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"name": "__cpp_lib_void_t",
|
|
|
|
|
"values": {"c++17": 201411},
|
|
|
|
|
"headers": ["type_traits"],
|
|
|
|
|
},
|
2023-05-17 11:09:29 +02:00
|
|
|
|
]
|
2021-01-07 18:04:41 -05:00
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
assert feature_test_macros == sorted(feature_test_macros, key=lambda tc: tc["name"])
|
2024-04-03 08:21:11 -04:00
|
|
|
|
for tc in feature_test_macros:
|
|
|
|
|
assert tc["headers"] == sorted(tc["headers"]), tc
|
|
|
|
|
assert ("libcxx_guard" in tc) == ("test_suite_guard" in tc), tc
|
|
|
|
|
valid_keys = ["name", "values", "headers", "libcxx_guard", "test_suite_guard", "unimplemented"]
|
|
|
|
|
assert all(key in valid_keys for key in tc.keys()), tc
|
2019-01-16 01:37:43 +00:00
|
|
|
|
|
2020-10-20 15:52:57 -04:00
|
|
|
|
# Map from each header to the Lit annotations that should be used for
|
|
|
|
|
# tests that include that header.
|
|
|
|
|
#
|
2021-11-19 09:50:05 -05:00
|
|
|
|
# For example, when threads are not supported, any test that includes
|
|
|
|
|
# <thread> should be marked as UNSUPPORTED, because including <thread>
|
|
|
|
|
# is a hard error in that case.
|
2020-10-20 15:52:57 -04:00
|
|
|
|
lit_markup = {
|
2022-05-26 11:49:47 -04:00
|
|
|
|
"barrier": ["UNSUPPORTED: no-threads"],
|
|
|
|
|
"filesystem": ["UNSUPPORTED: no-filesystem"],
|
2023-06-17 12:00:23 +02:00
|
|
|
|
"fstream": ["UNSUPPORTED: no-localization"],
|
2022-05-26 11:49:47 -04:00
|
|
|
|
"iomanip": ["UNSUPPORTED: no-localization"],
|
|
|
|
|
"ios": ["UNSUPPORTED: no-localization"],
|
|
|
|
|
"iostream": ["UNSUPPORTED: no-localization"],
|
|
|
|
|
"istream": ["UNSUPPORTED: no-localization"],
|
|
|
|
|
"latch": ["UNSUPPORTED: no-threads"],
|
|
|
|
|
"locale": ["UNSUPPORTED: no-localization"],
|
|
|
|
|
"mutex": ["UNSUPPORTED: no-threads"],
|
|
|
|
|
"ostream": ["UNSUPPORTED: no-localization"],
|
2023-08-04 00:23:41 -07:00
|
|
|
|
"print": ["UNSUPPORTED: no-filesystem"],
|
2022-05-26 11:49:47 -04:00
|
|
|
|
"regex": ["UNSUPPORTED: no-localization"],
|
|
|
|
|
"semaphore": ["UNSUPPORTED: no-threads"],
|
|
|
|
|
"shared_mutex": ["UNSUPPORTED: no-threads"],
|
2023-06-17 12:00:23 +02:00
|
|
|
|
"sstream": ["UNSUPPORTED: no-localization"],
|
2023-09-05 20:10:38 +02:00
|
|
|
|
"syncstream": ["UNSUPPORTED: no-localization"],
|
2022-05-26 11:49:47 -04:00
|
|
|
|
"stdatomic.h": ["UNSUPPORTED: no-threads"],
|
2023-05-17 13:22:23 +01:00
|
|
|
|
"stop_token": ["UNSUPPORTED: no-threads"],
|
2022-05-26 11:49:47 -04:00
|
|
|
|
"thread": ["UNSUPPORTED: no-threads"],
|
2020-10-20 15:52:57 -04:00
|
|
|
|
}
|
|
|
|
|
|
2023-05-17 11:09:29 +02:00
|
|
|
|
|
2019-01-16 01:37:43 +00:00
|
|
|
|
def get_std_dialects():
|
2023-05-20 12:38:57 +02:00
|
|
|
|
std_dialects = ["c++14", "c++17", "c++20", "c++23", "c++26"]
|
2019-01-16 01:37:43 +00:00
|
|
|
|
return list(std_dialects)
|
2023-05-17 11:09:29 +02:00
|
|
|
|
|
2019-01-16 01:37:43 +00:00
|
|
|
|
|
|
|
|
|
def get_first_std(d):
|
|
|
|
|
for s in get_std_dialects():
|
|
|
|
|
if s in d.keys():
|
|
|
|
|
return s
|
|
|
|
|
return None
|
|
|
|
|
|
2023-05-17 11:09:29 +02:00
|
|
|
|
|
2019-01-16 01:37:43 +00:00
|
|
|
|
def get_last_std(d):
|
|
|
|
|
rev_dialects = get_std_dialects()
|
|
|
|
|
rev_dialects.reverse()
|
|
|
|
|
for s in rev_dialects:
|
|
|
|
|
if s in d.keys():
|
|
|
|
|
return s
|
|
|
|
|
return None
|
2023-05-17 11:09:29 +02:00
|
|
|
|
|
2019-01-16 01:37:43 +00:00
|
|
|
|
|
|
|
|
|
def get_std_before(d, std):
|
|
|
|
|
std_dialects = get_std_dialects()
|
|
|
|
|
candidates = std_dialects[0 : std_dialects.index(std)]
|
|
|
|
|
candidates.reverse()
|
|
|
|
|
for cand in candidates:
|
|
|
|
|
if cand in d.keys():
|
|
|
|
|
return cand
|
|
|
|
|
return None
|
2023-05-17 11:09:29 +02:00
|
|
|
|
|
2019-01-16 01:37:43 +00:00
|
|
|
|
|
|
|
|
|
def get_value_before(d, std):
|
|
|
|
|
new_std = get_std_before(d, std)
|
|
|
|
|
if new_std is None:
|
|
|
|
|
return None
|
|
|
|
|
return d[new_std]
|
2023-05-17 11:09:29 +02:00
|
|
|
|
|
2019-01-16 01:37:43 +00:00
|
|
|
|
|
|
|
|
|
def get_for_std(d, std):
|
|
|
|
|
# This catches the C++11 case for which there should be no defined feature
|
|
|
|
|
# test macros.
|
|
|
|
|
std_dialects = get_std_dialects()
|
|
|
|
|
if std not in std_dialects:
|
|
|
|
|
return None
|
|
|
|
|
# Find the value for the newest C++ dialect between C++14 and std
|
|
|
|
|
std_list = list(std_dialects[0 : std_dialects.index(std) + 1])
|
|
|
|
|
std_list.reverse()
|
|
|
|
|
for s in std_list:
|
|
|
|
|
if s in d.keys():
|
|
|
|
|
return d[s]
|
|
|
|
|
return None
|
2023-05-17 11:09:29 +02:00
|
|
|
|
|
2019-01-16 01:37:43 +00:00
|
|
|
|
|
2021-01-18 15:17:28 -05:00
|
|
|
|
def get_std_number(std):
|
|
|
|
|
return std.replace("c++", "")
|
2023-05-17 11:09:29 +02:00
|
|
|
|
|
2019-01-16 01:37:43 +00:00
|
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
Functions to produce the <version> header
|
|
|
|
|
"""
|
|
|
|
|
|
2023-05-17 11:09:29 +02:00
|
|
|
|
|
2019-01-16 01:37:43 +00:00
|
|
|
|
def produce_macros_definition_for_std(std):
|
|
|
|
|
result = ""
|
2021-03-18 10:28:56 -04:00
|
|
|
|
indent = 55
|
2019-01-16 01:37:43 +00:00
|
|
|
|
for tc in feature_test_macros:
|
|
|
|
|
if std not in tc["values"]:
|
|
|
|
|
continue
|
|
|
|
|
inner_indent = 1
|
2021-03-30 20:19:12 +02:00
|
|
|
|
if "test_suite_guard" in tc.keys():
|
|
|
|
|
result += "# if %s\n" % tc["libcxx_guard"]
|
2019-01-16 01:37:43 +00:00
|
|
|
|
inner_indent += 2
|
|
|
|
|
if get_value_before(tc["values"], std) is not None:
|
2021-03-30 20:19:12 +02:00
|
|
|
|
assert "test_suite_guard" not in tc.keys()
|
2019-01-16 01:37:43 +00:00
|
|
|
|
result += "# undef %s\n" % tc["name"]
|
|
|
|
|
line = "#%sdefine %s" % ((" " * inner_indent), tc["name"])
|
|
|
|
|
line += " " * (indent - len(line))
|
2021-03-18 10:28:56 -04:00
|
|
|
|
line += " %sL" % tc["values"][std]
|
2019-01-16 01:37:43 +00:00
|
|
|
|
if "unimplemented" in tc.keys():
|
|
|
|
|
line = "// " + line
|
|
|
|
|
result += line
|
|
|
|
|
result += "\n"
|
2021-03-30 20:19:12 +02:00
|
|
|
|
if "test_suite_guard" in tc.keys():
|
2019-01-16 01:37:43 +00:00
|
|
|
|
result += "# endif\n"
|
2021-01-18 15:17:28 -05:00
|
|
|
|
return result.strip()
|
2023-05-17 11:09:29 +02:00
|
|
|
|
|
2021-01-18 15:17:28 -05:00
|
|
|
|
|
|
|
|
|
def produce_macros_definitions():
|
2023-02-14 00:56:09 +01:00
|
|
|
|
macro_definition_template = """#if _LIBCPP_STD_VER >= {std_number}
|
2021-01-18 15:17:28 -05:00
|
|
|
|
{macro_definition}
|
|
|
|
|
#endif"""
|
|
|
|
|
|
|
|
|
|
macros_definitions = []
|
|
|
|
|
for std in get_std_dialects():
|
|
|
|
|
macros_definitions.append(
|
2023-05-17 17:54:53 +02:00
|
|
|
|
macro_definition_template.format(
|
|
|
|
|
std_number=get_std_number(std),
|
2021-01-18 15:17:28 -05:00
|
|
|
|
macro_definition=produce_macros_definition_for_std(std),
|
2023-05-17 11:09:29 +02:00
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
|
2021-01-18 15:17:28 -05:00
|
|
|
|
return "\n\n".join(macros_definitions)
|
|
|
|
|
|
2019-01-16 01:37:43 +00:00
|
|
|
|
|
|
|
|
|
def chunks(l, n):
|
|
|
|
|
"""Yield successive n-sized chunks from l."""
|
|
|
|
|
for i in range(0, len(l), n):
|
|
|
|
|
yield l[i : i + n]
|
2023-05-17 11:09:29 +02:00
|
|
|
|
|
2019-01-16 01:37:43 +00:00
|
|
|
|
|
|
|
|
|
def produce_version_synopsis():
|
|
|
|
|
indent = 56
|
|
|
|
|
header_indent = 56 + len("20XXYYL ")
|
|
|
|
|
result = ""
|
2023-05-17 11:09:29 +02:00
|
|
|
|
|
2019-01-16 01:37:43 +00:00
|
|
|
|
def indent_to(s, val):
|
|
|
|
|
if len(s) >= val:
|
|
|
|
|
return s
|
|
|
|
|
s += " " * (val - len(s))
|
|
|
|
|
return s
|
2023-05-17 11:09:29 +02:00
|
|
|
|
|
2019-01-16 01:37:43 +00:00
|
|
|
|
line = indent_to("Macro name", indent) + "Value"
|
|
|
|
|
line = indent_to(line, header_indent) + "Headers"
|
|
|
|
|
result += line + "\n"
|
|
|
|
|
for tc in feature_test_macros:
|
|
|
|
|
prev_defined_std = get_last_std(tc["values"])
|
|
|
|
|
line = "{name: <{indent}}{value}L ".format(
|
|
|
|
|
name=tc["name"], indent=indent, value=tc["values"][prev_defined_std]
|
|
|
|
|
)
|
|
|
|
|
headers = list(tc["headers"])
|
|
|
|
|
headers.remove("version")
|
|
|
|
|
for chunk in chunks(headers, 3):
|
|
|
|
|
line = indent_to(line, header_indent)
|
|
|
|
|
chunk = ["<%s>" % header for header in chunk]
|
|
|
|
|
line += " ".join(chunk)
|
|
|
|
|
result += line
|
|
|
|
|
result += "\n"
|
|
|
|
|
line = ""
|
|
|
|
|
while True:
|
|
|
|
|
prev_defined_std = get_std_before(tc["values"], prev_defined_std)
|
|
|
|
|
if prev_defined_std is None:
|
|
|
|
|
break
|
|
|
|
|
result += "%s%sL // %s\n" % (
|
|
|
|
|
indent_to("", indent),
|
|
|
|
|
tc["values"][prev_defined_std],
|
|
|
|
|
prev_defined_std.replace("c++", "C++"),
|
|
|
|
|
)
|
|
|
|
|
return result
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def produce_version_header():
|
2021-10-01 12:59:24 -04:00
|
|
|
|
template = """// -*- C++ -*-
|
2021-10-04 13:34:26 -04:00
|
|
|
|
//===----------------------------------------------------------------------===//
|
2019-01-16 01:37:43 +00:00
|
|
|
|
//
|
2019-01-19 10:56:40 +00:00
|
|
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
|
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
|
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
2019-01-16 01:37:43 +00:00
|
|
|
|
//
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
|
|
#ifndef _LIBCPP_VERSIONH
|
|
|
|
|
#define _LIBCPP_VERSIONH
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
version synopsis
|
|
|
|
|
|
|
|
|
|
{synopsis}
|
|
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
2024-12-21 13:01:48 +01:00
|
|
|
|
#if __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
|
|
|
|
|
# include <__cxx03/version>
|
|
|
|
|
#else
|
|
|
|
|
# include <__config>
|
2019-01-16 01:37:43 +00:00
|
|
|
|
|
2024-12-21 13:01:48 +01:00
|
|
|
|
# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
|
|
|
|
# pragma GCC system_header
|
|
|
|
|
# endif
|
2019-01-16 01:37:43 +00:00
|
|
|
|
|
2021-02-19 14:10:12 +01:00
|
|
|
|
// clang-format off
|
|
|
|
|
|
2021-01-18 15:17:28 -05:00
|
|
|
|
{cxx_macros}
|
2021-01-08 18:40:42 +01:00
|
|
|
|
|
2024-12-21 13:01:48 +01:00
|
|
|
|
#endif // __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
|
|
|
|
|
|
2021-02-19 14:10:12 +01:00
|
|
|
|
// clang-format on
|
|
|
|
|
|
2019-01-16 01:37:43 +00:00
|
|
|
|
#endif // _LIBCPP_VERSIONH
|
2021-10-01 12:59:24 -04:00
|
|
|
|
"""
|
2020-10-13 09:16:40 -04:00
|
|
|
|
|
|
|
|
|
version_str = template.format(
|
2019-01-16 01:37:43 +00:00
|
|
|
|
synopsis=produce_version_synopsis().strip(),
|
2021-01-18 15:17:28 -05:00
|
|
|
|
cxx_macros=produce_macros_definitions(),
|
|
|
|
|
)
|
2020-10-13 09:16:40 -04:00
|
|
|
|
version_header_path = os.path.join(include_path, "version")
|
2020-12-11 14:31:54 -05:00
|
|
|
|
with open(version_header_path, "w", newline="\n") as f:
|
2020-10-13 09:16:40 -04:00
|
|
|
|
f.write(version_str)
|
|
|
|
|
|
|
|
|
|
|
2019-01-16 01:37:43 +00:00
|
|
|
|
"""
|
|
|
|
|
Functions to produce test files
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
test_types = {
|
|
|
|
|
"undefined": """
|
2025-04-12 14:20:01 +02:00
|
|
|
|
# ifdef {name}
|
|
|
|
|
# error "{name} should not be defined before {std_first}"
|
|
|
|
|
# endif
|
2019-01-16 01:37:43 +00:00
|
|
|
|
""",
|
2021-03-30 20:19:12 +02:00
|
|
|
|
"test_suite_guard": """
|
2025-04-12 14:20:01 +02:00
|
|
|
|
# if {test_suite_guard}
|
|
|
|
|
# ifndef {name}
|
|
|
|
|
# error "{name} should be defined in {std}"
|
|
|
|
|
# endif
|
|
|
|
|
# if {name} != {value}
|
|
|
|
|
# error "{name} should have the value {value} in {std}"
|
|
|
|
|
# endif
|
|
|
|
|
# else
|
|
|
|
|
# ifdef {name}
|
|
|
|
|
# error "{name} should not be defined when the requirement '{test_suite_guard}' is not met!"
|
|
|
|
|
# endif
|
|
|
|
|
# endif
|
2019-01-16 01:37:43 +00:00
|
|
|
|
""",
|
|
|
|
|
"unimplemented": """
|
2025-04-12 14:20:01 +02:00
|
|
|
|
# if !defined(_LIBCPP_VERSION)
|
|
|
|
|
# ifndef {name}
|
|
|
|
|
# error "{name} should be defined in {std}"
|
|
|
|
|
# endif
|
|
|
|
|
# if {name} != {value}
|
|
|
|
|
# error "{name} should have the value {value} in {std}"
|
|
|
|
|
# endif
|
|
|
|
|
# else
|
|
|
|
|
# ifdef {name}
|
|
|
|
|
# error "{name} should not be defined because it is unimplemented in libc++!"
|
|
|
|
|
# endif
|
|
|
|
|
# endif
|
2019-01-16 01:37:43 +00:00
|
|
|
|
""",
|
2021-01-07 18:04:41 -05:00
|
|
|
|
"defined": """
|
2025-04-12 14:20:01 +02:00
|
|
|
|
# ifndef {name}
|
|
|
|
|
# error "{name} should be defined in {std}"
|
|
|
|
|
# endif
|
|
|
|
|
# if {name} != {value}
|
|
|
|
|
# error "{name} should have the value {value} in {std}"
|
|
|
|
|
# endif
|
2019-01-16 01:37:43 +00:00
|
|
|
|
""",
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-17 11:09:29 +02:00
|
|
|
|
|
2019-01-16 01:37:43 +00:00
|
|
|
|
def generate_std_test(test_list, std):
|
|
|
|
|
result = ""
|
|
|
|
|
for tc in test_list:
|
|
|
|
|
val = get_for_std(tc["values"], std)
|
|
|
|
|
if val is not None:
|
|
|
|
|
val = "%sL" % val
|
|
|
|
|
if val is None:
|
|
|
|
|
result += test_types["undefined"].format(
|
|
|
|
|
name=tc["name"], std_first=get_first_std(tc["values"])
|
2023-05-17 11:09:29 +02:00
|
|
|
|
)
|
2019-01-16 01:37:43 +00:00
|
|
|
|
elif "unimplemented" in tc.keys():
|
|
|
|
|
result += test_types["unimplemented"].format(
|
|
|
|
|
name=tc["name"], value=val, std=std
|
|
|
|
|
)
|
2021-03-30 20:19:12 +02:00
|
|
|
|
elif "test_suite_guard" in tc.keys():
|
|
|
|
|
result += test_types["test_suite_guard"].format(
|
|
|
|
|
name=tc["name"],
|
|
|
|
|
value=val,
|
|
|
|
|
std=std,
|
|
|
|
|
test_suite_guard=tc["test_suite_guard"],
|
|
|
|
|
)
|
2019-01-16 01:37:43 +00:00
|
|
|
|
else:
|
|
|
|
|
result += test_types["defined"].format(name=tc["name"], value=val, std=std)
|
2021-01-18 15:17:28 -05:00
|
|
|
|
return result.strip()
|
2023-05-17 11:09:29 +02:00
|
|
|
|
|
2021-01-18 15:17:28 -05:00
|
|
|
|
|
|
|
|
|
def generate_std_tests(test_list):
|
|
|
|
|
std_tests_template = """#if TEST_STD_VER < {first_std_number}
|
|
|
|
|
|
|
|
|
|
{pre_std_test}
|
|
|
|
|
|
|
|
|
|
{other_std_tests}
|
|
|
|
|
|
|
|
|
|
#elif TEST_STD_VER > {penultimate_std_number}
|
|
|
|
|
|
|
|
|
|
{last_std_test}
|
|
|
|
|
|
|
|
|
|
#endif // TEST_STD_VER > {penultimate_std_number}"""
|
|
|
|
|
|
|
|
|
|
std_dialects = get_std_dialects()
|
|
|
|
|
|
|
|
|
|
other_std_tests = []
|
|
|
|
|
for std in std_dialects[:-1]:
|
|
|
|
|
other_std_tests.append("#elif TEST_STD_VER == " + get_std_number(std))
|
|
|
|
|
other_std_tests.append(generate_std_test(test_list, std))
|
|
|
|
|
|
|
|
|
|
std_tests = std_tests_template.format(
|
|
|
|
|
first_std_number=get_std_number(std_dialects[0]),
|
|
|
|
|
pre_std_test=generate_std_test(test_list, "c++11"),
|
|
|
|
|
other_std_tests="\n\n".join(other_std_tests),
|
|
|
|
|
penultimate_std_number=get_std_number(std_dialects[-2]),
|
|
|
|
|
last_std_test=generate_std_test(test_list, std_dialects[-1]),
|
|
|
|
|
)
|
2023-05-17 11:09:29 +02:00
|
|
|
|
|
2021-01-18 15:17:28 -05:00
|
|
|
|
return std_tests
|
|
|
|
|
|
2019-01-16 01:37:43 +00:00
|
|
|
|
|
|
|
|
|
def generate_synopsis(test_list):
|
|
|
|
|
max_name_len = max([len(tc["name"]) for tc in test_list])
|
|
|
|
|
indent = max_name_len + 8
|
2023-05-17 11:09:29 +02:00
|
|
|
|
|
2019-01-16 01:37:43 +00:00
|
|
|
|
def mk_line(prefix, suffix):
|
|
|
|
|
return "{prefix: <{max_len}}{suffix}\n".format(
|
|
|
|
|
prefix=prefix, suffix=suffix, max_len=indent
|
|
|
|
|
)
|
2023-05-17 11:09:29 +02:00
|
|
|
|
|
2019-01-16 01:37:43 +00:00
|
|
|
|
result = ""
|
|
|
|
|
result += mk_line("/* Constant", "Value")
|
|
|
|
|
for tc in test_list:
|
|
|
|
|
prefix = " %s" % tc["name"]
|
|
|
|
|
for std in [s for s in get_std_dialects() if s in tc["values"].keys()]:
|
|
|
|
|
result += mk_line(
|
|
|
|
|
prefix, "%sL [%s]" % (tc["values"][std], std.replace("c++", "C++"))
|
2023-05-17 11:09:29 +02:00
|
|
|
|
)
|
2019-01-16 01:37:43 +00:00
|
|
|
|
prefix = ""
|
|
|
|
|
result += "*/"
|
|
|
|
|
return result
|
|
|
|
|
|
2023-05-17 11:09:29 +02:00
|
|
|
|
|
2019-01-16 01:37:43 +00:00
|
|
|
|
def produce_tests():
|
|
|
|
|
headers = set([h for tc in feature_test_macros for h in tc["headers"]])
|
|
|
|
|
for h in headers:
|
|
|
|
|
test_list = [tc for tc in feature_test_macros if h in tc["headers"]]
|
|
|
|
|
if not has_header(h):
|
|
|
|
|
for tc in test_list:
|
|
|
|
|
assert "unimplemented" in tc.keys()
|
|
|
|
|
continue
|
2020-10-20 15:52:57 -04:00
|
|
|
|
markup = "\n".join("// " + tag for tag in lit_markup.get(h, []))
|
2019-01-16 01:37:43 +00:00
|
|
|
|
test_body = """//===----------------------------------------------------------------------===//
|
|
|
|
|
//
|
2019-01-19 11:38:40 +00:00
|
|
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
|
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
|
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
2019-01-16 01:37:43 +00:00
|
|
|
|
//
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
2025-04-12 14:20:01 +02:00
|
|
|
|
|
2019-01-16 05:43:02 +00:00
|
|
|
|
// WARNING: This test was generated by {script_name}
|
|
|
|
|
// and should not be edited manually.
|
2020-10-20 15:52:57 -04:00
|
|
|
|
{markup}
|
2019-01-16 01:37:43 +00:00
|
|
|
|
// <{header}>
|
|
|
|
|
|
|
|
|
|
// Test the feature test macros defined by <{header}>
|
|
|
|
|
|
2025-04-12 14:20:01 +02:00
|
|
|
|
// clang-format off
|
2019-01-16 01:37:43 +00:00
|
|
|
|
|
|
|
|
|
#include <{header}>
|
|
|
|
|
#include "test_macros.h"
|
|
|
|
|
|
2021-01-18 15:17:28 -05:00
|
|
|
|
{cxx_tests}
|
2019-01-16 01:37:43 +00:00
|
|
|
|
|
2025-04-12 14:20:01 +02:00
|
|
|
|
// clang-format on
|
|
|
|
|
|
2019-01-16 05:43:02 +00:00
|
|
|
|
""".format(
|
|
|
|
|
script_name=script_name,
|
|
|
|
|
header=h,
|
2020-10-20 15:52:57 -04:00
|
|
|
|
markup=("\n{}\n".format(markup) if markup else ""),
|
2021-01-18 15:17:28 -05:00
|
|
|
|
cxx_tests=generate_std_tests(test_list),
|
|
|
|
|
)
|
2022-04-11 10:38:26 -04:00
|
|
|
|
test_name = "{header}.version.compile.pass.cpp".format(header=h)
|
2019-02-02 23:13:49 +00:00
|
|
|
|
out_path = os.path.join(macro_test_path, test_name)
|
2020-12-11 14:31:54 -05:00
|
|
|
|
with open(out_path, "w", newline="\n") as f:
|
2019-01-16 01:37:43 +00:00
|
|
|
|
f.write(test_body)
|
2023-05-17 11:09:29 +02:00
|
|
|
|
|
2019-01-16 01:37:43 +00:00
|
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
Produce documentation for the feature test macros
|
|
|
|
|
"""
|
|
|
|
|
|
2023-05-17 11:09:29 +02:00
|
|
|
|
|
2019-01-16 01:37:43 +00:00
|
|
|
|
def make_widths(grid):
|
|
|
|
|
widths = []
|
|
|
|
|
for i in range(0, len(grid[0])):
|
|
|
|
|
cell_width = 2 + max(
|
|
|
|
|
reduce(lambda x, y: x + y, [[len(row[i])] for row in grid], [])
|
2023-05-17 11:09:29 +02:00
|
|
|
|
)
|
2019-01-16 01:37:43 +00:00
|
|
|
|
widths += [cell_width]
|
|
|
|
|
return widths
|
2023-05-17 11:09:29 +02:00
|
|
|
|
|
2019-01-16 01:37:43 +00:00
|
|
|
|
|
|
|
|
|
def create_table(grid, indent):
|
|
|
|
|
indent_str = " " * indent
|
|
|
|
|
col_widths = make_widths(grid)
|
2020-09-22 08:38:57 -04:00
|
|
|
|
result = [indent_str + add_divider(col_widths, 2)]
|
2019-01-16 01:37:43 +00:00
|
|
|
|
header_flag = 2
|
2019-11-06 16:44:14 +00:00
|
|
|
|
for row_i in range(0, len(grid)):
|
2019-01-16 01:37:43 +00:00
|
|
|
|
row = grid[row_i]
|
2020-09-22 08:38:57 -04:00
|
|
|
|
line = indent_str + " ".join(
|
|
|
|
|
[pad_cell(row[i], col_widths[i]) for i in range(0, len(row))]
|
|
|
|
|
)
|
|
|
|
|
result.append(line.rstrip())
|
2019-01-16 01:37:43 +00:00
|
|
|
|
if row_i == len(grid) - 1:
|
|
|
|
|
header_flag = 2
|
2023-05-20 12:38:57 +02:00
|
|
|
|
if row[0].startswith("**"):
|
|
|
|
|
header_flag += 1
|
|
|
|
|
separator = indent_str + add_divider(col_widths, header_flag)
|
2020-09-22 08:38:57 -04:00
|
|
|
|
result.append(separator.rstrip())
|
2019-01-16 01:37:43 +00:00
|
|
|
|
header_flag = 0
|
2020-09-22 08:38:57 -04:00
|
|
|
|
return "\n".join(result)
|
2023-05-17 11:09:29 +02:00
|
|
|
|
|
2019-01-16 01:37:43 +00:00
|
|
|
|
|
|
|
|
|
def add_divider(widths, header_flag):
|
2023-05-20 12:38:57 +02:00
|
|
|
|
if header_flag == 3:
|
|
|
|
|
return "=".join(["=" * w for w in widths])
|
2019-01-16 01:37:43 +00:00
|
|
|
|
if header_flag == 2:
|
2020-09-22 08:38:57 -04:00
|
|
|
|
return " ".join(["=" * w for w in widths])
|
2019-01-16 01:37:43 +00:00
|
|
|
|
if header_flag == 1:
|
2020-09-22 08:38:57 -04:00
|
|
|
|
return "-".join(["-" * w for w in widths])
|
2019-01-16 01:37:43 +00:00
|
|
|
|
else:
|
2020-09-22 08:38:57 -04:00
|
|
|
|
return " ".join(["-" * w for w in widths])
|
2023-05-17 11:09:29 +02:00
|
|
|
|
|
2019-01-16 01:37:43 +00:00
|
|
|
|
|
|
|
|
|
def pad_cell(s, length, left_align=True):
|
|
|
|
|
padding = (length - len(s)) * " "
|
|
|
|
|
return s + padding
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def get_status_table():
|
|
|
|
|
table = [["Macro Name", "Value"]]
|
|
|
|
|
for std in get_std_dialects():
|
2024-02-11 19:43:34 +01:00
|
|
|
|
table += [["**" + std.replace("c++", "C++") + "**", ""]]
|
2019-01-16 01:37:43 +00:00
|
|
|
|
for tc in feature_test_macros:
|
|
|
|
|
if std not in tc["values"].keys():
|
|
|
|
|
continue
|
|
|
|
|
value = "``%sL``" % tc["values"][std]
|
|
|
|
|
if "unimplemented" in tc.keys():
|
|
|
|
|
value = "*unimplemented*"
|
|
|
|
|
table += [["``%s``" % tc["name"], value]]
|
|
|
|
|
return table
|
2023-05-17 11:09:29 +02:00
|
|
|
|
|
2019-01-16 01:37:43 +00:00
|
|
|
|
|
|
|
|
|
def produce_docs():
|
|
|
|
|
doc_str = """.. _FeatureTestMacroTable:
|
|
|
|
|
|
|
|
|
|
==========================
|
|
|
|
|
Feature Test Macro Support
|
|
|
|
|
==========================
|
|
|
|
|
|
|
|
|
|
.. contents::
|
|
|
|
|
:local:
|
|
|
|
|
|
|
|
|
|
Overview
|
|
|
|
|
========
|
|
|
|
|
|
|
|
|
|
This file documents the feature test macros currently supported by libc++.
|
|
|
|
|
|
|
|
|
|
.. _feature-status:
|
|
|
|
|
|
|
|
|
|
Status
|
|
|
|
|
======
|
|
|
|
|
|
|
|
|
|
.. table:: Current Status
|
2021-10-21 20:06:30 +02:00
|
|
|
|
:name: feature-status-table
|
|
|
|
|
:widths: auto
|
2019-11-06 16:44:14 +00:00
|
|
|
|
|
2019-01-16 01:37:43 +00:00
|
|
|
|
{status_tables}
|
|
|
|
|
|
|
|
|
|
""".format(
|
|
|
|
|
status_tables=create_table(get_status_table(), 4)
|
2023-05-17 11:09:29 +02:00
|
|
|
|
)
|
|
|
|
|
|
2019-01-16 01:37:43 +00:00
|
|
|
|
table_doc_path = os.path.join(docs_path, "FeatureTestMacroTable.rst")
|
2020-12-11 14:31:54 -05:00
|
|
|
|
with open(table_doc_path, "w", newline="\n") as f:
|
2019-01-16 01:37:43 +00:00
|
|
|
|
f.write(doc_str)
|
|
|
|
|
|
|
|
|
|
|
2025-02-10 18:03:44 +01:00
|
|
|
|
Std = NewType("Std", str) # Standard version number
|
|
|
|
|
Ftm = NewType("Ftm", str) # The name of a feature test macro
|
|
|
|
|
Value = NewType("Value", str) # The value of a feature test macro including the L suffix
|
|
|
|
|
|
|
|
|
|
@dataclass
|
|
|
|
|
class Metadata:
|
2025-02-11 20:01:59 +01:00
|
|
|
|
headers: List[str] = None
|
2025-02-10 18:03:44 +01:00
|
|
|
|
test_suite_guard: str = None
|
|
|
|
|
libcxx_guard: str = None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@dataclass
|
|
|
|
|
class VersionHeader:
|
|
|
|
|
value: Value = None
|
|
|
|
|
implemented: bool = None
|
|
|
|
|
need_undef: bool = None
|
|
|
|
|
condition: str = None
|
|
|
|
|
|
|
|
|
|
|
2024-07-05 07:54:34 +02:00
|
|
|
|
def get_ftms(
|
2025-02-10 18:03:44 +01:00
|
|
|
|
data, std_dialects: List[Std], use_implemented_status: bool
|
|
|
|
|
) -> Dict[Ftm, Dict[Std, Optional[Value]]]:
|
2024-07-05 07:54:34 +02:00
|
|
|
|
"""Impementation for FeatureTestMacros.(standard|implemented)_ftms()."""
|
|
|
|
|
result = dict()
|
|
|
|
|
for feature in data:
|
|
|
|
|
last = None
|
|
|
|
|
entry = dict()
|
|
|
|
|
implemented = True
|
|
|
|
|
for std in std_dialects:
|
|
|
|
|
if std not in feature["values"].keys():
|
|
|
|
|
if last == None:
|
|
|
|
|
continue
|
|
|
|
|
else:
|
|
|
|
|
entry[std] = last
|
|
|
|
|
else:
|
|
|
|
|
if implemented:
|
|
|
|
|
values = feature["values"][std]
|
|
|
|
|
assert len(values) > 0, f"{feature['name']}[{std}] has no entries"
|
|
|
|
|
for value in values:
|
|
|
|
|
papers = list(values[value])
|
|
|
|
|
assert (
|
|
|
|
|
len(papers) > 0
|
|
|
|
|
), f"{feature['name']}[{std}][{value}] has no entries"
|
|
|
|
|
for paper in papers:
|
|
|
|
|
if use_implemented_status and not paper["implemented"]:
|
|
|
|
|
implemented = False
|
|
|
|
|
break
|
|
|
|
|
if implemented:
|
|
|
|
|
last = f"{value}L"
|
|
|
|
|
else:
|
|
|
|
|
break
|
|
|
|
|
|
2025-04-11 20:27:29 +02:00
|
|
|
|
if last:
|
|
|
|
|
entry[std] = last
|
2024-07-05 07:54:34 +02:00
|
|
|
|
result[feature["name"]] = entry
|
|
|
|
|
|
|
|
|
|
return result
|
|
|
|
|
|
|
|
|
|
|
2025-02-10 18:03:44 +01:00
|
|
|
|
def generate_version_header_dialect_block(data: Dict[Ftm, VersionHeader]) -> str:
|
2024-08-03 11:16:29 +02:00
|
|
|
|
"""Generates the contents of the version header for a dialect.
|
|
|
|
|
|
|
|
|
|
This generates the contents of a
|
|
|
|
|
#if _LIBCPP_STD_VER >= XY
|
|
|
|
|
#endif // _LIBCPP_STD_VER >= XY
|
|
|
|
|
block.
|
|
|
|
|
"""
|
|
|
|
|
result = ""
|
|
|
|
|
for element in data:
|
|
|
|
|
for ftm, entry in element.items():
|
2025-02-10 18:03:44 +01:00
|
|
|
|
if not entry.implemented:
|
2024-08-03 11:16:29 +02:00
|
|
|
|
# When a FTM is not implemented don't add the guards
|
|
|
|
|
# or undefine the (possibly) defined macro.
|
2025-02-10 18:03:44 +01:00
|
|
|
|
result += f"// define {ftm} {entry.value}\n"
|
2024-08-03 11:16:29 +02:00
|
|
|
|
else:
|
2025-02-10 18:03:44 +01:00
|
|
|
|
need_undef = entry.need_undef
|
|
|
|
|
if entry.condition:
|
|
|
|
|
result += f"# if {entry.condition}\n"
|
|
|
|
|
if entry.need_undef:
|
2024-08-03 11:16:29 +02:00
|
|
|
|
result += f"# undef {ftm}\n"
|
2025-02-10 18:03:44 +01:00
|
|
|
|
result += f"# define {ftm} {entry.value}\n"
|
2024-08-03 11:16:29 +02:00
|
|
|
|
result += f"# endif\n"
|
|
|
|
|
else:
|
2025-02-10 18:03:44 +01:00
|
|
|
|
if entry.need_undef:
|
2024-08-03 11:16:29 +02:00
|
|
|
|
result += f"# undef {ftm}\n"
|
2025-02-10 18:03:44 +01:00
|
|
|
|
result += f"# define {ftm} {entry.value}\n"
|
2024-08-03 11:16:29 +02:00
|
|
|
|
|
|
|
|
|
return result
|
|
|
|
|
|
|
|
|
|
|
2025-02-10 18:03:44 +01:00
|
|
|
|
def generate_version_header_implementation(
|
|
|
|
|
data: Dict[Std, Dict[Ftm, VersionHeader]]
|
|
|
|
|
) -> str:
|
2024-08-03 11:16:29 +02:00
|
|
|
|
"""Generates the body of the version header."""
|
|
|
|
|
|
|
|
|
|
template = """#if _LIBCPP_STD_VER >= {dialect}
|
|
|
|
|
{feature_test_macros}#endif // _LIBCPP_STD_VER >= {dialect}"""
|
|
|
|
|
|
|
|
|
|
result = []
|
|
|
|
|
for std, ftms in data.items():
|
|
|
|
|
result.append(
|
|
|
|
|
template.format(
|
|
|
|
|
dialect=std,
|
|
|
|
|
feature_test_macros=generate_version_header_dialect_block(ftms),
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
return "\n\n".join(result)
|
|
|
|
|
|
|
|
|
|
|
2024-07-05 07:54:34 +02:00
|
|
|
|
class FeatureTestMacros:
|
|
|
|
|
"""Provides all feature-test macro (FTM) output components.
|
|
|
|
|
|
|
|
|
|
The class has several generators to use the feature-test macros in libc++:
|
|
|
|
|
- FTM status page
|
|
|
|
|
- The version header and its tests
|
|
|
|
|
|
|
|
|
|
This class is not intended to duplicate
|
|
|
|
|
https://isocpp.org/std/standing-documents/sd-6-sg10-feature-test-recommendations#library-feature-test-macros
|
|
|
|
|
SD-FeatureTest: Feature-Test Macros and Policies
|
|
|
|
|
|
|
|
|
|
Historically libc++ did not list all papers affecting a FTM, the new data
|
|
|
|
|
structure is able to do that. However there is no intention to add the
|
|
|
|
|
historical data. After papers have been implemented this information can be
|
|
|
|
|
removed. For example, __cpp_lib_format's value 201907 requires 3 papers,
|
|
|
|
|
once implemented it can be reduced to 1 paper and remove the paper number
|
|
|
|
|
and title. This would reduce the size of the data.
|
|
|
|
|
|
|
|
|
|
The input data is stored in the following JSON format:
|
|
|
|
|
[ # A list with multiple feature-test macro entries.
|
|
|
|
|
{
|
|
|
|
|
# required
|
|
|
|
|
# The name of the feature test macro. These names should be unique and
|
|
|
|
|
# sorted in the list.
|
|
|
|
|
"name": "__cpp_lib_any",
|
|
|
|
|
|
|
|
|
|
# required
|
|
|
|
|
# A map with the value of the FTM based on the language standard. Only
|
|
|
|
|
# the versions in which the value of the FTM changes are listed. For
|
|
|
|
|
# example, this macro's value does not change in C++20 so it does not
|
|
|
|
|
# list C++20. If it changes in C++26, it will have entries for C++17 and
|
|
|
|
|
# C++26.
|
|
|
|
|
"values": {
|
|
|
|
|
|
|
|
|
|
# required
|
|
|
|
|
# The language standard, also named dialect in this class.
|
|
|
|
|
"c++17": {
|
|
|
|
|
|
|
|
|
|
# required
|
|
|
|
|
# The value of the feature test macro. This contains an array with
|
|
|
|
|
# one or more papers that need to be implemented before this value
|
|
|
|
|
# is considered implemented.
|
|
|
|
|
"201606": [
|
|
|
|
|
{
|
|
|
|
|
# optional
|
|
|
|
|
# Contains the paper number that is part of the FTM version.
|
|
|
|
|
"number": "P0220R1",
|
|
|
|
|
|
|
|
|
|
# optional
|
|
|
|
|
# Contains the title of the paper that is part of the FTM
|
|
|
|
|
# version.
|
|
|
|
|
"title": "Adopt Library Fundamentals V1 TS Components for C++17"
|
|
|
|
|
|
|
|
|
|
# required
|
|
|
|
|
# The implementation status of the paper.
|
|
|
|
|
"implemented": true
|
|
|
|
|
}
|
|
|
|
|
]
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
# required
|
|
|
|
|
# A sorted list of headers that should provide the FTM. The header
|
|
|
|
|
# <version> is automatically added to this list. This list could be
|
|
|
|
|
# empty. For example, __cpp_lib_modules is only present in version.
|
|
|
|
|
# Requiring the field makes it easier to detect accidental omission.
|
|
|
|
|
"headers": [
|
|
|
|
|
"any"
|
|
|
|
|
],
|
|
|
|
|
|
|
|
|
|
# optional, required when libcxx_guard is present
|
|
|
|
|
# This field is used only to generate the unit tests for the
|
|
|
|
|
# feature-test macros. It can't depend on macros defined in <__config>
|
|
|
|
|
# because the `test/std/` parts of the test suite are intended to be
|
|
|
|
|
# portable to any C++ standard library implementation, not just libc++.
|
|
|
|
|
# It may depend on
|
|
|
|
|
# * macros defined by the compiler itself, or
|
|
|
|
|
# * macros generated by CMake.
|
|
|
|
|
# In some cases we add also depend on macros defined in
|
|
|
|
|
# <__availability>.
|
|
|
|
|
"test_suite_guard": "!defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_PMR"
|
|
|
|
|
|
|
|
|
|
# optional, required when test_suite_guard is present
|
|
|
|
|
# This field is used only to guard the feature-test macro in
|
|
|
|
|
# <version>. It may be the same as `test_suite_guard`, or it may
|
|
|
|
|
# depend on macros defined in <__config>.
|
|
|
|
|
"libcxx_guard": "_LIBCPP_AVAILABILITY_HAS_PMR"
|
|
|
|
|
},
|
|
|
|
|
]
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
# The JSON data structure.
|
|
|
|
|
__data = None
|
|
|
|
|
|
|
|
|
|
def __init__(self, filename: str):
|
|
|
|
|
"""Initializes the class with the JSON data in the file 'filename'."""
|
2024-09-17 14:27:37 -04:00
|
|
|
|
with open(filename) as f:
|
|
|
|
|
self.__data = json.load(f)
|
2024-07-05 07:54:34 +02:00
|
|
|
|
|
|
|
|
|
@functools.cached_property
|
2025-02-10 18:03:44 +01:00
|
|
|
|
def std_dialects(self) -> List[Std]:
|
2024-07-05 07:54:34 +02:00
|
|
|
|
"""Returns the C++ dialects avaiable.
|
|
|
|
|
|
|
|
|
|
The available dialects are based on the 'c++xy' keys found the 'values'
|
|
|
|
|
entries in '__data'. So when WG21 starts to feature-test macros for a
|
|
|
|
|
future C++ Standard this dialect will automatically be available.
|
|
|
|
|
|
|
|
|
|
The return value is a sorted list with the C++ dialects used. Since FTM
|
|
|
|
|
were added in C++14 the list will not contain C++03 or C++11.
|
|
|
|
|
"""
|
|
|
|
|
dialects = set()
|
|
|
|
|
for feature in self.__data:
|
|
|
|
|
keys = feature["values"].keys()
|
|
|
|
|
assert len(keys) > 0, "'values' is empty"
|
|
|
|
|
dialects |= keys
|
|
|
|
|
|
|
|
|
|
return sorted(list(dialects))
|
|
|
|
|
|
|
|
|
|
@functools.cached_property
|
2025-02-10 18:03:44 +01:00
|
|
|
|
def standard_ftms(self) -> Dict[Ftm, Dict[Std, Optional[Value]]]:
|
2024-07-05 07:54:34 +02:00
|
|
|
|
"""Returns the FTM versions per dialect in the Standard.
|
|
|
|
|
|
|
|
|
|
This function does not use the 'implemented' flag. The output contains
|
|
|
|
|
the versions used in the Standard. When a FTM in libc++ is not
|
|
|
|
|
implemented according to the Standard to output may opt to show the
|
|
|
|
|
expected value.
|
|
|
|
|
"""
|
|
|
|
|
return get_ftms(self.__data, self.std_dialects, False)
|
|
|
|
|
|
|
|
|
|
@functools.cached_property
|
2025-02-10 18:03:44 +01:00
|
|
|
|
def implemented_ftms(self) -> Dict[Ftm, Dict[Std, Optional[Value]]]:
|
2024-07-05 07:54:34 +02:00
|
|
|
|
"""Returns the FTM versions per dialect implemented in libc++.
|
|
|
|
|
|
|
|
|
|
Unlike `get_std_dialect_versions` this function uses the 'implemented'
|
|
|
|
|
flag. This returns the actual implementation status in libc++.
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
return get_ftms(self.__data, self.std_dialects, True)
|
|
|
|
|
|
2025-04-11 20:27:29 +02:00
|
|
|
|
def is_implemented(self, ftm: Ftm, std: Std) -> bool:
|
|
|
|
|
"""Has the FTM `ftm` been implemented in the dialect `std`?"""
|
|
|
|
|
|
|
|
|
|
# When a paper for C++20 has not been implemented in libc++, then there will be no
|
|
|
|
|
# FTM entry in implemented_ftms for C++23 and later. Similarly, a paper like <format>
|
|
|
|
|
# has no entry in standard_ftms for e.g. C++11.
|
|
|
|
|
if not std in self.implemented_ftms[ftm].keys() or not std in self.standard_ftms[ftm].keys():
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
return self.implemented_ftms[ftm][std] == self.standard_ftms[ftm][std]
|
|
|
|
|
|
|
|
|
|
|
2024-08-03 11:16:29 +02:00
|
|
|
|
@functools.cached_property
|
2025-02-10 18:03:44 +01:00
|
|
|
|
def ftm_metadata(self) -> Dict[Ftm, Metadata]:
|
2024-08-03 11:16:29 +02:00
|
|
|
|
"""Returns the metadata of the FTMs defined in the Standard.
|
|
|
|
|
|
|
|
|
|
The metadata does not depend on the C++ dialect used.
|
|
|
|
|
"""
|
|
|
|
|
result = dict()
|
|
|
|
|
for feature in self.__data:
|
2025-02-10 18:03:44 +01:00
|
|
|
|
result[feature["name"]] = Metadata(
|
|
|
|
|
feature["headers"],
|
|
|
|
|
feature.get("test_suite_guard", None),
|
|
|
|
|
feature.get("libcxx_guard", None),
|
|
|
|
|
)
|
2024-08-03 11:16:29 +02:00
|
|
|
|
|
|
|
|
|
return result
|
|
|
|
|
|
|
|
|
|
@property
|
2025-02-10 18:03:44 +01:00
|
|
|
|
def version_header_implementation(self) -> Dict[Std, Dict[Ftm, VersionHeader]]:
|
2024-08-03 11:16:29 +02:00
|
|
|
|
"""Generates the body of the version header."""
|
|
|
|
|
result = dict()
|
|
|
|
|
for std in self.std_dialects:
|
|
|
|
|
result[get_std_number(std)] = list()
|
|
|
|
|
|
|
|
|
|
for ftm, values in self.standard_ftms.items():
|
|
|
|
|
last_value = None
|
2024-09-17 14:27:37 -04:00
|
|
|
|
last_entry = None
|
2024-08-03 11:16:29 +02:00
|
|
|
|
for std, value in values.items():
|
|
|
|
|
# When a newer Standard does not change the value of the macro
|
|
|
|
|
# there is no need to redefine it with the same value.
|
|
|
|
|
if last_value and value == last_value:
|
|
|
|
|
continue
|
|
|
|
|
last_value = value
|
|
|
|
|
|
2025-04-11 20:27:29 +02:00
|
|
|
|
implemented = self.is_implemented(ftm, std)
|
2025-02-10 18:03:44 +01:00
|
|
|
|
entry = VersionHeader(
|
|
|
|
|
value,
|
|
|
|
|
implemented,
|
|
|
|
|
last_entry is not None and last_entry.implemented and implemented,
|
|
|
|
|
self.ftm_metadata[ftm].libcxx_guard,
|
|
|
|
|
)
|
2024-08-03 11:16:29 +02:00
|
|
|
|
|
2024-09-17 14:27:37 -04:00
|
|
|
|
last_entry = entry
|
2024-08-03 11:16:29 +02:00
|
|
|
|
result[get_std_number(std)].append(dict({ftm: entry}))
|
|
|
|
|
|
|
|
|
|
return result
|
|
|
|
|
|
|
|
|
|
@property
|
|
|
|
|
def version_header(self) -> str:
|
|
|
|
|
"""Generates the version header."""
|
|
|
|
|
template = """// -*- C++ -*-
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
//
|
|
|
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
|
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
|
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
|
|
|
//
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
2024-12-11 12:39:43 -05:00
|
|
|
|
#ifndef _LIBCPP_VERSIONH
|
|
|
|
|
#define _LIBCPP_VERSIONH
|
2024-08-03 11:16:29 +02:00
|
|
|
|
|
|
|
|
|
#include <__config>
|
|
|
|
|
|
|
|
|
|
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
|
|
|
|
# pragma GCC system_header
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
{feature_test_macros}
|
|
|
|
|
|
2024-12-11 12:39:43 -05:00
|
|
|
|
#endif // _LIBCPP_VERSIONH
|
2024-08-03 11:16:29 +02:00
|
|
|
|
"""
|
|
|
|
|
return template.format(
|
|
|
|
|
feature_test_macros=generate_version_header_implementation(
|
|
|
|
|
self.version_header_implementation
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
|
2024-07-05 07:54:34 +02:00
|
|
|
|
|
2019-01-16 01:37:43 +00:00
|
|
|
|
def main():
|
2020-10-13 09:16:40 -04:00
|
|
|
|
produce_version_header()
|
2019-01-16 01:37:43 +00:00
|
|
|
|
produce_tests()
|
|
|
|
|
produce_docs()
|
|
|
|
|
|
2024-08-03 11:16:29 +02:00
|
|
|
|
# Example how to use the new version header generation function to generate
|
|
|
|
|
# the file.
|
|
|
|
|
if False:
|
|
|
|
|
ftm = FeatureTestMacros(
|
|
|
|
|
os.path.join(
|
|
|
|
|
source_root, "test", "libcxx", "feature_test_macro", "test_data.json"
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
version_header_path = os.path.join(include_path, "version")
|
|
|
|
|
with open(version_header_path, "w", newline="\n") as f:
|
|
|
|
|
f.write(ftm.version_header)
|
|
|
|
|
|
2019-01-16 01:37:43 +00:00
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
|
main()
|