{"id":13646056,"url":"https://github.com/foonathan/compatibility","last_synced_at":"2025-04-21T17:31:50.094Z","repository":{"id":74810155,"uuid":"40319034","full_name":"foonathan/compatibility","owner":"foonathan","description":"unmaintained - CMake module to activate certain C++ standard, feature checks and appropriate automated workarounds - basically an improved version of cmake-compile-features","archived":true,"fork":false,"pushed_at":"2017-02-21T09:49:16.000Z","size":176,"stargazers_count":74,"open_issues_count":1,"forks_count":14,"subscribers_count":11,"default_branch":"master","last_synced_at":"2024-11-09T19:41:17.616Z","etag":null,"topics":["cmake","feature-checks"],"latest_commit_sha":null,"homepage":"","language":"CMake","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"zlib","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/foonathan.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2015-08-06T17:51:46.000Z","updated_at":"2023-01-28T19:03:02.000Z","dependencies_parsed_at":null,"dependency_job_id":"8f2b013f-7bf0-4bc9-a599-85e837806c9f","html_url":"https://github.com/foonathan/compatibility","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/foonathan%2Fcompatibility","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/foonathan%2Fcompatibility/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/foonathan%2Fcompatibility/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/foonathan%2Fcompatibility/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/foonathan","download_url":"https://codeload.github.com/foonathan/compatibility/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250100540,"owners_count":21374962,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cmake","feature-checks"],"created_at":"2024-08-02T01:02:47.608Z","updated_at":"2025-04-21T17:31:49.680Z","avatar_url":"https://github.com/foonathan.png","language":"CMake","readme":"# Compatibility\n\n[![Build Status](https://travis-ci.org/foonathan/compatibility.svg?branch=master)](https://travis-ci.org/foonathan/compatibility)\n\nThis library provides an advanced `target_compile_features()` and `write_compiler_detection_header()`.\nThe problem with those is that they are controlled via a CMake internal database, which has to be kept manually up-to-date.\nThis version uses `check_cxx_source_compiles()` instead and is such automatically up-to-date - a compiler supports a feature,\nif the test code compiles.\n\nBased on the test results, a header file is generated that stores the result and often workaround code,\nfor example a `CONSTEXPR` macro that is `constexpr`, if supported, and `const` otherwise,\nto use the features anyway.\n\nIt also provides the automatic standard deduction from `target_compile_features()` to activate the right standard.\n\n## Example\n\nIf you only want the C++ standard activation, simply `include()` `comp_base.cmake` and replace `target_compile_features()` by `comp_compile_features()`.\n\nThis is a `CMakeLists.txt` for a more advanced usage:\n```\n# suppose we have a target 'tgt'\ninclude(your/dir/to/comp_base.cmake) # only file you need to download, rest is taken as needed\n\n# we want constexpr, noexcept, std::max_align_t and rtti_support\n# instead of cpp11_lang/constexpr and cpp11_lang/noexcept, you could also write cxx_constexpr/cxx_noexcept\ncomp_target_features(tgt PUBLIC cpp11_lang/constexpr cpp11_lang/noexcept cpp11_lib/max_align_t env/rtti_support)\n```\n\nFor convenience we include all generated files in a header named `config.hpp`.\nThe filenames are made available through macros.\n\n```cpp\n#ifndef CONFIG_HPP\n#define CONFIG_HPP\n\n#include COMP_CONSTEXPR_HEADER\n#include COMP_NOEXCEPT_HEADER\n#include COMP_MAX_ALIGN_T_HEADER\n#include COMP_RTTI_SUPPORT_HEADER\n\n#endif\n```\n\nAnd then we can use it just by including `config.hpp` in our code:\n\n```cpp\n#include \"config.hpp\"\n\n// use a workaround macro\nCOMP_CONSTEXPR int i = 0;\n\nvoid func() COMP_NOEXCEPT\n{\n    // use a workaround typedef\n    comp::max_align_t foo;\n\n    // or conditional compilation\n#if COMP_HAS_RTTI_SUPPORT\n    do_sth();\n#endif\n}\n```\n\nIf you don't care about the workarounds, but just want a specific standard, simply call:\n```\ncomp_target_features(tgt PUBLIC CPP11) # or CPP14 or CPP17\n```\nThis will only activate C++11/14/17 without doing anything else.\n\n*Note: The standard activation is always `PRIVATE` to allow users of a library to have a different (higher) standard than the library.*\n\n## Usage\n\nThe only file needed is `comp_base.cmake`.\nYou can either manually download it, use CMakes `file(DOWNLOAD` facility,\nor use git submodules.\nThe branch `git-submodule` only contains `comp_base.cmake` and is thus perfect for this purpose.\nRun `git submodule add -b \"git-submodule\" https://github.com/foonathan/compatibility.git` to initialize it and fetch the file.\nThen you only need to run `git submodule update --remote` to update it to the newest version.\n\n`include()` it in your `CMakeLists.txt` now.\nFirst it generates CMake options - `COMP_CPP11_FLAG`, `COMP_CPP14_FLAG` and `COMP_CPP17_FLAG` - storing the calculated compiler flag for a given standard,\nuseful if you want to override it, if it can't find one for your compiler.\nIt also provides the following function:\n\n    comp_target_features(\u003ctarget\u003e \u003cPRIVATE|PUBLIC|INTERFACE\u003e \u003cfeatures...\u003e\n                         [NOPREFIX | PREFIX \u003cprefix] [NAMESPACE \u003cnamespace\u003e]\n                         [CMAKE_PATH \u003cpath\u003e] [INCLUDE_PATH \u003cinclude_path\u003e]\n                         [NOFLAGS | CPP11 | CPP14 | CPP17] \n                         [LOG \u003cDEBUG | INFO | QUIET | SILENT | ALL\u003e]\n                         [NO_HEADER_MACROS] [SINGLE_HEADER \u003cname\u003e])\n\nIgnoring all the other options, it is like `target_compile_features()`.\nIt takes a list of features to activate for a certain target.\nA features is a file in this repository without the `.cmake` extension, e.g. `cpp11_lang` for all C++11 language features,\nor `cpp14_lang/deprecated` for the C++14 deprecated features.\n\nA feature file with name `dir/xxx.cmake` belonging to a feature `dir/xxx` consists of the following,\nwhere `dir` is the category of the feature, `xxx` the feature name in lowercase, `XXX` the feature name in upper case `\u003cPREFIX\u003e` the prefix as given to the function, `\u003cprefix\u003e` the prefix in lowercase and without a trailing underscore:\n\n* a test testing whether or not the compiler supports this feature\n\n* a CMake option with name `COMP_HAS_XXX` to override its result, useful if you want to act like it doesn't support a feature,\nor if the test is poorly written (please contact me in this case!)\n\n* a header named `\u003cprefix\u003e/xxx.hpp`.\nThe header contains at least a macro `\u003cPREFIX\u003eHAS_XXX` with the same value as the CMake option\nand often workaround macros or functions that can be used instead of the feature.\nThe workaround uses either the feature, if it is available, or own code.\nThis allows using many new features already, without support.\nIf the compiler gets support, you will be automatically using the native feature or the standard library implementation.\n\n* a globally available macro named `\u003cPREFIX\u003e_XXX_HEADER` to include the header file.\n\nTo use the generated header files, simply write `#include \u003cPREFIX\u003e_XXX_HEADER` inside your code, the macro is made available automatically (you could also `#incluce` the file directly but this is not recommended).\n\nWhat `comp_target_features` function actually does is the following:\n\n* For each feature, it downloads the latest version of the test file from Github, if it doesn't exist yet.\nThe remote url can be set via the option `COMP_REMOTE_URL`.\n\n* For each feature, it calls `include(feature.cmake)` after some set up. This runs the test and generates the header file.\n\n* It calls `target_include_directories` to allow including the generated header files\nand `target_compile_definitions` for the file macro.\nThe `INTERFACE/PUBLIC/PRIVATE` specifier are only used in these calls.\n\n* Activates the right C++ standard. E.g., if a feature requires C++11, it will be activated if it is available. If it is not, it will only activate the C++ standard required by the workaround code. This activation is always `PRIVATE`. The flag is exposed through the CACHE variable `${target}_COMP_COMPILE_OPTIONS`.\n\nThe behavior can be customized with the other options:\n\n* `NOPREFIX`/`PREFIX`: The prefix of any generated macros or none if `NOPREFIX` is set. Default is `COMP_`.\n\n* `NAMESPACE`: The namespace name of any generated code, default is `comp`. A given prefix must always use the same namespace name!\n\n* `CMAKE_PATH`/`INCLUDE_PATH`: The download destination for the CMake files/the destination of the generated headers,\ndefault is `${CMAKE_BINARY_DIR}/comp.downloaded` for cmake and `${CMAKE_BINARY_DIR}/comp.generated` for the headers.\n`INCLUDE_PATH` is also given to `target_include_directories()`, but note that the generated headers are in a subfolder `\u003cprefix\u003e` (this cannot be changed).\n\n* `NOFLAGS`/`CPP11`/`CPP14`/`CPP17`: Override for the standard detection, if you want to have a newer standard than deduced from the features,\nor a lower (not recommended). They have priority over the deduction, C++17 over C++14 over C++11.\nSpecify `NOFLAGS` if you do not want to have any compiler flags set.\nThe latter is useful for `INTERFACE` libraries which are only there to run the tests and generate the options and headers.\n\n* `LOG`: Turn down or up the logging for features. There is no default value, but it is fairly verbose by default.\n  * Possible options: `DEBUG`, `INFO`, `QUIET`, `SILENT`, `ALL` \n  * Additionally, setting `COMP_LOG_LEVEL` at the global level behaves the same way, except any option passed here will *override* for the current run\n \n* `NO_HEADER_MACROS`: Disables the definition of the macros that contain the header file location.\n\n* `SINGLE_HEADER`: Generate a single header file with that name that will include all generated headers.\n\n## Feature Reference\n\nA feature named `dir/xxx` is tested in `xxx.cmake`, defines an override CMake option `COMP_HAS_XXX` and a macro `\u003cPREFIX\u003eHAS_XXX` in a file named `\u003cprefix\u003e/xxx.hpp` (where `prefix` is `\u003cPREFIX\u003e` in lowercase without a trailing underscore), filename also made available over the global macro `\u003cPREFIX\u003eXXX_HEADER`.\n\nThere are also alternative names for the CMake `target_compile_features()` and SD-6 Feature Test Recommondations that are automatically translated.\nWhere appropriate, it will also generate the SD-6 feature macro as specified.\nThis will override the existing value if the new one is greater or the macro `COMP_OVERRIDE_SD6` is defined.\nIf a feature is not supported, it will not change or define anything.\n\nFor some features, macros are generated that can be used instead (i.e. for `noexcept`), they have the form `\u003cPREFIX\u003eXXX`.\nThose macros often use compiler extensions.\nIf there is none (or a lacking implementation...), an error message will be emmitted.\nTo prevent this, simply define the macro as no-op or as you want prior to including the file.\n\nThere are often workaround functions for library features. Those are defined in a namespace and either use the own implementation or the standard library implementation, if it is available.\n\nPrefix and namespace name can be controlled via parameters, see above.\nA given prefix must always use the same namespace name on each call.\n\nThis library currently tests for the following features.\nThe code below assumes no prefix and a namespace name of `comp`.\n\n*A feature will only be included (by me) if it is not a pure syntactic feature (like `auto` or lambdas which can be avoided) but if there is either sensible workaround code, e.g. through to compiler extensions or through reimplementing (small!) standard library functionality, or there can be conditional compilation based on the existense, e.g. optional literal definitions or move constructors.\n\nNote that I'm open to PRs of any kind :)*\n\n### C++11 language features\n\nThese features are all in the subdirectory `cpp11_lang`.\n\nfeature name|alternative name|example|workaround, if any\n------------|----------------|-------|------------------\nalias_template|cxx_alias_templas|`template \u003ctypename T\u003e using my_map = std::map\u003cint, T\u003e;`|no workaround\nalignas|cxx_alignas|`alignas(int) char c`|`ALIGNAS(x)`, fallback to compiler extension, if available\nalignof|cxx_alignof|`alignof(int)`|`ALIGNOF(x)`, fallback to compiler extension, if available\nauto_type|cxx_auto_type|`auto var = 0`|no workaround\nconstexpr|cxx_constexpr|`constexpr int foo()`|`CONSTEXPR`, fallback to `const`; `CONSTEXPR_FNC`, fallback to `inline`\ndecltype|cxx_decltype|`decltype(a)`|`DECLTYPE(x)`, fallback to `typeof` extension, if available\ndefault_function_template_args|cxx_default_function_template_args|`template \u003ctypename T = int\u003e void foo();`| no workaround\ndelete_fnc|cxx_deleted_functions|`void foo() = delete;`|no workaround\nenum_class|cxx_strong_enum|`enum class foo {}`|no workaround\nexplicit_conversion_op|cxx_explicit_conversion|`explicit operator bool()`|no workaround\nfinal|cxx_final|`void bar() final;`|`FINAL` macro, workaround expands to nothing\ninline_namespace|none|`inline namespace foo {...}`|no workaround\nlambdas|cxx_lambdas|`[](){}`|no workaround\nliteral_op|cxx_user_literals|`operator\"\"`|no workaround\nnoexcept|cxx_noexcept|`void foo() noexcept;`|`NOEXCEPT`, fallback to nothing; `NOEXCEPT_IF(x)`, fallback to nothing; `NOEXCEPT_OP(x)`, fallback to `false`\nnoreturn|none|`[[noreturn]] void foo();`|`NORETURN`, fallback to compiler extension, if available\nnullptr|cxx_nullptr|`void* ptr = nullptr;`|`NULLPTR`, fallback to [null pointer idiom](https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/nullptr); also `comp::nullptr_t`\noverride|cxx_override|`void bar() override;`|`OVERRIDE`, fallback to nothing\nparameter_pack|cxx_parameter_pack|`template \u003ctypename ... T\u003e void f(T... ts);`|no workaround\nrange_for|cxx_range_for|`for (auto var : container)`|no workaround\nright_angle_brackets|cxx_right_angle_brackets|`std::vector\u003cstd::vector\u003cint\u003e\u003e`|no workaround\nrvalue_ref|cxx_rvalue_references|`int\u0026\u0026 a = 4;`|no workaround\nstatic_assert|cxx_static_assert|`static_assert(std::is_integral\u003cT\u003e::value, \"\");`|`STATIC_ASSERT(Expr, Msg)`, fallback to simple undefined struct technique\nthread_local|cxx_thread_local|`thread_local int i;`|`THREAD_LOCAL`, fallback to `__thread` extension or similar, if available - **does not call constructors or destructors!**\n\n*Note: In general, it assumes proper C++11 support. The workarounds defined in this library rely on all common C++ features that can not be easily avoided except those listed here with a proper fallback (like `noexcept`, `constexpr`, ...).*\n\nGet them all by specifying `cpp11_lang`.\n\n### C++11 library features\n\nThese features are all in the subdirectory `cpp11_lib`.\n\nfeature name|example|workaround, if any\n------------|-------|------------------\nget_new_handler|`std::get_new_handler()`|`comp::get_new_handler()`, fallback to old `std::set_new_handler(nullptr)` technique - **not thread safe**\nget_terminate|`std::get_terminate()`|`comp::get_terminate()`, same as above\nis_trivially|`std::is_trivially_XXX\u003cT\u003e`|`comp::is_trivially_XXX`, workaround uses `std::is_XXX` combined with `std::is_trivial`\nmax_align_t|`std::max_align_t`|`comp::max_align_t`, fallback to `::max_align_t` or a struct with a `long double` and `long long`\nmutex|`std::mutex`/`std::lock_guard`/`std::unique_lock`|no workaround\nto_string|`std::to_string(54)`|`comp::to_string()`, fallback to `std::sprintf()`\n\n*Note: It only checks for minor features where an easy workaround implementation is feasible in the scope of this library.*\n\nGet them all by specifying `cpp11_lib`.\n\n### C++14 language features \\[complete\\]\n\nThese features are all in the subdirectory `cpp14_lang`.\n\npaper|feature name|alternative name|example|workaround, if any\n-----|------------|----------------|-------|------------------\n[N3760](http://www.open-std.org/JTC1/sc22/WG21/docs/papers/2013/n3760.html)|deprecated|cxx_attribute_deprecated|`[[deprecated]] int foo();`|`DEPRECATED` and `DEPRECATED(Msg)`, fallback to compiler attribute, if available\n[N3652](http://www.open-std.org/JTC1/sc22/WG21/docs/papers/2013/n3652.html)|general_constexpr|cxx_relaxed_constexpr|generalized constexpr|no workaround\n[N3638](http://www.open-std.org/JTC1/sc22/WG21/docs/papers/2013/n3638.html)|return_type_deduction|none|auto return type deduction for normal functions|`AUTO_RETURN` macro\n[N3778](http://www.open-std.org/JTC1/sc22/WG21/docs/papers/2013/n3778.html)|sized_deallocation|none|`void operator delete(void *ptr, std::size_t size)`|no workaround\n[N3651](http://www.open-std.org/JTC1/sc22/WG21/docs/papers/2013/n3651.html)|variable_template|cxx_variable_templates|`template \u003ctypename T\u003e T pi;`|no workaround\n\nGet them all by specifying `cpp14_lang`.\n\nThe following features are not and will never be supported:\n\npaper|description|reason\n-----|-----------|------\n[N3323](http://www.open-std.org/JTC1/sc22/WG21/docs/papers/2012/n3323.pdf)|Tweak Certain C++ Contextual Conversions|difficult to check, avoid relying on behavior\n[N3472](http://www.open-std.org/JTC1/sc22/WG21/docs/papers/2012/n3472.pdf)|Binary Literals|syntax sugar only\n[N3648](http://www.open-std.org/JTC1/sc22/WG21/docs/papers/2013/n3648.html)|Generalized Lambda Capture|lambdas are syntax sugar only\n[N3649](http://www.open-std.org/JTC1/sc22/WG21/docs/papers/2013/n3649.html)|Generic Lambdas|lambdas are syntax sugar only\n[N3653](http://www.open-std.org/JTC1/sc22/WG21/docs/papers/2013/n3653.html)|Member initializers and aggregates|difficult to check, no big user impact\n[N3664](http://www.open-std.org/JTC1/sc22/WG21/docs/papers/2013/n3664.html)|Clarifying Memory Allocation|wording change only\n[N3781](http://www.open-std.org/JTC1/sc22/WG21/docs/papers/2013/n3781.pdf)|Digit seperator for literals|syntax sugar only\n\n### C++14 library features \\[complete\\]\n\nThese features are all in the subdirectory `cpp14_lib`.\n\npaper|feature name|example|workaround, if any\n--------|------------|-------|------------------\n[N3668](http://www.open-std.org/JTC1/sc22/WG21/docs/papers/2013/n3668.htm)|exchange|`std::exchange()`|`comp::exchange()`, own implementation\n[N3421](http://www.open-std.org/JTC1/sc22/WG21/docs/papers/2012/n3421.html)|generic_operator_functors|`std::greater\u003c\u003e{}`|`comp::greater{}` and the rest, no class templates!\n[N3658](http://www.open-std.org/JTC1/sc22/WG21/docs/papers/2013/n3658.html)|integer_sequence|`std::index_sequence\u003c4\u003e`|`comp::index_sequence\u003c4\u003e` and co, own implementation\n[N3656](http://www.open-std.org/JTC1/sc22/WG21/docs/papers/2013/n3656.htm)|make_unique|`std::make_unique()`|`comp::make_unique`, own implementation\n[N3654](http://www.open-std.org/JTC1/sc22/WG21/docs/papers/2013/n3654.html)|quoted|`ss \u003e\u003e std::quoted(str)`|no workaround, use boost\n[N3659](http://www.open-std.org/JTC1/sc22/WG21/docs/papers/2013/n3659.html)|shared_lock|`std::shared_lock\u003cstd::shared_timed_mutex\u003e`|no workaround\n[N3671](http://www.open-std.org/JTC1/sc22/WG21/docs/papers/2013/n3671.html)|two_range_algorithm|`std::equal(first1, last1, first2, last2)`|`comp::equal()`/`comp::mismatch()`/`comp::is_permutation()`, own implementation\n\nGet them all by specifying `cpp14_lib`.\n\nThe following features are not and will never be supported:\n\npaper|description|reason\n-----|-----------|------\n[N3668](http://www.open-std.org/JTC1/sc22/WG21/docs/papers/2013/n3669.pdf)|Fixing constexpr member functions without const|workaround not possible, just avoid relying on that behavior\n[N3670](http://www.open-std.org/JTC1/sc22/WG21/docs/papers/2013/n3670.htm)|Addressing Tuples by Type|just use index version\n[N3462](http://www.open-std.org/JTC1/sc22/WG21/docs/papers/2012/n3462.html)|std::result_of and SFINAE|impossible to check\n[N3545](http://www.open-std.org/JTC1/sc22/WG21/docs/papers/2013/n3545.html)|operator() for std::integral_constant|just \"syntax\" sugar\n[N3642](http://www.open-std.org/JTC1/sc22/WG21/docs/papers/2013/n3642.pdf)|UDl's for standard library|just \"syntax\" sugar\n[N3469](http://www.open-std.org/JTC1/sc22/WG21/docs/papers/2012/n3469.html)|Constexpr for std::chrono|no great workaround possible\n[N3470](http://www.open-std.org/JTC1/sc22/WG21/docs/papers/2012/n3470.html)|Constexpr for std::array|no great workaround possible\n[N3471](http://www.open-std.org/JTC1/sc22/WG21/docs/papers/2012/n3471.html)|Constexpr for utilities|no great workaround possible\n[N3657](http://www.open-std.org/JTC1/sc22/WG21/docs/papers/2013/n3657.html)|Heterogeneous lookup|optimization only, workaround for transparent functors supports this extension\n[N3655](http://www.open-std.org/JTC1/sc22/WG21/docs/papers/2013/n3655.pdf)|Alias templates for traits|just \"syntax\" sugar\n\n### C++17 language features\n\nThese features are all in the subdirectory `cpp17_lang`.\n\npaper|feature name|example|workaround, if any\n-----|------------|-------|------------------\n[N4295](http://www.open-std.org/JTC1/sc22/WG21/docs/papers/2014/n4295.html)|fold_expressions|`return (args \u0026\u0026 ....);`|no workaround\n[N3928](http://www.open-std.org/JTC1/sc22/WG21/docs/papers/2014/n3928.pdf)|terse_static_assert|`static_assert(condition);`|`TERSE_STATIC_ASSERT(Cond)` macro\n[N4267](http://www.open-std.org/JTC1/sc22/WG21/docs/papers/2014/n4267.html)|utf8_char_literal|`char c = u8'A';`|`UTF8_ChAR_LITERAL(Str)` macro taking a normal string, appending `u8` prefix and converting it to a character\n\n### C++17 library features \\[up-to-date\\]\n\nThese features are all in the subdirectory `cpp17_lib`.\n\npaper|feature name|example|workaround, if any\n-----|------------|-------|------------------\n[N4389](http://www.open-std.org/JTC1/sc22/WG21/docs/papers/2015/n4389.html)|bool_constant|`std::bool_constant`|`comp::bool_constant`\n[N4280](http://www.open-std.org/JTC1/sc22/WG21/docs/papers/2014/n4280.pdf)|container_access|`std::size(cont)`|`comp::size(cont)`, likewise for `std::empty()`/`std::data()`\n[N4169](http://www.open-std.org/JTC1/sc22/WG21/docs/papers/2014/n4169.html)|invoke|`std::invoke(f)`|`comp::invoke(f)`\n[N4279](http://www.open-std.org/JTC1/sc22/WG21/docs/papers/2014/n4279.html)|map_insertion|`m.try_emplace(key, value)`|`comp::try_emplace(m, key, value)`, likewise for `insert_or_assign()`\n[N4508](http://www.open-std.org/JTC1/sc22/WG21/docs/papers/2015/n4508.html)|shared_mutex|`std::shared_mutex`|no workaround\n[N4259](http://www.open-std.org/JTC1/sc22/WG21/docs/papers/2014/n4259.pdf)|uncaught_exceptions|`std::uncaught_exceptions()`|no workaround, note the plural!\n[N3911](http://www.open-std.org/JTC1/sc22/WG21/docs/papers/2014/n3911.pdf)|void_t|`std::void_t\u003cint, char\u003e`|`comp::void_t\u003cint, char\u003e`\n\nGet them all by specifying `cpp17_lib`.\n\nThe following features are not and will never be supported:\n\npaper|description|reason\n-----|-----------|------\n[N4190](http://www.open-std.org/JTC1/sc22/WG21/docs/papers/2014/n34190.htm)|Removing deprecated things|removal, just don't use it\n[N4284](http://www.open-std.org/JTC1/sc22/WG21/docs/papers/2014/n4284)|Contiguous iterator|no actual code change\n[N4089](http://www.open-std.org/JTC1/sc22/WG21/docs/papers/2014/n4089.pdf)|Conversion for `std::unique_ptr\u003cT[]\u003e`|difficult to check, avoid relying on behavior\n[N4277](http://www.open-std.org/JTC1/sc22/WG21/docs/papers/2014/n4277.html)|TriviallyCopyable `std::reference_wrapper`|difficult to check, avoid relying on behavior\n[N4258](http://www.open-std.org/JTC1/sc22/WG21/docs/papers/2014/n4258.pdf)|Cleaning-up `noexcept`|difficult to check, no big impact on user\n[N4266](http://www.open-std.org/JTC1/sc22/WG21/docs/papers/2015/n4266.html)|Missing SFINAE rule in `std::unique_ptr`|difficult to check, no big impact on code, avoid relying on behavior\n[N4387](http://www.open-std.org/JTC1/sc22/WG21/docs/papers/2015/n4387.html)|Improving constructor `std::pair` and `std::tuple`|difficult to check, avoid relying on behavior\n[N4510](http://www.open-std.org/JTC1/sc22/WG21/docs/papers/2015/n4510.html)|Minimal incomplete type support for containers|difficult to check, avoid relying on behavior\n\n### Technical specifications\n\nThe technical specifications for the C++ standard library.\nThese features are all in the subdirectory `ts`.\n\npaper|feature name|description|workaround, if any\n-----|------------|-----------|------------------\n[N3804](http://www.open-std.org/JTC1/sc22/WG21/docs/papers/2013/n3804.html)|any|`std::experimental::any` class|none, use boost or other implementation\n[N3915](http://www.open-std.org/JTC1/sc22/WG21/docs/papers/2014/n3915.pdf)|apply|`std::experimental::apply(f, tuple)`|`comp::apply()`, own implementation\n[N4273](http://www.open-std.org/JTC1/sc22/WG21/docs/papers/2014/n4273.htm)|container_erausre|`std::experimental::erase_if(vector, pred)`|`comp::erase_if()`/`comp::erase()`, own implementation\n[P0013R1](http://www.open-std.org/JTC1/sc22/WG21/docs/papers/2015/p0013r1.html)|logical_operator_traits|`std::experimental::disjunction`|`comp::conjunction`/`comp::disjunction`/`comp::negation`, own implementation\n[N4391](http://www.open-std.org/JTC1/sc22/WG21/docs/papers/2015/n4391.html)|make_array|`std::experimental::make_array()`|`comp::make_array()`/`comp::to_array()`, own implementation\n[N4076](http://www.open-std.org/JTC1/sc22/WG21/docs/papers/2014/n4076.html)|not_fn|`std::experimental::not_fn()`|`comp::not_fn()`, own implementation\n[N3793](http://www.open-std.org/JTC1/sc22/WG21/docs/papers/2013/n3793.html)|optional|`std::experimental::optional`|none, use boost or other implementation\n[N3916](http://www.open-std.org/JTC1/sc22/WG21/docs/papers/2014/n3916.pdf)|pmr|Polymorphic memory resource|only `comp::memory_resource` base class\n[N3921](http://www.open-std.org/JTC1/sc22/WG21/docs/papers/2014/n3921.html)|string_view|`std::experimental::string_view`| none, use other implementation\n\nGet them all by specifying `ts`.\n\n### Environment\n\nFeatures regarding the general environment. These features are all in the subdirectory `env`.\nNote: These checks here aren't that great, it is recommended to set option explicitly.\n\nfeature name|description|workaround, if any\n------------|-------|------------------\nexception_support|support for exception handling|`THROW(Ex)`, `RETHROW_EX`, fallback to `std::abort()`; `TRY`, fallback to `if (true)`, CATCH_ALL, fallback to `if (false)`\nhosted_implementation|freestanding vs hosted|alias macro `HOSTED_IMPLEMENTATION`, implementation of `std::swap()` and `std::move()`/`std::forward()` (if rvalue references are supported); those are otherwise not available\nrtti_support|support for RTTI|`comp::polymorhpic_cast`, fallback to `static_cast`\nthreading_support|support for threading|no workaround\n\nGet them all by specifying `env`.\n\n### Common extensions\n\nThese features are all in the subdirectory `ext`.\n\nfeature name|example|workaround, if any\n------------|-------|------------------\nassume|`__assume(cond)` (from MSVC)|`ASSUME(x)`, fallback to nothing\nbswap|`__builtin_bswap(x)` (from GCC)|``comp::bswap(x)` (for unsigned fixed-sized integers), fallback to manual swap (constexpr)\nclz|`__builtin_clz(x)` (from GCC)|`comp::clz(x)` (for unsigned fixed-sized integers), fallback to binary search (constexpr)\ncounter|`__COUNTER__` (most compilers)|no workaround\nctz|`__builtin_ctz(x)` (from GCC)|`comp::ctz(x)` (for unsigned integers), fallback to binary search (constexpr)\nexpect|`__builtin_expect(x, val)` (from GCC)|`EXPECT(x, val)` (and `LIKELY(cond)`,`UNLIKELY(cond)`), fallback to value itself\nextension|`__extension__` (from GCC, marks extensions to silence warnings)|`EXTENSION`, fallback to nothing\nfallthrough|`[[clang::fallthrough]]` (from clang)|`FALLTHROUGH`, fallback to nothing\nhas_include|`__has_include(header)`|`HAS_INCLUDE(x)`, fallback to always `0`\nint128|`__int128` (from GCC)|`comp::(u)int128_t`, no workaround, just convenience typedefs\npopcount|`__builtin_popcount(x)` (from GCC)|`comp::popcount(x)` (for unsigned integers), fallback to bithacks (constexpr)\npretty_function|`__PRETTY_FUNCTION__` (from GCC)|`PRETTY_FUNCTION`, fallback to `__FUNCSIG__` on MSVC\nunreachable|`__builtin_unreachable()` (from GCC)|`UNREACHABLE`, fallback to `__assume(0)` under MSVC, otherwise nothing\nunused|`[[gnu::unused]]` (from GCC)|`UNUSED`, fallback to nothing; also `MAKE_UNUSED(expr)` that uses `(void)` trick\n\nGet them all by specifying `ext.cmake`.\n\n## Contribution\n\nAs you probably noted, there are features missing.\nI wrote this library in a few hours and concentrated on the most important features for me.\nIf you want to extend it or improve a workaround, please don't hesitate to fork and PR\n(or just write an issue and let me take care of it, when I have time, if you're lazy).\n\nTo write a new feature check, just create a new file in the appropriate subdirectory.\nNote: Do **not** include `comp_base.cmake!`.\n\nInside the feature file you should only use the following CMake functions in the given order:\n\n1. `comp_api_version(major[.minor[.patch]])` - checks if the API has the required version. `major` must match exactly, the rest not higher than the API version. If there is a version mismatch, it is an error.\n\n2. `comp_feature(\u003cname\u003e \u003ctest_code\u003e \u003cstandard\u003e \u003crequired...\u003e)` - does the feature check.\n`name` is the name of the feature without the directory, e.g. `constexpr`, not `cpp11_lang/constexpr`.\n`test_code` is the code that will be tested to see if the feature is supported.\n`standard` is the required C++ standard, this must be one of the `COMP_CPPXX_FLAG` values or `COMP_CPP98_FLAG` if no higher standard is needed.\n`required` is a list of requirede featuers that need to be supported in order to support this feature. If any of them isn't, this will not be checked.\n\n3. `comp_workaround(\u003cname\u003e \u003cworkaround_code\u003e \u003cstandard\u003e \u003crequired...\u003e)` - writes workaround code (optional).\n`name` must be the same as in `comp_feature()`.\n`workaround_code` is the workaround code itself.\nIt must use `${COMP_PREFIX}` for macros and put anything else into the namespace `${COMP_NAMESPACE]` (variable expansion works there, so write it exactly like that).\nThe result of the test is available through `${COMP_PREFIX}HAS_NAME`, e.g. `#if ${COMP_PREFIX}HAS_CONSTEXPR ... #else ... #endif`.\n`standard` is like in `comp_feature()` the standard required for the workaround code (the not-supported case, the supported case gets the standard of `comp_feature()`).\n`required` is a list of required features inside the workaround code. Their headers will be included prior to the workaround making it possible to use other workarounds.\n\n4. `comp_sd6_macro(\u003cname\u003e \u003csd6_name\u003e \u003cvalue\u003e)` - writes SD 6 macro (optional, since 1.1).\n`name` must be the same as in `comp_feature()`.\n`sd6_name` is the SD-6 macro name and `value` its value.\n\n5. `comp_unit_test(\u003cname\u003e \u003cglobal_code\u003e \u003ctest_code\u003e)` - defines a (Catch) unit test for the workaround code (optional).\n`name` must be the same as in `comp_feature()`.\n`global_code` will be put into the global namespace right after the including of the appropriate feature header and catch.\n`test_code` will be put into a Catch `TEST_CASE()`.\n\nThe code for feature checking should be minimal and do not depend on any other advanced features (for example, do not use `auto` or `nullptr`) to prevent false failure.\nThe workaround shouldn't use advanced features either, it can use other workarounds though.\n\nThe testing code should test the workaround. It will be run by the testing framework for both modes, supported and not supported.\n\nLook at a few other files for example implementations.\n","funding_links":[],"categories":["CMake","Utility Scripts"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffoonathan%2Fcompatibility","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffoonathan%2Fcompatibility","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffoonathan%2Fcompatibility/lists"}