GCC Code Coverage Report


Directory: include/spy/
File: include/spy/arch.hpp
Date: 2026-10-08 16:24:54
Exec Total Coverage
Lines: 2 2 100.0%
Functions: 0 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 namespace spy::_
11 {
12 enum class archs
13 {
14 undefined_ = -1,
15 x86_ = 10,
16 amd64_ = 11,
17 ppc_ = 20,
18 arm_ = 30,
19 wasm_ = 40,
20 riscv_ = 50
21 };
22
23 template<archs Arch> struct arch_info
24 {
25 static constexpr archs vendor = Arch;
26
27 inline constexpr explicit operator bool() const noexcept;
28
29 6 template<archs A2> constexpr bool operator==(arch_info<A2> const&) const noexcept
30 {
31 6 return A2 == vendor;
32 }
33
34 template<_::stream OS> friend auto& operator<<(OS& os, arch_info const&)
35 {
36 if(Arch == archs::x86_) return os << "X86";
37 if(Arch == archs::amd64_) return os << "AMD64";
38 if(Arch == archs::ppc_) return os << "PowerPC";
39 if(Arch == archs::arm_) return os << "ARM";
40 if(Arch == archs::wasm_) return os << "WebAssembly";
41 if(Arch == archs::riscv_) return os << "RISC-V";
42
43 return os << "Undefined Architecture";
44 }
45 };
46 }
47
48 namespace spy
49 {
50 #if defined(i386) || defined(__i386__) || defined(__i486__) || defined(__i586__) || \
51 defined(__i686__) || defined(__i386) || defined(_M_IX86) || defined(_X86_) || \
52 defined(__THW_INTEL__) || defined(__I86__) || defined(__INTEL__)
53 using arch_type = _::arch_info<_::archs::x86_>;
54 #define SPY_ARCH_IS_X86
55 #elif defined(__x86_64) || defined(__x86_64__) || defined(__amd64__) || defined(__amd64) || \
56 defined(_M_X64)
57 #define SPY_ARCH_IS_AMD64
58 using arch_type = _::arch_info<_::archs::amd64_>;
59 #elif defined(__powerpc) || defined(__powerpc__) || defined(__POWERPC__) || defined(__ppc__) || \
60 defined(_M_PPC) || defined(_ARCH_PPC) || defined(__PPCGECKO__) || defined(__PPCBROADWAY__) || \
61 defined(_XENON)
62 using arch_type = _::arch_info<_::archs::ppc_>;
63 #define SPY_ARCH_IS_PPC
64 #elif defined(__arm__) || defined(__arm64) || defined(__thumb__) || defined(__TARGET_ARCH_ARM) || \
65 defined(__TARGET_ARCH_THUMB) || defined(_M_ARM) || defined(__ARM_ARCH_ISA_A64)
66 using arch_type = _::arch_info<_::archs::arm_>;
67 #define SPY_ARCH_IS_ARM
68 #elif defined(__wasm__)
69 using arch_type = _::arch_info<_::archs::wasm_>;
70 #define SPY_ARCH_IS_WASM
71 #elif defined(__riscv)
72 using arch_type = _::arch_info<_::archs::riscv_>;
73 #define SPY_ARCH_IS_RISCV
74 #else
75 #define SPY_ARCH_IS_UNKNOWN
76 using arch_type = _::arch_info<_::archs::undefined_>;
77 #endif
78
79 //================================================================================================
80 //! @ingroup spy_platform
81 //! @brief Architecture reporting value
82 //!
83 //! The `spy::architecture` object can be compared to any other architecture related value to
84 //! verify if the code being compiled is compiled for a given CPU architecture.
85 //!
86 //! Additionally, any of the architecture related value are convertible to `bool`. They evaluates
87 //! to `true` if they matches the correct architecture currently targeted.
88 //!
89 //! @groupheader{Supported Value}
90 //!
91 //! Name | Architecture
92 //! --------------- | -------------
93 //! `spy::amd64` | Intel X86-64 and similar architectures.
94 //! `spy::arm` | ARM.
95 //! `spy::ppc` | PowerPC.
96 //! `spy::riscv` | RISC-V.
97 //! `spy::wasm` | WASM pseudo-architecture.
98 //! `spy::x86` | Intel X86.
99 //!
100 //! @groupheader{Example}
101 //! @godbolt{samples/architecture.cpp}
102 //================================================================================================
103 constexpr inline arch_type architecture;
104 }
105
106 namespace spy::_
107 {
108 template<archs Arch> inline constexpr arch_info<Arch>::operator bool() const noexcept
109 {
110 return spy::architecture == *this;
111 }
112 }
113
114 namespace spy
115 {
116 //================================================================================================
117 // Architecture detector stand-alone instances
118 //================================================================================================
119 constexpr inline auto x86_ = _::arch_info<_::archs::x86_> {};
120 constexpr inline auto amd64_ = _::arch_info<_::archs::amd64_> {};
121 constexpr inline auto ppc_ = _::arch_info<_::archs::ppc_> {};
122 constexpr inline auto arm_ = _::arch_info<_::archs::arm_> {};
123 constexpr inline auto wasm_ = _::arch_info<_::archs::wasm_> {};
124 constexpr inline auto riscv_ = _::arch_info<_::archs::riscv_> {};
125 }
126