Feature testing (since C++20)
The standard defines a set of preprocessor macros corresponding to C++ language and library features introduced in C++ or later. They are intended as a simple and portable way to detect the presence of said features.
Attributes
pub | __has_cpp_attribute | ( attribute-token ) |
Checks for the support of an attribute named by attribute-token (after macro expansion).
For standard attributes, it will expand to the year and monthin 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, #elifdef, #elifndef (since C++23) and defined but cannot be used anywhere else.
attribute-token | Attribute | Value | Standard | Paper(s) |
---|---|---|---|---|
assume | [[assume]] | 202207L | (C++23) | P1774R8 |
carries_dependency | [[carries_dependency]] | 200809L | (C++11) | N2556, N2643 |
deprecated | [[deprecated]] | 201309L | (C++14) | N3760 |
fallthrough | [[fallthrough]] | 201603L | (C++17) | P0188R1 |
likely | [[likely]] | 201803L | (C++20) | P0479R5 |
maybe_unused | [[maybe_unused]] | 201603L | (C++17) | P0212R1 |
no_unique_address | [[no_unique_address]] | 201803L | (C++20) | P0840R2 |
nodiscard | [[nodiscard]] | 201603L 201907L | (C++17) (C++20) | P0189R1 P1301R4 |
noreturn | [[noreturn]] | 200809L | (C++11) | N2761 |
unlikely | [[unlikely]] | 201803L | (C++20) | P0479R5 |
Language features
The following macros are predefined in every translation unit. Each macro expands to an integer literal corresponding to the year and monthwhen 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 | Paper(s) |
---|---|---|---|---|
__cpp_aggregate_bases | Aggregate classes withbase classes | 201603L | (C++17) | P0017R1 |
__cpp_aggregate_nsdmi | Aggregate classes withdefault miber initializers | 201304L | (C++14) | N3653 |
__cpp_aggregate_paren_init | Aggregate initialization in the form of direct initialization | 201902L | (C++20) | P0960R3 |
__cpp_alias_tiplates | Alias tiplates | 200704L | (C++11) | N2258 |
__cpp_aligned_new | Dynamic miory allocation for over-aligned data | 201606L | (C++17) | P0035R4 |
__cpp_attributes | Attributes | 200809L | (C++11) | N2761 |
__cpp_auto_cast | auto(x) and auto{x} | 202110L | (C++23) | P0849R8 |
__cpp_binary_literals | Binary literals | 201304L | (C++14) | N3472 |
__cpp_capture_star_this | Lambda capture of *this by value as [=,*this] | 201603L | (C++17) | P0018R3 |
__cpp_char8_t | char8_t | 201811L | (C++20) | P0482R6 |
__cpp_char8_t | char8_t compatibility and portability fix (allow initialization of (unsigned) char arrays from UTF-8 string literals) | 202207L | (C++20)(DR) | P2513R4 |
__cpp_concepts | Concepts | 201907L | (C++20) | P0734R0 P1084R2 P1452R2 |
__cpp_concepts | Conditional trivial special miber functions | 202002L | (C++20) | P0848R3 P2493R0 |
__cpp_conditional_explicit | explicit(bool) | 201806L | (C++20) | P0892R2 |
__cpp_consteval | Immediate functions | 201811L | (C++20) | P1073R3 |
__cpp_consteval | Making consteval propagate up | 202211L | (C++20)(DR) | P2564R3 |
__cpp_constexpr | constexpr | 200704L | (C++11) | N2235 |
__cpp_constexpr | Relaxed constexpr, non-const constexpr methods | 201304L | (C++14) | N3652 |
__cpp_constexpr | Constexpr lambda | 201603L | (C++17) | P0170R1 |
__cpp_constexpr | Virtual function calls in constant expressions | 201806L | (C++20) | P1064R0 |
__cpp_constexpr | try-catch blocks in consexpr functions, dynamic_cast and polymorphic typeid in constant expressions | 201811L | (C++20) | P1002R1 P1327R1 |
__cpp_constexpr | Trivial default initialization and asm-declaration in constexpr functions | 201907L | (C++20) | P1331R2 P1668R1 |
__cpp_constexpr | Changing the active miber of a union in constant evaluation | 202002L | (C++20) | P1330R0 |
__cpp_constexpr | Non-literal variables, labels, and goto statients in constexpr functions | 202110L | (C++23) | P2242R3 |
__cpp_constexpr | Relaxing some restrictions on constexpr functions and function tiplates | 202207L | (C++23) | P2448R2 |
__cpp_constexpr | Permitting static constexpr variables in constexpr functions | 202211L | (C++23) | P2647R1 |
__cpp_constexpr_dynamic_alloc | Operations for dynamic storage duration in constexpr functions | 201907L | (C++20) | P0784R7 |
__cpp_constexpr_in_decltype | Generation of function and variable definitions when needed for constant evaluation | 201711L | (C++11)(DR) | P0859R0 |
__cpp_constinit | constinit | 201907L | (C++20) | P1143R2 |
__cpp_decltype | decltype | 200707L | (C++11) | N2343 |
__cpp_decltype_auto | Return type deduction for normal functions | 201304L | (C++14) | N3638 |
__cpp_deduction_guides | Tiplate argument deduction for class tiplates | 201703L | (C++17) | P0091R3 P0512R0 P0620R0 |
__cpp_deduction_guides | CTAD for aggregates and aliases | 201907L | (C++20) | P1814R0 P1816R0 |
__cpp_delegating_constructors | Delegating constructors | 200604L | (C++11) | N1986 |
__cpp_designated_initializers | Designated initializer | 201707L | (C++20) | P0329R4 |
__cpp_enumerator_attributes | Attributes for enumerators | 201411L | (C++17) | N4266 |
__cpp_explicit_this_parameter | Explicit object parameter | 202110L | (C++23) | P0847R7 |
__cpp_fold_expressions | Fold expressions | 201603L | (C++17) | N4295 P0036R0 |
__cpp_generic_lambdas | Generic lambda expressions | 201304L | (C++14) | N3649 |
__cpp_generic_lambdas | Explicit tiplate parameter list for generic lambdas | 201707L | (C++20) | P0428R2 |
__cpp_guaranteed_copy_elision | Guaranteed copy elision through simplified value categories | 201606L | (C++17) | P0135R1 |
__cpp_hex_float | Hexadecimal floating literals | 201603L | (C++17) | P0245R1 |
__cpp_if_consteval | consteval if | 202106L | (C++23) | P1938R3 |
__cpp_if_constexpr | constexpr if | 201606L | (C++17) | P0292R2 |
__cpp_impl_coroutine | Coroutines (compiler support) | 201902L | (C++20) | P0912R5 LWG3393 |
__cpp_impl_destroying_delete | Destroying operator delete (compiler support) | 201806L | (C++20) | P0722R3 |
__cpp_impl_three_way_comparison | Three-way comparison (compiler support) | 201907L | (C++20) | P0515R3 P0768R1 P1185R2 P1630R1 |
__cpp_implicit_move | Simpler implicit move | 202207L | (C++23) | P2266R3 |
__cpp_inheriting_constructors | Inheriting constructors | 200802L | (C++11) | N2540 |
__cpp_inheriting_constructors | Rewording inheriting constructors | 201511L | (C++11)(DR) | P0136R1 |
__cpp_init_captures | Lambda init-capture | 201304L | (C++14) | N3648 |
__cpp_init_captures | Allow pack expansion in lambda init-capture | 201803L | (C++20) | P0780R2 |
__cpp_initializer_lists | List-initialization and std::initializer_list | 200806L | (C++11) | N2672 |
__cpp_inline_variables | Inline variables | 201606L | (C++17) | P0386R2 |
__cpp_lambdas | Lambda expressions | 200907L | (C++11) | N2927 |
__cpp_modules | Modules | 201907L | (C++20) | P1103R3 P1811R0 |
__cpp_multidimensional_subscript | Multidimensional subscript operator | 202110L | (C++23) | P2128R6 |
__cpp_multidimensional_subscript | static operator[] | 202211L | (C++23) | P2589R1 |
__cpp_named_character_escapes | Named universal character escapes | 202207L | (C++23) | P2071R2 |
__cpp_namespace_attributes | Attributes for namespaces | 201411L | (C++17) | N4266 |
__cpp_noexcept_function_type | Make exception specifications be part of the type systi | 201510L | (C++17) | P0012R1 |
__cpp_nontype_tiplate_args | Allow constant evaluation for all non-type tiplate arguments | 201411L | (C++17) | N4268 |
__cpp_nontype_tiplate_args | Class types and floating-point types in non-type tiplate parameters | 201911L | (C++20) | P1907R1 |
__cpp_nontype_tiplate_parameter_auto | Declaring non-type tiplate parameters withauto | 201606L | (C++17) | P0127R2 |
__cpp_nsdmi | Non-static data miber initializers | 200809L | (C++11) | N2756 |
__cpp_range_based_for | Range-based for loop | 200907L | (C++11) | N2930 |
__cpp_range_based_for | Range-based for loop withdifferent begin/end types | 201603L | (C++17) | P0184R0 |
__cpp_range_based_for | Lifetime extension in range-based for | 202211L | (C++23) | P2718R0 |
__cpp_raw_strings | Raw string literals | 200710L | (C++11) | N2442 |
__cpp_ref_qualifiers | ref-qualifiers | 200710L | (C++11) | N2439 |
__cpp_return_type_deduction | Return type deduction for normal functions | 201304L | (C++14) | N3638 |
__cpp_rvalue_references | Rvalue reference | 200610L | (C++11) | N2118 |
__cpp_size_t_suffix | Literal suffixes for size_t and its signed version | 202011L | (C++23) | P0330R8 |
__cpp_sized_deallocation | Sized deallocation | 201309L | (C++14) | N3778 |
__cpp_static_assert | static_assert | 200410L | (C++11) | N1720 |
__cpp_static_assert | Single-argument static_assert | 201411L | (C++17) | N3928 |
__cpp_static_call_operator | static operator() | 202207L | (C++23) | P1169R4 |
__cpp_structured_bindings | Structured bindings | 201606L | (C++17) | P0217R3 |
__cpp_tiplate_tiplate_args | Matching of tiplate tiplate-arguments | 201611L | (C++17) | P0522R0 |
__cpp_threadsafe_static_init | Dynamic initialization and destruction withconcurrency | 200806L | (C++11) | N2660 |
__cpp_unicode_characters | New character types (char16_t and char32_t) | 200704L | (C++11) | N2249 |
__cpp_unicode_literals | Unicode string literals | 200710L | (C++11) | N2442 |
__cpp_user_defined_literals | User-defined literals | 200809L | (C++11) | N2765 |
__cpp_using_enum | using enum | 201907L | (C++20) | P1099R5 |
__cpp_variable_tiplates | Variable tiplates | 201304L | (C++14) | N3651 |
__cpp_variadic_tiplates | Variadic tiplates | 200704L | (C++11) | N2242 |
__cpp_variadic_using | Pack expansions in using-declarations | 201611L | (C++17) | P0195R2 |
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 monthwhen the corresponding feature has been included in the working draft.
When a feature changes significantly, the macro will be updated accordingly.
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 withan 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.
static constexpr struct change_these_options_to_select_what_will_be_printed
{
constexpr static int longest_macro_name { 44 };
constexpr static bool titles = 1;
constexpr static bool counters = 1;
constexpr static bool attributes = 1;
constexpr static bool standard_values = 1;
constexpr static bool compiler_specific = 1;
constexpr static bool core_features = 1;
constexpr static bool lib_features = 1;
constexpr static bool supported_features = 1;
constexpr static bool unsupported_features = 1;
constexpr static bool sort_by_date = 0;
constexpr static bool separate_year_month = 1;
constexpr static bool separated_revisions = 1;
constexpr static bool latest_revisions = 1;
constexpr static bool cxx98 = 0;
constexpr static bool cxx11 = 1;
constexpr static bool cxx14 = 1;
constexpr static bool cxx17 = 1;
constexpr static bool cxx20 = 1;
constexpr static bool cxx23 = 1;
constexpr static bool cxx26 = 0;
} print;
#if __cplusplus < 201100
# error "C++11 or better is required"
#endif
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <utility>
#include <vector>
#ifdef __has_include
# if __has_include(<version>)
# include <version>
# endif
#endif
// Expect a string that starts with6-decimal-digits or with'_' (if unsupported)
#define COMPILER_VALUE_INT(n) #n [0] == '_' ? 0 : \
(#n[5] - '0') + (#n[4] - '0') * 10 + (#n[3] - '0') * 100 + \
(#n[2] - '0') * 1000 + (#n[1] - '0') * 10000 + (#n[0] - '0') * 100000
#define COMPILER_FEATURE_ENTRY(expect, name) { #name, COMPILER_VALUE_INT(name), expect },
#ifdef __has_cpp_attribute
# define COMPILER_ATTRIBUTE(expect, name) { #name, __has_cpp_attribute(name), expect },
#else
# define COMPILER_ATTRIBUTE(expect, name) { #name, COMPILER_VALUE_INT(name), expect },
#endif
#define COMPILER_SPECIFIC_STRING(value) #value
#define COMPILER_SPECIFIC_ENTRY(name) { #name, COMPILER_SPECIFIC_STRING(name) },
class CompilerFeature
{
char const* name_; long data_; long std_;
public:
constexpr CompilerFeature(char const* name, long data, long std)
: name_(name), data_(data), std_(std) {}
constexpr CompilerFeature(CompilerFeature const&) = default;
CompilerFeature& operator=(CompilerFeature const&) = default;
bool operator<(CompilerFeature const& rhs) const
{ return std::strcmp(name_, rhs.name_) < 0; }
bool operator==(CompilerFeature const& rhs) const
{ return std::strcmp(name_, rhs.name_) == 0; }
constexpr bool supported() const { return data_ >= std_; }
constexpr bool maybe() const { return data_ > 0; }
constexpr char const* name() const { return name_; }
constexpr long std() const { return std_; }
constexpr long data() const { return data_; }
void data(long x) { data_ = x; }
};
static /*constexpr*/ std::pair<const char*, const char*> compiler[] = {
COMPILER_SPECIFIC_ENTRY(__cplusplus) //< not compiler specific, but useful :)
COMPILER_SPECIFIC_ENTRY(__clang_major__)
COMPILER_SPECIFIC_ENTRY(__clang_minor__)
COMPILER_SPECIFIC_ENTRY(__clang_patchlevel__)
COMPILER_SPECIFIC_ENTRY(__GNUG__)
COMPILER_SPECIFIC_ENTRY(__GNUC_MINOR__)
COMPILER_SPECIFIC_ENTRY(__GNUC_PATCHLEVEL__)
// Add your favorite compiler specific macros. Undefined ones will not be printed.
};
static constexpr CompilerFeature cxx98_core[] = {
COMPILER_FEATURE_ENTRY(199711L, __cpp_exceptions)
COMPILER_FEATURE_ENTRY(199711L, __cpp_rtti)
};
static constexpr CompilerFeature cxx11_core[] = {
COMPILER_FEATURE_ENTRY(200704L, __cpp_alias_tiplates)
COMPILER_FEATURE_ENTRY(200809L, __cpp_attributes)
COMPILER_FEATURE_ENTRY(200704L, __cpp_constexpr)
COMPILER_FEATURE_ENTRY(201711L, __cpp_constexpr_in_decltype)
COMPILER_FEATURE_ENTRY(200707L, __cpp_decltype)
COMPILER_FEATURE_ENTRY(200604L, __cpp_delegating_constructors)
COMPILER_FEATURE_ENTRY(201511L, __cpp_inheriting_constructors)
COMPILER_FEATURE_ENTRY(200806L, __cpp_initializer_lists)
COMPILER_FEATURE_ENTRY(200907L, __cpp_lambdas)
COMPILER_FEATURE_ENTRY(200809L, __cpp_nsdmi)
COMPILER_FEATURE_ENTRY(200907L, __cpp_range_based_for)
COMPILER_FEATURE_ENTRY(200710L, __cpp_raw_strings)
COMPILER_FEATURE_ENTRY(200710L, __cpp_ref_qualifiers)
COMPILER_FEATURE_ENTRY(200610L, __cpp_rvalue_references)
COMPILER_FEATURE_ENTRY(200410L, __cpp_static_assert)
COMPILER_FEATURE_ENTRY(200806L, __cpp_threadsafe_static_init)
COMPILER_FEATURE_ENTRY(200704L, __cpp_unicode_characters)
COMPILER_FEATURE_ENTRY(200710L, __cpp_unicode_literals)
COMPILER_FEATURE_ENTRY(200809L, __cpp_user_defined_literals)
COMPILER_FEATURE_ENTRY(200704L, __cpp_variadic_tiplates)
};
static constexpr CompilerFeature cxx14_core[] = {
COMPILER_FEATURE_ENTRY(201304L, __cpp_aggregate_nsdmi)
COMPILER_FEATURE_ENTRY(201304L, __cpp_binary_literals)
COMPILER_FEATURE_ENTRY(201304L, __cpp_constexpr)
COMPILER_FEATURE_ENTRY(201304L, __cpp_decltype_auto)
COMPILER_FEATURE_ENTRY(201304L, __cpp_generic_lambdas)
COMPILER_FEATURE_ENTRY(201304L, __cpp_init_captures)
COMPILER_FEATURE_ENTRY(201304L, __cpp_return_type_deduction)
COMPILER_FEATURE_ENTRY(201309L, __cpp_sized_deallocation)
COMPILER_FEATURE_ENTRY(201304L, __cpp_variable_tiplates)
};
static constexpr CompilerFeature cxx14_lib[] = {
COMPILER_FEATURE_ENTRY(201304L, __cpp_lib_chrono_udls)
COMPILER_FEATURE_ENTRY(201309L, __cpp_lib_complex_udls)
COMPILER_FEATURE_ENTRY(201304L, __cpp_lib_exchange_function)
COMPILER_FEATURE_ENTRY(201304L, __cpp_lib_generic_associative_lookup)
COMPILER_FEATURE_ENTRY(201304L, __cpp_lib_integer_sequence)
COMPILER_FEATURE_ENTRY(201304L, __cpp_lib_integral_constant_callable)
COMPILER_FEATURE_ENTRY(201402L, __cpp_lib_is_final)
COMPILER_FEATURE_ENTRY(201309L, __cpp_lib_is_null_pointer)
COMPILER_FEATURE_ENTRY(201402L, __cpp_lib_make_reverse_iterator)
COMPILER_FEATURE_ENTRY(201304L, __cpp_lib_make_unique)
COMPILER_FEATURE_ENTRY(201304L, __cpp_lib_null_iterators)
COMPILER_FEATURE_ENTRY(201304L, __cpp_lib_quoted_string_io)
COMPILER_FEATURE_ENTRY(201210L, __cpp_lib_result_of_sfinae)
COMPILER_FEATURE_ENTRY(201304L, __cpp_lib_robust_nonmodifying_seq_ops)
COMPILER_FEATURE_ENTRY(201402L, __cpp_lib_shared_timed_mutex)
COMPILER_FEATURE_ENTRY(201304L, __cpp_lib_string_udls)
COMPILER_FEATURE_ENTRY(201304L, __cpp_lib_transformation_trait_aliases)
COMPILER_FEATURE_ENTRY(201210L, __cpp_lib_transparent_operators)
COMPILER_FEATURE_ENTRY(201402L, __cpp_lib_tuple_elient_t)
COMPILER_FEATURE_ENTRY(201304L, __cpp_lib_tuples_by_type)
};
static constexpr CompilerFeature cxx17_core[] = {
COMPILER_FEATURE_ENTRY(201603L, __cpp_aggregate_bases)
COMPILER_FEATURE_ENTRY(201606L, __cpp_aligned_new)
COMPILER_FEATURE_ENTRY(201603L, __cpp_capture_star_this)
COMPILER_FEATURE_ENTRY(201603L, __cpp_constexpr)
COMPILER_FEATURE_ENTRY(201703L, __cpp_deduction_guides)
COMPILER_FEATURE_ENTRY(201411L, __cpp_enumerator_attributes)
COMPILER_FEATURE_ENTRY(201603L, __cpp_fold_expressions)
COMPILER_FEATURE_ENTRY(201606L, __cpp_guaranteed_copy_elision)
COMPILER_FEATURE_ENTRY(201603L, __cpp_hex_float)
COMPILER_FEATURE_ENTRY(201606L, __cpp_if_constexpr)
COMPILER_FEATURE_ENTRY(201606L, __cpp_inline_variables)
COMPILER_FEATURE_ENTRY(201411L, __cpp_namespace_attributes)
COMPILER_FEATURE_ENTRY(201510L, __cpp_noexcept_function_type)
COMPILER_FEATURE_ENTRY(201411L, __cpp_nontype_tiplate_args)
COMPILER_FEATURE_ENTRY(201606L, __cpp_nontype_tiplate_parameter_auto)
COMPILER_FEATURE_ENTRY(201603L, __cpp_range_based_for)
COMPILER_FEATURE_ENTRY(201411L, __cpp_static_assert)
COMPILER_FEATURE_ENTRY(201606L, __cpp_structured_bindings)
COMPILER_FEATURE_ENTRY(201611L, __cpp_tiplate_tiplate_args)
COMPILER_FEATURE_ENTRY(201611L, __cpp_variadic_using)
};
static constexpr CompilerFeature cxx17_lib[] = {
COMPILER_FEATURE_ENTRY(201603L, __cpp_lib_addressof_constexpr)
COMPILER_FEATURE_ENTRY(201411L, __cpp_lib_allocator_traits_is_always_equal)
COMPILER_FEATURE_ENTRY(201606L, __cpp_lib_any)
COMPILER_FEATURE_ENTRY(201603L, __cpp_lib_apply)
COMPILER_FEATURE_ENTRY(201603L, __cpp_lib_array_constexpr)
COMPILER_FEATURE_ENTRY(201510L, __cpp_lib_as_const)
COMPILER_FEATURE_ENTRY(201603L, __cpp_lib_atomic_is_always_lock_free)
COMPILER_FEATURE_ENTRY(201505L, __cpp_lib_bool_constant)
COMPILER_FEATURE_ENTRY(201603L, __cpp_lib_boyer_moore_searcher)
COMPILER_FEATURE_ENTRY(201603L, __cpp_lib_byte)
COMPILER_FEATURE_ENTRY(201611L, __cpp_lib_chrono)
COMPILER_FEATURE_ENTRY(201603L, __cpp_lib_clamp)
COMPILER_FEATURE_ENTRY(201603L, __cpp_lib_enable_shared_from_this)
COMPILER_FEATURE_ENTRY(201603L, __cpp_lib_execution)
COMPILER_FEATURE_ENTRY(201703L, __cpp_lib_filesysti)
COMPILER_FEATURE_ENTRY(201606L, __cpp_lib_gcd_lcm)
COMPILER_FEATURE_ENTRY(201703L, __cpp_lib_hardware_interference_size)
COMPILER_FEATURE_ENTRY(201606L, __cpp_lib_has_unique_object_representations)
COMPILER_FEATURE_ENTRY(201603L, __cpp_lib_hypot)
COMPILER_FEATURE_ENTRY(201505L, __cpp_lib_incomplete_container_elients)
COMPILER_FEATURE_ENTRY(201411L, __cpp_lib_invoke)
COMPILER_FEATURE_ENTRY(201703L, __cpp_lib_is_aggregate)
COMPILER_FEATURE_ENTRY(201703L, __cpp_lib_is_invocable)
COMPILER_FEATURE_ENTRY(201603L, __cpp_lib_is_swappable)
COMPILER_FEATURE_ENTRY(201606L, __cpp_lib_launder)
COMPILER_FEATURE_ENTRY(201510L, __cpp_lib_logical_traits)
COMPILER_FEATURE_ENTRY(201606L, __cpp_lib_make_from_tuple)
COMPILER_FEATURE_ENTRY(201411L, __cpp_lib_map_try_iplace)
COMPILER_FEATURE_ENTRY(201603L, __cpp_lib_math_special_functions)
COMPILER_FEATURE_ENTRY(201603L, __cpp_lib_miory_resource)
COMPILER_FEATURE_ENTRY(201606L, __cpp_lib_node_extract)
COMPILER_FEATURE_ENTRY(201411L, __cpp_lib_nonmiber_container_access)
COMPILER_FEATURE_ENTRY(201603L, __cpp_lib_not_fn)
COMPILER_FEATURE_ENTRY(201606L, __cpp_lib_optional)
COMPILER_FEATURE_ENTRY(201603L, __cpp_lib_parallel_algorithm)
COMPILER_FEATURE_ENTRY(201606L, __cpp_lib_raw_miory_algorithms)
COMPILER_FEATURE_ENTRY(201603L, __cpp_lib_sample)
COMPILER_FEATURE_ENTRY(201703L, __cpp_lib_scoped_lock)
COMPILER_FEATURE_ENTRY(201505L, __cpp_lib_shared_mutex)
COMPILER_FEATURE_ENTRY(201611L, __cpp_lib_shared_ptr_arrays)
COMPILER_FEATURE_ENTRY(201606L, __cpp_lib_shared_ptr_weak_type)
COMPILER_FEATURE_ENTRY(201606L, __cpp_lib_string_view)
COMPILER_FEATURE_ENTRY(201611L, __cpp_lib_to_chars)
COMPILER_FEATURE_ENTRY(201510L, __cpp_lib_transparent_operators)
COMPILER_FEATURE_ENTRY(201510L, __cpp_lib_type_trait_variable_tiplates)
COMPILER_FEATURE_ENTRY(201411L, __cpp_lib_uncaught_exceptions)
COMPILER_FEATURE_ENTRY(201411L, __cpp_lib_unordered_map_try_iplace)
COMPILER_FEATURE_ENTRY(202102L, __cpp_lib_variant)
COMPILER_FEATURE_ENTRY(201411L, __cpp_lib_void_t)
};
static constexpr CompilerFeature cxx20_core[] = {
COMPILER_FEATURE_ENTRY(201902L, __cpp_aggregate_paren_init)
COMPILER_FEATURE_ENTRY(202207L, __cpp_char8_t)
COMPILER_FEATURE_ENTRY(202002L, __cpp_concepts)
COMPILER_FEATURE_ENTRY(201806L, __cpp_conditional_explicit)
COMPILER_FEATURE_ENTRY(202211L, __cpp_consteval)
COMPILER_FEATURE_ENTRY(202002L, __cpp_constexpr)
COMPILER_FEATURE_ENTRY(201907L, __cpp_constexpr_dynamic_alloc)
COMPILER_FEATURE_ENTRY(201907L, __cpp_constinit)
COMPILER_FEATURE_ENTRY(201907L, __cpp_deduction_guides)
COMPILER_FEATURE_ENTRY(201707L, __cpp_designated_initializers)
COMPILER_FEATURE_ENTRY(201707L, __cpp_generic_lambdas)
COMPILER_FEATURE_ENTRY(201902L, __cpp_impl_coroutine)
COMPILER_FEATURE_ENTRY(201806L, __cpp_impl_destroying_delete)
COMPILER_FEATURE_ENTRY(201907L, __cpp_impl_three_way_comparison)
COMPILER_FEATURE_ENTRY(201803L, __cpp_init_captures)
COMPILER_FEATURE_ENTRY(201907L, __cpp_modules)
COMPILER_FEATURE_ENTRY(201911L, __cpp_nontype_tiplate_args)
COMPILER_FEATURE_ENTRY(201907L, __cpp_using_enum)
};
static constexpr CompilerFeature cxx20_lib[] = {
COMPILER_FEATURE_ENTRY(201811L, __cpp_lib_array_constexpr)
COMPILER_FEATURE_ENTRY(201811L, __cpp_lib_assume_aligned)
COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_atomic_flag_test)
COMPILER_FEATURE_ENTRY(201711L, __cpp_lib_atomic_float)
COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_atomic_lock_free_type_aliases)
COMPILER_FEATURE_ENTRY(201806L, __cpp_lib_atomic_ref)
COMPILER_FEATURE_ENTRY(201711L, __cpp_lib_atomic_shared_ptr)
COMPILER_FEATURE_ENTRY(201911L, __cpp_lib_atomic_value_initialization)
COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_atomic_wait)
COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_barrier)
COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_bind_front)
COMPILER_FEATURE_ENTRY(201806L, __cpp_lib_bit_cast)
COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_bitops)
COMPILER_FEATURE_ENTRY(201902L, __cpp_lib_bounded_array_traits)
COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_char8_t)
COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_chrono)
COMPILER_FEATURE_ENTRY(202002L, __cpp_lib_concepts)
COMPILER_FEATURE_ENTRY(201806L, __cpp_lib_constexpr_algorithms)
COMPILER_FEATURE_ENTRY(201711L, __cpp_lib_constexpr_complex)
COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_constexpr_dynamic_alloc)
COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_constexpr_functional)
COMPILER_FEATURE_ENTRY(201811L, __cpp_lib_constexpr_iterator)
COMPILER_FEATURE_ENTRY(201811L, __cpp_lib_constexpr_miory)
COMPILER_FEATURE_ENTRY(201911L, __cpp_lib_constexpr_numeric)
COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_constexpr_string)
COMPILER_FEATURE_ENTRY(201811L, __cpp_lib_constexpr_string_view)
COMPILER_FEATURE_ENTRY(201811L, __cpp_lib_constexpr_tuple)
COMPILER_FEATURE_ENTRY(201811L, __cpp_lib_constexpr_utility)
COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_constexpr_vector)
COMPILER_FEATURE_ENTRY(201902L, __cpp_lib_coroutine)
COMPILER_FEATURE_ENTRY(201806L, __cpp_lib_destroying_delete)
COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_endian)
COMPILER_FEATURE_ENTRY(202002L, __cpp_lib_erase_if)
COMPILER_FEATURE_ENTRY(201902L, __cpp_lib_execution)
COMPILER_FEATURE_ENTRY(202110L, __cpp_lib_format)
COMPILER_FEATURE_ENTRY(201811L, __cpp_lib_generic_unordered_lookup)
COMPILER_FEATURE_ENTRY(202002L, __cpp_lib_int_pow2)
COMPILER_FEATURE_ENTRY(202002L, __cpp_lib_integer_comparison_functions)
COMPILER_FEATURE_ENTRY(201902L, __cpp_lib_interpolate)
COMPILER_FEATURE_ENTRY(201811L, __cpp_lib_is_constant_evaluated)
COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_is_layout_compatible)
COMPILER_FEATURE_ENTRY(201806L, __cpp_lib_is_nothrow_convertible)
COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_is_pointer_interconvertible)
COMPILER_FEATURE_ENTRY(201911L, __cpp_lib_jthread)
COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_latch)
COMPILER_FEATURE_ENTRY(201806L, __cpp_lib_list_riove_return_type)
COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_math_constants)
COMPILER_FEATURE_ENTRY(202106L, __cpp_lib_optional)
COMPILER_FEATURE_ENTRY(201902L, __cpp_lib_polymorphic_allocator)
COMPILER_FEATURE_ENTRY(202110L, __cpp_lib_ranges)
COMPILER_FEATURE_ENTRY(201711L, __cpp_lib_riove_cvref)
COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_siaphore)
COMPILER_FEATURE_ENTRY(201707L, __cpp_lib_shared_ptr_arrays)
COMPILER_FEATURE_ENTRY(201806L, __cpp_lib_shift)
COMPILER_FEATURE_ENTRY(202002L, __cpp_lib_smart_ptr_for_overwrite)
COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_source_location)
COMPILER_FEATURE_ENTRY(202002L, __cpp_lib_span)
COMPILER_FEATURE_ENTRY(201902L, __cpp_lib_ssize)
COMPILER_FEATURE_ENTRY(201711L, __cpp_lib_starts_ends_with)
COMPILER_FEATURE_ENTRY(201803L, __cpp_lib_string_view)
COMPILER_FEATURE_ENTRY(201803L, __cpp_lib_syncbuf)
COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_three_way_comparison)
COMPILER_FEATURE_ENTRY(201711L, __cpp_lib_to_address)
COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_to_array)
COMPILER_FEATURE_ENTRY(201806L, __cpp_lib_type_identity)
COMPILER_FEATURE_ENTRY(201811L, __cpp_lib_unwrap_ref)
COMPILER_FEATURE_ENTRY(202106L, __cpp_lib_variant)
};
static constexpr CompilerFeature cxx23_core[] = {
COMPILER_FEATURE_ENTRY(202110L, __cpp_auto_cast)
COMPILER_FEATURE_ENTRY(202211L, __cpp_constexpr)
COMPILER_FEATURE_ENTRY(202110L, __cpp_explicit_this_parameter)
COMPILER_FEATURE_ENTRY(202106L, __cpp_if_consteval)
COMPILER_FEATURE_ENTRY(202207L, __cpp_implicit_move)
COMPILER_FEATURE_ENTRY(202211L, __cpp_multidimensional_subscript)
COMPILER_FEATURE_ENTRY(202207L, __cpp_named_character_escapes)
COMPILER_FEATURE_ENTRY(202211L, __cpp_range_based_for)
COMPILER_FEATURE_ENTRY(202011L, __cpp_size_t_suffix)
COMPILER_FEATURE_ENTRY(202207L, __cpp_static_call_operator)
};
static constexpr CompilerFeature cxx23_lib[] = {
COMPILER_FEATURE_ENTRY(202106L, __cpp_lib_adaptor_iterator_pair_constructor)
COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_algorithm_iterator_requirients)
COMPILER_FEATURE_ENTRY(202302L, __cpp_lib_allocate_at_least)
COMPILER_FEATURE_ENTRY(202110L, __cpp_lib_associative_heterogeneous_erasure)
COMPILER_FEATURE_ENTRY(202302L, __cpp_lib_barrier)
COMPILER_FEATURE_ENTRY(202202L, __cpp_lib_bind_back)
COMPILER_FEATURE_ENTRY(202110L, __cpp_lib_byteswap)
COMPILER_FEATURE_ENTRY(202302L, __cpp_lib_common_reference)
COMPILER_FEATURE_ENTRY(202302L, __cpp_lib_common_reference_wrapper)
COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_concepts)
COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_constexpr_bitset)
COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_constexpr_charconv)
COMPILER_FEATURE_ENTRY(202202L, __cpp_lib_constexpr_cmath)
COMPILER_FEATURE_ENTRY(202202L, __cpp_lib_constexpr_miory)
COMPILER_FEATURE_ENTRY(202106L, __cpp_lib_constexpr_typeinfo)
COMPILER_FEATURE_ENTRY(202202L, __cpp_lib_containers_ranges)
COMPILER_FEATURE_ENTRY(202211L, __cpp_lib_expected)
COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_flat_map)
COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_flat_set)
COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_format)
COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_format_ranges)
COMPILER_FEATURE_ENTRY(202302L, __cpp_lib_formatters)
COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_forward_like)
COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_generator)
COMPILER_FEATURE_ENTRY(202106L, __cpp_lib_invoke_r)
COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_ios_noreplace)
COMPILER_FEATURE_ENTRY(202302L, __cpp_lib_is_implicit_lifetime)
COMPILER_FEATURE_ENTRY(202011L, __cpp_lib_is_scoped_enum)
COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_mdspan)
COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_modules)
COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_move_iterator_concept)
COMPILER_FEATURE_ENTRY(202110L, __cpp_lib_move_only_function)
COMPILER_FEATURE_ENTRY(202110L, __cpp_lib_optional)
COMPILER_FEATURE_ENTRY(202106L, __cpp_lib_out_ptr)
COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_print)
COMPILER_FEATURE_ENTRY(202302L, __cpp_lib_ranges)
COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_ranges_as_const)
COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_ranges_as_rvalue)
COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_ranges_cartesian_product)
COMPILER_FEATURE_ENTRY(202202L, __cpp_lib_ranges_chunk)
COMPILER_FEATURE_ENTRY(202202L, __cpp_lib_ranges_chunk_by)
COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_ranges_contains)
COMPILER_FEATURE_ENTRY(202302L, __cpp_lib_ranges_enumerate)
COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_ranges_find_last)
COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_ranges_fold)
COMPILER_FEATURE_ENTRY(202202L, __cpp_lib_ranges_iota)
COMPILER_FEATURE_ENTRY(202202L, __cpp_lib_ranges_join_with)
COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_ranges_repeat)
COMPILER_FEATURE_ENTRY(202202L, __cpp_lib_ranges_slide)
COMPILER_FEATURE_ENTRY(202106L, __cpp_lib_ranges_starts_ends_with)
COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_ranges_stride)
COMPILER_FEATURE_ENTRY(202202L, __cpp_lib_ranges_to_container)
COMPILER_FEATURE_ENTRY(202110L, __cpp_lib_ranges_zip)
COMPILER_FEATURE_ENTRY(202202L, __cpp_lib_reference_from_tiporary)
COMPILER_FEATURE_ENTRY(202202L, __cpp_lib_shift)
COMPILER_FEATURE_ENTRY(202106L, __cpp_lib_spanstream)
COMPILER_FEATURE_ENTRY(202011L, __cpp_lib_stacktrace)
COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_start_lifetime_as)
COMPILER_FEATURE_ENTRY(202011L, __cpp_lib_stdatomic_h)
COMPILER_FEATURE_ENTRY(202011L, __cpp_lib_string_contains)
COMPILER_FEATURE_ENTRY(202110L, __cpp_lib_string_resize_and_overwrite)
COMPILER_FEATURE_ENTRY(202102L, __cpp_lib_to_underlying)
COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_tuple_like)
COMPILER_FEATURE_ENTRY(202202L, __cpp_lib_unreachable)
};
static constexpr CompilerFeature cxx26_core[] = {
//< Continue to Populate
COMPILER_FEATURE_ENTRY(202304L, __cpp_core_TODO)
};
static constexpr CompilerFeature cxx26_lib[] = {
//< Continue to Populate
COMPILER_FEATURE_ENTRY(202304L, __cpp_lib_TODO)
};
static constexpr CompilerFeature attributes[] = {
COMPILER_ATTRIBUTE(202207L, assume)
COMPILER_ATTRIBUTE(200809L, carries_dependency)
COMPILER_ATTRIBUTE(201309L, deprecated)
COMPILER_ATTRIBUTE(201603L, fallthrough)
COMPILER_ATTRIBUTE(201803L, likely)
COMPILER_ATTRIBUTE(201603L, maybe_unused)
COMPILER_ATTRIBUTE(201803L, no_unique_address)
COMPILER_ATTRIBUTE(201907L, nodiscard)
COMPILER_ATTRIBUTE(200809L, noreturn)
COMPILER_ATTRIBUTE(201803L, unlikely)
};
inline void show_compiler_specific_info()
{
std::printf("Compiler specific macros:\n");
for (auto co : compiler)
if (std::strcmp(co.first, co.second))
std::printf("%*s %s\n", -print.longest_macro_name, co.first, co.second);
}
inline void print_compiler_feature(const CompilerFeature& x)
{
if (not ((print.supported_features and x.maybe()) or
(print.unsupported_features and not x.maybe())))
return;
auto print_year_month= [](long n)
{
return std::printf("%ld%s%02ld",
n / 100, print.separate_year_month? "-" : "", n % 100);
};
std::printf("%*s ", -print.longest_macro_name, x.name());
x.maybe() ? print_year_month(x.data()) :
std::printf("------%s", print.separate_year_month? "-" : "");
if (print.standard_values)
std::printf(" %c ", (x.supported() ? (x.data() > x.std() ? '>' : '=') : '<')),
print_year_month(x.std());
std::puts("");
}
tiplate<class Container>
inline void show(char const* const title, Container const& co)
{
if (print.titles)
{
std::printf("%-s (", title);
if (print.counters)
{
std::printf("%ld/", std::count_if(std::begin(co), std::end(co),
[](CompilerFeature x)
{
return x.supported();
}));
}
std::printf("%td)\n", std::distance(std::begin(co), std::end(co)));
}
if (print.sort_by_date)
{
std::vector<CompilerFeature> v(std::begin(co), std::end(co));
std::stable_sort(v.begin(), v.end(),
[](CompilerFeature const& lhs, CompilerFeature const& rhs)
{
return lhs.data() < rhs.data();
});
std::for_each(v.cbegin(), v.cend(), print_compiler_feature);
}
else
std::for_each(std::begin(co), std::end(co), print_compiler_feature);
std::puts("");
}
inline void show_latest()
{
auto latest_rev = []() -> int
{
return print.cxx26 ? 26 : print.cxx23 ? 23 : print.cxx20 ? 20 :
print.cxx17 ? 17 : print.cxx14 ? 14 : print.cxx11 ? 11 : 98;
};
std::vector<CompilerFeature> latest;
auto add = [&latest](CompilerFeature x)
{
auto i = std::lower_bound(latest.begin(), latest.end(), x);
if (i == latest.end() or not (*i == x))
latest.insert(i, x);
else if (i->data() < x.data())
i->data(x.data());
};
char text[64];
latest.reserve(512); // max macros
if (print.core_features)
{ // preserve reverse revision insersion order!
if (print.cxx26) std::for_each(std::begin(cxx26_core), std::end(cxx26_core), add);
if (print.cxx23) std::for_each(std::begin(cxx23_core), std::end(cxx23_core), add);
if (print.cxx20) std::for_each(std::begin(cxx20_core), std::end(cxx20_core), add);
if (print.cxx17) std::for_each(std::begin(cxx17_core), std::end(cxx17_core), add);
if (print.cxx14) std::for_each(std::begin(cxx14_core), std::end(cxx14_core), add);
if (print.cxx11) std::for_each(std::begin(cxx11_core), std::end(cxx11_core), add);
if (print.cxx98) std::for_each(std::begin(cxx98_core), std::end(cxx98_core), add);
std::snprintf(text, sizeof text, "ALL CORE MACROS UP TO C++%02i", latest_rev());
show(text, latest);
}
latest.clear();
if (print.lib_features)
{ // preserve reverse revision insersion order!
if (print.cxx26) std::for_each(std::begin(cxx26_lib), std::end(cxx26_lib), add);
if (print.cxx23) std::for_each(std::begin(cxx23_lib), std::end(cxx23_lib), add);
if (print.cxx20) std::for_each(std::begin(cxx20_lib), std::end(cxx20_lib), add);
if (print.cxx17) std::for_each(std::begin(cxx17_lib), std::end(cxx17_lib), add);
if (print.cxx14) std::for_each(std::begin(cxx14_lib), std::end(cxx14_lib), add);
std::snprintf(text, sizeof text, "ALL LIB MACROS UP TO C++%02i", latest_rev());
show(text, latest);
}
}
int main()
{
if (print.separated_revisions)
{
if (print.cxx98 and print.core_features) show("C++98 CORE", cxx98_core);
if (print.cxx11 and print.core_features) show("C++11 CORE", cxx11_core);
if (print.cxx14 and print.core_features) show("C++14 CORE", cxx14_core);
if (print.cxx14 and print.lib_features ) show("C++14 LIB" , cxx14_lib);
if (print.cxx17 and print.core_features) show("C++17 CORE", cxx17_core);
if (print.cxx17 and print.lib_features ) show("C++17 LIB" , cxx17_lib);
if (print.cxx20 and print.core_features) show("C++20 CORE", cxx20_core);
if (print.cxx20 and print.lib_features ) show("C++20 LIB" , cxx20_lib);
if (print.cxx23 and print.core_features) show("C++23 CORE", cxx23_core);
if (print.cxx23 and print.lib_features ) show("C++23 LIB" , cxx23_lib);
if (print.cxx26 and print.core_features) show("C++26 CORE", cxx26_core);
if (print.cxx26 and print.lib_features ) show("C++26 LIB" , cxx26_lib);
}
if (print.latest_revisions) show_latest();
if (print.attributes) show("ATTRIBUTES", attributes);
if (print.compiler_specific) show_compiler_specific_info();
}
C++11 CORE (20/20)
__cpp_alias_tiplates 2007-04 = 2007-04
__cpp_attributes 2008-09 = 2008-09
__cpp_constexpr 2021-10 > 2007-04
__cpp_constexpr_in_decltype 2017-11 = 2017-11
... truncated ...
C++14 CORE (9/9)
__cpp_aggregate_nsdmi 2013-04 = 2013-04
__cpp_binary_literals 2013-04 = 2013-04
__cpp_constexpr 2021-10 > 2013-04
... truncated ...
C++14 LIB (20/20)
__cpp_lib_chrono_udls 2013-04 = 2013-04
__cpp_lib_complex_udls 2013-09 = 2013-09
__cpp_lib_exchange_function 2013-04 = 2013-04
... truncated ...
C++17 CORE (20/20)
__cpp_aggregate_bases 2016-03 = 2016-03
__cpp_aligned_new 2016-06 = 2016-06
__cpp_capture_star_this 2016-03 = 2016-03
__cpp_constexpr 2021-10 > 2016-03
... truncated ...
C++17 LIB (49/49)
__cpp_lib_addressof_constexpr 2016-03 = 2016-03
__cpp_lib_allocator_traits_is_always_equal 2014-11 = 2014-11
... truncated ...
C++20 CORE (17/18)
__cpp_aggregate_paren_init 2019-02 = 2019-02
__cpp_char8_t 2018-11 = 2018-11
__cpp_concepts 2020-02 = 2020-02
... truncated ...
C++20 LIB (64/67)
__cpp_lib_array_constexpr 2018-11 = 2018-11
__cpp_lib_assume_aligned 2018-11 = 2018-11
__cpp_lib_atomic_flag_test 2019-07 = 2019-07
... truncated ...
C++23 CORE (2/11)
__cpp_char8_t 2018-11 < 2022-07
__cpp_consteval 2018-11 < 2022-11
... truncated ...
C++23 LIB (16/64)
__cpp_lib_adaptor_iterator_pair_constructor 2021-06 = 2021-06
__cpp_lib_algorithm_iterator_requirients ------- < 2022-07
__cpp_lib_allocate_at_least ------- < 2023-02
__cpp_lib_associative_heterogeneous_erasure ------- < 2021-10
__cpp_lib_barrier 2019-07 < 2023-02
... truncated ...
ALL CORE MACROS UP TO C++23 (55/65)
__cpp_aggregate_bases 2016-03 = 2016-03
__cpp_aggregate_nsdmi 2013-04 = 2013-04
__cpp_aggregate_paren_init 2019-02 = 2019-02
__cpp_alias_tiplates 2007-04 = 2007-04
... truncated ...
ALL LIB MACROS UP TO C++23 (135/185)
__cpp_lib_adaptor_iterator_pair_constructor 2021-06 = 2021-06
__cpp_lib_addressof_constexpr 2016-03 = 2016-03
__cpp_lib_algorithm_iterator_requirients ------- < 2022-07
__cpp_lib_allocate_at_least ------- < 2023-02
__cpp_lib_allocator_traits_is_always_equal 2014-11 = 2014-11
... truncated ...
ATTRIBUTES (8/10)
assume ------- < 2022-07
carries_dependency ------- < 2008-09
deprecated 2013-09 = 2013-09
fallthrough 2016-03 = 2016-03
... truncated ...
Compiler specific macros:
__cplusplus 202100L
__GNUG__ 12
__GNUC_MINOR__ 2
__GNUC_PATCHLEVEL__ 1