命名空间
变体
操作

功能测试 (自 C++20 起)

来自 cppreference.com
< cpp

标准定义了一组 预处理器宏,对应于 C++ 语言和库特性,这些特性在 C++11 或更高版本中引入。它们旨在作为一种简单且可移植的方式来检测这些特性的存在。

内容

[编辑] 属性

__has_cpp_attribute( attribute-token )

检查对名为 attribute-token属性 的支持(在宏展开后)。

对于每个标准属性,__has_cpp_attribute 是否扩展到下表中给定的值(即属性添加到工作草案的年份和月份)是实现定义的。如果标准属性导致实现按建议的行为(发出诊断消息、影响类布局等),它才会扩展到表中给定的值。否则,它将扩展到 0

供应商特定属性的存在由非零值确定。

__has_cpp_attribute 可以扩展到 #if #elif 表达式中。它由 #ifdef #ifndef, #elifdef, #elifndef(自 C++23 起)defined 视为已定义的宏,但不能用于其他任何地方。

attribute-token 属性 标准 论文
assume [[assume]] 202207L (C++23) P1774R8
carries_dependency [[carries_dependency]] 200809L (C++11) N2556, N2643
deprecated [[deprecated]] 201309L (C++14) N3760
fallthrough [[fallthrough]] 201603L (C++17) P0188R1
indeterminate [[indeterminate]] 202403L (C++26) P2795R5
likely [[likely]] 201803L (C++20) P0479R5
maybe_unused [[maybe_unused]] 201603L (C++17) P0212R1
no_unique_address [[no_unique_address]] 201803L (C++20) P0840R2
nodiscard [[nodiscard]] 201603L (C++17) P0189R1
201907L (C++20) P1301R4
noreturn [[noreturn]] 200809L (C++11) N2761
unlikely [[unlikely]] 201803L (C++20) P0479R5
属性总数:11

[编辑] 语言特性

以下宏在每个翻译单元中预定义。每个宏都扩展到一个整数字面量,对应于相应特性被包含在工作草案中的年份和月份。

当特性发生重大变化时,宏将相应更新。

宏名称 特性 Std 论文
__cpp_aggregate_bases 聚合类 具有基类 201603L (C++17) P0017R1
__cpp_aggregate_nsdmi 聚合类 具有 默认成员初始化器 201304L (C++14) N3653
__cpp_aggregate_paren_init 聚合初始化直接初始化 的形式 201902L (C++20) P0960R3
__cpp_alias_templates 别名模板 200704L (C++11) N2258
__cpp_aligned_new 为过度对齐的数据动态分配内存 201606L (C++17) P0035R4
__cpp_attributes 属性 200809L (C++11) N2761
__cpp_auto_cast auto(x)auto{x} 202110L (C++23) P0849R8
__cpp_binary_literals 二进制字面量 201304L (C++14) N3472
__cpp_capture_star_this Lambda 按值捕获 *this 作为 [=,*this] 201603L (C++17) P0018R3
__cpp_char8_t char8_t 201811L (C++20) P0482R6
char8_t 兼容性和可移植性修复(允许 从 (unsigned) char 数组初始化 UTF-8 字符串字面量 202207L (C++20)
(DR)
P2513R4
__cpp_concepts 概念 201907L (C++20) P0734R0
P1084R2
P1452R2
条件平凡的特殊成员函数 202002L (C++20) P0848R3
P2493R0
__cpp_conditional_explicit explicit(bool) 201806L (C++20) P0892R2
__cpp_consteval 立即函数 201811L (C++20) P1073R3
使 consteval 向上传播 202211L (C++20)
(DR)
P2564R3
__cpp_constexpr constexpr 200704L (C++11) N2235
放宽 constexprconst constexpr 方法 201304L (C++14) N3652
Constexpr lambda 201603L (C++17) P0170R1
虚函数 调用在常量表达式中;tryconstexpr 函数中,dynamic_cast 和多态 typeid 在常量表达式中;平凡 默认初始化asm 声明constexpr 函数中 201907L (C++20) P1064R0
P1002R1
P1327R1
P1331R2
P1668R1
在常量求值期间更改联合的活动成员 202002L (C++20) P1330R0
P2493R0
字面量 变量、标签和 goto 语句在 constexpr 函数中 202110L (C++23) P2242R3
放宽对 constexpr 函数和函数模板的一些限制 202207L (C++23) P2448R2
允许 constexpr 函数中存在静态 constexpr 变量 202211L (C++23) P2647R1
void* 的 constexpr 转换:走向 constexpr 类型擦除 202306L (C++26) P2738R1
constexpr 位置 new 202406L (C++26) P2747R2
__cpp_constexpr_dynamic_alloc constexpr 函数中对动态存储期限执行操作 201907L (C++20) P0784R7
__cpp_constexpr_in_decltype 需要常量求值时 生成函数和变量定义 201711L (C++11)
(DR)
P0859R0
__cpp_constinit constinit 201907L (C++20) P1143R2
__cpp_decltype decltype 200707L (C++11) N2343
__cpp_decltype_auto 为普通函数推断返回类型 201304L (C++14) N3638
__cpp_deduction_guides 类模板的模板参数推断 201703L (C++17) P0091R3
P0512R0
P0620R0
CTAD 用于聚合和别名 201907L (C++20) P1814R0
P1816R0
__cpp_delegating_constructors 委托构造函数 200604L (C++11) N1986
__cpp_deleted_function 具有消息的删除的 函数定义 (= delete("should have a reason");) 202403L (C++26) P2573R2
__cpp_designated_initializers 指定初始化器 201707L (C++20) P0329R4
__cpp_enumerator_attributes 用于 枚举器 的属性 201411L (C++17) N4266
__cpp_explicit_this_parameter 显式对象参数 202110L (C++23) P0847R7
__cpp_fold_expressions 折叠表达式 201603L (C++17) N4295
P0036R0
涉及约束折叠表达式的顺序 202406L (C++26) P2963R3
__cpp_generic_lambdas 泛型 lambda 表达式 201304L (C++14) N3649
用于泛型 lambda 表达式的显式模板参数列表 201707L (C++20) P0428R2
__cpp_guaranteed_copy_elision 通过简化的值类别保证复制省略 201606L (C++17) P0135R1
__cpp_hex_float 十六进制浮点字面量 201603L (C++17) P0245R1
__cpp_if_consteval consteval if 202106L (C++23) P1938R3
__cpp_if_constexpr constexpr if 201606L (C++17) P0292R2
__cpp_impl_coroutine 协程 (编译器支持) 201902L (C++20) P0912R5
LWG3393
__cpp_impl_destroying_delete 销毁运算符 delete (编译器支持) 201806L (C++20) P0722R3
__cpp_impl_three_way_comparison 三方比较 (编译器支持) 201907L (C++20) P0515R3
P0768R1
P1185R2
P1630R1
__cpp_implicit_move 更简单的隐式移动 202207L (C++23) P2266R3
__cpp_inheriting_constructors 继承构造函数 200802L (C++11) N2540
重新措辞继承构造函数 201511L (C++11)
(DR)
P0136R1
__cpp_init_captures Lambda 初始化捕获 201304L (C++14) N3648
允许在lambda 表达式 初始化捕获中使用包扩展 201803L (C++20) P0780R2
__cpp_initializer_lists 列表初始化std::initializer_list 200806L (C++11) N2672
__cpp_inline_variables 内联变量 201606L (C++17) P0386R2
__cpp_lambdas Lambda 表达式 200907L (C++11) N2927
__cpp_modules 模块 201907L (C++20) P1103R3
P1811R0
__cpp_multidimensional_subscript 多维下标运算符 202110L (C++23) P2128R6
static operator[] 202211L (C++23) P2589R1
__cpp_named_character_escapes 命名通用字符转义 202207L (C++23) P2071R2
__cpp_namespace_attributes 用于命名空间的属性 201411L (C++17) N4266
__cpp_noexcept_function_type 使异常说明成为类型系统的一部分 201510L (C++17) P0012R1
__cpp_nontype_template_args 允许对所有非类型模板参数进行常量求值 201411L (C++17) N4268
类类型和浮点类型在非类型模板参数中的使用 201911L (C++20) P1907R1
__cpp_nontype_template_parameter_auto 使用 auto 声明非类型模板参数 201606L (C++17) P0127R2
__cpp_nsdmi 非静态数据成员初始化器 200809L (C++11) N2756
__cpp_pack_indexing 包索引 202311L (C++26) P2662R3
__cpp_placeholder_variables 一个没有名字的好的占位符 202306L (C++26) P2169R4
__cpp_range_based_for 基于范围的 for 循环 200907L (C++11) N2930
基于范围的 for 循环 具有不同的 begin/end 类型 201603L (C++17) P0184R0
基于范围的 for 循环中的生命周期扩展 202211L (C++23) P2644R1
P2718R0
CWG2659
__cpp_raw_strings 原始字符串字面量 200710L (C++11) N2442
__cpp_ref_qualifiers 引用限定符 200710L (C++11) N2439
__cpp_return_type_deduction 为普通函数推断返回类型 201304L (C++14) N3638
__cpp_rvalue_references 右值引用 200610L (C++11) N2118
__cpp_size_t_suffix size_t 及其有符号版本的字面量后缀 202011L (C++23) P0330R8
__cpp_sized_deallocation 大小释放 201309L (C++14) N3778
__cpp_static_assert static_assert 200410L (C++11) N1720
单参数 static_assert 201411L (C++17) N3928
用户生成的 static_assert 消息 202306L (C++26) P2741R3
__cpp_static_call_operator static operator() 202207L (C++23) P1169R4
__cpp_structured_bindings 结构化绑定 201606L (C++17) P0217R3
属性 用于结构化绑定 202403L (C++26) P0609R3
结构化绑定 声明 作为条件 202406L (C++26) P0963R3
__cpp_template_template_args 模板模板参数 的匹配 201611L (C++17) P0522R0
__cpp_threadsafe_static_init 动态初始化和销毁与并发 200806L (C++11) N2660
__cpp_unicode_characters 新的字符类型 (char16_tchar32_t) 200704L (C++11) N2249
__cpp_unicode_literals Unicode 字符串字面量 200710L (C++11) N2442
__cpp_user_defined_literals 用户定义的字面量 200809L (C++11) N2765
__cpp_using_enum using enum 201907L (C++20) P1099R5
__cpp_variable_templates 变量模板 201304L (C++14) N3651
__cpp_variadic_friend 可变参数友元声明 202403L (C++26) P2893R3
__cpp_variadic_templates 可变参数模板 200704L (C++11) N2242
__cpp_variadic_using using 声明 中使用包扩展 201611L (C++17) P0195R2
宏总数:70

[edit] 库特性

如果包含了头文件 <version> 或者下表中的任何对应头文件,则会定义以下宏。每个宏都扩展为一个整数字面量,对应于该特性被包含到工作草案中的年份和月份。

当特性发生重大变化时,宏将相应更新。

宏名称 特性 头文件 Std 论文
__cpp_lib_adaptor_iterator_pair_constructor 用于 std::stackstd::queue 的迭代器对构造函数 202106L <queue> <stack> (C++23) P1425R4
__cpp_lib_addressof_constexpr Constexpr std::addressof 201603L <memory> (C++17) LWG2296
__cpp_lib_algorithm_default_value_type 启用列表初始化 用于算法 202403L <algorithm> <deque> <forward_list> <list> <ranges> <string> <vector> (C++26) P2248R8 P3217R0
__cpp_lib_algorithm_iterator_requirements 范围迭代器作为非范围算法 的输入 202207L <algorithm> <memory> <numeric> (C++23) P2408R5
__cpp_lib_allocate_at_least 分配器接口中的大小反馈,例如:std::allocator::allocate_at_leaststd::allocator_traits::allocate_at_least 202302L <memory> (C++23) P0401R6
P2652R2
LWG3887
__cpp_lib_allocator_traits_is_always_equal std::allocator_traits::is_always_equal 201411L <memory> <scoped_allocator> <string> <deque> <forward_list> <list> <vector> <map> <set> <unordered_map> <unordered_set> (C++17) N4258
__cpp_lib_any std::any 201606L <any> (C++17) P0220R1
P0032R3
__cpp_lib_apply std::apply 201603L <tuple> (C++17) P0220R1
__cpp_lib_array_constexpr Constexpr 用于 std::reverse_iteratorstd::move_iteratorstd::array范围访问 201603L <iterator> <array> (C++17) P0031R0
ConstexprIterator; constexpr 比较用于 std::array; 各种 constexpr 位 (std::array::fill 等) 201811L <iterator> <array> (C++20) P0858R0
LWG3257
P1023R0
P1032R1
__cpp_lib_as_const std::as_const 201510L <utility> (C++17) P0007R1
__cpp_lib_associative_heterogeneous_erasure 关联容器无序关联容器 中的异构擦除 202110L <map> <set> <unordered_map> <unordered_set> (C++23) P2077R3
__cpp_lib_associative_heterogeneous_insertion 有序无序关联容器 中的剩余成员函数的异构重载 202306L <map> <set> <unordered_map> <unordered_set> (C++26) P2363R5
__cpp_lib_assume_aligned std::assume_aligned 201811L <memory> (C++20) P1007R3
__cpp_lib_atomic_flag_test std::atomic_flag::test 201907L <atomic> (C++20) P1135R6
__cpp_lib_atomic_float 浮点原子类型 201711L <atomic> (C++20) P0020R6
__cpp_lib_atomic_is_always_lock_free constexpr atomic<T>::is_always_lock_free 201603L <atomic> (C++17) P0152R1
__cpp_lib_atomic_lock_free_type_aliases 原子无锁整数类型 (std::atomic_signed_lock_freestd::atomic_unsigned_lock_free) 201907L <atomic> (C++20) P1135R6
__cpp_lib_atomic_min_max 原子最小值/最大值 (std::atomic::fetch_minstd::atomic::fetch_max,等等) 202403L <atomic> (C++26) P0493R5
__cpp_lib_atomic_ref std::atomic_ref 201806L <atomic> (C++20) P0019R8
__cpp_lib_atomic_shared_ptr std::atomic<std::shared_ptr> 201711L <memory> (C++20) P0718R2
__cpp_lib_atomic_value_initialization 修复原子初始化(默认情况下按值初始化 std::atomic 201911L <atomic> <memory> (C++20) P0883R2
__cpp_lib_atomic_wait 高效的 std::atomic 等待 201907L <atomic> (C++20) P1135R6
__cpp_lib_barrier std::barrier 201907L <barrier> (C++20) P1135R6
std::barrier 的阶段完成保证 202302L <barrier> (C++23) P2588R3
__cpp_lib_bind_back std::bind_back 202202L <functional> (C++23) P2387R3
允许将可调用对象作为非类型模板参数传递给 std::bind_back 202306L <functional> (C++26) P2714R1
__cpp_lib_bind_front std::bind_front 201907L <functional> (C++20) P0356R5
P1651R0
允许将可调用对象作为非类型模板参数传递给 std::bind_front 202306L <functional> (C++26) P2714R1
__cpp_lib_bit_cast std::bit_cast 201806L <bit> (C++20) P0476R2
__cpp_lib_bitops 位运算 201907L <bit> (C++20) P0553R4
__cpp_lib_bitset std::bitsetstd::string_view 相互连接 202306L <bitset> (C++26) P2697R1
__cpp_lib_bool_constant std::bool_constant 201505L <type_traits> (C++17) N4389
__cpp_lib_bounded_array_traits std::is_bounded_arraystd::is_unbounded_array 201902L <type_traits> (C++20) P1357R1
__cpp_lib_boyer_moore_searcher 搜索器 201603L <functional> (C++17) P0220R1
__cpp_lib_byte std::byte 201603L <cstddef> (C++17) P0298R3
__cpp_lib_byteswap std::byteswap 202110L <bit> (C++23) P1272R4
__cpp_lib_char8_t char8_t 的库支持 201907L <atomic> <filesystem> <istream> <limits> <locale> <ostream> <string> <string_view> (C++20) P0482R6
P1423R3
__cpp_lib_chrono 用于 std::chrono::durationstd::chrono::time_point 的舍入函数 201510L <chrono> (C++17) P0092R1
所有 std::chrono::durationstd::chrono::time_point 成员函数的 constexpr 201611L <chrono> (C++17) P0505R0
日历时区 201907L <chrono> (C++20) P0355R7
P1466R3
std::chrono 值类的 哈希 支持 202306L <chrono> (C++26) P2592R3
__cpp_lib_chrono_udls 时间类型的用户定义文字 201304L <chrono> (C++14) N3642
__cpp_lib_clamp std::clamp 201603L <algorithm> (C++17) P0025R0
__cpp_lib_common_reference 使 std::common_reference_tstd::reference_wrapper 成为引用类型 202302L <type_traits> (C++23) P2655R3
__cpp_lib_common_reference_wrapper 使 std::common_reference_tstd::reference_wrapper 成为引用类型 202302L <functional> (C++23) P2655R3
__cpp_lib_complex_udls std::complex 的用户定义文字 201309L <complex> (C++14) N3779
__cpp_lib_concepts 标准库概念 202002L <concepts> (C++20) P0898R3
P1754R1
P1964R2
用于 equality_comparable_withtotally_ordered_withthree_way_comparable_with 的移动专用类型 202207L <compare> <concepts> (C++23) P2404R3
__cpp_lib_constexpr_algorithms 用于 算法 的 constexpr 201806L <algorithm> <utility> (C++20) P0202R3
P0879R0
LWG3256
LWG3792
constexpr 稳定排序 202306L <algorithm> <utility> (C++26) P2562R1
__cpp_lib_constexpr_bitset 更 constexpr 的 std::bitset 202207L <bitset> (C++23) P2417R2
__cpp_lib_constexpr_charconv 为整数类型添加 constexpr 修饰符到函数 std::to_charsstd::from_chars 202207L <charconv> (C++23) P2291R3
__cpp_lib_constexpr_cmath 用于 <cmath><cstdlib> 中的数学函数的 constexpr 202202L <cmath> <cstdlib> (C++23) P0533R9
更多用于 <cmath> 的 constexpr 202306L <cmath> <cstdlib> (C++26) P1383R2
__cpp_lib_constexpr_complex 用于 std::complex 的 constexpr 201711L <complex> (C++20) P0415R1
更多用于 <complex> 的 constexpr 202306L <complex> (C++26) P1383R2
__cpp_lib_constexpr_dynamic_alloc 用于 std::allocator 和相关实用程序的 constexpr 201907L <memory> (C++20) P0784R7
__cpp_lib_constexpr_functional 其他 constexpr 位 (std::default_searcher);constexpr INVOKE 201907L <functional> (C++20) P1032R1
P1065R2
__cpp_lib_constexpr_iterator 其他 constexpr 位 (std::insert_iterator 等) 201811L <iterator> (C++20) P1032R1
__cpp_lib_constexpr_memory 用于 std::pointer_traits 的 constexpr 201811L <memory> (C++20) P1006R1
constexpr std::unique_ptr 202202L <memory> (C++23) P2273R3
__cpp_lib_constexpr_new constexpr placement new 202406L <new> (C++26) P2747R2
__cpp_lib_constexpr_numeric 用于 算法 的 constexpr,在 <numeric> 201911L <numeric> (C++20) P1645R1
__cpp_lib_constexpr_string 用于 std::string 的 constexpr 201907L <string> (C++20) P0426R1
P1032R1
P0980R1
__cpp_lib_constexpr_string_view 其他 constexpr 位 (std::string_view::copy) 201811L <string_view> (C++20) P0426R1
P1032R1
__cpp_lib_constexpr_tuple 其他 constexpr 位 (std::tuple::operator= 等) 201811L <tuple> (C++20) P1032R1
__cpp_lib_constexpr_typeinfo 用于 std::type_info::operator== 的 constexpr 202106L <typeinfo> (C++23) P1328R1
__cpp_lib_constexpr_utility 其他 constexpr 位 (std::pair::operator= 等) 201811L <utility> (C++20) P1032R1
__cpp_lib_constexpr_vector 用于 std::vector 的 constexpr 201907L <vector> (C++20) P1004R2
__cpp_lib_constrained_equality 用于 std::pairstd::tuplestd::optionalstd::variant 的受约束的关系运算符 202403L <optional> <tuple> <utility> <variant> (C++26) P2944R3
__cpp_lib_containers_ranges 容器和字符串的 范围感知 构造和插入 202202L <vector> <list> <forward_list> <map> <set> <unordered_map> <unordered_set> <deque> <queue> <stack> <string> (C++23) P1206R7
__cpp_lib_copyable_function std::copyable_function 202306L <functional> (C++26) P2548R6
__cpp_lib_coroutine 协程(库支持) 201902L <coroutine> (C++20) P0912R5
LWG3393
__cpp_lib_debugging 调试支持 202311L <debugging> (C++26) P2546R5
可替换的 std::is_debugger_present 202403L <debugging> (C++26) P2810R4
__cpp_lib_destroying_delete 销毁 operator delete(库支持) 201806L <new> (C++20) P0722R3
__cpp_lib_enable_shared_from_this std::enable_shared_from_this::weak_from_this 201603L <memory> (C++17) P0033R1
__cpp_lib_endian std::endian 201907L <bit> (C++20) P0463R1
P1612R1
__cpp_lib_erase_if 统一容器擦除 202002L <string> <deque> <forward_list> <list> <vector> <map> <set> <unordered_map> <unordered_set> (C++20) P1209R0
P1115R3
__cpp_lib_exchange_function std::exchange 201304L <utility> (C++14) N3668
__cpp_lib_execution 执行策略 201603L <execution> (C++17) P0024R2
std::execution::unsequenced_policy 201902L <execution> (C++20) P1001R2
__cpp_lib_expected 类模板 std::expected 202202L <expected> (C++23) P0323R12
用于 std::expected 的单子函数 202211L <expected> (C++23) P2505R5
__cpp_lib_filesystem 文件系统库 201703L <filesystem> (C++17) P0218R1
P0219R1
P0392R0
P0317R1
__cpp_lib_flat_map std::flat_mapstd::flat_multimap 202207L <flat_map> (C++23) P0429R9
__cpp_lib_flat_set std::flat_setstd::flat_multiset 202207L <flat_set> (C++23) P1222R4
LWG3751
__cpp_lib_format 文本格式化 201907L <format> (C++20) P0645R10
P1361R2
P1652R1
编译时格式字符串检查;减少 std::vformat_to 的参数化 202106L <format> (C++20)
(DR)
P2216R3
修复 chrono 格式化程序中的区域设置处理;支持非 const 可格式化类型 202110L <format> (C++20)
(DR)
P2372R3
P2418R2
公开 std::basic_format_string;阐明 chrono 类型的本地化格式化中编码的处理方式 202207L <format> (C++23) P2419R2
P2508R1
格式化指针 202304L <format> (C++26) P2510R3
类型检查格式参数 202305L <format> (C++26) P2757R3
成员 visit 202306L <format> (C++26) P2637R3
运行时格式字符串 202311L <format> (C++26) P2918R2
__cpp_lib_format_path 格式化 std::filesystem::path 202403L <filesystem> (C++26) P2845R8
__cpp_lib_format_ranges 格式化范围 202207L <format> (C++23) P2286R8
P2585R1
LWG3750
__cpp_lib_format_uchar 修复代码单元格作为整数的格式 202311L <format> (C++26) P2909R4
__cpp_lib_formatters 格式化 std::thread::idstd::stacktrace 202302L <stacktrace> <thread> (C++23) P2693R1
__cpp_lib_forward_like std::forward_like 202207L <utility> (C++23) P2445R1
__cpp_lib_freestanding_algorithm <algorithm> 中的独立设施 202311L <algorithm> (C++26) P2407R5
__cpp_lib_freestanding_array 使部分 std::array 独立 202311L <array> (C++26) P2407R5
__cpp_lib_freestanding_char_traits 独立 std::char_traits 202306L <string> (C++26) P2338R4
__cpp_lib_freestanding_charconv <charconv> 中的独立设施 202306L <charconv> (C++26) P2338R4
__cpp_lib_freestanding_cstdlib <cstdlib> 中的独立设施 202306L <cmath> <cstdlib> (C++26) P2338R4
__cpp_lib_freestanding_cstring <cstring> 中的独立设施 202306L <cstring> (C++26) P2338R4
从独立设施中移除 std::strtok 202311L <cstring> (C++26) P2937R0
__cpp_lib_freestanding_cwchar <cwchar> 中的独立设施 202306L <cwchar> (C++26) P2338R4
__cpp_lib_freestanding_errc 独立 std::errc 202306L <cerrno> <system_error> (C++26) P2338R4
__cpp_lib_freestanding_expected 使部分 std::expected 独立 202311L <expected> (C++26) P2833R2
__cpp_lib_freestanding_feature_test_macros 对独立功能测试宏的支持 202306L (C++26) P2198R7
__cpp_lib_freestanding_functional <functional> 中的独立设施 202306L <functional> (C++26) P2198R7
__cpp_lib_freestanding_iterator <iterator> 中的独立设施 202306L <iterator> (C++26) P2198R7
__cpp_lib_freestanding_mdspan 独立 std::mdspan 202311L <mdspan> (C++26) P2833R2
__cpp_lib_freestanding_memory <memory> 中的独立设施 202306L <memory> (C++26) P2198R7
__cpp_lib_freestanding_numeric <numeric> 中的独立设施(饱和算术) 202311L <numeric> (C++26) P0543R3
__cpp_lib_freestanding_operator_new operator new 的定义(在独立实现中是可选的) 202306L <new> (C++26) P2198R7
__cpp_lib_freestanding_optional 使部分 std::optional 独立 202311L <optional> (C++26) P2407R5
__cpp_lib_freestanding_ranges <ranges> 中的独立设施 202306L <ranges> (C++26) P2198R7
__cpp_lib_freestanding_ratio <ratio> 中的独立设施 202306L <ratio> (C++26) P2198R7
__cpp_lib_freestanding_string_view 使部分 std::string_view 独立 202311L <string_view> (C++26) P2407R5
__cpp_lib_freestanding_tuple <tuple> 中的独立设施 202306L <tuple> (C++26) P2198R7
__cpp_lib_freestanding_utility <utility> 中的独立设施 202306L <utility> (C++26) P2198R7
__cpp_lib_freestanding_variant 使部分 std::variant 独立 202311L <variant> (C++26) P2407R5
__cpp_lib_fstream_native_handle 从文件流获取本地句柄 202306L <fstream> (C++26) P1759R6
__cpp_lib_function_ref std::function_ref: 一个类型擦除的可调用引用 202306L <functional> (C++26) P0792R14
__cpp_lib_gcd_lcm std::gcd, std::lcm 201606L <numeric> (C++17) P0295R0
__cpp_lib_generator std::generator: 用于范围的同步协程生成器 202207L <generator> (C++23) P2502R2
__cpp_lib_generic_associative_lookup 关联容器 中的异构比较查找 201304L <map> <set> (C++14) N3657
__cpp_lib_generic_unordered_lookup 无序关联容器 中的异构比较查找 201811L <unordered_map> <unordered_set> (C++20) P0919R3
__cpp_lib_hardware_interference_size constexpr std::hardware_{constructive, destructive}_interference_size 201703L <new> (C++17) P0154R1
__cpp_lib_has_unique_object_representations std::has_unique_object_representations 201606L <type_traits> (C++17) P0258R2
__cpp_lib_hazard_pointer 危险指针 202306L <hazard_pointer> (C++26) P2530R3
__cpp_lib_hypot 3 个参数重载的 std::hypot 201603L <cmath> (C++17) P0030R1
__cpp_lib_incomplete_container_elements std::forward_liststd::liststd::vector 的最小不完整类型支持 201505L <forward_list> <list> <vector> (C++17) N4510
__cpp_lib_inplace_vector std::inplace_vector: 具有固定容量(就地存储)的动态可调整大小的向量 202406L <inplace_vector> (C++26) P0843R14
__cpp_lib_int_pow2 整数 2 的幂运算std::has_single_bitstd::bit_ceilstd::bit_floorstd::bit_width 202002L <bit> (C++20) P0556R3
P1956R1
__cpp_lib_integer_comparison_functions 整数比较函数 202002L <utility> (C++20) P0586R2
__cpp_lib_integer_sequence 编译时整数序列 201304L <utility> (C++14) N3658
__cpp_lib_integral_constant_callable std::integral_constant::operator() 201304L <type_traits> (C++14) N3545
__cpp_lib_interpolate std::lerpstd::midpoint 201902L <cmath> <numeric> (C++20) P0811R3
__cpp_lib_invoke std::invoke 201411L <functional> (C++17) N4169
__cpp_lib_invoke_r std::invoke_r 202106L <functional> (C++23) P2136R3
__cpp_lib_ios_noreplace 支持 独占模式 用于文件流 202207L <ios> (C++23) P2467R1
__cpp_lib_is_aggregate std::is_aggregate 201703L <type_traits> (C++17) LWG2911
__cpp_lib_is_constant_evaluated std::is_constant_evaluated 201811L <type_traits> (C++20) P0595R2
__cpp_lib_is_final std::is_final 201402L <type_traits> (C++14) LWG2112
__cpp_lib_is_implicit_lifetime std::is_implicit_lifetime 202302L <type_traits> (C++23) P2674R1
__cpp_lib_is_invocable std::is_invocablestd::invoke_result 201703L <type_traits> (C++17) P0604R0
__cpp_lib_is_layout_compatible std::is_layout_compatible 201907L <type_traits> (C++20) P0466R5
__cpp_lib_is_nothrow_convertible std::is_nothrow_convertible 201806L <type_traits> (C++20) P0758R1
LWG3356
__cpp_lib_is_null_pointer std::is_null_pointer 201309L <type_traits> (C++14) LWG2247
__cpp_lib_is_pointer_interconvertible 指针可互换性特征:std::is_pointer_interconvertible_with_classstd::is_pointer_interconvertible_base_of 201907L <type_traits> (C++20) P0466R5
__cpp_lib_is_scoped_enum std::is_scoped_enum 202011L <type_traits> (C++23) P1048R1
__cpp_lib_is_swappable [nothrow-] 可交换特征 201603L <type_traits> (C++17) P0185R1
__cpp_lib_is_virtual_base_of std::is_virtual_base_of: 用于检测虚基类的类型特征 202406L <type_traits> (C++26) P2985R0
__cpp_lib_is_within_lifetime 检查联合备选方案是否处于活动状态 (std::is_within_lifetime) 202306L <type_traits> (C++26) P2641R4
__cpp_lib_jthread 停止令牌连接线程 201911L <stop_token> <thread> (C++20) P0660R10
P1869R1
__cpp_lib_latch std::latch 201907L <latch> (C++20) P1135R6
__cpp_lib_launder 核心问题 1776: 替换包含引用成员的类对象 (std::launder) 201606L <new> (C++17) P0137R1
__cpp_lib_linalg 基于 BLAS 的自由函数线性代数接口 202311L <linalg> (C++26) P1673R13
__cpp_lib_list_remove_return_type 更改 remove()remove_if()unique() 的返回值类型,属于 std::forward_liststd::list 201806L <forward_list> <list> (C++20) P0646R1
__cpp_lib_logical_traits 类型特征上的逻辑运算 201510L <type_traits> (C++17) P0013R1
__cpp_lib_make_from_tuple std::make_from_tuple() 201606L <tuple> (C++17) P0209R2
__cpp_lib_make_reverse_iterator std::make_reverse_iterator 201402L <iterator> (C++14) LWG2285
__cpp_lib_make_unique std::make_unique 201304L <memory> (C++14) N3656
__cpp_lib_map_try_emplace std::map::try_emplacestd::map::insert_or_assign 201411L <map> (C++17) N4279
__cpp_lib_math_constants 数学常量 201907L <numbers> (C++20) P0631R8
__cpp_lib_math_special_functions C++17 的数学特殊函数 201603L <cmath> (C++17) P0226R1
__cpp_lib_mdspan std::mdspan 202207L <mdspan> (C++23) P0009R18
P2599R2
P2604R0
P2613R1
std::dims 用于 std::mdspan 202406L <mdspan> (C++26) P2389R2
__cpp_lib_memory_resource std::pmr::memory_resource 201603L <memory_resource> (C++17) P0220R1
__cpp_lib_modules 标准库模块 stdstd.compat 202207L (C++23) P2465R3
__cpp_lib_move_iterator_concept 使 std::move_iterator<T*> 成为一个随机访问迭代器 202207L <iterator> (C++23) P2520R0
__cpp_lib_move_only_function std::move_only_function 202110L <functional> (C++23) P0288R9
__cpp_lib_node_extract 拼接映射和集合 (std::map::extractstd::map::mergestd::map::insert(node_type) 等) 201606L <map> <set> <unordered_map> <unordered_set> (C++17) P0083R3
__cpp_lib_nonmember_container_access std::size()std::data()std::empty() 201411L <iterator> <array> <deque> <forward_list> <list> <map> <regex> <set> <string> <unordered_map> <unordered_set> <vector> (C++17) N4280
__cpp_lib_not_fn std::not_fn() 201603L <functional> (C++17) P0005R4
允许将可调用对象作为非类型模板参数传递给 std::not_fn 202306L <functional> (C++26) P2714R1
__cpp_lib_null_iterators LegacyForwardIterators 201304L <iterator> (C++14) N3644
__cpp_lib_optional std::optional 201606L <optional> (C++17) P0220R1
P0032R3
P0307R2
完全 constexpr std::optional 202106L <optional> (C++20)
(DR)
P2231R1
一元操作std::optional 202110L <optional> (C++23) P0798R8
LWG3621
__cpp_lib_optional_range_support std::optional 范围支持 202406L <optional> (C++26) P3168R2
__cpp_lib_out_ptr std::out_ptr, std::inout_ptr 202106L <memory> (C++23) P1132R7
独立的 std::out_ptr, std::inout_ptr 202311L <memory> (C++26) P2833R2
__cpp_lib_parallel_algorithm 并行算法 201603L <algorithm> <numeric> (C++17) P0024R2
__cpp_lib_polymorphic_allocator std::pmr::polymorphic_allocator<> 作为词汇类型 201902L <memory_resource> (C++20) P0339R6
LWG3437
__cpp_lib_print 格式化输出 202207L <ostream> <print> (C++23) P2093R14
允许 std::print 的高效实现 202403L (C++23)
(DR)
P3107R5 P3235R3
使用 std::println 打印空白行 202403L (C++26) P3142R0
__cpp_lib_quoted_string_io std::quoted 201304L <iomanip> (C++14) N3654
__cpp_lib_philox_engine std::philox_engine: 基于计数器的随机数引擎 202406L <random> (C++26) P2075R6
__cpp_lib_ranges 范围库受限算法 201911L <algorithm> <functional> <iterator> <memory> <ranges> (C++20) P0896R4
P1035R7
P1716R3
默认可初始化的 视图 202106L (C++20)
(DR)
P2325R3
视图 带有 所有权 202110L (C++20)
(DR)
P2415R2
std::ranges::range_adaptor_closure 202202L (C++23) P2387R3
放宽 范围适配器 允许移动类型 202207L (C++23) P2494R2
移除 ranges::begin, ranges::end, ranges::rbegin, ranges::rend, 和 ranges::size 中的“毒丸”重载 202211L (C++23) P2602R2
放宽范围以允许某些投影 202302L (C++23) P2609R3
从间接可调用概念中删除通用引用要求 202406L (C++20)
(DR)
P2997R1
__cpp_lib_ranges_as_const std::const_iterator, std::ranges::as_const_view 202207L <ranges> (C++23) P2278R4
使 std::basic_const_iterator 遵循其底层类型的可转换性 202311L <ranges> (C++26) P2836R1
__cpp_lib_ranges_as_rvalue std::ranges::as_rvalue_view 202207L <ranges> (C++23) P2446R2
__cpp_lib_ranges_cartesian_product std::ranges::cartesian_product_view 202207L <ranges> (C++23) P2374R4
P2540R1
__cpp_lib_ranges_chunk std::ranges::chunk_view 202202L <ranges> (C++23) P2442R1
__cpp_lib_ranges_chunk_by std::ranges::chunk_by_view 202202L <ranges> (C++23) P2443R1
__cpp_lib_ranges_concat std::views::concat 202403L <ranges> (C++26) P2542R8
__cpp_lib_ranges_contains std::ranges::contains 202207L <algorithm> (C++23) P2302R4
__cpp_lib_ranges_enumerate std::ranges::enumerate_view 202302L <ranges> (C++23) P2164R9
__cpp_lib_ranges_find_last std::find_last(), std::find_last(), 和 std::find_last() 202207L <algorithm> (C++23) P1223R5
LWG3807
__cpp_lib_ranges_fold std::ranges 折叠算法 202207L <algorithm> (C++23) P2322R6
__cpp_lib_ranges_generate_random 随机数生成的向量 API (std::ranges::generate_random) 202403L <random> (C++26) P1068R11
__cpp_lib_ranges_iota std::ranges::iota 202202L <numeric> (C++23) P2440R1
__cpp_lib_ranges_join_with std::ranges::join_with_view 202202L <ranges> (C++23) P2441R2
__cpp_lib_ranges_repeat std::ranges::repeat_view 202207L <ranges> (C++23) P2474R2
__cpp_lib_ranges_slide std::ranges::slide_view 202202L <ranges> (C++23) P2442R1
__cpp_lib_ranges_starts_ends_with std::ranges::starts_with, std::ranges::ends_with 202106L <algorithm> (C++23) P1659R3
__cpp_lib_ranges_stride std::ranges::stride_view 202207L <ranges> (C++23) P1899R3
__cpp_lib_ranges_to_container std::ranges::to 202202L <ranges> (C++23) P1206R7
__cpp_lib_ranges_zip std::ranges::zip_view, std::ranges::zip_transform_view, std::ranges::adjacent_view, std::ranges::adjacent_transform_view 202110L <ranges> <tuple> <utility> (C++23) P2321R2
__cpp_lib_ratio 添加新的 2022 年 SI 前缀 202306L <ratio> (C++26) P2734R0
__cpp_lib_raw_memory_algorithms 扩展内存管理工具 201606L <memory> (C++17) P0040R3
__cpp_lib_rcu 读写更新 (RCU) 202306L <rcu> (C++26) P2545R4
__cpp_lib_reference_from_temporary std::reference_constructs_from_temporarystd::reference_converts_from_temporary 202202L <type_traits> (C++23) P2255R2
__cpp_lib_reference_wrapper 用于 std::reference_wrapper 的比较 202403L <functional> (C++26) P2944R3
__cpp_lib_remove_cvref std::remove_cvref 201711L <type_traits> (C++20) P0550R2
__cpp_lib_result_of_sfinae std::result_ofSFINAE 201210L <type_traits> <functional> (C++14) N3462
__cpp_lib_robust_nonmodifying_seq_ops 使非修改序列操作更健壮(std::mismatchstd::equalstd::is_permutation 的双范围重载) 201304L <algorithm> (C++14) N3671
__cpp_lib_sample std::sample 201603L <algorithm> (C++17) P0220R1
__cpp_lib_saturation_arithmetic 饱和算术 202311L <numeric> (C++26) P0543R3
__cpp_lib_scoped_lock std::scoped_lock 201703L <mutex> (C++17) P0156R2
__cpp_lib_semaphore std::counting_semaphore, std::binary_semaphore 201907L <semaphore> (C++20) P1135R6
__cpp_lib_senders std::execution: 发送者-接收者执行控制模型 202406L <execution> (C++26) P2300R10
__cpp_lib_shared_mutex std::shared_mutex(非计时) 201505L <shared_mutex> (C++17) N4508
__cpp_lib_shared_ptr_arrays std::shared_ptr<T[]> 201611L <memory> (C++17) P0497R0
std::make_shared 的数组支持 201707L <memory> (C++20) P0674R1
__cpp_lib_shared_ptr_weak_type shared_ptr::weak_type 201606L <memory> (C++17) P0163R0
__cpp_lib_shared_timed_mutex std::shared_timed_mutex 201402L <shared_mutex> (C++14) N3891
__cpp_lib_shift std::shift_leftstd::shift_right 201806L <algorithm> (C++20) P0769R2
std::ranges::shift_leftstd::ranges::shift_right 202202L <algorithm> (C++23) P2440R1
__cpp_lib_smart_ptr_for_overwrite 使用默认初始化创建智能指针 (std::allocate_shared_for_overwrite, std::make_shared_for_overwrite, std::make_unique_for_overwrite) 202002L <memory> (C++20) P1020R1
P1973R1
__cpp_lib_smart_ptr_owner_equality 启用将 std::weak_ptr 用作 无序关联容器 中的键 202306L <memory> (C++26) P1901R2
__cpp_lib_source_location 源代码信息捕获 (std::source_location) 201907L <source_location> (C++20) P1208R6
__cpp_lib_span std::span 202002L <span> (C++20) P0122R7
LWG3274
P1024R3
P1976R2
使 std::span 的部分独立 202311L <span> (C++26) P2821R5
P2833R2
__cpp_lib_span_initializer_list 从初始化列表构造 std::span 202311L <span> (C++26) P2447R6
__cpp_lib_spanstream std::spanbuf, std::spanstream 202106L <spanstream> (C++23) P0448R4
__cpp_lib_ssize std::ssize 和无符号 std::span::size 201902L <iterator> (C++20) P1227R2
__cpp_lib_sstream_from_string_view std::stringstreamstd::string_view 互操作 202306L <sstream> (C++26) P2495R3
__cpp_lib_stacktrace 堆栈跟踪库 202011L <stacktrace> (C++23) P0881R7
__cpp_lib_start_lifetime_as 显式生命周期管理 (std::start_lifetime_as) 202207L <memory> (C++23) P2590R2
__cpp_lib_starts_ends_with 字符串前缀和后缀检查 (starts_with()ends_with() 用于 std::stringstd::string_view) 201711L <string> <string_view> (C++20) P0457R2
__cpp_lib_stdatomic_h C 原子操作的兼容性头文件 202011L <stdatomic.h> (C++23) P0943R6
__cpp_lib_string_contains contains 函数 of std::basic_stringstd::basic_string_view 202011L <string> <string_view> (C++23) P1679R3
__cpp_lib_string_resize_and_overwrite std::basic_string::resize_and_overwrite 202110L <string> (C++23) P1072R10
__cpp_lib_string_udls 字符串类型的用户定义文字 201304L <string> (C++14) N3642
__cpp_lib_string_view std::string_view 201606L <string> <string_view> (C++17) P0220R1
P0254R2
ConstexprIterator 201803L <string> <string_view> (C++20) P0858R0
LWG3257
连接 std::strings 和 std::string_views 202403L <string> <string_view> (C++26) P2591R5
__cpp_lib_submdspan std::submdspan 202306L <mdspan> (C++26) P2630R4
填充的 mdspan 布局 202403L <mdspan> (C++26) P2642R6
__cpp_lib_syncbuf 同步缓冲输出流(std::syncbufstd::osyncstream)和操纵器 201803L <syncstream> (C++20) P0053R7
P0753R2
__cpp_lib_text_encoding std::text_encoding 202306L <text_encoding> (C++26) P1885R12
__cpp_lib_three_way_comparison 三方比较(库支持);将三方比较添加到库中 201907L <compare> (C++20) P0768R1
P1614R2
__cpp_lib_to_address 将指针转换为原始指针的实用程序(std::to_address 201711L <memory> (C++20) P0653R2
__cpp_lib_to_array std::to_array 201907L <array> (C++20) P0325R4
__cpp_lib_to_chars 基本字符串转换(std::to_charsstd::from_chars 201611L <charconv> (C++17) P0067R5
P0682R1
LWG3137
测试<charconv>函数的成功或失败 202306L <charconv> (C++26) P2497R0
__cpp_lib_to_string 根据std::format重新定义std::to_string 202306L <string> (C++26) P2587R3
__cpp_lib_to_underlying std::to_underlying 202102L <utility> (C++23) P1682R2
__cpp_lib_transformation_trait_aliases TransformationTraits 的别名模板 201304L <type_traits> (C++14) N3655
__cpp_lib_transparent_operators 透明运算符仿函数(std::less<> 等) 201210L <functional> (C++14) N3421
透明 std::owner_less (std::owner_less<void>) 201510L <memory> <functional> (C++17) P0074R0
__cpp_lib_tuple_element_t std::tuple_element_t 201402L <tuple> (C++14) N3887
__cpp_lib_tuple_like std::tuple 和元组类对象(std::pairstd::arraystd::subrange)之间的兼容性 202207L <map> <tuple> <unordered_map> <utility> (C++23) P2165R4
将元组协议添加到std::complex 202311L (C++26) P2819R2
__cpp_lib_tuples_by_type 按类型寻址元组 201304L <tuple> <utility> (C++14) N3670
__cpp_lib_type_identity std::type_identity 201806L <type_traits> (C++20) P0887R1
__cpp_lib_type_trait_variable_templates 类型特征变量模板(std::is_void_v 等) 201510L <type_traits> (C++17) P0006R0
__cpp_lib_uncaught_exceptions std::uncaught_exceptions 201411L <exception> (C++17) N4259
__cpp_lib_unordered_map_try_emplace std::unordered_map::try_emplacestd::unordered_map::insert_or_assign 201411L <unordered_map> (C++17) N4279
__cpp_lib_unreachable std::unreachable 202202L <utility> (C++23) P0627R6
__cpp_lib_unwrap_ref std::unwrap_ref_decaystd::unwrap_reference 201811L <type_traits> (C++20) P0318R1
LWG3348
__cpp_lib_variant std::variant:C++17 的类型安全联合 201606L <variant> (C++17) P0088R3
P0393R3
P0032R3
std::visit 用于从 std::variant 派生的类 202102L <variant> (C++17)
(DR)
P2162R2
完全 constexpr std::variant 202106L <variant> (C++20)
(DR)
P2231R1
成员 visit 202306L <variant> (C++26) P2637R3
__cpp_lib_void_t std::void_t 201411L <type_traits> (C++17) N3911
宏总数:240

[edit] 示例

[edit] 正常使用

#ifdef __has_include                           // Check if __has_include is present
#  if __has_include(<optional>)                // Check for a standard library
#    include <optional>
#  elif __has_include(<experimental/optional>) // Check for an experimental version
#    include <experimental/optional>
#  elif __has_include(<boost/optional.hpp>)    // Try with an external library
#    include <boost/optional.hpp>
#  else                                        // Not found at all
#     error "Missing <optional>"
#  endif
#endif
 
#ifdef __has_cpp_attribute                      // Check if __has_cpp_attribute is present
#  if __has_cpp_attribute(deprecated)           // Check for an attribute
#    define DEPRECATED(msg) [[deprecated(msg)]]
#  endif
#endif
#ifndef DEPRECATED
#    define DEPRECATED(msg)
#endif
 
DEPRECATED("foo() has been deprecated") void foo();
 
#if __cpp_constexpr >= 201304                // Check for a specific version of a feature
#  define CONSTEXPR constexpr
#else
#  define CONSTEXPR inline
#endif
 
CONSTEXPR int bar(unsigned i)
{
#if __cpp_binary_literals                    // Check for the presence of a feature
    unsigned mask1 = 0b11000000;
    unsigned mask2 = 0b00000111;
#else
    unsigned mask1 = 0xC0;
    unsigned mask2 = 0x07;
#endif
    if (i & mask1)
        return 1;
    if (i & mask2)
        return 2;
    return 0;
}
 
int main() {}

[edit] 编译器功能转储

以下(与 C++11 兼容)程序转储 C++ 编译器功能和属性。注意,使用 __has_cpp_attribute() 不符合规范,并且取决于 gcc/clang 实现。

static constexpr struct change_these_options_to_select_what_will_be_printed
{
    constexpr static int longest_macro_name { 45 };
    constexpr static bool titles               = 1;
    constexpr static bool counters             = 1;
    constexpr static bool attributes           = 1;
    constexpr static bool standard_values      = 1;
    constexpr static bool compiler_specific    = 1;
    constexpr static bool core_features        = 1;
    constexpr static bool lib_features         = 1;
    constexpr static bool supported_features   = 1;
    constexpr static bool unsupported_features = 1;
    constexpr static bool sort_by_date         = 0;
    constexpr static bool separate_year_month  = 1;
    constexpr static bool separated_revisions  = 1;
    constexpr static bool latest_revisions     = 1;
    constexpr static bool cxx98                = 0;
    constexpr static bool cxx11                = 1;
    constexpr static bool cxx14                = 1;
    constexpr static bool cxx17                = 1;
    constexpr static bool cxx20                = 1;
    constexpr static bool cxx23                = 1;
    constexpr static bool cxx26                = 1;
    constexpr static bool cxx29                = 0;
} print;
 
#if __cplusplus < 201100
#  error "C++11 or better is required"
#endif
 
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <utility>
#include <vector>
 
#ifdef __has_include
# if __has_include(<version>)
#   include <version>
# endif
#endif
 
// Expect a string that starts with 6-decimal-digits or with '_' (if unsupported)
#define COMPILER_VALUE_INT(n) #n [0] == '_' ? 0 : \
    (#n[5] - '0') + (#n[4] - '0') * 10 + (#n[3] - '0') * 100 + \
    (#n[2] - '0') * 1000 + (#n[1] - '0') * 10000 + (#n[0] - '0') * 100000
#define COMPILER_FEATURE_ENTRY(expect, name) { #name, COMPILER_VALUE_INT(name), expect },
 
#if defined(__has_cpp_attribute) && defined(__GNUG__)
# define COMPILER_ATTRIBUTE(expect, name) { #name, __has_cpp_attribute(name), expect },
#else
# define COMPILER_ATTRIBUTE(expect, name) { #name, COMPILER_VALUE_INT(name), expect },
#endif
 
#define COMPILER_SPECIFIC_STRING(value) #value
#define COMPILER_SPECIFIC_ENTRY(name) { #name, COMPILER_SPECIFIC_STRING(name) },
 
class CompilerFeature
{
    char const* name_; long data_; long std_;
public:
    constexpr CompilerFeature(char const* name, long data, long std)
        : name_(name), data_(data), std_(std) {}
    constexpr CompilerFeature(CompilerFeature const&) = default;
    CompilerFeature& operator=(CompilerFeature const&) = default;
    bool operator<(CompilerFeature const& rhs) const
        { return std::strcmp(name_, rhs.name_) < 0; }
    bool operator==(CompilerFeature const& rhs) const
        { return std::strcmp(name_, rhs.name_) == 0; }
    constexpr bool supported() const { return data_ >= std_; }
    constexpr bool maybe() const { return data_ > 0; }
    constexpr char const* name() const { return name_; }
    constexpr long std() const { return std_; }
    constexpr long data() const { return data_; }
    void data(long x) { data_ = x; }
};
 
static /*constexpr*/ std::pair<const char*, const char*> compiler[] = {
    COMPILER_SPECIFIC_ENTRY(__cplusplus) //< not compiler specific, but useful :)
    COMPILER_SPECIFIC_ENTRY(__clang_major__)
    COMPILER_SPECIFIC_ENTRY(__clang_minor__)
    COMPILER_SPECIFIC_ENTRY(__clang_patchlevel__)
    COMPILER_SPECIFIC_ENTRY(__GNUG__)
    COMPILER_SPECIFIC_ENTRY(__GNUC_MINOR__)
    COMPILER_SPECIFIC_ENTRY(__GNUC_PATCHLEVEL__)
    // Add your favorite compiler specific macros. Undefined ones will not be printed.
};
 
static constexpr CompilerFeature cxx98_core[] = {
    COMPILER_FEATURE_ENTRY(199711L, __cpp_exceptions)
    COMPILER_FEATURE_ENTRY(199711L, __cpp_rtti)
};
 
static constexpr CompilerFeature cxx11_core[] = {
    COMPILER_FEATURE_ENTRY(200704L, __cpp_alias_templates)
    COMPILER_FEATURE_ENTRY(200809L, __cpp_attributes)
    COMPILER_FEATURE_ENTRY(200704L, __cpp_constexpr)
    COMPILER_FEATURE_ENTRY(201711L, __cpp_constexpr_in_decltype)
    COMPILER_FEATURE_ENTRY(200707L, __cpp_decltype)
    COMPILER_FEATURE_ENTRY(200604L, __cpp_delegating_constructors)
    COMPILER_FEATURE_ENTRY(201511L, __cpp_inheriting_constructors)
    COMPILER_FEATURE_ENTRY(200806L, __cpp_initializer_lists)
    COMPILER_FEATURE_ENTRY(200907L, __cpp_lambdas)
    COMPILER_FEATURE_ENTRY(200809L, __cpp_nsdmi)
    COMPILER_FEATURE_ENTRY(200907L, __cpp_range_based_for)
    COMPILER_FEATURE_ENTRY(200710L, __cpp_raw_strings)
    COMPILER_FEATURE_ENTRY(200710L, __cpp_ref_qualifiers)
    COMPILER_FEATURE_ENTRY(200610L, __cpp_rvalue_references)
    COMPILER_FEATURE_ENTRY(200410L, __cpp_static_assert)
    COMPILER_FEATURE_ENTRY(200806L, __cpp_threadsafe_static_init)
    COMPILER_FEATURE_ENTRY(200704L, __cpp_unicode_characters)
    COMPILER_FEATURE_ENTRY(200710L, __cpp_unicode_literals)
    COMPILER_FEATURE_ENTRY(200809L, __cpp_user_defined_literals)
    COMPILER_FEATURE_ENTRY(200704L, __cpp_variadic_templates)
};
 
static constexpr CompilerFeature cxx14_core[] = {
    COMPILER_FEATURE_ENTRY(201304L, __cpp_aggregate_nsdmi)
    COMPILER_FEATURE_ENTRY(201304L, __cpp_binary_literals)
    COMPILER_FEATURE_ENTRY(201304L, __cpp_constexpr)
    COMPILER_FEATURE_ENTRY(201304L, __cpp_decltype_auto)
    COMPILER_FEATURE_ENTRY(201304L, __cpp_generic_lambdas)
    COMPILER_FEATURE_ENTRY(201304L, __cpp_init_captures)
    COMPILER_FEATURE_ENTRY(201304L, __cpp_return_type_deduction)
    COMPILER_FEATURE_ENTRY(201309L, __cpp_sized_deallocation)
    COMPILER_FEATURE_ENTRY(201304L, __cpp_variable_templates)
};
static constexpr CompilerFeature cxx14_lib[] = {
    COMPILER_FEATURE_ENTRY(201304L, __cpp_lib_chrono_udls)
    COMPILER_FEATURE_ENTRY(201309L, __cpp_lib_complex_udls)
    COMPILER_FEATURE_ENTRY(201304L, __cpp_lib_exchange_function)
    COMPILER_FEATURE_ENTRY(201304L, __cpp_lib_generic_associative_lookup)
    COMPILER_FEATURE_ENTRY(201304L, __cpp_lib_integer_sequence)
    COMPILER_FEATURE_ENTRY(201304L, __cpp_lib_integral_constant_callable)
    COMPILER_FEATURE_ENTRY(201402L, __cpp_lib_is_final)
    COMPILER_FEATURE_ENTRY(201309L, __cpp_lib_is_null_pointer)
    COMPILER_FEATURE_ENTRY(201402L, __cpp_lib_make_reverse_iterator)
    COMPILER_FEATURE_ENTRY(201304L, __cpp_lib_make_unique)
    COMPILER_FEATURE_ENTRY(201304L, __cpp_lib_null_iterators)
    COMPILER_FEATURE_ENTRY(201304L, __cpp_lib_quoted_string_io)
    COMPILER_FEATURE_ENTRY(201210L, __cpp_lib_result_of_sfinae)
    COMPILER_FEATURE_ENTRY(201304L, __cpp_lib_robust_nonmodifying_seq_ops)
    COMPILER_FEATURE_ENTRY(201402L, __cpp_lib_shared_timed_mutex)
    COMPILER_FEATURE_ENTRY(201304L, __cpp_lib_string_udls)
    COMPILER_FEATURE_ENTRY(201304L, __cpp_lib_transformation_trait_aliases)
    COMPILER_FEATURE_ENTRY(201210L, __cpp_lib_transparent_operators)
    COMPILER_FEATURE_ENTRY(201402L, __cpp_lib_tuple_element_t)
    COMPILER_FEATURE_ENTRY(201304L, __cpp_lib_tuples_by_type)
};
 
static constexpr CompilerFeature cxx17_core[] = {
    COMPILER_FEATURE_ENTRY(201603L, __cpp_aggregate_bases)
    COMPILER_FEATURE_ENTRY(201606L, __cpp_aligned_new)
    COMPILER_FEATURE_ENTRY(201603L, __cpp_capture_star_this)
    COMPILER_FEATURE_ENTRY(201603L, __cpp_constexpr)
    COMPILER_FEATURE_ENTRY(201703L, __cpp_deduction_guides)
    COMPILER_FEATURE_ENTRY(201411L, __cpp_enumerator_attributes)
    COMPILER_FEATURE_ENTRY(201603L, __cpp_fold_expressions)
    COMPILER_FEATURE_ENTRY(201606L, __cpp_guaranteed_copy_elision)
    COMPILER_FEATURE_ENTRY(201603L, __cpp_hex_float)
    COMPILER_FEATURE_ENTRY(201606L, __cpp_if_constexpr)
    COMPILER_FEATURE_ENTRY(201606L, __cpp_inline_variables)
    COMPILER_FEATURE_ENTRY(201411L, __cpp_namespace_attributes)
    COMPILER_FEATURE_ENTRY(201510L, __cpp_noexcept_function_type)
    COMPILER_FEATURE_ENTRY(201411L, __cpp_nontype_template_args)
    COMPILER_FEATURE_ENTRY(201606L, __cpp_nontype_template_parameter_auto)
    COMPILER_FEATURE_ENTRY(201603L, __cpp_range_based_for)
    COMPILER_FEATURE_ENTRY(201411L, __cpp_static_assert)
    COMPILER_FEATURE_ENTRY(201606L, __cpp_structured_bindings)
    COMPILER_FEATURE_ENTRY(201611L, __cpp_template_template_args)
    COMPILER_FEATURE_ENTRY(201611L, __cpp_variadic_using)
};
static constexpr CompilerFeature cxx17_lib[] = {
    COMPILER_FEATURE_ENTRY(201603L, __cpp_lib_addressof_constexpr)
    COMPILER_FEATURE_ENTRY(201411L, __cpp_lib_allocator_traits_is_always_equal)
    COMPILER_FEATURE_ENTRY(201606L, __cpp_lib_any)
    COMPILER_FEATURE_ENTRY(201603L, __cpp_lib_apply)
    COMPILER_FEATURE_ENTRY(201603L, __cpp_lib_array_constexpr)
    COMPILER_FEATURE_ENTRY(201510L, __cpp_lib_as_const)
    COMPILER_FEATURE_ENTRY(201603L, __cpp_lib_atomic_is_always_lock_free)
    COMPILER_FEATURE_ENTRY(201505L, __cpp_lib_bool_constant)
    COMPILER_FEATURE_ENTRY(201603L, __cpp_lib_boyer_moore_searcher)
    COMPILER_FEATURE_ENTRY(201603L, __cpp_lib_byte)
    COMPILER_FEATURE_ENTRY(201611L, __cpp_lib_chrono)
    COMPILER_FEATURE_ENTRY(201603L, __cpp_lib_clamp)
    COMPILER_FEATURE_ENTRY(201603L, __cpp_lib_enable_shared_from_this)
    COMPILER_FEATURE_ENTRY(201603L, __cpp_lib_execution)
    COMPILER_FEATURE_ENTRY(201703L, __cpp_lib_filesystem)
    COMPILER_FEATURE_ENTRY(201606L, __cpp_lib_gcd_lcm)
    COMPILER_FEATURE_ENTRY(201703L, __cpp_lib_hardware_interference_size)
    COMPILER_FEATURE_ENTRY(201606L, __cpp_lib_has_unique_object_representations)
    COMPILER_FEATURE_ENTRY(201603L, __cpp_lib_hypot)
    COMPILER_FEATURE_ENTRY(201505L, __cpp_lib_incomplete_container_elements)
    COMPILER_FEATURE_ENTRY(201411L, __cpp_lib_invoke)
    COMPILER_FEATURE_ENTRY(201703L, __cpp_lib_is_aggregate)
    COMPILER_FEATURE_ENTRY(201703L, __cpp_lib_is_invocable)
    COMPILER_FEATURE_ENTRY(201603L, __cpp_lib_is_swappable)
    COMPILER_FEATURE_ENTRY(201606L, __cpp_lib_launder)
    COMPILER_FEATURE_ENTRY(201510L, __cpp_lib_logical_traits)
    COMPILER_FEATURE_ENTRY(201606L, __cpp_lib_make_from_tuple)
    COMPILER_FEATURE_ENTRY(201411L, __cpp_lib_map_try_emplace)
    COMPILER_FEATURE_ENTRY(201603L, __cpp_lib_math_special_functions)
    COMPILER_FEATURE_ENTRY(201603L, __cpp_lib_memory_resource)
    COMPILER_FEATURE_ENTRY(201606L, __cpp_lib_node_extract)
    COMPILER_FEATURE_ENTRY(201411L, __cpp_lib_nonmember_container_access)
    COMPILER_FEATURE_ENTRY(201603L, __cpp_lib_not_fn)
    COMPILER_FEATURE_ENTRY(201606L, __cpp_lib_optional)
    COMPILER_FEATURE_ENTRY(201603L, __cpp_lib_parallel_algorithm)
    COMPILER_FEATURE_ENTRY(201606L, __cpp_lib_raw_memory_algorithms)
    COMPILER_FEATURE_ENTRY(201603L, __cpp_lib_sample)
    COMPILER_FEATURE_ENTRY(201703L, __cpp_lib_scoped_lock)
    COMPILER_FEATURE_ENTRY(201505L, __cpp_lib_shared_mutex)
    COMPILER_FEATURE_ENTRY(201611L, __cpp_lib_shared_ptr_arrays)
    COMPILER_FEATURE_ENTRY(201606L, __cpp_lib_shared_ptr_weak_type)
    COMPILER_FEATURE_ENTRY(201606L, __cpp_lib_string_view)
    COMPILER_FEATURE_ENTRY(201611L, __cpp_lib_to_chars)
    COMPILER_FEATURE_ENTRY(201510L, __cpp_lib_transparent_operators)
    COMPILER_FEATURE_ENTRY(201510L, __cpp_lib_type_trait_variable_templates)
    COMPILER_FEATURE_ENTRY(201411L, __cpp_lib_uncaught_exceptions)
    COMPILER_FEATURE_ENTRY(201411L, __cpp_lib_unordered_map_try_emplace)
    COMPILER_FEATURE_ENTRY(202102L, __cpp_lib_variant)
    COMPILER_FEATURE_ENTRY(201411L, __cpp_lib_void_t)
};
 
static constexpr CompilerFeature cxx20_core[] = {
    COMPILER_FEATURE_ENTRY(201902L, __cpp_aggregate_paren_init)
    COMPILER_FEATURE_ENTRY(202207L, __cpp_char8_t)
    COMPILER_FEATURE_ENTRY(202002L, __cpp_concepts)
    COMPILER_FEATURE_ENTRY(201806L, __cpp_conditional_explicit)
    COMPILER_FEATURE_ENTRY(202211L, __cpp_consteval)
    COMPILER_FEATURE_ENTRY(202002L, __cpp_constexpr)
    COMPILER_FEATURE_ENTRY(201907L, __cpp_constexpr_dynamic_alloc)
    COMPILER_FEATURE_ENTRY(201907L, __cpp_constinit)
    COMPILER_FEATURE_ENTRY(201907L, __cpp_deduction_guides)
    COMPILER_FEATURE_ENTRY(201707L, __cpp_designated_initializers)
    COMPILER_FEATURE_ENTRY(201707L, __cpp_generic_lambdas)
    COMPILER_FEATURE_ENTRY(201902L, __cpp_impl_coroutine)
    COMPILER_FEATURE_ENTRY(201806L, __cpp_impl_destroying_delete)
    COMPILER_FEATURE_ENTRY(201907L, __cpp_impl_three_way_comparison)
    COMPILER_FEATURE_ENTRY(201803L, __cpp_init_captures)
    COMPILER_FEATURE_ENTRY(201907L, __cpp_modules)
    COMPILER_FEATURE_ENTRY(201911L, __cpp_nontype_template_args)
    COMPILER_FEATURE_ENTRY(201907L, __cpp_using_enum)
};
static constexpr CompilerFeature cxx20_lib[] = {
    COMPILER_FEATURE_ENTRY(201811L, __cpp_lib_array_constexpr)
    COMPILER_FEATURE_ENTRY(201811L, __cpp_lib_assume_aligned)
    COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_atomic_flag_test)
    COMPILER_FEATURE_ENTRY(201711L, __cpp_lib_atomic_float)
    COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_atomic_lock_free_type_aliases)
    COMPILER_FEATURE_ENTRY(201806L, __cpp_lib_atomic_ref)
    COMPILER_FEATURE_ENTRY(201711L, __cpp_lib_atomic_shared_ptr)
    COMPILER_FEATURE_ENTRY(201911L, __cpp_lib_atomic_value_initialization)
    COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_atomic_wait)
    COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_barrier)
    COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_bind_front)
    COMPILER_FEATURE_ENTRY(201806L, __cpp_lib_bit_cast)
    COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_bitops)
    COMPILER_FEATURE_ENTRY(201902L, __cpp_lib_bounded_array_traits)
    COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_char8_t)
    COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_chrono)
    COMPILER_FEATURE_ENTRY(202002L, __cpp_lib_concepts)
    COMPILER_FEATURE_ENTRY(201806L, __cpp_lib_constexpr_algorithms)
    COMPILER_FEATURE_ENTRY(201711L, __cpp_lib_constexpr_complex)
    COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_constexpr_dynamic_alloc)
    COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_constexpr_functional)
    COMPILER_FEATURE_ENTRY(201811L, __cpp_lib_constexpr_iterator)
    COMPILER_FEATURE_ENTRY(201811L, __cpp_lib_constexpr_memory)
    COMPILER_FEATURE_ENTRY(201911L, __cpp_lib_constexpr_numeric)
    COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_constexpr_string)
    COMPILER_FEATURE_ENTRY(201811L, __cpp_lib_constexpr_string_view)
    COMPILER_FEATURE_ENTRY(201811L, __cpp_lib_constexpr_tuple)
    COMPILER_FEATURE_ENTRY(201811L, __cpp_lib_constexpr_utility)
    COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_constexpr_vector)
    COMPILER_FEATURE_ENTRY(201902L, __cpp_lib_coroutine)
    COMPILER_FEATURE_ENTRY(201806L, __cpp_lib_destroying_delete)
    COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_endian)
    COMPILER_FEATURE_ENTRY(202002L, __cpp_lib_erase_if)
    COMPILER_FEATURE_ENTRY(201902L, __cpp_lib_execution)
    COMPILER_FEATURE_ENTRY(202110L, __cpp_lib_format)
    COMPILER_FEATURE_ENTRY(201811L, __cpp_lib_generic_unordered_lookup)
    COMPILER_FEATURE_ENTRY(202002L, __cpp_lib_int_pow2)
    COMPILER_FEATURE_ENTRY(202002L, __cpp_lib_integer_comparison_functions)
    COMPILER_FEATURE_ENTRY(201902L, __cpp_lib_interpolate)
    COMPILER_FEATURE_ENTRY(201811L, __cpp_lib_is_constant_evaluated)
    COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_is_layout_compatible)
    COMPILER_FEATURE_ENTRY(201806L, __cpp_lib_is_nothrow_convertible)
    COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_is_pointer_interconvertible)
    COMPILER_FEATURE_ENTRY(201911L, __cpp_lib_jthread)
    COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_latch)
    COMPILER_FEATURE_ENTRY(201806L, __cpp_lib_list_remove_return_type)
    COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_math_constants)
    COMPILER_FEATURE_ENTRY(202106L, __cpp_lib_optional)
    COMPILER_FEATURE_ENTRY(201902L, __cpp_lib_polymorphic_allocator)
    COMPILER_FEATURE_ENTRY(202110L, __cpp_lib_ranges)
    COMPILER_FEATURE_ENTRY(201711L, __cpp_lib_remove_cvref)
    COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_semaphore)
    COMPILER_FEATURE_ENTRY(201707L, __cpp_lib_shared_ptr_arrays)
    COMPILER_FEATURE_ENTRY(201806L, __cpp_lib_shift)
    COMPILER_FEATURE_ENTRY(202002L, __cpp_lib_smart_ptr_for_overwrite)
    COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_source_location)
    COMPILER_FEATURE_ENTRY(202002L, __cpp_lib_span)
    COMPILER_FEATURE_ENTRY(201902L, __cpp_lib_ssize)
    COMPILER_FEATURE_ENTRY(201711L, __cpp_lib_starts_ends_with)
    COMPILER_FEATURE_ENTRY(201803L, __cpp_lib_string_view)
    COMPILER_FEATURE_ENTRY(201803L, __cpp_lib_syncbuf)
    COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_three_way_comparison)
    COMPILER_FEATURE_ENTRY(201711L, __cpp_lib_to_address)
    COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_to_array)
    COMPILER_FEATURE_ENTRY(201806L, __cpp_lib_type_identity)
    COMPILER_FEATURE_ENTRY(201811L, __cpp_lib_unwrap_ref)
    COMPILER_FEATURE_ENTRY(202106L, __cpp_lib_variant)
};
 
static constexpr CompilerFeature cxx23_core[] = {
    COMPILER_FEATURE_ENTRY(202110L, __cpp_auto_cast)
    COMPILER_FEATURE_ENTRY(202211L, __cpp_constexpr)
    COMPILER_FEATURE_ENTRY(202110L, __cpp_explicit_this_parameter)
    COMPILER_FEATURE_ENTRY(202106L, __cpp_if_consteval)
    COMPILER_FEATURE_ENTRY(202207L, __cpp_implicit_move)
    COMPILER_FEATURE_ENTRY(202211L, __cpp_multidimensional_subscript)
    COMPILER_FEATURE_ENTRY(202207L, __cpp_named_character_escapes)
    COMPILER_FEATURE_ENTRY(202211L, __cpp_range_based_for)
    COMPILER_FEATURE_ENTRY(202011L, __cpp_size_t_suffix)
    COMPILER_FEATURE_ENTRY(202207L, __cpp_static_call_operator)
};
static constexpr CompilerFeature cxx23_lib[] = {
    COMPILER_FEATURE_ENTRY(202106L, __cpp_lib_adaptor_iterator_pair_constructor)
    COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_algorithm_iterator_requirements)
    COMPILER_FEATURE_ENTRY(202302L, __cpp_lib_allocate_at_least)
    COMPILER_FEATURE_ENTRY(202110L, __cpp_lib_associative_heterogeneous_erasure)
    COMPILER_FEATURE_ENTRY(202302L, __cpp_lib_barrier)
    COMPILER_FEATURE_ENTRY(202202L, __cpp_lib_bind_back)
    COMPILER_FEATURE_ENTRY(202110L, __cpp_lib_byteswap)
    COMPILER_FEATURE_ENTRY(202302L, __cpp_lib_common_reference)
    COMPILER_FEATURE_ENTRY(202302L, __cpp_lib_common_reference_wrapper)
    COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_concepts)
    COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_constexpr_bitset)
    COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_constexpr_charconv)
    COMPILER_FEATURE_ENTRY(202202L, __cpp_lib_constexpr_cmath)
    COMPILER_FEATURE_ENTRY(202202L, __cpp_lib_constexpr_memory)
    COMPILER_FEATURE_ENTRY(202106L, __cpp_lib_constexpr_typeinfo)
    COMPILER_FEATURE_ENTRY(202202L, __cpp_lib_containers_ranges)
    COMPILER_FEATURE_ENTRY(202211L, __cpp_lib_expected)
    COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_flat_map)
    COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_flat_set)
    COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_format)
    COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_format_ranges)
    COMPILER_FEATURE_ENTRY(202302L, __cpp_lib_formatters)
    COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_forward_like)
    COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_generator)
    COMPILER_FEATURE_ENTRY(202106L, __cpp_lib_invoke_r)
    COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_ios_noreplace)
    COMPILER_FEATURE_ENTRY(202302L, __cpp_lib_is_implicit_lifetime)
    COMPILER_FEATURE_ENTRY(202011L, __cpp_lib_is_scoped_enum)
    COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_mdspan)
    COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_modules)
    COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_move_iterator_concept)
    COMPILER_FEATURE_ENTRY(202110L, __cpp_lib_move_only_function)
    COMPILER_FEATURE_ENTRY(202110L, __cpp_lib_optional)
    COMPILER_FEATURE_ENTRY(202106L, __cpp_lib_out_ptr)
    COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_print)
    COMPILER_FEATURE_ENTRY(202302L, __cpp_lib_ranges)
    COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_ranges_as_const)
    COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_ranges_as_rvalue)
    COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_ranges_cartesian_product)
    COMPILER_FEATURE_ENTRY(202202L, __cpp_lib_ranges_chunk)
    COMPILER_FEATURE_ENTRY(202202L, __cpp_lib_ranges_chunk_by)
    COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_ranges_contains)
    COMPILER_FEATURE_ENTRY(202302L, __cpp_lib_ranges_enumerate)
    COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_ranges_find_last)
    COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_ranges_fold)
    COMPILER_FEATURE_ENTRY(202202L, __cpp_lib_ranges_iota)
    COMPILER_FEATURE_ENTRY(202202L, __cpp_lib_ranges_join_with)
    COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_ranges_repeat)
    COMPILER_FEATURE_ENTRY(202202L, __cpp_lib_ranges_slide)
    COMPILER_FEATURE_ENTRY(202106L, __cpp_lib_ranges_starts_ends_with)
    COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_ranges_stride)
    COMPILER_FEATURE_ENTRY(202202L, __cpp_lib_ranges_to_container)
    COMPILER_FEATURE_ENTRY(202110L, __cpp_lib_ranges_zip)
    COMPILER_FEATURE_ENTRY(202202L, __cpp_lib_reference_from_temporary)
    COMPILER_FEATURE_ENTRY(202202L, __cpp_lib_shift)
    COMPILER_FEATURE_ENTRY(202106L, __cpp_lib_spanstream)
    COMPILER_FEATURE_ENTRY(202011L, __cpp_lib_stacktrace)
    COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_start_lifetime_as)
    COMPILER_FEATURE_ENTRY(202011L, __cpp_lib_stdatomic_h)
    COMPILER_FEATURE_ENTRY(202011L, __cpp_lib_string_contains)
    COMPILER_FEATURE_ENTRY(202110L, __cpp_lib_string_resize_and_overwrite)
    COMPILER_FEATURE_ENTRY(202102L, __cpp_lib_to_underlying)
    COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_tuple_like)
    COMPILER_FEATURE_ENTRY(202202L, __cpp_lib_unreachable)
};
 
static constexpr CompilerFeature cxx26_core[] = {
    //< Continue to Populate
    COMPILER_FEATURE_ENTRY(202406L, __cpp_constexpr)
    COMPILER_FEATURE_ENTRY(202403L, __cpp_deleted_function)
    COMPILER_FEATURE_ENTRY(202406L, __cpp_fold_expressions)
    COMPILER_FEATURE_ENTRY(202311L, __cpp_pack_indexing)
    COMPILER_FEATURE_ENTRY(202306L, __cpp_placeholder_variables)
    COMPILER_FEATURE_ENTRY(202306L, __cpp_static_assert)
    COMPILER_FEATURE_ENTRY(202406L, __cpp_structured_bindings)
    COMPILER_FEATURE_ENTRY(202403L, __cpp_variadic_friend)
};
static constexpr CompilerFeature cxx26_lib[] = {
    //< Continue to Populate
    COMPILER_FEATURE_ENTRY(202403L, __cpp_lib_algorithm_default_value_type)
    COMPILER_FEATURE_ENTRY(202311L, __cpp_lib_associative_heterogeneous_insertion)
    COMPILER_FEATURE_ENTRY(202403L, __cpp_lib_atomic_min_max)
    COMPILER_FEATURE_ENTRY(202306L, __cpp_lib_bind_back)
    COMPILER_FEATURE_ENTRY(202306L, __cpp_lib_bind_front)
    COMPILER_FEATURE_ENTRY(202306L, __cpp_lib_bitset)
    COMPILER_FEATURE_ENTRY(202306L, __cpp_lib_chrono)
    COMPILER_FEATURE_ENTRY(202306L, __cpp_lib_constexpr_algorithms)
    COMPILER_FEATURE_ENTRY(202306L, __cpp_lib_constexpr_cmath)
    COMPILER_FEATURE_ENTRY(202306L, __cpp_lib_constexpr_complex)
    COMPILER_FEATURE_ENTRY(202406L, __cpp_lib_constexpr_new)
    COMPILER_FEATURE_ENTRY(202403L, __cpp_lib_constrained_equality)
    COMPILER_FEATURE_ENTRY(202306L, __cpp_lib_copyable_function)
    COMPILER_FEATURE_ENTRY(202403L, __cpp_lib_debugging)
    COMPILER_FEATURE_ENTRY(202311L, __cpp_lib_format)
    COMPILER_FEATURE_ENTRY(202403L, __cpp_lib_format_path)
    COMPILER_FEATURE_ENTRY(202311L, __cpp_lib_format_uchar)
    COMPILER_FEATURE_ENTRY(202311L, __cpp_lib_freestanding_algorithm)
    COMPILER_FEATURE_ENTRY(202311L, __cpp_lib_freestanding_array)
    COMPILER_FEATURE_ENTRY(202306L, __cpp_lib_freestanding_char_traits)
    COMPILER_FEATURE_ENTRY(202306L, __cpp_lib_freestanding_charconv)
    COMPILER_FEATURE_ENTRY(202306L, __cpp_lib_freestanding_cstdlib)
    COMPILER_FEATURE_ENTRY(202311L, __cpp_lib_freestanding_cstring)
    COMPILER_FEATURE_ENTRY(202306L, __cpp_lib_freestanding_cwchar)
    COMPILER_FEATURE_ENTRY(202306L, __cpp_lib_freestanding_errc)
    COMPILER_FEATURE_ENTRY(202311L, __cpp_lib_freestanding_expected)
    COMPILER_FEATURE_ENTRY(202306L, __cpp_lib_freestanding_feature_test_macros)
    COMPILER_FEATURE_ENTRY(202306L, __cpp_lib_freestanding_functional)
    COMPILER_FEATURE_ENTRY(202306L, __cpp_lib_freestanding_iterator)
    COMPILER_FEATURE_ENTRY(202311L, __cpp_lib_freestanding_mdspan)
    COMPILER_FEATURE_ENTRY(202306L, __cpp_lib_freestanding_memory)
    COMPILER_FEATURE_ENTRY(202311L, __cpp_lib_freestanding_numeric)
    COMPILER_FEATURE_ENTRY(202306L, __cpp_lib_freestanding_operator_new)
    COMPILER_FEATURE_ENTRY(202311L, __cpp_lib_freestanding_optional)
    COMPILER_FEATURE_ENTRY(202306L, __cpp_lib_freestanding_ranges)
    COMPILER_FEATURE_ENTRY(202306L, __cpp_lib_freestanding_ratio)
    COMPILER_FEATURE_ENTRY(202311L, __cpp_lib_freestanding_string_view)
    COMPILER_FEATURE_ENTRY(202306L, __cpp_lib_freestanding_tuple)
    COMPILER_FEATURE_ENTRY(202306L, __cpp_lib_freestanding_utility)
    COMPILER_FEATURE_ENTRY(202311L, __cpp_lib_freestanding_variant)
    COMPILER_FEATURE_ENTRY(202306L, __cpp_lib_fstream_native_handle)
    COMPILER_FEATURE_ENTRY(202306L, __cpp_lib_function_ref)
    COMPILER_FEATURE_ENTRY(202306L, __cpp_lib_hazard_pointer)
    COMPILER_FEATURE_ENTRY(202406L, __cpp_lib_inplace_vector)
    COMPILER_FEATURE_ENTRY(202406L, __cpp_lib_is_virtual_base_of)
    COMPILER_FEATURE_ENTRY(202306L, __cpp_lib_is_within_lifetime)
    COMPILER_FEATURE_ENTRY(202311L, __cpp_lib_linalg)
    COMPILER_FEATURE_ENTRY(202406L, __cpp_lib_mdspan)
    COMPILER_FEATURE_ENTRY(202306L, __cpp_lib_not_fn)
    COMPILER_FEATURE_ENTRY(202311L, __cpp_lib_out_ptr)
    COMPILER_FEATURE_ENTRY(202406L, __cpp_lib_optional_range_support)
    COMPILER_FEATURE_ENTRY(202406L, __cpp_lib_philox_engine)
    COMPILER_FEATURE_ENTRY(202403L, __cpp_lib_print)
    COMPILER_FEATURE_ENTRY(202406L, __cpp_lib_ranges)
    COMPILER_FEATURE_ENTRY(202311L, __cpp_lib_ranges_as_const)
    COMPILER_FEATURE_ENTRY(202403L, __cpp_lib_ranges_concat)
    COMPILER_FEATURE_ENTRY(202403L, __cpp_lib_ranges_generate_random)
    COMPILER_FEATURE_ENTRY(202306L, __cpp_lib_ratio)
    COMPILER_FEATURE_ENTRY(202306L, __cpp_lib_rcu)
    COMPILER_FEATURE_ENTRY(202403L, __cpp_lib_reference_wrapper)
    COMPILER_FEATURE_ENTRY(202311L, __cpp_lib_saturation_arithmetic)
    COMPILER_FEATURE_ENTRY(202406L, __cpp_lib_senders)
    COMPILER_FEATURE_ENTRY(202306L, __cpp_lib_smart_ptr_owner_equality)
    COMPILER_FEATURE_ENTRY(202311L, __cpp_lib_span)
    COMPILER_FEATURE_ENTRY(202311L, __cpp_lib_span_initializer_list)
    COMPILER_FEATURE_ENTRY(202306L, __cpp_lib_sstream_from_string_view)
    COMPILER_FEATURE_ENTRY(202403L, __cpp_lib_string_view)
    COMPILER_FEATURE_ENTRY(202403L, __cpp_lib_submdspan)
    COMPILER_FEATURE_ENTRY(202306L, __cpp_lib_text_encoding)
    COMPILER_FEATURE_ENTRY(202306L, __cpp_lib_to_chars)
    COMPILER_FEATURE_ENTRY(202306L, __cpp_lib_to_string)
    COMPILER_FEATURE_ENTRY(202311L, __cpp_lib_tuple_like)
    COMPILER_FEATURE_ENTRY(202306L, __cpp_lib_variant)
};
 
static constexpr CompilerFeature cxx29_core[] = {
    //< Continue to Populate
    COMPILER_FEATURE_ENTRY(202604L, __cpp_core_TODO)
};
static constexpr CompilerFeature cxx29_lib[] = {
    //< Continue to Populate
    COMPILER_FEATURE_ENTRY(202604L, __cpp_lib_TODO)
};
 
static constexpr CompilerFeature attributes[] = {
    COMPILER_ATTRIBUTE(202207L, assume)
    COMPILER_ATTRIBUTE(200809L, carries_dependency)
    COMPILER_ATTRIBUTE(201309L, deprecated)
    COMPILER_ATTRIBUTE(201603L, fallthrough)
    COMPILER_ATTRIBUTE(202403L, indeterminate)
    COMPILER_ATTRIBUTE(201803L, likely)
    COMPILER_ATTRIBUTE(201603L, maybe_unused)
    COMPILER_ATTRIBUTE(201803L, no_unique_address)
    COMPILER_ATTRIBUTE(201907L, nodiscard)
    COMPILER_ATTRIBUTE(200809L, noreturn)
    COMPILER_ATTRIBUTE(201803L, unlikely)
};
 
inline void show_compiler_specific_info()
{
    std::printf("Compiler specific macros:\n");
    for (auto co : compiler)
        if (std::strcmp(co.first, co.second))
            std::printf("%*s %s\n", -print.longest_macro_name, co.first, co.second);
}
 
inline void print_compiler_feature(const CompilerFeature& x)
{
    if (not ((print.supported_features and x.maybe()) or
            (print.unsupported_features and not x.maybe())))
        return;
    auto print_year_month = [](long n)
    {
        return std::printf("%ld%s%02ld",
            n / 100, print.separate_year_month ? "-" : "", n % 100);
    };
    std::printf("%*s ", -print.longest_macro_name, x.name());
    x.maybe() ? print_year_month(x.data()) :
                    std::printf("------%s", print.separate_year_month ? "-" : "");
    if (print.standard_values)
        std::printf("  %c  ", (x.supported() ? (x.data() > x.std() ? '>' : '=') : '<')),
            print_year_month(x.std());
    std::puts("");
}
 
template<class Container>
inline void show(char const* const title, Container const& co)
{
    if (print.titles)
    {
        std::printf("%-s (", title);
        if (print.counters)
        {
            std::printf("%zd/", std::count_if(std::begin(co), std::end(co),
                [](CompilerFeature x)
                {
                    return x.supported();
                }));
        }
        std::printf("%td)\n", std::distance(std::begin(co), std::end(co)));
    }
    if (print.sort_by_date)
    {
        std::vector<CompilerFeature> v(std::begin(co), std::end(co));
        std::stable_sort(v.begin(), v.end(),
            [](CompilerFeature const& lhs, CompilerFeature const& rhs)
            {
                return lhs.data() < rhs.data();
            });
        std::for_each(v.cbegin(), v.cend(), print_compiler_feature);
    }
    else
        std::for_each(std::begin(co), std::end(co), print_compiler_feature);
    std::puts("");
}
 
inline void show_latest()
{
    auto latest_rev = []() -> int
    {
        return print.cxx29 ? 29 : print.cxx26 ? 26 : print.cxx23 ? 23 : print.cxx20 ? 20 :
               print.cxx17 ? 17 : print.cxx14 ? 14 : print.cxx11 ? 11 : 98;
    };
    std::vector<CompilerFeature> latest;
    auto add = [&latest](CompilerFeature x)
    {
        auto i = std::lower_bound(latest.begin(), latest.end(), x);
        if (i == latest.end() or not (*i == x))
            latest.insert(i, x);
        else if (i->data() < x.data())
            i->data(x.data());
    };
    char text[64];
    latest.reserve(512); // max macros
    if (print.core_features)
    {   // preserve reverse revision insertion order!
        if (print.cxx29) std::for_each(std::begin(cxx29_core), std::end(cxx29_core), add);
        if (print.cxx26) std::for_each(std::begin(cxx26_core), std::end(cxx26_core), add);
        if (print.cxx23) std::for_each(std::begin(cxx23_core), std::end(cxx23_core), add);
        if (print.cxx20) std::for_each(std::begin(cxx20_core), std::end(cxx20_core), add);
        if (print.cxx17) std::for_each(std::begin(cxx17_core), std::end(cxx17_core), add);
        if (print.cxx14) std::for_each(std::begin(cxx14_core), std::end(cxx14_core), add);
        if (print.cxx11) std::for_each(std::begin(cxx11_core), std::end(cxx11_core), add);
        if (print.cxx98) std::for_each(std::begin(cxx98_core), std::end(cxx98_core), add);
        std::snprintf(text, sizeof text, "ALL CORE MACROS UP TO C++%02i", latest_rev());
        show(text, latest);
    }
    latest.clear();
    if (print.lib_features)
    {   // preserve reverse revision insertion order!
        if (print.cxx29) std::for_each(std::begin(cxx29_lib), std::end(cxx29_lib), add);
        if (print.cxx26) std::for_each(std::begin(cxx26_lib), std::end(cxx26_lib), add);
        if (print.cxx23) std::for_each(std::begin(cxx23_lib), std::end(cxx23_lib), add);
        if (print.cxx20) std::for_each(std::begin(cxx20_lib), std::end(cxx20_lib), add);
        if (print.cxx17) std::for_each(std::begin(cxx17_lib), std::end(cxx17_lib), add);
        if (print.cxx14) std::for_each(std::begin(cxx14_lib), std::end(cxx14_lib), add);
        std::snprintf(text, sizeof text, "ALL LIB MACROS UP TO C++%02i", latest_rev());
        show(text, latest);
    }
}
 
int main()
{
    if (print.separated_revisions)
    {
        if (print.cxx98 and print.core_features) show("C++98 CORE", cxx98_core);
        if (print.cxx11 and print.core_features) show("C++11 CORE", cxx11_core);
        if (print.cxx14 and print.core_features) show("C++14 CORE", cxx14_core);
        if (print.cxx14 and print.lib_features ) show("C++14 LIB" , cxx14_lib);
        if (print.cxx17 and print.core_features) show("C++17 CORE", cxx17_core);
        if (print.cxx17 and print.lib_features ) show("C++17 LIB" , cxx17_lib);
        if (print.cxx20 and print.core_features) show("C++20 CORE", cxx20_core);
        if (print.cxx20 and print.lib_features ) show("C++20 LIB" , cxx20_lib);
        if (print.cxx23 and print.core_features) show("C++23 CORE", cxx23_core);
        if (print.cxx23 and print.lib_features ) show("C++23 LIB" , cxx23_lib);
        if (print.cxx26 and print.core_features) show("C++26 CORE", cxx26_core);
        if (print.cxx26 and print.lib_features ) show("C++26 LIB" , cxx26_lib);
        if (print.cxx29 and print.core_features) show("C++29 CORE", cxx29_core);
        if (print.cxx29 and print.lib_features ) show("C++29 LIB" , cxx29_lib);
    }
    if (print.latest_revisions) show_latest();
    if (print.attributes) show("ATTRIBUTES", attributes);
    if (print.compiler_specific) show_compiler_specific_info();
}

可能的输出

C++11 CORE (20/20)
__cpp_alias_templates                         2007-04  =  2007-04
__cpp_attributes                              2008-09  =  2008-09
__cpp_constexpr                               2022-11  >  2007-04
__cpp_constexpr_in_decltype                   2017-11  =  2017-11
... truncated ...
 
C++14 CORE (9/9)
__cpp_aggregate_nsdmi                         2013-04  =  2013-04
__cpp_binary_literals                         2013-04  =  2013-04
__cpp_constexpr                               2022-11  >  2013-04
... truncated ...
 
C++14 LIB (20/20)
__cpp_lib_chrono_udls                         2013-04  =  2013-04
__cpp_lib_complex_udls                        2013-09  =  2013-09
__cpp_lib_exchange_function                   2013-04  =  2013-04
... truncated ...
 
... truncated ...
 
C++23 LIB (34/64)
__cpp_lib_adaptor_iterator_pair_constructor   2021-06  =  2021-06
__cpp_lib_algorithm_iterator_requirements     -------  <  2022-07
__cpp_lib_allocate_at_least                   -------  <  2023-02
__cpp_lib_associative_heterogeneous_erasure   -------  <  2021-10
__cpp_lib_barrier                             2019-07  <  2023-02
... truncated ...
 
ALL CORE MACROS UP TO C++26 (59/68)
__cpp_aggregate_bases                         2016-03  =  2016-03
__cpp_aggregate_nsdmi                         2013-04  =  2013-04
__cpp_aggregate_paren_init                    2019-02  =  2019-02
__cpp_alias_templates                         2007-04  =  2007-04
... truncated ...
 
ALL LIB MACROS UP TO C++26 (146/227)
__cpp_lib_adaptor_iterator_pair_constructor   2021-06  =  2021-06
__cpp_lib_addressof_constexpr                 2016-03  =  2016-03
__cpp_lib_algorithm_iterator_requirements     -------  <  2022-07
__cpp_lib_allocate_at_least                   -------  <  2023-02
__cpp_lib_allocator_traits_is_always_equal    2014-11  =  2014-11
... truncated ...
 
ATTRIBUTES (9/10)
assume                                        2022-07  =  2022-07
carries_dependency                            -------  <  2008-09
deprecated                                    2013-09  =  2013-09
fallthrough                                   2016-03  =  2016-03
... truncated ...
 
Compiler specific macros:
__cplusplus                                   202100L
__GNUG__                                      13
__GNUC_MINOR__                                1
__GNUC_PATCHLEVEL__                           1

[edit] 缺陷报告

以下行为变更缺陷报告被追溯应用于先前发布的 C++ 标准。

DR 应用于 发布的行为 正确行为
P2552R3 C++20 __has_cpp_attribute 必须扩展为标准属性的非零值 可以扩展为 0

[edit] 另请参阅

库功能测试宏 (C++20) 在头文件中定义 <version>
预定义宏符号
宏符号索引

[edit] 外部链接

1.  关于功能测试建议的官方文档
2.  转储编译器功能的源代码