qxLib
static_assert.h
Go to the documentation of this file.
1 /**
2 
3  @file static_assert.h
4  @brief Static assert macros
5  @author Khrapov
6  @date 7.08.2022
7  @copyright © Nick Khrapov, 2022. All right reserved.
8 
9 **/
10 #pragma once
11 
12 #include <qx/macros/common.h>
13 #include <qx/macros/names.h>
14 #include <qx/math/common.h>
15 
16 #include <functional>
17 
18 namespace qx::details
19 {
20 
21 template<auto left, auto right, typename compare_t>
23 {
24  static_assert(compare_t()(left, right));
25 };
26 
27 template<auto left, auto right>
28 struct static_assert_two<left, right, std::equal_to<>>
29 {
30  static_assert(std::equal_to<>()(left, right), "!(left == right)");
31 };
32 
33 template<auto left, auto right>
34 struct static_assert_two<left, right, std::not_equal_to<>>
35 {
36  static_assert(std::not_equal_to<>()(left, right), "!(left != right)");
37 };
38 
39 template<auto left, auto right>
40 struct static_assert_two<left, right, std::less<>>
41 {
42  static_assert(std::less<>()(left, right), "!(left < right)");
43 };
44 
45 template<auto left, auto right>
46 struct static_assert_two<left, right, std::less_equal<>>
47 {
48  static_assert(std::less_equal<>()(left, right), "!(left <= right)");
49 };
50 
51 template<auto left, auto right>
52 struct static_assert_two<left, right, std::greater<>>
53 {
54  static_assert(std::greater<>()(left, right), "!(left > right)");
55 };
56 
57 template<auto left, auto right>
58 struct static_assert_two<left, right, std::greater_equal<>>
59 {
60  static_assert(std::greater_equal<>()(left, right), "!(left >= right)");
61 };
62 
63 template<auto left, auto value, auto right>
65 {
66  static_assert(qx::between(left, value, right), "value is not between right and left");
67 };
68 
69 } // namespace qx::details
70 
71 /*
72  Static assertions that shows left and right in error msg
73 */
74 #define QX_STATIC_ASSERT_EQ(left, right) \
75  constexpr qx::details::static_assert_two<(left), (right), std::equal_to<>> QX_LINE_NAME(_static_assert_eq_)
76 
77 #define QX_STATIC_ASSERT_NE(left, right) \
78  constexpr qx::details::static_assert_two<(left), (right), std::not_equal_to<>> QX_LINE_NAME(_static_assert_nq_)
79 
80 #define QX_STATIC_ASSERT_LT(left, right) \
81  constexpr qx::details::static_assert_two<(left), (right), std::less<>> QX_LINE_NAME(_static_assert_lt_)
82 
83 #define QX_STATIC_ASSERT_LE(left, right) \
84  constexpr qx::details::static_assert_two<(left), (right), std::less_equal<>> QX_LINE_NAME(_static_assert_le_)
85 
86 #define QX_STATIC_ASSERT_GT(left, right) \
87  constexpr qx::details::static_assert_two<(left), (right), std::greater<>> QX_LINE_NAME(_static_assert_gt_)
88 
89 #define QX_STATIC_ASSERT_GE(left, right) \
90  constexpr qx::details::static_assert_two<(left), (right), std::greater_equal<>> QX_LINE_NAME(_static_assert_ge_)
91 
92 /**
93  @def QX_STATIC_ASSERT_BETWEEN
94  @brief Shows left, value and right in error msg
95  @param left - left value
96  @param value - value to check
97  @param right - right value
98 **/
99 #define QX_STATIC_ASSERT_BETWEEN(left, value, right) \
100  qx::details::static_assert_between<(left), (value), (right)> QX_LINE_NAME(static_assert_between_)
101 
102 /**
103  @brief This static assert will fail if block it placed in must not be instantiated
104 
105  @code
106  template<class T>
107  constexpr int GetValue()
108  {
109  if constexpr (std::is_same_v<T, bool>)
110  {
111  return 0;
112  }
113  else if constexpr (std::is_same_v<T, int>)
114  {
115  return 0;
116  }
117  else
118  {
119  QX_STATIC_ASSERT_NO_INSTANTIATION("T must be bool or int");
120  return 0;
121  }
122  }
123 
124  constexpr int val1 = GetValue<bool>(); // ok
125  constexpr int val2 = GetValue<int>(); // ok
126  constexpr int val3 = GetValue<long>(); // static_assert failure
127  @endcode
128 
129  @param Message - static_assert message
130 **/
131 #define QX_STATIC_ASSERT_NO_INSTANTIATION(Message) \
132  []<bool flag = false>() \
133  { \
134  static_assert(flag, Message); \
135  }()
constexpr bool between(T left, T value, T right, compare_t compare)
Checks if value is between left and right.
Definition: common.inl:153