Макросы проверки возможностей (начиная с 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 |
std::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 | 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 |
Изменение типа возврата std::list::remove, std::list::remove_if и std::list::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 | 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 |
Проверка префикса и суффикса строки (std::string_view::starts_with и std::string_view::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. | Исходный код для дампа функциональности компилятора |