Feature detection. More...
#include <UGMISC_PREDEFS_HEADER>#include <version>Go to the source code of this file.
Classes | |
| struct | ugmisc::Features |
Macros | |
| #define | UGMISC_PREDEFS_HEADER "quoted_header_name" |
| #define | UGMISC_HAVE_VERSION |
| #define | UGMISC_HAS_INCLUDE_OR_IGNORE(...) |
| #define | UGMISC_HAVE_CONSTEXPR_DESTRUCTORS |
| #define | UGMISC_NO_CONSTEXPR_DESTRUCTORS |
| #define | UGMISC_HAVE_CONSTEVAL |
| #define | UGMISC_HAVE_CONSTEVAL_IF |
| Defined if consteval if is supported. | |
| #define | UGMISC_HAVE_BIT_CAST |
| #define | UGMISC_HAVE_BITOPS |
| #define | UGMISC_HAVE_CONSTEXPR_SWAP_ALGORITHMS |
| #define | UGMISC_HAVE_UNREACHABLE |
| #define | UGMISC_unreachable ::ugmisc::unreachable |
Functions | |
| void | unreachable () |
Feature detection.
Feature detection is mostly just standard feature detection, but there are some things we would find ourselves doing again to make it work if it wasn't all in one place, so here it is. Plus this way features, in addition to being macros, are also static constexpr members of a Features class, use of which is sometimes more convenient than a preprocessor directive.
We don't try to be fancy here. C++17 and later are supported. It is assumed that all C++17 language and library features work. Everything else depends on feature test macros provided by compiler and the version header.
You can still include <version> if __has_include doesn't work, by predefining UGMISC_HAVE_VERSION.
Some of the features don't have proper feature test macros. For these we guess based on the C++ standard version number.
But it is possible to predefine a macro for each of those features. This allows a build system to run a feature test during setup. Either define all of the required macros on the compiler command line, or define them in a header and define UGMISC_PREDEFS_HEADER to cause them to be included.
Or of course you could not define UGMISC_PREDEFS_HEADER and always include the predefs header yourself before including ugmisc/features.hpp.
Don't forget the double quotes or angle brackets!
The following macros are respected by features.hpp if they are predefined.
Some of the features are not so much detected as guessed. These features may be detected by a build system at build configuration time. A couple of examples of how to do this using Meson follow.
Copy the feature_tests/meson.build script, and it will define some useful variables:
If a target uses the ugmisc_config_header_dep dependency, it gets:
If using ugmisc as a Meson subproject, you can do this:
ugmisc_dep = dependency('ugmisc', allow_fallback: true)
Using the ugmisc_dep dependency adds UgMisc's header include path to a build target.
Or you can do this:
ugmisc_subproject = subproject('ugmisc')
ugmisc_dep = ugmisc_subproject.get_variable('ugmisc_dep')
ugmisc_with_config_header_dep = ugmisc_subproject.get_variable('ugmisc_with_config_header_dep')
Using the ugmisc_with_config_header_dep dependency adds the header include path, and the include path of the generated configuration header, and adds the macro definition that tells ugmisc/features.hpp to include the configuration header, and adds the configuration header as a prerequisite.
You could also do it this way:
ugmisc_with_config_header_dep = dependency('ugmisc-with-feature-tests', allow_fallback: true)
This will always fall back to using the subproject, because UgMisc will not install anything called ugmisc-with-feature-tests. It would not make sense for it to do so; that would be installing a generated header which is generated differently depending on the compiler and the options passed to the compiler.
| #define UGMISC_HAVE_BIT_CAST |
Defined if std::bit_cast is supported.
| #define UGMISC_HAVE_BITOPS |
Defined if <bit> is supported.
| #define UGMISC_HAVE_CONSTEVAL |
Defined if consteval keyword supported.
| #define UGMISC_HAVE_CONSTEVAL_IF |
Defined if consteval if is supported.
| #define UGMISC_HAVE_CONSTEXPR_DESTRUCTORS |
Defined if constexpr desctuctors are supported. Detection is based on the C++ standard version number only, unless
If UGMISC_HAVE_CONSTEXPR_DESTRUCTORS or UGMISC_NO_CONSTEXPR_DESTRUCTORS is predefined, that will override features.hpp's detection of this feature. A build script may define one of these macros in response to a compiler test.
| #define UGMISC_HAVE_CONSTEXPR_SWAP_ALGORITHMS |
Defined if std::swap, std::exchange etc are constexpr.
| #define UGMISC_HAVE_UNREACHABLE |
Defined if std::unreachable() exists.
| #define UGMISC_HAVE_VERSION |
This macro is not defined by features.hpp. If it is predefined before including features.hpp, or it is defined in the header identified by UGMISC_PREDEFS_HEADER, then <version> will be included.
Otherwise, if __has_include is defined, that will be used to determine whether to include <version>.
| #define UGMISC_NO_CONSTEXPR_DESTRUCTORS |
This macro is never defined by features.hpp. If it is predefined before including features.hpp, or defined in the header indicated by UGMISC_PREDEFS_HEADER, it overrides the crude detection performed by features.hpp.
| #define UGMISC_PREDEFS_HEADER "quoted_header_name" |
This is not defined by features.hpp. If it is defined when features.hpp is included, features.hpp will include the header named by the macro like this:
Consequently, the header must expand to a name in quotes or angle brackets.