| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | //================================================================================================== | ||
| 2 | /* | ||
| 3 | SPY - C++ Informations Broker | ||
| 4 | Copyright : SPY Project Contributors | ||
| 5 | SPDX-License-Identifier: BSL-1.0 | ||
| 6 | */ | ||
| 7 | //================================================================================================== | ||
| 8 | #pragma once | ||
| 9 | |||
| 10 | // Make sure the proper header is included to detect GNU libc | ||
| 11 | #include <spy/detail.hpp> | ||
| 12 | |||
| 13 | #include <compare> | ||
| 14 | #include <cstddef> | ||
| 15 | |||
| 16 | namespace spy::_ | ||
| 17 | { | ||
| 18 | template<int Year> struct cpp_standard_t | ||
| 19 | { | ||
| 20 | static constexpr int year = Year; | ||
| 21 | |||
| 22 | template<int OtherYear> constexpr auto operator<=>(cpp_standard_t<OtherYear>) const | ||
| 23 | { | ||
| 24 | return year <=> OtherYear; | ||
| 25 | } | ||
| 26 | |||
| 27 | template<int OtherYear> constexpr bool operator==(cpp_standard_t<OtherYear>) const | ||
| 28 | { | ||
| 29 | return year == OtherYear; | ||
| 30 | } | ||
| 31 | |||
| 32 | constexpr auto operator<=>(int other_year) const { return year <=> other_year; } | ||
| 33 | |||
| 34 | constexpr bool operator==(int other_year) const { return year == other_year; } | ||
| 35 | }; | ||
| 36 | |||
| 37 | 1 | template<_::stream OS, int Y> auto& operator<<(OS& os, cpp_standard_t<Y> const&) | |
| 38 | { | ||
| 39 | 1 | if constexpr(Y != 0) return os << "C++" << Y; | |
| 40 | else return os << "Unknown C++ standard version"; | ||
| 41 | } | ||
| 42 | } | ||
| 43 | |||
| 44 | namespace spy | ||
| 45 | { | ||
| 46 | //================================================================================================ | ||
| 47 | // C++ Standard detection object type | ||
| 48 | //================================================================================================ | ||
| 49 | #if defined(_MSVC_LANG) | ||
| 50 | #define SPY_RAW_CXX_STANDARD _MSVC_LANG | ||
| 51 | #else | ||
| 52 | #define SPY_RAW_CXX_STANDARD __cplusplus | ||
| 53 | #endif | ||
| 54 | |||
| 55 | #if SPY_RAW_CXX_STANDARD > 202302L | ||
| 56 | #define SPY_CXX_VERSION 26 | ||
| 57 | #elif SPY_RAW_CXX_STANDARD >= 202302L | ||
| 58 | #define SPY_CXX_VERSION 23 | ||
| 59 | #elif SPY_RAW_CXX_STANDARD >= 202002L | ||
| 60 | #define SPY_CXX_VERSION 20 | ||
| 61 | #else | ||
| 62 | #define SPY_CXX_VERSION 0 | ||
| 63 | #endif | ||
| 64 | |||
| 65 | //================================================================================================ | ||
| 66 | //! @ingroup spy_standards | ||
| 67 | //! @brief C++ standard version reporting value | ||
| 68 | //! | ||
| 69 | //! The `spy::cpp_standard` object can be compared to any other C++ standard related value to | ||
| 70 | //! verify if the code being compiled with a specific version of the C++ standard. It reports | ||
| 71 | //! `20`, `23` or `26`, and `0` when the standard version is unknown. | ||
| 72 | //! | ||
| 73 | //! The targeted version is specified either as an integer or with the `_cpp` literal. | ||
| 74 | //! | ||
| 75 | //! @groupheader{Example} | ||
| 76 | //! @godbolt{samples/standard.cpp} | ||
| 77 | //================================================================================================ | ||
| 78 | inline constexpr _::cpp_standard_t<SPY_CXX_VERSION> cpp_standard {}; | ||
| 79 | } | ||
| 80 | |||
| 81 | namespace spy::literal | ||
| 82 | { | ||
| 83 | //! @ingroup spy_standards | ||
| 84 | //! @brief User-defined suffix for C++ standard definition | ||
| 85 | template<char... c> | ||
| 86 | requires(sizeof...(c) == 2) | ||
| 87 | constexpr auto operator""_cpp() | ||
| 88 | { | ||
| 89 | return _::cpp_standard_t<_::parse<c...>(0, 2)> {}; | ||
| 90 | } | ||
| 91 | } | ||
| 92 |