![**The C++ Informations Broker**](https://github.com/jfalcou/spy/raw/develop/logo.png) Purpose ==================================================================================================== Detection and versioning of operating systems, compilers, architecture and other element are traditionally done using preprocessor macros. Library like [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 informations and provides a `constexpr` compatible interface to access those information, thus making their exploitation within `constexpr` context possible. **References:** ![**Our CppCon 2019 Ligthning talk video**](https://www.youtube.com/watch?v=t406o2EhG-A) - [Our CppCon 2019 Ligthning talk slides](https://docs.google.com/presentation/d/1nSBhU4pr5EWznni0MYsyDkMCr3O3q2XS-KQdz2_BRRI/edit?usp=sharing) - [Boost.Predef](https://www.boost.org/doc/libs/release/doc/html/predef.html) How to install ==================================================================================================== Using CMake ---------------------------------------------------------------------------------------------------- After cloning the repository, run `CMake` with an install prefix path then run the `install` target using `Make` or any other build system. ~~~~~ bash git clone https://github.com/jfalcou/spy.git mkdir build cd build cmake .. -DCMAKE_INSTALL_PREFIX=path/to/install/folder make install ~~~~~ Manually ---------------------------------------------------------------------------------------------------- After cloning the repository, copy the `include` folder into the folder of your choice. ~~~~~ bash git clone https://github.com/jfalcou/spy.git cp -r include/* path/to/install/folder ~~~~~ ## Sample usage SPY is usable by simply including the `spy.hpp` file as demonstrated here: Just compile this example using a C++17 compliant compiler. Don't forget to add the path to the SPY library files to your favorite compiler's options. Redistribuable include ---------------------------------------------------------------------------------------------------- If you want to use SPY in your own project but want to keep a low imprint on your own source code, one can copy the standalone `spy.hpp` file provided at the root of the include folder. This file contains the whole SPY library ready to be used and shipped. User manual ==================================================================================================== Supported detectors ---------------------------------------------------------------------------------------------------- SPY can detect: - Architecture family via the `spy::architecture` object. - OS vendor via the `spy::operating_system` object. - Compiler vendor and version (in the M.N.P format) via the `spy::compiler` object. - libc vendor and version (in the M.N.P format) via the `spy::libc` object. - stdlib vendor and version (in the M.N.P format) via the `spy::stdlib` object. The simplest usage of those objects is to pass them to an output stream to get a readable display of their informations. Comparing vendors ---------------------------------------------------------------------------------------------------- Knowing is half the battle, we may want to compare the current compiler or OS to a given one so you can branch off your code based on this informations. Here is the list of each detected vendor for each SPY objects. | Detector | Supported vendor | | ----------------------- | ------------------------------------------------------------------------------ | | `spy::architecture` | `x86_`, `amd64_`, `ppc_`, `arm_` | | `spy::operating_system` | `android_`, `bsd_`, `cygwin_`, `ios_`, `linux_`, `macos_`, `unix_`, `windows_` | | `spy::compiler` | `clang_`, `gcc_`, `intel_`, `msvc_` | | `spy::libc` | `cloudabi_`, `gnu_` `uc_`, `vms_`, `zos_` | | `spy::stdlib` | `gnucpp_`, `libcpp_` | Here is a sample code comparing some detectors to a specific vendor: Additional features can be checked using the `spy::supports` namespace: - Checking for POSIX capability via `spy::supports::posix_` Comparing versions ---------------------------------------------------------------------------------------------------- Checking for a vendor is sometimes not enough, we need to check which version of a given component is used. To do this, you can compare a detector to a given version value using any comparison operators. Versions are build using a custom literal suffix based on the vendor name (`_vendor`) and a series of integral values separated by `'`. | Detector | Supported version suffixes | | --------------- | ------------------------------------------------------------------------------ | | `spy::compiler` | `_clang`, `_gcc`, `_intel`, `_msvc` | | `spy::libc` | `_cloudabi`, `_gnu` `_uc`, `_vms`, `_zos` | | `spy::stdlib` | `_gnucpp`, `_libcpp` | The following code demonstrates such comparisons: Handling SIMD extensions ---------------------------------------------------------------------------------------------------- SIMD extensions set detection is made so that one can ask if the current SIMD extension is exactly, below or above a given reference instruction set. Detectable instructions sets depends on SIMD hardware vendor | Architecture | Supported SIMD instructions sets | | ------------- | ----------------------------------------------------------------------------------- | | X86 | `sse1_`, `sse2_`, `sse3_`, `ssse3_`, `sse41_`, `sse42_`, `avx_`, `avx2_`, `avx512_` | | Power PC | `vmx_`, `vsx_` | | ARM | `neon_`,`asimd_` | Complete set of comparison operators is provided for those sets. Order of instructions sets are built so that if an instructions set supersedes another, it is considered greater than. For example, `avx_` is greater than `sse41_` as the former is a super-set of the later. One can also simply asks if a given family of instructions set is available. Some SIMD instructions set provides supplemental instructions on top of existing system. Those supplemental instruction set can be checked using the `spy::supports` namespace. The complete list of supplemental instruction sets si given in the following table. | Architecture | Supported SIMD instructions sets | | ------------- | ------------------------------------------------------------------------------------------------------------------------------- | | X86 AVX | `xop_`, `fma_`, `fma4_` | | X86 AVX512 | `avx512::bw_`, `avx512::cd_`, `avx512::dq_`, `avx512::er_`, `avx512::ifma_`, `avx512::pf_`, `avx512::vl_`, `avx512::popcntdq_`, `avx512::_4fmaps_`, `avx512::vnniw_`, `avx512::vbmi_`, `avx512::bf16_`, `avx512::bitalg_`, `avx512::vbmi2_`, `avx512::vnni_`, `avx512::vpintersect_` | Caveat with `if constexpr` ---------------------------------------------------------------------------------------------------- The detection and comparisons of versions using SPY detectors are subject to some caveats that stem from the way `if constexpr` behaves. As both branch of the `if constexpr` are ODR_checked, all functions and type names must be defined even if not used. This means that this can't compile whatsoever: Post C++20, we advice you to use concepts with template functions: License ==================================================================================================== This library is licensed under the MIT License as specified in the LICENSE.md file. If you use SPY in your project or product, feel free to send us an email so we can advertise it here. ``` The MIT License (MIT) Copyright (c) 2018-2021 Joel FALCOU Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ```