diff --git a/.github/workflows/unit.yml b/.github/workflows/unit.yml index 3d32dae..a1e6064 100644 --- a/.github/workflows/unit.yml +++ b/.github/workflows/unit.yml @@ -144,33 +144,33 @@ jobs: - name: Running Unit Tests run: cd build && ctest --verbose --output-on-failure -j 2 - ################################################################################################## - ## NVCC targets - ################################################################################################## - nvcc: - runs-on: ubuntu-latest - container: - image: nvidia/cuda:12.3.2-devel-ubi8 - steps: - - name: Fetch current branch - uses: actions/checkout@v4.1.1 - - name: Compiling Unit Tests - run: | - mkdir build && cd build - nvcc ../test/unit/accelerator.cu -std=c++17 -I../include -o accelerator.device.exe - nvcc ../test/unit/accelerator.cpp -std=c++17 -I../include -o accelerator.host.exe - nvcc ../test/unit/arch.cpp -std=c++17 -I../include -o arch.exe - nvcc ../test/unit/compiler.cpp -std=c++17 -I../include -o compiler.exe - nvcc ../test/unit/data_model.cpp -std=c++17 -I../include -o data_model.exe - nvcc ../test/unit/libc.cpp -std=c++17 -I../include -o libc.exe - nvcc ../test/unit/os.cpp -std=c++17 -I../include -o os.exe - nvcc ../test/unit/simd.cpp -std=c++17 -I../include -o simd.exe - nvcc ../test/unit/stdlib.cpp -std=c++17 -I../include -o stdlib.exe - - name: Running Unit Tests - run: | - cd build - ./accelerator.device.exe && ./accelerator.host.exe && ./arch.exe && ./compiler.exe && ./data_model.exe && \ - ./libc.exe && ./os.exe && ./simd.exe && ./stdlib.exe + # ################################################################################################## + # ## NVCC targets + # ################################################################################################## + # nvcc: + # runs-on: ubuntu-latest + # container: + # image: nvcr.io/nvidia/nvhpc:24.11-devel-cuda_multi-ubuntu22.04 + # steps: + # - name: Fetch current branch + # uses: actions/checkout@v4.1.1 + # - name: Compiling Unit Tests + # run: | + # mkdir build && cd build + # nvc++ ../test/unit/accelerator.cu -std=c++20 -I../include -o accelerator.device.exe + # nvc++ ../test/unit/accelerator.cpp -std=c++20 -I../include -o accelerator.host.exe + # nvc++ ../test/unit/arch.cpp -std=c++20 -I../include -o arch.exe + # nvc++ ../test/unit/compiler.cpp -std=c++20 -I../include -o compiler.exe + # nvc++ ../test/unit/data_model.cpp -std=c++20 -I../include -o data_model.exe + # nvc++ ../test/unit/libc.cpp -std=c++20 -I../include -o libc.exe + # nvc++ ../test/unit/os.cpp -std=c++20 -I../include -o os.exe + # nvc++ ../test/unit/simd.cpp -std=c++20 -I../include -o simd.exe + # nvc++ ../test/unit/stdlib.cpp -std=c++20 -I../include -o stdlib.exe + # - name: Running Unit Tests + # run: | + # cd build + # ./accelerator.device.exe && ./accelerator.host.exe && ./arch.exe && ./compiler.exe && ./data_model.exe && \ + # ./libc.exe && ./os.exe && ./simd.exe && ./stdlib.exe ################################################################################################## ## DPC++ Target diff --git a/cmake/compiler.cmake b/cmake/compiler.cmake index fe4950b..3202152 100644 --- a/cmake/compiler.cmake +++ b/cmake/compiler.cmake @@ -9,7 +9,7 @@ ##====================================================================================================================== add_library(spy_tests INTERFACE) -target_compile_features ( spy_tests INTERFACE cxx_std_17 ) +target_compile_features ( spy_tests INTERFACE cxx_std_20 ) if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") if(CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "MSVC") diff --git a/doc/base.html b/doc/base.html index 5b72a4a..eb2d5c7 100644 --- a/doc/base.html +++ b/doc/base.html @@ -22,7 +22,7 @@ $treeview $search diff --git a/doc/index.hpp b/doc/index.hpp index 89b93b9..8d27691 100644 --- a/doc/index.hpp +++ b/doc/index.hpp @@ -8,7 +8,7 @@ //! [Boost.Predef](https://www.boost.org/doc/libs/release/doc/html/predef.html) provides a sanitized //! interface on top of those but still live in a world where the preprocessor is king. //! -//! SPY is a C++17 (and onward) library that gathers similar information and provides a `constexpr` +//! SPY is a C++20 (and onward) library that gathers similar information and provides a `constexpr` //! compatible interface to access those information, thus making their exploitation within `constexpr` //! context possible. //! diff --git a/doc/spy.tag b/doc/spy.tag new file mode 100644 index 0000000..7b7755d --- /dev/null +++ b/doc/spy.tag @@ -0,0 +1,268 @@ + + + + literal + namespaceliteral.html + + + spy + namespacespy.html + + constexpr arch_type + architecture + group__api_gaad5f2aa34188a02b894a0d8c7e402d6e.html + gaad5f2aa34188a02b894a0d8c7e402d6e + + + + constexpr compiler_type + compiler + group__api_ga2d96c18fea5b9a06ac37487ab570599d.html + ga2d96c18fea5b9a06ac37487ab570599d + + + + constexpr auto + data_model + group__api_gaa091fe192a7f9d0d164cf7546083200d.html + gaa091fe192a7f9d0d164cf7546083200d + + + + constexpr auto + libc + group__api_ga03dc3f2a9b02b025902f9df3b2db53ab.html + ga03dc3f2a9b02b025902f9df3b2db53ab + + + + constexpr os_type + operating_system + group__api_gadb7c5be967e00cff21ae5b98cc12a7dc.html + gadb7c5be967e00cff21ae5b98cc12a7dc + + + + constexpr auto + simd_instruction_set + group__api_ga45f64b82d4939d55865b0e6a311b2dde.html + ga45f64b82d4939d55865b0e6a311b2dde + + + + constexpr auto + stdlib + group__api_gafe99b815db524eacf659ba8348ca2e0d.html + gafe99b815db524eacf659ba8348ca2e0d + + + + + supports + namespacesupports.html + + + api + Main API + group__api.html + + constexpr bool + spy::supports::address_sanitizers_status + group__api_ga37e2c07363dadf1eb40e89a9a91f8121.html + ga37e2c07363dadf1eb40e89a9a91f8121 + + + + constexpr arch_type + spy::architecture + group__api_gaad5f2aa34188a02b894a0d8c7e402d6e.html + gaad5f2aa34188a02b894a0d8c7e402d6e + + + + constexpr compiler_type + spy::compiler + group__api_ga2d96c18fea5b9a06ac37487ab570599d.html + ga2d96c18fea5b9a06ac37487ab570599d + + + + constexpr auto + spy::supports::cuda + group__api_gaad706954aedb6aaf6ff1a9858a971e00.html + gaad706954aedb6aaf6ff1a9858a971e00 + + + + constexpr auto + spy::data_model + group__api_gaa091fe192a7f9d0d164cf7546083200d.html + gaa091fe192a7f9d0d164cf7546083200d + + + + constexpr auto + spy::libc + group__api_ga03dc3f2a9b02b025902f9df3b2db53ab.html + ga03dc3f2a9b02b025902f9df3b2db53ab + + + + constexpr os_type + spy::operating_system + group__api_gadb7c5be967e00cff21ae5b98cc12a7dc.html + gadb7c5be967e00cff21ae5b98cc12a7dc + + + + constexpr auto + spy::supports::posix_ + group__api_ga63eef44bc05ea6f77f278ba5b394ada8.html + ga63eef44bc05ea6f77f278ba5b394ada8 + + + + constexpr bool + spy::supports::sanitizers_status + group__api_ga28313e4f9673ea0f5d0ca44ffd1a967a.html + ga28313e4f9673ea0f5d0ca44ffd1a967a + + + + constexpr auto + spy::simd_instruction_set + group__api_ga45f64b82d4939d55865b0e6a311b2dde.html + ga45f64b82d4939d55865b0e6a311b2dde + + + + constexpr auto + spy::stdlib + group__api_gafe99b815db524eacf659ba8348ca2e0d.html + gafe99b815db524eacf659ba8348ca2e0d + + + + constexpr auto + spy::supports::sycl + group__api_ga03e4a3ae6533a43cdf9bcbf1317707cd.html + ga03e4a3ae6533a43cdf9bcbf1317707cd + + + + constexpr bool + spy::supports::thread_sanitizers_status + group__api_ga16591d3ea9aaa049682bfbedd519dc43.html + ga16591d3ea9aaa049682bfbedd519dc43 + + + + constexpr auto + spy::literal::operator""_clang + group__api.html + gab3e0f11a5ec1b2963564755b84630970 + () + + + constexpr auto + spy::literal::operator""_cloud + group__api.html + ga1dc236e3cae2ef3c7ec23d45659b7b30 + () + + + constexpr auto + spy::literal::operator""_dpcpp + group__api.html + gab38166c11c2a99b2257e00630db206ec + () + + + constexpr auto + spy::literal::operator""_em + group__api.html + ga8b0155c33f6f54c0d1d2dd498417c536 + () + + + constexpr auto + spy::literal::operator""_gcc + group__api.html + ga542b6a98ac5e95f906da14325a2064be + () + + + constexpr auto + spy::literal::operator""_gnu + group__api.html + ga01fac6d9d1025344d16c3ab4fee137c8 + () + + + constexpr auto + spy::literal::operator""_intel + group__api.html + ga17b7828b022e763e749aebf056d24195 + () + + + constexpr auto + spy::literal::operator""_msvc + group__api.html + gaafdbca6599d9792e579da8041b5addcd + () + + + constexpr auto + spy::literal::operator""_nvcc + group__api.html + ga39f9d138ef1adb4b5c12f4279878f1fc + () + + + constexpr auto + spy::literal::operator""_uc + group__api.html + ga0c3666ca0bb5f551cc0103e355a28569 + () + + + constexpr auto + spy::literal::operator""_vms + group__api.html + ga772746f665f6dd13b9a6c8bd19564dab + () + + + constexpr auto + spy::literal::operator""_zos + group__api.html + ga3c0e24636d16a543f4bf2ed64875eaeb + () + + + + changelog + Change Log + changelog.html + + + licence + Licence + licence.html + + + setup + Setup + setup.html + setup-source + setup-standalone + setup-fetchcontent + setup-cpm + + + index + The C++ Information Broker + index.html + + diff --git a/include/spy/accelerator.hpp b/include/spy/accelerator.hpp index f336767..fd0a28c 100644 --- a/include/spy/accelerator.hpp +++ b/include/spy/accelerator.hpp @@ -6,7 +6,6 @@ */ //================================================================================================== #pragma once -#include namespace spy::supports { @@ -14,7 +13,8 @@ namespace spy::supports { explicit constexpr operator bool() const noexcept { return M>0 && N>0; } - friend std::ostream& operator<<(std::ostream& os, sycl_t) + template<_::stream OS> + friend OS& operator<<(OS& os, sycl_t) { os << "SYCL v" << M << '.' << N; if(P>0) os << '.' << P; @@ -38,7 +38,8 @@ namespace spy::supports { explicit constexpr operator bool() const noexcept { return M>0 && N>0; } - friend std::ostream& operator<<(std::ostream& os, cuda_t) + template<_::stream OS> + friend OS& operator<<(OS& os, cuda_t) { os << "NVCC CUDA v" << M << '.' << N; if(P>0) os << '.' << P; diff --git a/include/spy/arch.hpp b/include/spy/arch.hpp index 6c8d7c3..25fabf1 100644 --- a/include/spy/arch.hpp +++ b/include/spy/arch.hpp @@ -6,9 +6,8 @@ */ //================================================================================================== #pragma once -#include -namespace spy::detail +namespace spy::_ { enum class archs { undefined_ = -1 , x86_ = 10, amd64_ = 11 @@ -28,20 +27,20 @@ namespace spy::detail { return A2 == vendor; } - }; - template - std::ostream& operator<<(std::ostream& os, arch_info const&) - { - if(Arch == archs::x86_ ) return os << "X86"; - if(Arch == archs::amd64_) return os << "AMD64"; - if(Arch == archs::ppc_ ) return os << "PowerPC"; - if(Arch == archs::arm_ ) return os << "ARM"; - if(Arch == archs::wasm_ ) return os << "WebAssembly"; - if(Arch == archs::riscv_) return os << "RISC-V"; + template<_::stream OS> + friend OS& operator<<(OS& os, arch_info const&) + { + if(Arch == archs::x86_ ) return os << "X86"; + if(Arch == archs::amd64_) return os << "AMD64"; + if(Arch == archs::ppc_ ) return os << "PowerPC"; + if(Arch == archs::arm_ ) return os << "ARM"; + if(Arch == archs::wasm_ ) return os << "WebAssembly"; + if(Arch == archs::riscv_) return os << "RISC-V"; - return os << "Undefined Architecture"; - } + return os << "Undefined Architecture"; + } + }; } namespace spy @@ -49,29 +48,29 @@ namespace spy #if defined(i386) || defined(__i386__) || defined(__i486__) || defined(__i586__) || \ defined(__i686__) || defined(__i386) || defined(_M_IX86) || defined(_X86_) || \ defined(__THW_INTEL__) || defined(__I86__) || defined(__INTEL__) - using arch_type = detail::arch_info; + using arch_type = _::arch_info<_::archs::x86_>; #define SPY_ARCH_IS_X86 #elif defined(__x86_64) || defined(__x86_64__) || defined(__amd64__) || defined(__amd64) || defined(_M_X64) #define SPY_ARCH_IS_AMD64 - using arch_type = detail::arch_info; + using arch_type = _::arch_info<_::archs::amd64_>; #elif defined(__powerpc) || defined(__powerpc__) || defined(__POWERPC__) || defined(__ppc__) || \ defined(_M_PPC) || defined(_ARCH_PPC) || defined(__PPCGECKO__) || defined(__PPCBROADWAY__) || \ defined(_XENON) - using arch_type = detail::arch_info; + using arch_type = _::arch_info<_::archs::ppc_>; #define SPY_ARCH_IS_PPC #elif defined(__arm__) || defined(__arm64) || defined(__thumb__) || defined(__TARGET_ARCH_ARM) || \ defined(__TARGET_ARCH_THUMB) || defined(_M_ARM) || defined(__ARM_ARCH_ISA_A64) - using arch_type = detail::arch_info; + using arch_type = _::arch_info<_::archs::arm_>; #define SPY_ARCH_IS_ARM #elif defined(__wasm__) - using arch_type = detail::arch_info; + using arch_type = _::arch_info<_::archs::wasm_>; #define SPY_ARCH_IS_WASM #elif defined(__riscv) - using arch_type = detail::arch_info; + using arch_type = _::arch_info<_::archs::riscv_>; #define SPY_ARCH_IS_RISCV #else #define SPY_ARCH_IS_UNKNOWN - using arch_type = detail::arch_info; + using arch_type = _::arch_info<_::archs::undefined_>; #endif //================================================================================================ @@ -101,7 +100,7 @@ namespace spy constexpr inline arch_type architecture; } -namespace spy::detail +namespace spy::_ { template inline constexpr arch_info::operator bool() const noexcept @@ -115,10 +114,10 @@ namespace spy //================================================================================================ // Architecture detector stand-alone instances //================================================================================================ - constexpr inline auto x86_ = detail::arch_info{}; - constexpr inline auto amd64_ = detail::arch_info{}; - constexpr inline auto ppc_ = detail::arch_info{}; - constexpr inline auto arm_ = detail::arch_info{}; - constexpr inline auto wasm_ = detail::arch_info{}; - constexpr inline auto riscv_ = detail::arch_info{}; + constexpr inline auto x86_ = _::arch_info<_::archs::x86_>{}; + constexpr inline auto amd64_ = _::arch_info<_::archs::amd64_>{}; + constexpr inline auto ppc_ = _::arch_info<_::archs::ppc_>{}; + constexpr inline auto arm_ = _::arch_info<_::archs::arm_>{}; + constexpr inline auto wasm_ = _::arch_info<_::archs::wasm_>{}; + constexpr inline auto riscv_ = _::arch_info<_::archs::riscv_>{}; } diff --git a/include/spy/compiler.hpp b/include/spy/compiler.hpp index 047942a..c3b7d31 100644 --- a/include/spy/compiler.hpp +++ b/include/spy/compiler.hpp @@ -15,7 +15,7 @@ # endif #endif -namespace spy::detail +namespace spy::_ { enum class compilers { undefined_ = - 1, msvc_, intel_, clang_, gcc_, emscripten_, dpcpp_, nvcc_ }; @@ -35,8 +35,8 @@ namespace spy::detail SPY_VERSION_COMPARISONS_OPERATOR(compilers,compilers_info) }; - template - std::ostream& operator<<(std::ostream& os, compilers_info const& c) + template<_::stream OS, compilers C, int M, int N, int P> + OS& operator<<(OS& os, compilers_info const& c) { if(C == compilers::nvcc_ ) return os << "NVIDIA CUDA Compiler " << c.version; if(C == compilers::msvc_ ) return os << "Microsoft Visual Studio " << c.version; @@ -65,33 +65,33 @@ namespace spy //================================================================================================ #if defined(__NVCC__) #define SPY_COMPILER_IS_NVCC - using compiler_type = detail::nvcc_t<__CUDACC_VER_MAJOR__, __CUDACC_VER_MINOR__, 0>; + using compiler_type = _::nvcc_t<__CUDACC_VER_MAJOR__, __CUDACC_VER_MINOR__, 0>; #elif defined(_MSC_VER) #define SPY_COMPILER_IS_MSVC - using compiler_type = detail::msvc_t<_MSC_VER / 100, _MSC_VER % 100, _MSC_FULL_VER % 100000>; + using compiler_type = _::msvc_t<_MSC_VER / 100, _MSC_VER % 100, _MSC_FULL_VER % 100000>; #elif defined(__INTEL_LLVM_COMPILER) #define SPY_COMPILER_IS_INTEL_DPCPP #define SPY0 __INTEL_LLVM_COMPILER - using compiler_type = detail::dpcpp_t; + using compiler_type = _::dpcpp_t; #undef SPY0 #elif defined(__INTEL_COMPILER) || defined(__ICL) || defined(__ICC) || defined(__ECC) #define SPY_COMPILER_IS_INTEL #define SPY0 __INTEL_COMPILER - using compiler_type = detail::intel_t<(SPY0 / 100) % 100,SPY0 % 100, __INTEL_COMPILER_UPDATE>; + using compiler_type = _::intel_t<(SPY0 / 100) % 100,SPY0 % 100, __INTEL_COMPILER_UPDATE>; #undef SPY0 #elif defined(__EMSCRIPTEN__) #define SPY_COMPILER_IS_CLANG - using compiler_type = detail::emscripten_t<__EMSCRIPTEN_major__, __EMSCRIPTEN_minor__, __EMSCRIPTEN_tiny__ >; + using compiler_type = _::emscripten_t<__EMSCRIPTEN_major__, __EMSCRIPTEN_minor__, __EMSCRIPTEN_tiny__ >; #undef SPY0 #elif defined(__clang__) #define SPY_COMPILER_IS_CLANG - using compiler_type = detail::clang_t<__clang_major__, __clang_minor__, __clang_patchlevel__>; + using compiler_type = _::clang_t<__clang_major__, __clang_minor__, __clang_patchlevel__>; #elif defined(__GNUC__) #define SPY_COMPILER_IS_GCC - using compiler_type = detail::gcc_t<__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__>; + using compiler_type = _::gcc_t<__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__>; #else #define SPY_COMPILER_IS_UNKNOWN - using compiler_type = detail::compilers_info; + using compiler_type = _::compilers_info; #endif //================================================================================================ @@ -125,7 +125,7 @@ namespace spy constexpr inline compiler_type compiler; } -namespace spy::detail +namespace spy::_ { template inline constexpr compilers_info::operator bool() const noexcept @@ -139,13 +139,13 @@ namespace spy //================================================================================================ // Compilers detector stand-alone instances //================================================================================================ - constexpr inline auto nvcc_ = detail::nvcc_t<-1,0,0>{}; - constexpr inline auto msvc_ = detail::msvc_t<-1,0,0>{}; - constexpr inline auto intel_ = detail::intel_t<-1,0,0>{}; - constexpr inline auto dpcpp_ = detail::dpcpp_t<-1,0,0>{}; - constexpr inline auto clang_ = detail::clang_t<-1,0,0>{}; - constexpr inline auto gcc_ = detail::gcc_t<-1,0,0>{}; - constexpr inline auto emscripten_ = detail::emscripten_t<-1,0,0>{}; + constexpr inline auto nvcc_ = _::nvcc_t<-1,0,0>{}; + constexpr inline auto msvc_ = _::msvc_t<-1,0,0>{}; + constexpr inline auto intel_ = _::intel_t<-1,0,0>{}; + constexpr inline auto dpcpp_ = _::dpcpp_t<-1,0,0>{}; + constexpr inline auto clang_ = _::clang_t<-1,0,0>{}; + constexpr inline auto gcc_ = _::gcc_t<-1,0,0>{}; + constexpr inline auto emscripten_ = _::emscripten_t<-1,0,0>{}; } namespace spy::literal @@ -154,48 +154,48 @@ namespace spy::literal //! @brief User-defined suffix for NVCC version definition template constexpr auto operator"" _nvcc() { - return detail::literal_wrap(); + return _::literal_wrap<_::nvcc_t,c...>(); } //! @ingroup api //! @brief User-defined suffix for MSVC version definition template constexpr auto operator"" _msvc() { - return detail::literal_wrap(); + return _::literal_wrap<_::msvc_t,c...>(); } //! @ingroup api //! @brief User-defined suffix for Intel ICC version definition template constexpr auto operator"" _intel() { - return detail::literal_wrap(); + return _::literal_wrap<_::intel_t,c...>(); } //! @ingroup api //! @brief User-defined suffix for Intel DCP++/ICPX version definition template constexpr auto operator"" _dpcpp() { - return detail::literal_wrap(); + return _::literal_wrap<_::dpcpp_t,c...>(); } //! @ingroup api //! @brief User-defined suffix for Clang version definition template constexpr auto operator"" _clang() { - return detail::literal_wrap(); + return _::literal_wrap<_::clang_t,c...>(); } //! @ingroup api //! @brief User-defined suffix for G++ version definition template constexpr auto operator"" _gcc() { - return detail::literal_wrap(); + return _::literal_wrap<_::gcc_t,c...>(); } //! @ingroup api //! @brief User-defined suffix for Emscripten version definition template constexpr auto operator"" _em() { - return detail::literal_wrap(); + return _::literal_wrap<_::emscripten_t,c...>(); } } diff --git a/include/spy/data_model.hpp b/include/spy/data_model.hpp index e70849b..c15ec89 100644 --- a/include/spy/data_model.hpp +++ b/include/spy/data_model.hpp @@ -7,7 +7,7 @@ //================================================================================================== #pragma once -namespace spy::detail +namespace spy::_ { template struct data_model_info @@ -21,8 +21,8 @@ namespace spy::detail } }; - template - std::ostream& operator<<(std::ostream& os, data_model_info const&) + template<_::stream OS, int Short, int Integer, int Long, int Pointer> + OS& operator<<(OS& os, data_model_info const&) { if constexpr(Pointer == 4 && Integer == 4) return os << "ILP32"; else if constexpr(Pointer == 4 && Integer == 2) return os << "LP32"; @@ -36,7 +36,7 @@ namespace spy::detail namespace spy { - using data_model_type = detail::data_model_info < sizeof(short), sizeof(int) + using data_model_type = _::data_model_info < sizeof(short), sizeof(int) , sizeof(long), sizeof(void*) >; @@ -67,7 +67,7 @@ namespace spy constexpr inline auto data_model = data_model_type{}; } -namespace spy::detail +namespace spy::_ { template inline constexpr data_model_info::operator bool() const noexcept @@ -81,10 +81,10 @@ namespace spy //================================================================================================ // Data model detector stand-alone instances //================================================================================================ - constexpr inline auto ilp32_ = detail::data_model_info<2,4,sizeof(long),4>{}; - constexpr inline auto lp32_ = detail::data_model_info<2,2,sizeof(long),4>{}; - constexpr inline auto silp64_ = detail::data_model_info<8,8,8,8>{}; - constexpr inline auto ilp64_ = detail::data_model_info<2,8,8,8>{}; - constexpr inline auto llp64_ = detail::data_model_info<2,8,4,8>{}; - constexpr inline auto lp64_ = detail::data_model_info<2,4,8,8>{}; + constexpr inline auto ilp32_ = _::data_model_info<2,4,sizeof(long),4>{}; + constexpr inline auto lp32_ = _::data_model_info<2,2,sizeof(long),4>{}; + constexpr inline auto silp64_ = _::data_model_info<8,8,8,8>{}; + constexpr inline auto ilp64_ = _::data_model_info<2,8,8,8>{}; + constexpr inline auto llp64_ = _::data_model_info<2,8,4,8>{}; + constexpr inline auto lp64_ = _::data_model_info<2,4,8,8>{}; } diff --git a/include/spy/detail.hpp b/include/spy/detail.hpp index 0c6de82..b781638 100644 --- a/include/spy/detail.hpp +++ b/include/spy/detail.hpp @@ -6,10 +6,16 @@ */ //================================================================================================== #pragma once -#include - -namespace spy::detail +namespace spy::_ { + template + concept stream = requires(T& os, char c) + { + { os.copyfmt(os) }; + { os.flush() }; + { os.put(c) }; + }; + template constexpr int find(int i0) { int sz = sizeof...(c); @@ -91,13 +97,14 @@ namespace spy::detail return !(a - std::ostream& operator<<(std::ostream& os, version_id const&) + template<_::stream OS, int M, int N, int P> + OS& operator<<(OS& os, version_id const&) { return os << "v" << M << "." << N << "." << P; } - inline std::ostream& operator<<(std::ostream& os, unspecified_version_t const&) + template<_::stream OS> + OS& operator<<(OS& os, unspecified_version_t const&) { return os << "(unspecified)"; } diff --git a/include/spy/libc.hpp b/include/spy/libc.hpp index 801212b..2dc97b4 100644 --- a/include/spy/libc.hpp +++ b/include/spy/libc.hpp @@ -11,7 +11,7 @@ #include #include -namespace spy::detail +namespace spy::_ { enum class libC { undefined_ = - 1, cloudabi_, uc_, vms_, zos_, gnu_ }; @@ -31,8 +31,8 @@ namespace spy::detail SPY_VERSION_COMPARISONS_OPERATOR(libC,libc_info) }; - template - std::ostream& operator<<(std::ostream& os, libc_info const& c) + template<_::stream OS, libC C, int M, int N, int P> + OS& operator<<(OS& os, libc_info const& c) { if(c.vendor == libC::cloudabi_) return os << "CloudABI Standard C Library " << c.version; if(c.vendor == libC::uc_ ) return os << "uClibc Standard C Library " << c.version; @@ -57,30 +57,30 @@ namespace spy //================================================================================================ #if defined(__cloudlibc__) #define SPY_LIBC_IS_CLOUDABI - using libc_type = detail::cloudabi_t<__cloudlibc_major__,__cloudlibc_minor__,0>; + using libc_type = _::cloudabi_t<__cloudlibc_major__,__cloudlibc_minor__,0>; #elif defined(__GLIBC__) #define SPY_LIBC_IS_GNU - using libc_type = detail::gnu_t<__GLIBC__, __GLIBC_MINOR__, 0>; + using libc_type = _::gnu_t<__GLIBC__, __GLIBC_MINOR__, 0>; #elif defined(__GNU_LIBRARY__) #define SPY_LIBC_IS_GNU - using libc_type = detail::gnu_t<__GNU_LIBRARY__, __GNU_LIBRARY_MINOR__, 0>; + using libc_type = _::gnu_t<__GNU_LIBRARY__, __GNU_LIBRARY_MINOR__, 0>; #elif defined(__UCLIBC__) #define SPY_LIBC_IS_UCLIBC - using libc_type = detail::uc_t<__UCLIBC_MAJOR__, __UCLIBC_MINOR__, __UCLIBC_SUBLEVEL__>; + using libc_type = _::uc_t<__UCLIBC_MAJOR__, __UCLIBC_MINOR__, __UCLIBC_SUBLEVEL__>; #elif defined(__CRTL_VER) #define SPY_LIBC_IS_VMS #define SPY0 (__CRTL_VER/100) - using libc_type = detail::vms_t<(SPY0/100000)%100, (SPY0/1000)%100, (SPY0)%100>; + using libc_type = _::vms_t<(SPY0/100000)%100, (SPY0/1000)%100, (SPY0)%100>; #undef SPY0 #elif defined(__LIBREL__) #define SPY_LIBC_IS_ZOS - using libc_type = detail::zos_t < (__LIBREL__&0xF000000)>>24 + using libc_type = _::zos_t < (__LIBREL__&0xF000000)>>24 , (__LIBREL__&0xFF0000)>>16 , (__LIBREL__&0xFFFF) >; #else #define SPY_LIBC_IS_UNKNOWN - using libc_type = detail::libc_info; + using libc_type = _::libc_info<_::libC::undefined_,-1,0,0>; #endif //================================================================================================ @@ -112,7 +112,7 @@ namespace spy constexpr inline auto libc = libc_type{}; } -namespace spy::detail +namespace spy::_ { template inline constexpr libc_info::operator bool() const noexcept @@ -126,11 +126,11 @@ namespace spy //================================================================================================ // LIBCs detector stand-alone instances //================================================================================================ - constexpr inline auto cloudabi_ = detail::cloudabi_t<-1,0,0>{}; - constexpr inline auto uc_ = detail::uc_t<-1,0,0>{}; - constexpr inline auto vms_ = detail::vms_t<-1,0,0>{}; - constexpr inline auto zos_ = detail::zos_t<-1,0,0>{}; - constexpr inline auto gnu_ = detail::gnu_t<-1,0,0>{}; + constexpr inline auto cloudabi_ = _::cloudabi_t<-1,0,0>{}; + constexpr inline auto uc_ = _::uc_t<-1,0,0>{}; + constexpr inline auto vms_ = _::vms_t<-1,0,0>{}; + constexpr inline auto zos_ = _::zos_t<-1,0,0>{}; + constexpr inline auto gnu_ = _::gnu_t<-1,0,0>{}; } namespace spy::literal @@ -139,34 +139,34 @@ namespace spy::literal //! @brief User-defined suffix for the CloudABI libc version definition template constexpr auto operator"" _cloud() { - return detail::literal_wrap(); + return _::literal_wrap<_::cloudabi_t,c...>(); } //! @ingroup api //! @brief User-defined suffix for the uClibc version definition template constexpr auto operator"" _uc() { - return detail::literal_wrap(); + return _::literal_wrap<_::uc_t,c...>(); } //! @ingroup api //! @brief User-defined suffix for the VMS libc version definition template constexpr auto operator"" _vms() { - return detail::literal_wrap(); + return _::literal_wrap<_::vms_t,c...>(); } //! @ingroup api //! @brief User-defined suffix for the zOS libc version definition template constexpr auto operator"" _zos() { - return detail::literal_wrap(); + return _::literal_wrap<_::zos_t,c...>(); } //! @ingroup api //! @brief User-defined suffix for the GNU libc version definition template constexpr auto operator"" _gnu() { - return detail::literal_wrap(); + return _::literal_wrap<_::gnu_t,c...>(); } } diff --git a/include/spy/os.hpp b/include/spy/os.hpp index b1a1443..c5422a5 100644 --- a/include/spy/os.hpp +++ b/include/spy/os.hpp @@ -11,7 +11,7 @@ # include #endif -namespace spy::detail +namespace spy::_ { enum class systems { undefined_ = - 1 , android_, bsd_, cygwin_, ios_, linux_, macos_, unix_, windows_ @@ -30,8 +30,8 @@ namespace spy::detail } }; - template - std::ostream& operator<<(std::ostream& os, os_info const&) + template<_::stream OS, systems OpSys> + OS& operator<<(OS& os, os_info const&) { if(OpSys == systems::android_ ) return os << "Android"; if(OpSys == systems::bsd_ ) return os << "BSD"; @@ -50,31 +50,31 @@ namespace spy { #if defined(__ANDROID__) #define SPY_OS_IS_ANDROID - using os_type = detail::os_info; + using os_type = _::os_info<_::systems::android_>; #elif defined(BSD) || defined(_SYSTYPE_BSD) #define SPY_OS_IS_BSD - using os_type = detail::os_info; + using os_type = _::os_info<_::systems::bsd_>; #elif defined(__CYGWIN__) #define SPY_OS_IS_CYGWIN - using os_type = detail::os_info; + using os_type = _::os_info<_::systems::cygwin_>; #elif defined(__APPLE__) && defined(__MACH__) && defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) #define SPY_OS_IS_IOS - using os_type = detail::os_info; + using os_type = _::os_info<_::systems::ios_>; #elif defined(linux) || defined(__linux) #define SPY_OS_IS_LINUX - using os_type = detail::os_info; + using os_type = _::os_info<_::systems::linux_>; #elif defined(macintosh) || defined(Macintosh) || (defined(__APPLE__) && defined(__MACH__)) #define SPY_OS_IS_MACOS - using os_type = detail::os_info; + using os_type = _::os_info<_::systems::macos_>; #elif defined(unix) || defined(__unix) || defined(_XOPEN_SOURCE) || defined(_POSIX_SOURCE) #define SPY_OS_IS_UNIX - using os_type = detail::os_info; + using os_type = _::os_info<_::systems::unix_>; #elif defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(__TOS_WIN__) || defined(__WINDOWS__) #define SPY_OS_IS_WINDOWS - using os_type = detail::os_info; + using os_type = _::os_info<_::systems::windows_>; #else #define SPY_OS_IS_UNKNOWN - using os_type = detail::os_info; + using os_type = _::os_info<_::systems::undefined_>; #endif //================================================================================================ @@ -106,7 +106,7 @@ namespace spy constexpr inline os_type operating_system; } -namespace spy::detail +namespace spy::_ { template inline constexpr os_info::operator bool() const noexcept @@ -117,14 +117,14 @@ namespace spy::detail namespace spy { - constexpr inline auto android_ = detail::os_info{}; - constexpr inline auto bsd_ = detail::os_info{}; - constexpr inline auto cygwin_ = detail::os_info{}; - constexpr inline auto ios_ = detail::os_info{}; - constexpr inline auto linux_ = detail::os_info{}; - constexpr inline auto macos_ = detail::os_info{}; - constexpr inline auto unix_ = detail::os_info{}; - constexpr inline auto windows_ = detail::os_info{}; + constexpr inline auto android_ = _::os_info<_::systems::android_>{}; + constexpr inline auto bsd_ = _::os_info<_::systems::bsd_>{}; + constexpr inline auto cygwin_ = _::os_info<_::systems::cygwin_>{}; + constexpr inline auto ios_ = _::os_info<_::systems::ios_>{}; + constexpr inline auto linux_ = _::os_info<_::systems::linux_>{}; + constexpr inline auto macos_ = _::os_info<_::systems::macos_>{}; + constexpr inline auto unix_ = _::os_info<_::systems::unix_>{}; + constexpr inline auto windows_ = _::os_info<_::systems::windows_>{}; } namespace spy::supports diff --git a/include/spy/simd.hpp b/include/spy/simd.hpp index be19e8a..c0a5717 100644 --- a/include/spy/simd.hpp +++ b/include/spy/simd.hpp @@ -7,14 +7,13 @@ //================================================================================================== #pragma once -#include #include #include #include #include #include -namespace spy::detail +namespace spy::_ { enum class simd_isa { undefined_ = -1 , x86_ = 1000 @@ -49,7 +48,7 @@ namespace spy::detail static constexpr auto isa = InsSetArch; static constexpr auto version = Version; - static constexpr std::ptrdiff_t width = []() + static constexpr int width = []() { if constexpr( Version == simd_version::simd128_ || (Version >= simd_version::sse1_ && Version <= simd_version::sse42_) @@ -84,7 +83,8 @@ namespace spy::detail static constexpr bool has_fixed_cardinal() { return width != -1; } - friend std::ostream& operator<<(std::ostream& os, simd_info const&) + template<_::stream OS> + friend OS& operator<<(OS& os, simd_info const&) { if constexpr ( Version == simd_version::simd128_ ) os << "WASM SIMD128"; else if constexpr ( Version == simd_version::sse1_ ) os << "X86 SSE"; @@ -231,71 +231,71 @@ namespace spy //! //================================================================================================ #if defined(SPY_SIMD_DETECTED) - constexpr inline auto simd_instruction_set = detail::simd_info{}; + constexpr inline auto simd_instruction_set = _::simd_info{}; #else - constexpr inline auto simd_instruction_set = detail::simd_info<>{}; + constexpr inline auto simd_instruction_set = _::simd_info<>{}; #endif //================================================================================================ // Available SIMD instructions set //================================================================================================ - constexpr inline auto undefined_simd_ = detail::simd_info<>{}; + constexpr inline auto undefined_simd_ = _::simd_info<>{}; - template - using wasm_simd_info = detail::simd_info; + template<_::simd_version V = _::simd_version::undefined_> + using wasm_simd_info = _::simd_info<_::simd_isa::wasm_,V>; constexpr inline auto wasm_simd_ = wasm_simd_info<>{}; - constexpr inline auto simd128_ = wasm_simd_info{}; + constexpr inline auto simd128_ = wasm_simd_info<_::simd_version::simd128_>{}; - template - using x86_simd_info = detail::simd_info; + template<_::simd_version V = _::simd_version::undefined_> + using x86_simd_info = _::simd_info<_::simd_isa::x86_,V>; constexpr inline auto x86_simd_ = x86_simd_info<>{}; - constexpr inline auto sse1_ = x86_simd_info{}; - constexpr inline auto sse2_ = x86_simd_info{}; - constexpr inline auto sse3_ = x86_simd_info{}; - constexpr inline auto ssse3_ = x86_simd_info{}; - constexpr inline auto sse41_ = x86_simd_info{}; - constexpr inline auto sse42_ = x86_simd_info{}; - constexpr inline auto avx_ = x86_simd_info{}; - constexpr inline auto avx2_ = x86_simd_info{}; - constexpr inline auto avx512_ = x86_simd_info{}; + constexpr inline auto sse1_ = x86_simd_info<_::simd_version::sse1_ >{}; + constexpr inline auto sse2_ = x86_simd_info<_::simd_version::sse2_ >{}; + constexpr inline auto sse3_ = x86_simd_info<_::simd_version::sse3_ >{}; + constexpr inline auto ssse3_ = x86_simd_info<_::simd_version::ssse3_ >{}; + constexpr inline auto sse41_ = x86_simd_info<_::simd_version::sse41_ >{}; + constexpr inline auto sse42_ = x86_simd_info<_::simd_version::sse42_ >{}; + constexpr inline auto avx_ = x86_simd_info<_::simd_version::avx_ >{}; + constexpr inline auto avx2_ = x86_simd_info<_::simd_version::avx2_ >{}; + constexpr inline auto avx512_ = x86_simd_info<_::simd_version::avx512_ >{}; - template - using ppc_simd_info = detail::simd_info; + template<_::simd_version V = _::simd_version::undefined_> + using ppc_simd_info = _::simd_info<_::simd_isa::ppc_,V>; constexpr inline auto ppc_simd_ = ppc_simd_info<>{}; - constexpr inline auto vmx_ = ppc_simd_info{}; - constexpr inline auto vmx_2_03_ = ppc_simd_info{}; - constexpr inline auto vmx_2_05_ = ppc_simd_info{}; - constexpr inline auto vmx_2_06_ = ppc_simd_info{}; - constexpr inline auto vmx_2_07_ = ppc_simd_info{}; - constexpr inline auto vmx_3_00_ = ppc_simd_info{}; - constexpr inline auto vmx_3_01_ = ppc_simd_info{}; + constexpr inline auto vmx_ = ppc_simd_info<_::simd_version::vmx_>{}; + constexpr inline auto vmx_2_03_ = ppc_simd_info<_::simd_version::vmx_2_03_>{}; + constexpr inline auto vmx_2_05_ = ppc_simd_info<_::simd_version::vmx_2_05_>{}; + constexpr inline auto vmx_2_06_ = ppc_simd_info<_::simd_version::vmx_2_06_>{}; + constexpr inline auto vmx_2_07_ = ppc_simd_info<_::simd_version::vmx_2_07_>{}; + constexpr inline auto vmx_3_00_ = ppc_simd_info<_::simd_version::vmx_3_00_>{}; + constexpr inline auto vmx_3_01_ = ppc_simd_info<_::simd_version::vmx_3_01_>{}; - constexpr inline auto vsx_ = ppc_simd_info{}; - constexpr inline auto vsx_2_06_ = ppc_simd_info{}; - constexpr inline auto vsx_2_07_ = ppc_simd_info{}; - constexpr inline auto vsx_3_00_ = ppc_simd_info{}; - constexpr inline auto vsx_3_01_ = ppc_simd_info{}; + constexpr inline auto vsx_ = ppc_simd_info<_::simd_version::vsx_>{}; + constexpr inline auto vsx_2_06_ = ppc_simd_info<_::simd_version::vsx_2_06_>{}; + constexpr inline auto vsx_2_07_ = ppc_simd_info<_::simd_version::vsx_2_07_>{}; + constexpr inline auto vsx_3_00_ = ppc_simd_info<_::simd_version::vsx_3_00_>{}; + constexpr inline auto vsx_3_01_ = ppc_simd_info<_::simd_version::vsx_3_01_>{}; - template - using arm_simd_info = detail::simd_info; + template<_::simd_version V = _::simd_version::undefined_> + using arm_simd_info = _::simd_info<_::simd_isa::arm_,V>; - template - using sve_simd_info = detail::simd_info; + template<_::simd_version V = _::simd_version::undefined_> + using sve_simd_info = _::simd_info<_::simd_isa::arm_sve_,V>; constexpr inline auto arm_simd_ = arm_simd_info<>{}; - constexpr inline auto neon_ = arm_simd_info{}; - constexpr inline auto asimd_ = arm_simd_info{}; - constexpr inline auto sve_ = sve_simd_info{}; - constexpr inline auto fixed_sve_ = sve_simd_info{}; - constexpr inline auto sve2_ = sve_simd_info{}; - constexpr inline auto fixed_sve2_ = sve_simd_info{}; + constexpr inline auto neon_ = arm_simd_info<_::simd_version::neon_ >{}; + constexpr inline auto asimd_ = arm_simd_info<_::simd_version::asimd_>{}; + constexpr inline auto sve_ = sve_simd_info<_::simd_version::sve_>{}; + constexpr inline auto fixed_sve_ = sve_simd_info<_::simd_version::fixed_sve_>{}; + constexpr inline auto sve2_ = sve_simd_info<_::simd_version::sve2_>{}; + constexpr inline auto fixed_sve2_ = sve_simd_info<_::simd_version::fixed_sve2_>{}; - template - using riscv_simd_info = detail::simd_info; + template<_::simd_version V= _::simd_version::undefined_> + using riscv_simd_info = _::simd_info<_::simd_isa::riscv_, V>; constexpr inline auto riscv_simd_ = riscv_simd_info<> {}; - constexpr inline auto rvv_ = riscv_simd_info {}; - constexpr inline auto fixed_rvv_ = riscv_simd_info {}; + constexpr inline auto rvv_ = riscv_simd_info<_::simd_version::rvv_> {}; + constexpr inline auto fixed_rvv_ = riscv_simd_info<_::simd_version::fixed_rvv_> {}; } diff --git a/include/spy/simd/arm.hpp b/include/spy/simd/arm.hpp index f13e3aa..7ad21b0 100644 --- a/include/spy/simd/arm.hpp +++ b/include/spy/simd/arm.hpp @@ -11,21 +11,21 @@ // Flexible SVE2 has no SVE_BITS or SVE_BITS set at 0 and is set via -march=armv8-a+sve # if !defined(__ARM_FEATURE_SVE_BITS) || (__ARM_FEATURE_SVE_BITS == 0) # define SPY_SIMD_IS_ARM_FLEXIBLE_SVE2 -# define SPY_SIMD_DETECTED ::spy::detail::simd_version::sve2_ +# define SPY_SIMD_DETECTED ::spy::_::simd_version::sve2_ // Fixed-size SVE has SVE_BITS set at expected size via -msve-vector-bits # elif defined(__ARM_FEATURE_SVE_BITS) # if(__ARM_FEATURE_SVE_BITS == 128) # define SPY_SIMD_IS_ARM_FIXED_SVE2 -# define SPY_SIMD_DETECTED ::spy::detail::simd_version::fixed_sve2_ +# define SPY_SIMD_DETECTED ::spy::_::simd_version::fixed_sve2_ # elif(__ARM_FEATURE_SVE_BITS == 256) # define SPY_SIMD_IS_ARM_FIXED_SVE2 -# define SPY_SIMD_DETECTED ::spy::detail::simd_version::fixed_sve2_ +# define SPY_SIMD_DETECTED ::spy::_::simd_version::fixed_sve2_ # elif(__ARM_FEATURE_SVE_BITS == 512) # define SPY_SIMD_IS_ARM_FIXED_SVE2 -# define SPY_SIMD_DETECTED ::spy::detail::simd_version::fixed_sve2_ +# define SPY_SIMD_DETECTED ::spy::_::simd_version::fixed_sve2_ # elif(__ARM_FEATURE_SVE_BITS == 1024) # define SPY_SIMD_IS_ARM_FIXED_SVE2 -# define SPY_SIMD_DETECTED ::spy::detail::simd_version::fixed_sve2_ +# define SPY_SIMD_DETECTED ::spy::_::simd_version::fixed_sve2_ # else # error "[SPY] - No support for non-power of 2 SVE-2 cardinals" # endif @@ -36,21 +36,21 @@ // Flexible SVE has no SVE_BITS or SVE_BITS set at 0 and is set via -march=armv8-a+sve # if !defined(__ARM_FEATURE_SVE_BITS) || (__ARM_FEATURE_SVE_BITS == 0) # define SPY_SIMD_IS_ARM_FLEXIBLE_SVE -# define SPY_SIMD_DETECTED ::spy::detail::simd_version::sve_ +# define SPY_SIMD_DETECTED ::spy::_::simd_version::sve_ // Fixed-size SVE has SVE_BITS set at expected size via -msve-vector-bits # elif defined(__ARM_FEATURE_SVE_BITS) # if(__ARM_FEATURE_SVE_BITS == 128) # define SPY_SIMD_IS_ARM_FIXED_SVE -# define SPY_SIMD_DETECTED ::spy::detail::simd_version::fixed_sve_ +# define SPY_SIMD_DETECTED ::spy::_::simd_version::fixed_sve_ # elif(__ARM_FEATURE_SVE_BITS == 256) # define SPY_SIMD_IS_ARM_FIXED_SVE -# define SPY_SIMD_DETECTED ::spy::detail::simd_version::fixed_sve_ +# define SPY_SIMD_DETECTED ::spy::_::simd_version::fixed_sve_ # elif(__ARM_FEATURE_SVE_BITS == 512) # define SPY_SIMD_IS_ARM_FIXED_SVE -# define SPY_SIMD_DETECTED ::spy::detail::simd_version::fixed_sve_ +# define SPY_SIMD_DETECTED ::spy::_::simd_version::fixed_sve_ # elif(__ARM_FEATURE_SVE_BITS == 1024) # define SPY_SIMD_IS_ARM_FIXED_SVE -# define SPY_SIMD_DETECTED ::spy::detail::simd_version::fixed_sve_ +# define SPY_SIMD_DETECTED ::spy::_::simd_version::fixed_sve_ # else # error "[SPY] - No support for non-power of 2 SVE cardinals" # endif @@ -59,23 +59,23 @@ #if defined(__ARM_FEATURE_SVE2) # define SPY_SIMD_IS_ARM_SVE2 -# define SPY_SIMD_VENDOR ::spy::detail::simd_isa::arm_sve_ +# define SPY_SIMD_VENDOR ::spy::_::simd_isa::arm_sve_ #elif defined(__ARM_FEATURE_SVE) # define SPY_SIMD_IS_ARM_SVE -# define SPY_SIMD_VENDOR ::spy::detail::simd_isa::arm_sve_ +# define SPY_SIMD_VENDOR ::spy::_::simd_isa::arm_sve_ #endif #if !defined(SPY_SIMD_DETECTED) && defined(__aarch64__) # define SPY_SIMD_IS_ARM_ASIMD -# define SPY_SIMD_DETECTED ::spy::detail::simd_version::asimd_ +# define SPY_SIMD_DETECTED ::spy::_::simd_version::asimd_ #endif #if !defined(SPY_SIMD_DETECTED) && ((defined(__ARM_NEON__) || defined(_M_ARM)) && (__ARM_ARCH == 7)) # define SPY_SIMD_IS_ARM_NEON -# define SPY_SIMD_DETECTED ::spy::detail::simd_version::neon_ +# define SPY_SIMD_DETECTED ::spy::_::simd_version::neon_ #endif #if defined(SPY_SIMD_DETECTED) && !defined(SPY_SIMD_VENDOR) # define SPY_SIMD_IS_ARM -# define SPY_SIMD_VENDOR ::spy::detail::simd_isa::arm_ +# define SPY_SIMD_VENDOR ::spy::_::simd_isa::arm_ #endif diff --git a/include/spy/simd/ppc.hpp b/include/spy/simd/ppc.hpp index 82a1c21..0aea16c 100644 --- a/include/spy/simd/ppc.hpp +++ b/include/spy/simd/ppc.hpp @@ -11,16 +11,16 @@ # define SPY_SIMD_IS_PPC_VSX # if defined(_ARCH_PWR10) # define SPY_SIMD_IS_PPC_VSX_3_01 -# define SPY_SIMD_DETECTED ::spy::detail::simd_version::vsx_3_01_ +# define SPY_SIMD_DETECTED ::spy::_::simd_version::vsx_3_01_ # elif defined(_ARCH_PWR9) # define SPY_SIMD_IS_PPC_VSX_3_00 -# define SPY_SIMD_DETECTED ::spy::detail::simd_version::vsx_3_00_ +# define SPY_SIMD_DETECTED ::spy::_::simd_version::vsx_3_00_ # elif defined(_ARCH_PWR8) # define SPY_SIMD_IS_PPC_VSX_2_07 -# define SPY_SIMD_DETECTED ::spy::detail::simd_version::vsx_2_07_ +# define SPY_SIMD_DETECTED ::spy::_::simd_version::vsx_2_07_ # elif defined(_ARCH_PWR7) # define SPY_SIMD_IS_PPC_VSX_2_06 -# define SPY_SIMD_DETECTED ::spy::detail::simd_version::vsx_2_06_ +# define SPY_SIMD_DETECTED ::spy::_::simd_version::vsx_2_06_ # endif #endif @@ -28,27 +28,27 @@ # define SPY_SIMD_IS_PPC_VMX # if defined(_ARCH_PWR10) # define SPY_SIMD_IS_PPC_VMX_3_01 -# define SPY_SIMD_DETECTED ::spy::detail::simd_version::vmx_3_01_ +# define SPY_SIMD_DETECTED ::spy::_::simd_version::vmx_3_01_ # elif defined(_ARCH_PWR9) # define SPY_SIMD_IS_PPC_VMX_3_00 -# define SPY_SIMD_DETECTED ::spy::detail::simd_version::vmx_3_00_ +# define SPY_SIMD_DETECTED ::spy::_::simd_version::vmx_3_00_ # elif defined(_ARCH_PWR8) # define SPY_SIMD_IS_PPC_VMX_2_07 -# define SPY_SIMD_DETECTED ::spy::detail::simd_version::vmx_2_07_ +# define SPY_SIMD_DETECTED ::spy::_::simd_version::vmx_2_07_ # elif defined(_ARCH_PWR7) # define SPY_SIMD_IS_PPC_VMX_2_06 -# define SPY_SIMD_DETECTED ::spy::detail::simd_version::vmx_2_06_ +# define SPY_SIMD_DETECTED ::spy::_::simd_version::vmx_2_06_ # elif defined(_ARCH_PWR6) # define SPY_SIMD_IS_PPC_VMX_2_05 -# define SPY_SIMD_DETECTED ::spy::detail::simd_version::vmx_2_05_ +# define SPY_SIMD_DETECTED ::spy::_::simd_version::vmx_2_05_ # elif defined(_ARCH_PWR5) # define SPY_SIMD_IS_PPC_VMX_2_03 -# define SPY_SIMD_DETECTED ::spy::detail::simd_version::vmx_2_03_ +# define SPY_SIMD_DETECTED ::spy::_::simd_version::vmx_2_03_ # endif -# define SPY_SIMD_DETECTED ::spy::detail::simd_version::vmx_ +# define SPY_SIMD_DETECTED ::spy::_::simd_version::vmx_ #endif #if defined(SPY_SIMD_DETECTED) && !defined(SPY_SIMD_VENDOR) # define SPY_SIMD_IS_PPC -# define SPY_SIMD_VENDOR ::spy::detail::simd_isa::ppc_ +# define SPY_SIMD_VENDOR ::spy::_::simd_isa::ppc_ #endif diff --git a/include/spy/simd/riscv.hpp b/include/spy/simd/riscv.hpp index fc9fa5d..6d9a410 100644 --- a/include/spy/simd/riscv.hpp +++ b/include/spy/simd/riscv.hpp @@ -11,15 +11,15 @@ // Flexible RISC-V Vector has no __riscv_v_fixed_vlen defined # if !defined(__riscv_v_fixed_vlen) # define SPY_SIMD_IS_RISCV_FLEXIBLE_RVV -# define SPY_SIMD_DETECTED ::spy::detail::simd_version::rvv_ +# define SPY_SIMD_DETECTED ::spy::_::simd_version::rvv_ // Fixed-size RISC-V Vector has __riscv_v_fixed_vlen #else # define SPY_SIMD_IS_RISCV_FIXED_RVV -# define SPY_SIMD_DETECTED ::spy::detail::simd_version::fixed_rvv_ +# define SPY_SIMD_DETECTED ::spy::_::simd_version::fixed_rvv_ #endif #endif #if defined(__riscv_vector) # define SPY_SIMD_IS_RISCV_RVV -# define SPY_SIMD_VENDOR ::spy::detail::simd_isa::riscv_ +# define SPY_SIMD_VENDOR ::spy::_::simd_isa::riscv_ #endif diff --git a/include/spy/simd/wasm.hpp b/include/spy/simd/wasm.hpp index 6bfdc5f..10b7480 100644 --- a/include/spy/simd/wasm.hpp +++ b/include/spy/simd/wasm.hpp @@ -8,10 +8,10 @@ #pragma once #if !defined(SPY_SIMD_DETECTED) && defined(__wasm_simd128__) -# define SPY_SIMD_DETECTED ::spy::detail::simd_version::simd128_ +# define SPY_SIMD_DETECTED ::spy::_::simd_version::simd128_ #endif #if defined(SPY_SIMD_DETECTED) && !defined(SPY_SIMD_VENDOR) # define SPY_SIMD_IS_WASM -# define SPY_SIMD_VENDOR ::spy::detail::simd_isa::wasm_ +# define SPY_SIMD_VENDOR ::spy::_::simd_isa::wasm_ #endif diff --git a/include/spy/simd/x86.hpp b/include/spy/simd/x86.hpp index 79bba34..0f1793e 100644 --- a/include/spy/simd/x86.hpp +++ b/include/spy/simd/x86.hpp @@ -8,7 +8,7 @@ #pragma once #if !defined(SPY_SIMD_DETECTED) && defined(__AVX512F__) # define SPY_SIMD_IS_X86_AVX512 -# define SPY_SIMD_DETECTED ::spy::detail::simd_version::avx512_ +# define SPY_SIMD_DETECTED ::spy::_::simd_version::avx512_ #if defined(__AVX512BW__) # define SPY_SIMD_IS_X86_AVX512_BW @@ -78,47 +78,47 @@ #if !defined(SPY_SIMD_DETECTED) && defined(__AVX2__) # define SPY_SIMD_IS_X86_AVX2 -# define SPY_SIMD_DETECTED ::spy::detail::simd_version::avx2_ +# define SPY_SIMD_DETECTED ::spy::_::simd_version::avx2_ #endif #if !defined(SPY_SIMD_DETECTED) && defined(__AVX__) # define SPY_SIMD_IS_X86_AVX -# define SPY_SIMD_DETECTED ::spy::detail::simd_version::avx_ +# define SPY_SIMD_DETECTED ::spy::_::simd_version::avx_ #endif #if !defined(SPY_SIMD_DETECTED) && defined(__SSE4_2__) # define SPY_SIMD_IS_X86_SSE4_2 -# define SPY_SIMD_DETECTED ::spy::detail::simd_version::sse42_ +# define SPY_SIMD_DETECTED ::spy::_::simd_version::sse42_ #endif #if !defined(SPY_SIMD_DETECTED) && defined(__SSE4_1__) # define SPY_SIMD_IS_X86_SSE4_1 -# define SPY_SIMD_DETECTED ::spy::detail::simd_version::sse41_ +# define SPY_SIMD_DETECTED ::spy::_::simd_version::sse41_ #endif #if !defined(SPY_SIMD_DETECTED) && defined(__SSSE3__) # define SPY_SIMD_IS_X86_SSSE3 -# define SPY_SIMD_DETECTED ::spy::detail::simd_version::ssse3_ +# define SPY_SIMD_DETECTED ::spy::_::simd_version::ssse3_ #endif #if !defined(SPY_SIMD_DETECTED) && defined(__SSE3__) # define SPY_SIMD_IS_X86_SSE3 -# define SPY_SIMD_DETECTED ::spy::detail::simd_version::sse3_ +# define SPY_SIMD_DETECTED ::spy::_::simd_version::sse3_ #endif #if !defined(SPY_SIMD_DETECTED) && (defined(__SSE2__) || defined(_M_X64) || (defined(_M_IX86_FP) && _M_IX86_FP >= 2)) # define SPY_SIMD_IS_X86_SSE2 -# define SPY_SIMD_DETECTED ::spy::detail::simd_version::sse2_ +# define SPY_SIMD_DETECTED ::spy::_::simd_version::sse2_ #endif #if !defined(SPY_SIMD_DETECTED) && (defined(__SSE__) || defined(_M_IX86_FP)) # define SPY_SIMD_IS_X86_SSE -# define SPY_SIMD_DETECTED ::spy::detail::simd_version::sse1_ +# define SPY_SIMD_DETECTED ::spy::_::simd_version::sse1_ #endif #if defined(SPY_SIMD_DETECTED) && !defined(SPY_SIMD_VENDOR) # define SPY_SIMD_IS_X86 -# define SPY_SIMD_VENDOR ::spy::detail::simd_isa::x86_ +# define SPY_SIMD_VENDOR ::spy::_::simd_isa::x86_ #endif namespace spy::supports diff --git a/include/spy/spy.hpp b/include/spy/spy.hpp index 29ae416..356da73 100644 --- a/include/spy/spy.hpp +++ b/include/spy/spy.hpp @@ -31,7 +31,7 @@ namespace spy namespace literal {} } - +#include #include #include #include diff --git a/include/spy/stdlib.hpp b/include/spy/stdlib.hpp index c724a8c..90b4dd2 100644 --- a/include/spy/stdlib.hpp +++ b/include/spy/stdlib.hpp @@ -11,7 +11,7 @@ #include #include -namespace spy::detail +namespace spy::_ { enum class stdlib { undefined_ = - 1, libcpp_, gnucpp_ }; @@ -31,8 +31,8 @@ namespace spy::detail SPY_VERSION_COMPARISONS_OPERATOR(stdlib,stdlib_info) }; - template - std::ostream& operator<<(std::ostream& os, stdlib_info const& p) + template<_::stream OS, stdlib SLib, int M, int N, int P> + OS& operator<<(OS& os, stdlib_info const& p) { if(SLib == stdlib::libcpp_) return os << "libc++ Standard C++ Library " << p.version ; if(SLib == stdlib::gnucpp_) return os << "GNU Standard C++ Library " << p.version; @@ -48,15 +48,15 @@ namespace spy { #if defined(_LIBCPP_VERSION) #define SPY_STDLIB_IS_LIBCPP - using stdlib_type = detail::libcpp_t<(_LIBCPP_VERSION/1000)%10,0,_LIBCPP_VERSION%1000>; + using stdlib_type = _::libcpp_t<(_LIBCPP_VERSION/1000)%10,0,_LIBCPP_VERSION%1000>; #elif defined(__GLIBCXX__) #define SPY_STDLIB_IS_GLIBCXX #define SPY0 (__GLIBCXX__/100) - using stdlib_type = detail::gnucpp_t<(SPY0/100)%10000, SPY0%100, __GLIBCXX__%100>; + using stdlib_type = _::gnucpp_t<(SPY0/100)%10000, SPY0%100, __GLIBCXX__%100>; #undef SPY0 #else #define SPY_STDLIB_IS_UNKNOWN - using stdlib_type = detail::stdlib_info; + using stdlib_type = _::stdlib_info<_::stdlib::undefined_,-1,0,0>; #endif //================================================================================================ @@ -85,7 +85,7 @@ namespace spy constexpr inline auto stdlib = stdlib_type{}; } -namespace spy::detail +namespace spy::_ { template inline constexpr stdlib_info::operator bool() const noexcept @@ -99,19 +99,19 @@ namespace spy //================================================================================================ // STDLIBs detector stand-alone instances //================================================================================================ - constexpr inline auto libcpp_ = detail::libcpp_t<-1,0,0>{}; - constexpr inline auto gnucpp_ = detail::gnucpp_t<-1,0,0>{}; + constexpr inline auto libcpp_ = _::libcpp_t<-1,0,0>{}; + constexpr inline auto gnucpp_ = _::gnucpp_t<-1,0,0>{}; } namespace spy::literal { template constexpr auto operator"" _libcpp() { - return detail::literal_wrap(); + return _::literal_wrap<_::libcpp_t,c...>(); } template constexpr auto operator"" _gnucpp() { - return detail::literal_wrap(); + return _::literal_wrap<_::gnucpp_t,c...>(); } } diff --git a/standalone/spy/spy.hpp b/standalone/spy/spy.hpp index 6a80365..b76d0cd 100644 --- a/standalone/spy/spy.hpp +++ b/standalone/spy/spy.hpp @@ -27,148 +27,15 @@ namespace spy //==================================================================================================================== namespace literal {} } -#include -namespace spy::supports -{ - template struct sycl_t - { - explicit constexpr operator bool() const noexcept { return M>0 && N>0; } - friend std::ostream& operator<<(std::ostream& os, sycl_t) - { - os << "SYCL v" << M << '.' << N; - if(P>0) os << '.' << P; - return os; - } - }; - template - constexpr inline bool operator==(sycl_t const&, sycl_t const&) noexcept - { - return M0==M1 && N0==N1 && P0==P1; - } - template - constexpr inline bool operator!=(sycl_t const& a, sycl_t const& b) noexcept - { - return !(a==b); - } - template struct cuda_t - { - explicit constexpr operator bool() const noexcept { return M>0 && N>0; } - friend std::ostream& operator<<(std::ostream& os, cuda_t) - { - os << "NVCC CUDA v" << M << '.' << N; - if(P>0) os << '.' << P; - return os; - } - }; - template - constexpr inline bool operator==(cuda_t const&, cuda_t const&) noexcept - { - return M0==M1 && N0==N1 && P0==P1; - } - template - constexpr inline bool operator!=(cuda_t const& a, cuda_t const& b) noexcept - { - return !(a==b); - } -#if defined(SYCL_LANGUAGE_VERSION) && defined (__INTEL_LLVM_COMPILER) -# define SPY_ACCELERATOR_SUPPORTS_SYCL - constexpr inline auto sycl = sycl_t{}; -#elif defined(SPY_DOXYGEN_INVOKED) - constexpr inline auto sycl = **implementation-defined**; -#else - constexpr inline auto sycl = sycl_t<-1,-1,-1>{}; -#endif -#if defined(__CUDACC__) -# define SPY_ACCELERATOR_SUPPORTS_CUDA - constexpr inline auto cuda = cuda_t<__CUDACC_VER_MAJOR__, __CUDACC_VER_MINOR__, 0>{}; -#elif defined(SPY_DOXYGEN_INVOKED) - constexpr inline auto cuda = **implementation-defined**; -#else - constexpr inline auto cuda = cuda_t<-1,-1,-1>{}; -#endif -} -#include -namespace spy::detail +namespace spy::_ { - enum class archs { undefined_ = -1 - , x86_ = 10, amd64_ = 11 - , ppc_ = 20, arm_ = 30 - , wasm_ = 40 - , riscv_ = 50 - }; - template struct arch_info + template + concept stream = requires(T& os, char c) { - static constexpr archs vendor = Arch; - inline constexpr explicit operator bool() const noexcept; - template - constexpr bool operator==(arch_info const&) const noexcept - { - return A2 == vendor; - } + { os.copyfmt(os) }; + { os.flush() }; + { os.put(c) }; }; - template - std::ostream& operator<<(std::ostream& os, arch_info const&) - { - if(Arch == archs::x86_ ) return os << "X86"; - if(Arch == archs::amd64_) return os << "AMD64"; - if(Arch == archs::ppc_ ) return os << "PowerPC"; - if(Arch == archs::arm_ ) return os << "ARM"; - if(Arch == archs::wasm_ ) return os << "WebAssembly"; - if(Arch == archs::riscv_) return os << "RISC-V"; - return os << "Undefined Architecture"; - } -} -namespace spy -{ -#if defined(i386) || defined(__i386__) || defined(__i486__) || defined(__i586__) || \ - defined(__i686__) || defined(__i386) || defined(_M_IX86) || defined(_X86_) || \ - defined(__THW_INTEL__) || defined(__I86__) || defined(__INTEL__) - using arch_type = detail::arch_info; - #define SPY_ARCH_IS_X86 -#elif defined(__x86_64) || defined(__x86_64__) || defined(__amd64__) || defined(__amd64) || defined(_M_X64) - #define SPY_ARCH_IS_AMD64 - using arch_type = detail::arch_info; -#elif defined(__powerpc) || defined(__powerpc__) || defined(__POWERPC__) || defined(__ppc__) || \ - defined(_M_PPC) || defined(_ARCH_PPC) || defined(__PPCGECKO__) || defined(__PPCBROADWAY__) || \ - defined(_XENON) - using arch_type = detail::arch_info; - #define SPY_ARCH_IS_PPC -#elif defined(__arm__) || defined(__arm64) || defined(__thumb__) || defined(__TARGET_ARCH_ARM) || \ - defined(__TARGET_ARCH_THUMB) || defined(_M_ARM) || defined(__ARM_ARCH_ISA_A64) - using arch_type = detail::arch_info; - #define SPY_ARCH_IS_ARM -#elif defined(__wasm__) - using arch_type = detail::arch_info; - #define SPY_ARCH_IS_WASM -#elif defined(__riscv) - using arch_type = detail::arch_info; - #define SPY_ARCH_IS_RISCV -#else - #define SPY_ARCH_IS_UNKNOWN - using arch_type = detail::arch_info; -#endif - constexpr inline arch_type architecture; -} -namespace spy::detail -{ - template - inline constexpr arch_info::operator bool() const noexcept - { - return spy::architecture == *this; - } -} -namespace spy -{ - constexpr inline auto x86_ = detail::arch_info{}; - constexpr inline auto amd64_ = detail::arch_info{}; - constexpr inline auto ppc_ = detail::arch_info{}; - constexpr inline auto arm_ = detail::arch_info{}; - constexpr inline auto wasm_ = detail::arch_info{}; - constexpr inline auto riscv_ = detail::arch_info{}; -} -#include -namespace spy::detail -{ template constexpr int find(int i0) { int sz = sizeof...(c); @@ -237,12 +104,13 @@ namespace spy::detail { return !(a - std::ostream& operator<<(std::ostream& os, version_id const&) + template<_::stream OS, int M, int N, int P> + OS& operator<<(OS& os, version_id const&) { return os << "v" << M << "." << N << "." << P; } - inline std::ostream& operator<<(std::ostream& os, unspecified_version_t const&) + template<_::stream OS> + OS& operator<<(OS& os, unspecified_version_t const&) { return os << "(unspecified)"; } @@ -284,12 +152,151 @@ constexpr bool operator<=( TYPE const& c2 ) const noexcept \ return C2 == vendor && version <= c2.version; \ } \ +namespace spy::supports +{ + template struct sycl_t + { + explicit constexpr operator bool() const noexcept { return M>0 && N>0; } + template<_::stream OS> + friend OS& operator<<(OS& os, sycl_t) + { + os << "SYCL v" << M << '.' << N; + if(P>0) os << '.' << P; + return os; + } + }; + template + constexpr inline bool operator==(sycl_t const&, sycl_t const&) noexcept + { + return M0==M1 && N0==N1 && P0==P1; + } + template + constexpr inline bool operator!=(sycl_t const& a, sycl_t const& b) noexcept + { + return !(a==b); + } + template struct cuda_t + { + explicit constexpr operator bool() const noexcept { return M>0 && N>0; } + template<_::stream OS> + friend OS& operator<<(OS& os, cuda_t) + { + os << "NVCC CUDA v" << M << '.' << N; + if(P>0) os << '.' << P; + return os; + } + }; + template + constexpr inline bool operator==(cuda_t const&, cuda_t const&) noexcept + { + return M0==M1 && N0==N1 && P0==P1; + } + template + constexpr inline bool operator!=(cuda_t const& a, cuda_t const& b) noexcept + { + return !(a==b); + } +#if defined(SYCL_LANGUAGE_VERSION) && defined (__INTEL_LLVM_COMPILER) +# define SPY_ACCELERATOR_SUPPORTS_SYCL + constexpr inline auto sycl = sycl_t{}; +#elif defined(SPY_DOXYGEN_INVOKED) + constexpr inline auto sycl = **implementation-defined**; +#else + constexpr inline auto sycl = sycl_t<-1,-1,-1>{}; +#endif +#if defined(__CUDACC__) +# define SPY_ACCELERATOR_SUPPORTS_CUDA + constexpr inline auto cuda = cuda_t<__CUDACC_VER_MAJOR__, __CUDACC_VER_MINOR__, 0>{}; +#elif defined(SPY_DOXYGEN_INVOKED) + constexpr inline auto cuda = **implementation-defined**; +#else + constexpr inline auto cuda = cuda_t<-1,-1,-1>{}; +#endif +} +namespace spy::_ +{ + enum class archs { undefined_ = -1 + , x86_ = 10, amd64_ = 11 + , ppc_ = 20, arm_ = 30 + , wasm_ = 40 + , riscv_ = 50 + }; + template struct arch_info + { + static constexpr archs vendor = Arch; + inline constexpr explicit operator bool() const noexcept; + template + constexpr bool operator==(arch_info const&) const noexcept + { + return A2 == vendor; + } + template<_::stream OS> + friend OS& operator<<(OS& os, arch_info const&) + { + if(Arch == archs::x86_ ) return os << "X86"; + if(Arch == archs::amd64_) return os << "AMD64"; + if(Arch == archs::ppc_ ) return os << "PowerPC"; + if(Arch == archs::arm_ ) return os << "ARM"; + if(Arch == archs::wasm_ ) return os << "WebAssembly"; + if(Arch == archs::riscv_) return os << "RISC-V"; + return os << "Undefined Architecture"; + } + }; +} +namespace spy +{ +#if defined(i386) || defined(__i386__) || defined(__i486__) || defined(__i586__) || \ + defined(__i686__) || defined(__i386) || defined(_M_IX86) || defined(_X86_) || \ + defined(__THW_INTEL__) || defined(__I86__) || defined(__INTEL__) + using arch_type = _::arch_info<_::archs::x86_>; + #define SPY_ARCH_IS_X86 +#elif defined(__x86_64) || defined(__x86_64__) || defined(__amd64__) || defined(__amd64) || defined(_M_X64) + #define SPY_ARCH_IS_AMD64 + using arch_type = _::arch_info<_::archs::amd64_>; +#elif defined(__powerpc) || defined(__powerpc__) || defined(__POWERPC__) || defined(__ppc__) || \ + defined(_M_PPC) || defined(_ARCH_PPC) || defined(__PPCGECKO__) || defined(__PPCBROADWAY__) || \ + defined(_XENON) + using arch_type = _::arch_info<_::archs::ppc_>; + #define SPY_ARCH_IS_PPC +#elif defined(__arm__) || defined(__arm64) || defined(__thumb__) || defined(__TARGET_ARCH_ARM) || \ + defined(__TARGET_ARCH_THUMB) || defined(_M_ARM) || defined(__ARM_ARCH_ISA_A64) + using arch_type = _::arch_info<_::archs::arm_>; + #define SPY_ARCH_IS_ARM +#elif defined(__wasm__) + using arch_type = _::arch_info<_::archs::wasm_>; + #define SPY_ARCH_IS_WASM +#elif defined(__riscv) + using arch_type = _::arch_info<_::archs::riscv_>; + #define SPY_ARCH_IS_RISCV +#else + #define SPY_ARCH_IS_UNKNOWN + using arch_type = _::arch_info<_::archs::undefined_>; +#endif + constexpr inline arch_type architecture; +} +namespace spy::_ +{ + template + inline constexpr arch_info::operator bool() const noexcept + { + return spy::architecture == *this; + } +} +namespace spy +{ + constexpr inline auto x86_ = _::arch_info<_::archs::x86_>{}; + constexpr inline auto amd64_ = _::arch_info<_::archs::amd64_>{}; + constexpr inline auto ppc_ = _::arch_info<_::archs::ppc_>{}; + constexpr inline auto arm_ = _::arch_info<_::archs::arm_>{}; + constexpr inline auto wasm_ = _::arch_info<_::archs::wasm_>{}; + constexpr inline auto riscv_ = _::arch_info<_::archs::riscv_>{}; +} #if defined __has_include # if __has_include () # include # endif #endif -namespace spy::detail +namespace spy::_ { enum class compilers { undefined_ = - 1, msvc_, intel_, clang_, gcc_, emscripten_, dpcpp_, nvcc_ }; template struct compilers_info @@ -304,8 +311,8 @@ namespace spy::detail } SPY_VERSION_COMPARISONS_OPERATOR(compilers,compilers_info) }; - template - std::ostream& operator<<(std::ostream& os, compilers_info const& c) + template<_::stream OS, compilers C, int M, int N, int P> + OS& operator<<(OS& os, compilers_info const& c) { if(C == compilers::nvcc_ ) return os << "NVIDIA CUDA Compiler " << c.version; if(C == compilers::msvc_ ) return os << "Microsoft Visual Studio " << c.version; @@ -328,37 +335,37 @@ namespace spy { #if defined(__NVCC__) #define SPY_COMPILER_IS_NVCC - using compiler_type = detail::nvcc_t<__CUDACC_VER_MAJOR__, __CUDACC_VER_MINOR__, 0>; + using compiler_type = _::nvcc_t<__CUDACC_VER_MAJOR__, __CUDACC_VER_MINOR__, 0>; #elif defined(_MSC_VER) #define SPY_COMPILER_IS_MSVC - using compiler_type = detail::msvc_t<_MSC_VER / 100, _MSC_VER % 100, _MSC_FULL_VER % 100000>; + using compiler_type = _::msvc_t<_MSC_VER / 100, _MSC_VER % 100, _MSC_FULL_VER % 100000>; #elif defined(__INTEL_LLVM_COMPILER) #define SPY_COMPILER_IS_INTEL_DPCPP #define SPY0 __INTEL_LLVM_COMPILER - using compiler_type = detail::dpcpp_t; + using compiler_type = _::dpcpp_t; #undef SPY0 #elif defined(__INTEL_COMPILER) || defined(__ICL) || defined(__ICC) || defined(__ECC) #define SPY_COMPILER_IS_INTEL #define SPY0 __INTEL_COMPILER - using compiler_type = detail::intel_t<(SPY0 / 100) % 100,SPY0 % 100, __INTEL_COMPILER_UPDATE>; + using compiler_type = _::intel_t<(SPY0 / 100) % 100,SPY0 % 100, __INTEL_COMPILER_UPDATE>; #undef SPY0 #elif defined(__EMSCRIPTEN__) #define SPY_COMPILER_IS_CLANG - using compiler_type = detail::emscripten_t<__EMSCRIPTEN_major__, __EMSCRIPTEN_minor__, __EMSCRIPTEN_tiny__ >; + using compiler_type = _::emscripten_t<__EMSCRIPTEN_major__, __EMSCRIPTEN_minor__, __EMSCRIPTEN_tiny__ >; #undef SPY0 #elif defined(__clang__) #define SPY_COMPILER_IS_CLANG - using compiler_type = detail::clang_t<__clang_major__, __clang_minor__, __clang_patchlevel__>; + using compiler_type = _::clang_t<__clang_major__, __clang_minor__, __clang_patchlevel__>; #elif defined(__GNUC__) #define SPY_COMPILER_IS_GCC - using compiler_type = detail::gcc_t<__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__>; + using compiler_type = _::gcc_t<__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__>; #else #define SPY_COMPILER_IS_UNKNOWN - using compiler_type = detail::compilers_info; + using compiler_type = _::compilers_info; #endif constexpr inline compiler_type compiler; } -namespace spy::detail +namespace spy::_ { template inline constexpr compilers_info::operator bool() const noexcept @@ -368,46 +375,46 @@ namespace spy::detail } namespace spy { - constexpr inline auto nvcc_ = detail::nvcc_t<-1,0,0>{}; - constexpr inline auto msvc_ = detail::msvc_t<-1,0,0>{}; - constexpr inline auto intel_ = detail::intel_t<-1,0,0>{}; - constexpr inline auto dpcpp_ = detail::dpcpp_t<-1,0,0>{}; - constexpr inline auto clang_ = detail::clang_t<-1,0,0>{}; - constexpr inline auto gcc_ = detail::gcc_t<-1,0,0>{}; - constexpr inline auto emscripten_ = detail::emscripten_t<-1,0,0>{}; + constexpr inline auto nvcc_ = _::nvcc_t<-1,0,0>{}; + constexpr inline auto msvc_ = _::msvc_t<-1,0,0>{}; + constexpr inline auto intel_ = _::intel_t<-1,0,0>{}; + constexpr inline auto dpcpp_ = _::dpcpp_t<-1,0,0>{}; + constexpr inline auto clang_ = _::clang_t<-1,0,0>{}; + constexpr inline auto gcc_ = _::gcc_t<-1,0,0>{}; + constexpr inline auto emscripten_ = _::emscripten_t<-1,0,0>{}; } namespace spy::literal { template constexpr auto operator"" _nvcc() { - return detail::literal_wrap(); + return _::literal_wrap<_::nvcc_t,c...>(); } template constexpr auto operator"" _msvc() { - return detail::literal_wrap(); + return _::literal_wrap<_::msvc_t,c...>(); } template constexpr auto operator"" _intel() { - return detail::literal_wrap(); + return _::literal_wrap<_::intel_t,c...>(); } template constexpr auto operator"" _dpcpp() { - return detail::literal_wrap(); + return _::literal_wrap<_::dpcpp_t,c...>(); } template constexpr auto operator"" _clang() { - return detail::literal_wrap(); + return _::literal_wrap<_::clang_t,c...>(); } template constexpr auto operator"" _gcc() { - return detail::literal_wrap(); + return _::literal_wrap<_::gcc_t,c...>(); } template constexpr auto operator"" _em() { - return detail::literal_wrap(); + return _::literal_wrap<_::emscripten_t,c...>(); } } -namespace spy::detail +namespace spy::_ { template struct data_model_info @@ -419,8 +426,8 @@ namespace spy::detail return (Short==Short2) && (Integer == Integer2) && (Long == Long2) && (Pointer == Pointer2); } }; - template - std::ostream& operator<<(std::ostream& os, data_model_info const&) + template<_::stream OS, int Short, int Integer, int Long, int Pointer> + OS& operator<<(OS& os, data_model_info const&) { if constexpr(Pointer == 4 && Integer == 4) return os << "ILP32"; else if constexpr(Pointer == 4 && Integer == 2) return os << "LP32"; @@ -433,12 +440,12 @@ namespace spy::detail } namespace spy { - using data_model_type = detail::data_model_info < sizeof(short), sizeof(int) + using data_model_type = _::data_model_info < sizeof(short), sizeof(int) , sizeof(long), sizeof(void*) >; constexpr inline auto data_model = data_model_type{}; } -namespace spy::detail +namespace spy::_ { template inline constexpr data_model_info::operator bool() const noexcept @@ -448,15 +455,15 @@ namespace spy::detail } namespace spy { - constexpr inline auto ilp32_ = detail::data_model_info<2,4,sizeof(long),4>{}; - constexpr inline auto lp32_ = detail::data_model_info<2,2,sizeof(long),4>{}; - constexpr inline auto silp64_ = detail::data_model_info<8,8,8,8>{}; - constexpr inline auto ilp64_ = detail::data_model_info<2,8,8,8>{}; - constexpr inline auto llp64_ = detail::data_model_info<2,8,4,8>{}; - constexpr inline auto lp64_ = detail::data_model_info<2,4,8,8>{}; + constexpr inline auto ilp32_ = _::data_model_info<2,4,sizeof(long),4>{}; + constexpr inline auto lp32_ = _::data_model_info<2,2,sizeof(long),4>{}; + constexpr inline auto silp64_ = _::data_model_info<8,8,8,8>{}; + constexpr inline auto ilp64_ = _::data_model_info<2,8,8,8>{}; + constexpr inline auto llp64_ = _::data_model_info<2,8,4,8>{}; + constexpr inline auto lp64_ = _::data_model_info<2,4,8,8>{}; } #include -namespace spy::detail +namespace spy::_ { enum class libC { undefined_ = - 1, cloudabi_, uc_, vms_, zos_, gnu_ }; template struct libc_info @@ -471,8 +478,8 @@ namespace spy::detail } SPY_VERSION_COMPARISONS_OPERATOR(libC,libc_info) }; - template - std::ostream& operator<<(std::ostream& os, libc_info const& c) + template<_::stream OS, libC C, int M, int N, int P> + OS& operator<<(OS& os, libc_info const& c) { if(c.vendor == libC::cloudabi_) return os << "CloudABI Standard C Library " << c.version; if(c.vendor == libC::uc_ ) return os << "uClibc Standard C Library " << c.version; @@ -491,34 +498,34 @@ namespace spy { #if defined(__cloudlibc__) #define SPY_LIBC_IS_CLOUDABI - using libc_type = detail::cloudabi_t<__cloudlibc_major__,__cloudlibc_minor__,0>; + using libc_type = _::cloudabi_t<__cloudlibc_major__,__cloudlibc_minor__,0>; #elif defined(__GLIBC__) #define SPY_LIBC_IS_GNU - using libc_type = detail::gnu_t<__GLIBC__, __GLIBC_MINOR__, 0>; + using libc_type = _::gnu_t<__GLIBC__, __GLIBC_MINOR__, 0>; #elif defined(__GNU_LIBRARY__) #define SPY_LIBC_IS_GNU - using libc_type = detail::gnu_t<__GNU_LIBRARY__, __GNU_LIBRARY_MINOR__, 0>; + using libc_type = _::gnu_t<__GNU_LIBRARY__, __GNU_LIBRARY_MINOR__, 0>; #elif defined(__UCLIBC__) #define SPY_LIBC_IS_UCLIBC - using libc_type = detail::uc_t<__UCLIBC_MAJOR__, __UCLIBC_MINOR__, __UCLIBC_SUBLEVEL__>; + using libc_type = _::uc_t<__UCLIBC_MAJOR__, __UCLIBC_MINOR__, __UCLIBC_SUBLEVEL__>; #elif defined(__CRTL_VER) #define SPY_LIBC_IS_VMS #define SPY0 (__CRTL_VER/100) - using libc_type = detail::vms_t<(SPY0/100000)%100, (SPY0/1000)%100, (SPY0)%100>; + using libc_type = _::vms_t<(SPY0/100000)%100, (SPY0/1000)%100, (SPY0)%100>; #undef SPY0 #elif defined(__LIBREL__) #define SPY_LIBC_IS_ZOS - using libc_type = detail::zos_t < (__LIBREL__&0xF000000)>>24 + using libc_type = _::zos_t < (__LIBREL__&0xF000000)>>24 , (__LIBREL__&0xFF0000)>>16 , (__LIBREL__&0xFFFF) >; #else #define SPY_LIBC_IS_UNKNOWN - using libc_type = detail::libc_info; + using libc_type = _::libc_info<_::libC::undefined_,-1,0,0>; #endif constexpr inline auto libc = libc_type{}; } -namespace spy::detail +namespace spy::_ { template inline constexpr libc_info::operator bool() const noexcept @@ -528,39 +535,39 @@ namespace spy::detail } namespace spy { - constexpr inline auto cloudabi_ = detail::cloudabi_t<-1,0,0>{}; - constexpr inline auto uc_ = detail::uc_t<-1,0,0>{}; - constexpr inline auto vms_ = detail::vms_t<-1,0,0>{}; - constexpr inline auto zos_ = detail::zos_t<-1,0,0>{}; - constexpr inline auto gnu_ = detail::gnu_t<-1,0,0>{}; + constexpr inline auto cloudabi_ = _::cloudabi_t<-1,0,0>{}; + constexpr inline auto uc_ = _::uc_t<-1,0,0>{}; + constexpr inline auto vms_ = _::vms_t<-1,0,0>{}; + constexpr inline auto zos_ = _::zos_t<-1,0,0>{}; + constexpr inline auto gnu_ = _::gnu_t<-1,0,0>{}; } namespace spy::literal { template constexpr auto operator"" _cloud() { - return detail::literal_wrap(); + return _::literal_wrap<_::cloudabi_t,c...>(); } template constexpr auto operator"" _uc() { - return detail::literal_wrap(); + return _::literal_wrap<_::uc_t,c...>(); } template constexpr auto operator"" _vms() { - return detail::literal_wrap(); + return _::literal_wrap<_::vms_t,c...>(); } template constexpr auto operator"" _zos() { - return detail::literal_wrap(); + return _::literal_wrap<_::zos_t,c...>(); } template constexpr auto operator"" _gnu() { - return detail::literal_wrap(); + return _::literal_wrap<_::gnu_t,c...>(); } } #if defined(__APPLE__) || defined(__APPLE_CC__) || defined(macintosh) # include #endif -namespace spy::detail +namespace spy::_ { enum class systems { undefined_ = - 1 , android_, bsd_, cygwin_, ios_, linux_, macos_, unix_, windows_ @@ -575,8 +582,8 @@ namespace spy::detail return C2 == vendor; } }; - template - std::ostream& operator<<(std::ostream& os, os_info const&) + template<_::stream OS, systems OpSys> + OS& operator<<(OS& os, os_info const&) { if(OpSys == systems::android_ ) return os << "Android"; if(OpSys == systems::bsd_ ) return os << "BSD"; @@ -593,35 +600,35 @@ namespace spy { #if defined(__ANDROID__) #define SPY_OS_IS_ANDROID - using os_type = detail::os_info; + using os_type = _::os_info<_::systems::android_>; #elif defined(BSD) || defined(_SYSTYPE_BSD) #define SPY_OS_IS_BSD - using os_type = detail::os_info; + using os_type = _::os_info<_::systems::bsd_>; #elif defined(__CYGWIN__) #define SPY_OS_IS_CYGWIN - using os_type = detail::os_info; + using os_type = _::os_info<_::systems::cygwin_>; #elif defined(__APPLE__) && defined(__MACH__) && defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) #define SPY_OS_IS_IOS - using os_type = detail::os_info; + using os_type = _::os_info<_::systems::ios_>; #elif defined(linux) || defined(__linux) #define SPY_OS_IS_LINUX - using os_type = detail::os_info; + using os_type = _::os_info<_::systems::linux_>; #elif defined(macintosh) || defined(Macintosh) || (defined(__APPLE__) && defined(__MACH__)) #define SPY_OS_IS_MACOS - using os_type = detail::os_info; + using os_type = _::os_info<_::systems::macos_>; #elif defined(unix) || defined(__unix) || defined(_XOPEN_SOURCE) || defined(_POSIX_SOURCE) #define SPY_OS_IS_UNIX - using os_type = detail::os_info; + using os_type = _::os_info<_::systems::unix_>; #elif defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(__TOS_WIN__) || defined(__WINDOWS__) #define SPY_OS_IS_WINDOWS - using os_type = detail::os_info; + using os_type = _::os_info<_::systems::windows_>; #else #define SPY_OS_IS_UNKNOWN - using os_type = detail::os_info; + using os_type = _::os_info<_::systems::undefined_>; #endif constexpr inline os_type operating_system; } -namespace spy::detail +namespace spy::_ { template inline constexpr os_info::operator bool() const noexcept @@ -631,14 +638,14 @@ namespace spy::detail } namespace spy { - constexpr inline auto android_ = detail::os_info{}; - constexpr inline auto bsd_ = detail::os_info{}; - constexpr inline auto cygwin_ = detail::os_info{}; - constexpr inline auto ios_ = detail::os_info{}; - constexpr inline auto linux_ = detail::os_info{}; - constexpr inline auto macos_ = detail::os_info{}; - constexpr inline auto unix_ = detail::os_info{}; - constexpr inline auto windows_ = detail::os_info{}; + constexpr inline auto android_ = _::os_info<_::systems::android_>{}; + constexpr inline auto bsd_ = _::os_info<_::systems::bsd_>{}; + constexpr inline auto cygwin_ = _::os_info<_::systems::cygwin_>{}; + constexpr inline auto ios_ = _::os_info<_::systems::ios_>{}; + constexpr inline auto linux_ = _::os_info<_::systems::linux_>{}; + constexpr inline auto macos_ = _::os_info<_::systems::macos_>{}; + constexpr inline auto unix_ = _::os_info<_::systems::unix_>{}; + constexpr inline auto windows_ = _::os_info<_::systems::windows_>{}; } namespace spy::supports { @@ -703,7 +710,7 @@ namespace spy::supports #include #if !defined(SPY_SIMD_DETECTED) && defined(__AVX512F__) # define SPY_SIMD_IS_X86_AVX512 -# define SPY_SIMD_DETECTED ::spy::detail::simd_version::avx512_ +# define SPY_SIMD_DETECTED ::spy::_::simd_version::avx512_ #if defined(__AVX512BW__) # define SPY_SIMD_IS_X86_AVX512_BW #endif @@ -755,39 +762,39 @@ namespace spy::supports #endif #if !defined(SPY_SIMD_DETECTED) && defined(__AVX2__) # define SPY_SIMD_IS_X86_AVX2 -# define SPY_SIMD_DETECTED ::spy::detail::simd_version::avx2_ +# define SPY_SIMD_DETECTED ::spy::_::simd_version::avx2_ #endif #if !defined(SPY_SIMD_DETECTED) && defined(__AVX__) # define SPY_SIMD_IS_X86_AVX -# define SPY_SIMD_DETECTED ::spy::detail::simd_version::avx_ +# define SPY_SIMD_DETECTED ::spy::_::simd_version::avx_ #endif #if !defined(SPY_SIMD_DETECTED) && defined(__SSE4_2__) # define SPY_SIMD_IS_X86_SSE4_2 -# define SPY_SIMD_DETECTED ::spy::detail::simd_version::sse42_ +# define SPY_SIMD_DETECTED ::spy::_::simd_version::sse42_ #endif #if !defined(SPY_SIMD_DETECTED) && defined(__SSE4_1__) # define SPY_SIMD_IS_X86_SSE4_1 -# define SPY_SIMD_DETECTED ::spy::detail::simd_version::sse41_ +# define SPY_SIMD_DETECTED ::spy::_::simd_version::sse41_ #endif #if !defined(SPY_SIMD_DETECTED) && defined(__SSSE3__) # define SPY_SIMD_IS_X86_SSSE3 -# define SPY_SIMD_DETECTED ::spy::detail::simd_version::ssse3_ +# define SPY_SIMD_DETECTED ::spy::_::simd_version::ssse3_ #endif #if !defined(SPY_SIMD_DETECTED) && defined(__SSE3__) # define SPY_SIMD_IS_X86_SSE3 -# define SPY_SIMD_DETECTED ::spy::detail::simd_version::sse3_ +# define SPY_SIMD_DETECTED ::spy::_::simd_version::sse3_ #endif #if !defined(SPY_SIMD_DETECTED) && (defined(__SSE2__) || defined(_M_X64) || (defined(_M_IX86_FP) && _M_IX86_FP >= 2)) # define SPY_SIMD_IS_X86_SSE2 -# define SPY_SIMD_DETECTED ::spy::detail::simd_version::sse2_ +# define SPY_SIMD_DETECTED ::spy::_::simd_version::sse2_ #endif #if !defined(SPY_SIMD_DETECTED) && (defined(__SSE__) || defined(_M_IX86_FP)) # define SPY_SIMD_IS_X86_SSE -# define SPY_SIMD_DETECTED ::spy::detail::simd_version::sse1_ +# define SPY_SIMD_DETECTED ::spy::_::simd_version::sse1_ #endif #if defined(SPY_SIMD_DETECTED) && !defined(SPY_SIMD_VENDOR) # define SPY_SIMD_IS_X86 -# define SPY_SIMD_VENDOR ::spy::detail::simd_isa::x86_ +# define SPY_SIMD_VENDOR ::spy::_::simd_isa::x86_ #endif namespace spy::supports { @@ -912,20 +919,20 @@ namespace avx512 #if defined(__ARM_FEATURE_SVE2) # if !defined(__ARM_FEATURE_SVE_BITS) || (__ARM_FEATURE_SVE_BITS == 0) # define SPY_SIMD_IS_ARM_FLEXIBLE_SVE2 -# define SPY_SIMD_DETECTED ::spy::detail::simd_version::sve2_ +# define SPY_SIMD_DETECTED ::spy::_::simd_version::sve2_ # elif defined(__ARM_FEATURE_SVE_BITS) # if(__ARM_FEATURE_SVE_BITS == 128) # define SPY_SIMD_IS_ARM_FIXED_SVE2 -# define SPY_SIMD_DETECTED ::spy::detail::simd_version::fixed_sve2_ +# define SPY_SIMD_DETECTED ::spy::_::simd_version::fixed_sve2_ # elif(__ARM_FEATURE_SVE_BITS == 256) # define SPY_SIMD_IS_ARM_FIXED_SVE2 -# define SPY_SIMD_DETECTED ::spy::detail::simd_version::fixed_sve2_ +# define SPY_SIMD_DETECTED ::spy::_::simd_version::fixed_sve2_ # elif(__ARM_FEATURE_SVE_BITS == 512) # define SPY_SIMD_IS_ARM_FIXED_SVE2 -# define SPY_SIMD_DETECTED ::spy::detail::simd_version::fixed_sve2_ +# define SPY_SIMD_DETECTED ::spy::_::simd_version::fixed_sve2_ # elif(__ARM_FEATURE_SVE_BITS == 1024) # define SPY_SIMD_IS_ARM_FIXED_SVE2 -# define SPY_SIMD_DETECTED ::spy::detail::simd_version::fixed_sve2_ +# define SPY_SIMD_DETECTED ::spy::_::simd_version::fixed_sve2_ # else # error "[SPY] - No support for non-power of 2 SVE-2 cardinals" # endif @@ -934,20 +941,20 @@ namespace avx512 #if !defined(SPY_SIMD_DETECTED) && defined(__ARM_FEATURE_SVE) # if !defined(__ARM_FEATURE_SVE_BITS) || (__ARM_FEATURE_SVE_BITS == 0) # define SPY_SIMD_IS_ARM_FLEXIBLE_SVE -# define SPY_SIMD_DETECTED ::spy::detail::simd_version::sve_ +# define SPY_SIMD_DETECTED ::spy::_::simd_version::sve_ # elif defined(__ARM_FEATURE_SVE_BITS) # if(__ARM_FEATURE_SVE_BITS == 128) # define SPY_SIMD_IS_ARM_FIXED_SVE -# define SPY_SIMD_DETECTED ::spy::detail::simd_version::fixed_sve_ +# define SPY_SIMD_DETECTED ::spy::_::simd_version::fixed_sve_ # elif(__ARM_FEATURE_SVE_BITS == 256) # define SPY_SIMD_IS_ARM_FIXED_SVE -# define SPY_SIMD_DETECTED ::spy::detail::simd_version::fixed_sve_ +# define SPY_SIMD_DETECTED ::spy::_::simd_version::fixed_sve_ # elif(__ARM_FEATURE_SVE_BITS == 512) # define SPY_SIMD_IS_ARM_FIXED_SVE -# define SPY_SIMD_DETECTED ::spy::detail::simd_version::fixed_sve_ +# define SPY_SIMD_DETECTED ::spy::_::simd_version::fixed_sve_ # elif(__ARM_FEATURE_SVE_BITS == 1024) # define SPY_SIMD_IS_ARM_FIXED_SVE -# define SPY_SIMD_DETECTED ::spy::detail::simd_version::fixed_sve_ +# define SPY_SIMD_DETECTED ::spy::_::simd_version::fixed_sve_ # else # error "[SPY] - No support for non-power of 2 SVE cardinals" # endif @@ -955,87 +962,87 @@ namespace avx512 #endif #if defined(__ARM_FEATURE_SVE2) # define SPY_SIMD_IS_ARM_SVE2 -# define SPY_SIMD_VENDOR ::spy::detail::simd_isa::arm_sve_ +# define SPY_SIMD_VENDOR ::spy::_::simd_isa::arm_sve_ #elif defined(__ARM_FEATURE_SVE) # define SPY_SIMD_IS_ARM_SVE -# define SPY_SIMD_VENDOR ::spy::detail::simd_isa::arm_sve_ +# define SPY_SIMD_VENDOR ::spy::_::simd_isa::arm_sve_ #endif #if !defined(SPY_SIMD_DETECTED) && defined(__aarch64__) # define SPY_SIMD_IS_ARM_ASIMD -# define SPY_SIMD_DETECTED ::spy::detail::simd_version::asimd_ +# define SPY_SIMD_DETECTED ::spy::_::simd_version::asimd_ #endif #if !defined(SPY_SIMD_DETECTED) && ((defined(__ARM_NEON__) || defined(_M_ARM)) && (__ARM_ARCH == 7)) # define SPY_SIMD_IS_ARM_NEON -# define SPY_SIMD_DETECTED ::spy::detail::simd_version::neon_ +# define SPY_SIMD_DETECTED ::spy::_::simd_version::neon_ #endif #if defined(SPY_SIMD_DETECTED) && !defined(SPY_SIMD_VENDOR) # define SPY_SIMD_IS_ARM -# define SPY_SIMD_VENDOR ::spy::detail::simd_isa::arm_ +# define SPY_SIMD_VENDOR ::spy::_::simd_isa::arm_ #endif #if !defined(SPY_SIMD_DETECTED) && defined(__VSX__) # define SPY_SIMD_IS_PPC_VSX # if defined(_ARCH_PWR10) # define SPY_SIMD_IS_PPC_VSX_3_01 -# define SPY_SIMD_DETECTED ::spy::detail::simd_version::vsx_3_01_ +# define SPY_SIMD_DETECTED ::spy::_::simd_version::vsx_3_01_ # elif defined(_ARCH_PWR9) # define SPY_SIMD_IS_PPC_VSX_3_00 -# define SPY_SIMD_DETECTED ::spy::detail::simd_version::vsx_3_00_ +# define SPY_SIMD_DETECTED ::spy::_::simd_version::vsx_3_00_ # elif defined(_ARCH_PWR8) # define SPY_SIMD_IS_PPC_VSX_2_07 -# define SPY_SIMD_DETECTED ::spy::detail::simd_version::vsx_2_07_ +# define SPY_SIMD_DETECTED ::spy::_::simd_version::vsx_2_07_ # elif defined(_ARCH_PWR7) # define SPY_SIMD_IS_PPC_VSX_2_06 -# define SPY_SIMD_DETECTED ::spy::detail::simd_version::vsx_2_06_ +# define SPY_SIMD_DETECTED ::spy::_::simd_version::vsx_2_06_ # endif #endif #if !defined(SPY_SIMD_DETECTED) && (defined(__ALTIVEC__) || defined(__VEC__)) # define SPY_SIMD_IS_PPC_VMX # if defined(_ARCH_PWR10) # define SPY_SIMD_IS_PPC_VMX_3_01 -# define SPY_SIMD_DETECTED ::spy::detail::simd_version::vmx_3_01_ +# define SPY_SIMD_DETECTED ::spy::_::simd_version::vmx_3_01_ # elif defined(_ARCH_PWR9) # define SPY_SIMD_IS_PPC_VMX_3_00 -# define SPY_SIMD_DETECTED ::spy::detail::simd_version::vmx_3_00_ +# define SPY_SIMD_DETECTED ::spy::_::simd_version::vmx_3_00_ # elif defined(_ARCH_PWR8) # define SPY_SIMD_IS_PPC_VMX_2_07 -# define SPY_SIMD_DETECTED ::spy::detail::simd_version::vmx_2_07_ +# define SPY_SIMD_DETECTED ::spy::_::simd_version::vmx_2_07_ # elif defined(_ARCH_PWR7) # define SPY_SIMD_IS_PPC_VMX_2_06 -# define SPY_SIMD_DETECTED ::spy::detail::simd_version::vmx_2_06_ +# define SPY_SIMD_DETECTED ::spy::_::simd_version::vmx_2_06_ # elif defined(_ARCH_PWR6) # define SPY_SIMD_IS_PPC_VMX_2_05 -# define SPY_SIMD_DETECTED ::spy::detail::simd_version::vmx_2_05_ +# define SPY_SIMD_DETECTED ::spy::_::simd_version::vmx_2_05_ # elif defined(_ARCH_PWR5) # define SPY_SIMD_IS_PPC_VMX_2_03 -# define SPY_SIMD_DETECTED ::spy::detail::simd_version::vmx_2_03_ +# define SPY_SIMD_DETECTED ::spy::_::simd_version::vmx_2_03_ # endif -# define SPY_SIMD_DETECTED ::spy::detail::simd_version::vmx_ +# define SPY_SIMD_DETECTED ::spy::_::simd_version::vmx_ #endif #if defined(SPY_SIMD_DETECTED) && !defined(SPY_SIMD_VENDOR) # define SPY_SIMD_IS_PPC -# define SPY_SIMD_VENDOR ::spy::detail::simd_isa::ppc_ +# define SPY_SIMD_VENDOR ::spy::_::simd_isa::ppc_ #endif #if !defined(SPY_SIMD_DETECTED) && defined(__wasm_simd128__) -# define SPY_SIMD_DETECTED ::spy::detail::simd_version::simd128_ +# define SPY_SIMD_DETECTED ::spy::_::simd_version::simd128_ #endif #if defined(SPY_SIMD_DETECTED) && !defined(SPY_SIMD_VENDOR) # define SPY_SIMD_IS_WASM -# define SPY_SIMD_VENDOR ::spy::detail::simd_isa::wasm_ +# define SPY_SIMD_VENDOR ::spy::_::simd_isa::wasm_ #endif #if defined(__riscv_vector) # if !defined(__riscv_v_fixed_vlen) # define SPY_SIMD_IS_RISCV_FLEXIBLE_RVV -# define SPY_SIMD_DETECTED ::spy::detail::simd_version::rvv_ +# define SPY_SIMD_DETECTED ::spy::_::simd_version::rvv_ #else # define SPY_SIMD_IS_RISCV_FIXED_RVV -# define SPY_SIMD_DETECTED ::spy::detail::simd_version::fixed_rvv_ +# define SPY_SIMD_DETECTED ::spy::_::simd_version::fixed_rvv_ #endif #endif #if defined(__riscv_vector) # define SPY_SIMD_IS_RISCV_RVV -# define SPY_SIMD_VENDOR ::spy::detail::simd_isa::riscv_ +# define SPY_SIMD_VENDOR ::spy::_::simd_isa::riscv_ #endif -namespace spy::detail +namespace spy::_ { enum class simd_isa { undefined_ = -1 , x86_ = 1000 @@ -1100,7 +1107,8 @@ namespace spy::detail else return -1; }(); static constexpr bool has_fixed_cardinal() { return width != -1; } - friend std::ostream& operator<<(std::ostream& os, simd_info const&) + template<_::stream OS> + friend OS& operator<<(OS& os, simd_info const&) { if constexpr ( Version == simd_version::simd128_ ) os << "WASM SIMD128"; else if constexpr ( Version == simd_version::sse1_ ) os << "X86 SSE"; @@ -1175,61 +1183,61 @@ namespace spy::detail namespace spy { #if defined(SPY_SIMD_DETECTED) - constexpr inline auto simd_instruction_set = detail::simd_info{}; + constexpr inline auto simd_instruction_set = _::simd_info{}; #else - constexpr inline auto simd_instruction_set = detail::simd_info<>{}; + constexpr inline auto simd_instruction_set = _::simd_info<>{}; #endif - constexpr inline auto undefined_simd_ = detail::simd_info<>{}; - template - using wasm_simd_info = detail::simd_info; + constexpr inline auto undefined_simd_ = _::simd_info<>{}; + template<_::simd_version V = _::simd_version::undefined_> + using wasm_simd_info = _::simd_info<_::simd_isa::wasm_,V>; constexpr inline auto wasm_simd_ = wasm_simd_info<>{}; - constexpr inline auto simd128_ = wasm_simd_info{}; - template - using x86_simd_info = detail::simd_info; + constexpr inline auto simd128_ = wasm_simd_info<_::simd_version::simd128_>{}; + template<_::simd_version V = _::simd_version::undefined_> + using x86_simd_info = _::simd_info<_::simd_isa::x86_,V>; constexpr inline auto x86_simd_ = x86_simd_info<>{}; - constexpr inline auto sse1_ = x86_simd_info{}; - constexpr inline auto sse2_ = x86_simd_info{}; - constexpr inline auto sse3_ = x86_simd_info{}; - constexpr inline auto ssse3_ = x86_simd_info{}; - constexpr inline auto sse41_ = x86_simd_info{}; - constexpr inline auto sse42_ = x86_simd_info{}; - constexpr inline auto avx_ = x86_simd_info{}; - constexpr inline auto avx2_ = x86_simd_info{}; - constexpr inline auto avx512_ = x86_simd_info{}; - template - using ppc_simd_info = detail::simd_info; + constexpr inline auto sse1_ = x86_simd_info<_::simd_version::sse1_ >{}; + constexpr inline auto sse2_ = x86_simd_info<_::simd_version::sse2_ >{}; + constexpr inline auto sse3_ = x86_simd_info<_::simd_version::sse3_ >{}; + constexpr inline auto ssse3_ = x86_simd_info<_::simd_version::ssse3_ >{}; + constexpr inline auto sse41_ = x86_simd_info<_::simd_version::sse41_ >{}; + constexpr inline auto sse42_ = x86_simd_info<_::simd_version::sse42_ >{}; + constexpr inline auto avx_ = x86_simd_info<_::simd_version::avx_ >{}; + constexpr inline auto avx2_ = x86_simd_info<_::simd_version::avx2_ >{}; + constexpr inline auto avx512_ = x86_simd_info<_::simd_version::avx512_ >{}; + template<_::simd_version V = _::simd_version::undefined_> + using ppc_simd_info = _::simd_info<_::simd_isa::ppc_,V>; constexpr inline auto ppc_simd_ = ppc_simd_info<>{}; - constexpr inline auto vmx_ = ppc_simd_info{}; - constexpr inline auto vmx_2_03_ = ppc_simd_info{}; - constexpr inline auto vmx_2_05_ = ppc_simd_info{}; - constexpr inline auto vmx_2_06_ = ppc_simd_info{}; - constexpr inline auto vmx_2_07_ = ppc_simd_info{}; - constexpr inline auto vmx_3_00_ = ppc_simd_info{}; - constexpr inline auto vmx_3_01_ = ppc_simd_info{}; - constexpr inline auto vsx_ = ppc_simd_info{}; - constexpr inline auto vsx_2_06_ = ppc_simd_info{}; - constexpr inline auto vsx_2_07_ = ppc_simd_info{}; - constexpr inline auto vsx_3_00_ = ppc_simd_info{}; - constexpr inline auto vsx_3_01_ = ppc_simd_info{}; - template - using arm_simd_info = detail::simd_info; - template - using sve_simd_info = detail::simd_info; + constexpr inline auto vmx_ = ppc_simd_info<_::simd_version::vmx_>{}; + constexpr inline auto vmx_2_03_ = ppc_simd_info<_::simd_version::vmx_2_03_>{}; + constexpr inline auto vmx_2_05_ = ppc_simd_info<_::simd_version::vmx_2_05_>{}; + constexpr inline auto vmx_2_06_ = ppc_simd_info<_::simd_version::vmx_2_06_>{}; + constexpr inline auto vmx_2_07_ = ppc_simd_info<_::simd_version::vmx_2_07_>{}; + constexpr inline auto vmx_3_00_ = ppc_simd_info<_::simd_version::vmx_3_00_>{}; + constexpr inline auto vmx_3_01_ = ppc_simd_info<_::simd_version::vmx_3_01_>{}; + constexpr inline auto vsx_ = ppc_simd_info<_::simd_version::vsx_>{}; + constexpr inline auto vsx_2_06_ = ppc_simd_info<_::simd_version::vsx_2_06_>{}; + constexpr inline auto vsx_2_07_ = ppc_simd_info<_::simd_version::vsx_2_07_>{}; + constexpr inline auto vsx_3_00_ = ppc_simd_info<_::simd_version::vsx_3_00_>{}; + constexpr inline auto vsx_3_01_ = ppc_simd_info<_::simd_version::vsx_3_01_>{}; + template<_::simd_version V = _::simd_version::undefined_> + using arm_simd_info = _::simd_info<_::simd_isa::arm_,V>; + template<_::simd_version V = _::simd_version::undefined_> + using sve_simd_info = _::simd_info<_::simd_isa::arm_sve_,V>; constexpr inline auto arm_simd_ = arm_simd_info<>{}; - constexpr inline auto neon_ = arm_simd_info{}; - constexpr inline auto asimd_ = arm_simd_info{}; - constexpr inline auto sve_ = sve_simd_info{}; - constexpr inline auto fixed_sve_ = sve_simd_info{}; - constexpr inline auto sve2_ = sve_simd_info{}; - constexpr inline auto fixed_sve2_ = sve_simd_info{}; - template - using riscv_simd_info = detail::simd_info; + constexpr inline auto neon_ = arm_simd_info<_::simd_version::neon_ >{}; + constexpr inline auto asimd_ = arm_simd_info<_::simd_version::asimd_>{}; + constexpr inline auto sve_ = sve_simd_info<_::simd_version::sve_>{}; + constexpr inline auto fixed_sve_ = sve_simd_info<_::simd_version::fixed_sve_>{}; + constexpr inline auto sve2_ = sve_simd_info<_::simd_version::sve2_>{}; + constexpr inline auto fixed_sve2_ = sve_simd_info<_::simd_version::fixed_sve2_>{}; + template<_::simd_version V= _::simd_version::undefined_> + using riscv_simd_info = _::simd_info<_::simd_isa::riscv_, V>; constexpr inline auto riscv_simd_ = riscv_simd_info<> {}; - constexpr inline auto rvv_ = riscv_simd_info {}; - constexpr inline auto fixed_rvv_ = riscv_simd_info {}; + constexpr inline auto rvv_ = riscv_simd_info<_::simd_version::rvv_> {}; + constexpr inline auto fixed_rvv_ = riscv_simd_info<_::simd_version::fixed_rvv_> {}; } #include -namespace spy::detail +namespace spy::_ { enum class stdlib { undefined_ = - 1, libcpp_, gnucpp_ }; template struct stdlib_info @@ -1244,8 +1252,8 @@ namespace spy::detail } SPY_VERSION_COMPARISONS_OPERATOR(stdlib,stdlib_info) }; - template - std::ostream& operator<<(std::ostream& os, stdlib_info const& p) + template<_::stream OS, stdlib SLib, int M, int N, int P> + OS& operator<<(OS& os, stdlib_info const& p) { if(SLib == stdlib::libcpp_) return os << "libc++ Standard C++ Library " << p.version ; if(SLib == stdlib::gnucpp_) return os << "GNU Standard C++ Library " << p.version; @@ -1258,19 +1266,19 @@ namespace spy { #if defined(_LIBCPP_VERSION) #define SPY_STDLIB_IS_LIBCPP - using stdlib_type = detail::libcpp_t<(_LIBCPP_VERSION/1000)%10,0,_LIBCPP_VERSION%1000>; + using stdlib_type = _::libcpp_t<(_LIBCPP_VERSION/1000)%10,0,_LIBCPP_VERSION%1000>; #elif defined(__GLIBCXX__) #define SPY_STDLIB_IS_GLIBCXX #define SPY0 (__GLIBCXX__/100) - using stdlib_type = detail::gnucpp_t<(SPY0/100)%10000, SPY0%100, __GLIBCXX__%100>; + using stdlib_type = _::gnucpp_t<(SPY0/100)%10000, SPY0%100, __GLIBCXX__%100>; #undef SPY0 #else #define SPY_STDLIB_IS_UNKNOWN - using stdlib_type = detail::stdlib_info; + using stdlib_type = _::stdlib_info<_::stdlib::undefined_,-1,0,0>; #endif constexpr inline auto stdlib = stdlib_type{}; } -namespace spy::detail +namespace spy::_ { template inline constexpr stdlib_info::operator bool() const noexcept @@ -1280,18 +1288,18 @@ namespace spy::detail } namespace spy { - constexpr inline auto libcpp_ = detail::libcpp_t<-1,0,0>{}; - constexpr inline auto gnucpp_ = detail::gnucpp_t<-1,0,0>{}; + constexpr inline auto libcpp_ = _::libcpp_t<-1,0,0>{}; + constexpr inline auto gnucpp_ = _::gnucpp_t<-1,0,0>{}; } namespace spy::literal { template constexpr auto operator"" _libcpp() { - return detail::literal_wrap(); + return _::literal_wrap<_::libcpp_t,c...>(); } template constexpr auto operator"" _gnucpp() { - return detail::literal_wrap(); + return _::literal_wrap<_::gnucpp_t,c...>(); } } #endif