summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib/netlist/plib
diff options
context:
space:
mode:
author couriersud <couriersud@users.noreply.github.com>2022-05-21 17:16:50 +0200
committer GitHub <noreply@github.com>2022-05-22 01:16:50 +1000
commit324f9d44d5c4293645e7bb8f42e7d95d5ac1e604 (patch)
tree1ad2d66458486f184e11536e247309eb6c0161fb /src/lib/netlist/plib
parentb33946d980772bf8e973b3816684f313a5b4e9ea (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.h20
-rw-r--r--src/lib/netlist/plib/palloc.h18
-rw-r--r--src/lib/netlist/plib/pchrono.h2
-rw-r--r--src/lib/netlist/plib/pconfig.h36
-rw-r--r--src/lib/netlist/plib/pdynlib.cpp3
-rw-r--r--src/lib/netlist/plib/pdynlib.h7
-rw-r--r--src/lib/netlist/plib/pexception.cpp2
-rw-r--r--src/lib/netlist/plib/pexception.h2
-rw-r--r--src/lib/netlist/plib/pmath.h2
-rw-r--r--src/lib/netlist/plib/pomp.h4
-rw-r--r--src/lib/netlist/plib/poptions.cpp3
-rw-r--r--src/lib/netlist/plib/ppmf.cpp8
-rw-r--r--src/lib/netlist/plib/ppmf.h112
-rw-r--r--src/lib/netlist/plib/ppreprocessor.h4
-rw-r--r--src/lib/netlist/plib/prandom.h3
-rw-r--r--src/lib/netlist/plib/pstonum.h2
-rw-r--r--src/lib/netlist/plib/pstream.h9
-rw-r--r--src/lib/netlist/plib/ptests.h210
-rw-r--r--src/lib/netlist/plib/ptime.h3
-rw-r--r--src/lib/netlist/plib/ptypes.h45
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(&params);
+ })).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
///