GCC Code Coverage Report


Directory: include/spy/
File: include/spy/stdlib.hpp
Date: 2026-10-08 16:24:54
Exec Total Coverage
Lines: 2 2 100.0%
Functions: 1 1 100.0%
Branches: 0 0 -%

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 libstd
11 #include <spy/detail.hpp>
12
13 #include <cstddef>
14
15 namespace spy::_
16 {
17 enum class stdlib
18 {
19 undefined_ = -1,
20 libcpp_,
21 gnucpp_
22 };
23
24 template<stdlib Lib, int M, int N, int P> struct stdlib_info
25 {
26 static constexpr stdlib vendor = Lib;
27 static constexpr version_id<M, N, P> version = {};
28
29 inline constexpr explicit operator bool() const noexcept;
30
31 template<stdlib C2> constexpr bool operator==(stdlib_info<C2, -1, 0, 0> const&) const noexcept
32 {
33 return C2 == vendor;
34 }
35
36 template<stdlib C2, int M2, int N2, int P2>
37 constexpr bool operator==(stdlib_info<C2, M2, N2, P2> const& c2) const noexcept
38 {
39 return C2 == vendor && version == c2.version;
40 }
41
42 template<stdlib C2, int M2, int N2, int P2>
43 constexpr std::partial_ordering
44 operator<=>(stdlib_info<C2, M2, N2, P2> const& c2) const noexcept
45 {
46 if constexpr(vendor == C2) return version <=> c2.version;
47 else return std::partial_ordering::unordered;
48 }
49 };
50
51 template<_::stream OS, stdlib SLib, int M, int N, int P>
52 1 auto& operator<<(OS& os, stdlib_info<SLib, M, N, P> const& p)
53 {
54 if(SLib == stdlib::libcpp_) return os << "libc++ Standard C++ Library " << p.version;
55 1 if(SLib == stdlib::gnucpp_) return os << "GNU Standard C++ Library " << p.version;
56
57 return os << "Undefined Standard C++ Library";
58 }
59
60 template<int M, int N, int P> using libcpp_t = stdlib_info<stdlib::libcpp_, M, N, P>;
61 template<int M, int N, int P> using gnucpp_t = stdlib_info<stdlib::gnucpp_, M, N, P>;
62 }
63
64 namespace spy
65 {
66 #if defined(_LIBCPP_VERSION)
67 #define SPY_STDLIB_IS_LIBCPP
68 using stdlib_type = _::libcpp_t<(_LIBCPP_VERSION / 1000) % 10, 0, _LIBCPP_VERSION % 1000>;
69 #elif defined(__GLIBCXX__)
70 #define SPY_STDLIB_IS_GLIBCXX
71 #define SPY0 (__GLIBCXX__ / 100)
72 using stdlib_type = _::gnucpp_t<(SPY0 / 100) % 10000, SPY0 % 100, __GLIBCXX__ % 100>;
73 #undef SPY0
74 #else
75 #define SPY_STDLIB_IS_UNKNOWN
76 using stdlib_type = _::stdlib_info<_::stdlib::undefined_, -1, 0, 0>;
77 #endif
78
79 //================================================================================================
80 //! @ingroup spy_standards
81 //! @brief C++ Standard Library version reporting value
82 //!
83 //! The `spy::stdlib` object can be compared to any other stdlib related value to verify
84 //! if the code being compiled with a specific version of the C++ standard library.
85 //!
86 //! Any stdlib related value can be checked for equality or ordering for a given version. The
87 //! targeted version is then specified using a stdlib-dependent literal.
88 //!
89 //! Additionally, any of the stdlib related value are convertible to `bool`. They evaluates to
90 //! `true` if they matches the correct standard library currently used.
91 //!
92 //! @groupheader{Supported Value}
93 //!
94 //! Name | Vendor
95 //! ----------------- | -------------
96 //! `spy::libcpp_` | Clang libcpp
97 //! `spy::gnucpp_` | GNU C++ standard library
98 //!
99 //! @groupheader{Example}
100 //! @godbolt{samples/stdlib.cpp}
101 //================================================================================================
102 constexpr inline auto stdlib = stdlib_type {};
103 }
104
105 namespace spy::_
106 {
107 template<stdlib SLib, int M, int N, int P>
108 inline constexpr stdlib_info<SLib, M, N, P>::operator bool() const noexcept
109 {
110 return spy::stdlib == *this;
111 }
112 }
113
114 namespace spy
115 {
116 //================================================================================================
117 // STDLIBs detector stand-alone instances
118 //================================================================================================
119 constexpr inline auto libcpp_ = _::libcpp_t<-1, 0, 0> {};
120 constexpr inline auto gnucpp_ = _::gnucpp_t<-1, 0, 0> {};
121 }
122
123 namespace spy::literal
124 {
125 template<char... c> constexpr auto operator""_libcpp()
126 {
127 return _::literal_wrap<_::libcpp_t, c...>();
128 }
129
130 template<char... c> constexpr auto operator""_gnucpp()
131 {
132 return _::literal_wrap<_::gnucpp_t, c...>();
133 }
134 }
135