basedOpinionated utility library |
git clone git://git.dimitrijedobrota.com/based.git |
Log | Files | Refs | README | LICENSE | HACKING | CONTRIBUTING | CODE_OF_CONDUCT | BUILDING |
commit | 3856d3137cdba85b4727fc08a4c6cd9678771686 |
parent | 510a7d2b0afcfb88e852707aeebb2fed23a8176f |
author | Dimitrije Dobrota < mail@dimitrijedobrota.com > |
date | Wed, 4 Jun 2025 15:10:40 +0200 |
Rework type conversions and literals
M | include/based/char/character.hpp | | | +++++++++ -------------------- |
M | include/based/char/mapper.hpp | | | +++ ---- |
M | include/based/container/array.hpp | | | ++ -- |
D | include/based/types/limits.hpp | | | --------------------------------------------------------------------------------- |
M | include/based/types/literals.hpp | | | ++++++++++++++++++ ------------------------------------ |
M | include/based/types/strong.hpp | | | ++ --- |
M | include/based/types/types.hpp | | | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ------------- |
M | test/source/types/limits.cpp | | | ++ -- |
M | test/source/types/literals.cpp | | | ++++++++++++++++++++++++ ------------------------ |
9 files changed, 271 insertions(+), 223 deletions(-)
diff --git a/ include/based/char/character.hpp b/ include/based/char/character.hpp
@@ -5,53 +5,42 @@
namespace based
{
class character : public strong_type<unsigned char, character>
struct character : public strong_type<char, character>
{
static constexpr auto cast(char pos)
{
return static_cast<unsigned char>(pos);
}
static constexpr auto cast(unsigned char pos)
{
return static_cast<char>(pos);
}
public:
using strong_type::strong_type;
using strong_type::operator=;
constexpr character(char chr) // NOLINT(*explicit*)
: strong_type(cast(chr))
: strong_type(chr)
{
}
explicit constexpr character(u8 ord)
: strong_type(ord.value)
: strong_type(static_cast<char>(ord.value))
{
}
[[nodiscard]] char chr() const { return cast(value); }
[[nodiscard]] u8 ord() const { return u8::basic_cast(value); }
[[nodiscard]] char chr() const { return value; }
[[nodiscard]] u8 ord() const { return u8::underlying_cast(value); }
friend constexpr bool operator==(character lhs, char rhs)
{
return lhs.value == cast(rhs);
return lhs.value == rhs;
}
friend constexpr bool operator==(char lhs, character rhs)
{
return cast(lhs) == rhs.value;
return lhs == rhs.value;
}
friend constexpr auto operator<=>(character lhs, char rhs)
{
return lhs.value <=> cast(rhs);
return lhs.value <=> rhs;
}
friend constexpr auto operator<=>(char lhs, character rhs)
{
return cast(lhs) <=> rhs.value;
return lhs <=> rhs.value;
}
};
diff --git a/ include/based/char/mapper.hpp b/ include/based/char/mapper.hpp
@@ -3,7 +3,6 @@
#include "based/char/character.hpp"
#include "based/concepts/procedure/predicate.hpp"
#include "based/container/array.hpp"
#include "based/types/limits.hpp"
#include "based/types/literals.hpp"
namespace based
@@ -24,7 +23,7 @@
class mapper
mapped_type count = 0_u8;
for (auto idx = 0_u8; idx < size; idx++) {
if (m_predicate(character::basic_cast(idx))) {
if (m_predicate(character::cast(idx))) {
res[idx] = count++;
}
}
@@ -36,7 +35,7 @@
class mapper
{
mapped_type count = 0_u8;
for (auto idx = 0_u8; idx < size; idx++) {
if (m_predicate(character::basic_cast(idx))) {
if (m_predicate(character::cast(idx))) {
count++;
}
}
@@ -50,7 +49,7 @@
class mapper
mapped_type count = 0_u8;
for (auto idx = 0_u8; idx < size; idx++) {
const auto chr = character::basic_cast(idx);
const auto chr = character::cast(idx);
if (m_predicate(chr)) {
res[count++] = chr;
}
diff --git a/ include/based/container/array.hpp b/ include/based/container/array.hpp
@@ -8,9 +8,9 @@
namespace based
{
template<class T, class U, U n>
class array : public std::array<T, u64::basic_cast(n).value>
class array : public std::array<T, u64::cast(n).value>
{
using base = std::array<T, u64::basic_cast(n).value>;
using base = std::array<T, u64::cast(n).value>;
static constexpr auto cast(U pos)
{
diff --git a/ include/based/types/limits.hpp b/ include/based/types/limits.hpp
@@ -1,95 +0,0 @@
#pragma once
#include "based/types/types.hpp"
namespace based
{
template<class T>
struct limits;
// Signed
template<>
struct limits<i8>
{
static constexpr bool is_integer = true;
static constexpr bool is_signed = true;
static constexpr auto min = i8::basic_cast(0x80);
static constexpr auto max = i8::basic_cast(0x7F);
};
template<>
struct limits<i16>
{
static constexpr bool is_integer = true;
static constexpr bool is_signed = true;
static constexpr auto min = i16::basic_cast(0x8000);
static constexpr auto max = i16::basic_cast(0x7FFF);
};
template<>
struct limits<i32>
{
static constexpr bool is_integer = true;
static constexpr bool is_signed = true;
static constexpr auto min = i32::basic_cast(0x80000000);
static constexpr auto max = i32::basic_cast(0x7FFFFFFF);
};
template<>
struct limits<i64>
{
static constexpr bool is_integer = true;
static constexpr bool is_signed = true;
static constexpr auto min = i64::basic_cast(0x8000000000000000);
static constexpr auto max = i64::basic_cast(0x7FFFFFFFFFFFFFFF);
};
// Unsigned
template<>
struct limits<u8>
{
static constexpr bool is_integer = true;
static constexpr bool is_signed = false;
static constexpr auto min = u8::basic_cast(0x00);
static constexpr auto max = u8::basic_cast(0xFF);
};
template<>
struct limits<u16>
{
static constexpr bool is_integer = true;
static constexpr bool is_signed = false;
static constexpr auto min = u16::basic_cast(0x0000);
static constexpr auto max = u16::basic_cast(0xFFFF);
};
template<>
struct limits<u32>
{
static constexpr bool is_integer = true;
static constexpr bool is_signed = false;
static constexpr auto min = u32::basic_cast(0x00000000);
static constexpr auto max = u32::basic_cast(0xFFFFFFFF);
};
template<>
struct limits<u64>
{
static constexpr bool is_integer = true;
static constexpr bool is_signed = false;
static constexpr auto min = u64::basic_cast(0x0000000000000000);
static constexpr auto max = u64::basic_cast(0xFFFFFFFFFFFFFFFF);
};
} // namespace based
diff --git a/ include/based/types/literals.hpp b/ include/based/types/literals.hpp
@@ -2,7 +2,6 @@
#include "based/char/is/digit.hpp"
#include "based/concepts/is/castable.hpp"
#include "based/types/limits.hpp"
#include "based/types/types.hpp"
// NOLINTBEGIN(google-runtime-int)
@@ -11,26 +10,17 @@
namespace based
{
// Signed
namespace detail
{
template<signed long long val>
constexpr auto make_signed_itnernal()
consteval i make_signed_itnernal()
{
if constexpr (val <= limits<i8>::max.value) {
return i8::basic_cast(val);
} else if constexpr (val <= limits<i16>::max.value) {
return i16::basic_cast(val);
} else if constexpr (val <= limits<i32>::max.value) {
return i32::basic_cast(val);
} else {
return i64::basic_cast(val);
}
return i::underlying_cast(val);
}
template<signed long long v, char c, char... cs>
constexpr auto make_signed_itnernal()
consteval auto make_signed_itnernal()
{
const signed long long radix = 10;
@@ -41,7 +31,7 @@
constexpr auto make_signed_itnernal()
}
template<char... cs>
constexpr auto make_signed()
consteval auto make_signed()
{
return make_signed_itnernal<0, cs...>();
}
@@ -52,7 +42,7 @@
namespace literals
{
template<char... cs>
auto operator"" _i()
consteval auto operator"" _i()
{
return detail::make_signed<cs...>();
}
@@ -61,28 +51,28 @@
template<char... cs>
requires CastableTo<decltype(detail::make_signed<cs...>()), u8>
consteval auto operator"" _i8()
{
return static_cast<u8>(detail::make_signed<cs...>());
return i8::cast(detail::make_signed<cs...>());
}
template<char... cs>
requires CastableTo<decltype(detail::make_signed<cs...>()), u16>
consteval auto operator"" _i16()
{
return static_cast<u16>(detail::make_signed<cs...>());
return i16::cast(detail::make_signed<cs...>());
}
template<char... cs>
requires CastableTo<decltype(detail::make_signed<cs...>()), u32>
consteval auto operator"" _i32()
{
return static_cast<u32>(detail::make_signed<cs...>());
return i32::cast(detail::make_signed<cs...>());
}
template<char... cs>
requires CastableTo<decltype(detail::make_signed<cs...>()), u64>
consteval auto operator"" _i64()
{
return static_cast<u64>(detail::make_signed<cs...>());
return i64::cast(detail::make_signed<cs...>());
}
} // namespace literals
@@ -93,21 +83,13 @@
namespace detail
{
template<unsigned long long val>
constexpr auto make_unsigned_internal()
consteval u make_unsigned_internal()
{
if constexpr (val <= limits<u8>::max.value) {
return u8::basic_cast(val);
} else if constexpr (val <= limits<u16>::max.value) {
return u16::basic_cast(val);
} else if constexpr (val <= limits<u32>::max.value) {
return u32::basic_cast(val);
} else {
return u64::basic_cast(val);
}
return u::underlying_cast(val);
}
template<unsigned long long v, char c, char... cs>
constexpr auto make_unsigned_internal()
consteval auto make_unsigned_internal()
{
const unsigned long long radix = 10;
@@ -118,7 +100,7 @@
constexpr auto make_unsigned_internal()
}
template<char... cs>
constexpr auto make_unsigned()
consteval auto make_unsigned()
{
return make_unsigned_internal<0, cs...>();
}
@@ -129,7 +111,7 @@
namespace literals
{
template<char... cs>
auto operator"" _u()
consteval auto operator"" _u()
{
return detail::make_unsigned<cs...>();
}
@@ -138,28 +120,28 @@
template<char... cs>
requires CastableTo<decltype(detail::make_unsigned<cs...>()), u8>
consteval auto operator"" _u8()
{
return static_cast<u8>(detail::make_unsigned<cs...>());
return u8::cast(detail::make_unsigned<cs...>());
}
template<char... cs>
requires CastableTo<decltype(detail::make_unsigned<cs...>()), u16>
consteval auto operator"" _u16()
{
return static_cast<u16>(detail::make_unsigned<cs...>());
return u16::cast(detail::make_unsigned<cs...>());
}
template<char... cs>
requires CastableTo<decltype(detail::make_unsigned<cs...>()), u32>
consteval auto operator"" _u32()
{
return static_cast<u32>(detail::make_unsigned<cs...>());
return u32::cast(detail::make_unsigned<cs...>());
}
template<char... cs>
requires CastableTo<decltype(detail::make_unsigned<cs...>()), u64>
consteval auto operator"" _u64()
{
return static_cast<u64>(detail::make_unsigned<cs...>());
return u64::cast(detail::make_unsigned<cs...>());
}
} // namespace literals
diff --git a/ include/based/types/strong.hpp b/ include/based/types/strong.hpp
@@ -46,14 +46,13 @@
struct strong_type
constexpr strong_type& operator=(strong_type&&) = default;
template<class T>
static constexpr Tag basic_cast(T value)
static constexpr Tag underlying_cast(T value)
{
return Tag {static_cast<basic_type>(value)};
}
template<class T>
requires is_class_v<T>
static constexpr Tag basic_cast(T value)
static constexpr Tag cast(T value)
{
return static_cast<Tag>(value);
}
diff --git a/ include/based/types/types.hpp b/ include/based/types/types.hpp
@@ -1,5 +1,6 @@
#pragma once
#include "based/assert.hpp"
#include "based/macro/foreach_1.hpp"
#include "based/types/strong.hpp"
@@ -20,6 +21,39 @@
using bu64 = unsigned long long int;
using size_t = bu64;
#define BASED_DETAIL_OP_UNARY(Prefix, Name, Index) \
auto Name(Prefix##8)->Prefix##8; \
auto Name(Prefix##16)->Prefix##16; \
auto Name(Prefix##32)->Prefix##32; \
auto Name(Prefix##64)->Prefix##64; \
auto Name(Prefix)->Prefix;
#define BASED_DETAIL_OP_BINARY(Prefix, Name, Index) \
auto Name(Prefix##8, Prefix##8)->Prefix##8; \
auto Name(Prefix##8, Prefix##16)->Prefix##16; \
auto Name(Prefix##8, Prefix##32)->Prefix##32; \
auto Name(Prefix##8, Prefix##64)->Prefix##64; \
\
auto Name(Prefix##16, Prefix##8)->Prefix##16; \
auto Name(Prefix##16, Prefix##16)->Prefix##16; \
auto Name(Prefix##16, Prefix##32)->Prefix##32; \
auto Name(Prefix##16, Prefix##64)->Prefix##64; \
\
auto Name(Prefix##32, Prefix##8)->Prefix##32; \
auto Name(Prefix##32, Prefix##16)->Prefix##32; \
auto Name(Prefix##32, Prefix##32)->Prefix##32; \
auto Name(Prefix##32, Prefix##64)->Prefix##64; \
\
auto Name(Prefix##64, Prefix##8)->Prefix##64; \
auto Name(Prefix##64, Prefix##16)->Prefix##64; \
auto Name(Prefix##64, Prefix##32)->Prefix##64; \
auto Name(Prefix##64, Prefix##64)->Prefix##64; \
\
auto Name(Prefix, Prefix)->Prefix;
template<class T>
struct limits;
struct i64 : strong_type<signed long long int, i64>
{
using strong_type::strong_type;
@@ -31,7 +65,9 @@
struct i32 : strong_type<signed int, i32>
using strong_type::strong_type;
using strong_type::operator=;
explicit constexpr operator i64() { return i64::basic_cast(value); }
explicit constexpr operator i64() { return i64::underlying_cast(value); }
[[nodiscard]] constexpr i64 to_i64() const { return i64::cast(*this); }
};
struct i16 : strong_type<signed short int, i16>
@@ -39,8 +75,11 @@
struct i16 : strong_type<signed short int, i16>
using strong_type::strong_type;
using strong_type::operator=;
explicit constexpr operator i64() { return i64::basic_cast(value); }
explicit constexpr operator i32() { return i32::basic_cast(value); }
explicit constexpr operator i64() { return i64::underlying_cast(value); }
explicit constexpr operator i32() { return i32::underlying_cast(value); }
[[nodiscard]] constexpr i64 to_i64() const { return i64::cast(*this); }
[[nodiscard]] constexpr i32 to_i32() const { return i32::cast(*this); }
};
struct i8 : strong_type<signed char, i8>
@@ -48,11 +87,91 @@
struct i8 : strong_type<signed char, i8>
using strong_type::strong_type;
using strong_type::operator=;
explicit constexpr operator i64() { return i64::basic_cast(value); }
explicit constexpr operator i32() { return i32::basic_cast(value); }
explicit constexpr operator i16() { return i16::basic_cast(value); }
explicit constexpr operator i64() { return i64::underlying_cast(value); }
explicit constexpr operator i32() { return i32::underlying_cast(value); }
explicit constexpr operator i16() { return i16::underlying_cast(value); }
[[nodiscard]] constexpr i64 to_i64() const { return i64::cast(*this); }
[[nodiscard]] constexpr i32 to_i32() const { return i32::cast(*this); }
[[nodiscard]] constexpr i16 to_i16() const { return i16::cast(*this); }
};
template<>
struct limits<i8>
{
static constexpr bool is_integer = true;
static constexpr bool is_signed = true;
static constexpr auto min = i8::underlying_cast(0x80);
static constexpr auto max = i8::underlying_cast(0x7F);
};
template<>
struct limits<i16>
{
static constexpr bool is_integer = true;
static constexpr bool is_signed = true;
static constexpr auto min = i16::underlying_cast(0x8000);
static constexpr auto max = i16::underlying_cast(0x7FFF);
};
template<>
struct limits<i32>
{
static constexpr bool is_integer = true;
static constexpr bool is_signed = true;
static constexpr auto min = i32::underlying_cast(0x80000000);
static constexpr auto max = i32::underlying_cast(0x7FFFFFFF);
};
template<>
struct limits<i64>
{
static constexpr bool is_integer = true;
static constexpr bool is_signed = true;
static constexpr auto min = i64::underlying_cast(0x8000000000000000);
static constexpr auto max = i64::underlying_cast(0x7FFFFFFFFFFFFFFF);
};
struct i : strong_type<signed long long int, i>
{
using strong_type::strong_type;
using strong_type::operator=;
consteval operator i8() const // NOLINT(*explicit*)
{
BASED_ASSERT(value >= limits<i8>::min.value);
BASED_ASSERT(value <= limits<i8>::max.value);
return i8::underlying_cast(value);
}
consteval operator i16() const // NOLINT(*explicit*)
{
BASED_ASSERT(value >= limits<i16>::min.value);
BASED_ASSERT(value <= limits<i16>::max.value);
return i16::underlying_cast(value);
}
consteval operator i32() const // NOLINT(*explicit*)
{
BASED_ASSERT(value >= limits<i32>::min.value);
BASED_ASSERT(value <= limits<i32>::max.value);
return i32::underlying_cast(value);
}
consteval operator i64() const // NOLINT(*explicit*)
{
BASED_ASSERT(value >= limits<i64>::min.value);
BASED_ASSERT(value <= limits<i64>::max.value);
return i64::underlying_cast(value);
}
};
auto unary(i) -> i;
struct u64 : strong_type<unsigned long long int, u64>
{
using strong_type::strong_type;
@@ -64,7 +183,9 @@
struct u32 : strong_type<unsigned int, u32>
using strong_type::strong_type;
using strong_type::operator=;
explicit constexpr operator u64() { return u64::basic_cast(value); }
explicit constexpr operator u64() { return u64::underlying_cast(value); }
[[nodiscard]] constexpr u64 to_u64() const { return u64::cast(*this); }
};
struct u16 : strong_type<unsigned short int, u16>
@@ -72,8 +193,11 @@
struct u16 : strong_type<unsigned short int, u16>
using strong_type::strong_type;
using strong_type::operator=;
explicit constexpr operator u64() { return u64::basic_cast(value); }
explicit constexpr operator u32() { return u32::basic_cast(value); }
explicit constexpr operator u64() { return u64::underlying_cast(value); }
explicit constexpr operator u32() { return u32::underlying_cast(value); }
[[nodiscard]] constexpr u64 to_u64() const { return u64::cast(*this); }
[[nodiscard]] constexpr u32 to_u32() const { return u32::cast(*this); }
};
struct u8 : strong_type<unsigned char, u8>
@@ -81,37 +205,87 @@
struct u8 : strong_type<unsigned char, u8>
using strong_type::strong_type;
using strong_type::operator=;
explicit constexpr operator u64() { return u64::basic_cast(value); }
explicit constexpr operator u32() { return u32::basic_cast(value); }
explicit constexpr operator u16() { return u16::basic_cast(value); }
explicit constexpr operator u64() { return u64::underlying_cast(value); }
explicit constexpr operator u32() { return u32::underlying_cast(value); }
explicit constexpr operator u16() { return u16::underlying_cast(value); }
[[nodiscard]] constexpr u64 to_u64() const { return u64::cast(*this); }
[[nodiscard]] constexpr u32 to_u32() const { return u32::cast(*this); }
[[nodiscard]] constexpr u16 to_u16() const { return u16::cast(*this); }
};
#define BASED_DETAIL_OP_UNARY(Prefix, Name, Index) \
auto Name(Prefix##8)->Prefix##8; \
auto Name(Prefix##16)->Prefix##16; \
auto Name(Prefix##32)->Prefix##32; \
auto Name(Prefix##64)->Prefix##64;
template<>
struct limits<u8>
{
static constexpr bool is_integer = true;
static constexpr bool is_signed = false;
#define BASED_DETAIL_OP_BINARY(Prefix, Name, Index) \
auto Name(Prefix##8, Prefix##8)->Prefix##8; \
auto Name(Prefix##8, Prefix##16)->Prefix##16; \
auto Name(Prefix##8, Prefix##32)->Prefix##32; \
auto Name(Prefix##8, Prefix##64)->Prefix##64; \
\
auto Name(Prefix##16, Prefix##8)->Prefix##16; \
auto Name(Prefix##16, Prefix##16)->Prefix##16; \
auto Name(Prefix##16, Prefix##32)->Prefix##32; \
auto Name(Prefix##16, Prefix##64)->Prefix##64; \
\
auto Name(Prefix##32, Prefix##8)->Prefix##32; \
auto Name(Prefix##32, Prefix##16)->Prefix##32; \
auto Name(Prefix##32, Prefix##32)->Prefix##32; \
auto Name(Prefix##32, Prefix##64)->Prefix##64; \
\
auto Name(Prefix##64, Prefix##8)->Prefix##64; \
auto Name(Prefix##64, Prefix##16)->Prefix##64; \
auto Name(Prefix##64, Prefix##32)->Prefix##64; \
auto Name(Prefix##64, Prefix##64)->Prefix##64;
static constexpr auto min = u8::underlying_cast(0x00);
static constexpr auto max = u8::underlying_cast(0xFF);
};
template<>
struct limits<u16>
{
static constexpr bool is_integer = true;
static constexpr bool is_signed = false;
static constexpr auto min = u16::underlying_cast(0x0000);
static constexpr auto max = u16::underlying_cast(0xFFFF);
};
template<>
struct limits<u32>
{
static constexpr bool is_integer = true;
static constexpr bool is_signed = false;
static constexpr auto min = u32::underlying_cast(0x00000000);
static constexpr auto max = u32::underlying_cast(0xFFFFFFFF);
};
template<>
struct limits<u64>
{
static constexpr bool is_integer = true;
static constexpr bool is_signed = false;
static constexpr auto min = u64::underlying_cast(0x0000000000000000);
static constexpr auto max = u64::underlying_cast(0xFFFFFFFFFFFFFFFF);
};
struct u : strong_type<unsigned long long int, u>
{
using strong_type::strong_type;
consteval operator u8() const // NOLINT(*explicit*)
{
BASED_ASSERT(value >= limits<u8>::min.value);
BASED_ASSERT(value <= limits<u8>::max.value);
return u8::underlying_cast(value);
}
consteval operator u16() const // NOLINT(*explicit*)
{
BASED_ASSERT(value >= limits<u16>::min.value);
BASED_ASSERT(value <= limits<u16>::max.value);
return u16::underlying_cast(value);
}
consteval operator u32() const // NOLINT(*explicit*)
{
BASED_ASSERT(value >= limits<u32>::min.value);
BASED_ASSERT(value <= limits<u32>::max.value);
return u32::underlying_cast(value);
}
consteval operator u64() const // NOLINT(*explicit*)
{
BASED_ASSERT(value >= limits<u64>::min.value);
BASED_ASSERT(value <= limits<u64>::max.value);
return u64::underlying_cast(value);
}
};
BASED_FOREACH_1(
i, BASED_DETAIL_OP_UNARY, unary, preinc, postinc, predec, postdec
diff --git a/ test/source/types/limits.cpp b/ test/source/types/limits.cpp
@@ -1,9 +1,9 @@
#define CATCH_CONFIG_RUNTIME_STATIC_REQUIRE
#include "based/types/limits.hpp"
#include <catch2/catch_test_macros.hpp>
#include "based/types/types.hpp"
using based::limits;
TEST_CASE("unsigned", "[types/literals]")
diff --git a/ test/source/types/literals.cpp b/ test/source/types/literals.cpp
@@ -4,38 +4,38 @@
#include <catch2/catch_test_macros.hpp>
#include "based/concepts/is/same.hpp"
#include "based/concepts/is/castable.hpp"
using namespace based::literals; // NOLINT(*namespace*)
using based::SameAs;
using based::CastableTo;
TEST_CASE("unsigned", "[types/literals]")
{
STATIC_REQUIRE(SameAs<decltype(0_u), based::u8>);
STATIC_REQUIRE(SameAs<decltype(255_u), based::u8>);
STATIC_REQUIRE(SameAs<decltype(256_u), based::u16>);
STATIC_REQUIRE(SameAs<decltype(65535_u), based::u16>);
STATIC_REQUIRE(SameAs<decltype(65536_u), based::u32>);
STATIC_REQUIRE(SameAs<decltype(4294967295_u), based::u32>);
STATIC_REQUIRE(SameAs<decltype(4294967296_u), based::u64>);
STATIC_REQUIRE(SameAs<decltype(18446744073709551615_u), based::u64>);
STATIC_REQUIRE(CastableTo<decltype(0_u), based::u8>);
STATIC_REQUIRE(CastableTo<decltype(255_u), based::u8>);
STATIC_REQUIRE(CastableTo<decltype(256_u), based::u16>);
STATIC_REQUIRE(CastableTo<decltype(65535_u), based::u16>);
STATIC_REQUIRE(CastableTo<decltype(65536_u), based::u32>);
STATIC_REQUIRE(CastableTo<decltype(4294967295_u), based::u32>);
STATIC_REQUIRE(CastableTo<decltype(4294967296_u), based::u64>);
STATIC_REQUIRE(CastableTo<decltype(18446744073709551615_u), based::u64>);
}
TEST_CASE("signed", "[types/literals]")
{
STATIC_REQUIRE(SameAs<decltype(0_i), based::i8>);
STATIC_REQUIRE(SameAs<decltype(127_i), based::i8>);
STATIC_REQUIRE(SameAs<decltype(128_i), based::i16>);
STATIC_REQUIRE(SameAs<decltype(32767_i), based::i16>);
STATIC_REQUIRE(SameAs<decltype(2147483647_i), based::i32>);
STATIC_REQUIRE(SameAs<decltype(2147483648_i), based::i64>);
STATIC_REQUIRE(SameAs<decltype(9223372036854775807_i), based::i64>);
STATIC_REQUIRE(SameAs<decltype(-127_i), based::i8>);
STATIC_REQUIRE(SameAs<decltype(-128_i), based::i16>);
STATIC_REQUIRE(SameAs<decltype(-32767_i), based::i16>);
STATIC_REQUIRE(SameAs<decltype(-2147483647_i), based::i32>);
STATIC_REQUIRE(SameAs<decltype(-2147483648_i), based::i64>);
STATIC_REQUIRE(SameAs<decltype(-9223372036854775807_i), based::i64>);
STATIC_REQUIRE(CastableTo<decltype(0_i), based::i8>);
STATIC_REQUIRE(CastableTo<decltype(127_i), based::i8>);
STATIC_REQUIRE(CastableTo<decltype(128_i), based::i16>);
STATIC_REQUIRE(CastableTo<decltype(32767_i), based::i16>);
STATIC_REQUIRE(CastableTo<decltype(2147483647_i), based::i32>);
STATIC_REQUIRE(CastableTo<decltype(2147483648_i), based::i64>);
STATIC_REQUIRE(CastableTo<decltype(9223372036854775807_i), based::i64>);
STATIC_REQUIRE(CastableTo<decltype(-127_i), based::i8>);
STATIC_REQUIRE(CastableTo<decltype(-128_i), based::i16>);
STATIC_REQUIRE(CastableTo<decltype(-32767_i), based::i16>);
STATIC_REQUIRE(CastableTo<decltype(-2147483647_i), based::i32>);
STATIC_REQUIRE(CastableTo<decltype(-2147483648_i), based::i64>);
STATIC_REQUIRE(CastableTo<decltype(-9223372036854775807_i), based::i64>);
}