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