1#pragma once
2#include <cstdint>
3#include <cstdlib>
4#include <type_traits>
5#include <algorithm>
6
7using Int8 = int8_t;
8using Int16 = int16_t;
9using Int32 = int32_t;
10using Int64 = int64_t;
11
12using UInt8 = uint8_t;
13using UInt16 = uint16_t;
14using UInt32 = uint32_t;
15using UInt64 = uint64_t;
16
17/// The standard library type traits, such as std::is_arithmetic, with one exception
18/// (std::common_type), are "set in stone". Attempting to specialize them causes undefined behavior.
19/// So instead of using the std type_traits, we use our own version which allows extension.
20template <typename T>
21struct is_signed
22{
23 static constexpr bool value = std::is_signed_v<T>;
24};
25
26template <typename T>
27inline constexpr bool is_signed_v = is_signed<T>::value;
28
29template <typename T>
30struct is_unsigned
31{
32 static constexpr bool value = std::is_unsigned_v<T>;
33};
34
35template <typename T>
36inline constexpr bool is_unsigned_v = is_unsigned<T>::value;
37
38template <typename T>
39struct is_integral
40{
41 static constexpr bool value = std::is_integral_v<T>;
42};
43
44template <typename T>
45inline constexpr bool is_integral_v = is_integral<T>::value;
46
47template <typename T>
48struct is_arithmetic
49{
50 static constexpr bool value = std::is_arithmetic_v<T>;
51};
52
53template <typename T>
54inline constexpr bool is_arithmetic_v = is_arithmetic<T>::value;
55
56