iutest  1.17.1.0
iutest_expression_assertion.hpp
[詳解]
1 //======================================================================
2 //-----------------------------------------------------------------------
13 //-----------------------------------------------------------------------
14 //======================================================================
15 #ifndef INCG_IRIS_IUTEST_EXPRESSION_ASSERTION_HPP_B9783316_33CF_4CA7_81D0_0BF44B048A4A_
16 #define INCG_IRIS_IUTEST_EXPRESSION_ASSERTION_HPP_B9783316_33CF_4CA7_81D0_0BF44B048A4A_
17 
18 //======================================================================
19 // define
24 #define IUTEST_OPERAND(op) op IIUT_EXPRESSION_DECOMPOSE()
25 
30 #define IUTEST_EXPRESSION(expr) (IIUT_EXPRESSION_DECOMPOSE() expr).GetResult()
31 
32 
38 #if IUTEST_HAS_ARITHMETIC_EXPRESSION_DECOMPOSE
39 # define IIUT_EXPRESSION_DECOMPOSE() ::iutest::detail::ExpressionDecomposer()->*
40 #else
41 # define IIUT_EXPRESSION_DECOMPOSE() ::iutest::detail::ExpressionDecomposer()>>
42 #endif
43 
44 #ifndef IUTEST_NO_VARIADIC_MACROS
45 # define IIUT_TEST_EXPRESSION_UNPAREN_(...) __VA_ARGS__
46 # define IIUT_TEST_EXPRESSION_EXPAND_EXPRESSION(expr) IIUT_TEST_EXPRESSION_EXPAND_EXPRESSION_(UNPAREN_ expr)
47 # define IIUT_TEST_EXPRESSION_EXPAND_EXPRESSION_(expr) IIUT_TEST_EXPRESSION_##expr
48 # define IIUT_TEST_EXPRESSION_(expr, expected, on_failure) \
49  IUTEST_TEST_TRUE( ( IIUT_EXPRESSION_DECOMPOSE() expr ).GetResult(expected), #expr, on_failure )
50 # define IUTEST_TEST_EXPRESSION_(expr, expected, on_failure) \
51  IIUT_TEST_EXPRESSION_( IIUT_TEST_EXPRESSION_EXPAND_EXPRESSION(expr), expected, on_failure )
52 #else
53 # define IUTEST_TEST_EXPRESSION_(expr, expected, on_failure) \
54  IUTEST_TEST_TRUE( ( IIUT_EXPRESSION_DECOMPOSE() expr ).GetResult(expected), #expr, on_failure )
55 #endif
56 
57 
58 #define IIUT_DECL_EXPRESSION_RESULT_OP(op) \
59  template<typename RHS>ExpressionResult operator op (const RHS& rhs) const { \
60  const bool b = result() op rhs ? true : false; \
61  return ExpressionResult(AssertionResult(b) \
62  << m_result.message() << " " #op " " << rhs); \
63  } \
64  ExpressionResult operator op (const ExpressionResult& rhs) const { \
65  const bool b = result() op rhs.result() ? true : false; \
66  return ExpressionResult(AssertionResult(b) \
67  << m_result.message() << " " #op " " << rhs.message()); \
68  } \
69  ExpressionResult operator op (const AssertionResult& rhs) const { \
70  const bool b = result() op rhs.passed() ? true : false; \
71  return ExpressionResult(AssertionResult(b) \
72  << m_result.message() << " " #op " " << rhs.message()); \
73  }
74 
75 #define IIUT_DECL_EXPRESSION_OP(op) \
76  template<typename RHS>ExpressionResult operator op (const RHS& rhs) const { \
77  const bool b = (m_lhs op rhs) ? true : false; \
78  return ExpressionResult(AssertionResult(b) << m_message << " " #op " " << rhs); \
79  }
80 
81 #if IUTEST_HAS_ARITHMETIC_EXPRESSION_DECOMPOSE || IUTEST_HAS_BITWISE_EXPRESSION_DECOMPOSE
82 
83 #if IUTEST_HAS_DECLTYPE && IUTEST_HAS_STD_DECLVAL
84 
85 #define IIUT_DECL_EXPRESSION_OP_LHS(op) \
86  template<typename RHS>auto operator op (const RHS& rhs) const \
87  -> ExpressionLHS< decltype( expression_op_helper::operand_result( \
88  ( ::std::declval<T>() op rhs ) ) )> { \
89  return OperandResult(m_lhs op rhs) << " " #op " " << rhs; \
90  }
91 
92 #else
93 
94 #define IIUT_DECL_EXPRESSION_OP_LHS(op) \
95  template<typename RHS>ExpressionLHS<RHS> operator op (const RHS& rhs) const { \
96  return OperandResult(m_lhs op rhs) << " " #op " " << rhs; \
97  }
98 
99 #endif
100 
101 #endif
102 
107 namespace iutest {
108 namespace detail
109 {
110 
111 //======================================================================
112 // class
113 
117 class ExpressionResult
118 {
119 public:
120  explicit ExpressionResult(const AssertionResult& ar)
121  : m_result(ar) {}
122 
123 public:
124  IIUT_DECL_EXPRESSION_RESULT_OP(||)
125  IIUT_DECL_EXPRESSION_RESULT_OP(&&)
126 
127 public:
128  AssertionResult GetResult(bool expected) const
129  {
130  return AssertionResult(result() == expected) << "expansion: " << m_result.message();
131  }
132  AssertionResult GetResult() const
133  {
134  return AssertionResult(result()) << m_result.message();
135  }
136 private:
137  bool result() const { return m_result.passed(); }
138  const char* message() const { return m_result.message(); }
139 private:
140  AssertionResult m_result;
141 };
142 
143 namespace expression_op_helper
144 {
145  template<typename T>
146  T operand_result(const T&);
147 }
148 
153 template<typename T>
154 class ExpressionLHS
155 {
156  typedef ExpressionLHS<T> _Myt;
157 public:
158 #if IUTEST_HAS_RVALUE_REFS
159  explicit ExpressionLHS(T&& lhs) : m_lhs( ::std::forward<T>(lhs) )
160  {
161  AppendMessage(m_lhs);
162  }
163 #else
164  explicit ExpressionLHS(T lhs) : m_lhs(lhs)
165  {
166  AppendMessage(lhs);
167  }
168 #endif
169  ExpressionLHS(T lhs, const ::std::string& msg) : m_lhs(lhs), m_message(msg) {}
170 
171 public:
172  IIUT_DECL_EXPRESSION_OP(==)
173  IIUT_DECL_EXPRESSION_OP(!=)
174  IIUT_DECL_EXPRESSION_OP(<)
175  IIUT_DECL_EXPRESSION_OP(<=)
176  IIUT_DECL_EXPRESSION_OP(>)
177  IIUT_DECL_EXPRESSION_OP(>=)
178  IIUT_DECL_EXPRESSION_OP(&&)
179  IIUT_DECL_EXPRESSION_OP(||)
180 
181 #if IUTEST_HAS_ARITHMETIC_EXPRESSION_DECOMPOSE
182  IIUT_DECL_EXPRESSION_OP_LHS(+)
183  IIUT_DECL_EXPRESSION_OP_LHS(-)
184  IIUT_DECL_EXPRESSION_OP_LHS(*)
185  IIUT_DECL_EXPRESSION_OP_LHS(/)
186  IIUT_DECL_EXPRESSION_OP_LHS(%)
187 #endif
188 
189 #if IUTEST_HAS_BITWISE_EXPRESSION_DECOMPOSE
190  IIUT_DECL_EXPRESSION_OP_LHS(&)
191  IIUT_DECL_EXPRESSION_OP_LHS(|)
192  IIUT_DECL_EXPRESSION_OP_LHS(^)
193  IIUT_DECL_EXPRESSION_OP_LHS(<<)
194  IIUT_DECL_EXPRESSION_OP_LHS(>>)
195 #endif
196 
197 private:
198  template<typename U>
199  ExpressionLHS<U> OperandResult(const U& lhs) const
200  {
201  return ExpressionLHS<U>(lhs, m_message);
202  }
203 
204 public:
208  template<typename U>
209  _Myt& operator << (const U& value)
210  {
211  AppendMessage(value);
212  return *this;
213  }
214 
215 public:
217  AssertionResult GetResult(bool expected) const
218  {
219  const bool b = m_lhs ? true : false;
220  return AssertionResult(b == expected) << "expansion: " << m_message;
221  }
222  AssertionResult GetResult() const
223  {
224  const bool b = m_lhs ? true : false;
225  return AssertionResult(b) << m_message;
226  }
227 
228 private:
229  template<typename U>
230  void AppendMessage(const U& value)
231  {
232  Message msg;
233  msg << value;
234  m_message += msg.GetString();
235  }
236 
237 private:
238  ExpressionLHS& operator = (const ExpressionLHS&) IUTEST_CXX_DELETED_FUNCTION;
239 private:
240  T m_lhs;
241  ::std::string m_message;
242 };
243 
244 #undef IIUT_DECL_EXPRESSION_RESULT_OP
245 #undef IIUT_DECL_EXPRESSION_OP
246 #ifdef IIUT_DECL_EXPRESSION_OP_LHS
247 # undef IIUT_DECL_EXPRESSION_OP_LHS
248 #endif
249 
253 class ExpressionDecomposer
254 {
255 public:
256 #if IUTEST_HAS_ARITHMETIC_EXPRESSION_DECOMPOSE
257 #if IUTEST_HAS_RVALUE_REFS
258  template<typename T>
259  ExpressionLHS<T> operator ->*(T&& expr)
260  {
261  return ExpressionLHS<T>(::std::forward<T>(expr));
262  }
263 #else
264  template<typename T>
265  ExpressionLHS<const T&> operator ->*(const T& expr)
266  {
267  return ExpressionLHS<const T&>(expr);
268  }
269 #endif
270 #else
271  template<typename T>
272  ExpressionLHS<const T&> operator >>(const T& expr)
273  {
274  return ExpressionLHS<const T&>(expr);
275  }
276 #endif
277 };
278 
279 } // end of namespace detail
280 } // end of namespace iutest
281 
282 #endif // INCG_IRIS_IUTEST_EXPRESSION_ASSERTION_HPP_B9783316_33CF_4CA7_81D0_0BF44B048A4A_
iutest_config.hpp
iris unit test config
iutest
iutest root namespace
Definition: iutest_charcode.hpp:31
iutest::Message
detail::iuStreamMessage Message
Message クラス
Definition: iutest_assertion.hpp:31
IUTEST_CXX_DELETED_FUNCTION
#define IUTEST_CXX_DELETED_FUNCTION
delete function
Definition: iutest_compiler.hpp:371