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.
__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 |
---|---|---|---|
assume |
[[assume]] |
202207L ? | (C++23) |
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) |
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) |
char8_t compatibility and portability fix (allow initialization of (unsigned) char arrays from UTF-8 string literals) | 202207L | (C++23) | |
__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) | |
Relaxing some constexpr restrictions | 202207L | (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_implicit_move | Simpler implicit move | 202207L | (C++23) |
__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_named_character_escapes | Named universal character escapes | 202207L | (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_static_call_operator | static operator() | 202207L | (C++23) |
__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) |
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_algorithm_ iterator_requirements | Ranges iterators as inputs to non-Ranges algorithms | 202207L | <algorithm> <memory> <numeric> | (C++23) |
__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) |
Move-only types for equality_comparable_with , totally_ordered_with , and three_way_comparable_with | 202207L | <compare> <concepts> | (C++23) | |
__cpp_lib_constexpr_algorithms | Constexpr for algorithms | 201806L | <algorithm> | (C++20) |
__cpp_lib_constexpr_bitset | A more constexpr std::bitset | 202207L | <bitset> | (C++23) |
__cpp_lib_constexpr_charconv | Add constexpr modifiers to functions std::to_chars and std::from_chars for integral types | 202207L | <charconv> | (C++23) |
__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_find_last | std::ranges::find_last | 202207L | <algorithm> | (C++23) |
__cpp_lib_flat_map | std::flat_map and std::flat_multimap | 202207L | <flat_map> | (C++23) |
__cpp_lib_flat_set | std::flat_set and std::flat_multiset | 202207L | <flat_set> | (C++23) |
__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) | |
Exposing std::basic_format_string ; clarify handling of encodings in localized formatting of chrono types | 202207L | <format> | (C++23) | |
__cpp_lib_format_ranges | Formatting ranges | 202207L | <format> | (C++23) |
__cpp_lib_forward_like | std::forward_like | 202207L | <utility> | (C++23) |
__cpp_lib_gcd_lcm | std::gcd , std::lcm | 201606L | <numeric> | (C++17) |
__cpp_lib_generator | std::generator : synchronous coroutine generator for ranges | 202207L | <generator> | (C++23) |
__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_ios_noreplace | Support exclusive mode for fstreams | 202207L | <ios> | (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_mdspan | std::mdspan | 202207L | <mdspan> | (C++23) |
__cpp_lib_memory_resource | std::pmr::memory_resource | 201603L | <memory_resource> | (C++17) |
__cpp_lib_modules | Standard library modules std and std.compat | 202207L | (C++23) | |
__cpp_lib_move_iterator_ concept | Make std::move_iterator<T*> a random access iterator | 202207L | <iterator> | (C++23) |
__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_print | Formatted output | 202207L | <ostream> <print> | (C++23) |
__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) | ||
Relaxing range adaptors to allow for move only types | 202207L | (C++23) | ||
__cpp_lib_ranges_as_const | std::const_iterator , std::ranges::as_const_view | 202207L | <ranges> | (C++23) |
__cpp_lib_ranges_as_rvalue | std::ranges::as_rvalue_view | 202207L | <ranges> | (C++23) |
__cpp_lib_ranges_ cartesian_product | std::ranges::cartesian_product_view | 202207L | <ranges> | (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_contains | std::ranges::contains | 202207L | <algorithm> | (C++23) |
__cpp_lib_ranges_fold | std::ranges fold algorithms | 202207L | <algorithm> | (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_repeat | std::ranges::repeat_view | 202207L | <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_stride | std::ranges::stride_view | 202207L | <ranges> | (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_start_lifetime_as | Explicit lifetime management (std::start_lifetime_as ) | 202207L | <memory> | (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_tuple_like | Compatibility between std::tuple and tuple-like objects (std::pair , std::array , std::subrange ) | 202207L | <map> <tuple> <unordered_map> <utility> | (C++23) |
__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) |
#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() { }
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_flat_set) COMPILER_FEATURE_ENTRY(__cpp_lib_format) COMPILER_FEATURE_ENTRY(__cpp_lib_format_ranges) 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_modules) 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_fold) 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) }; 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 ...
Library feature-test macros (C++20) | defined in the header <version> |
C++ documentation for Macro Symbol Index |
The official document on Feature-Test Recommendations | |
Source code to dump compiler features |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/feature_test