diff options
author | 2022-05-21 17:16:50 +0200 | |
---|---|---|
committer | 2022-05-22 01:16:50 +1000 | |
commit | 324f9d44d5c4293645e7bb8f42e7d95d5ac1e604 (patch) | |
tree | 1ad2d66458486f184e11536e247309eb6c0161fb /src/lib/netlist/plib | |
parent | b33946d980772bf8e973b3816684f313a5b4e9ea (diff) |
netlist: More c++, less macros, added support for cspell (#9794)
- More c++, less macros
* Significantly reduced the use of unused_var and replaced it with
[[maybe_unused]]
* use enum class in ppmf.h
- Changes to testing code in ptest.h
* Catch exceptions in more places
* The verbosity of the output can now be controlled
* Display of test stats totals
- added support for cspell
- fixed various typos
- fixed SUBTARGET=nl build
- fixed more file permissions
- srcclean and add fix_permissions target to netlist makefile
Diffstat (limited to 'src/lib/netlist/plib')
-rw-r--r-- | src/lib/netlist/plib/gmres.h | 20 | ||||
-rw-r--r-- | src/lib/netlist/plib/palloc.h | 18 | ||||
-rw-r--r-- | src/lib/netlist/plib/pchrono.h | 2 | ||||
-rw-r--r-- | src/lib/netlist/plib/pconfig.h | 36 | ||||
-rw-r--r-- | src/lib/netlist/plib/pdynlib.cpp | 3 | ||||
-rw-r--r-- | src/lib/netlist/plib/pdynlib.h | 7 | ||||
-rw-r--r-- | src/lib/netlist/plib/pexception.cpp | 2 | ||||
-rw-r--r-- | src/lib/netlist/plib/pexception.h | 2 | ||||
-rw-r--r-- | src/lib/netlist/plib/pmath.h | 2 | ||||
-rw-r--r-- | src/lib/netlist/plib/pomp.h | 4 | ||||
-rw-r--r-- | src/lib/netlist/plib/poptions.cpp | 3 | ||||
-rw-r--r-- | src/lib/netlist/plib/ppmf.cpp | 8 | ||||
-rw-r--r-- | src/lib/netlist/plib/ppmf.h | 112 | ||||
-rw-r--r-- | src/lib/netlist/plib/ppreprocessor.h | 4 | ||||
-rw-r--r-- | src/lib/netlist/plib/prandom.h | 3 | ||||
-rw-r--r-- | src/lib/netlist/plib/pstonum.h | 2 | ||||
-rw-r--r-- | src/lib/netlist/plib/pstream.h | 9 | ||||
-rw-r--r-- | src/lib/netlist/plib/ptests.h | 210 | ||||
-rw-r--r-- | src/lib/netlist/plib/ptime.h | 3 | ||||
-rw-r--r-- | src/lib/netlist/plib/ptypes.h | 45 |
20 files changed, 309 insertions, 186 deletions
diff --git a/src/lib/netlist/plib/gmres.h b/src/lib/netlist/plib/gmres.h index 1beb4b20041..91a06371b33 100644 --- a/src/lib/netlist/plib/gmres.h +++ b/src/lib/netlist/plib/gmres.h @@ -81,12 +81,11 @@ namespace plib template <typename FT, int SIZE> struct mat_precondition_diag { - mat_precondition_diag(std::size_t size, int dummy = 0) + mat_precondition_diag(std::size_t size, [[maybe_unused]] int dummy = 0) : m_mat(size) , m_diag(size) , nzcol(size) { - plib::unused_var(dummy); } template <typename M> @@ -120,19 +119,19 @@ namespace plib // ILUT: 265% FT v(0.0); #if 0 - // doesn't works, Mame perforamnce drops significantly% + // doesn't works, Mame performance drops significantly% // 136% for (std::size_t j = m_mat.row_idx[i]; j< m_mat.row_idx[i+1]; j++) v += m_mat.A[j] * m_mat.A[j]; m_diag[i] = reciprocal(std::sqrt(v)); #elif 0 - // works halfway, i.e. Mame perforamnce 50% + // works halfway, i.e. Mame performance 50% // 147% - lowest average solution time with 7.094 for (std::size_t j = m_mat.row_idx[i]; j< m_mat.row_idx[i+1]; j++) v += m_mat.A[j] * m_mat.A[j]; m_diag[i] = m_mat.A[m_mat.diag[i]] / v; #elif 0 - // works halfway, i.e. Mame perforamnce 50% + // works halfway, i.e. Mame performance 50% // sum over column i // 344% - lowest average solution time with 3.06 std::size_t nzcolp = 0; @@ -145,7 +144,7 @@ namespace plib } m_diag[i] = m_mat.A[m_mat.diag[i]] / v; #elif 0 - // works halfway, i.e. Mame perforamnce 50% + // works halfway, i.e. Mame performance 50% // 151% for (std::size_t j = m_mat.row_idx[i]; j< m_mat.row_idx[i+1]; j++) v += plib::abs(m_mat.A[j]); @@ -175,10 +174,9 @@ namespace plib template <typename FT, int SIZE> struct mat_precondition_none { - mat_precondition_none(std::size_t size, int dummy = 0) + mat_precondition_none(std::size_t size, [[maybe_unused]] int dummy = 0) : m_mat(size) { - plib::unused_var(dummy); } template <typename M> @@ -198,9 +196,8 @@ namespace plib } template<typename V> - void solve_inplace(V &v) + void solve_inplace([[maybe_unused]] V &v) { - plib::unused_var(v); } plib::pmatrix_cr<FT, SIZE> m_mat; @@ -344,9 +341,8 @@ namespace plib } template <int k, typename OPS, typename VT> - bool do_k(OPS &ops, VT &x, std::size_t &itr_used, FT rho_delta, bool dummy) + bool do_k(OPS &ops, VT &x, std::size_t &itr_used, FT rho_delta, [[maybe_unused]] bool dummy) { - plib::unused_var(dummy); if (do_k<k-1, OPS>(ops, x, itr_used, rho_delta, do_khelper<k-1>::value)) return true; diff --git a/src/lib/netlist/plib/palloc.h b/src/lib/netlist/plib/palloc.h index 6c197aa9238..f565e02d7b6 100644 --- a/src/lib/netlist/plib/palloc.h +++ b/src/lib/netlist/plib/palloc.h @@ -90,15 +90,17 @@ namespace plib { { using arena_storage_type = P; - constexpr arena_deleter_base(arena_storage_type *a = nullptr) noexcept + constexpr arena_deleter_base( /*[[maybe_unused]]*/ arena_storage_type *a = nullptr) noexcept { + // gcc 7.2 (mingw) and 7.5 (ubuntu) don't accept maybe_unused here plib::unused_var(a); } template<typename U, typename = typename std::enable_if<std::is_convertible< U*, T*>::value>::type> - arena_deleter_base(const arena_deleter_base<P, U, true> &rhs) noexcept + arena_deleter_base( /*[[maybe_unused]]*/ const arena_deleter_base<P, U, true> &rhs) noexcept { + // gcc 7.2 (mingw) and 7.5 (ubuntu) don't accept maybe_unused here plib::unused_var(rhs); } @@ -454,9 +456,8 @@ namespace plib { #endif } - bool operator ==(const aligned_arena &rhs) const noexcept + bool operator ==([[maybe_unused]] const aligned_arena &rhs) const noexcept { - plib::unused_var(rhs); return true; } @@ -464,10 +465,9 @@ namespace plib { struct std_arena : public arena_base<std_arena, true, true> { - static inline void *allocate( size_t alignment, size_t size ) + static inline void *allocate([[maybe_unused]] size_t alignment, size_t size ) { inc_alloc_stat(size); - unused_var(alignment); return ::operator new(size); } @@ -477,9 +477,8 @@ namespace plib { ::operator delete(ptr); } - bool operator ==(const aligned_arena &rhs) const noexcept + bool operator ==([[maybe_unused]] const aligned_arena &rhs) const noexcept { - plib::unused_var(rhs); return true; } }; @@ -636,9 +635,8 @@ namespace plib { ~paged_arena() = default; - static void *allocate(size_t align, size_t size) + static void *allocate([[maybe_unused]] size_t align, size_t size) { - plib::unused_var(align); //size = ((size + PG_SIZE - 1) / PG_SIZE) * PG_SIZE; return arena().allocate(PG_SIZE, size); } diff --git a/src/lib/netlist/plib/pchrono.h b/src/lib/netlist/plib/pchrono.h index be391502946..629d7573239 100644 --- a/src/lib/netlist/plib/pchrono.h +++ b/src/lib/netlist/plib/pchrono.h @@ -110,7 +110,7 @@ namespace plib { #if PUSE_ACCURATE_STATS && PHAS_RDTSCP // // kills performance completely, but is accurate - // cpuid serializes, but clobbers ebx and ecx + // `cpuid` serializes, but clobbers ebx and ecx // struct exact_ticks : public base_ticks<exact_ticks, int64_t> diff --git a/src/lib/netlist/plib/pconfig.h b/src/lib/netlist/plib/pconfig.h index be56ad86507..d0dded12358 100644 --- a/src/lib/netlist/plib/pconfig.h +++ b/src/lib/netlist/plib/pconfig.h @@ -83,8 +83,8 @@ #define PALIGNAS_VECTOROPT() #endif -// FIXME: Breaks mame build on windows mingw due to -Wattribute -// also triggers -Wattribute on ARM +// FIXME: Breaks mame build on windows mingw due to `-Wattribute` +// also triggers `-Wattribute` on ARM // This is fixed on mingw version 10 // FIXME: no error on cross-compile - need further checks #if defined(__GNUC__) && ((defined(_WIN32) && __GNUC__ < 10) || defined(__arm__) || defined(__ARMEL__)) @@ -115,30 +115,16 @@ // //============================================================ -#if (NVCCBUILD > 0) - #if NVCCBUILD >= 101 - #define NVCC_CONSTEXPR constexpr - #else - #define NVCC_CONSTEXPR constexpr - #endif - #if NVCCBUILD < 113 - #if __cplusplus != 201402L - #error nvcc - use c++14 to compile - #endif - #endif +#if defined(_MSC_VER) + // Ok +#elif __cplusplus == 201103L + #error c++11 not supported - you need c++17 +#elif __cplusplus == 201402L + #error c++14 not supported - you need c++17 +#elif __cplusplus == 201703L + // Ok #else - #define NVCC_CONSTEXPR constexpr - #if __cplusplus == 201103L - #error c++11 not supported - you need c++14 - #elif __cplusplus == 201402L - // Ok - #elif __cplusplus == 201703L - // Ok - #elif defined(_MSC_VER) - // Ok - #else - #error "C++ version not supported" - #endif + #error "C++ version not supported" #endif diff --git a/src/lib/netlist/plib/pdynlib.cpp b/src/lib/netlist/plib/pdynlib.cpp index 7e9ea3ea73f..52fc5effb96 100644 --- a/src/lib/netlist/plib/pdynlib.cpp +++ b/src/lib/netlist/plib/pdynlib.cpp @@ -40,11 +40,10 @@ dynlib::dynlib(const pstring &libname) // printf("library <%s> not found: %s\n", libname.c_str(), dlerror()); } -dynlib::dynlib(const pstring &path, const pstring &libname) +dynlib::dynlib( [[maybe_unused]] const pstring &path, const pstring &libname) : m_lib(nullptr) { // FIXME: implement path search - plib::unused_var(path); // printf("win: loading <%s>\n", libname.c_str()); #ifdef _WIN32 if (!libname.empty()) diff --git a/src/lib/netlist/plib/pdynlib.h b/src/lib/netlist/plib/pdynlib.h index 04a6a354a69..4e8ce023d6f 100644 --- a/src/lib/netlist/plib/pdynlib.h +++ b/src/lib/netlist/plib/pdynlib.h @@ -7,14 +7,13 @@ /// /// \file pdynlib.h /// +/// Dynamic loading of libraries +/// #include "pstring.h" #include "ptypes.h" namespace plib { - // ---------------------------------------------------------------------------------------- - // pdynlib: dynamic loading of libraries ... - // ---------------------------------------------------------------------------------------- class dynlib_base { @@ -46,7 +45,7 @@ namespace plib { { public: explicit dynlib(const pstring &libname); - dynlib(const pstring &path, const pstring &libname); + dynlib(/*[[maybe_unused]]*/ const pstring &path, const pstring &libname); ~dynlib() override; diff --git a/src/lib/netlist/plib/pexception.cpp b/src/lib/netlist/plib/pexception.cpp index 86e7e732b45..bd2d81847a6 100644 --- a/src/lib/netlist/plib/pexception.cpp +++ b/src/lib/netlist/plib/pexception.cpp @@ -104,7 +104,7 @@ namespace plib { bool fpsignalenabler::m_enable = false; // NOLINT - //FIXME: mingw needs to be compiled with "-fnon-call-exceptions" + //FIXME: mingw needs to be compiled with `-fnon-call-exceptions` fpsignalenabler::fpsignalenabler(unsigned fpexceptions) { diff --git a/src/lib/netlist/plib/pexception.h b/src/lib/netlist/plib/pexception.h index d07122b7ebb..3b896f2b3dd 100644 --- a/src/lib/netlist/plib/pexception.h +++ b/src/lib/netlist/plib/pexception.h @@ -83,7 +83,7 @@ namespace plib { }; // FIXME: currently only a stub for later use. More use could be added by - // using “-fnon-call-exceptions" and sigaction to enable c++ exception supported. + // using `-fnon-call-exceptions` and sigaction to enable c++ exception supported. // class fpexception_e : public pexception diff --git a/src/lib/netlist/plib/pmath.h b/src/lib/netlist/plib/pmath.h index d28090079e3..311a928a597 100644 --- a/src/lib/netlist/plib/pmath.h +++ b/src/lib/netlist/plib/pmath.h @@ -15,7 +15,7 @@ #include <cmath> #include <type_traits> -// quadmath.h included by ptypes.h +// `quadmath.h` included by `ptypes.h` namespace plib { diff --git a/src/lib/netlist/plib/pomp.h b/src/lib/netlist/plib/pomp.h index 27b4cc74c2a..d698d6ea34f 100644 --- a/src/lib/netlist/plib/pomp.h +++ b/src/lib/netlist/plib/pomp.h @@ -55,12 +55,10 @@ void for_static_np(const I start, const I end, const T &what) noexcept(noexcept( } -inline void set_num_threads(const std::size_t threads) noexcept +inline void set_num_threads([[maybe_unused]] const std::size_t threads) noexcept { #if PHAS_OPENMP && PUSE_OPENMP omp_set_num_threads(threads); -#else - plib::unused_var(threads); #endif } diff --git a/src/lib/netlist/plib/poptions.cpp b/src/lib/netlist/plib/poptions.cpp index 5b4b2228df1..b7e0b595114 100644 --- a/src/lib/netlist/plib/poptions.cpp +++ b/src/lib/netlist/plib/poptions.cpp @@ -26,9 +26,8 @@ namespace plib { return 0; } - int option_bool::parse(const pstring &argument) + int option_bool::parse([[maybe_unused]] const pstring &argument) { - unused_var(argument); m_val = true; return 0; } diff --git a/src/lib/netlist/plib/ppmf.cpp b/src/lib/netlist/plib/ppmf.cpp index 8100b94ade0..05493f98d2f 100644 --- a/src/lib/netlist/plib/ppmf.cpp +++ b/src/lib/netlist/plib/ppmf.cpp @@ -15,7 +15,7 @@ namespace plib { - void mfp_raw<PPMF_TYPE_INTERNAL_ITANIUM>::convert_to_generic(generic_function &func, mfp_generic_class *&object) const + void mfp_raw<ppmf_type::INTERNAL_ITANIUM>::convert_to_generic(generic_function &func, mfp_generic_class *&object) const { // apply the "this" delta to the object first // NOLINTNEXTLINE(clang-analyzer-core.UndefinedBinaryOperatorResult,cppcoreguidelines-pro-type-reinterpret-cast) @@ -42,7 +42,7 @@ namespace plib { object = o_p_delta; } - void mfp_raw<PPMF_TYPE_INTERNAL_ARM>::convert_to_generic(generic_function &func, mfp_generic_class *&object) const + void mfp_raw<ppmf_type::INTERNAL_ARM>::convert_to_generic(generic_function &func, mfp_generic_class *&object) const { // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) object = reinterpret_cast<mfp_generic_class *>(reinterpret_cast<std::uint8_t *>(object) + (m_this_delta >> 1)); @@ -64,9 +64,9 @@ namespace plib { } } - struct unknown_base_equiv_novtdisp { mfp_raw<PPMF_TYPE_INTERNAL_MSC>::generic_function fptr; int thisdisp, vptrdisp; }; + struct unknown_base_equiv_novtdisp { mfp_raw<ppmf_type::INTERNAL_MSC>::generic_function fptr; int thisdisp, vptrdisp; }; - void mfp_raw<PPMF_TYPE_INTERNAL_MSC>::convert_to_generic(generic_function &func, mfp_generic_class *&object) const + void mfp_raw<ppmf_type::INTERNAL_MSC>::convert_to_generic(generic_function &func, mfp_generic_class *&object) const { //printf("%lx, %lx, %lx, %lx %lx\n", m_function, m_this_delta, m_vptr_offs, m_vt_index, m_size); diff --git a/src/lib/netlist/plib/ppmf.h b/src/lib/netlist/plib/ppmf.h index 31818f9f12c..b188ca0cd81 100644 --- a/src/lib/netlist/plib/ppmf.h +++ b/src/lib/netlist/plib/ppmf.h @@ -20,7 +20,7 @@ /// Use the same approach as MAME for deriving the function pointer. /// This is compiler-dependent as well /// -/// Benchmarks for ./nltool -c run -t 10 -n pongf src/mame/machine/nl_pongf.cpp +/// Benchmarks for `./nltool -c run -t 10 -n pongf src/mame/machine/nl_pongf.cpp` /// /// PMF_TYPE_INTERNAL: 215% 215% 564% 580% /// PMF_TYPE_GNUC_PMF: 163% 196% 516% 490% @@ -31,7 +31,7 @@ /// \brief Enable experimental code on Visual Studio builds and VS clang llvm builds /// /// This enables experimental code which uses optimized builds the -/// PPMF_TYPE_INTERNAL_MSC path also for complex (struct/union) return types. +/// ppmf_type::INTERNAL_MSC path also for complex (struct/union) return types. /// This currently depends on whether the code can adequately determine on /// x64 builds if the return type is returned through registers or passed as a /// second argument as a pointer to the member function. @@ -46,7 +46,9 @@ /// /// This code path is disabled by default currently. /// +#if !defined(PPMF_EXPERIMENTAL) #define PPMF_EXPERIMENTAL 0 +#endif /// brief Enable using MAME delegates as a replacement for ppmf. /// @@ -54,7 +56,9 @@ /// as a replacement to ppmf. Enable this setting if you want to use the nltool /// test suite (nltool -c tests) to produce comparisons to ppmf. /// +#if !defined(PPMF_USE_MAME_DELEGATES) #define PPMF_USE_MAME_DELEGATES 0 +#endif #if PPMF_USE_MAME_DELEGATES @@ -87,39 +91,43 @@ namespace plib { //#define PPMF_FORCE_TYPE 0 -#define PPMF_TYPE_PMF 0 -#define PPMF_TYPE_GNUC_PMF_CONV 1 -#define PPMF_TYPE_INTERNAL_ITANIUM 2 -#define PPMF_TYPE_INTERNAL_ARM 3 -#define PPMF_TYPE_INTERNAL_MSC 4 - #ifndef PPMF_FORCE_TYPE #define PPMF_FORCE_TYPE -1 #endif namespace plib { - struct ppmf_internal + enum class ppmf_type + { + PMF, + GNUC_PMF_CONV, + INTERNAL_ITANIUM, + INTERNAL_ARM, + INTERNAL_MSC + }; + + + struct ppmf_internal_selector { using ci = compile_info; - enum { value = - (PPMF_FORCE_TYPE >= 0) ? PPMF_FORCE_TYPE : + constexpr static ppmf_type value = + (PPMF_FORCE_TYPE >= 0) ? static_cast<ppmf_type>(PPMF_FORCE_TYPE) : (ci::type() == ci_compiler::CLANG && !ci::m64() - && ci::os() == ci_os::WINDOWS) ? PPMF_TYPE_PMF : - (ci::mingw() && !ci::m64() && ci::version() >= 407) ? PPMF_TYPE_PMF : - (ci::mingw() && !ci::m64()) ? PPMF_TYPE_PMF : // Dropped support for mingw32 < 407 PPMF_TYPE_INTERNAL_ITANIUM : - (ci::env() == ci_env::MSVC && ci::m64()) ? PPMF_TYPE_INTERNAL_MSC : + && ci::os() == ci_os::WINDOWS) ? ppmf_type::PMF : + (ci::mingw() && !ci::m64() && ci::version::full() >= typed_version<4,7>::full()) ? ppmf_type::PMF : + (ci::mingw() && !ci::m64()) ? ppmf_type::PMF : // Dropped support for mingw32 < 407 ppmf_type::INTERNAL_ITANIUM : + (ci::env() == ci_env::MSVC && ci::m64()) ? ppmf_type::INTERNAL_MSC : ((ci::type() == ci_compiler::CLANG || ci::type() == ci_compiler::GCC) && (ci::arch() == ci_arch::MIPS || ci::arch() == ci_arch::ARM - || ci::os() == ci_os::EMSCRIPTEN)) ? PPMF_TYPE_INTERNAL_ARM : - (ci::type() == ci_compiler::CLANG || ci::type() == ci_compiler::GCC) ? PPMF_TYPE_INTERNAL_ITANIUM : - PPMF_TYPE_PMF - }; + || ci::os() == ci_os::EMSCRIPTEN)) ? ppmf_type::INTERNAL_ARM : + (ci::type() == ci_compiler::CLANG || ci::type() == ci_compiler::GCC) ? ppmf_type::INTERNAL_ITANIUM : + ppmf_type::PMF + ; }; - static_assert(!(compile_info::type() == ci_compiler::CLANG && (PPMF_FORCE_TYPE) == (PPMF_TYPE_GNUC_PMF_CONV)), "clang does not support PPMF_TYPE_GNUC_PMF_CONV"); - static_assert(!(compile_info::type() == ci_compiler::NVCC && (PPMF_FORCE_TYPE) == (PPMF_TYPE_GNUC_PMF_CONV)), "nvcc does not support PPMF_TYPE_GNUC_PMF_CONV"); + static_assert(!(compile_info::type() == ci_compiler::CLANG && ppmf_internal_selector::value == (ppmf_type::GNUC_PMF_CONV)), "clang does not support ppmf_type::GNUC_PMF_CONV"); + static_assert(!(compile_info::env() == ci_env::NVCC && ppmf_internal_selector::value == (ppmf_type::GNUC_PMF_CONV)), "nvcc does not support ppmf_type::GNUC_PMF_CONV"); template<typename R, typename... Targs> struct mfp_traits @@ -138,11 +146,11 @@ namespace plib { /// /// The following class was derived from the MAME delegate.h code. /// - template <int PMFINTERNAL> + template <ppmf_type PMFINTERNAL> class mfp_raw; template <> - class mfp_raw<PPMF_TYPE_INTERNAL_ITANIUM> + class mfp_raw<ppmf_type::INTERNAL_ITANIUM> { public: // construct from any member function pointer @@ -156,14 +164,14 @@ namespace plib { // actual state uintptr_t m_function; // first item can be one of two things: - // if even, it's a pointer to the function - // if odd, it's the byte offset into the vtable - // or a byte offset into the function descriptors on IA64 + // if even, it's a pointer to the function + // if odd, it's the byte offset into the vtable + // or a byte offset into the function descriptors on IA64 ptrdiff_t m_this_delta; // delta to apply to the 'this' pointer }; template <> - class mfp_raw<PPMF_TYPE_INTERNAL_ARM> + class mfp_raw<ppmf_type::INTERNAL_ARM> { public: // construct from any member function pointer @@ -178,12 +186,12 @@ namespace plib { // actual state uintptr_t m_function; // first item can pointer to the function or a byte offset into the vtable ptrdiff_t m_this_delta; // delta to apply to the 'this' pointer after right shifting by one bit - // m_function is the byte offset into the vtable - // On IA64 it may also be a byte offset into the function descriptors + // m_function is the byte offset into the vtable + // On IA64 it may also be a byte offset into the function descriptors }; template <> - class mfp_raw<PPMF_TYPE_INTERNAL_MSC> + class mfp_raw<ppmf_type::INTERNAL_MSC> { public: // construct from any member function pointer @@ -214,11 +222,11 @@ namespace plib { std::is_same_v<std::remove_cv_t<R>, compile_info::int128_type> || std::is_same_v<std::remove_cv_t<R>, compile_info::uint128_type> >; - template<int PMFINTERNAL, typename R, typename... Targs> + template<ppmf_type PMFINTERNAL, typename R, typename... Targs> struct mfp_helper { protected: - static_assert(PMFINTERNAL >= PPMF_TYPE_INTERNAL_ITANIUM && PMFINTERNAL <= PPMF_TYPE_INTERNAL_MSC, "Invalid PMF type"); + static_assert(PMFINTERNAL >= ppmf_type::INTERNAL_ITANIUM && PMFINTERNAL <= ppmf_type::INTERNAL_MSC, "Invalid PMF type"); using traits = mfp_traits<R, Targs...>; using generic_member_function = typename traits::template specific_member_function<mfp_generic_class>; @@ -262,7 +270,7 @@ namespace plib { }; template<typename R, typename... Targs> - struct mfp_helper<PPMF_TYPE_PMF, R, Targs...> + struct mfp_helper<ppmf_type::PMF, R, Targs...> { protected: using traits = mfp_traits<R, Targs...>; @@ -292,9 +300,9 @@ namespace plib { static R stub(const generic_member_function* funci, mfp_generic_class* obji, Targs&&... args) noexcept(true); }; -#if NVCCBUILD == 0 +#if !defined(__NVCC__) template<typename R, typename... Targs> - struct mfp_helper<PPMF_TYPE_GNUC_PMF_CONV, R, Targs...> + struct mfp_helper<ppmf_type::GNUC_PMF_CONV, R, Targs...> { protected: using traits = mfp_traits<R, Targs...>; @@ -319,15 +327,15 @@ namespace plib { }; #endif - template <int PMFINTERNAL, typename R, typename... Targs> + template <ppmf_type PMFINTERNAL, typename R, typename... Targs> using pmfp_helper_select = std::conditional< pmf_is_register_return_type<R>::value - || PMFINTERNAL != PPMF_TYPE_INTERNAL_MSC || (PPMF_EXPERIMENTAL), - mfp_helper<PMFINTERNAL, R, Targs...>, mfp_helper<PPMF_TYPE_PMF, R, Targs...>>; + || PMFINTERNAL != ppmf_type::INTERNAL_MSC || (PPMF_EXPERIMENTAL), + mfp_helper<PMFINTERNAL, R, Targs...>, mfp_helper<ppmf_type::PMF, R, Targs...>>; - template<int PMFINTERNAL, typename SIGNATURE> class pmfp_base; + template<ppmf_type PMFINTERNAL, typename SIGNATURE> class pmfp_base; - template<int PMFINTERNAL, typename R, typename... Targs> + template<ppmf_type PMFINTERNAL, typename R, typename... Targs> class pmfp_base<PMFINTERNAL, R (Targs...)> : public pmfp_helper_select<PMFINTERNAL, R, Targs...>::type { public: @@ -377,7 +385,7 @@ namespace plib { }; template<typename Signature> - using pmfp = pmfp_base<ppmf_internal::value, Signature>; + using pmfp = pmfp_base<ppmf_internal_selector::value, Signature>; /// /// \brief Class to support delegate late binding @@ -424,7 +432,7 @@ namespace plib { }; template<typename MemberFunctionType> - mfp_raw<PPMF_TYPE_INTERNAL_ITANIUM>::mfp_raw(MemberFunctionType mftp) + mfp_raw<ppmf_type::INTERNAL_ITANIUM>::mfp_raw(MemberFunctionType mftp) : m_function(0), m_this_delta(0) { static_assert(sizeof(*this) >= sizeof(MemberFunctionType), "size mismatch"); @@ -433,7 +441,7 @@ namespace plib { } template<typename MemberFunctionType> - mfp_raw<PPMF_TYPE_INTERNAL_ARM>::mfp_raw(MemberFunctionType mftp) + mfp_raw<ppmf_type::INTERNAL_ARM>::mfp_raw(MemberFunctionType mftp) : m_function(0), m_this_delta(0) { static_assert(sizeof(*this) >= sizeof(MemberFunctionType), "size mismatch"); @@ -441,7 +449,7 @@ namespace plib { } template<typename MemberFunctionType> - mfp_raw<PPMF_TYPE_INTERNAL_MSC>::mfp_raw(MemberFunctionType mftp) + mfp_raw<ppmf_type::INTERNAL_MSC>::mfp_raw(MemberFunctionType mftp) : m_function(0), m_this_delta(0), m_vptr_index(0), m_vt_index(0), m_size(0) { static_assert(sizeof(*this) >= sizeof(MemberFunctionType), "size mismatch"); @@ -449,7 +457,7 @@ namespace plib { m_size = sizeof(mftp); //NOLINT } - template<int PMFINTERNAL, typename R, typename... Targs> + template<ppmf_type PMFINTERNAL, typename R, typename... Targs> mfp_helper<PMFINTERNAL, R, Targs...>::mfp_helper() : m_obj(nullptr) { @@ -458,7 +466,7 @@ namespace plib { std::fill(s, s + sizeof(m_resolved), 0); } - template<int PMFINTERNAL, typename R, typename... Targs> + template<ppmf_type PMFINTERNAL, typename R, typename... Targs> template<typename O, typename F> void mfp_helper<PMFINTERNAL, R, Targs...>::bind(O *object, F *mftp) { @@ -478,7 +486,7 @@ namespace plib { } template<typename R, typename... Targs> - mfp_helper<PPMF_TYPE_PMF, R, Targs...>::mfp_helper() + mfp_helper<ppmf_type::PMF, R, Targs...>::mfp_helper() : m_obj(nullptr) , m_stub(nullptr) { @@ -489,7 +497,7 @@ namespace plib { template<typename R, typename... Targs> template<typename O, typename F> - void mfp_helper<PPMF_TYPE_PMF, R, Targs...>::bind(O *object, F *mftp) + void mfp_helper<ppmf_type::PMF, R, Targs...>::bind(O *object, F *mftp) { reinterpret_copy(*mftp, this->m_resolved); // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) @@ -499,7 +507,7 @@ namespace plib { template<typename R, typename... Targs> template<typename O> - R mfp_helper<PPMF_TYPE_PMF, R, Targs...>::stub(const generic_member_function* funci, mfp_generic_class* obji, Targs&&... args) noexcept(true) + R mfp_helper<ppmf_type::PMF, R, Targs...>::stub(const generic_member_function* funci, mfp_generic_class* obji, Targs&&... args) noexcept(true) { // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) auto* obj = reinterpret_cast<O*>(obji); @@ -508,9 +516,9 @@ namespace plib { return (obj->*(*func))(std::forward<Targs>(args)...); } -#if NVCCBUILD == 0 +#if !defined(__NVCC__) template<typename R, typename... Targs> - mfp_helper<PPMF_TYPE_GNUC_PMF_CONV, R, Targs...>::mfp_helper() + mfp_helper<ppmf_type::GNUC_PMF_CONV, R, Targs...>::mfp_helper() : m_obj(nullptr) { // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) @@ -520,7 +528,7 @@ namespace plib { template<typename R, typename... Targs> template<typename O, typename F> - void mfp_helper<PPMF_TYPE_GNUC_PMF_CONV, R, Targs...>::bind(O *object, F *mftp) + void mfp_helper<ppmf_type::GNUC_PMF_CONV, R, Targs...>::bind(O *object, F *mftp) { // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) member_abi_function<O> t = reinterpret_cast<member_abi_function<O>>(object->*(*mftp)); diff --git a/src/lib/netlist/plib/ppreprocessor.h b/src/lib/netlist/plib/ppreprocessor.h index 8fd8db1ac44..1e21e72a5b0 100644 --- a/src/lib/netlist/plib/ppreprocessor.h +++ b/src/lib/netlist/plib/ppreprocessor.h @@ -52,8 +52,8 @@ namespace plib { /// /// \param filename a filename or identifier identifying the stream. /// - /// FIXME: this is sub-optimal. Refactor input_context into pinput_context - /// and pass this to ppreprocessor. + /// FIXME: this is sub-optimal. Refactor input_context into `pinput`_context + /// and pass this to `ppreprocessor`. /// template <typename T> pstring process(T &&istrm, const pstring &filename) diff --git a/src/lib/netlist/plib/prandom.h b/src/lib/netlist/plib/prandom.h index 03e066f94cd..062e0507705 100644 --- a/src/lib/netlist/plib/prandom.h +++ b/src/lib/netlist/plib/prandom.h @@ -145,9 +145,8 @@ namespace plib } template <typename ST> - void save_state(ST &st) + void save_state([[maybe_unused]] ST &st) { - plib::unused_var(st); /* no state to save */ } diff --git a/src/lib/netlist/plib/pstonum.h b/src/lib/netlist/plib/pstonum.h index 7b3492c29d0..18c67ca2b86 100644 --- a/src/lib/netlist/plib/pstonum.h +++ b/src/lib/netlist/plib/pstonum.h @@ -85,7 +85,7 @@ namespace plib template<> struct pstonum_helper<FLOAT128> { - // FIXME: use strtoflt128 from quadmath.h + // FIXME: use `strtoflt128` from `quadmath.h` template <typename S> FLOAT128 operator()(std::locale loc, const S &arg, bool *err) { diff --git a/src/lib/netlist/plib/pstream.h b/src/lib/netlist/plib/pstream.h index 0d1545e58b3..30c9f2b5c08 100644 --- a/src/lib/netlist/plib/pstream.h +++ b/src/lib/netlist/plib/pstream.h @@ -16,7 +16,6 @@ #include <array> #include <fstream> -#include <fstream> #include <ios> #include <iostream> #include <memory> @@ -26,7 +25,7 @@ namespace plib { - /// \brief wrapper around isteam read + /// \brief wrapper around istream read /// template <typename S, typename T> static S & istream_read(S &is, T * data, size_t len) @@ -37,7 +36,7 @@ namespace plib { return is.read(reinterpret_cast<ct *>(data), gsl::narrow<std::streamsize>(len * sizeof(T))); } - /// \brief wrapper around osteam write + /// \brief wrapper around ostream write /// template <typename S, typename T> static S & ostream_write(S &os, const T * data, size_t len) @@ -366,7 +365,7 @@ class ifstream : public std::ifstream { public: - using filename_type = std::conditional<compile_info::win32() && (!compile_info::mingw() || compile_info::version()>=900), + using filename_type = std::conditional<compile_info::win32() && (!compile_info::mingw() || compile_info::version::vmajor()>=9), pstring_t<pwchar_traits>, pstring_t<putf8_traits>>::type; template <typename T> @@ -387,7 +386,7 @@ public: class ofstream : public std::ofstream { public: - using filename_type = std::conditional<compile_info::win32() && (!compile_info::mingw() || compile_info::version()>=900), + using filename_type = std::conditional<compile_info::win32() && (!compile_info::mingw() || compile_info::version::vmajor()>=9), pstring_t<pwchar_traits>, pstring_t<putf8_traits>>::type; template <typename T> diff --git a/src/lib/netlist/plib/ptests.h b/src/lib/netlist/plib/ptests.h index 1aac62997f4..856cbacf735 100644 --- a/src/lib/netlist/plib/ptests.h +++ b/src/lib/netlist/plib/ptests.h @@ -15,6 +15,8 @@ #include <iostream> #include <string> #include <vector> +#include <algorithm> +#include <sstream> #if defined(__clang__) #pragma clang diagnostic ignored "-Wglobal-constructors" @@ -35,43 +37,80 @@ #define PTEST(name, desc) PINT_TEST(name, desc) #define PTEST_F(name, desc) PINT_TEST_F(name, desc, name) -#define PRUN_ALL_TESTS() plib::testing::run_all_tests() +#define PRUN_ALL_TESTS(loglevel) plib::testing::run_all_tests(loglevel) #define PINT_TEST(name, desc) PINT_TEST_F(name, desc, plib::testing::Test) +#define PINT_TESTNAME(name, desc) name ## _ ## desc +#define PINT_LOCATION() ::plib::testing::test_location(__FILE__, __LINE__) +#define PINT_SET_LAST(loc) this->m_parameters->m_last_source = loc + +#define PINT_REGISTER(name, desc) \ + extern const plib::testing::reg_entry<PINT_TESTNAME(name, desc)> PINT_TESTNAME(name, desc ## _reg); \ + const plib::testing::reg_entry<PINT_TESTNAME(name, desc)> PINT_TESTNAME(name, desc ## _reg)(#name, #desc, PINT_LOCATION()); \ + #define PINT_TEST_F(name, desc, base) \ - class name ## _ ## desc : public base \ + class PINT_TESTNAME(name, desc) : public base \ { public:\ void desc (); \ void run() override { desc (); } \ }; \ - extern const plib::testing::reg_entry<name ## _ ## desc> name ## _ ## desc ## _reg; \ - const plib::testing::reg_entry<name ## _ ## desc> name ## _ ## desc ## _reg(#name, #desc); \ - void name ## _ ## desc :: desc () + PINT_REGISTER(name, desc) \ + void PINT_TESTNAME(name, desc) :: desc () #define PINT_EXPECT(comp, exp1, exp2) \ - if (!plib::testing::internal_assert(plib::testing::comp_ ## comp (), # exp1, # exp2, exp1, exp2)) \ - std::cout << __FILE__ << ":" << __LINE__ << ":1: error: test failed\n" + if (true) \ + { \ + ::plib::testing::test_location source = PINT_LOCATION(); PINT_SET_LAST(source); \ + m_parameters->m_num_tests++; \ + if (!this->internal_assert(plib::testing::comp_ ## comp (), # exp1, # exp2, exp1, exp2)) \ + this->test_error(source) << "test failed" << std::endl; \ + } else do {} while (0) #define PINT_EXPECT_THROW(exp, excep) \ - if (const char *ptest_f = __FILE__) \ + if (true) \ { \ - try { exp; std::cout << ptest_f << ":" << __LINE__ << ":1: error: no " #excep " exception thrown\n";} \ - catch (excep &) { std::cout << "\tOK: got " #excep " for " # exp "\n";} \ - catch (std::exception &ptest_e) { std::cout << ptest_f << ":" << __LINE__ << ":1: error: unexpected exception thrown: " << ptest_e.what() << "\n"; } \ - catch (...) { std::cout << ptest_f << ":" << __LINE__ << ":1: error: unexpected exception thrown\n"; } \ + ::plib::testing::test_location source = PINT_LOCATION(); PINT_SET_LAST(source); \ + m_parameters->m_num_tests++; \ + try { exp; this->test_error(source) << "no " #excep " exception thrown" << std::endl;} \ + catch (excep &) { this->test_ok() << "got " #excep " for " # exp "" << std::endl;} \ + catch (std::exception &ptest_e) { this->test_error(source) << "unexpected exception thrown: " << ptest_e.what() << std::endl; } \ + catch (...) { this->test_error(source) << "unexpected exception thrown" << std::endl; } \ } else do {} while (0) #define PINT_EXPECT_NO_THROW(exp) \ - if (const char *ptest_f = __FILE__) \ + if (true) \ { \ - try { exp; std::cout << "\tOK: got no exception for " # exp "\n";} \ - catch (std::exception &ptest_e) { std::cout << ptest_f << ":" << __LINE__ << ":1: error: unexpected exception thrown: " << ptest_e.what() << "\n"; } \ - catch (...) { std::cout << ptest_f << ":" << __LINE__ << ":1: error: unexpected exception thrown\n"; } \ + ::plib::testing::test_location source = PINT_LOCATION(); PINT_SET_LAST(source); \ + m_parameters->m_num_tests++; \ + try { exp; this->test_ok() << "got no exception for " # exp << std::endl;} \ + catch (std::exception &ptest_e) { this->test_error(source) << "unexpected exception thrown: " << ptest_e.what() << std::endl; } \ + catch (...) { this->test_error(source) << "unexpected exception thrown" << std::endl; } \ } else do {} while (0) namespace plib::testing { + enum class loglevel + { + INFO, + WARNING, + ERROR + }; + + using test_location = std::pair<const char *, std::size_t>; + + struct test_parameters + { + loglevel m_loglevel = loglevel::INFO; + std::size_t m_num_errors = 0; + std::size_t m_num_tests = 0; + test_location m_last_source = {"", 0 }; + }; + + static std::ostream &stream_error(std::ostream &os, test_location loc) + { + return os << loc.first << ":" << loc.second << ":1: error: "; + } class Test { @@ -87,13 +126,54 @@ namespace plib::testing virtual void run() {} virtual void SetUp() {} virtual void TearDown() {} + + void set_parameters(test_parameters *params) + { + m_parameters = params; + } + protected: + std::ostream & test_ok() { return output(loglevel::INFO) << "\tOK: "; } + std::ostream & test_fail() { return output(loglevel::WARNING) << "\tFAIL: "; } + std::ostream & test_error(const test_location & loc) + { + return stream_error(output(loglevel::ERROR), loc); + } + + template <typename C, typename T1, typename T2> + bool internal_assert(C comp, + const char* exp1, const char* exp2, + const T1& val1, const T2& val2); + test_parameters *m_parameters = nullptr; + private: + std::ostream &output(loglevel ll) + { + if (ll == loglevel::ERROR) + m_parameters->m_num_errors++; + return (ll >= m_parameters->m_loglevel) ? std::cout : m_nulstream; + } + std::ostringstream m_nulstream; }; + template <typename C, typename T1, typename T2> + bool Test::internal_assert(C comp, + const char* exp1, const char* exp2, + const T1& val1, const T2& val2) + { + if (comp(val1, val2)) + { + test_ok() << exp1 << " " << C::opstr() << " " << exp2 << std::endl; + return true; + } + test_fail() << exp1 << " " << C::opstr() << " " << exp2 + << " <" << val1 << ">,<" << val2 << ">" << std::endl; + return false; + } + struct reg_entry_base { using list_t = std::vector<reg_entry_base *>; - reg_entry_base(const std::string &n, const std::string &d) - : name(n), desc(d) + reg_entry_base(const char *n, const char *d, test_location l) + : name(n), desc(d), location(l) { registry().push_back(this); } @@ -107,8 +187,9 @@ namespace plib::testing virtual Test *create() const { return nullptr; } - std::string name; - std::string desc; + const char *name; + const char *desc; + test_location location; public: static list_t & registry() { @@ -125,36 +206,81 @@ namespace plib::testing Test *create() const override { return new T(); } // NOLINT }; - template <typename C, typename T1, typename T2> - bool internal_assert(C comp, - const char* exp1, const char* exp2, - const T1& val1, const T2& val2) + template <typename L> + std::pair<bool, std::string> catch_exception(L lambda) { - if (comp(val1, val2)) + try { + lambda(); + } + catch (std::exception &ptest_e) { - std::cout << "\tOK: " << exp1 << " " << C::opstr() << " " << exp2 << "\n"; - return true; + return { true, ptest_e.what() }; } - std::cout << "\tFAIL: " << exp1 << " " << C::opstr() << " " << exp2 - << " <" << val1 << ">,<" << val2 << ">\n"; - return false; + catch (...) + { + return { true, "" }; + } + return { false, "" }; } - static inline int run_all_tests() + static inline int run_all_tests(loglevel ll) { - std::cout << "======================================\n"; - std::cout << "Running " << reg_entry_base::registry().size() << " tests\n"; - std::cout << "======================================\n"; - for (auto &e : reg_entry_base::registry()) + std::cout << "================================================" << std::endl; + std::cout << "Running " << reg_entry_base::registry().size() << " test groups" << std::endl; + std::cout << "================================================" << std::endl; + + auto &list = reg_entry_base::registry(); + + std::sort(list.begin(), list.end(), [](reg_entry_base *a, reg_entry_base *b) { + return (a->name < b->name); + }); + + std::size_t total_errors(0); + std::size_t total_tests(0); + + for (auto &e : list) { - std::cout << e->name << "::" << e->desc << ":\n"; - Test *t = e->create(); - t->SetUp(); - t->run(); - t->TearDown(); - delete t; + test_parameters params; + params.m_loglevel = ll; + params.m_last_source = e->location; + + std::cout << e->name << "::" << e->desc << ":" << std::endl; + Test *t = nullptr; + + std::pair<bool, std::string> r; + if ((r = catch_exception([&]{ + t = e->create(); + t->set_parameters(¶ms); + })).first) + { + stream_error(std::cout, e->location) << "unexpected exception thrown during instantiation" << (r.second != "" ? ": " + r.second : "") << std::endl; + total_errors++; + } + else if ((r = catch_exception([&]{ t->SetUp(); })).first) + { + stream_error(std::cout, e->location) << "unexpected exception thrown during Setup" << (r.second != "" ? ": " + r.second : "") << std::endl; + total_errors++; + } + else if ((r = catch_exception([&]{ t->run(); })).first) + { + stream_error(std::cout, params.m_last_source) << "unexpected exception thrown during run after this line" << (r.second != "" ? ": " + r.second : "") << std::endl; + total_errors++; + } + else if ((r = catch_exception([&]{ t->TearDown(); })).first) + { + stream_error(std::cout, e->location) << "unexpected exception thrown during Teardown" << (r.second != "" ? ": " + r.second : "") << std::endl; + total_errors++; + } + + total_errors += params.m_num_errors; + total_tests += params.m_num_tests; + if (t != nullptr) + delete t; } - return 0; + std::cout << "================================================" << std::endl; + std::cout << "Found " << total_errors << " errors in " << total_tests << " tests from " << reg_entry_base::registry().size() << " test groups" << std::endl; + std::cout << "================================================" << std::endl; + return (total_errors ? 1 : 0); } #define DEF_COMP(name, op) \ diff --git a/src/lib/netlist/plib/ptime.h b/src/lib/netlist/plib/ptime.h index 3d5c912f812..cb597aa590f 100644 --- a/src/lib/netlist/plib/ptime.h +++ b/src/lib/netlist/plib/ptime.h @@ -60,10 +60,9 @@ namespace plib } template <typename O, typename T = std::enable_if_t<!ptime_le<ptime<O, RES>, ptime>::value, int>> - constexpr explicit ptime(const ptime<O, RES> &rhs, T dummy = 0) noexcept + constexpr explicit ptime(const ptime<O, RES> &rhs,[[maybe_unused]] T dummy = 0) noexcept : m_time(static_cast<TYPE>(rhs.m_time)) { - plib::unused_var(dummy); } template <typename O> diff --git a/src/lib/netlist/plib/ptypes.h b/src/lib/netlist/plib/ptypes.h index 12e2a73f826..7f09a083793 100644 --- a/src/lib/netlist/plib/ptypes.h +++ b/src/lib/netlist/plib/ptypes.h @@ -81,8 +81,7 @@ namespace plib UNKNOWN, CLANG, GCC, - MSC, - NVCC + MSC }; enum class ci_cpp_stdlib @@ -115,7 +114,18 @@ namespace plib enum class ci_env { DEFAULT, - MSVC + MSVC, + NVCC + }; + + // <sys/types.h> on ubuntu system may define major and minor as macros + // That's why we use vmajor, .. here + template <std::size_t MAJOR, std::size_t MINOR> + struct typed_version + { + using vmajor = std::integral_constant<std::size_t, MAJOR>; + using vminor = std::integral_constant<std::size_t, MINOR>; + using full = std::integral_constant<std::size_t, MAJOR * 100 + MINOR>; }; struct compile_info @@ -144,21 +154,18 @@ namespace plib static constexpr int128_type int128_max() { return int128_type(); } static constexpr uint128_type uint128_max() { return uint128_type(); } #endif - #if (NVCCBUILD > 0) - using type = std::integral_constant<ci_compiler, ci_compiler::NVCC>; - using version = std::integral_constant<int, NVCCBUILD>; - #elif defined(__clang__) + #if defined(__clang__) using type = std::integral_constant<ci_compiler, ci_compiler::CLANG>; - using version = std::integral_constant<int, (__clang_major__) * 100 + (__clang_minor__)>; + using version = typed_version<__clang_major__, __clang_minor__>; #elif defined(__GNUC__) using type = std::integral_constant<ci_compiler, ci_compiler::GCC>; - using version = std::integral_constant<int, (__GNUC__) * 100 + (__GNUC_MINOR__)>; + using version = typed_version< __GNUC__, __GNUC_MINOR__ >; #elif defined(_MSC_VER) using type = std::integral_constant<ci_compiler, ci_compiler::MSC>; - using version = std::integral_constant<int, _MSC_VER>; + using version = typed_version<_MSC_VER / 100, _MSC_VER % 100>; #else using type = std::integral_constant<ci_compiler, ci_compiler::UNKNOWN>; - using version = std::integral_constant<int, 0>; + using version = typed_version<0, 0>; #endif #if defined(_LIBCPP_VERSION) using cpp_stdlib = std::integral_constant<ci_cpp_stdlib, ci_cpp_stdlib::LIBCPP>; @@ -212,9 +219,9 @@ namespace plib using mingw = std::integral_constant<bool, false>; #endif #if defined(__APPLE__) - using clang_noexcept_issue = std::integral_constant<bool, version::value < 1100>; + using clang_noexcept_issue = std::integral_constant<bool, version::vmajor::value < 11>; #else - using clang_noexcept_issue = std::integral_constant<bool, (type::value == ci_compiler::CLANG) && (version::value < 800)>; + using clang_noexcept_issue = std::integral_constant<bool, (type::value == ci_compiler::CLANG) && (version::vmajor::value < 8)>; #endif #if defined(__ia64__) using abi_vtable_function_descriptors = std::integral_constant<bool, true>; @@ -223,8 +230,18 @@ namespace plib #endif #if defined(_MSC_VER) using env = std::integral_constant<ci_env, ci_env::MSVC>; + using env_version = typed_version<_MSC_VER / 100, _MSC_VER % 100>; + #elif defined(__NVCC__) || defined(__CUDACC__) + using env = std::integral_constant<ci_env, ci_env::NVCC>; + using env_version = typed_version<__CUDA_API_VER_MAJOR__, __CUDA_API_VER_MINOR__>; + #if defined(__CUDA_ARCH__) + using cuda_arch = std::integral_constant<std::size_t, __CUDA_ARCH__>; + #else + using cuda_arch = std::integral_constant<std::size_t, 0>; + #endif #else using env = std::integral_constant<ci_env, ci_env::DEFAULT>; + using env_version = version; #endif }; @@ -336,7 +353,7 @@ namespace plib /// @tparam Ts unsused parameters /// template<typename... Ts> - inline void unused_var(Ts&&...) noexcept {} // NOLINT(readability-named-parameter) + inline void unused_var(Ts&&...) noexcept {} // NOLINT(readability-named-parameter) // FIXME: remove unused var completely /// \brief copy type S to type D byte by byte /// |