Feature detection & migration

Feature-test macros, shims, standard-by-standard adoption.

The dark age: __cplusplus plus per-compiler macro matrices; every portable library carries a config header.

#if defined(_MSC_VER) && _MSC_VER < 1900
#  define MYLIB_NO_CONSTEXPR
#endif

No relief yet; SD-6 feature-test macro recommendations circulate but are not required.

__has_include enables header-level probing — the first standard detection tool.

#if __has_include(<optional>)
#  include <optional>
#endif

<version> lands with ~200 __cpp_lib_* / __cpp_* macros: feature detection becomes per-feature, not per-compiler-version — the idiomatic shim pattern ever since.

#include <version>
#ifdef __cpp_lib_format
#  include <format>
#  define FMT(...) std::format(__VA_ARGS__)
#else
#  define FMT(...) fmt::format(__VA_ARGS__)
#endif

Detection of language features in constant evaluation gets cleaner with if consteval; migration guides increasingly phrase support as paper numbers + macros (the cppstat view of the world).

Contracts and hardening introduce build-mode axes (ignore/observe/enforce) alongside standard version — migration planning becomes two-dimensional: language level and enforcement level.

C++29direction · not adopted

Direction: profiles (P3081 line) would make opt-in rulesets a third detection axis if adopted.

C++26 per the final working draft; C++29 rows are proposals and direction, not adopted features.