Макросы проверки возможностей (начиная с C++20)
Стандарт определяет набор макросов препроцессора, соответствующих языку C++ и возможностям библиотеки, представленным в C++11 или новее. Они предназначены как простой и портабельный способ проверки наличия указанных возможностей.
Содержание |
[править] Атрибуты
__has_cpp_attribute( маркер-атрибута )
|
|||||||||
Проверяет поддержку атрибута с именем маркер-атрибута (после раскрытия макроса).
Для каждого стандартного атрибута реализация определяет, расширяется ли __has_cpp_attribute
до значения, указанного в таблице ниже (это год и месяц, в которых атрибут был добавлен в рабочий проект) или 0. Он расширится до заданного значения в таблице тогда и только тогда, когда стандартный атрибут заставляет реализацию вести себя так, как рекомендовано (выдача диагностических сообщений, влияние на структуру классов и т.д.).
Наличие атрибутов, специфичных для поставщика, определяется ненулевым значением.
__has_cpp_attribute
можно разложить на выражение
#if и
#elif.
Он рассматривается как определённый макрос для
#ifdef,
#ifndef,
#elifdef,
#elifndef (начиная с C++23) и defined, но не может быть использован где-либо еще.
маркер-атрибута | Атрибут | Значение | Стандарт | Документ(ы) |
---|---|---|---|---|
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 | (C++17) | P0189R1 |
201907L | (C++20) | P1301R4 | ||
noreturn
|
[[noreturn]]
|
200809L | (C++11) | N2761 |
unlikely
|
[[unlikely]]
|
201803L | (C++20) | P0479R5 |
Общее количество атрибутов: 10 |
[править] Возможности языка
Следующие макросы предопределены в каждой единице трансляции. Каждый макрос расширяется до целочисленного литерала, соответствующего году и месяцу, когда соответствующая возможность была включена в рабочий черновик.
Когда возможность значительно изменится, макрос будет обновлён соответствующим образом.
Имя макроса | Возможность | Значение | Стд |
---|---|---|---|
__cpp_aggregate_bases | Агрегирование классов с базовыми классами | 201603L | (C++17) |
__cpp_aggregate_nsdmi | Агрегирование классов с инициализаторами элементов по умолчанию | 201304L | (C++14) |
__cpp_aggregate_paren_init | Агрегированная инициализация в форме прямой инициализации | 201902L | (C++20) |
__cpp_alias_templates | Шаблоны псевдонимов | 200704L | (C++11) |
__cpp_aligned_new | Динамическое выделение памяти для данных с нестандартным выравниванием | 201606L | (C++17) |
__cpp_attributes | Атрибуты | 200809L | (C++11) |
__cpp_binary_literals | Двоичные литералы | 201304L | (C++14) |
__cpp_capture_star_this | Лямбда-захват *this по значению как [=,*this] | 201603L | (C++17) |
__cpp_char8_t | char8_t | 201811L | (C++20) |
__cpp_concepts | Концепты | 201907L | (C++20) |
__cpp_conditional_explicit | explicit(bool) |
201806L | (C++20) |
__cpp_consteval | Немедленно выполняемые функции | 201811L | (C++20) |
__cpp_constexpr | constexpr | 200704L | (C++11) |
Ослабленный constexpr , не-const constexpr методы |
201304L | (C++14) | |
Constexpr лямбда | 201603L | (C++17) | |
Тривиальный инициализация по умолчанию и объявление asm в constexpr функциях | 201907L | (C++20) | |
__cpp_constexpr_dynamic_alloc | Операции для динамической длительности хранения в constexpr функциях | 201907L | (C++20) |
__cpp_constexpr_in_decltype | Создание определений функций и переменных, когда они необходимы для вычисления константы | 201711L | (C++20) |
__cpp_constinit | constinit | 201907L | (C++20) |
__cpp_decltype | decltype | 200707L | (C++11) |
__cpp_decltype_auto | Вывод типа возвращаемого значения для обычных функций | 201304L | (C++14) |
__cpp_deduction_guides | Вывод аргументов шаблона для шаблонов классов | 201703L | (C++17) |
CTAD для агрегатов и псевдонимов | 201907L | (C++20) | |
__cpp_delegating_constructors | Делегирование конструкторов | 200604L | (C++11) |
__cpp_designated_initializers | Назначенный инициализатор | 201707L | (C++20) |
__cpp_enumerator_attributes | Атрибуты для нумераторов | 201411L | (C++17) |
__cpp_fold_expressions | Выражения свёртки | 201603L | (C++17) |
__cpp_generic_lambdas | Общие лямбда-выражения | 201304L | (C++14) |
Знакомый синтаксис шаблона для общих лямбд | 201707L | (C++20) | |
__cpp_guaranteed_copy_elision | Гарантированный пропуск копирования за счёт упрощённой категории значений | 201606L | (C++17) |
__cpp_hex_float | Шестнадцатеричные литералы с плавающей запятой | 201603L | (C++17) |
__cpp_if_consteval | consteval if |
202106L | (C++23) |
__cpp_if_constexpr | constexpr if |
201606L | (C++17) |
__cpp_impl_coroutine | Сопрограммы (поддержка компилятором) | 201902L | (C++20) |
__cpp_impl_destroying_delete | Уничтожающий оператор delete (поддержка компилятором) | 201806L | (C++20) |
__cpp_impl_three_way_comparison | Трёхстороннее сравнение (поддержка компилятором) | 201907L | (C++20) |
__cpp_inheriting_constructors | Наследование конструкторов | 200802L | (C++11) |
Переделка наследуемых конструкторов | 201511L | (C++17) | |
__cpp_init_captures | Захват при инициализации лямбда | 201304L | (C++14) |
Разрешено расширение пакета в захвате при инициализации лямбда | 201803L | (C++20) | |
__cpp_initializer_lists | Список инициализации и std::initializer_list | 200806L | (C++11) |
__cpp_inline_variables | Встроенные переменные | 201606L | (C++17) |
__cpp_lambdas | Лямбда-выражения | 200907L | (C++11) |
__cpp_modules | Модули | 201907L | (C++20) |
__cpp_namespace_attributes | Атрибуты для пространств имён | 201411L | (C++17) |
__cpp_noexcept_function_type | Спецификации исключений сделаны частью системы типов | 201510L | (C++17) |
__cpp_nontype_template_args | Разрешено константное вычисление для всех аргументов шаблона, не относящиеся к типу | 201411L | (C++17) |
Типы классов и типы с плавающей запятой в аргументах шаблона не являющихся типами | 201911L | (C++20) | |
__cpp_nontype_template_parameter_auto | Объявление аргументов шаблона не являющиеся типами с auto |
201606L | (C++17) |
__cpp_nsdmi | Инициализаторы нестатических элементов данных | 200809L | (C++11) |
__cpp_range_based_for | Основанный на диапазоне цикл for |
200907L | (C++11) |
Цикл for на основе диапазона с разными начальным /конечным типами |
201603L | (C++17) | |
__cpp_raw_strings | Необработанные строковые литералы | 200710L | (C++11) |
__cpp_ref_qualifiers | Квалификаторы ссылок | 200710L | (C++11) |
__cpp_return_type_deduction | Вывод типа возвращаемого значения для обычных функций | 201304L | (C++14) |
__cpp_rvalue_references | Правосторонняя ссылка | 200610L | (C++11) |
__cpp_size_t_suffix | Литеральные суффиксы для size_t и её знаковой версии |
202011L | (C++23) |
__cpp_sized_deallocation | Освобождение памяти по размеру | 201309L | (C++14) |
__cpp_static_assert | static_assert | 200410L | (C++11) |
Одно-аргументный static_assert |
201411L | (C++17) | |
__cpp_structured_bindings | Структурные привязки | 201606L | (C++17) |
__cpp_template_template_args | Соответствие шаблонным аргументам шаблона | 201611L | (C++17) |
__cpp_threadsafe_static_init | Динамическая инициализация и уничтожение с конкуренцией | 200806L | (C++11) |
__cpp_unicode_characters | Новые символьные типы (char16_t и char32_t) | 200704L | (C++11) |
__cpp_unicode_literals | Строковые литералы в Юникоде | 200710L | (C++11) |
__cpp_user_defined_literals | Пользовательские литералы | 200809L | (C++11) |
__cpp_using_enum | Using enum | 201907L | (C++20) |
__cpp_variable_templates | Шаблоны переменных | 201304L | (C++14) |
__cpp_variadic_templates | Вариативные шаблоны | 200704L | (C++11) |
__cpp_variadic_using | Расширения пакетов в using -объявлении |
201611L | (C++17) |
[править] Возможности библиотеки
Следующие макросы определены, если включён заголовок <version> или любой из соответствующих заголовков в таблице ниже. Каждый макрос расширяется в целочисленный литерал, соответствующий году и месяцу, когда соответствующая возможность была включена в рабочий черновик.
Когда возможность значительно изменяется, макрос обновляется соответствующим образом.
Имя макроса | Возможность | Значение | Заголовок | Стд |
---|---|---|---|---|
__cpp_lib_addressof_constexpr | Constexpr std::addressof | 201603L | <memory> | (C++17) |
__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 для std::reverse_iterator, std::move_iterator, std::array и доступа в диапазоне | 201603L | <iterator> <array> | (C++17) |
ConstexprIterator; constexpr сравнение для std::array; разные constexpr биты (std::array::fill и другие) | 201811L | <iterator> <array> | (C++20) | |
__cpp_lib_as_const | std::as_const | 201510L | <utility> | (C++17) |
__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 | Атомарность с плавающей точкой | 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 | атомарные целочисленные типы без блокировок (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 | Исправление атомарной инициализации (инициализация значения std::atomic по умолчанию) | 201911L | <atomic> <memory> | (C++20) |
__cpp_lib_atomic_wait | Эффективное std::atomic ожидание | 201907L | <atomic> | (C++20) |
__cpp_lib_barrier | std::barrier | 201907L | <barrier> | (C++20) |
__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 | Битовые операции | 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 | Алгоритмы поиска | 201603L | <functional> | (C++17) |
__cpp_lib_byte | std::byte | 201603L | <cstddef> | (C++17) |
__cpp_lib_char8_t | Библиотечная поддержка для char8_t | 201907L | <atomic> <filesystem> <istream> <limits> <locale> <ostream> <string> <string_view> | (C++20) |
__cpp_lib_chrono | Функции округления для std::chrono::duration и std::chrono::time_point | 201510L | <chrono> | (C++17) |
Constexpr для всех функций-элементов std::chrono::duration и std::chrono::time_point | 201611L | <chrono> | (C++17) | |
Календари и Часовые Пояса | 201907L | <chrono> | (C++20) | |
__cpp_lib_chrono_udls | Определяемые пользователем литералы для типов времени | 201304L | <chrono> | (C++14) |
__cpp_lib_clamp | std::clamp | 201603L | <algorithm> | (C++17) |
__cpp_lib_complex_udls | Пользовательские литералы для std::complex |
201309L | <complex> | (C++14) |
__cpp_lib_concepts | Концепты стандартной библиотеки | 202002L | <concepts> | (C++20) |
__cpp_lib_constexpr_algorithms | Constexpr для алгоритмов | 201806L | <algorithm> | (C++20) |
__cpp_lib_constexpr_complex | Constexpr для std::complex | 201711L | <complex> | (C++20) |
__cpp_lib_constexpr_dynamic_alloc | Constexpr для std::allocator и связанных утилит | 201907L | <memory> | (C++20) |
__cpp_lib_constexpr_functional | Разные constexpr биты (std::default_searcher); constexpr INVOKE | 201907L | <functional> | (C++20) |
__cpp_lib_constexpr_iterator | Разные constexpr биты (std::insert_iterator и другие) | 201811L | <iterator> | (C++20) |
__cpp_lib_constexpr_memory | Constexpr в std::pointer_traits | 201811L | <memory> | (C++20) |
__cpp_lib_constexpr_numeric | Constexpr для числовых алгоритмов | 201911L | <numeric> | (C++20) |
__cpp_lib_constexpr_string | Constexpr для std::string | 201907L | <string> | (C++20) |
__cpp_lib_constexpr_string_view | Разные constexpr биты (std::string_view::copy) | 201811L | <string_view> | (C++20) |
__cpp_lib_constexpr_tuple | Разные constexpr биты (std::tuple::operator= и другие) | 201811L | <tuple> | (C++20) |
__cpp_lib_constexpr_typeinfo | Constexpr для std::type_info::operator== | 202106L | <typeinfo> | (C++23) |
__cpp_lib_constexpr_utility | Разные constexpr биты (std::pair::operator= и другие) | 201811L | <utility> | (C++20) |
__cpp_lib_constexpr_vector | Constexpr для std::vector | 201907L | <vector> | (C++20) |
__cpp_lib_coroutine | Сопрограммы (поддержка библиотекой) | 201902L | <coroutine> | (C++20) |
__cpp_lib_destroying_delete | Уничтожение operator delete (поддержка библиотекой) |
201806L | <new> | (C++20) |
__cpp_lib_enable_shared_from_this | Более точная спецификация std::enable_shared_from_this | 201603L | <memory> | (C++17) |
__cpp_lib_endian | std::endian | 201907L | <bit> | (C++20) |
__cpp_lib_erase_if | Равномерная очистка контейнера | 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 | Политики исполнения | 201603L | <execution> | (C++17) |
std::execution::unsequenced_policy | 201902L | <execution> | (C++20) | |
__cpp_lib_filesystem | Библиотека файловой системы | 201703L | <filesystem> | (C++17) |
__cpp_lib_format | Форматирование текста | 201907L | <format> | (C++20) |
__cpp_lib_gcd_lcm | std::gcd, std::lcm | 201606L | <numeric> | (C++17) |
__cpp_lib_generic_associative_lookup | Поиск гетерогенным сравнением в [[cpp/container#Ассоциативные контейнеры|ассоциативных контейнерах | 201304L | <map> <set> | (C++14) |
__cpp_lib_generic_unordered_lookup | Поиск гетерогенным сравнением в ассоциативных контейнерах | 201811L | <unordered_map> <unordered_set> | (C++20) |
__cpp_lib_hardware_interference_size | [[constexpr std::hardware_{constructive, destructive}_interference_size|hardware_destructive_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-аргументная перегрузка std::hypot | 201603L | <cmath> | (C++17) |
__cpp_lib_incomplete_container_elements | Минимальная поддержка неполных типов для стандартных контейнеров | 201505L | <forward_list> <list> <vector> | (C++17) |
__cpp_lib_int_pow2 | Интегральные операции степени двойки (std::has_single_bit, std::bit_ceil, std::bit_floor, std::bit_length) | 202002L | <bit> | (C++20) |
__cpp_lib_integer_comparison_functions | Целочисленные функции сравнения | 202002L | <utility> | (C++20) |
__cpp_lib_integer_sequence | Целочисленные последовательности времени компиляции | 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 | Свойства указателя-взаимоконвертируемости | 201907L | <type_traits> | (C++20) |
__cpp_lib_is_scoped_enum | std::is_scoped_enum | 202011L | <type_traits> | (C++23) |
__cpp_lib_is_swappable | [nothrow -]замена свойств |
201603L | <type_traits> | (C++17) |
__cpp_lib_jthread | Стоповый токен и присоединяющаяся ветвь | 201911L | <stop_token> <thread> | (C++20) |
__cpp_lib_latch | std::latch | 201907L | <latch> | (C++20) |
__cpp_lib_launder | Основной Выпуск 1776: Обмен объектов класса, содержащих ссылочные элементы (std::launder) | 201606L | <new> | (C++17) |
__cpp_lib_list_remove_return_type | Изменение типа возврата remove(), remove_if() и unique() элементов объектов std::forward_list и std::list | 201806L | <forward_list> <list> | (C++20) |
__cpp_lib_logical_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 | Математические константы | 201907L | <numbers> | (C++20) |
__cpp_lib_math_special_functions | Специальные математические функции для C++17 | 201603L | <cmath> | (C++17) |
__cpp_lib_memory_resource | std::pmr::memory_resource | 201603L | <memory_resource> | (C++17) |
__cpp_lib_node_extract | Объединение карт и наборов (std::map::extract, std::map::merge, std::map::insert(node_type) и т.д.) | 201606L | <map> <set> <unordered_map> <unordered_set> | (C++17) |
__cpp_lib_nonmember_container_access | std::size(), std::data() и std::empty() | 201411L | <iterator> <array> <deque> <forward_list> <list> <map> <regex> <set> <string> <unordered_map> <unordered_set> <vector> | (C++17) |
__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) |
__cpp_lib_parallel_algorithm | Параллельные алгоритмы | 201603L | <algorithm> <numeric> | (C++17) |
__cpp_lib_polymorphic_allocator | std::polymorphic_allocator<> как тип словаря | 201902L | <memory_resource> | (C++20) |
__cpp_lib_quoted_string_io | std::quoted | 201304L | <iomanip> | (C++14) |
__cpp_lib_ranges | Библиотека диапазонов и ограниченные алгоритмы | 201911L | <algorithm> <functional> <iterator> <memory> <ranges> | (C++20) |
__cpp_lib_raw_memory_algorithms | Расширение инструментов управления памятью | 201606L | <memory> | (C++17) |
__cpp_lib_remove_cvref | std::remove_cvref | 201711L | <type_traits> | (C++20) |
__cpp_lib_result_of_sfinae | std::result_of и SFINAE | 201210L | <type_traits> <functional> | (C++14) |
__cpp_lib_robust_nonmodifying_seq_ops | Повышение устойчивости последовательности немодифицирующих операций (двухдиапазонные перегрузки для std::mismatch, std::equal и 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 (безвременной) | 201505L | <shared_mutex> | (C++17) |
__cpp_lib_shared_ptr_arrays | std::shared_ptr<T[]> | 201611L | <memory> | (C++17) |
Поддержка массива 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 и std::shift_right | 201806L | <algorithm> | (C++20) |
__cpp_lib_smart_ptr_for_overwrite | Создание умного указателя с инициализацией по умолчанию (std::allocate_shared_for_overwrite, std::make_shared_for_overwrite, std::make_unique_for_overwrite) | 202002L | <memory> | (C++20) |
__cpp_lib_source_location | Сбор информации об исходном коде (std::source_location) | 201907L | <source_location> | (C++20) |
__cpp_lib_span | std::span | 202002L | <span> | (C++20) |
__cpp_lib_ssize | std::ssize и беззнаковый std::span::size | 201902L | <iterator> | (C++20) |
__cpp_lib_stacktrace | Библиотека Stacktrace | 202011L | <stacktrace> | (C++23) |
__cpp_lib_starts_ends_with | Проверка префикса и суффикса строки (starts_with() и ends_with() для std::string и std::string_view) | 201711L | <string> <string_view> | (C++20) |
__cpp_lib_stdatomic_h | Заголовок совместимости для атомарных операций C | 202011L | <stdatomic.h> | (C++23) |
__cpp_lib_string_contains | Функции contains объектов std::basic_string и std::basic_string_view |
202011L | <string> <string_view> | (C++23) |
__cpp_lib_string_udls | Пользовательские литералы для строковых типов | 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 | Синхронизированный буферизированный ostream (std::syncbuf, std::osyncstream) и манипуляторы | 201803L | <syncstream> | (C++20) |
__cpp_lib_three_way_comparison | Трёхстороннее сравнение (поддержка библиотекой); добавление трёхстороннего сравнения в библиотеку | 201907L | <compare> | (C++20) |
__cpp_lib_to_address | Утилита для преобразования указателя в сырой указатель (std::to_address) | 201711L | <memory> | (C++20) |
__cpp_lib_to_array | std::to_array | 201907L | <array> | (C++20) |
__cpp_lib_to_chars | Элементарные преобразования строк (std::to_chars, std::from_chars) | 201611L | <charconv> | (C++17) |
__cpp_lib_to_underlying | std::to_underlying | 2XXXXXL | <utility> | (C++23) |
__cpp_lib_transformation_trait_aliases | Шаблоны псевдонимов для TransformationTraits | 201304L | <type_traits> | (C++14) |
__cpp_lib_transparent_operators | Прозрачные операторы функторы (std::less<> и другие) | 201210L | <functional> | (C++14) |
Прозрачный 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 | Адресация кортежей по типу | 201304L | <tuple> <utility> | (C++14) |
__cpp_lib_type_identity | std::type_identity | 201806L | <type_traits> | (C++20) |
__cpp_lib_type_trait_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_unwrap_ref | std::unwrap_ref_decay и std::unwrap_reference | 201811L | <functional> | (C++20) |
__cpp_lib_variant | std::variant: типобезопасное объединение для C++17 | 201606L | <variant> | (C++17) |
__cpp_lib_void_t | std::void_t | 201411L | <type_traits> | (C++17) |
[править] Пример
[править] Обычное использование
#ifdef __has_include // Проверяет, присутствует ли __has_include # if __has_include(<optional>) // Проверяет наличие стандартной библиотеки # include <optional> # elif __has_include(<experimental/optional>) // Проверяет наличие экспериментальной // версии # include <experimental/optional> # elif __has_include(<boost/optional.hpp>) // Проверяет наличие внешней библиотеки # include <boost/optional.hpp> # else // Вообще ничего не найдено # error "Отсутствует <optional>" # endif #endif #ifdef __has_cpp_attribute // Проверяет, присутствует ли // __has_cpp_attribute # if __has_cpp_attribute(deprecated) // Проверяет атрибут # define DEPRECATED(msg) [[deprecated(msg)]] # endif #endif #ifndef DEPRECATED # define DEPRECATED(msg) #endif DEPRECATED("foo() устарела") void foo(); #if __cpp_constexpr >= 201304 // Проверяет конкретную версию // функциональности # define CONSTEXPR constexpr #else # define CONSTEXPR inline #endif CONSTEXPR int bar(unsigned i) { #if __cpp_binary_literals // Проверяет наличие функциональности 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() { }
[править] Дамп возможностей компилятора
Следующая (совместимая с C++11) программа выводит функциональность и атрибуты компилятора C++.
// Измените эти параметры, чтобы распечатать только необходимую информацию. static struct PrintOptions { constexpr static int longest_macro_name { 45 }; constexpr static bool titles = 1; constexpr static bool counters = 1; constexpr static bool attributes = 1; constexpr static bool standard_values = 1; constexpr static bool compiler_specific = 1; constexpr static bool core_features = 1; constexpr static bool lib_features = 1; constexpr static bool supported_features = 1; constexpr static bool unsupported_features = 1; constexpr static bool sort_by_date = 0; constexpr static bool separate_year_month = 1; constexpr static bool separated_revisions = 1; constexpr static bool latest_revisions = 1; constexpr static bool cxx98 = 0; constexpr static bool cxx11 = 1; constexpr static bool cxx14 = 1; constexpr static bool cxx17 = 1; constexpr static bool cxx20 = 1; constexpr static bool cxx23 = 1; constexpr static bool cxx26 = 1; constexpr static bool cxx29 = 0; } print; #if __cplusplus < 201100 # error "Требуется C++11 или выше" #endif #include <algorithm> #include <cstdio> #include <cstring> #include <utility> #include <vector> #ifdef __has_include # if __has_include(<version>) # include <version> # endif #endif // Ожидает строку, которая начинается с 6 десятичных цифр или с '_' // (если не поддерживается) #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) //< не зависит от компилятора, но полезен :) 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__) // Добавьте свои любимые макросы для компилятора. Неопределённые не будут напечатаны. }; static constexpr CompilerFeature cxx98_core[] = { COMPILER_FEATURE_ENTRY(199711L, __cpp_exceptions) COMPILER_FEATURE_ENTRY(199711L, __cpp_rtti) }; static constexpr CompilerFeature cxx11_core[] = { COMPILER_FEATURE_ENTRY(200704L, __cpp_alias_templates) COMPILER_FEATURE_ENTRY(200809L, __cpp_attributes) COMPILER_FEATURE_ENTRY(200704L, __cpp_constexpr) COMPILER_FEATURE_ENTRY(201711L, __cpp_constexpr_in_decltype) COMPILER_FEATURE_ENTRY(200707L, __cpp_decltype) COMPILER_FEATURE_ENTRY(200604L, __cpp_delegating_constructors) COMPILER_FEATURE_ENTRY(201511L, __cpp_inheriting_constructors) COMPILER_FEATURE_ENTRY(200806L, __cpp_initializer_lists) COMPILER_FEATURE_ENTRY(200907L, __cpp_lambdas) COMPILER_FEATURE_ENTRY(200809L, __cpp_nsdmi) COMPILER_FEATURE_ENTRY(200907L, __cpp_range_based_for) COMPILER_FEATURE_ENTRY(200710L, __cpp_raw_strings) COMPILER_FEATURE_ENTRY(200710L, __cpp_ref_qualifiers) COMPILER_FEATURE_ENTRY(200610L, __cpp_rvalue_references) COMPILER_FEATURE_ENTRY(200410L, __cpp_static_assert) COMPILER_FEATURE_ENTRY(200806L, __cpp_threadsafe_static_init) COMPILER_FEATURE_ENTRY(200704L, __cpp_unicode_characters) COMPILER_FEATURE_ENTRY(200710L, __cpp_unicode_literals) COMPILER_FEATURE_ENTRY(200809L, __cpp_user_defined_literals) COMPILER_FEATURE_ENTRY(200704L, __cpp_variadic_templates) }; static constexpr CompilerFeature cxx14_core[] = { COMPILER_FEATURE_ENTRY(201304L, __cpp_aggregate_nsdmi) COMPILER_FEATURE_ENTRY(201304L, __cpp_binary_literals) COMPILER_FEATURE_ENTRY(201304L, __cpp_constexpr) COMPILER_FEATURE_ENTRY(201304L, __cpp_decltype_auto) COMPILER_FEATURE_ENTRY(201304L, __cpp_generic_lambdas) COMPILER_FEATURE_ENTRY(201304L, __cpp_init_captures) COMPILER_FEATURE_ENTRY(201304L, __cpp_return_type_deduction) COMPILER_FEATURE_ENTRY(201309L, __cpp_sized_deallocation) COMPILER_FEATURE_ENTRY(201304L, __cpp_variable_templates) }; static constexpr CompilerFeature cxx14_lib[] = { COMPILER_FEATURE_ENTRY(201304L, __cpp_lib_chrono_udls) COMPILER_FEATURE_ENTRY(201309L, __cpp_lib_complex_udls) COMPILER_FEATURE_ENTRY(201304L, __cpp_lib_exchange_function) COMPILER_FEATURE_ENTRY(201304L, __cpp_lib_generic_associative_lookup) COMPILER_FEATURE_ENTRY(201304L, __cpp_lib_integer_sequence) COMPILER_FEATURE_ENTRY(201304L, __cpp_lib_integral_constant_callable) COMPILER_FEATURE_ENTRY(201402L, __cpp_lib_is_final) COMPILER_FEATURE_ENTRY(201309L, __cpp_lib_is_null_pointer) COMPILER_FEATURE_ENTRY(201402L, __cpp_lib_make_reverse_iterator) COMPILER_FEATURE_ENTRY(201304L, __cpp_lib_make_unique) COMPILER_FEATURE_ENTRY(201304L, __cpp_lib_null_iterators) COMPILER_FEATURE_ENTRY(201304L, __cpp_lib_quoted_string_io) COMPILER_FEATURE_ENTRY(201210L, __cpp_lib_result_of_sfinae) COMPILER_FEATURE_ENTRY(201304L, __cpp_lib_robust_nonmodifying_seq_ops) COMPILER_FEATURE_ENTRY(201402L, __cpp_lib_shared_timed_mutex) COMPILER_FEATURE_ENTRY(201304L, __cpp_lib_string_udls) COMPILER_FEATURE_ENTRY(201304L, __cpp_lib_transformation_trait_aliases) COMPILER_FEATURE_ENTRY(201210L, __cpp_lib_transparent_operators) COMPILER_FEATURE_ENTRY(201402L, __cpp_lib_tuple_element_t) COMPILER_FEATURE_ENTRY(201304L, __cpp_lib_tuples_by_type) }; static constexpr CompilerFeature cxx17_core[] = { COMPILER_FEATURE_ENTRY(201603L, __cpp_aggregate_bases) COMPILER_FEATURE_ENTRY(201606L, __cpp_aligned_new) COMPILER_FEATURE_ENTRY(201603L, __cpp_capture_star_this) COMPILER_FEATURE_ENTRY(201603L, __cpp_constexpr) COMPILER_FEATURE_ENTRY(201703L, __cpp_deduction_guides) COMPILER_FEATURE_ENTRY(201411L, __cpp_enumerator_attributes) COMPILER_FEATURE_ENTRY(201603L, __cpp_fold_expressions) COMPILER_FEATURE_ENTRY(201606L, __cpp_guaranteed_copy_elision) COMPILER_FEATURE_ENTRY(201603L, __cpp_hex_float) COMPILER_FEATURE_ENTRY(201606L, __cpp_if_constexpr) COMPILER_FEATURE_ENTRY(201606L, __cpp_inline_variables) COMPILER_FEATURE_ENTRY(201411L, __cpp_namespace_attributes) COMPILER_FEATURE_ENTRY(201510L, __cpp_noexcept_function_type) COMPILER_FEATURE_ENTRY(201411L, __cpp_nontype_template_args) COMPILER_FEATURE_ENTRY(201606L, __cpp_nontype_template_parameter_auto) COMPILER_FEATURE_ENTRY(201603L, __cpp_range_based_for) COMPILER_FEATURE_ENTRY(201411L, __cpp_static_assert) COMPILER_FEATURE_ENTRY(201606L, __cpp_structured_bindings) COMPILER_FEATURE_ENTRY(201611L, __cpp_template_template_args) COMPILER_FEATURE_ENTRY(201611L, __cpp_variadic_using) }; static constexpr CompilerFeature cxx17_lib[] = { COMPILER_FEATURE_ENTRY(201603L, __cpp_lib_addressof_constexpr) COMPILER_FEATURE_ENTRY(201411L, __cpp_lib_allocator_traits_is_always_equal) COMPILER_FEATURE_ENTRY(201606L, __cpp_lib_any) COMPILER_FEATURE_ENTRY(201603L, __cpp_lib_apply) COMPILER_FEATURE_ENTRY(201603L, __cpp_lib_array_constexpr) COMPILER_FEATURE_ENTRY(201510L, __cpp_lib_as_const) COMPILER_FEATURE_ENTRY(201603L, __cpp_lib_atomic_is_always_lock_free) COMPILER_FEATURE_ENTRY(201505L, __cpp_lib_bool_constant) COMPILER_FEATURE_ENTRY(201603L, __cpp_lib_boyer_moore_searcher) COMPILER_FEATURE_ENTRY(201603L, __cpp_lib_byte) COMPILER_FEATURE_ENTRY(201611L, __cpp_lib_chrono) COMPILER_FEATURE_ENTRY(201603L, __cpp_lib_clamp) COMPILER_FEATURE_ENTRY(201603L, __cpp_lib_enable_shared_from_this) COMPILER_FEATURE_ENTRY(201603L, __cpp_lib_execution) COMPILER_FEATURE_ENTRY(201703L, __cpp_lib_filesystem) COMPILER_FEATURE_ENTRY(201606L, __cpp_lib_gcd_lcm) COMPILER_FEATURE_ENTRY(201703L, __cpp_lib_hardware_interference_size) COMPILER_FEATURE_ENTRY(201606L, __cpp_lib_has_unique_object_representations) COMPILER_FEATURE_ENTRY(201603L, __cpp_lib_hypot) COMPILER_FEATURE_ENTRY(201505L, __cpp_lib_incomplete_container_elements) COMPILER_FEATURE_ENTRY(201411L, __cpp_lib_invoke) COMPILER_FEATURE_ENTRY(201703L, __cpp_lib_is_aggregate) COMPILER_FEATURE_ENTRY(201703L, __cpp_lib_is_invocable) COMPILER_FEATURE_ENTRY(201603L, __cpp_lib_is_swappable) COMPILER_FEATURE_ENTRY(201606L, __cpp_lib_launder) COMPILER_FEATURE_ENTRY(201510L, __cpp_lib_logical_traits) COMPILER_FEATURE_ENTRY(201606L, __cpp_lib_make_from_tuple) COMPILER_FEATURE_ENTRY(201411L, __cpp_lib_map_try_emplace) COMPILER_FEATURE_ENTRY(201603L, __cpp_lib_math_special_functions) COMPILER_FEATURE_ENTRY(201603L, __cpp_lib_memory_resource) COMPILER_FEATURE_ENTRY(201606L, __cpp_lib_node_extract) COMPILER_FEATURE_ENTRY(201411L, __cpp_lib_nonmember_container_access) COMPILER_FEATURE_ENTRY(201603L, __cpp_lib_not_fn) COMPILER_FEATURE_ENTRY(201606L, __cpp_lib_optional) COMPILER_FEATURE_ENTRY(201603L, __cpp_lib_parallel_algorithm) COMPILER_FEATURE_ENTRY(201606L, __cpp_lib_raw_memory_algorithms) COMPILER_FEATURE_ENTRY(201603L, __cpp_lib_sample) COMPILER_FEATURE_ENTRY(201703L, __cpp_lib_scoped_lock) COMPILER_FEATURE_ENTRY(201505L, __cpp_lib_shared_mutex) COMPILER_FEATURE_ENTRY(201611L, __cpp_lib_shared_ptr_arrays) COMPILER_FEATURE_ENTRY(201606L, __cpp_lib_shared_ptr_weak_type) COMPILER_FEATURE_ENTRY(201606L, __cpp_lib_string_view) COMPILER_FEATURE_ENTRY(201611L, __cpp_lib_to_chars) COMPILER_FEATURE_ENTRY(201510L, __cpp_lib_transparent_operators) COMPILER_FEATURE_ENTRY(201510L, __cpp_lib_type_trait_variable_templates) COMPILER_FEATURE_ENTRY(201411L, __cpp_lib_uncaught_exceptions) COMPILER_FEATURE_ENTRY(201411L, __cpp_lib_unordered_map_try_emplace) COMPILER_FEATURE_ENTRY(202102L, __cpp_lib_variant) COMPILER_FEATURE_ENTRY(201411L, __cpp_lib_void_t) }; static constexpr CompilerFeature cxx20_core[] = { COMPILER_FEATURE_ENTRY(201902L, __cpp_aggregate_paren_init) COMPILER_FEATURE_ENTRY(202207L, __cpp_char8_t) COMPILER_FEATURE_ENTRY(202002L, __cpp_concepts) COMPILER_FEATURE_ENTRY(201806L, __cpp_conditional_explicit) COMPILER_FEATURE_ENTRY(202207L, __cpp_consteval) COMPILER_FEATURE_ENTRY(202002L, __cpp_constexpr) COMPILER_FEATURE_ENTRY(201907L, __cpp_constexpr_dynamic_alloc) COMPILER_FEATURE_ENTRY(201907L, __cpp_constinit) COMPILER_FEATURE_ENTRY(201907L, __cpp_deduction_guides) COMPILER_FEATURE_ENTRY(201707L, __cpp_designated_initializers) COMPILER_FEATURE_ENTRY(201707L, __cpp_generic_lambdas) COMPILER_FEATURE_ENTRY(201902L, __cpp_impl_coroutine) COMPILER_FEATURE_ENTRY(201806L, __cpp_impl_destroying_delete) COMPILER_FEATURE_ENTRY(201907L, __cpp_impl_three_way_comparison) COMPILER_FEATURE_ENTRY(201803L, __cpp_init_captures) COMPILER_FEATURE_ENTRY(201907L, __cpp_modules) COMPILER_FEATURE_ENTRY(201911L, __cpp_nontype_template_args) COMPILER_FEATURE_ENTRY(201907L, __cpp_using_enum) }; static constexpr CompilerFeature cxx20_lib[] = { COMPILER_FEATURE_ENTRY(201811L, __cpp_lib_array_constexpr) COMPILER_FEATURE_ENTRY(201811L, __cpp_lib_assume_aligned) COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_atomic_flag_test) COMPILER_FEATURE_ENTRY(201711L, __cpp_lib_atomic_float) COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_atomic_lock_free_type_aliases) COMPILER_FEATURE_ENTRY(201806L, __cpp_lib_atomic_ref) COMPILER_FEATURE_ENTRY(201711L, __cpp_lib_atomic_shared_ptr) COMPILER_FEATURE_ENTRY(201911L, __cpp_lib_atomic_value_initialization) COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_atomic_wait) COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_barrier) COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_bind_front) COMPILER_FEATURE_ENTRY(201806L, __cpp_lib_bit_cast) COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_bitops) COMPILER_FEATURE_ENTRY(201902L, __cpp_lib_bounded_array_traits) COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_char8_t) COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_chrono) COMPILER_FEATURE_ENTRY(202002L, __cpp_lib_concepts) COMPILER_FEATURE_ENTRY(201806L, __cpp_lib_constexpr_algorithms) COMPILER_FEATURE_ENTRY(201711L, __cpp_lib_constexpr_complex) COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_constexpr_dynamic_alloc) COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_constexpr_functional) COMPILER_FEATURE_ENTRY(201811L, __cpp_lib_constexpr_iterator) COMPILER_FEATURE_ENTRY(201811L, __cpp_lib_constexpr_memory) COMPILER_FEATURE_ENTRY(201911L, __cpp_lib_constexpr_numeric) COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_constexpr_string) COMPILER_FEATURE_ENTRY(201811L, __cpp_lib_constexpr_string_view) COMPILER_FEATURE_ENTRY(201811L, __cpp_lib_constexpr_tuple) COMPILER_FEATURE_ENTRY(201811L, __cpp_lib_constexpr_utility) COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_constexpr_vector) COMPILER_FEATURE_ENTRY(201902L, __cpp_lib_coroutine) COMPILER_FEATURE_ENTRY(201806L, __cpp_lib_destroying_delete) COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_endian) COMPILER_FEATURE_ENTRY(202002L, __cpp_lib_erase_if) COMPILER_FEATURE_ENTRY(201902L, __cpp_lib_execution) COMPILER_FEATURE_ENTRY(202110L, __cpp_lib_format) COMPILER_FEATURE_ENTRY(201811L, __cpp_lib_generic_unordered_lookup) COMPILER_FEATURE_ENTRY(202002L, __cpp_lib_int_pow2) COMPILER_FEATURE_ENTRY(202002L, __cpp_lib_integer_comparison_functions) COMPILER_FEATURE_ENTRY(201902L, __cpp_lib_interpolate) COMPILER_FEATURE_ENTRY(201811L, __cpp_lib_is_constant_evaluated) COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_is_layout_compatible) COMPILER_FEATURE_ENTRY(201806L, __cpp_lib_is_nothrow_convertible) COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_is_pointer_interconvertible) COMPILER_FEATURE_ENTRY(201911L, __cpp_lib_jthread) COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_latch) COMPILER_FEATURE_ENTRY(201806L, __cpp_lib_list_remove_return_type) COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_math_constants) COMPILER_FEATURE_ENTRY(202106L, __cpp_lib_optional) COMPILER_FEATURE_ENTRY(201902L, __cpp_lib_polymorphic_allocator) COMPILER_FEATURE_ENTRY(202110L, __cpp_lib_ranges) COMPILER_FEATURE_ENTRY(201711L, __cpp_lib_remove_cvref) COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_semaphore) COMPILER_FEATURE_ENTRY(201707L, __cpp_lib_shared_ptr_arrays) COMPILER_FEATURE_ENTRY(201806L, __cpp_lib_shift) COMPILER_FEATURE_ENTRY(202002L, __cpp_lib_smart_ptr_for_overwrite) COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_source_location) COMPILER_FEATURE_ENTRY(202002L, __cpp_lib_span) COMPILER_FEATURE_ENTRY(201902L, __cpp_lib_ssize) COMPILER_FEATURE_ENTRY(201711L, __cpp_lib_starts_ends_with) COMPILER_FEATURE_ENTRY(201803L, __cpp_lib_string_view) COMPILER_FEATURE_ENTRY(201803L, __cpp_lib_syncbuf) COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_three_way_comparison) COMPILER_FEATURE_ENTRY(201711L, __cpp_lib_to_address) COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_to_array) COMPILER_FEATURE_ENTRY(201806L, __cpp_lib_type_identity) COMPILER_FEATURE_ENTRY(201811L, __cpp_lib_unwrap_ref) COMPILER_FEATURE_ENTRY(202106L, __cpp_lib_variant) }; static constexpr CompilerFeature cxx23_core[] = { COMPILER_FEATURE_ENTRY(202110L, __cpp_auto_cast) COMPILER_FEATURE_ENTRY(202211L, __cpp_constexpr) COMPILER_FEATURE_ENTRY(202110L, __cpp_explicit_this_parameter) COMPILER_FEATURE_ENTRY(202106L, __cpp_if_consteval) COMPILER_FEATURE_ENTRY(202207L, __cpp_implicit_move) COMPILER_FEATURE_ENTRY(202211L, __cpp_multidimensional_subscript) COMPILER_FEATURE_ENTRY(202207L, __cpp_named_character_escapes) COMPILER_FEATURE_ENTRY(202211L, __cpp_range_based_for) COMPILER_FEATURE_ENTRY(202011L, __cpp_size_t_suffix) COMPILER_FEATURE_ENTRY(202207L, __cpp_static_call_operator) }; static constexpr CompilerFeature cxx23_lib[] = { COMPILER_FEATURE_ENTRY(202106L, __cpp_lib_adaptor_iterator_pair_constructor) COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_algorithm_iterator_requirements) COMPILER_FEATURE_ENTRY(202302L, __cpp_lib_allocate_at_least) COMPILER_FEATURE_ENTRY(202110L, __cpp_lib_associative_heterogeneous_erasure) COMPILER_FEATURE_ENTRY(202302L, __cpp_lib_barrier) COMPILER_FEATURE_ENTRY(202202L, __cpp_lib_bind_back) COMPILER_FEATURE_ENTRY(202110L, __cpp_lib_byteswap) COMPILER_FEATURE_ENTRY(202302L, __cpp_lib_common_reference) COMPILER_FEATURE_ENTRY(202302L, __cpp_lib_common_reference_wrapper) COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_concepts) COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_constexpr_bitset) COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_constexpr_charconv) COMPILER_FEATURE_ENTRY(202202L, __cpp_lib_constexpr_cmath) COMPILER_FEATURE_ENTRY(202202L, __cpp_lib_constexpr_memory) COMPILER_FEATURE_ENTRY(202106L, __cpp_lib_constexpr_typeinfo) COMPILER_FEATURE_ENTRY(202202L, __cpp_lib_containers_ranges) COMPILER_FEATURE_ENTRY(202211L, __cpp_lib_expected) COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_flat_map) COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_flat_set) COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_format) COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_format_ranges) COMPILER_FEATURE_ENTRY(202302L, __cpp_lib_formatters) COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_forward_like) COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_generator) COMPILER_FEATURE_ENTRY(202106L, __cpp_lib_invoke_r) COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_ios_noreplace) COMPILER_FEATURE_ENTRY(202302L, __cpp_lib_is_implicit_lifetime) COMPILER_FEATURE_ENTRY(202011L, __cpp_lib_is_scoped_enum) COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_mdspan) COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_modules) COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_move_iterator_concept) COMPILER_FEATURE_ENTRY(202110L, __cpp_lib_move_only_function) COMPILER_FEATURE_ENTRY(202110L, __cpp_lib_optional) COMPILER_FEATURE_ENTRY(202106L, __cpp_lib_out_ptr) COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_print) COMPILER_FEATURE_ENTRY(202302L, __cpp_lib_ranges) COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_ranges_as_const) COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_ranges_as_rvalue) COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_ranges_cartesian_product) COMPILER_FEATURE_ENTRY(202202L, __cpp_lib_ranges_chunk) COMPILER_FEATURE_ENTRY(202202L, __cpp_lib_ranges_chunk_by) COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_ranges_contains) COMPILER_FEATURE_ENTRY(202302L, __cpp_lib_ranges_enumerate) COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_ranges_find_last) COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_ranges_fold) COMPILER_FEATURE_ENTRY(202202L, __cpp_lib_ranges_iota) COMPILER_FEATURE_ENTRY(202202L, __cpp_lib_ranges_join_with) COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_ranges_repeat) COMPILER_FEATURE_ENTRY(202202L, __cpp_lib_ranges_slide) COMPILER_FEATURE_ENTRY(202106L, __cpp_lib_ranges_starts_ends_with) COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_ranges_stride) COMPILER_FEATURE_ENTRY(202202L, __cpp_lib_ranges_to_container) COMPILER_FEATURE_ENTRY(202110L, __cpp_lib_ranges_zip) COMPILER_FEATURE_ENTRY(202202L, __cpp_lib_reference_from_temporary) COMPILER_FEATURE_ENTRY(202202L, __cpp_lib_shift) COMPILER_FEATURE_ENTRY(202106L, __cpp_lib_spanstream) COMPILER_FEATURE_ENTRY(202011L, __cpp_lib_stacktrace) COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_start_lifetime_as) COMPILER_FEATURE_ENTRY(202011L, __cpp_lib_stdatomic_h) COMPILER_FEATURE_ENTRY(202011L, __cpp_lib_string_contains) COMPILER_FEATURE_ENTRY(202110L, __cpp_lib_string_resize_and_overwrite) COMPILER_FEATURE_ENTRY(202102L, __cpp_lib_to_underlying) COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_tuple_like) COMPILER_FEATURE_ENTRY(202202L, __cpp_lib_unreachable) }; static constexpr CompilerFeature cxx26_core[] = { //< Продолжить заполнение COMPILER_FEATURE_ENTRY(202306L, __cpp_constexpr) COMPILER_FEATURE_ENTRY(202306L, __cpp_placeholder_variables) COMPILER_FEATURE_ENTRY(202306L, __cpp_static_assert) }; static constexpr CompilerFeature cxx26_lib[] = { //< Продолжить заполнение COMPILER_FEATURE_ENTRY(202306L, __cpp_lib_associative_heterogeneous_insertion) COMPILER_FEATURE_ENTRY(202306L, __cpp_lib_bind_back) COMPILER_FEATURE_ENTRY(202306L, __cpp_lib_bind_front) COMPILER_FEATURE_ENTRY(202306L, __cpp_lib_bitset) COMPILER_FEATURE_ENTRY(202306L, __cpp_lib_chrono) COMPILER_FEATURE_ENTRY(202306L, __cpp_lib_constexpr_algorithms) COMPILER_FEATURE_ENTRY(202306L, __cpp_lib_constexpr_cmath) COMPILER_FEATURE_ENTRY(202306L, __cpp_lib_constexpr_complex) COMPILER_FEATURE_ENTRY(202306L, __cpp_lib_copyable_function) COMPILER_FEATURE_ENTRY(202306L, __cpp_lib_format) COMPILER_FEATURE_ENTRY(202306L, __cpp_lib_freestanding_char_traits) COMPILER_FEATURE_ENTRY(202306L, __cpp_lib_freestanding_charconv) COMPILER_FEATURE_ENTRY(202306L, __cpp_lib_freestanding_cstdlib) COMPILER_FEATURE_ENTRY(202306L, __cpp_lib_freestanding_cstring) COMPILER_FEATURE_ENTRY(202306L, __cpp_lib_freestanding_cwchar) COMPILER_FEATURE_ENTRY(202306L, __cpp_lib_freestanding_errc) COMPILER_FEATURE_ENTRY(202306L, __cpp_lib_freestanding_feature_test_macros) COMPILER_FEATURE_ENTRY(202306L, __cpp_lib_freestanding_functional) COMPILER_FEATURE_ENTRY(202306L, __cpp_lib_freestanding_iterator) COMPILER_FEATURE_ENTRY(202306L, __cpp_lib_freestanding_memory) COMPILER_FEATURE_ENTRY(202306L, __cpp_lib_freestanding_operator_new) COMPILER_FEATURE_ENTRY(202306L, __cpp_lib_freestanding_ranges) COMPILER_FEATURE_ENTRY(202306L, __cpp_lib_freestanding_ratio) COMPILER_FEATURE_ENTRY(202306L, __cpp_lib_freestanding_tuple) COMPILER_FEATURE_ENTRY(202306L, __cpp_lib_freestanding_utility) COMPILER_FEATURE_ENTRY(202306L, __cpp_lib_fstream_native_handle) COMPILER_FEATURE_ENTRY(202306L, __cpp_lib_function_ref) COMPILER_FEATURE_ENTRY(202306L, __cpp_lib_hazard_pointer) COMPILER_FEATURE_ENTRY(202306L, __cpp_lib_is_within_lifetime) COMPILER_FEATURE_ENTRY(202306L, __cpp_lib_not_fn) COMPILER_FEATURE_ENTRY(202306L, __cpp_lib_ratio) COMPILER_FEATURE_ENTRY(202306L, __cpp_lib_rcu) COMPILER_FEATURE_ENTRY(202306L, __cpp_lib_smart_ptr_owner_equality) COMPILER_FEATURE_ENTRY(202306L, __cpp_lib_sstream_from_string_view) COMPILER_FEATURE_ENTRY(202306L, __cpp_lib_submdspan) COMPILER_FEATURE_ENTRY(202306L, __cpp_lib_text_encoding) COMPILER_FEATURE_ENTRY(202306L, __cpp_lib_to_chars) COMPILER_FEATURE_ENTRY(202306L, __cpp_lib_to_string) COMPILER_FEATURE_ENTRY(202306L, __cpp_lib_variant) }; static constexpr CompilerFeature cxx29_core[] = { //< Продолжить заполнение COMPILER_FEATURE_ENTRY(202604L, __cpp_core_TODO) }; static constexpr CompilerFeature cxx29_lib[] = { //< Продолжить заполнение COMPILER_FEATURE_ENTRY(202604L, __cpp_lib_TODO) }; static constexpr CompilerFeature attributes[] = { COMPILER_ATTRIBUTE(202207L, assume) COMPILER_ATTRIBUTE(200809L, carries_dependency) COMPILER_ATTRIBUTE(201309L, deprecated) COMPILER_ATTRIBUTE(201603L, fallthrough) COMPILER_ATTRIBUTE(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("Макросы, специфичные для компилятора:\n"); for (auto co : compiler) if (std::strcmp(co.first, co.second)) std::printf("%*s %s\n", -print.longest_macro_name, co.first, co.second); } inline void print_compiler_feature(const CompilerFeature& x) { if (not ((print.supported_features and x.maybe()) or (print.unsupported_features and not x.maybe()))) return; auto print_year_month = [](long n) { return std::printf("%ld%s%02ld", n / 100, print.separate_year_month ? "-" : "", n % 100); }; std::printf("%*s ", -print.longest_macro_name, x.name()); x.maybe() ? print_year_month(x.data()) : std::printf("------%s", print.separate_year_month ? "-" : ""); if (print.standard_values) std::printf(" %c ", (x.supported() ? (x.data() > x.std() ? '>' : '=') : '<')), print_year_month(x.std()); std::puts(""); } template<class Container> inline void show(char const* const title, Container const& co) { if (print.titles) { std::printf("%-s (", title); if (print.counters) { std::printf("%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.cxx29 ? 29 : print.cxx26 ? 26 : print.cxx23 ? 23 : print.cxx20 ? 20 : print.cxx17 ? 17 : print.cxx14 ? 14 : print.cxx11 ? 11 : 98; }; std::vector<CompilerFeature> latest; auto add = [&latest](CompilerFeature x) { auto i = std::lower_bound(latest.begin(), latest.end(), x); if (i == latest.end() or not (*i == x)) latest.insert(i, x); else if (i->data() < x.data()) i->data(x.data()); }; char text[64]; latest.reserve(512); // макросы max if (print.core_features) { // сохранить обратный порядок вставки ревизии! if (print.cxx29) std::for_each(std::begin(cxx29_core), std::end(cxx29_core), add); if (print.cxx26) std::for_each(std::begin(cxx26_core), std::end(cxx26_core), add); if (print.cxx23) std::for_each(std::begin(cxx23_core), std::end(cxx23_core), add); if (print.cxx20) std::for_each(std::begin(cxx20_core), std::end(cxx20_core), add); if (print.cxx17) std::for_each(std::begin(cxx17_core), std::end(cxx17_core), add); if (print.cxx14) std::for_each(std::begin(cxx14_core), std::end(cxx14_core), add); if (print.cxx11) std::for_each(std::begin(cxx11_core), std::end(cxx11_core), add); if (print.cxx98) std::for_each(std::begin(cxx98_core), std::end(cxx98_core), add); std::snprintf(text, sizeof text, "ВСЕ МАКРОСЫ CORE ДО C++%02i", latest_rev()); show(text, latest); } latest.clear(); if (print.lib_features) { // сохранить обратный порядок вставки ревизии! if (print.cxx29) std::for_each(std::begin(cxx29_lib), std::end(cxx29_lib), add); if (print.cxx26) std::for_each(std::begin(cxx26_lib), std::end(cxx26_lib), add); if (print.cxx23) std::for_each(std::begin(cxx23_lib), std::end(cxx23_lib), add); if (print.cxx20) std::for_each(std::begin(cxx20_lib), std::end(cxx20_lib), add); if (print.cxx17) std::for_each(std::begin(cxx17_lib), std::end(cxx17_lib), add); if (print.cxx14) std::for_each(std::begin(cxx14_lib), std::end(cxx14_lib), add); std::snprintf(text, sizeof text, "ВСЕ МАКРОСЫ LIB ДО C++%02i", latest_rev()); show(text, latest); } } int main() { if (print.separated_revisions) { if (print.cxx98 and print.core_features) show("C++98 CORE", cxx98_core); if (print.cxx11 and print.core_features) show("C++11 CORE", cxx11_core); if (print.cxx14 and print.core_features) show("C++14 CORE", cxx14_core); if (print.cxx14 and print.lib_features ) show("C++14 LIB" , cxx14_lib); if (print.cxx17 and print.core_features) show("C++17 CORE", cxx17_core); if (print.cxx17 and print.lib_features ) show("C++17 LIB" , cxx17_lib); if (print.cxx20 and print.core_features) show("C++20 CORE", cxx20_core); if (print.cxx20 and print.lib_features ) show("C++20 LIB" , cxx20_lib); if (print.cxx23 and print.core_features) show("C++23 CORE", cxx23_core); if (print.cxx23 and print.lib_features ) show("C++23 LIB" , cxx23_lib); if (print.cxx26 and print.core_features) show("C++26 CORE", cxx26_core); if (print.cxx26 and print.lib_features ) show("C++26 LIB" , cxx26_lib); if (print.cxx29 and print.core_features) show("C++29 CORE", cxx29_core); if (print.cxx29 and print.lib_features ) show("C++29 LIB" , cxx29_lib); } if (print.latest_revisions) show_latest(); if (print.attributes) show("АТРИБУТЫ", attributes); if (print.compiler_specific) show_compiler_specific_info(); }
Возможный вывод:
C++11 CORE (20/20) __cpp_alias_templates 2007-04 = 2007-04 __cpp_attributes 2008-09 = 2008-09 __cpp_constexpr 2021-10 > 2007-04 __cpp_constexpr_in_decltype 2017-11 = 2017-11 ... усечено ... 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 ... усечено ... 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 ... усечено ... 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 ... усечено ... C++17 LIB (49/49) __cpp_lib_addressof_constexpr 2016-03 = 2016-03 __cpp_lib_allocator_traits_is_always_equal 2014-11 = 2014-11 ... усечено ... 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 ... усечено ... 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 ... усечено ... C++23 CORE (2/11) __cpp_char8_t 2018-11 < 2022-07 __cpp_consteval 2018-11 < 2022-11 ... усечено ... C++23 LIB (16/64) __cpp_lib_adaptor_iterator_pair_constructor 2021-06 = 2021-06 __cpp_lib_algorithm_iterator_requirements ------- < 2022-07 __cpp_lib_allocate_at_least ------- < 2023-02 __cpp_lib_associative_heterogeneous_erasure ------- < 2021-10 __cpp_lib_barrier 2019-07 < 2023-02 ... усечено ... ВСЕ МАКРОСЫ CORE ДО 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_templates 2007-04 = 2007-04 ... усечено ... ВСЕ МАКРОСЫ LIB ДО 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_requirements ------- < 2022-07 __cpp_lib_allocate_at_least ------- < 2023-02 __cpp_lib_allocator_traits_is_always_equal 2014-11 = 2014-11 ... усечено ... АТРИБУТЫ (8/10) assume ------- < 2022-07 carries_dependency ------- < 2008-09 deprecated 2013-09 = 2013-09 fallthrough 2016-03 = 2016-03 ... усечено ... Compiler specific macros: __cplusplus 202100L __GNUG__ 12 __GNUC_MINOR__ 2 __GNUC_PATCHLEVEL__ 1
[править] Отчёты о дефектах
Следующие изменения поведения были применены с обратной силой к ранее опубликованным стандартам C++:
Номер | Применён | Поведение в стандарте | Корректное поведение |
---|---|---|---|
WG не указан | C++20 | для стандартных атрибутов __has_cpp_attribute должен расширяться до ненулевого значения |
может расширяться до 0 |
[править] Смотрите также
Макросы тестирования функциональности библиотеки (C++20) | определено в заголовке <version> |
Документация C++ по Предопределенные символы макросов
| |
Документация C++ по Индекс макросимволов
|
[править] Внешние ссылки
1. | Официальный документ о рекомендациях по тестированию функциональности |
2. | Исходный код для дампа функциональности компилятора |