Added compile-time static_assert for assumptions we make in this app

They are basically taken from BCHN sources compact/assumptions.h, but
rather than live in a header, we put them into Common.cpp.
This commit is contained in:
Calin Culianu 2021-07-01 17:51:43 -04:00
parent 704bc27963
commit 4ad1ce2c73
No known key found for this signature in database
GPG key ID: 21810A542031C02C

View file

@ -22,3 +22,52 @@
Exception::~Exception() {}
InternalError::~InternalError() {}
BadArgs::~BadArgs() {}
// Compile-time verification of assumptions we make. The below is basically taken from BCHN: src/compat/assumptions.h.
#include <cstdint>
#include <limits>
#include <type_traits>
// Assumption: We assume a C++17 (ISO/IEC 14882:2017) compiler (minimum requirement).
// Example(s): We may use use C++17 only constructs such as if constexpr, structured binding, std::is_same_v, etc.
// Note: MSVC does not report the expected __cplusplus value due to legacy reasons.
#if !defined(_MSC_VER)
// N4713 §19.8/p1 [cpp.predefined]/p1::
// "The name __cplusplus is defined to the value 201703L when compiling a C++ translation unit."
static_assert (__cplusplus >= 201703L, "C++17 standard assumed");
#endif
// Assumption: We assume the floating-point types to fulfill the requirements of IEC 559 (IEEE 754) standard.
static_assert (std::numeric_limits<float>::is_iec559, "IEEE 754 float assumed");
static_assert (std::numeric_limits<double>::is_iec559, "IEEE 754 double assumed");
// Assumption: We assume floating-point widths.
// Example(s): Type punning in serialization code (ser_{float,double}_to_uint{32,64}).
static_assert (sizeof(float) == 4, "32-bit float assumed");
static_assert (sizeof(double) == 8, "64-bit double assumed");
// Assumption: We assume integer widths.
// Example(s): GetSizeOfCompactSize and WriteCompactSize in the serialization code.
static_assert (sizeof(short) == 2, "16-bit short assumed");
static_assert (sizeof(int) == 4, "32-bit int assumed");
// Assumption: We assume 8-bit bytes, because 32-bit int and 16-bit short are assumed.
// (This is another way of saying CHAR_BIT == 8)
static_assert (std::numeric_limits<unsigned char>::min() == 0 && std::numeric_limits<unsigned char>::max() == 255,
"8-bit bytes assumed");
// Assumption: We assume uint8_t is an alias of unsigned char. char, unsigned char, and std::byte (C++17) are the only
// "byte types" according to the C++ Standard. "byte type" means a type that can be used to observe an object's value
// representation. We use uint8_t everywhere to see bytes, so we have to ensure that uint8_t is an alias to a
// "byte type".
// http://eel.is/c++draft/basic.types
// http://eel.is/c++draft/basic.memobj#def:byte
// http://eel.is/c++draft/expr.sizeof#1
// http://eel.is/c++draft/cstdint#syn
static_assert (std::is_same_v<uint8_t, unsigned char>, "uint8_t is an alias of unsigned char is assumed");
// Some important things we are NOT assuming (non-exhaustive list):
// * We are NOT assuming a specific value for sizeof(std::size_t).
// * We are NOT assuming a specific value for std::endian::native.
// * We are NOT assuming a specific value for std::locale("").name().
// * We are NOT assuming a specific value for std::numeric_limits<char>::is_signed.