Feature testing (C++20)
The standard defines a set of preprocessor macros corresponding to C++ language and library features introduced in C++11 or later. They are intended as a simple and portable way to detect the presence of said features.
Attributes
__has_cpp_attribute( attribute-token )
|
|||||||||
Checks for the presence of an attribute named by attribute-token (after macro expansion).
For standard attributes, it will expand to the year and month in which the attribute was added to the working draft (see table below), the presence of vendor-specific attributes is determined by a non-zero value.
__has_cpp_attribute
can be expanded in the expression of
#if and
#elif.
It is treated as a defined macro by
#ifdef,
#ifndef and defined but cannot be used anywhere else.
attribute-token | Attribute | Value | Standard |
---|---|---|---|
carries_dependency
|
[[carries_dependency]]
|
200809L | (C++11) |
deprecated
|
[[deprecated]]
|
201309L | (C++14) |
fallthrough
|
[[fallthrough]]
|
201603L | (C++17) |
likely
|
[[likely]]
|
201803L | (C++20) |
maybe_unused
|
[[maybe_unused]]
|
201603L | (C++17) |
no_unique_address
|
[[no_unique_address]]
|
201803L | (C++20) |
nodiscard
|
[[nodiscard]]
|
201603L | (C++17) |
201907L | (C++20) | ||
noreturn
|
[[noreturn]]
|
200809L | (C++11) |
unlikely
|
[[unlikely]]
|
201803L | (C++20) |
Language features
The following macros are predefined in every translation unit. Each macro expands to an integer literal corresponding to the year and month when the corresponding feature has been included in the working draft.
When a feature changes significantly, the macro will be updated accordingly.
Macro name | Feature | Value | Std |
---|---|---|---|
__cpp_aggregate_bases | Aggregate classes with base classes | 201603L | (C++17) |
__cpp_aggregate_nsdmi | Aggregate classes with default member initializers | 201304L | (C++14) |
__cpp_aggregate_paren_init | Aggregate initialization in the form of direct initialization | 201902L | (C++20) |
__cpp_alias_templates | Alias templates | 200704L | (C++11) |
__cpp_aligned_new | Dynamic memory allocation for over-aligned data | 201606L | (C++17) |
__cpp_attributes | Attributes | 200809L | (C++11) |
__cpp_binary_literals | Binary literals | 201304L | (C++14) |
__cpp_capture_star_this | Lambda capture of *this by value as [=,*this] | 201603L | (C++17) |
__cpp_char8_t | char8_t | 201811L | (C++20) |
__cpp_concepts | Concepts | 201907L | (C++20) |
Conditional trivial special member functions | 202002L | (C++20) | |
__cpp_conditional_explicit | explicit(bool) |
201806L | (C++20) |
__cpp_consteval | Immediate functions | 201811L | (C++20) |
__cpp_constexpr | constexpr | 200704L | (C++11) |
Relaxed constexpr , non-const constexpr methods |
201304L | (C++14) | |
Constexpr lambda | 201603L | (C++17) | |
Trivial default initialization and asm-declaration in constexpr functions | 201907L | (C++20) | |
Changing the active member of a union in constant evaluation | 202002L | (C++20) | |
Non-literal variables, labels, and goto statements in constexpr functions | 202110L | (C++23) | |
__cpp_constexpr_dynamic_alloc | Operations for dynamic storage duration in constexpr functions | 201907L | (C++20) |
__cpp_constexpr_in_decltype | Generation of function and variable definitions when needed for constant evaluation | 201711L | (C++11)(DR) |
__cpp_constinit | constinit | 201907L | (C++20) |
__cpp_decltype | decltype | 200707L | (C++11) |
__cpp_decltype_auto | Return type deduction for normal functions | 201304L | (C++14) |
__cpp_deduction_guides | Template argument deduction for class templates | 201703L | (C++17) |
CTAD for aggregates and aliases | 201907L | (C++20) | |
__cpp_delegating_constructors | Delegating constructors | 200604L | (C++11) |
__cpp_designated_initializers | Designated initializer | 201707L | (C++20) |
__cpp_enumerator_attributes | Attributes for enumerators | 201411L | (C++17) |
__cpp_explicit_this_parameter | Explicit object parameter | 202110L | (C++23) |
__cpp_fold_expressions | Fold expressions | 201603L | (C++17) |
__cpp_generic_lambdas | Generic lambda expressions | 201304L | (C++14) |
Explicit template parameter list for generic lambdas | 201707L | (C++20) | |
__cpp_guaranteed_copy_elision | Guaranteed copy elision through simplified value categories | 201606L | (C++17) |
__cpp_hex_float | Hexadecimal floating literals | 201603L | (C++17) |
__cpp_if_consteval | consteval if |
202106L | (C++23) |
__cpp_if_constexpr | constexpr if |
201606L | (C++17) |
__cpp_impl_coroutine | Coroutines (compiler support) | 201902L | (C++20) |
__cpp_impl_destroying_delete | Destroying operator delete (compiler support) | 201806L | (C++20) |
__cpp_impl_three_way_comparison | Three-way comparison (compiler support) | 201907L | (C++20) |
__cpp_inheriting_constructors | Inheriting constructors | 200802L | (C++11) |
Rewording inheriting constructors | 201511L | (C++11)(DR) | |
__cpp_init_captures | Lambda init-capture | 201304L | (C++14) |
Allow pack expansion in lambda init-capture | 201803L | (C++20) | |
__cpp_initializer_lists | List-initialization and std::initializer_list | 200806L | (C++11) |
__cpp_inline_variables | Inline variables | 201606L | (C++17) |
__cpp_lambdas | Lambda expressions | 200907L | (C++11) |
__cpp_modules | Modules | 201907L | (C++20) |
__cpp_multidimensional_subscript | Multidimensional subscript operator | 202110L | (C++23) |
__cpp_namespace_attributes | Attributes for namespaces | 201411L | (C++17) |
__cpp_noexcept_function_type | Make exception specifications be part of the type system | 201510L | (C++17) |
__cpp_nontype_template_args | Allow constant evaluation for all non-type template arguments | 201411L | (C++17) |
Class types and floating-point types in non-type template parameters | 201911L | (C++20) | |
__cpp_nontype_template_parameter_auto | Declaring non-type template parameters with auto |
201606L | (C++17) |
__cpp_nsdmi | Non-static data member initializers | 200809L | (C++11) |
__cpp_range_based_for | Range-based for loop |
200907L | (C++11) |
Range-based for loop with different begin /end types |
201603L | (C++17) | |
__cpp_raw_strings | Raw string literals | 200710L | (C++11) |
__cpp_ref_qualifiers | ref-qualifiers | 200710L | (C++11) |
__cpp_return_type_deduction | Return type deduction for normal functions | 201304L | (C++14) |
__cpp_rvalue_references | Rvalue reference | 200610L | (C++11) |
__cpp_size_t_suffix | Literal suffixes for size_t and its signed version |
202011L | (C++23) |
__cpp_sized_deallocation | Sized deallocation | 201309L | (C++14) |
__cpp_static_assert | static_assert | 200410L | (C++11) |
Single-argument static_assert |
201411L | (C++17) | |
__cpp_structured_bindings | Structured bindings | 201606L | (C++17) |
__cpp_template_template_args | Matching of template template-arguments | 201611L | (C++17) |
__cpp_threadsafe_static_init | Dynamic initialization and destruction with concurrency | 200806L | (C++11) |
__cpp_unicode_characters | New character types (char16_t and char32_t) | 200704L | (C++11) |
__cpp_unicode_literals | Unicode string literals | 200710L | (C++11) |
__cpp_user_defined_literals | User-defined literals | 200809L | (C++11) |
__cpp_using_enum | using enum | 201907L | (C++20) |
__cpp_variable_templates | Variable templates | 201304L | (C++14) |
__cpp_variadic_templates | Variadic templates | 200704L | (C++11) |
__cpp_variadic_using | Pack expansions in using -declarations |
201611L | (C++17) |
Library features
The following macros are defined if the header <version> or any of the corresponding headers in the table below is included. Each macro expands to an integer literal corresponding to the year and month when the corresponding feature has been included in the working draft.
When a feature changes significantly, the macro will be updated accordingly.
Macro name | Feature | Value | Header | Std |
---|---|---|---|---|
__cpp_lib_adaptor_iterator_pair_constructor | Iterator pair constructors for std::stack and std::queue | 202106L | <stack> <queue> | (C++23) |
__cpp_lib_addressof_constexpr | Constexpr std::addressof | 201603L | <memory> | (C++17) |
__cpp_lib_allocate_at_least | std::allocate_at_least etc. | 202106L | <memory> | (C++23) |
__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) |
__cpp_lib_any | std::any | 201606L | <any> | (C++17) |
__cpp_lib_apply | std::apply | 201603L | <tuple> | (C++17) |
__cpp_lib_array_constexpr | Constexpr for std::reverse_iterator, std::move_iterator, std::array and range access | 201603L | <iterator> <array> | (C++17) |
ConstexprIterator; constexpr comparison for std::array; misc constexpr bits (std::array::fill et al.) | 201811L | <iterator> <array> | (C++20) | |
__cpp_lib_as_const | std::as_const | 201510L | <utility> | (C++17) |
__cpp_lib_associative_heterogeneous_erasure | Heterogeneous erasure in associative containers and unordered associative containers | 202110L | <map> <set> <unordered_map> <unordered_set> | (C++23) |
__cpp_lib_assume_aligned | std::assume_aligned | 201811L | <memory> | (C++20) |
__cpp_lib_atomic_flag_test | std::atomic_flag::test | 201907L | <atomic> | (C++20) |
__cpp_lib_atomic_float | Floating-point atomic | 201711L | <atomic> | (C++20) |
__cpp_lib_atomic_is_always_lock_free | constexpr atomic<T>::is_always_lock_free | 201603L | <atomic> | (C++17) |
__cpp_lib_atomic_lock_free_type_aliases | atomic lockfree integral types (std::atomic_signed_lock_free, std::atomic_unsigned_lock_free) | 201907L | <atomic> | (C++20) |
__cpp_lib_atomic_ref | std::atomic_ref | 201806L | <atomic> | (C++20) |
__cpp_lib_atomic_shared_ptr | std::atomic<std::shared_ptr> | 201711L | <memory> | (C++20) |
__cpp_lib_atomic_value_initialization | Fixing atomic initialization (value-initialize std::atomic by default) | 201911L | <atomic> <memory> | (C++20) |
__cpp_lib_atomic_wait | Efficient std::atomic waiting | 201907L | <atomic> | (C++20) |
__cpp_lib_barrier | std::barrier | 201907L | <barrier> | (C++20) |
__cpp_lib_bind_back | std::bind_back | 202202L | <functional> | (C++23) |
__cpp_lib_bind_front | std::bind_front | 201907L | <functional> | (C++20) |
__cpp_lib_bit_cast | std::bit_cast | 201806L | <bit> | (C++20) |
__cpp_lib_bitops | Bit operations | 201907L | <bit> | (C++20) |
__cpp_lib_bool_constant | std::bool_constant | 201505L | <type_traits> | (C++17) |
__cpp_lib_bounded_array_traits | std::is_bounded_array, std::is_unbounded_array | 201902L | <type_traits> | (C++20) |
__cpp_lib_boyer_moore_searcher | Searchers | 201603L | <functional> | (C++17) |
__cpp_lib_byte | std::byte | 201603L | <cstddef> | (C++17) |
__cpp_lib_byteswap | std::byteswap | 202110L | <bit> | (C++23) |
__cpp_lib_char8_t | Library support for char8_t | 201907L | <atomic> <filesystem> <istream> <limits> <locale> <ostream> <string> <string_view> | (C++20) |
__cpp_lib_chrono | Rounding functions for std::chrono::duration and std::chrono::time_point | 201510L | <chrono> | (C++17) |
Constexpr for all the member functions of std::chrono::duration and std::chrono::time_point | 201611L | <chrono> | (C++17) | |
Calendars and Time Zones | 201907L | <chrono> | (C++20) | |
__cpp_lib_chrono_udls | User-defined literals for time types | 201304L | <chrono> | (C++14) |
__cpp_lib_clamp | std::clamp | 201603L | <algorithm> | (C++17) |
__cpp_lib_complex_udls | User-defined Literals for std::complex |
201309L | <complex> | (C++14) |
__cpp_lib_concepts | Standard library concepts | 202002L | <concepts> | (C++20) |
__cpp_lib_constexpr_algorithms | Constexpr for algorithms | 201806L | <algorithm> | (C++20) |
__cpp_lib_constexpr_cmath | Constexpr for mathematical functions in <cmath> and <cstdlib> | 202202L | <cmath> <cstdlib> | (C++23) |
__cpp_lib_constexpr_complex | Constexpr for std::complex | 201711L | <complex> | (C++20) |
__cpp_lib_constexpr_dynamic_alloc | Constexpr for std::allocator and related utilities | 201907L | <memory> | (C++20) |
__cpp_lib_constexpr_functional | Misc constexpr bits (std::default_searcher); constexpr INVOKE |
201907L | <functional> | (C++20) |
__cpp_lib_constexpr_iterator | Misc constexpr bits (std::insert_iterator et al.) | 201811L | <iterator> | (C++20) |
__cpp_lib_constexpr_memory | Constexpr in std::pointer_traits | 201811L | <memory> | (C++20) |
Constexpr std::unique_ptr | 202202L | <memory> | (C++23) | |
__cpp_lib_constexpr_numeric | Constexpr for algorithms in <numeric> | 201911L | <numeric> | (C++20) |
__cpp_lib_constexpr_string | Constexpr for std::string | 201907L | <string> | (C++20) |
__cpp_lib_constexpr_string_view | Misc constexpr bits (std::string_view::copy) | 201811L | <string_view> | (C++20) |
__cpp_lib_constexpr_tuple | Misc constexpr bits (std::tuple::operator= et al.) | 201811L | <tuple> | (C++20) |
__cpp_lib_constexpr_typeinfo | Constexpr for std::type_info::operator== | 202106L | <typeinfo> | (C++23) |
__cpp_lib_constexpr_utility | Misc constexpr bits (std::pair::operator= et al.) | 201811L | <utility> | (C++20) |
__cpp_lib_constexpr_vector | Constexpr for std::vector | 201907L | <vector> | (C++20) |
__cpp_lib_containers_ranges | Ranges construction and insertion for containers | 202202L | <vector> <list> <forward_list> <map> <set> <unordered_map> <unordered_set> <deque> <queue> <stack> <string> | (C++23) |
__cpp_lib_coroutine | Coroutines (library support) | 201902L | <coroutine> | (C++20) |
__cpp_lib_destroying_delete | Destroying operator delete (library support) |
201806L | <new> | (C++20) |
__cpp_lib_enable_shared_from_this | More precise specification of std::enable_shared_from_this | 201603L | <memory> | (C++17) |
__cpp_lib_endian | std::endian | 201907L | <bit> | (C++20) |
__cpp_lib_erase_if | Uniform container erasure | 202002L | <string> <deque> <forward_list> <list> <vector> <map> <set> <unordered_map> <unordered_set> | (C++20) |
__cpp_lib_exchange_function | std::exchange | 201304L | <utility> | (C++14) |
__cpp_lib_execution | Execution policies | 201603L | <execution> | (C++17) |
std::execution::unsequenced_policy | 201902L | <execution> | (C++20) | |
__cpp_lib_expected | class template std::expected | 202202L | <expected> | (C++23) |
__cpp_lib_filesystem | Filesystem library | 201703L | <filesystem> | (C++17) |
__cpp_lib_format | Text formatting | 201907L | <format> | (C++20) |
Compile-time format string checks; Reducing parameterization of std::vformat_to | 202106L | <format> | (C++20)(DR) | |
Fixing locale handling in chrono formatters; Supporting non-const-formattable types | 202110L | <format> | (C++20)(DR) | |
__cpp_lib_gcd_lcm | std::gcd, std::lcm | 201606L | <numeric> | (C++17) |
__cpp_lib_generic_associative_lookup | Heterogeneous comparison lookup in associative containers | 201304L | <map> <set> | (C++14) |
__cpp_lib_generic_unordered_lookup | Heterogeneous comparison lookup in unordered associative containers | 201811L | <unordered_map> <unordered_set> | (C++20) |
__cpp_lib_hardware_interference_size | constexpr std::hardware_{constructive, destructive}_interference_size | 201703L | <new> | (C++17) |
__cpp_lib_has_unique_object_representations | std::has_unique_object_representations | 201606L | <type_traits> | (C++17) |
__cpp_lib_hypot | 3-argument overload of std::hypot | 201603L | <cmath> | (C++17) |
__cpp_lib_incomplete_container_elements | Minimal incomplete type support for std::forward_list, std::list, and std::vector | 201505L | <forward_list> <list> <vector> | (C++17) |
__cpp_lib_int_pow2 | Integral power-of-2 operations (std::has_single_bit, std::bit_ceil, std::bit_floor, std::bit_width) | 202002L | <bit> | (C++20) |
__cpp_lib_integer_comparison_functions | Integer comparison functions | 202002L | <utility> | (C++20) |
__cpp_lib_integer_sequence | Compile-time integer sequences | 201304L | <utility> | (C++14) |
__cpp_lib_integral_constant_callable | std::integral_constant::operator() | 201304L | <type_traits> | (C++14) |
__cpp_lib_interpolate | std::lerp, std::midpoint | 201902L | <cmath> <numeric> | (C++20) |
__cpp_lib_invoke | std::invoke | 201411L | <functional> | (C++17) |
__cpp_lib_invoke_r | std::invoke_r | 202106L | <functional> | (C++23) |
__cpp_lib_is_aggregate | std::is_aggregate | 201703L | <type_traits> | (C++17) |
__cpp_lib_is_constant_evaluated | std::is_constant_evaluated | 201811L | <type_traits> | (C++20) |
__cpp_lib_is_final | std::is_final | 201402L | <type_traits> | (C++14) |
__cpp_lib_is_invocable | std::is_invocable, std::invoke_result | 201703L | <type_traits> | (C++17) |
__cpp_lib_is_layout_compatible | std::is_layout_compatible | 201907L | <type_traits> | (C++20) |
__cpp_lib_is_nothrow_convertible | std::is_nothrow_convertible | 201806L | <type_traits> | (C++20) |
__cpp_lib_is_null_pointer | std::is_null_pointer | 201309L | <type_traits> | (C++14) |
__cpp_lib_is_pointer_interconvertible | Pointer-interconvertibility traits: std::is_pointer_interconvertible_with_class, std::is_pointer_interconvertible_base_of | 201907L | <type_traits> | (C++20) |
__cpp_lib_is_scoped_enum | std::is_scoped_enum | 202011L | <type_traits> | (C++23) |
__cpp_lib_is_swappable | [nothrow -]swappable traits |
201603L | <type_traits> | (C++17) |
__cpp_lib_jthread | Stop token and joining thread | 201911L | <stop_token> <thread> | (C++20) |
__cpp_lib_latch | std::latch | 201907L | <latch> | (C++20) |
__cpp_lib_launder | Core Issue 1776: Replacement of class objects containing reference members (std::launder) | 201606L | <new> | (C++17) |
__cpp_lib_list_remove_return_type | Change the return type of the remove(), remove_if() and unique() members of std::forward_list and std::list | 201806L | <forward_list> <list> | (C++20) |
__cpp_lib_logical_traits | Logical operator type traits | 201510L | <type_traits> | (C++17) |
__cpp_lib_make_from_tuple | std::make_from_tuple() | 201606L | <tuple> | (C++17) |
__cpp_lib_make_reverse_iterator | std::make_reverse_iterator | 201402L | <iterator> | (C++14) |
__cpp_lib_make_unique | std::make_unique | 201304L | <memory> | (C++14) |
__cpp_lib_map_try_emplace | std::map::try_emplace, std::map::insert_or_assign | 201411L | <map> | (C++17) |
__cpp_lib_math_constants | Mathematical constants | 201907L | <numbers> | (C++20) |
__cpp_lib_math_special_functions | Mathematical special functions for C++17 | 201603L | <cmath> | (C++17) |
__cpp_lib_memory_resource | std::pmr::memory_resource | 201603L | <memory_resource> | (C++17) |
__cpp_lib_move_only_function | std::move_only_function | 202110L | <functional> | (C++23) |
__cpp_lib_node_extract | Splicing maps and sets (std::map::extract, std::map::merge, std::map::insert(node_type), etc) | 201606L | <map> <set> <unordered_map> <unordered_set> | (C++17) |
__cpp_lib_nonmember_container_access | std::size(), std::data() and std::empty() | 201411L | <iterator> <array> <deque> <forward_list> <list> <map> <regex> <set> <string> <unordered_map> <unordered_set> <vector> | (C++17) |
__cpp_lib_not_fn | std::not_fn() | 201603L | <functional> | (C++17) |
__cpp_lib_null_iterators | Null LegacyForwardIterators | 201304L | <iterator> | (C++14) |
__cpp_lib_optional | std::optional | 201606L | <optional> | (C++17) |
Fully constexpr std::optional |
202106L | <optional> | (C++20)(DR) | |
Monadic operations in std::optional | 202110L | <optional> | (C++23) | |
__cpp_lib_out_ptr | std::out_ptr, std::inout_ptr | 202106L | <memory> | (C++23) |
__cpp_lib_parallel_algorithm | Parallel algorithms | 201603L | <algorithm> <numeric> | (C++17) |
__cpp_lib_polymorphic_allocator | std::pmr::polymorphic_allocator<> as a vocabulary type | 201902L | <memory_resource> | (C++20) |
__cpp_lib_quoted_string_io | std::quoted | 201304L | <iomanip> | (C++14) |
__cpp_lib_ranges | Ranges library and constrained algorithms | 201911L | <algorithm> <functional> <iterator> <memory> <ranges> | (C++20) |
Non-default-initializable views | 202106L | (C++20)(DR) | ||
Views with ownership | 202110L | (C++20)(DR) | ||
std::ranges::range_adaptor_closure | 202202L | (C++23) | ||
__cpp_lib_ranges_chunk | std::ranges::chunk_view | 202202L | <ranges> | (C++23) |
__cpp_lib_ranges_chunk_by | std::ranges::chunk_by_view | 202202L | <ranges> | (C++23) |
__cpp_lib_ranges_iota | std::ranges::iota | 202202L | <numeric> | (C++23) |
__cpp_lib_ranges_join_with | std::ranges::join_with_view | 202202L | <ranges> | (C++23) |
__cpp_lib_ranges_slide | std::ranges::slide_view | 202202L | <ranges> | (C++23) |
__cpp_lib_ranges_starts_ends_with | std::ranges::starts_with, std::ranges::ends_with | 202106L | <algorithm> | (C++23) |
__cpp_lib_ranges_to_container | std::ranges::to | 202202L | <ranges> | (C++23) |
__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) |
__cpp_lib_raw_memory_algorithms | Extending memory management tools | 201606L | <memory> | (C++17) |
__cpp_lib_reference_from_temporary | std::reference_constructs_from_temporary and std::reference_converts_from_temporary | 202202L | <type_traits> | (C++23) |
__cpp_lib_remove_cvref | std::remove_cvref | 201711L | <type_traits> | (C++20) |
__cpp_lib_result_of_sfinae | std::result_of and SFINAE | 201210L | <type_traits> <functional> | (C++14) |
__cpp_lib_robust_nonmodifying_seq_ops | Making non-modifying sequence operations more robust (two-range overloads for std::mismatch, std::equal and std::is_permutation) | 201304L | <algorithm> | (C++14) |
__cpp_lib_sample | std::sample | 201603L | <algorithm> | (C++17) |
__cpp_lib_scoped_lock | std::scoped_lock | 201703L | <mutex> | (C++17) |
__cpp_lib_semaphore | std::counting_semaphore , std::binary_semaphore |
201907L | <semaphore> | (C++20) |
__cpp_lib_shared_mutex | std::shared_mutex (untimed) | 201505L | <shared_mutex> | (C++17) |
__cpp_lib_shared_ptr_arrays | std::shared_ptr<T[]> | 201611L | <memory> | (C++17) |
Array support of std::make_shared | 201707L | <memory> | (C++20) | |
__cpp_lib_shared_ptr_weak_type | shared_ptr::weak_type | 201606L | <memory> | (C++17) |
__cpp_lib_shared_timed_mutex | std::shared_timed_mutex | 201402L | <shared_mutex> | (C++14) |
__cpp_lib_shift | std::shift_left and std::shift_right | 201806L | <algorithm> | (C++20) |
std::ranges::shift_left and std::ranges::shift_right | 202202L | <algorithm> | (C++23) | |
__cpp_lib_smart_ptr_for_overwrite | Smart pointer creation with default initialization (std::allocate_shared_for_overwrite, std::make_shared_for_overwrite, std::make_unique_for_overwrite) | 202002L | <memory> | (C++20) |
__cpp_lib_source_location | Source-code information capture (std::source_location) | 201907L | <source_location> | (C++20) |
__cpp_lib_span | std::span | 202002L | <span> | (C++20) |
__cpp_lib_spanstream | std::spanbuf, std::spanstream | 202106L | <spanstream> | (C++23) |
__cpp_lib_ssize | std::ssize and unsigned std::span::size | 201902L | <iterator> | (C++20) |
__cpp_lib_stacktrace | Stacktrace library | 202011L | <stacktrace> | (C++23) |
__cpp_lib_starts_ends_with | String prefix and suffix checking (starts_with() and ends_with() for std::string and std::string_view) | 201711L | <string> <string_view> | (C++20) |
__cpp_lib_stdatomic_h | Compatibility header for C atomic operations | 202011L | <stdatomic.h> | (C++23) |
__cpp_lib_string_contains | contains functions of std::basic_string and std::basic_string_view |
202011L | <string> <string_view> | (C++23) |
__cpp_lib_string_resize_and_overwrite | std::basic_string::resize_and_overwrite | 202110L | <string> | (C++23) |
__cpp_lib_string_udls | User-defined literals for string types | 201304L | <string> | (C++14) |
__cpp_lib_string_view | std::string_view | 201606L | <string> <string_view> | (C++17) |
ConstexprIterator | 201803L | <string> <string_view> | (C++20) | |
__cpp_lib_syncbuf | Synchronized buffered ostream (std::syncbuf, std::osyncstream) and manipulators | 201803L | <syncstream> | (C++20) |
__cpp_lib_three_way_comparison | Three-way comparison (library support); adding three-way comparison to the library | 201907L | <compare> | (C++20) |
__cpp_lib_to_address | Utility to convert a pointer to a raw pointer (std::to_address) | 201711L | <memory> | (C++20) |
__cpp_lib_to_array | std::to_array | 201907L | <array> | (C++20) |
__cpp_lib_to_chars | Elementary string conversions (std::to_chars, std::from_chars) | 201611L | <charconv> | (C++17) |
__cpp_lib_to_underlying | std::to_underlying | 202102L | <utility> | (C++23) |
__cpp_lib_transformation_trait_aliases | Alias templates for TransformationTraits | 201304L | <type_traits> | (C++14) |
__cpp_lib_transparent_operators | Transparent operator functors (std::less<> et al) | 201210L | <functional> | (C++14) |
Transparent std::owner_less (std::owner_less<void>) | 201510L | <memory> <functional> | (C++17) | |
__cpp_lib_tuple_element_t | std::tuple_element_t | 201402L | <tuple> | (C++14) |
__cpp_lib_tuples_by_type | Addressing tuples by type | 201304L | <tuple> <utility> | (C++14) |
__cpp_lib_type_identity | std::type_identity | 201806L | <type_traits> | (C++20) |
__cpp_lib_type_trait_variable_templates | Type traits variable templates (std::is_void_v, etc) | 201510L | <type_traits> | (C++17) |
__cpp_lib_uncaught_exceptions | std::uncaught_exceptions | 201411L | <exception> | (C++17) |
__cpp_lib_unordered_map_try_emplace | std::unordered_map::try_emplace, std::unordered_map::insert_or_assign | 201411L | <unordered_map> | (C++17) |
__cpp_lib_unreachable | std::unreachable | 202202L | <utility> | (C++23) |
__cpp_lib_unwrap_ref | std::unwrap_ref_decay and std::unwrap_reference | 201811L | <type_traits> | (C++20) |
__cpp_lib_variant | std::variant: a type-safe union for C++17 | 201606L | <variant> | (C++17) |
std::visit for classes derived from std::variant | 202102L | <variant> | (C++17)(DR) | |
Fully constexpr std::variant |
202106L | <variant> | (C++20)(DR) | |
__cpp_lib_void_t | std::void_t | 201411L | <type_traits> | (C++17) |
Example
Normal usage
#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() { }
Compiler Features Dump
The following program dumps C++ compiler features and attributes.
// Change these options to print out only necessary info. static struct PrintOptions { constexpr static bool titles = 1; constexpr static bool counters = 1; constexpr static bool attributes = 1; constexpr static bool general_features = 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 = 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 = 0; } print; #if __cplusplus < 201100 # error "C++11 or better is required" #endif #include <algorithm> #include <cstring> #include <iomanip> #include <iostream> #include <string> #ifdef __has_include # if __has_include(<version>) # include <version> # endif #endif #define COMPILER_FEATURE_VALUE(value) #value #define COMPILER_FEATURE_ENTRY(name) { #name, COMPILER_FEATURE_VALUE(name) }, #ifdef __has_cpp_attribute # define COMPILER_ATTRIBUTE_VALUE_AS_STRING(s) #s # define COMPILER_ATTRIBUTE_AS_NUMBER(x) COMPILER_ATTRIBUTE_VALUE_AS_STRING(x) # define COMPILER_ATTRIBUTE_ENTRY(attr) \ { #attr, COMPILER_ATTRIBUTE_AS_NUMBER(__has_cpp_attribute(attr)) }, #else # define COMPILER_ATTRIBUTE_ENTRY(attr) { #attr, "_" }, #endif struct CompilerFeature { CompilerFeature(const char* name = nullptr, const char* value = nullptr) : name(name), value(value) {} const char* name; const char* value; }; static CompilerFeature cxx_core[] = { COMPILER_FEATURE_ENTRY(__cplusplus) COMPILER_FEATURE_ENTRY(__cpp_exceptions) COMPILER_FEATURE_ENTRY(__cpp_rtti) #if 0 COMPILER_FEATURE_ENTRY(__GNUC__) COMPILER_FEATURE_ENTRY(__GNUC_MINOR__) COMPILER_FEATURE_ENTRY(__GNUC_PATCHLEVEL__) COMPILER_FEATURE_ENTRY(__GNUG__) COMPILER_FEATURE_ENTRY(__clang__) COMPILER_FEATURE_ENTRY(__clang_major__) COMPILER_FEATURE_ENTRY(__clang_minor__) COMPILER_FEATURE_ENTRY(__clang_patchlevel__) #endif }; static CompilerFeature cxx11_core[] = { COMPILER_FEATURE_ENTRY(__cpp_alias_templates) COMPILER_FEATURE_ENTRY(__cpp_attributes) COMPILER_FEATURE_ENTRY(__cpp_constexpr) COMPILER_FEATURE_ENTRY(__cpp_decltype) COMPILER_FEATURE_ENTRY(__cpp_delegating_constructors) COMPILER_FEATURE_ENTRY(__cpp_inheriting_constructors) COMPILER_FEATURE_ENTRY(__cpp_initializer_lists) COMPILER_FEATURE_ENTRY(__cpp_lambdas) COMPILER_FEATURE_ENTRY(__cpp_nsdmi) COMPILER_FEATURE_ENTRY(__cpp_range_based_for) COMPILER_FEATURE_ENTRY(__cpp_raw_strings) COMPILER_FEATURE_ENTRY(__cpp_ref_qualifiers) COMPILER_FEATURE_ENTRY(__cpp_rvalue_references) COMPILER_FEATURE_ENTRY(__cpp_static_assert) COMPILER_FEATURE_ENTRY(__cpp_threadsafe_static_init) COMPILER_FEATURE_ENTRY(__cpp_unicode_characters) COMPILER_FEATURE_ENTRY(__cpp_unicode_literals) COMPILER_FEATURE_ENTRY(__cpp_user_defined_literals) COMPILER_FEATURE_ENTRY(__cpp_variadic_templates) }; static CompilerFeature cxx14_core[] = { COMPILER_FEATURE_ENTRY(__cpp_aggregate_nsdmi) COMPILER_FEATURE_ENTRY(__cpp_binary_literals) COMPILER_FEATURE_ENTRY(__cpp_constexpr) COMPILER_FEATURE_ENTRY(__cpp_decltype_auto) COMPILER_FEATURE_ENTRY(__cpp_generic_lambdas) COMPILER_FEATURE_ENTRY(__cpp_init_captures) COMPILER_FEATURE_ENTRY(__cpp_return_type_deduction) COMPILER_FEATURE_ENTRY(__cpp_sized_deallocation) COMPILER_FEATURE_ENTRY(__cpp_variable_templates) }; static CompilerFeature cxx14_lib[] = { COMPILER_FEATURE_ENTRY(__cpp_lib_chrono_udls) COMPILER_FEATURE_ENTRY(__cpp_lib_complex_udls) COMPILER_FEATURE_ENTRY(__cpp_lib_exchange_function) COMPILER_FEATURE_ENTRY(__cpp_lib_generic_associative_lookup) COMPILER_FEATURE_ENTRY(__cpp_lib_integer_sequence) COMPILER_FEATURE_ENTRY(__cpp_lib_integral_constant_callable) COMPILER_FEATURE_ENTRY(__cpp_lib_is_final) COMPILER_FEATURE_ENTRY(__cpp_lib_is_null_pointer) COMPILER_FEATURE_ENTRY(__cpp_lib_make_reverse_iterator) COMPILER_FEATURE_ENTRY(__cpp_lib_make_unique) COMPILER_FEATURE_ENTRY(__cpp_lib_null_iterators) COMPILER_FEATURE_ENTRY(__cpp_lib_quoted_string_io) COMPILER_FEATURE_ENTRY(__cpp_lib_result_of_sfinae) COMPILER_FEATURE_ENTRY(__cpp_lib_robust_nonmodifying_seq_ops) COMPILER_FEATURE_ENTRY(__cpp_lib_shared_timed_mutex) COMPILER_FEATURE_ENTRY(__cpp_lib_string_udls) COMPILER_FEATURE_ENTRY(__cpp_lib_transformation_trait_aliases) COMPILER_FEATURE_ENTRY(__cpp_lib_transparent_operators) COMPILER_FEATURE_ENTRY(__cpp_lib_tuple_element_t) COMPILER_FEATURE_ENTRY(__cpp_lib_tuples_by_type) }; static CompilerFeature cxx17_core[] = { COMPILER_FEATURE_ENTRY(__cpp_aggregate_bases) COMPILER_FEATURE_ENTRY(__cpp_aligned_new) COMPILER_FEATURE_ENTRY(__cpp_capture_star_this) COMPILER_FEATURE_ENTRY(__cpp_constexpr) COMPILER_FEATURE_ENTRY(__cpp_deduction_guides) COMPILER_FEATURE_ENTRY(__cpp_enumerator_attributes) COMPILER_FEATURE_ENTRY(__cpp_fold_expressions) COMPILER_FEATURE_ENTRY(__cpp_guaranteed_copy_elision) COMPILER_FEATURE_ENTRY(__cpp_hex_float) COMPILER_FEATURE_ENTRY(__cpp_if_constexpr) COMPILER_FEATURE_ENTRY(__cpp_inheriting_constructors) COMPILER_FEATURE_ENTRY(__cpp_inline_variables) COMPILER_FEATURE_ENTRY(__cpp_namespace_attributes) COMPILER_FEATURE_ENTRY(__cpp_noexcept_function_type) COMPILER_FEATURE_ENTRY(__cpp_nontype_template_args) COMPILER_FEATURE_ENTRY(__cpp_nontype_template_parameter_auto) COMPILER_FEATURE_ENTRY(__cpp_range_based_for) COMPILER_FEATURE_ENTRY(__cpp_static_assert) COMPILER_FEATURE_ENTRY(__cpp_structured_bindings) COMPILER_FEATURE_ENTRY(__cpp_template_template_args) COMPILER_FEATURE_ENTRY(__cpp_variadic_using) }; static CompilerFeature cxx17_lib[] = { COMPILER_FEATURE_ENTRY(__cpp_lib_addressof_constexpr) COMPILER_FEATURE_ENTRY(__cpp_lib_allocator_traits_is_always_equal) COMPILER_FEATURE_ENTRY(__cpp_lib_any) COMPILER_FEATURE_ENTRY(__cpp_lib_apply) COMPILER_FEATURE_ENTRY(__cpp_lib_array_constexpr) COMPILER_FEATURE_ENTRY(__cpp_lib_as_const) COMPILER_FEATURE_ENTRY(__cpp_lib_atomic_is_always_lock_free) COMPILER_FEATURE_ENTRY(__cpp_lib_bool_constant) COMPILER_FEATURE_ENTRY(__cpp_lib_boyer_moore_searcher) COMPILER_FEATURE_ENTRY(__cpp_lib_byte) COMPILER_FEATURE_ENTRY(__cpp_lib_chrono) COMPILER_FEATURE_ENTRY(__cpp_lib_clamp) COMPILER_FEATURE_ENTRY(__cpp_lib_enable_shared_from_this) COMPILER_FEATURE_ENTRY(__cpp_lib_execution) COMPILER_FEATURE_ENTRY(__cpp_lib_filesystem) COMPILER_FEATURE_ENTRY(__cpp_lib_gcd_lcm) COMPILER_FEATURE_ENTRY(__cpp_lib_hardware_interference_size) COMPILER_FEATURE_ENTRY(__cpp_lib_has_unique_object_representations) COMPILER_FEATURE_ENTRY(__cpp_lib_hypot) COMPILER_FEATURE_ENTRY(__cpp_lib_incomplete_container_elements) COMPILER_FEATURE_ENTRY(__cpp_lib_invoke) COMPILER_FEATURE_ENTRY(__cpp_lib_is_aggregate) COMPILER_FEATURE_ENTRY(__cpp_lib_is_invocable) COMPILER_FEATURE_ENTRY(__cpp_lib_is_swappable) COMPILER_FEATURE_ENTRY(__cpp_lib_launder) COMPILER_FEATURE_ENTRY(__cpp_lib_logical_traits) COMPILER_FEATURE_ENTRY(__cpp_lib_make_from_tuple) COMPILER_FEATURE_ENTRY(__cpp_lib_map_try_emplace) COMPILER_FEATURE_ENTRY(__cpp_lib_math_special_functions) COMPILER_FEATURE_ENTRY(__cpp_lib_memory_resource) COMPILER_FEATURE_ENTRY(__cpp_lib_node_extract) COMPILER_FEATURE_ENTRY(__cpp_lib_nonmember_container_access) COMPILER_FEATURE_ENTRY(__cpp_lib_not_fn) COMPILER_FEATURE_ENTRY(__cpp_lib_optional) COMPILER_FEATURE_ENTRY(__cpp_lib_parallel_algorithm) COMPILER_FEATURE_ENTRY(__cpp_lib_raw_memory_algorithms) COMPILER_FEATURE_ENTRY(__cpp_lib_sample) COMPILER_FEATURE_ENTRY(__cpp_lib_scoped_lock) COMPILER_FEATURE_ENTRY(__cpp_lib_shared_mutex) COMPILER_FEATURE_ENTRY(__cpp_lib_shared_ptr_arrays) COMPILER_FEATURE_ENTRY(__cpp_lib_shared_ptr_weak_type) COMPILER_FEATURE_ENTRY(__cpp_lib_string_view) COMPILER_FEATURE_ENTRY(__cpp_lib_to_chars) COMPILER_FEATURE_ENTRY(__cpp_lib_transparent_operators) COMPILER_FEATURE_ENTRY(__cpp_lib_type_trait_variable_templates) COMPILER_FEATURE_ENTRY(__cpp_lib_uncaught_exceptions) COMPILER_FEATURE_ENTRY(__cpp_lib_unordered_map_try_emplace) COMPILER_FEATURE_ENTRY(__cpp_lib_variant) COMPILER_FEATURE_ENTRY(__cpp_lib_void_t) }; static CompilerFeature cxx20_core[] = { COMPILER_FEATURE_ENTRY(__cpp_aggregate_paren_init) COMPILER_FEATURE_ENTRY(__cpp_char8_t) COMPILER_FEATURE_ENTRY(__cpp_concepts) COMPILER_FEATURE_ENTRY(__cpp_conditional_explicit) COMPILER_FEATURE_ENTRY(__cpp_consteval) COMPILER_FEATURE_ENTRY(__cpp_constexpr) COMPILER_FEATURE_ENTRY(__cpp_constexpr_dynamic_alloc) COMPILER_FEATURE_ENTRY(__cpp_constexpr_in_decltype) COMPILER_FEATURE_ENTRY(__cpp_constinit) COMPILER_FEATURE_ENTRY(__cpp_deduction_guides) COMPILER_FEATURE_ENTRY(__cpp_designated_initializers) COMPILER_FEATURE_ENTRY(__cpp_generic_lambdas) COMPILER_FEATURE_ENTRY(__cpp_impl_coroutine) COMPILER_FEATURE_ENTRY(__cpp_impl_destroying_delete) COMPILER_FEATURE_ENTRY(__cpp_impl_three_way_comparison) COMPILER_FEATURE_ENTRY(__cpp_init_captures) COMPILER_FEATURE_ENTRY(__cpp_modules) COMPILER_FEATURE_ENTRY(__cpp_nontype_template_args) COMPILER_FEATURE_ENTRY(__cpp_using_enum) }; static CompilerFeature cxx20_lib[] = { COMPILER_FEATURE_ENTRY(__cpp_lib_array_constexpr) COMPILER_FEATURE_ENTRY(__cpp_lib_assume_aligned) COMPILER_FEATURE_ENTRY(__cpp_lib_atomic_flag_test) COMPILER_FEATURE_ENTRY(__cpp_lib_atomic_float) COMPILER_FEATURE_ENTRY(__cpp_lib_atomic_lock_free_type_aliases) COMPILER_FEATURE_ENTRY(__cpp_lib_atomic_ref) COMPILER_FEATURE_ENTRY(__cpp_lib_atomic_shared_ptr) COMPILER_FEATURE_ENTRY(__cpp_lib_atomic_value_initialization) COMPILER_FEATURE_ENTRY(__cpp_lib_atomic_wait) COMPILER_FEATURE_ENTRY(__cpp_lib_barrier) COMPILER_FEATURE_ENTRY(__cpp_lib_bind_front) COMPILER_FEATURE_ENTRY(__cpp_lib_bit_cast) COMPILER_FEATURE_ENTRY(__cpp_lib_bitops) COMPILER_FEATURE_ENTRY(__cpp_lib_bounded_array_traits) COMPILER_FEATURE_ENTRY(__cpp_lib_char8_t) COMPILER_FEATURE_ENTRY(__cpp_lib_chrono) COMPILER_FEATURE_ENTRY(__cpp_lib_concepts) COMPILER_FEATURE_ENTRY(__cpp_lib_constexpr_algorithms) COMPILER_FEATURE_ENTRY(__cpp_lib_constexpr_complex) COMPILER_FEATURE_ENTRY(__cpp_lib_constexpr_dynamic_alloc) COMPILER_FEATURE_ENTRY(__cpp_lib_constexpr_functional) COMPILER_FEATURE_ENTRY(__cpp_lib_constexpr_iterator) COMPILER_FEATURE_ENTRY(__cpp_lib_constexpr_memory) COMPILER_FEATURE_ENTRY(__cpp_lib_constexpr_numeric) COMPILER_FEATURE_ENTRY(__cpp_lib_constexpr_string) COMPILER_FEATURE_ENTRY(__cpp_lib_constexpr_string_view) COMPILER_FEATURE_ENTRY(__cpp_lib_constexpr_tuple) COMPILER_FEATURE_ENTRY(__cpp_lib_constexpr_utility) COMPILER_FEATURE_ENTRY(__cpp_lib_constexpr_vector) COMPILER_FEATURE_ENTRY(__cpp_lib_coroutine) COMPILER_FEATURE_ENTRY(__cpp_lib_destroying_delete) COMPILER_FEATURE_ENTRY(__cpp_lib_endian) COMPILER_FEATURE_ENTRY(__cpp_lib_erase_if) COMPILER_FEATURE_ENTRY(__cpp_lib_execution) COMPILER_FEATURE_ENTRY(__cpp_lib_format) COMPILER_FEATURE_ENTRY(__cpp_lib_generic_unordered_lookup) COMPILER_FEATURE_ENTRY(__cpp_lib_int_pow2) COMPILER_FEATURE_ENTRY(__cpp_lib_integer_comparison_functions) COMPILER_FEATURE_ENTRY(__cpp_lib_interpolate) COMPILER_FEATURE_ENTRY(__cpp_lib_is_constant_evaluated) COMPILER_FEATURE_ENTRY(__cpp_lib_is_layout_compatible) COMPILER_FEATURE_ENTRY(__cpp_lib_is_nothrow_convertible) COMPILER_FEATURE_ENTRY(__cpp_lib_is_pointer_interconvertible) COMPILER_FEATURE_ENTRY(__cpp_lib_jthread) COMPILER_FEATURE_ENTRY(__cpp_lib_latch) COMPILER_FEATURE_ENTRY(__cpp_lib_list_remove_return_type) COMPILER_FEATURE_ENTRY(__cpp_lib_math_constants) COMPILER_FEATURE_ENTRY(__cpp_lib_polymorphic_allocator) COMPILER_FEATURE_ENTRY(__cpp_lib_ranges) COMPILER_FEATURE_ENTRY(__cpp_lib_remove_cvref) COMPILER_FEATURE_ENTRY(__cpp_lib_semaphore) COMPILER_FEATURE_ENTRY(__cpp_lib_shared_ptr_arrays) COMPILER_FEATURE_ENTRY(__cpp_lib_shift) COMPILER_FEATURE_ENTRY(__cpp_lib_smart_ptr_for_overwrite) COMPILER_FEATURE_ENTRY(__cpp_lib_source_location) COMPILER_FEATURE_ENTRY(__cpp_lib_span) COMPILER_FEATURE_ENTRY(__cpp_lib_ssize) COMPILER_FEATURE_ENTRY(__cpp_lib_starts_ends_with) COMPILER_FEATURE_ENTRY(__cpp_lib_string_view) COMPILER_FEATURE_ENTRY(__cpp_lib_syncbuf) COMPILER_FEATURE_ENTRY(__cpp_lib_three_way_comparison) COMPILER_FEATURE_ENTRY(__cpp_lib_to_address) COMPILER_FEATURE_ENTRY(__cpp_lib_to_array) COMPILER_FEATURE_ENTRY(__cpp_lib_type_identity) COMPILER_FEATURE_ENTRY(__cpp_lib_unwrap_ref) }; static CompilerFeature cxx23_core[] = { //< Continue to Populate COMPILER_FEATURE_ENTRY(__cpp_char8_t) COMPILER_FEATURE_ENTRY(__cpp_concepts) COMPILER_FEATURE_ENTRY(__cpp_constexpr) COMPILER_FEATURE_ENTRY(__cpp_explicit_this_parameter) COMPILER_FEATURE_ENTRY(__cpp_if_consteval) COMPILER_FEATURE_ENTRY(__cpp_implicit_move) COMPILER_FEATURE_ENTRY(__cpp_multidimensional_subscript) COMPILER_FEATURE_ENTRY(__cpp_named_character_escapes) COMPILER_FEATURE_ENTRY(__cpp_size_t_suffix) COMPILER_FEATURE_ENTRY(__cpp_static_call_operator) }; static CompilerFeature cxx23_lib[] = { //< Continue to Populate COMPILER_FEATURE_ENTRY(__cpp_lib_adaptor_iterator_pair_constructor) COMPILER_FEATURE_ENTRY(__cpp_lib_algorithm_iterator_requirements) COMPILER_FEATURE_ENTRY(__cpp_lib_allocate_at_least) COMPILER_FEATURE_ENTRY(__cpp_lib_associative_heterogeneous_erasure) COMPILER_FEATURE_ENTRY(__cpp_lib_bind_back) COMPILER_FEATURE_ENTRY(__cpp_lib_byteswap) COMPILER_FEATURE_ENTRY(__cpp_lib_concepts) COMPILER_FEATURE_ENTRY(__cpp_lib_constexpr_bitset) COMPILER_FEATURE_ENTRY(__cpp_lib_constexpr_charconv) COMPILER_FEATURE_ENTRY(__cpp_lib_constexpr_cmath) COMPILER_FEATURE_ENTRY(__cpp_lib_constexpr_memory) COMPILER_FEATURE_ENTRY(__cpp_lib_constexpr_typeinfo) COMPILER_FEATURE_ENTRY(__cpp_lib_containers_ranges) COMPILER_FEATURE_ENTRY(__cpp_lib_expected) COMPILER_FEATURE_ENTRY(__cpp_lib_find_last) COMPILER_FEATURE_ENTRY(__cpp_lib_flat_map) COMPILER_FEATURE_ENTRY(__cpp_lib_format) COMPILER_FEATURE_ENTRY(__cpp_lib_forward_like) COMPILER_FEATURE_ENTRY(__cpp_lib_generator) COMPILER_FEATURE_ENTRY(__cpp_lib_invoke_r) COMPILER_FEATURE_ENTRY(__cpp_lib_ios_noreplace) COMPILER_FEATURE_ENTRY(__cpp_lib_is_scoped_enum) COMPILER_FEATURE_ENTRY(__cpp_lib_mdspan) COMPILER_FEATURE_ENTRY(__cpp_lib_move_iterator_concept) COMPILER_FEATURE_ENTRY(__cpp_lib_move_only_function) COMPILER_FEATURE_ENTRY(__cpp_lib_optional) COMPILER_FEATURE_ENTRY(__cpp_lib_out_ptr) COMPILER_FEATURE_ENTRY(__cpp_lib_print) COMPILER_FEATURE_ENTRY(__cpp_lib_ranges) COMPILER_FEATURE_ENTRY(__cpp_lib_ranges_as_const) COMPILER_FEATURE_ENTRY(__cpp_lib_ranges_as_rvalue) COMPILER_FEATURE_ENTRY(__cpp_lib_ranges_cartesian_product) COMPILER_FEATURE_ENTRY(__cpp_lib_ranges_chunk) COMPILER_FEATURE_ENTRY(__cpp_lib_ranges_chunk_by) COMPILER_FEATURE_ENTRY(__cpp_lib_ranges_contains) COMPILER_FEATURE_ENTRY(__cpp_lib_ranges_iota) COMPILER_FEATURE_ENTRY(__cpp_lib_ranges_join_with) COMPILER_FEATURE_ENTRY(__cpp_lib_ranges_repeat) COMPILER_FEATURE_ENTRY(__cpp_lib_ranges_slide) COMPILER_FEATURE_ENTRY(__cpp_lib_ranges_starts_ends_with) COMPILER_FEATURE_ENTRY(__cpp_lib_ranges_stride) COMPILER_FEATURE_ENTRY(__cpp_lib_ranges_to_container) COMPILER_FEATURE_ENTRY(__cpp_lib_ranges_zip) COMPILER_FEATURE_ENTRY(__cpp_lib_reference_from_temporary) COMPILER_FEATURE_ENTRY(__cpp_lib_shift) COMPILER_FEATURE_ENTRY(__cpp_lib_spanstream) COMPILER_FEATURE_ENTRY(__cpp_lib_stacktrace) COMPILER_FEATURE_ENTRY(__cpp_lib_start_lifetime_as) COMPILER_FEATURE_ENTRY(__cpp_lib_stdatomic_h) COMPILER_FEATURE_ENTRY(__cpp_lib_string_contains) COMPILER_FEATURE_ENTRY(__cpp_lib_string_resize_and_overwrite) COMPILER_FEATURE_ENTRY(__cpp_lib_to_underlying) COMPILER_FEATURE_ENTRY(__cpp_lib_tuple_like) COMPILER_FEATURE_ENTRY(__cpp_lib_unreachable) COMPILER_FEATURE_ENTRY(__cpp_lib_variant) COMPILER_FEATURE_ENTRY(__cpp_lib_fold) }; static CompilerFeature cxx26_core[] = { //< Populate COMPILER_FEATURE_ENTRY(__cpp_core_TODO) }; static CompilerFeature cxx26_lib[] = { //< Populate COMPILER_FEATURE_ENTRY(__cpp_lib_TODO) }; static CompilerFeature attributes[] = { COMPILER_ATTRIBUTE_ENTRY(assume) COMPILER_ATTRIBUTE_ENTRY(carries_dependency) COMPILER_ATTRIBUTE_ENTRY(deprecated) COMPILER_ATTRIBUTE_ENTRY(fallthrough) COMPILER_ATTRIBUTE_ENTRY(likely) COMPILER_ATTRIBUTE_ENTRY(maybe_unused) COMPILER_ATTRIBUTE_ENTRY(nodiscard) COMPILER_ATTRIBUTE_ENTRY(noreturn) COMPILER_ATTRIBUTE_ENTRY(no_unique_address) COMPILER_ATTRIBUTE_ENTRY(unlikely) }; constexpr bool is_feature_supported(const CompilerFeature& x) { return x.value[0] != '_' && x.value[0] != '0'; } inline void print_compiler_feature(const CompilerFeature& x) { constexpr static int max_name_length = 44; //< Update if necessary std::string value{ is_feature_supported(x) ? x.value : "------" }; if (value.back() == 'L') value.pop_back(); //~ 201603L -> 201603 if (print.separate_year_month) value.insert(4, 1, '-'); //~ 201603 -> 2016-03 if ( (print.supported_features && is_feature_supported(x)) or (print.unsupported_features && !is_feature_supported(x))) { std::cout << std::left << std::setw(max_name_length) << x.name << " " << value << '\n'; } } template<size_t N> inline void show(char const* title, CompilerFeature (&features)[N]) { if (print.titles) { std::cout << std::left << title << " ("; if (print.counters) std::cout << std::count_if( std::begin(features), std::end(features), is_feature_supported) << '/'; std::cout << N << ")\n"; } if (print.sort_by_date) { std::sort(std::begin(features), std::end(features), [](CompilerFeature const& lhs, CompilerFeature const& rhs) { return std::strcmp(lhs.value, rhs.value) < 0; }); } for (const CompilerFeature& x : features) { print_compiler_feature(x); } std::cout << '\n'; } int main() { if (print.general_features) show("C++ GENERAL", cxx_core); if (print.cxx11 && print.core_features) show("C++11 CORE", cxx11_core); if (print.cxx14 && print.core_features) show("C++14 CORE", cxx14_core); if (print.cxx14 && print.lib_features ) show("C++14 LIB" , cxx14_lib); if (print.cxx17 && print.core_features) show("C++17 CORE", cxx17_core); if (print.cxx17 && print.lib_features ) show("C++17 LIB" , cxx17_lib); if (print.cxx20 && print.core_features) show("C++20 CORE", cxx20_core); if (print.cxx20 && print.lib_features ) show("C++20 LIB" , cxx20_lib); if (print.cxx23 && print.core_features) show("C++23 CORE", cxx23_core); if (print.cxx23 && print.lib_features ) show("C++23 LIB" , cxx23_lib); if (print.cxx26 && print.core_features) show("C++26 CORE", cxx26_core); if (print.cxx26 && print.lib_features ) show("C++26 LIB" , cxx26_lib); if (print.attributes) show("ATTRIBUTES", attributes); }
Possible output:
C++ GENERAL (3/3) __cplusplus 202002 __cpp_exceptions 199711 __cpp_rtti 199711 C++11 CORE (19/19) __cpp_alias_templates 200704 __cpp_attributes 200809 __cpp_constexpr 201907 __cpp_decltype 200707 __cpp_delegating_constructors 200604 __cpp_inheriting_constructors 201511 __cpp_initializer_lists 200806 __cpp_lambdas 200907 __cpp_nsdmi 200809 __cpp_range_based_for 201603 __cpp_raw_strings 200710 __cpp_ref_qualifiers 200710 __cpp_rvalue_references 200610 __cpp_static_assert 201411 __cpp_threadsafe_static_init 200806 __cpp_unicode_characters 200704 __cpp_unicode_literals 200710 __cpp_user_defined_literals 200809 __cpp_variadic_templates 200704 C++14 CORE (9/9) __cpp_aggregate_nsdmi 201304 __cpp_binary_literals 201304 __cpp_constexpr 201907 __cpp_decltype_auto 201304 __cpp_generic_lambdas 201707 __cpp_init_captures 201803 __cpp_return_type_deduction 201304 __cpp_sized_deallocation ------ __cpp_variable_templates 201304 ... truncated ...
See also
Library feature-test macros (C++20) | defined in the header <version> |
External links
The official document on Feature-Test Recommendations | |
Source code to dump compiler features |