Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

4778 lines
141KB

  1. /*
  2. * Trompeloeil C++ mocking framework
  3. *
  4. * Copyright Björn Fahller 2014-2018
  5. * Copyright (C) 2017 Andrew Paxie
  6. *
  7. * Use, modification and distribution is subject to the
  8. * Boost Software License, Version 1.0. (See accompanying
  9. * file LICENSE_1_0.txt or copy at
  10. * http://www.boost.org/LICENSE_1_0.txt)
  11. *
  12. * Project home: https://github.com/rollbear/trompeloeil
  13. */
  14. #ifndef TROMPELOEIL_HPP_
  15. #define TROMPELOEIL_HPP_
  16. // trompe l'oeil noun (Concise Encyclopedia)
  17. // Style of representation in which a painted object is intended
  18. // to deceive the viewer into believing it is the object itself...
  19. // project home: https://github.com/rollbear/trompeloeil
  20. // Deficiencies and missing features
  21. // * Mocking function templates is not supported
  22. // * If a macro kills a kitten, this threatens extinction of all felines!
  23. #if defined(_MSC_VER)
  24. # define TROMPELOEIL_NORETURN __declspec(noreturn)
  25. # if (!defined(__cplusplus) || _MSC_VER < 1900)
  26. # error requires C++ in Visual Studio 2015 RC or later
  27. # endif
  28. #else
  29. # define TROMPELOEIL_NORETURN [[noreturn]]
  30. # if (!defined(__cplusplus) || __cplusplus < 201103L)
  31. # error requires C++11 or higher
  32. # endif
  33. #endif
  34. #if defined(__clang__)
  35. #define TROMPELOEIL_CLANG 1
  36. #define TROMPELOEIL_GCC 0
  37. #define TROMPELOEIL_MSVC 0
  38. #define TROMPELOEIL_GCC_VERSION 0
  39. #define TROMPELOEIL_CPLUSPLUS __cplusplus
  40. #elif defined(__GNUC__)
  41. #define TROMPELOEIL_CLANG 0
  42. #define TROMPELOEIL_GCC 1
  43. #define TROMPELOEIL_MSVC 0
  44. #define TROMPELOEIL_GCC_VERSION \
  45. (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
  46. #define TROMPELOEIL_CPLUSPLUS __cplusplus
  47. #elif defined(_MSC_VER)
  48. #define TROMPELOEIL_CLANG 0
  49. #define TROMPELOEIL_GCC 0
  50. #define TROMPELOEIL_MSVC 1
  51. #define TROMPELOEIL_GCC_VERSION 0
  52. /* MSVC is an amalgam of C++ versions, with no provision to
  53. * force C++11 mode. It also has a __cplusplus macro stuck at 199711L.
  54. * Assume the C++14 code path.
  55. */
  56. #define TROMPELOEIL_CPLUSPLUS 201401L
  57. #endif
  58. #include <tuple>
  59. #include <iomanip>
  60. #include <sstream>
  61. #include <exception>
  62. #include <functional>
  63. #include <memory>
  64. #include <cstring>
  65. #include <regex>
  66. #include <mutex>
  67. #include <atomic>
  68. #include <initializer_list>
  69. #include <type_traits>
  70. #include <utility>
  71. #ifdef TROMPELOEIL_SANITY_CHECKS
  72. #include <cassert>
  73. #define TROMPELOEIL_ASSERT(x) assert(x)
  74. #else
  75. #define TROMPELOEIL_ASSERT(x) do {} while (false)
  76. #endif
  77. #define TROMPELOEIL_IDENTITY(...) __VA_ARGS__ // work around stupid MS VS2015 RC bug
  78. #define TROMPELOEIL_ARG16(_0,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15, ...) _15
  79. #define TROMPELOEIL_COUNT(...) \
  80. TROMPELOEIL_IDENTITY(TROMPELOEIL_ARG16(__VA_ARGS__, \
  81. 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0))
  82. #define TROMPELOEIL_CONCAT_(x, y) x ## y
  83. #define TROMPELOEIL_CONCAT(x, y) TROMPELOEIL_CONCAT_(x, y)
  84. #define TROMPELOEIL_INIT_WITH_STR15(base, x, ...) \
  85. base{#x, x}, TROMPELOEIL_INIT_WITH_STR14(base, __VA_ARGS__)
  86. #define TROMPELOEIL_INIT_WITH_STR14(base, x, ...) \
  87. base{#x, x}, TROMPELOEIL_INIT_WITH_STR13(base, __VA_ARGS__)
  88. #define TROMPELOEIL_INIT_WITH_STR13(base, x, ...) \
  89. base{#x, x}, TROMPELOEIL_INIT_WITH_STR12(base, __VA_ARGS__)
  90. #define TROMPELOEIL_INIT_WITH_STR12(base, x, ...) \
  91. base{#x, x}, TROMPELOEIL_INIT_WITH_STR11(base, __VA_ARGS__)
  92. #define TROMPELOEIL_INIT_WITH_STR11(base, x, ...) \
  93. base{#x, x}, TROMPELOEIL_INIT_WITH_STR10(base, __VA_ARGS__)
  94. #define TROMPELOEIL_INIT_WITH_STR10(base, x, ...) \
  95. base{#x, x}, TROMPELOEIL_INIT_WITH_STR9(base, __VA_ARGS__)
  96. #define TROMPELOEIL_INIT_WITH_STR9(base, x, ...) \
  97. base{#x, x}, TROMPELOEIL_INIT_WITH_STR8(base, __VA_ARGS__)
  98. #define TROMPELOEIL_INIT_WITH_STR8(base, x, ...) \
  99. base{#x, x}, TROMPELOEIL_INIT_WITH_STR7(base, __VA_ARGS__)
  100. #define TROMPELOEIL_INIT_WITH_STR7(base, x, ...) \
  101. base{#x, x}, TROMPELOEIL_INIT_WITH_STR6(base, __VA_ARGS__)
  102. #define TROMPELOEIL_INIT_WITH_STR6(base, x, ...) \
  103. base{#x, x}, TROMPELOEIL_INIT_WITH_STR5(base, __VA_ARGS__)
  104. #define TROMPELOEIL_INIT_WITH_STR5(base, x, ...) \
  105. base{#x, x}, TROMPELOEIL_INIT_WITH_STR4(base, __VA_ARGS__)
  106. #define TROMPELOEIL_INIT_WITH_STR4(base, x, ...) \
  107. base{#x, x}, TROMPELOEIL_INIT_WITH_STR3(base, __VA_ARGS__)
  108. #define TROMPELOEIL_INIT_WITH_STR3(base, x, ...) \
  109. base{#x, x}, TROMPELOEIL_INIT_WITH_STR2(base, __VA_ARGS__)
  110. #define TROMPELOEIL_INIT_WITH_STR2(base, x, ...) \
  111. base{#x, x}, TROMPELOEIL_INIT_WITH_STR1(base, __VA_ARGS__)
  112. #define TROMPELOEIL_INIT_WITH_STR1(base, x) \
  113. base{#x, x}
  114. #define TROMPELOEIL_INIT_WITH_STR0(base)
  115. #define TROMPELOEIL_INIT_WITH_STR(base, ...) \
  116. TROMPELOEIL_CONCAT(TROMPELOEIL_INIT_WITH_STR, \
  117. TROMPELOEIL_COUNT(__VA_ARGS__))(base, __VA_ARGS__)
  118. #define TROMPELOEIL_PARAM_LIST15(func_type) \
  119. TROMPELOEIL_PARAM_LIST14(func_type), \
  120. ::trompeloeil::param_list_t<func_type, 14> p15
  121. #define TROMPELOEIL_PARAM_LIST14(func_type) \
  122. TROMPELOEIL_PARAM_LIST13(func_type), \
  123. ::trompeloeil::param_list_t<func_type, 13> p14
  124. #define TROMPELOEIL_PARAM_LIST13(func_type) \
  125. TROMPELOEIL_PARAM_LIST12(func_type), \
  126. ::trompeloeil::param_list_t<func_type, 12> p13
  127. #define TROMPELOEIL_PARAM_LIST12(func_type) \
  128. TROMPELOEIL_PARAM_LIST11(func_type), \
  129. ::trompeloeil::param_list_t<func_type, 11> p12
  130. #define TROMPELOEIL_PARAM_LIST11(func_type) \
  131. TROMPELOEIL_PARAM_LIST10(func_type), \
  132. ::trompeloeil::param_list_t<func_type, 10> p11
  133. #define TROMPELOEIL_PARAM_LIST10(func_type) \
  134. TROMPELOEIL_PARAM_LIST9(func_type), \
  135. ::trompeloeil::param_list_t<func_type, 9> p10
  136. #define TROMPELOEIL_PARAM_LIST9(func_type) \
  137. TROMPELOEIL_PARAM_LIST8(func_type), \
  138. ::trompeloeil::param_list_t<func_type, 8> p9
  139. #define TROMPELOEIL_PARAM_LIST8(func_type) \
  140. TROMPELOEIL_PARAM_LIST7(func_type), \
  141. ::trompeloeil::param_list_t<func_type, 7> p8
  142. #define TROMPELOEIL_PARAM_LIST7(func_type) \
  143. TROMPELOEIL_PARAM_LIST6(func_type), \
  144. ::trompeloeil::param_list_t<func_type, 6> p7
  145. #define TROMPELOEIL_PARAM_LIST6(func_type) \
  146. TROMPELOEIL_PARAM_LIST5(func_type), \
  147. ::trompeloeil::param_list_t<func_type, 5> p6
  148. #define TROMPELOEIL_PARAM_LIST5(func_type) \
  149. TROMPELOEIL_PARAM_LIST4(func_type), \
  150. ::trompeloeil::param_list_t<func_type, 4> p5
  151. #define TROMPELOEIL_PARAM_LIST4(func_type) \
  152. TROMPELOEIL_PARAM_LIST3(func_type), \
  153. ::trompeloeil::param_list_t<func_type, 3> p4
  154. #define TROMPELOEIL_PARAM_LIST3(func_type) \
  155. TROMPELOEIL_PARAM_LIST2(func_type), \
  156. ::trompeloeil::param_list_t<func_type, 2> p3
  157. #define TROMPELOEIL_PARAM_LIST2(func_type) \
  158. TROMPELOEIL_PARAM_LIST1(func_type), \
  159. ::trompeloeil::param_list_t<func_type, 1> p2
  160. #define TROMPELOEIL_PARAM_LIST1(func_type) \
  161. ::trompeloeil::param_list_t<func_type, 0> p1
  162. #define TROMPELOEIL_PARAM_LIST0(func_type)
  163. #define TROMPELOEIL_PARAM_LIST(num, func_type) \
  164. TROMPELOEIL_CONCAT(TROMPELOEIL_PARAM_LIST, num)(func_type)
  165. #define TROMPELOEIL_PARAMS15 TROMPELOEIL_PARAMS14, p15
  166. #define TROMPELOEIL_PARAMS14 TROMPELOEIL_PARAMS13, p14
  167. #define TROMPELOEIL_PARAMS13 TROMPELOEIL_PARAMS12, p13
  168. #define TROMPELOEIL_PARAMS12 TROMPELOEIL_PARAMS11, p12
  169. #define TROMPELOEIL_PARAMS11 TROMPELOEIL_PARAMS10, p11
  170. #define TROMPELOEIL_PARAMS10 TROMPELOEIL_PARAMS9, p10
  171. #define TROMPELOEIL_PARAMS9 TROMPELOEIL_PARAMS8, p9
  172. #define TROMPELOEIL_PARAMS8 TROMPELOEIL_PARAMS7, p8
  173. #define TROMPELOEIL_PARAMS7 TROMPELOEIL_PARAMS6, p7
  174. #define TROMPELOEIL_PARAMS6 TROMPELOEIL_PARAMS5, p6
  175. #define TROMPELOEIL_PARAMS5 TROMPELOEIL_PARAMS4, p5
  176. #define TROMPELOEIL_PARAMS4 TROMPELOEIL_PARAMS3, p4
  177. #define TROMPELOEIL_PARAMS3 TROMPELOEIL_PARAMS2, p3
  178. #define TROMPELOEIL_PARAMS2 TROMPELOEIL_PARAMS1, p2
  179. #define TROMPELOEIL_PARAMS1 , p1
  180. #define TROMPELOEIL_PARAMS0
  181. #define TROMPELOEIL_PARAMS(num) TROMPELOEIL_CONCAT(TROMPELOEIL_PARAMS, num)
  182. #if (TROMPELOEIL_CPLUSPLUS == 201103L)
  183. #define TROMPELOEIL_DECLTYPE_AUTO \
  184. auto
  185. #define TROMPELOEIL_TRAILING_RETURN_TYPE(return_type) \
  186. -> return_type
  187. #else /* (TROMPELOEIL_CPLUSPLUS == 201103L) */
  188. #define TROMPELOEIL_DECLTYPE_AUTO \
  189. decltype(auto)
  190. #define TROMPELOEIL_TRAILING_RETURN_TYPE(return_type) \
  191. /**/
  192. #endif /* !(TROMPELOEIL_CPLUSPLUS == 201103L) */
  193. namespace trompeloeil
  194. {
  195. template <typename T>
  196. struct identity_type
  197. {
  198. using type = T;
  199. };
  200. template <typename R, typename C, typename ... Args>
  201. identity_type<R(Args...)>
  202. nonconst_member_signature(R (C::*)(Args...))
  203. {
  204. return {};
  205. }
  206. template <typename R, typename C, typename ... Args>
  207. identity_type<R(Args...)>
  208. const_member_signature(R (C::*)(Args...) const)
  209. {
  210. return {};
  211. }
  212. # if (TROMPELOEIL_CPLUSPLUS == 201103L)
  213. namespace detail
  214. {
  215. /* Implement C++14 features using only C++11 entities. */
  216. /* <memory> */
  217. /* Implementation of make_unique is from
  218. *
  219. * Stephan T. Lavavej, "make_unique (Revision 1),"
  220. * ISO/IEC JTC1 SC22 WG21 N3656, 18 April 2013.
  221. * Available: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3656.htm
  222. * Accessed: 14 June 2017
  223. */
  224. template <class T>
  225. struct _Unique_if
  226. {
  227. typedef std::unique_ptr<T> _Single_object;
  228. };
  229. template <class T>
  230. struct _Unique_if<T[]>
  231. {
  232. typedef std::unique_ptr<T[]> _Unknown_bound;
  233. };
  234. template <class T, size_t N>
  235. struct _Unique_if<T[N]>
  236. {
  237. typedef void _Known_bound;
  238. };
  239. template <class T, class... Args>
  240. typename _Unique_if<T>::_Single_object
  241. make_unique(Args&&... args)
  242. {
  243. return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
  244. }
  245. template <class T>
  246. typename _Unique_if<T>::_Unknown_bound
  247. make_unique(size_t n)
  248. {
  249. typedef typename std::remove_extent<T>::type U;
  250. return std::unique_ptr<T>(new U[n]());
  251. }
  252. template <class T, class... Args>
  253. typename _Unique_if<T>::_Known_bound
  254. make_unique(Args&&...) = delete;
  255. /* <type_traits> */
  256. /* The implementation of these is from
  257. *
  258. * Walter E. Brown, "TransformationTraits Redux, v2,"
  259. * ISO/IEC JTC1 SC22 WG21 N3655, 18 April 2013.
  260. * Available: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3655.pdf
  261. * Accessed: 2 November 2017
  262. *
  263. * Minor changes to capitalize template parameter `bool B` has been made.
  264. *
  265. * See also:
  266. * http://en.cppreference.com/w/cpp/types/conditional
  267. * http://en.cppreference.com/w/cpp/types/decay
  268. * http://en.cppreference.com/w/cpp/types/enable_if
  269. * http://en.cppreference.com/w/cpp/types/remove_pointer
  270. * http://en.cppreference.com/w/cpp/types/remove_reference
  271. * Accessed: 17 May 2017
  272. */
  273. template <bool B, typename T, typename F>
  274. using conditional_t = typename std::conditional<B, T, F>::type;
  275. template <typename T>
  276. using decay_t = typename std::decay<T>::type;
  277. template <bool B, typename T = void>
  278. using enable_if_t = typename std::enable_if<B, T>::type;
  279. template <typename T>
  280. using remove_pointer_t = typename std::remove_pointer<T>::type;
  281. template <typename T>
  282. using remove_reference_t = typename std::remove_reference<T>::type;
  283. /* <utility> */
  284. /* This implementation of exchange is from
  285. *
  286. * Jeffrey Yasskin, "exchange() utility function, revision 3,"
  287. * ISO/IEC JTC1 SC22 WG21 N3688, 19 April 2013.
  288. * Available: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3668.html
  289. * Accessed: 2 November 2017
  290. *
  291. * See also:
  292. * http://en.cppreference.com/w/cpp/utility/exchange
  293. * Accessed: 17 May 2017
  294. */
  295. template<class T, class U = T>
  296. inline
  297. T
  298. exchange(
  299. T& obj,
  300. U&& new_value)
  301. {
  302. T old_value = std::move(obj);
  303. obj = std::forward<U>(new_value);
  304. return old_value;
  305. }
  306. /* integer_sequence and index_sequence implemenations are from
  307. *
  308. * Jonathan Wakely, "Compile-time integer sequences,"
  309. * ISO/IEC JTC1 SC22 WG21 N3658, 18 April 2013.
  310. * Available: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3658.html
  311. * Accessed: 2 November 2017
  312. *
  313. * See also:
  314. * http://en.cppreference.com/w/cpp/utility/integer_sequence
  315. * Accessed: 17 May 2017
  316. */
  317. template <typename T, T... I>
  318. struct integer_sequence
  319. {
  320. // Replaces a typedef used in the definition found in N3658.
  321. using value_type = T;
  322. static constexpr size_t size() noexcept
  323. {
  324. return sizeof...(I);
  325. }
  326. };
  327. template <size_t... I>
  328. using index_sequence = integer_sequence<size_t, I...>;
  329. /* This implementation of make_integer_sequence is from boost/mp11,
  330. *
  331. * Copyright 2015, 2017 Peter Dimov
  332. *
  333. * Distributed under the Boost Software License, Version 1.0.
  334. *
  335. * Implemented here:
  336. *
  337. * https://github.com/pdimov/mp11/blob/master/include/boost/
  338. * integer_sequence.hpp
  339. * Accessed: 17 May 2017
  340. *
  341. * (now missing) and here:
  342. *
  343. * https://github.com/boostorg/mp11/blob/develop/include/boost/
  344. * mp11/integer_sequence.hpp
  345. * Accessed: 13 August 2017
  346. */
  347. namespace impl
  348. {
  349. // iseq_if_c
  350. template <bool C, class T, class E>
  351. struct iseq_if_c_impl;
  352. template <class T, class E>
  353. struct iseq_if_c_impl<true, T, E>
  354. {
  355. using type = T;
  356. };
  357. template <class T, class E>
  358. struct iseq_if_c_impl<false, T, E>
  359. {
  360. using type = E;
  361. };
  362. template <bool C, class T, class E>
  363. using iseq_if_c = typename iseq_if_c_impl<C, T, E>::type;
  364. // iseq_identity
  365. template <class T>
  366. struct iseq_identity
  367. {
  368. using type = T;
  369. };
  370. template <class S1, class S2>
  371. struct append_integer_sequence;
  372. template <class T, T... I, T... J>
  373. struct append_integer_sequence<integer_sequence<T, I...>, integer_sequence<T, J...>>
  374. {
  375. using type = integer_sequence<T, I..., ( J + sizeof...(I) )...>;
  376. };
  377. template <class T, T N>
  378. struct make_integer_sequence_impl;
  379. template <class T, T N>
  380. struct make_integer_sequence_impl_
  381. {
  382. private:
  383. static_assert( N >= 0, "make_integer_sequence<T, N>: N must not be negative" );
  384. static T const M = N / 2;
  385. static T const R = N % 2;
  386. using S1 = typename make_integer_sequence_impl<T, M>::type;
  387. using S2 = typename append_integer_sequence<S1, S1>::type;
  388. using S3 = typename make_integer_sequence_impl<T, R>::type;
  389. using S4 = typename append_integer_sequence<S2, S3>::type;
  390. public:
  391. using type = S4;
  392. };
  393. template <class T, T N>
  394. struct make_integer_sequence_impl:
  395. iseq_if_c<N == 0,
  396. iseq_identity<integer_sequence<T>>,
  397. iseq_if_c<N == 1,
  398. iseq_identity<integer_sequence<T, 0>>,
  399. make_integer_sequence_impl_<T, N>>>
  400. {
  401. };
  402. }
  403. template<class T, T N>
  404. using make_integer_sequence = typename impl::make_integer_sequence_impl<T, N>::type;
  405. template <size_t N>
  406. using make_index_sequence = make_integer_sequence<size_t, N>;
  407. template <typename... T>
  408. using index_sequence_for = make_index_sequence<sizeof...(T)>;
  409. } /* namespace detail */
  410. # else /* (TROMPELOEIL_CPLUSPLUS == 201103L) */
  411. /* Only these entities really need to
  412. * be available in namespace detail, but
  413. * VS 2015 has a problem with this approach.
  414. *
  415. * namespace detail {
  416. *
  417. * using std::make_unique;
  418. *
  419. * using std::conditional_t;
  420. * using std::decay_t;
  421. * using std::enable_if_t;
  422. * using std::remove_pointer_t;
  423. * using std::remove_reference_t;
  424. *
  425. * using std::exchange;
  426. * using std::index_sequence;
  427. * using std::index_sequence_for;
  428. * using std::integer_sequence;
  429. * using std::make_index_sequence;
  430. *
  431. * }
  432. *
  433. * Instead, use a namespace alias.
  434. */
  435. namespace detail = std;
  436. # endif /* !(TROMPELOEIL_CPLUSPLUS == 201103L) */
  437. class specialized;
  438. namespace {
  439. inline
  440. const std::shared_ptr<std::recursive_mutex>&
  441. get_mutex_obj()
  442. {
  443. static auto obj = std::make_shared<std::recursive_mutex>();
  444. return obj;
  445. }
  446. auto mutex_holder = get_mutex_obj();
  447. }
  448. template <typename T = void>
  449. std::unique_lock<std::recursive_mutex> get_lock()
  450. {
  451. return std::unique_lock<std::recursive_mutex>{ *get_mutex_obj() };
  452. }
  453. template <size_t N, typename T>
  454. using conditional_tuple_element
  455. = detail::conditional_t<(N < std::tuple_size<T>::value),
  456. typename std::tuple_element<N, T>::type,
  457. int>;
  458. template <typename T>
  459. struct param_list;
  460. template <typename R, typename ... P>
  461. struct param_list<R(P...)>
  462. {
  463. static size_t constexpr const size = sizeof...(P);
  464. template <size_t N>
  465. using type = conditional_tuple_element<N, std::tuple<P...>>;
  466. };
  467. template <typename Sig, size_t N>
  468. using param_list_t = typename param_list<Sig>::template type<N>;
  469. class expectation_violation : public std::logic_error
  470. {
  471. public:
  472. using std::logic_error::logic_error;
  473. };
  474. struct location
  475. {
  476. location()
  477. noexcept
  478. : file("")
  479. , line(0U)
  480. {}
  481. location(
  482. char const* file_,
  483. unsigned long line_
  484. )
  485. noexcept
  486. : file{file_}
  487. , line{line_}
  488. {}
  489. char const *file;
  490. unsigned long line;
  491. };
  492. inline
  493. std::ostream&
  494. operator<<(
  495. std::ostream& os,
  496. const location& loc)
  497. {
  498. if (loc.line != 0U) os << loc.file << ':' << loc.line;
  499. return os;
  500. }
  501. enum class severity { fatal, nonfatal };
  502. using reporter_func = std::function<void(severity,
  503. char const *file,
  504. unsigned long line,
  505. std::string const &msg)>;
  506. inline
  507. void
  508. default_reporter(
  509. severity,
  510. char const *file,
  511. unsigned long line,
  512. std::string const &msg)
  513. {
  514. if (!std::current_exception())
  515. {
  516. std::stringstream os;
  517. os << location{ file, line } << "\n" << msg;
  518. throw expectation_violation(os.str());
  519. }
  520. }
  521. inline
  522. reporter_func&
  523. reporter_obj()
  524. {
  525. static reporter_func obj = default_reporter;
  526. return obj;
  527. }
  528. inline
  529. reporter_func
  530. set_reporter(
  531. reporter_func f)
  532. {
  533. return detail::exchange(reporter_obj(), std::move(f));
  534. }
  535. class tracer;
  536. inline
  537. tracer*&
  538. tracer_obj()
  539. noexcept
  540. {
  541. static tracer* ptr = nullptr;
  542. return ptr;
  543. }
  544. inline
  545. tracer*
  546. set_tracer(
  547. tracer* obj)
  548. noexcept
  549. {
  550. // std::exchange would be sane here, but it costs compilation time
  551. auto& ptr = tracer_obj();
  552. auto rv = ptr;
  553. ptr = obj;
  554. return rv;
  555. }
  556. class tracer
  557. {
  558. public:
  559. virtual
  560. void
  561. trace(
  562. char const *file,
  563. unsigned long line,
  564. std::string const &call) = 0;
  565. protected:
  566. tracer()
  567. noexcept
  568. : previous{set_tracer(this)} {}
  569. tracer(tracer const&) = delete;
  570. tracer& operator=(tracer const&) = delete;
  571. virtual
  572. ~tracer()
  573. {
  574. set_tracer(previous);
  575. }
  576. private:
  577. tracer* previous = nullptr;
  578. };
  579. class stream_tracer : public tracer
  580. {
  581. public:
  582. stream_tracer(
  583. std::ostream& stream_)
  584. : stream(stream_) {}
  585. void
  586. trace(
  587. char const *file,
  588. unsigned long line,
  589. std::string const &call)
  590. override
  591. {
  592. stream << location{file, line} << '\n' << call << '\n';
  593. }
  594. private:
  595. std::ostream& stream;
  596. };
  597. class trace_agent;
  598. template <typename T>
  599. struct reporter;
  600. template <typename T>
  601. void
  602. send_report(
  603. severity s,
  604. location loc,
  605. std::string const &msg)
  606. {
  607. reporter<T>::send(s, loc.file, loc.line, msg.c_str());
  608. }
  609. template <typename T>
  610. struct reporter
  611. {
  612. static
  613. void
  614. send(
  615. severity s,
  616. char const *file,
  617. unsigned long line,
  618. char const *msg);
  619. };
  620. template <typename T>
  621. void reporter<T>::
  622. send(
  623. severity s,
  624. char const *file,
  625. unsigned long line,
  626. char const *msg)
  627. {
  628. reporter_obj()(s, file, line, msg);
  629. }
  630. template <typename ... T>
  631. inline
  632. constexpr
  633. bool
  634. ignore(
  635. T const& ...)
  636. noexcept
  637. {
  638. return true;
  639. }
  640. struct illegal_argument
  641. {
  642. template <bool b = false>
  643. constexpr
  644. illegal_argument const& operator&() const
  645. {
  646. static_assert(b, "illegal argument");
  647. return *this;
  648. }
  649. template <bool b = false>
  650. constexpr
  651. illegal_argument const& operator*() const
  652. {
  653. static_assert(b, "illegal argument");
  654. return *this;
  655. }
  656. template <typename T, bool b = false>
  657. constexpr
  658. illegal_argument const& operator=(T const&) const
  659. {
  660. static_assert(b, "illegal argument");
  661. return *this;
  662. }
  663. template <typename T, bool b = false>
  664. constexpr
  665. operator T() const
  666. {
  667. static_assert(b, "illegal argument");
  668. return {};
  669. }
  670. };
  671. template <typename ...>
  672. struct void_t_
  673. {
  674. using type = void;
  675. };
  676. template <typename ... T>
  677. using void_t = typename void_t_<T...>::type;
  678. template <template <typename ...> class, typename, typename ...>
  679. struct is_detected_{
  680. using type = std::false_type;
  681. };
  682. template <template <typename ...> class D, typename ... Ts>
  683. struct is_detected_<D, void_t<D<Ts...>>, Ts...>
  684. {
  685. using type = std::true_type;
  686. };
  687. template <template <typename ...> class D, typename ... Ts>
  688. using is_detected = typename is_detected_<D, void, Ts...>::type;
  689. struct matcher { };
  690. template <typename T>
  691. using matcher_access = decltype(static_cast<matcher*>(std::declval<typename std::add_pointer<T>::type>()));
  692. template <typename T>
  693. using is_matcher = typename is_detected<matcher_access, T>::type;
  694. template <typename T>
  695. struct typed_matcher : matcher
  696. {
  697. operator T() const;
  698. };
  699. template <>
  700. struct typed_matcher<std::nullptr_t> : matcher
  701. {
  702. template <typename T, typename = decltype(std::declval<T>() == nullptr)>
  703. operator T&&() const;
  704. template <typename T,
  705. typename = decltype(std::declval<T>() == nullptr),
  706. typename = detail::enable_if_t<std::is_copy_constructible<T>::value>>
  707. operator T&()const;
  708. template <typename T, typename C>
  709. operator T C::*() const;
  710. };
  711. template <typename Pred, typename ... T>
  712. class duck_typed_matcher : public matcher
  713. {
  714. public:
  715. #if (!TROMPELOEIL_GCC) || \
  716. (TROMPELOEIL_GCC && TROMPELOEIL_GCC_VERSION >= 40900)
  717. // g++ 4.8 gives a "conversion from <T> to <U> is ambiguous" error
  718. // if this operator is defined.
  719. template <typename V,
  720. typename = decltype(std::declval<Pred>()(std::declval<V&&>(), std::declval<T>()...))>
  721. operator V&&() const;
  722. #endif
  723. template <typename V,
  724. typename = decltype(std::declval<Pred>()(std::declval<V&>(), std::declval<T>()...))>
  725. operator V&() const;
  726. };
  727. template <typename T>
  728. using ostream_insertion = decltype(std::declval<std::ostream&>() << std::declval<T>());
  729. template <typename T>
  730. using is_output_streamable = std::integral_constant<bool, is_detected<ostream_insertion, T>::value && !std::is_array<T>::value>;
  731. struct stream_sentry
  732. {
  733. stream_sentry(
  734. std::ostream& os_)
  735. : os(os_)
  736. , width(os.width(0))
  737. , flags(os.flags(std::ios_base::dec | std::ios_base::left))
  738. , fill(os.fill(' '))
  739. { }
  740. ~stream_sentry()
  741. {
  742. os.flags(flags);
  743. os.fill(fill);
  744. os.width(width);
  745. }
  746. private:
  747. std::ostream& os;
  748. std::streamsize width;
  749. std::ios_base::fmtflags flags;
  750. char fill;
  751. };
  752. template <typename T, typename U>
  753. using equality_comparison = decltype(std::declval<T>() == std::declval<U>());
  754. template <typename T, typename U>
  755. using is_equal_comparable = is_detected<equality_comparison, T, U>;
  756. template <typename T>
  757. using is_null_comparable = is_equal_comparable<T, std::nullptr_t>;
  758. template <typename T>
  759. inline
  760. constexpr
  761. bool
  762. is_null(
  763. T const &t,
  764. std::true_type)
  765. noexcept(noexcept(std::declval<const T&>() == nullptr))
  766. {
  767. return t == nullptr;
  768. }
  769. template <typename T>
  770. inline
  771. constexpr
  772. bool
  773. is_null(
  774. T const &,
  775. std::false_type)
  776. noexcept
  777. {
  778. return false;
  779. }
  780. template <typename T>
  781. inline
  782. constexpr
  783. bool
  784. is_null(
  785. T const &t)
  786. {
  787. // g++-4.9 uses C++11 rules for constexpr function, so can't
  788. // break this up into smaller bits
  789. using tag = std::integral_constant<bool, is_null_comparable<T>::value
  790. && !is_matcher<T>::value
  791. && !std::is_array<T>::value>;
  792. return ::trompeloeil::is_null(t, tag{});
  793. }
  794. template <typename T>
  795. void
  796. print(
  797. std::ostream& os,
  798. T const &t);
  799. template <typename T>
  800. using iterable = decltype(std::begin(std::declval<T&>()) == std::end(std::declval<T&>()));
  801. template <typename T>
  802. using is_collection = is_detected<iterable, T>;
  803. template <typename T,
  804. bool = is_output_streamable<T>::value,
  805. bool = is_collection<detail::remove_reference_t<T>>::value>
  806. struct streamer
  807. {
  808. static
  809. void
  810. print(
  811. std::ostream& os,
  812. T const &t)
  813. {
  814. stream_sentry s(os);
  815. os << t;
  816. }
  817. };
  818. template <typename ... T>
  819. struct streamer<std::tuple<T...>, false, false>
  820. {
  821. static
  822. void
  823. print(
  824. std::ostream& os,
  825. std::tuple<T...> const& t)
  826. {
  827. print_tuple(os, t, detail::index_sequence_for<T...>{});
  828. }
  829. template <size_t ... I>
  830. static
  831. void
  832. print_tuple(
  833. std::ostream& os,
  834. std::tuple<T...> const& t,
  835. detail::index_sequence<I...>)
  836. {
  837. os << "{ ";
  838. const char* sep = "";
  839. std::initializer_list<const char*> v{((os << sep),
  840. ::trompeloeil::print(os, std::get<I>(t)),
  841. (sep = ", "))...};
  842. ignore(v);
  843. os << " }";
  844. }
  845. };
  846. template <typename T, typename U>
  847. struct streamer<std::pair<T, U>, false, false>
  848. {
  849. static
  850. void
  851. print(
  852. std::ostream& os,
  853. std::pair<T, U> const& t)
  854. {
  855. os << "{ ";
  856. ::trompeloeil::print(os, t.first);
  857. os << ", ";
  858. ::trompeloeil::print(os, t.second);
  859. os << " }";
  860. }
  861. };
  862. template <typename T>
  863. struct streamer<T, false, true>
  864. {
  865. static
  866. void
  867. print(
  868. std::ostream& os,
  869. T const& t)
  870. {
  871. os << "{ ";
  872. const char* sep = "";
  873. for (auto& elem : t)
  874. {
  875. os << sep;
  876. ::trompeloeil::print(os, elem);
  877. sep = ", ";
  878. }
  879. os << " }";
  880. }
  881. };
  882. template <typename T>
  883. struct streamer<T, false, false>
  884. {
  885. static
  886. void
  887. print(
  888. std::ostream& os,
  889. T const &t)
  890. {
  891. stream_sentry s(os);
  892. static const char *linebreak = "\n";
  893. os << sizeof(T) << "-byte object={";
  894. os << (linebreak + (sizeof(T) <= 8)); // stupid construction silences VS2015 warning
  895. os << std::setfill('0') << std::hex;
  896. auto p = reinterpret_cast<uint8_t const*>(&t);
  897. for (size_t i = 0; i < sizeof(T); ++i)
  898. {
  899. os << " 0x" << std::setw(2) << unsigned(p[i]);
  900. if ((i & 0xf) == 0xf) os << '\n';
  901. }
  902. os << " }";
  903. }
  904. };
  905. template <typename T>
  906. void
  907. print(
  908. std::ostream& os,
  909. T const &t)
  910. {
  911. if (is_null(t))
  912. {
  913. os << "nullptr";
  914. }
  915. else
  916. {
  917. streamer<T>::print(os, t);
  918. }
  919. }
  920. inline
  921. constexpr
  922. auto
  923. param_compare_operator(
  924. ...)
  925. TROMPELOEIL_TRAILING_RETURN_TYPE(const char*)
  926. {
  927. return " == ";
  928. }
  929. inline
  930. constexpr
  931. auto
  932. param_compare_operator(
  933. matcher const*)
  934. TROMPELOEIL_TRAILING_RETURN_TYPE(const char*)
  935. {
  936. return "";
  937. }
  938. template <typename T>
  939. void
  940. print_expectation(
  941. std::ostream& os,
  942. T const& t)
  943. {
  944. os << param_compare_operator(&t);
  945. print(os, t);
  946. os << '\n';
  947. }
  948. template <typename T>
  949. class list_elem
  950. {
  951. public:
  952. list_elem(
  953. const list_elem&)
  954. = delete;
  955. list_elem(
  956. list_elem &&r)
  957. noexcept
  958. {
  959. *this = std::move(r);
  960. }
  961. list_elem&
  962. operator=(
  963. list_elem &&r)
  964. noexcept
  965. {
  966. if (this != &r)
  967. {
  968. next = r.next;
  969. prev = &r;
  970. r.invariant_check();
  971. next->prev = this;
  972. r.next = this;
  973. TROMPELOEIL_ASSERT(next->prev == this);
  974. TROMPELOEIL_ASSERT(prev->next == this);
  975. r.unlink();
  976. TROMPELOEIL_ASSERT(!r.is_linked());
  977. invariant_check();
  978. }
  979. return *this;
  980. }
  981. list_elem&
  982. operator=(
  983. const list_elem&)
  984. = delete;
  985. virtual
  986. ~list_elem()
  987. {
  988. unlink();
  989. }
  990. void
  991. unlink()
  992. noexcept
  993. {
  994. invariant_check();
  995. auto n = next;
  996. auto p = prev;
  997. n->prev = p;
  998. p->next = n;
  999. next = this;
  1000. prev = this;
  1001. invariant_check();
  1002. }
  1003. void
  1004. invariant_check()
  1005. const
  1006. noexcept
  1007. {
  1008. #ifdef TROMPELOEIL_SANITY_CHECKS
  1009. TROMPELOEIL_ASSERT(next->prev == this);
  1010. TROMPELOEIL_ASSERT(prev->next == this);
  1011. TROMPELOEIL_ASSERT((next == this) == (prev == this));
  1012. TROMPELOEIL_ASSERT((prev->next == next) == (next == this));
  1013. TROMPELOEIL_ASSERT((next->prev == prev) == (prev == this));
  1014. auto pp = prev;
  1015. auto nn = next;
  1016. do {
  1017. TROMPELOEIL_ASSERT((nn == this) == (pp == this));
  1018. TROMPELOEIL_ASSERT(nn->next->prev == nn);
  1019. TROMPELOEIL_ASSERT(nn->prev->next == nn);
  1020. TROMPELOEIL_ASSERT(pp->next->prev == pp);
  1021. TROMPELOEIL_ASSERT(pp->prev->next == pp);
  1022. TROMPELOEIL_ASSERT((nn->next == nn) == (nn == this));
  1023. TROMPELOEIL_ASSERT((pp->prev == pp) == (pp == this));
  1024. nn = nn->next;
  1025. pp = pp->prev;
  1026. } while (nn != this);
  1027. #endif
  1028. }
  1029. bool
  1030. is_linked()
  1031. const
  1032. noexcept
  1033. {
  1034. invariant_check();
  1035. return next != this;
  1036. }
  1037. protected:
  1038. list_elem() noexcept = default;
  1039. public:
  1040. list_elem* next = this;
  1041. list_elem* prev = this;
  1042. };
  1043. class ignore_disposer
  1044. {
  1045. protected:
  1046. template <typename T>
  1047. TROMPELOEIL_NORETURN
  1048. void
  1049. dispose(
  1050. T*)
  1051. const
  1052. noexcept
  1053. {
  1054. std::abort(); // must never be called
  1055. }
  1056. };
  1057. class delete_disposer
  1058. {
  1059. protected:
  1060. template <typename T>
  1061. void
  1062. dispose(
  1063. T* t)
  1064. const
  1065. {
  1066. delete t;
  1067. }
  1068. };
  1069. template <typename T, typename Disposer = ignore_disposer>
  1070. class list : private list_elem<T>, private Disposer
  1071. {
  1072. public:
  1073. list() noexcept;
  1074. list(list&&) noexcept;
  1075. list(const list&) = delete;
  1076. list& operator=(list&&) noexcept;
  1077. list& operator=(const list&) = delete;
  1078. ~list();
  1079. class iterator;
  1080. iterator begin() const noexcept;
  1081. iterator end() const noexcept;
  1082. iterator push_front(T* t) noexcept;
  1083. iterator push_back(T* t) noexcept;
  1084. bool empty() const noexcept { return begin() == end(); }
  1085. private:
  1086. using list_elem<T>::invariant_check;
  1087. using list_elem<T>::next;
  1088. using list_elem<T>::prev;
  1089. };
  1090. template <typename T, typename Disposer>
  1091. class list<T, Disposer>::iterator
  1092. : public std::iterator<std::bidirectional_iterator_tag, T>
  1093. {
  1094. friend class list<T, Disposer>;
  1095. public:
  1096. iterator()
  1097. noexcept
  1098. : p{nullptr}
  1099. {}
  1100. friend
  1101. bool
  1102. operator==(
  1103. iterator const &lh,
  1104. iterator const &rh)
  1105. noexcept
  1106. {
  1107. return lh.p == rh.p;
  1108. }
  1109. friend
  1110. bool
  1111. operator!=(
  1112. iterator const &lh,
  1113. iterator const &rh)
  1114. noexcept
  1115. {
  1116. return !(lh == rh);
  1117. }
  1118. iterator&
  1119. operator++()
  1120. noexcept
  1121. {
  1122. p = p->next;
  1123. return *this;
  1124. }
  1125. iterator
  1126. operator++(int)
  1127. noexcept
  1128. {
  1129. auto rv = *this;
  1130. operator++();
  1131. return rv;
  1132. }
  1133. T&
  1134. operator*()
  1135. noexcept
  1136. {
  1137. return static_cast<T&>(*p);
  1138. }
  1139. T*
  1140. operator->()
  1141. noexcept
  1142. {
  1143. return static_cast<T*>(p);
  1144. }
  1145. private:
  1146. iterator(
  1147. list_elem<T> const *t)
  1148. noexcept
  1149. : p{const_cast<list_elem<T>*>(t)}
  1150. {}
  1151. list_elem<T>* p;
  1152. };
  1153. template <typename T, typename Disposer>
  1154. list<T, Disposer>::list() noexcept = default;
  1155. template <typename T, typename Disposer>
  1156. list<T, Disposer>::list(list&&) noexcept = default;
  1157. template <typename T, typename Disposer>
  1158. list<T, Disposer>& list<T, Disposer>::operator=(list&&) noexcept = default;
  1159. template <typename T, typename Disposer>
  1160. list<T, Disposer>::~list()
  1161. {
  1162. auto i = this->begin();
  1163. while (i != this->end())
  1164. {
  1165. auto p = i++;
  1166. Disposer::dispose(&*p);
  1167. }
  1168. }
  1169. template <typename T, typename Disposer>
  1170. auto
  1171. list<T, Disposer>::begin()
  1172. const
  1173. noexcept
  1174. -> iterator
  1175. {
  1176. return {next};
  1177. }
  1178. template <typename T, typename Disposer>
  1179. auto
  1180. list<T, Disposer>::end()
  1181. const
  1182. noexcept
  1183. -> iterator
  1184. {
  1185. return {this};
  1186. }
  1187. template <typename T, typename Disposer>
  1188. auto
  1189. list<T, Disposer>::push_front(
  1190. T* t)
  1191. noexcept
  1192. -> iterator
  1193. {
  1194. invariant_check();
  1195. t->next = next;
  1196. t->prev = this;
  1197. next->prev = t;
  1198. next = t;
  1199. invariant_check();
  1200. return {t};
  1201. }
  1202. template <typename T, typename Disposer>
  1203. auto
  1204. list<T, Disposer>::push_back(
  1205. T* t)
  1206. noexcept
  1207. -> iterator
  1208. {
  1209. invariant_check();
  1210. t->prev = prev;
  1211. t->next = this;
  1212. prev->next = t;
  1213. prev = t;
  1214. invariant_check();
  1215. return {t};
  1216. }
  1217. class sequence_matcher;
  1218. class sequence_type
  1219. {
  1220. public:
  1221. sequence_type() noexcept = default;
  1222. sequence_type(sequence_type&&) noexcept = delete;
  1223. sequence_type(const sequence_type&) = delete;
  1224. sequence_type& operator=(sequence_type&&) noexcept = delete;
  1225. sequence_type& operator=(const sequence_type&) = delete;
  1226. ~sequence_type();
  1227. bool
  1228. is_completed()
  1229. const
  1230. noexcept;
  1231. bool
  1232. is_first(
  1233. sequence_matcher const *m)
  1234. const
  1235. noexcept;
  1236. void
  1237. add_last(
  1238. sequence_matcher *m)
  1239. noexcept;
  1240. void
  1241. validate_match(
  1242. severity s,
  1243. sequence_matcher const *matcher,
  1244. char const *seq_name,
  1245. char const *match_name,
  1246. location loc)
  1247. const;
  1248. private:
  1249. list<sequence_matcher> matchers;
  1250. };
  1251. class sequence
  1252. {
  1253. public:
  1254. sequence() : obj(new sequence_type) {}
  1255. sequence_type& operator*() { return *obj; }
  1256. bool is_completed() const { return obj->is_completed(); }
  1257. private:
  1258. std::unique_ptr<sequence_type> obj;
  1259. };
  1260. class sequence_matcher : public list_elem<sequence_matcher>
  1261. {
  1262. public:
  1263. using init_type = std::pair<char const*, sequence&>;
  1264. sequence_matcher(
  1265. char const *exp,
  1266. location loc,
  1267. init_type i)
  1268. noexcept
  1269. : seq_name(i.first)
  1270. , exp_name(exp)
  1271. , exp_loc(loc)
  1272. , seq(*i.second)
  1273. {
  1274. seq.add_last(this);
  1275. }
  1276. void
  1277. validate_match(
  1278. severity s,
  1279. char const *match_name,
  1280. location loc)
  1281. const
  1282. {
  1283. seq.validate_match(s, this, seq_name, match_name, loc);
  1284. }
  1285. bool
  1286. is_first()
  1287. const
  1288. noexcept
  1289. {
  1290. return seq.is_first(this);
  1291. }
  1292. void
  1293. retire()
  1294. noexcept
  1295. {
  1296. this->unlink();
  1297. }
  1298. void
  1299. print_expectation(std::ostream& os)
  1300. const
  1301. {
  1302. os << exp_name << " at " << exp_loc;
  1303. }
  1304. char const*
  1305. sequence_name()
  1306. noexcept
  1307. {
  1308. return seq_name;
  1309. }
  1310. private:
  1311. char const *seq_name;
  1312. char const *exp_name;
  1313. location exp_loc;
  1314. sequence_type& seq;
  1315. };
  1316. inline
  1317. bool
  1318. sequence_type::is_completed()
  1319. const
  1320. noexcept
  1321. {
  1322. return matchers.empty();
  1323. }
  1324. inline
  1325. bool
  1326. sequence_type::is_first(
  1327. sequence_matcher const *m)
  1328. const
  1329. noexcept
  1330. {
  1331. return !matchers.empty() && &*matchers.begin() == m;
  1332. }
  1333. inline
  1334. void
  1335. sequence_type::validate_match(
  1336. severity s,
  1337. sequence_matcher const *matcher,
  1338. char const* seq_name,
  1339. char const* match_name,
  1340. location loc)
  1341. const
  1342. {
  1343. if (is_first(matcher)) return;
  1344. for (auto& m : matchers)
  1345. {
  1346. std::ostringstream os;
  1347. os << "Sequence mismatch for sequence \"" << seq_name
  1348. << "\" with matching call of " << match_name
  1349. << " at " << loc
  1350. << ". Sequence \"" << seq_name << "\" has ";
  1351. m.print_expectation(os);
  1352. os << " first in line\n";
  1353. send_report<specialized>(s, loc, os.str());
  1354. }
  1355. }
  1356. inline
  1357. sequence_type::~sequence_type()
  1358. {
  1359. bool touched = false;
  1360. std::ostringstream os;
  1361. while (!matchers.empty())
  1362. {
  1363. auto m = matchers.begin();
  1364. if (!touched)
  1365. {
  1366. os << "Sequence expectations not met at destruction of sequence object \""
  1367. << m->sequence_name() << "\":";
  1368. touched = true;
  1369. }
  1370. os << "\n missing ";
  1371. m->print_expectation(os);
  1372. m->unlink();
  1373. }
  1374. if (touched)
  1375. {
  1376. os << "\n";
  1377. send_report<specialized>(severity::nonfatal, location{}, os.str());
  1378. }
  1379. }
  1380. inline
  1381. void
  1382. sequence_type::add_last(
  1383. sequence_matcher *m)
  1384. noexcept
  1385. {
  1386. matchers.push_back(m);
  1387. }
  1388. struct wildcard : public matcher
  1389. {
  1390. // This abomination of constructor seems necessary for g++ 4.9 and 5.1
  1391. template <typename ... T>
  1392. constexpr
  1393. wildcard(
  1394. T&& ...)
  1395. noexcept
  1396. {}
  1397. #if (!TROMPELOEIL_GCC) || \
  1398. (TROMPELOEIL_GCC && TROMPELOEIL_GCC_VERSION >= 40900)
  1399. // g++ 4.8 gives a "conversion from <T> to <U> is ambiguous" error
  1400. // if this operator is defined.
  1401. template <typename T,
  1402. typename = detail::enable_if_t<!std::is_lvalue_reference<T>::value>>
  1403. operator T&&()
  1404. const;
  1405. #endif
  1406. template <typename T,
  1407. typename = detail::enable_if_t<std::is_copy_constructible<T>::value
  1408. || !std::is_move_constructible<T>::value>>
  1409. operator T&()
  1410. const;
  1411. template <typename T>
  1412. constexpr
  1413. bool
  1414. matches(
  1415. T const&)
  1416. const
  1417. noexcept
  1418. {
  1419. return true;
  1420. }
  1421. friend
  1422. std::ostream&
  1423. operator<<(
  1424. std::ostream& os,
  1425. wildcard const&)
  1426. noexcept
  1427. {
  1428. return os << " matching _";
  1429. }
  1430. };
  1431. static constexpr wildcard const _{};
  1432. template <typename T>
  1433. void can_match_parameter(T&);
  1434. template <typename T>
  1435. void can_match_parameter(T&&);
  1436. template <typename M>
  1437. class ptr_deref : public matcher
  1438. {
  1439. public:
  1440. template <typename U,
  1441. typename = decltype(can_match_parameter<detail::remove_reference_t<decltype(*std::declval<U>())>>(std::declval<M>()))>
  1442. operator U() const;
  1443. template <typename U>
  1444. explicit
  1445. ptr_deref(
  1446. U&& m_)
  1447. : m( std::forward<U>(m_) )
  1448. {}
  1449. template <typename U>
  1450. bool
  1451. matches(
  1452. const U& u)
  1453. const
  1454. noexcept(noexcept(std::declval<M>().matches(*u)))
  1455. {
  1456. return (u != nullptr) && m.matches(*u);
  1457. }
  1458. friend
  1459. std::ostream&
  1460. operator<<(
  1461. std::ostream& os,
  1462. ptr_deref<M> const& p)
  1463. {
  1464. return os << p.m;
  1465. }
  1466. private:
  1467. M m;
  1468. };
  1469. template <typename M>
  1470. class neg_matcher : public matcher
  1471. {
  1472. public:
  1473. template <typename U,
  1474. typename = decltype(can_match_parameter<detail::remove_reference_t<decltype(std::declval<U>())>>(std::declval<M>()))>
  1475. operator U() const;
  1476. template <typename U>
  1477. explicit
  1478. neg_matcher(
  1479. U&& m_)
  1480. : m( std::forward<U>(m_) )
  1481. {}
  1482. template <typename U>
  1483. bool
  1484. matches(
  1485. const U& u)
  1486. const
  1487. noexcept(noexcept(!std::declval<M>().matches(u)))
  1488. {
  1489. return !m.matches(u);
  1490. }
  1491. friend
  1492. std::ostream&
  1493. operator<<(
  1494. std::ostream& os,
  1495. neg_matcher<M> const& p)
  1496. {
  1497. return os << p.m;
  1498. }
  1499. private:
  1500. M m;
  1501. };
  1502. template <typename MatchType, typename Predicate, typename ... ActualType>
  1503. struct matcher_kind
  1504. {
  1505. using type = typed_matcher<MatchType>;
  1506. };
  1507. template <typename Predicate, typename ... ActualType>
  1508. struct matcher_kind<wildcard, Predicate, ActualType...>
  1509. {
  1510. using type = duck_typed_matcher<Predicate, ActualType...>;
  1511. };
  1512. template <typename MatchType, typename Predicate, typename ... ActualType>
  1513. using matcher_kind_t =
  1514. typename matcher_kind<MatchType, Predicate, ActualType...>::type;
  1515. template <typename Predicate, typename Printer, typename MatcherType, typename ... T>
  1516. class predicate_matcher
  1517. : private Predicate
  1518. , private Printer
  1519. , public MatcherType
  1520. {
  1521. public:
  1522. template <typename ... U>
  1523. constexpr
  1524. predicate_matcher(
  1525. Predicate&& pred,
  1526. Printer&& printer,
  1527. U&& ... v)
  1528. noexcept(noexcept(std::tuple<T...>(std::declval<U>()...)) && noexcept(Predicate(std::declval<Predicate&&>())) && noexcept(Printer(std::declval<Printer&&>())))
  1529. : Predicate(std::move(pred))
  1530. , Printer(std::move(printer))
  1531. , value(std::forward<U>(v)...)
  1532. {}
  1533. template <typename V>
  1534. constexpr
  1535. bool
  1536. matches(
  1537. V&& v)
  1538. const
  1539. noexcept(noexcept(std::declval<Predicate const&>()(std::declval<V&&>(), std::declval<const T&>()...)))
  1540. {
  1541. return matches_(std::forward<V>(v), detail::make_index_sequence<sizeof...(T)>{});
  1542. }
  1543. friend
  1544. std::ostream&
  1545. operator<<(
  1546. std::ostream& os,
  1547. predicate_matcher const& v)
  1548. {
  1549. return v.print_(os, detail::make_index_sequence<sizeof...(T)>{});
  1550. }
  1551. private:
  1552. // The below function call operator must be declared to
  1553. // work around gcc bug 78446
  1554. //
  1555. // For some reason microsoft compiler from VS2015 update 3
  1556. // requires the function call operator to be private to avoid
  1557. // ambiguities.
  1558. template <typename ... U>
  1559. void operator()(U&&...) const = delete;
  1560. template <typename V, size_t ... I>
  1561. bool matches_(V&& v, detail::index_sequence<I...>) const
  1562. {
  1563. return Predicate::operator()(std::forward<V>(v), std::get<I>(value)...);
  1564. }
  1565. template <size_t ... I>
  1566. std::ostream& print_(std::ostream& os_, detail::index_sequence<I...>) const
  1567. {
  1568. Printer::operator()(os_, std::get<I>(value)...);
  1569. return os_;
  1570. }
  1571. std::tuple<T...> value;
  1572. };
  1573. template <typename MatchType, typename Predicate, typename Printer, typename ... T>
  1574. using make_matcher_return =
  1575. predicate_matcher<Predicate,
  1576. Printer,
  1577. matcher_kind_t<MatchType, Predicate, detail::decay_t<T>...>,
  1578. detail::decay_t<T>...>;
  1579. namespace lambdas {
  1580. struct any_predicate
  1581. {
  1582. template <typename T>
  1583. bool
  1584. operator()(
  1585. T&&)
  1586. const
  1587. {
  1588. return true;
  1589. }
  1590. };
  1591. // The below must be classes/structs to work with VS 2015 update 3
  1592. // since it doesn't respect the trailing return type declaration on
  1593. // the lambdas of template deduction context
  1594. #define TROMPELOEIL_MK_PRED_BINOP(name, op) \
  1595. struct name { \
  1596. template <typename X, typename Y> \
  1597. auto operator()(X const& x, Y const& y) const -> decltype(x op y) \
  1598. { \
  1599. ::trompeloeil::ignore(x,y); \
  1600. return x op y; \
  1601. } \
  1602. }
  1603. TROMPELOEIL_MK_PRED_BINOP(equal, ==);
  1604. TROMPELOEIL_MK_PRED_BINOP(not_equal, !=);
  1605. TROMPELOEIL_MK_PRED_BINOP(less, <);
  1606. TROMPELOEIL_MK_PRED_BINOP(less_equal, <=);
  1607. TROMPELOEIL_MK_PRED_BINOP(greater, >);
  1608. TROMPELOEIL_MK_PRED_BINOP(greater_equal, >=);
  1609. #undef TROMPELOEIL_MK_PRED_BINOP
  1610. // Define `struct` with `operator()` to replace generic lambdas.
  1611. struct any_printer
  1612. {
  1613. explicit
  1614. any_printer(
  1615. char const* type_name_)
  1616. : type_name(type_name_)
  1617. {}
  1618. void
  1619. operator()(
  1620. std::ostream& os)
  1621. const
  1622. {
  1623. os << " matching ANY(" << type_name << ")";
  1624. }
  1625. private:
  1626. char const* type_name;
  1627. };
  1628. // These structures replace the `op` printer lambdas.
  1629. #define TROMPELOEIL_MK_OP_PRINTER(name, op_string) \
  1630. struct name ## _printer \
  1631. { \
  1632. template <typename T> \
  1633. void \
  1634. operator()( \
  1635. std::ostream& os, \
  1636. T const& value) \
  1637. const \
  1638. { \
  1639. os << op_string; \
  1640. ::trompeloeil::print(os, value); \
  1641. } \
  1642. }
  1643. TROMPELOEIL_MK_OP_PRINTER(equal, " == ");
  1644. TROMPELOEIL_MK_OP_PRINTER(not_equal, " != ");
  1645. TROMPELOEIL_MK_OP_PRINTER(less, " < ");
  1646. TROMPELOEIL_MK_OP_PRINTER(less_equal, " <= ");
  1647. TROMPELOEIL_MK_OP_PRINTER(greater, " > ");
  1648. TROMPELOEIL_MK_OP_PRINTER(greater_equal, " >= ");
  1649. #undef TROMPELOEIL_MK_OP_PRINTER
  1650. }
  1651. template <typename MatchType, typename Predicate, typename Printer, typename ... T>
  1652. inline
  1653. make_matcher_return<MatchType, Predicate, Printer, T...>
  1654. make_matcher(Predicate pred, Printer print, T&& ... t)
  1655. {
  1656. return {std::move(pred), std::move(print), std::forward<T>(t)...};
  1657. }
  1658. template <
  1659. typename T,
  1660. typename R = make_matcher_return<T, lambdas::any_predicate, lambdas::any_printer>>
  1661. inline
  1662. auto
  1663. any_matcher(char const* type_name)
  1664. TROMPELOEIL_TRAILING_RETURN_TYPE(R)
  1665. {
  1666. return make_matcher<T>(lambdas::any_predicate(), lambdas::any_printer(type_name));
  1667. }
  1668. template <
  1669. typename T = wildcard,
  1670. typename V,
  1671. typename R = make_matcher_return<T, lambdas::equal, lambdas::equal_printer, V>>
  1672. inline
  1673. auto
  1674. eq(
  1675. V&& v)
  1676. TROMPELOEIL_TRAILING_RETURN_TYPE(R)
  1677. {
  1678. return make_matcher<T>(lambdas::equal(),
  1679. lambdas::equal_printer(),
  1680. std::forward<V>(v));
  1681. }
  1682. template <
  1683. typename T = wildcard,
  1684. typename V,
  1685. typename R = make_matcher_return<T, lambdas::not_equal, lambdas::not_equal_printer, V>>
  1686. inline
  1687. auto
  1688. ne(
  1689. V&& v)
  1690. TROMPELOEIL_TRAILING_RETURN_TYPE(R)
  1691. {
  1692. return make_matcher<T>(lambdas::not_equal(),
  1693. lambdas::not_equal_printer(),
  1694. std::forward<V>(v));
  1695. }
  1696. template <
  1697. typename T = wildcard,
  1698. typename V,
  1699. typename R = make_matcher_return<T, lambdas::greater_equal, lambdas::greater_equal_printer, V>>
  1700. inline
  1701. auto
  1702. ge(
  1703. V&& v)
  1704. TROMPELOEIL_TRAILING_RETURN_TYPE(R)
  1705. {
  1706. return make_matcher<T>(lambdas::greater_equal(),
  1707. lambdas::greater_equal_printer(),
  1708. std::forward<V>(v));
  1709. }
  1710. template <
  1711. typename T = wildcard,
  1712. typename V,
  1713. typename R = make_matcher_return<T, lambdas::greater, lambdas::greater_printer, V>>
  1714. inline
  1715. auto
  1716. gt(
  1717. V&& v)
  1718. TROMPELOEIL_TRAILING_RETURN_TYPE(R)
  1719. {
  1720. return make_matcher<T>(lambdas::greater(),
  1721. lambdas::greater_printer(),
  1722. std::forward<V>(v));
  1723. }
  1724. template <
  1725. typename T = wildcard,
  1726. typename V,
  1727. typename R = make_matcher_return<T, lambdas::less, lambdas::less_printer, V>>
  1728. inline
  1729. auto
  1730. lt(
  1731. V&& v)
  1732. TROMPELOEIL_TRAILING_RETURN_TYPE(R)
  1733. {
  1734. return make_matcher<T>(lambdas::less(),
  1735. lambdas::less_printer(),
  1736. std::forward<V>(v));
  1737. }
  1738. template <
  1739. typename T = wildcard,
  1740. typename V,
  1741. typename R = make_matcher_return<T, lambdas::less_equal, lambdas::less_equal_printer, V>>
  1742. inline
  1743. auto
  1744. le(
  1745. V&& v)
  1746. TROMPELOEIL_TRAILING_RETURN_TYPE(R)
  1747. {
  1748. return make_matcher<T>(lambdas::less_equal(),
  1749. lambdas::less_equal_printer(),
  1750. std::forward<V>(v));
  1751. }
  1752. namespace lambdas {
  1753. struct regex_check
  1754. {
  1755. class string_helper // a vastly simplified string_view type of class
  1756. {
  1757. public:
  1758. string_helper(
  1759. std::string const& s)
  1760. noexcept
  1761. : str(s.c_str())
  1762. {}
  1763. constexpr
  1764. string_helper(
  1765. char const* s)
  1766. noexcept
  1767. : str(s)
  1768. {}
  1769. char const*
  1770. c_str()
  1771. const
  1772. noexcept
  1773. {
  1774. return str;
  1775. }
  1776. private:
  1777. char const* str;
  1778. };
  1779. regex_check(
  1780. std::regex&& re_,
  1781. std::regex_constants::match_flag_type match_type_)
  1782. : re(std::move(re_)),
  1783. match_type(match_type_)
  1784. {}
  1785. template <typename T>
  1786. bool
  1787. operator()(
  1788. string_helper str,
  1789. T const&)
  1790. const
  1791. {
  1792. return !::trompeloeil::is_null(str.c_str())
  1793. && std::regex_search(str.c_str(), re, match_type);
  1794. }
  1795. private:
  1796. std::regex re;
  1797. std::regex_constants::match_flag_type match_type;
  1798. };
  1799. struct regex_printer
  1800. {
  1801. template <typename T>
  1802. void
  1803. operator()(
  1804. std::ostream& os,
  1805. T const& str)
  1806. const
  1807. {
  1808. os << " matching regular expression /" << str << "/";
  1809. }
  1810. };
  1811. }
  1812. template <
  1813. typename Kind = wildcard,
  1814. typename R = make_matcher_return<Kind, lambdas::regex_check, lambdas::regex_printer, std::string&&>>
  1815. auto
  1816. re(
  1817. std::string s,
  1818. std::regex_constants::syntax_option_type opt = std::regex_constants::ECMAScript,
  1819. std::regex_constants::match_flag_type match_type = std::regex_constants::match_default)
  1820. TROMPELOEIL_TRAILING_RETURN_TYPE(R)
  1821. {
  1822. return make_matcher<Kind>(lambdas::regex_check(std::regex(s, opt),
  1823. match_type),
  1824. lambdas::regex_printer(),
  1825. std::move(s));
  1826. }
  1827. template <
  1828. typename Kind = wildcard,
  1829. typename R = make_matcher_return<Kind, lambdas::regex_check, lambdas::regex_printer, std::string&&>>
  1830. auto
  1831. re(
  1832. std::string s,
  1833. std::regex_constants::match_flag_type match_type)
  1834. TROMPELOEIL_TRAILING_RETURN_TYPE(R)
  1835. {
  1836. return make_matcher<Kind>(lambdas::regex_check(std::regex(s), match_type),
  1837. lambdas::regex_printer(),
  1838. std::move(s));
  1839. }
  1840. inline
  1841. std::string
  1842. param_name_prefix(
  1843. ...)
  1844. {
  1845. return "";
  1846. }
  1847. template <typename M>
  1848. std::string
  1849. param_name_prefix(
  1850. const ptr_deref<M>*)
  1851. {
  1852. return "*" + ::trompeloeil::param_name_prefix(static_cast<M*>(nullptr));
  1853. }
  1854. template <typename M>
  1855. std::string
  1856. param_name_prefix(
  1857. const neg_matcher<M>*)
  1858. {
  1859. return "not " + ::trompeloeil::param_name_prefix(static_cast<M*>(nullptr));
  1860. }
  1861. template <typename T>
  1862. struct null_on_move
  1863. {
  1864. public:
  1865. null_on_move()
  1866. noexcept
  1867. : p{nullptr}
  1868. {}
  1869. null_on_move(
  1870. T* p_)
  1871. noexcept
  1872. : p{p_}
  1873. {}
  1874. null_on_move(
  1875. null_on_move&&)
  1876. noexcept
  1877. : p{nullptr}
  1878. {}
  1879. null_on_move(
  1880. null_on_move const&)
  1881. noexcept
  1882. : p{nullptr}
  1883. {}
  1884. null_on_move&
  1885. operator=(
  1886. const null_on_move&)
  1887. noexcept
  1888. {
  1889. p = nullptr;
  1890. return *this;
  1891. }
  1892. null_on_move&
  1893. operator=(
  1894. null_on_move&&)
  1895. noexcept
  1896. {
  1897. p = nullptr;
  1898. return *this;
  1899. }
  1900. null_on_move&
  1901. operator=(
  1902. T* t)
  1903. noexcept
  1904. {
  1905. p = t;
  1906. return *this;
  1907. }
  1908. T*&
  1909. leak()
  1910. noexcept
  1911. {
  1912. return p;
  1913. }
  1914. T&
  1915. operator*()
  1916. const
  1917. noexcept
  1918. {
  1919. return *p;
  1920. }
  1921. T*
  1922. operator->()
  1923. const
  1924. noexcept
  1925. {
  1926. return p;
  1927. }
  1928. explicit
  1929. operator bool()
  1930. const
  1931. noexcept
  1932. {
  1933. return p != nullptr;
  1934. }
  1935. private:
  1936. T* p;
  1937. };
  1938. struct sequence_handler_base
  1939. {
  1940. virtual
  1941. ~sequence_handler_base()
  1942. noexcept = default;
  1943. virtual
  1944. void
  1945. validate(severity s, char const *, location) = 0;
  1946. virtual
  1947. bool
  1948. is_first()
  1949. const
  1950. noexcept = 0;
  1951. virtual
  1952. void
  1953. retire()
  1954. noexcept = 0;
  1955. };
  1956. template <size_t N>
  1957. struct sequence_handler : public sequence_handler_base
  1958. {
  1959. public:
  1960. template <typename ... S>
  1961. sequence_handler(
  1962. char const *name,
  1963. location loc,
  1964. S&& ... s)
  1965. noexcept
  1966. : matchers{{name, loc, std::forward<S>(s)}...}
  1967. {
  1968. }
  1969. void
  1970. validate(
  1971. severity s,
  1972. char const *match_name,
  1973. location loc)
  1974. override
  1975. {
  1976. for (auto& e : matchers)
  1977. {
  1978. e.validate_match(s, match_name, loc);
  1979. }
  1980. }
  1981. bool
  1982. is_first()
  1983. const
  1984. noexcept
  1985. override
  1986. {
  1987. // std::all_of() is almost always preferable. The only reason
  1988. // for using a hand rolled loop is because it cuts compilation
  1989. // times quite noticeably (almost 10% with g++5.1)
  1990. for (auto& m : matchers)
  1991. {
  1992. if (!m.is_first()) return false;
  1993. }
  1994. return true;
  1995. }
  1996. void
  1997. retire()
  1998. noexcept
  1999. override
  2000. {
  2001. for (auto& e : matchers)
  2002. {
  2003. e.retire();
  2004. }
  2005. }
  2006. private:
  2007. sequence_matcher matchers[N];
  2008. };
  2009. struct lifetime_monitor;
  2010. template <typename T>
  2011. class deathwatched : public T
  2012. {
  2013. static_assert(std::has_virtual_destructor<T>::value,
  2014. "virtual destructor is a necessity for deathwatched to work");
  2015. public:
  2016. template <typename ... U,
  2017. typename = detail::enable_if_t<std::is_constructible<T,U...>::value>>
  2018. deathwatched(
  2019. U&& ...u)
  2020. noexcept(noexcept(T(std::declval<U>()...)))
  2021. : T(std::forward<U>(u)...)
  2022. {}
  2023. ~deathwatched();
  2024. trompeloeil::lifetime_monitor*&
  2025. trompeloeil_expect_death(
  2026. trompeloeil::lifetime_monitor* monitor)
  2027. const
  2028. noexcept
  2029. {
  2030. auto lock = get_lock();
  2031. trompeloeil_lifetime_monitor = monitor;
  2032. return trompeloeil_lifetime_monitor.leak();
  2033. }
  2034. private:
  2035. mutable null_on_move<trompeloeil::lifetime_monitor> trompeloeil_lifetime_monitor;
  2036. };
  2037. struct expectation {
  2038. virtual ~expectation() = default;
  2039. virtual bool is_satisfied() const noexcept = 0;
  2040. virtual bool is_saturated() const noexcept = 0;
  2041. };
  2042. struct lifetime_monitor : public expectation
  2043. {
  2044. template <typename T>
  2045. lifetime_monitor(
  2046. ::trompeloeil::deathwatched<T> const &obj,
  2047. char const* obj_name_,
  2048. char const* invocation_name_,
  2049. char const* call_name_,
  2050. location loc_)
  2051. noexcept
  2052. : object_monitor(obj.trompeloeil_expect_death(this))
  2053. , loc(loc_)
  2054. , object_name(obj_name_)
  2055. , invocation_name(invocation_name_)
  2056. , call_name(call_name_)
  2057. {
  2058. }
  2059. bool is_satisfied() const noexcept override
  2060. {
  2061. return died;
  2062. }
  2063. bool is_saturated() const noexcept override
  2064. {
  2065. return died;
  2066. }
  2067. lifetime_monitor(lifetime_monitor const&) = delete;
  2068. ~lifetime_monitor() override
  2069. {
  2070. auto lock = get_lock();
  2071. if (!died)
  2072. {
  2073. std::ostringstream os;
  2074. os << "Object " << object_name << " is still alive";
  2075. send_report<specialized>(severity::nonfatal, loc, os.str());
  2076. object_monitor = nullptr; // prevent its death poking this cadaver
  2077. }
  2078. }
  2079. void
  2080. notify()
  2081. noexcept
  2082. {
  2083. died = true;
  2084. if (sequences) sequences->validate(severity::nonfatal, call_name, loc);
  2085. }
  2086. template <typename ... T>
  2087. void
  2088. set_sequence(
  2089. T&& ... t)
  2090. {
  2091. auto seq = new sequence_handler<sizeof...(T)>(invocation_name,
  2092. loc,
  2093. std::forward<T>(t)...);
  2094. sequences.reset(seq);
  2095. }
  2096. private:
  2097. std::atomic<bool> died{false};
  2098. lifetime_monitor *&object_monitor;
  2099. location loc;
  2100. char const *object_name;
  2101. char const *invocation_name;
  2102. char const *call_name;
  2103. std::unique_ptr<sequence_handler_base> sequences;
  2104. };
  2105. template <typename T>
  2106. deathwatched<T>::~deathwatched()
  2107. {
  2108. auto lock = get_lock();
  2109. if (trompeloeil_lifetime_monitor)
  2110. {
  2111. trompeloeil_lifetime_monitor->notify();
  2112. return;
  2113. }
  2114. std::ostringstream os;
  2115. os << "Unexpected destruction of "
  2116. << typeid(T).name() << "@" << this << '\n';
  2117. send_report<specialized>(severity::nonfatal,
  2118. location{},
  2119. os.str());
  2120. }
  2121. template <typename T>
  2122. struct return_of;
  2123. template <typename R, typename ... A>
  2124. struct return_of<R(A...)>
  2125. {
  2126. using type = R;
  2127. };
  2128. template <typename T>
  2129. using return_of_t = typename return_of<T>::type;
  2130. template <typename T>
  2131. struct call_params_type;
  2132. template <typename R, typename ... T>
  2133. struct call_params_type<R(T...)>
  2134. {
  2135. using type = std::tuple<typename std::add_lvalue_reference<T>::type...>;
  2136. };
  2137. template <typename T>
  2138. using call_params_type_t = typename call_params_type<T>::type;
  2139. template <typename R>
  2140. struct default_return_t
  2141. {
  2142. TROMPELOEIL_NORETURN static R value()
  2143. {
  2144. std::abort(); // must never be called
  2145. }
  2146. };
  2147. template <typename R>
  2148. inline
  2149. R
  2150. default_return()
  2151. {
  2152. /* Work around VS 2017 15.7.x C4702 warning by
  2153. * enclosing the operation in an otherwise
  2154. * unnecessary try/catch block.
  2155. */
  2156. try
  2157. {
  2158. return default_return_t<R>::value();
  2159. }
  2160. catch (...)
  2161. {
  2162. throw;
  2163. }
  2164. }
  2165. template <>
  2166. inline
  2167. void
  2168. default_return<void>()
  2169. {
  2170. }
  2171. template <typename Sig>
  2172. struct call_matcher_base;
  2173. template <typename Sig>
  2174. struct call_matcher_list : public list<call_matcher_base<Sig>>
  2175. {
  2176. void decommission()
  2177. {
  2178. auto lock = get_lock();
  2179. auto iter = this->begin();
  2180. auto const e = this->end();
  2181. while (iter != e)
  2182. {
  2183. auto i = iter++;
  2184. auto &m = *i;
  2185. m.mock_destroyed();
  2186. m.unlink();
  2187. }
  2188. }
  2189. };
  2190. template <typename Sig>
  2191. struct call_matcher_base : public list_elem<call_matcher_base<Sig>>
  2192. {
  2193. call_matcher_base(
  2194. location loc_,
  2195. char const* name_)
  2196. : loc{loc_}
  2197. , name{name_}
  2198. {
  2199. }
  2200. call_matcher_base(call_matcher_base&&) = delete;
  2201. virtual
  2202. ~call_matcher_base() = default;
  2203. virtual
  2204. void
  2205. mock_destroyed() = 0;
  2206. virtual
  2207. bool
  2208. matches(
  2209. call_params_type_t<Sig> const&)
  2210. const = 0;
  2211. virtual
  2212. bool
  2213. first_in_sequence()
  2214. const
  2215. noexcept = 0;
  2216. virtual
  2217. void
  2218. run_actions(
  2219. call_params_type_t<Sig> &,
  2220. call_matcher_list<Sig> &saturated_list
  2221. ) = 0;
  2222. virtual
  2223. std::ostream&
  2224. report_signature(
  2225. std::ostream&)
  2226. const = 0;
  2227. TROMPELOEIL_NORETURN
  2228. virtual
  2229. std::ostream&
  2230. report_mismatch(
  2231. std::ostream&,
  2232. call_params_type_t<Sig> const &) = 0;
  2233. virtual
  2234. return_of_t<Sig>
  2235. return_value(
  2236. trace_agent&,
  2237. call_params_type_t<Sig>& p) = 0;
  2238. virtual
  2239. void
  2240. report_missed(
  2241. char const *reason) = 0;
  2242. location loc;
  2243. char const *name;
  2244. };
  2245. template <typename T, typename U>
  2246. bool
  2247. param_matches_impl(
  2248. T const& t,
  2249. U const& u,
  2250. matcher const*)
  2251. noexcept(noexcept(t.matches(u)))
  2252. {
  2253. return t.matches(u);
  2254. }
  2255. template <typename T,
  2256. typename U,
  2257. typename = detail::enable_if_t<is_equal_comparable<T, U>::value>>
  2258. inline
  2259. U&
  2260. identity(
  2261. U& t)
  2262. noexcept
  2263. {
  2264. return t;
  2265. }
  2266. template <typename T,
  2267. typename U,
  2268. typename = detail::enable_if_t<!is_equal_comparable<T, U>::value>>
  2269. inline
  2270. T
  2271. identity(
  2272. const U& u)
  2273. noexcept(noexcept(T(u)))
  2274. {
  2275. return u;
  2276. }
  2277. template <typename T, typename U>
  2278. bool
  2279. param_matches_impl(
  2280. T const& t,
  2281. U const& u,
  2282. ...)
  2283. noexcept(noexcept(::trompeloeil::identity<U>(t) == u))
  2284. {
  2285. return ::trompeloeil::identity<U>(t) == u;
  2286. }
  2287. template <typename T, typename U>
  2288. bool
  2289. param_matches(
  2290. T const& t,
  2291. U const& u)
  2292. noexcept(noexcept(param_matches_impl(t, u, &t)))
  2293. {
  2294. return ::trompeloeil::param_matches_impl(t, u, &t);
  2295. }
  2296. template <size_t ... I, typename T, typename U>
  2297. bool
  2298. match_parameters(
  2299. detail::index_sequence<I...>,
  2300. T const& t,
  2301. U const& u)
  2302. noexcept(noexcept(std::initializer_list<bool>{trompeloeil::param_matches(std::get<I>(t),std::get<I>(u))...}))
  2303. {
  2304. bool all_true = true;
  2305. ::trompeloeil::ignore(t, u); // Kills unmotivated VS2015 warning in the empty case
  2306. ::trompeloeil::ignore(std::initializer_list<bool>{all_true = all_true && ::trompeloeil::param_matches(std::get<I>(t), std::get<I>(u))...});
  2307. return all_true;
  2308. }
  2309. template <typename ... T, typename ... U>
  2310. bool
  2311. match_parameters(
  2312. std::tuple<T...> const& t,
  2313. std::tuple<U...> const& u)
  2314. noexcept(noexcept(match_parameters(detail::make_index_sequence<sizeof...(T)>{}, t, u)))
  2315. {
  2316. return ::trompeloeil::match_parameters(detail::make_index_sequence<sizeof...(T)>{}, t, u);
  2317. }
  2318. template <typename V, typename P>
  2319. void print_mismatch(
  2320. std::ostream& os,
  2321. size_t num,
  2322. V const& v,
  2323. P const& p)
  2324. {
  2325. if (!::trompeloeil::param_matches(v, p))
  2326. {
  2327. auto prefix = ::trompeloeil::param_name_prefix(&v) + "_";
  2328. os << " Expected " << std::setw((num < 9) + 1) << prefix << num+1;
  2329. ::trompeloeil::print_expectation(os, v);
  2330. }
  2331. }
  2332. template <typename ... V, typename ... P, size_t ... I>
  2333. void print_mismatch(
  2334. std::ostream& os,
  2335. detail::index_sequence<I...>,
  2336. std::tuple<V...> const& v,
  2337. std::tuple<P...> const& p)
  2338. {
  2339. ::trompeloeil::ignore(os, v, p); // Kills unmotivated VS2015 warning in the empty case
  2340. ::trompeloeil::ignore(std::initializer_list<int>{(print_mismatch(os, I, std::get<I>(v), std::get<I>(p)),0)...});
  2341. }
  2342. template <typename ... V, typename ... P>
  2343. void print_mismatch(
  2344. std::ostream& os,
  2345. std::tuple<V...> const& v,
  2346. std::tuple<P...> const& p)
  2347. {
  2348. print_mismatch(os, detail::make_index_sequence<sizeof...(V)>{}, v, p);
  2349. }
  2350. template <typename T>
  2351. void missed_value(
  2352. std::ostream& os,
  2353. int i,
  2354. T const& t)
  2355. {
  2356. auto prefix = ::trompeloeil::param_name_prefix(&t) + "_";
  2357. os << " param " << std::setw((i < 9) + 1) << prefix << i + 1
  2358. << ::trompeloeil::param_compare_operator(&t);
  2359. ::trompeloeil::print(os, t);
  2360. os << '\n';
  2361. }
  2362. template <size_t ... I, typename ... T>
  2363. void stream_params(
  2364. std::ostream &os,
  2365. detail::index_sequence<I...>,
  2366. std::tuple<T...> const &t)
  2367. {
  2368. ::trompeloeil::ignore(os, t); // Kills unmotivated VS2015 warning in the empty case
  2369. ::trompeloeil::ignore(std::initializer_list<int>{(missed_value(os, I, std::get<I>(t)),0)...});
  2370. }
  2371. template <typename ... T>
  2372. void
  2373. stream_params(
  2374. std::ostream &os,
  2375. std::tuple<T...> const &t)
  2376. {
  2377. stream_params(os, detail::make_index_sequence<sizeof...(T)>{}, t);
  2378. }
  2379. template <typename ... T>
  2380. std::string
  2381. params_string(
  2382. std::tuple<T...> const& t)
  2383. {
  2384. std::ostringstream os;
  2385. stream_params(os, t);
  2386. return os.str();
  2387. }
  2388. class trace_agent
  2389. {
  2390. public:
  2391. trace_agent(
  2392. location loc_,
  2393. char const* name_,
  2394. tracer* t_)
  2395. : loc{loc_}
  2396. , t{t_}
  2397. {
  2398. if (t)
  2399. {
  2400. os << name_ << " with.\n";
  2401. }
  2402. }
  2403. trace_agent(trace_agent const&) = delete;
  2404. trace_agent(trace_agent &&) = delete;
  2405. ~trace_agent()
  2406. {
  2407. if (t)
  2408. {
  2409. t->trace(loc.file, loc.line, os.str());
  2410. }
  2411. }
  2412. trace_agent&
  2413. operator=(trace_agent const&) = delete;
  2414. trace_agent&
  2415. operator=(trace_agent &&) = delete;
  2416. template <typename ... T>
  2417. void
  2418. trace_params(
  2419. std::tuple<T...> const& params)
  2420. {
  2421. if (t)
  2422. {
  2423. stream_params(os, params);
  2424. }
  2425. }
  2426. template <typename T>
  2427. auto
  2428. trace_return(
  2429. T&& rv)
  2430. -> T
  2431. {
  2432. if (t)
  2433. {
  2434. os << " -> ";
  2435. print(os, rv);
  2436. os << '\n';
  2437. }
  2438. return std::forward<T>(rv);
  2439. }
  2440. void
  2441. trace_exception()
  2442. {
  2443. if (t)
  2444. {
  2445. try {
  2446. throw;
  2447. }
  2448. catch (std::exception& e)
  2449. {
  2450. os << "threw exception: what() = " << e.what() << '\n';
  2451. }
  2452. catch (...)
  2453. {
  2454. os << "threw unknown exception\n";
  2455. }
  2456. }
  2457. }
  2458. private:
  2459. location loc;
  2460. tracer* t;
  2461. std::ostringstream os;
  2462. };
  2463. template <typename Sig>
  2464. call_matcher_base <Sig> *
  2465. find(
  2466. call_matcher_list <Sig> &list,
  2467. call_params_type_t <Sig> const &p)
  2468. noexcept
  2469. {
  2470. call_matcher_base<Sig>* first_match = nullptr;
  2471. for (auto& i : list)
  2472. {
  2473. if (i.matches(p))
  2474. {
  2475. if (i.first_in_sequence())
  2476. {
  2477. return &i;
  2478. }
  2479. if (!first_match)
  2480. {
  2481. first_match = &i;
  2482. }
  2483. }
  2484. }
  2485. return first_match;
  2486. }
  2487. template <typename Sig>
  2488. TROMPELOEIL_NORETURN
  2489. void
  2490. report_mismatch(
  2491. call_matcher_list <Sig> &matcher_list,
  2492. call_matcher_list <Sig> &saturated_list,
  2493. std::string const &name,
  2494. call_params_type_t <Sig> const &p)
  2495. {
  2496. std::ostringstream os;
  2497. os << "No match for call of " << name << " with.\n";
  2498. stream_params(os, p);
  2499. bool saturated_match = false;
  2500. for (auto& m : saturated_list)
  2501. {
  2502. if (m.matches(p))
  2503. {
  2504. if (!saturated_match)
  2505. {
  2506. os << "\nMatches saturated call requirement\n";
  2507. saturated_match = true;
  2508. }
  2509. os << " ";
  2510. m.report_signature(os) << '\n';
  2511. }
  2512. }
  2513. if (!saturated_match)
  2514. {
  2515. for (auto& m : matcher_list)
  2516. {
  2517. os << "\nTried ";
  2518. m.report_mismatch(os, p);
  2519. }
  2520. }
  2521. send_report<specialized>(severity::fatal, location{}, os.str());
  2522. std::abort(); // must never get here.
  2523. }
  2524. template <typename Sig>
  2525. class return_handler
  2526. {
  2527. public:
  2528. virtual
  2529. ~return_handler() = default;
  2530. virtual
  2531. return_of_t<Sig>
  2532. call(
  2533. trace_agent&,
  2534. call_params_type_t<Sig>& params) = 0;
  2535. };
  2536. template <typename Ret, typename F, typename P, typename = detail::enable_if_t<std::is_void<Ret>::value>>
  2537. void
  2538. trace_return(
  2539. trace_agent&,
  2540. F& func,
  2541. P& params)
  2542. {
  2543. func(params);
  2544. }
  2545. template <typename Ret, typename F, typename P, typename = detail::enable_if_t<!std::is_void<Ret>::value>>
  2546. Ret
  2547. trace_return(
  2548. trace_agent& agent,
  2549. F& func,
  2550. P& params)
  2551. {
  2552. /* Work around VS 2017 15.7.x C4702 warning by
  2553. * enclosing the operation in an otherwise
  2554. * unnecessary try/catch block.
  2555. */
  2556. try
  2557. {
  2558. return agent.trace_return(func(params));
  2559. }
  2560. catch (...)
  2561. {
  2562. throw;
  2563. }
  2564. }
  2565. template <typename Sig, typename T>
  2566. class return_handler_t : public return_handler<Sig>
  2567. {
  2568. public:
  2569. template <typename U>
  2570. return_handler_t(
  2571. U&& u)
  2572. : func(std::forward<U>(u))
  2573. {}
  2574. return_of_t<Sig>
  2575. call(
  2576. trace_agent& agent,
  2577. call_params_type_t<Sig>& params)
  2578. override
  2579. {
  2580. return trace_return<return_of_t<Sig>>(agent, func, params);
  2581. }
  2582. private:
  2583. T func;
  2584. };
  2585. template <typename Sig>
  2586. class condition_base : public list_elem<condition_base<Sig>>
  2587. {
  2588. public:
  2589. condition_base(
  2590. char const *n)
  2591. noexcept
  2592. : id(n)
  2593. {}
  2594. virtual
  2595. ~condition_base() = default;
  2596. virtual
  2597. bool
  2598. check(
  2599. call_params_type_t<Sig> const&)
  2600. const = 0;
  2601. virtual
  2602. char const*
  2603. name()
  2604. const
  2605. noexcept
  2606. {
  2607. return id;
  2608. }
  2609. private:
  2610. char const *id;
  2611. };
  2612. template <typename Sig>
  2613. using condition_list = list<condition_base<Sig>, delete_disposer>;
  2614. template <typename Sig, typename Cond>
  2615. struct condition : public condition_base<Sig>
  2616. {
  2617. condition(
  2618. char const *str_,
  2619. Cond c_)
  2620. : condition_base<Sig>(str_)
  2621. , c(c_) {}
  2622. bool
  2623. check(
  2624. call_params_type_t<Sig> const & t)
  2625. const
  2626. override
  2627. {
  2628. return c(t);
  2629. }
  2630. private:
  2631. Cond c;
  2632. };
  2633. template <typename Sig>
  2634. struct side_effect_base : public list_elem<side_effect_base<Sig>>
  2635. {
  2636. virtual
  2637. ~side_effect_base() = default;
  2638. virtual
  2639. void
  2640. action(
  2641. call_params_type_t<Sig> &)
  2642. const = 0;
  2643. };
  2644. template <typename Sig>
  2645. using side_effect_list = list<side_effect_base<Sig>, delete_disposer>;
  2646. template <typename Sig, typename Action>
  2647. struct side_effect : public side_effect_base<Sig>
  2648. {
  2649. template <typename A>
  2650. side_effect(
  2651. A&& a_)
  2652. : a(std::forward<A>(a_))
  2653. {}
  2654. void
  2655. action(
  2656. call_params_type_t<Sig> &t)
  2657. const
  2658. override
  2659. {
  2660. a(t);
  2661. }
  2662. private:
  2663. Action a;
  2664. };
  2665. template <unsigned long long L, unsigned long long H = L>
  2666. struct multiplicity { };
  2667. template <typename R, typename Parent>
  2668. struct return_injector : Parent
  2669. {
  2670. using return_type = R;
  2671. };
  2672. template <typename Parent>
  2673. struct throw_injector : Parent
  2674. {
  2675. static bool const throws = true;
  2676. };
  2677. template <typename Parent>
  2678. struct sideeffect_injector : Parent
  2679. {
  2680. static bool const side_effects = true;
  2681. };
  2682. template <typename Parent, unsigned long long H>
  2683. struct call_limit_injector : Parent
  2684. {
  2685. static bool const call_limit_set = true;
  2686. static unsigned long long const upper_call_limit = H;
  2687. };
  2688. template <typename Parent>
  2689. struct call_limit_injector<Parent, 0ULL> : Parent
  2690. {
  2691. static bool const call_limit_set = true;
  2692. static unsigned long long const upper_call_limit = 0ULL;
  2693. };
  2694. template <typename Parent>
  2695. struct sequence_injector : Parent
  2696. {
  2697. static bool const sequence_set = true;
  2698. };
  2699. template <typename Matcher, typename modifier_tag, typename Parent>
  2700. struct call_modifier : public Parent
  2701. {
  2702. using typename Parent::signature;
  2703. using typename Parent::return_type;
  2704. using Parent::call_limit_set;
  2705. using Parent::upper_call_limit;
  2706. using Parent::sequence_set;
  2707. using Parent::throws;
  2708. using Parent::side_effects;
  2709. call_modifier(
  2710. Matcher* m)
  2711. noexcept
  2712. : matcher{m}
  2713. {}
  2714. template <typename D>
  2715. call_modifier&&
  2716. with(
  2717. char const* str,
  2718. D&& d)
  2719. &&
  2720. {
  2721. matcher->add_condition(str, std::forward<D>(d));
  2722. return std::move(*this);
  2723. }
  2724. template <typename A>
  2725. call_modifier<Matcher, modifier_tag, sideeffect_injector<Parent>>
  2726. sideeffect(
  2727. A&& a)
  2728. {
  2729. constexpr bool forbidden = upper_call_limit == 0U;
  2730. static_assert(!forbidden,
  2731. "SIDE_EFFECT for forbidden call does not make sense");
  2732. matcher->add_side_effect(std::forward<A>(a));
  2733. return {std::move(matcher)};
  2734. }
  2735. template <typename H>
  2736. call_modifier<Matcher, modifier_tag, return_injector<return_of_t<signature>, Parent >>
  2737. handle_return(
  2738. H&& h)
  2739. {
  2740. using params_type = call_params_type_t<signature>&;
  2741. using sigret = return_of_t<signature>;
  2742. using ret = decltype(std::declval<H>()(std::declval<params_type>()));
  2743. // don't know why MS VS 2015 RC doesn't like std::result_of
  2744. constexpr bool is_illegal_type = std::is_same<detail::decay_t<ret>, illegal_argument>::value;
  2745. constexpr bool is_first_return = std::is_same<return_type, void>::value;
  2746. constexpr bool void_signature = std::is_same<sigret, void>::value;
  2747. constexpr bool is_pointer_sigret = std::is_pointer<sigret>::value;
  2748. constexpr bool is_pointer_ret = std::is_pointer<detail::decay_t<ret>>::value;
  2749. constexpr bool ptr_const_mismatch =
  2750. is_pointer_ret &&
  2751. is_pointer_sigret &&
  2752. !std::is_const<detail::remove_pointer_t<sigret>>{} &&
  2753. std::is_const<detail::remove_pointer_t<detail::decay_t<ret>>>{};
  2754. constexpr bool is_ref_sigret = std::is_reference<sigret>::value;
  2755. constexpr bool is_ref_ret = std::is_reference<ret>::value;
  2756. constexpr bool ref_const_mismatch=
  2757. is_ref_ret &&
  2758. is_ref_sigret &&
  2759. !std::is_const<detail::remove_reference_t<sigret>>::value &&
  2760. std::is_const<detail::remove_reference_t<ret>>::value;
  2761. constexpr bool matching_ret_type = std::is_constructible<sigret, ret>::value;
  2762. constexpr bool ref_value_mismatch = !is_ref_ret && is_ref_sigret;
  2763. static_assert(matching_ret_type || !void_signature,
  2764. "RETURN does not make sense for void-function");
  2765. static_assert(!is_illegal_type,
  2766. "RETURN illegal argument");
  2767. static_assert(!ptr_const_mismatch,
  2768. "RETURN const* from function returning pointer to non-const");
  2769. static_assert(!ref_value_mismatch || matching_ret_type,
  2770. "RETURN non-reference from function returning reference");
  2771. static_assert(ref_value_mismatch || !ref_const_mismatch,
  2772. "RETURN const& from function returning non-const reference");
  2773. static_assert(ptr_const_mismatch || ref_const_mismatch || is_illegal_type || matching_ret_type || void_signature,
  2774. "RETURN value is not convertible to the return type of the function");
  2775. static_assert(is_first_return,
  2776. "Multiple RETURN does not make sense");
  2777. static_assert(!throws || upper_call_limit == 0,
  2778. "THROW and RETURN does not make sense");
  2779. static_assert(upper_call_limit > 0ULL,
  2780. "RETURN for forbidden call does not make sense");
  2781. constexpr bool valid = !is_illegal_type && matching_ret_type && is_first_return && !throws && upper_call_limit > 0ULL;
  2782. using tag = std::integral_constant<bool, valid>;
  2783. matcher->set_return(tag{}, std::forward<H>(h));
  2784. return {matcher};
  2785. }
  2786. call_modifier&&
  2787. null_modifier()
  2788. {
  2789. return std::move(*this);
  2790. }
  2791. private:
  2792. template <typename H>
  2793. struct throw_handler_t
  2794. {
  2795. using R = decltype(default_return<return_of_t<signature>>());
  2796. throw_handler_t(H&& h_)
  2797. : h(std::forward<H>(h_))
  2798. {}
  2799. template <typename T>
  2800. R operator()(T& p)
  2801. {
  2802. /* Work around VS 2017 15.7.x C4702 warning by
  2803. * enclosing the operation in an otherwise
  2804. * unnecessary try/catch block.
  2805. */
  2806. try
  2807. {
  2808. h(p);
  2809. }
  2810. catch (...)
  2811. {
  2812. throw;
  2813. }
  2814. return R();
  2815. }
  2816. private:
  2817. H h;
  2818. };
  2819. public:
  2820. template <typename H>
  2821. call_modifier<Matcher, modifier_tag, throw_injector<Parent>>
  2822. handle_throw(
  2823. H&& h)
  2824. {
  2825. static_assert(!throws,
  2826. "Multiple THROW does not make sense");
  2827. constexpr bool has_return = !std::is_same<return_type, void>::value;
  2828. static_assert(!has_return,
  2829. "THROW and RETURN does not make sense");
  2830. constexpr bool forbidden = upper_call_limit == 0U;
  2831. static_assert(!forbidden,
  2832. "THROW for forbidden call does not make sense");
  2833. constexpr bool valid = !throws && !has_return;// && !forbidden;
  2834. using tag = std::integral_constant<bool, valid>;
  2835. auto handler = throw_handler_t<H>(std::forward<H>(h));
  2836. matcher->set_return(tag{}, std::move(handler));
  2837. return {matcher};
  2838. }
  2839. template <unsigned long long L,
  2840. unsigned long long H,
  2841. bool times_set = call_limit_set>
  2842. call_modifier<Matcher, modifier_tag, call_limit_injector<Parent, H>>
  2843. times(
  2844. multiplicity<L, H>)
  2845. {
  2846. static_assert(!times_set,
  2847. "Only one TIMES call limit is allowed, but it can express an interval");
  2848. static_assert(H >= L,
  2849. "In TIMES the first value must not exceed the second");
  2850. static_assert(H > 0 || !throws,
  2851. "THROW and TIMES(0) does not make sense");
  2852. static_assert(H > 0 || std::is_same<return_type, void>::value,
  2853. "RETURN and TIMES(0) does not make sense");
  2854. static_assert(H > 0 || !side_effects,
  2855. "SIDE_EFFECT and TIMES(0) does not make sense");
  2856. static_assert(H > 0 || !sequence_set,
  2857. "IN_SEQUENCE and TIMES(0) does not make sense");
  2858. matcher->min_calls = L;
  2859. matcher->max_calls = H;
  2860. return {matcher};
  2861. }
  2862. template <typename ... T,
  2863. bool b = sequence_set>
  2864. call_modifier<Matcher, modifier_tag, sequence_injector<Parent>>
  2865. in_sequence(
  2866. T&& ... t)
  2867. {
  2868. static_assert(!b,
  2869. "Multiple IN_SEQUENCE does not make sense."
  2870. " You can list several sequence objects at once");
  2871. static_assert(upper_call_limit > 0ULL,
  2872. "IN_SEQUENCE for forbidden call does not make sense");
  2873. matcher->set_sequence(std::forward<T>(t)...);
  2874. return {matcher};
  2875. }
  2876. Matcher* matcher;
  2877. };
  2878. inline
  2879. void
  2880. report_unfulfilled(
  2881. const char* reason,
  2882. char const *name,
  2883. std::string const &values,
  2884. unsigned long long min_calls,
  2885. unsigned long long call_count,
  2886. location loc)
  2887. {
  2888. std::ostringstream os;
  2889. os << reason
  2890. << ":\nExpected " << name << " to be called ";
  2891. if (min_calls == 1)
  2892. os << "once";
  2893. else
  2894. os << min_calls << " times";
  2895. os << ", actually ";
  2896. switch (call_count)
  2897. {
  2898. case 0:
  2899. os << "never called\n"; break;
  2900. case 1:
  2901. os << "called once\n"; break;
  2902. default:
  2903. os << "called " << call_count << " times\n";
  2904. }
  2905. os << values;
  2906. send_report<specialized>(severity::nonfatal, loc, os.str());
  2907. }
  2908. inline
  2909. void
  2910. report_forbidden_call(
  2911. char const *name,
  2912. location loc,
  2913. std::string const& values)
  2914. {
  2915. std::ostringstream os;
  2916. os << "Match of forbidden call of " << name
  2917. << " at " << loc << '\n' << values;
  2918. send_report<specialized>(severity::fatal, loc, os.str());
  2919. }
  2920. template <typename Sig>
  2921. struct matcher_info
  2922. {
  2923. using signature = Sig;
  2924. using return_type = void;
  2925. static unsigned long long const upper_call_limit = 1;
  2926. static bool const throws = false;
  2927. static bool const call_limit_set = false;
  2928. static bool const sequence_set = false;
  2929. static bool const side_effects = false;
  2930. };
  2931. template <typename Sig, typename Value>
  2932. struct call_matcher : public call_matcher_base<Sig>, expectation
  2933. {
  2934. using call_matcher_base<Sig>::name;
  2935. using call_matcher_base<Sig>::loc;
  2936. template <typename ... U>
  2937. call_matcher(
  2938. char const *file,
  2939. unsigned long line,
  2940. char const *call_string,
  2941. U &&... u)
  2942. : call_matcher_base<Sig>(location{file, line}, call_string)
  2943. , val(std::forward<U>(u)...)
  2944. {}
  2945. call_matcher(call_matcher &&r) = delete;
  2946. ~call_matcher() override
  2947. {
  2948. auto lock = get_lock();
  2949. if (is_unfulfilled())
  2950. {
  2951. report_missed("Unfulfilled expectation");
  2952. }
  2953. this->unlink();
  2954. }
  2955. bool
  2956. is_satisfied()
  2957. const
  2958. noexcept
  2959. override
  2960. {
  2961. auto lock = get_lock();
  2962. return call_count >= min_calls;
  2963. }
  2964. bool
  2965. is_saturated()
  2966. const
  2967. noexcept
  2968. override
  2969. {
  2970. auto lock = get_lock();
  2971. return call_count >= max_calls;
  2972. }
  2973. bool
  2974. is_unfulfilled()
  2975. const
  2976. noexcept
  2977. {
  2978. return !reported && this->is_linked() && call_count < min_calls;
  2979. }
  2980. void
  2981. mock_destroyed()
  2982. override
  2983. {
  2984. if (is_unfulfilled())
  2985. {
  2986. report_missed("Pending expectation on destroyed mock object");
  2987. }
  2988. }
  2989. call_matcher*
  2990. hook_last(
  2991. call_matcher_list<Sig> &list)
  2992. noexcept
  2993. {
  2994. list.push_front(this);
  2995. return this;
  2996. }
  2997. bool
  2998. matches(
  2999. call_params_type_t<Sig> const& params)
  3000. const
  3001. override
  3002. {
  3003. return match_parameters(val, params) && match_conditions(params);
  3004. }
  3005. bool
  3006. match_conditions(
  3007. call_params_type_t<Sig> const & params)
  3008. const
  3009. {
  3010. // std::all_of() is almost always preferable. The only reason
  3011. // for using a hand rolled loop is because it cuts compilation
  3012. // times quite noticeably (almost 10% with g++5.1)
  3013. for (auto& c : conditions)
  3014. {
  3015. if (!c.check(params)) return false;
  3016. }
  3017. return true;
  3018. }
  3019. bool
  3020. first_in_sequence()
  3021. const
  3022. noexcept
  3023. override
  3024. {
  3025. auto saturated = call_count >= min_calls;
  3026. return saturated || !sequences || sequences->is_first();
  3027. }
  3028. return_of_t<Sig>
  3029. return_value(
  3030. trace_agent& agent,
  3031. call_params_type_t<Sig>& params)
  3032. override
  3033. {
  3034. if (!return_handler_obj) return default_return<return_of_t<Sig>>();
  3035. return return_handler_obj->call(agent, params);
  3036. }
  3037. void
  3038. run_actions(
  3039. call_params_type_t<Sig>& params,
  3040. call_matcher_list<Sig> &saturated_list)
  3041. override
  3042. {
  3043. if (max_calls == 0)
  3044. {
  3045. reported = true;
  3046. report_forbidden_call(name, loc, params_string(params));
  3047. }
  3048. auto lock = get_lock();
  3049. {
  3050. if (call_count < min_calls && sequences)
  3051. {
  3052. sequences->validate(severity::fatal, name, loc);
  3053. }
  3054. if (++call_count == min_calls && sequences)
  3055. {
  3056. sequences->retire();
  3057. }
  3058. if (call_count == max_calls)
  3059. {
  3060. this->unlink();
  3061. saturated_list.push_back(this);
  3062. }
  3063. }
  3064. for (auto& a : actions) a.action(params);
  3065. }
  3066. std::ostream&
  3067. report_signature(
  3068. std::ostream& os)
  3069. const override
  3070. {
  3071. return os << name << " at " << loc;
  3072. }
  3073. std::ostream&
  3074. report_mismatch(
  3075. std::ostream& os,
  3076. call_params_type_t<Sig> const & params)
  3077. override
  3078. {
  3079. reported = true;
  3080. report_signature(os);
  3081. if (match_parameters(val, params))
  3082. {
  3083. for (auto& cond : conditions)
  3084. {
  3085. if (!cond.check(params))
  3086. {
  3087. os << "\n Failed WITH(" << cond.name() << ')';
  3088. }
  3089. }
  3090. }
  3091. else
  3092. {
  3093. os << '\n';
  3094. ::trompeloeil::print_mismatch(os, val, params);
  3095. }
  3096. return os;
  3097. }
  3098. void
  3099. report_missed(
  3100. char const *reason)
  3101. override
  3102. {
  3103. reported = true;
  3104. report_unfulfilled(
  3105. reason,
  3106. name,
  3107. params_string(val),
  3108. min_calls,
  3109. call_count,
  3110. loc);
  3111. }
  3112. template <typename C>
  3113. void
  3114. add_condition(
  3115. char const *str,
  3116. C&& c)
  3117. {
  3118. auto cond = new condition<Sig, C>(str, std::forward<C>(c));
  3119. conditions.push_back(cond);
  3120. }
  3121. template <typename S>
  3122. void
  3123. add_side_effect(
  3124. S&& s)
  3125. {
  3126. auto effect = new side_effect<Sig, S>(std::forward<S>(s));
  3127. actions.push_back(effect);
  3128. }
  3129. template <typename ... T>
  3130. void
  3131. set_sequence(
  3132. T&& ... t)
  3133. {
  3134. auto seq = new sequence_handler<sizeof...(T)>(name,
  3135. loc,
  3136. std::forward<T>(t)...);
  3137. sequences.reset(seq);
  3138. }
  3139. template <typename T>
  3140. inline
  3141. void
  3142. set_return(
  3143. std::true_type,
  3144. T&& h)
  3145. {
  3146. using basic_t = typename std::remove_reference<T>::type;
  3147. using handler = return_handler_t<Sig, basic_t>;
  3148. return_handler_obj.reset(new handler(std::forward<T>(h)));
  3149. }
  3150. template <typename T>
  3151. inline // Never called. Used to limit errmsg
  3152. static // with RETURN of wrong type and after:
  3153. void // FORBIDDEN_CALL
  3154. set_return(std::false_type, T&&t)// RETURN
  3155. noexcept; // THROW
  3156. condition_list<Sig> conditions;
  3157. side_effect_list<Sig> actions;
  3158. std::unique_ptr<return_handler<Sig>> return_handler_obj;
  3159. std::unique_ptr<sequence_handler_base> sequences;
  3160. unsigned long long call_count = 0;
  3161. std::atomic<unsigned long long> min_calls{1};
  3162. std::atomic<unsigned long long> max_calls{1};
  3163. Value val;
  3164. bool reported = false;
  3165. };
  3166. /* Clang (all versions) does not like computing the return type R
  3167. * before determining if the function overload is the best match.
  3168. */
  3169. template <
  3170. int N,
  3171. typename T,
  3172. typename = detail::enable_if_t<N <= std::tuple_size<T>::value>,
  3173. typename R = decltype(std::get<N-1>(std::declval<T>()))
  3174. >
  3175. constexpr
  3176. TROMPELOEIL_DECLTYPE_AUTO
  3177. arg(
  3178. T* t,
  3179. std::true_type)
  3180. TROMPELOEIL_TRAILING_RETURN_TYPE(R)
  3181. {
  3182. return std::get<N-1>(*t);
  3183. }
  3184. template <int N>
  3185. inline
  3186. constexpr
  3187. illegal_argument const
  3188. arg(
  3189. void const*,
  3190. std::false_type)
  3191. noexcept
  3192. {
  3193. return {};
  3194. }
  3195. template <
  3196. int N,
  3197. typename T,
  3198. typename R = decltype(arg<N>(std::declval<T*>(),
  3199. std::integral_constant<bool, (N <= std::tuple_size<T>::value)>{}))
  3200. >
  3201. TROMPELOEIL_DECLTYPE_AUTO
  3202. mkarg(
  3203. T& t)
  3204. noexcept
  3205. TROMPELOEIL_TRAILING_RETURN_TYPE(R)
  3206. {
  3207. return arg<N>(&t, std::integral_constant<bool, (N <= std::tuple_size<T>::value)>{});
  3208. }
  3209. template <typename Mock>
  3210. struct call_validator_t
  3211. {
  3212. template <typename M, typename Tag, typename Info>
  3213. auto
  3214. make_expectation(
  3215. std::true_type,
  3216. call_modifier<M, Tag, Info>&& m)
  3217. const
  3218. noexcept
  3219. TROMPELOEIL_TRAILING_RETURN_TYPE(std::unique_ptr<expectation>)
  3220. {
  3221. auto lock = get_lock();
  3222. m.matcher->hook_last(obj.trompeloeil_matcher_list(static_cast<Tag*>(nullptr)));
  3223. return std::unique_ptr<expectation>(m.matcher);
  3224. }
  3225. template <typename T>
  3226. static // Never called. Used to
  3227. std::unique_ptr<expectation> // limit errmsg when RETURN
  3228. make_expectation(std::false_type, T&&) noexcept; // is missing in non-void
  3229. // function
  3230. template <typename M, typename Tag, typename Info>
  3231. inline
  3232. auto
  3233. operator+(
  3234. call_modifier<M, Tag, Info>&& t)
  3235. const
  3236. TROMPELOEIL_TRAILING_RETURN_TYPE(std::unique_ptr<expectation>)
  3237. {
  3238. using call = call_modifier<M, Tag, Info>;
  3239. using sigret = return_of_t<typename call::signature>;
  3240. using ret = typename call::return_type;
  3241. constexpr bool retmatch = std::is_same<ret, sigret>::value;
  3242. constexpr bool forbidden = call::upper_call_limit == 0ULL;
  3243. constexpr bool valid_return_type = call::throws || retmatch || forbidden;
  3244. static_assert(valid_return_type, "RETURN missing for non-void function");
  3245. auto tag = std::integral_constant<bool, valid_return_type>{};
  3246. return make_expectation(tag, std::move(t));
  3247. }
  3248. Mock& obj;
  3249. };
  3250. template <typename T,
  3251. typename = detail::enable_if_t<std::is_lvalue_reference<T&&>::value>>
  3252. inline
  3253. T&&
  3254. decay_return_type(
  3255. T&& t)
  3256. {
  3257. return std::forward<T>(t);
  3258. }
  3259. template <typename T,
  3260. typename = detail::enable_if_t<std::is_rvalue_reference<T&&>::value>>
  3261. inline
  3262. T
  3263. decay_return_type(
  3264. T&& t)
  3265. {
  3266. return std::forward<T>(t);
  3267. }
  3268. template <typename T, size_t N>
  3269. inline
  3270. T*
  3271. decay_return_type(
  3272. T (&t)[N])
  3273. {
  3274. return t;
  3275. }
  3276. template <bool sequence_set>
  3277. struct lifetime_monitor_modifier
  3278. {
  3279. operator std::unique_ptr<lifetime_monitor>() { return std::move(monitor);}
  3280. template <typename ... T, bool b = sequence_set>
  3281. lifetime_monitor_modifier<true>
  3282. in_sequence(T&& ... t)
  3283. {
  3284. static_assert(!b,
  3285. "Multiple IN_SEQUENCE does not make sense."
  3286. " You can list several sequence objects at once");
  3287. monitor->set_sequence(std::forward<T>(t)...);
  3288. return { std::move(monitor) };
  3289. }
  3290. std::unique_ptr<lifetime_monitor> monitor;
  3291. };
  3292. struct lifetime_monitor_releaser
  3293. {
  3294. template <bool b>
  3295. std::unique_ptr<trompeloeil::lifetime_monitor>
  3296. operator+(
  3297. lifetime_monitor_modifier<b>&& m)
  3298. const
  3299. {
  3300. return m;
  3301. }
  3302. };
  3303. template <typename Sig>
  3304. struct expectations
  3305. {
  3306. ~expectations() {
  3307. active.decommission();
  3308. saturated.decommission();
  3309. }
  3310. call_matcher_list<Sig> active;
  3311. call_matcher_list<Sig> saturated;
  3312. };
  3313. template <typename Sig, typename ... P>
  3314. return_of_t<Sig> mock_func(std::false_type, P&& ...);
  3315. template <typename Sig, typename ... P>
  3316. return_of_t<Sig>
  3317. mock_func(std::true_type,
  3318. expectations<Sig>& e,
  3319. char const *func_name,
  3320. char const *sig_name,
  3321. P&& ... p)
  3322. {
  3323. auto lock = get_lock();
  3324. call_params_type_t<void(P...)> param_value(std::forward<P>(p)...);
  3325. auto i = find(e.active, param_value);
  3326. if (!i)
  3327. {
  3328. report_mismatch(e.active,
  3329. e.saturated,
  3330. func_name + std::string(" with signature ") + sig_name,
  3331. param_value);
  3332. }
  3333. trace_agent ta{i->loc, i->name, tracer_obj()};
  3334. try
  3335. {
  3336. ta.trace_params(param_value);
  3337. i->run_actions(param_value, e.saturated);
  3338. return i->return_value(ta, param_value);
  3339. }
  3340. catch (...)
  3341. {
  3342. ta.trace_exception();
  3343. throw;
  3344. }
  3345. }
  3346. template <typename ... U>
  3347. struct param_helper {
  3348. using type = decltype(std::make_tuple(std::declval<U>()...));
  3349. };
  3350. template <typename ... U>
  3351. using param_t = typename param_helper<U...>::type;
  3352. template <typename sig, typename tag, typename... U>
  3353. using modifier_t = call_modifier<call_matcher<sig, param_t<U...>>,
  3354. tag,
  3355. matcher_info<sig>>;
  3356. template <typename M,
  3357. typename = detail::enable_if_t<::trompeloeil::is_matcher<M>::value>>
  3358. inline
  3359. ::trompeloeil::ptr_deref<detail::decay_t<M>>
  3360. operator*(
  3361. M&& m)
  3362. {
  3363. return ::trompeloeil::ptr_deref<detail::decay_t<M>>{std::forward<M>(m)};
  3364. }
  3365. template <typename M,
  3366. typename = detail::enable_if_t<::trompeloeil::is_matcher<M>::value>>
  3367. inline
  3368. ::trompeloeil::neg_matcher<detail::decay_t<M>>
  3369. operator!(
  3370. M&& m)
  3371. {
  3372. return ::trompeloeil::neg_matcher<detail::decay_t<M>>{std::forward<M>(m)};
  3373. }
  3374. /*
  3375. * Convert the signature S of a mock function to the signature of
  3376. * a member function of class T that takes the same parameters P
  3377. * but returns R.
  3378. *
  3379. * The member function has the same constness as the mock function.
  3380. */
  3381. template <typename T, typename R, typename S>
  3382. struct signature_to_member_function;
  3383. template <typename T, typename R, typename R_of_S, typename... P>
  3384. struct signature_to_member_function<T, R, R_of_S(P...)>
  3385. {
  3386. using type = detail::conditional_t<
  3387. std::is_const<T>::value,
  3388. R (T::*)(P...) const,
  3389. R (T::*)(P...)>;
  3390. };
  3391. template <typename T>
  3392. struct mock_interface : public T
  3393. {
  3394. using trompeloeil_interface_name = T;
  3395. using T::T;
  3396. };
  3397. }
  3398. #define TROMPELOEIL_LINE_ID(name) \
  3399. TROMPELOEIL_CONCAT(trompeloeil_l_ ## name ## _, __LINE__)
  3400. #define TROMPELOEIL_COUNT_ID(name) \
  3401. TROMPELOEIL_CONCAT(trompeloeil_c_ ## name ## _, __COUNTER__)
  3402. #ifdef _MSC_VER
  3403. #define TROMPELOEIL_MAKE_MOCK0(name, sig, ...) \
  3404. TROMPELOEIL_MAKE_MOCK_(name,,0, sig, __VA_ARGS__,,)
  3405. #define TROMPELOEIL_MAKE_MOCK1(name, sig, ...) \
  3406. TROMPELOEIL_MAKE_MOCK_(name,,1, sig, __VA_ARGS__,,)
  3407. #define TROMPELOEIL_MAKE_MOCK2(name, sig, ...) \
  3408. TROMPELOEIL_MAKE_MOCK_(name,,2, sig, __VA_ARGS__,,)
  3409. #define TROMPELOEIL_MAKE_MOCK3(name, sig, ...) \
  3410. TROMPELOEIL_MAKE_MOCK_(name,,3, sig, __VA_ARGS__,,)
  3411. #define TROMPELOEIL_MAKE_MOCK4(name, sig, ...) \
  3412. TROMPELOEIL_MAKE_MOCK_(name,,4, sig, __VA_ARGS__,,)
  3413. #define TROMPELOEIL_MAKE_MOCK5(name, sig, ...) \
  3414. TROMPELOEIL_MAKE_MOCK_(name,,5, sig, __VA_ARGS__,,)
  3415. #define TROMPELOEIL_MAKE_MOCK6(name, sig, ...) \
  3416. TROMPELOEIL_MAKE_MOCK_(name,,6, sig, __VA_ARGS__,,)
  3417. #define TROMPELOEIL_MAKE_MOCK7(name, sig, ...) \
  3418. TROMPELOEIL_MAKE_MOCK_(name,,7, sig, __VA_ARGS__,,)
  3419. #define TROMPELOEIL_MAKE_MOCK8(name, sig, ...) \
  3420. TROMPELOEIL_MAKE_MOCK_(name,,8, sig, __VA_ARGS__,,)
  3421. #define TROMPELOEIL_MAKE_MOCK9(name, sig, ...) \
  3422. TROMPELOEIL_MAKE_MOCK_(name,,9, sig, __VA_ARGS__,,)
  3423. #define TROMPELOEIL_MAKE_MOCK10(name, sig, ...) \
  3424. TROMPELOEIL_MAKE_MOCK_(name,,10, sig, __VA_ARGS__,,)
  3425. #define TROMPELOEIL_MAKE_MOCK11(name, sig, ...) \
  3426. TROMPELOEIL_MAKE_MOCK_(name,,11, sig, __VA_ARGS__,,)
  3427. #define TROMPELOEIL_MAKE_MOCK12(name, sig, ...) \
  3428. TROMPELOEIL_MAKE_MOCK_(name,,12, sig, __VA_ARGS__,,)
  3429. #define TROMPELOEIL_MAKE_MOCK13(name, sig, ...) \
  3430. TROMPELOEIL_MAKE_MOCK_(name,,13, sig, __VA_ARGS__,,)
  3431. #define TROMPELOEIL_MAKE_MOCK14(name, sig, ...) \
  3432. TROMPELOEIL_MAKE_MOCK_(name,,14, sig, __VA_ARGS__,,)
  3433. #define TROMPELOEIL_MAKE_MOCK15(name, sig, ...) \
  3434. TROMPELOEIL_MAKE_MOCK_(name,,15, sig, __VA_ARGS__,,)
  3435. #define TROMPELOEIL_MAKE_CONST_MOCK0(name, sig, ...) \
  3436. TROMPELOEIL_MAKE_MOCK_(name,const,0, sig, __VA_ARGS__,,)
  3437. #define TROMPELOEIL_MAKE_CONST_MOCK1(name, sig, ...) \
  3438. TROMPELOEIL_MAKE_MOCK_(name,const,1, sig, __VA_ARGS__,,)
  3439. #define TROMPELOEIL_MAKE_CONST_MOCK2(name, sig, ...) \
  3440. TROMPELOEIL_MAKE_MOCK_(name,const,2, sig, __VA_ARGS__,,)
  3441. #define TROMPELOEIL_MAKE_CONST_MOCK3(name, sig, ...) \
  3442. TROMPELOEIL_MAKE_MOCK_(name,const,3, sig, __VA_ARGS__,,)
  3443. #define TROMPELOEIL_MAKE_CONST_MOCK4(name, sig, ...) \
  3444. TROMPELOEIL_MAKE_MOCK_(name,const,4, sig, __VA_ARGS__,,)
  3445. #define TROMPELOEIL_MAKE_CONST_MOCK5(name, sig, ...) \
  3446. TROMPELOEIL_MAKE_MOCK_(name,const,5, sig, __VA_ARGS__,,)
  3447. #define TROMPELOEIL_MAKE_CONST_MOCK6(name, sig, ...) \
  3448. TROMPELOEIL_MAKE_MOCK_(name,const,6, sig, __VA_ARGS__,,)
  3449. #define TROMPELOEIL_MAKE_CONST_MOCK7(name, sig, ...) \
  3450. TROMPELOEIL_MAKE_MOCK_(name,const,7, sig, __VA_ARGS__,,)
  3451. #define TROMPELOEIL_MAKE_CONST_MOCK8(name, sig, ...) \
  3452. TROMPELOEIL_MAKE_MOCK_(name,const,8, sig, __VA_ARGS__,,)
  3453. #define TROMPELOEIL_MAKE_CONST_MOCK9(name, sig, ...) \
  3454. TROMPELOEIL_MAKE_MOCK_(name,const,9, sig, __VA_ARGS__,,)
  3455. #define TROMPELOEIL_MAKE_CONST_MOCK10(name, sig, ...) \
  3456. TROMPELOEIL_MAKE_MOCK_(name,const,10, sig, __VA_ARGS__,,)
  3457. #define TROMPELOEIL_MAKE_CONST_MOCK11(name, sig, ...) \
  3458. TROMPELOEIL_MAKE_MOCK_(name,const,11, sig, __VA_ARGS__,,)
  3459. #define TROMPELOEIL_MAKE_CONST_MOCK12(name, sig, ...) \
  3460. TROMPELOEIL_MAKE_MOCK_(name,const,12, sig, __VA_ARGS__,,)
  3461. #define TROMPELOEIL_MAKE_CONST_MOCK13(name, sig, ...) \
  3462. TROMPELOEIL_MAKE_MOCK_(name,const,13, sig, __VA_ARGS__,,)
  3463. #define TROMPELOEIL_MAKE_CONST_MOCK14(name, sig, ...) \
  3464. TROMPELOEIL_MAKE_MOCK_(name,const,14, sig, __VA_ARGS__,,)
  3465. #define TROMPELOEIL_MAKE_CONST_MOCK15(name, sig, ...) \
  3466. TROMPELOEIL_MAKE_MOCK_(name,const,15, sig, __VA_ARGS__,,)
  3467. #else
  3468. // sane standards compliant preprocessor
  3469. #define TROMPELOEIL_MAKE_MOCK0(name, ...) \
  3470. TROMPELOEIL_MAKE_MOCK_(name,,0, __VA_ARGS__,,)
  3471. #define TROMPELOEIL_MAKE_MOCK1(name, ...) \
  3472. TROMPELOEIL_MAKE_MOCK_(name,,1, __VA_ARGS__,,)
  3473. #define TROMPELOEIL_MAKE_MOCK2(name, ...) \
  3474. TROMPELOEIL_MAKE_MOCK_(name,,2, __VA_ARGS__,,)
  3475. #define TROMPELOEIL_MAKE_MOCK3(name, ...) \
  3476. TROMPELOEIL_MAKE_MOCK_(name,,3, __VA_ARGS__,,)
  3477. #define TROMPELOEIL_MAKE_MOCK4(name, ...) \
  3478. TROMPELOEIL_MAKE_MOCK_(name,,4, __VA_ARGS__,,)
  3479. #define TROMPELOEIL_MAKE_MOCK5(name, ...) \
  3480. TROMPELOEIL_MAKE_MOCK_(name,,5, __VA_ARGS__,,)
  3481. #define TROMPELOEIL_MAKE_MOCK6(name, ...) \
  3482. TROMPELOEIL_MAKE_MOCK_(name,,6, __VA_ARGS__,,)
  3483. #define TROMPELOEIL_MAKE_MOCK7(name, ...) \
  3484. TROMPELOEIL_MAKE_MOCK_(name,,7, __VA_ARGS__,,)
  3485. #define TROMPELOEIL_MAKE_MOCK8(name, ...) \
  3486. TROMPELOEIL_MAKE_MOCK_(name,,8, __VA_ARGS__,,)
  3487. #define TROMPELOEIL_MAKE_MOCK9(name, ...) \
  3488. TROMPELOEIL_MAKE_MOCK_(name,,9, __VA_ARGS__,,)
  3489. #define TROMPELOEIL_MAKE_MOCK10(name, ...) \
  3490. TROMPELOEIL_MAKE_MOCK_(name,,10, __VA_ARGS__,,)
  3491. #define TROMPELOEIL_MAKE_MOCK11(name, ...) \
  3492. TROMPELOEIL_MAKE_MOCK_(name,,11, __VA_ARGS__,,)
  3493. #define TROMPELOEIL_MAKE_MOCK12(name, ...) \
  3494. TROMPELOEIL_MAKE_MOCK_(name,,12, __VA_ARGS__,,)
  3495. #define TROMPELOEIL_MAKE_MOCK13(name, ...) \
  3496. TROMPELOEIL_MAKE_MOCK_(name,,13, __VA_ARGS__,,)
  3497. #define TROMPELOEIL_MAKE_MOCK14(name, ...) \
  3498. TROMPELOEIL_MAKE_MOCK_(name,,14,__VA_ARGS__,,)
  3499. #define TROMPELOEIL_MAKE_MOCK15(name, ...) \
  3500. TROMPELOEIL_MAKE_MOCK_(name,,15, __VA_ARGS__,,)
  3501. #define TROMPELOEIL_MAKE_CONST_MOCK0(name, ...) \
  3502. TROMPELOEIL_MAKE_MOCK_(name,const,0, __VA_ARGS__,,)
  3503. #define TROMPELOEIL_MAKE_CONST_MOCK1(name, ...) \
  3504. TROMPELOEIL_MAKE_MOCK_(name,const,1, __VA_ARGS__,,)
  3505. #define TROMPELOEIL_MAKE_CONST_MOCK2(name, ...) \
  3506. TROMPELOEIL_MAKE_MOCK_(name,const,2, __VA_ARGS__,,)
  3507. #define TROMPELOEIL_MAKE_CONST_MOCK3(name, ...) \
  3508. TROMPELOEIL_MAKE_MOCK_(name,const,3, __VA_ARGS__,,)
  3509. #define TROMPELOEIL_MAKE_CONST_MOCK4(name, ...) \
  3510. TROMPELOEIL_MAKE_MOCK_(name,const,4, __VA_ARGS__,,)
  3511. #define TROMPELOEIL_MAKE_CONST_MOCK5(name, ...) \
  3512. TROMPELOEIL_MAKE_MOCK_(name,const,5, __VA_ARGS__,,)
  3513. #define TROMPELOEIL_MAKE_CONST_MOCK6(name, ...) \
  3514. TROMPELOEIL_MAKE_MOCK_(name,const,6, __VA_ARGS__,,)
  3515. #define TROMPELOEIL_MAKE_CONST_MOCK7(name, ...) \
  3516. TROMPELOEIL_MAKE_MOCK_(name,const,7, __VA_ARGS__,,)
  3517. #define TROMPELOEIL_MAKE_CONST_MOCK8(name, ...) \
  3518. TROMPELOEIL_MAKE_MOCK_(name,const,8, __VA_ARGS__,,)
  3519. #define TROMPELOEIL_MAKE_CONST_MOCK9(name, ...) \
  3520. TROMPELOEIL_MAKE_MOCK_(name,const,9, __VA_ARGS__,,)
  3521. #define TROMPELOEIL_MAKE_CONST_MOCK10(name, ...) \
  3522. TROMPELOEIL_MAKE_MOCK_(name,const,10, __VA_ARGS__,,)
  3523. #define TROMPELOEIL_MAKE_CONST_MOCK11(name, ...) \
  3524. TROMPELOEIL_MAKE_MOCK_(name,const,11, __VA_ARGS__,,)
  3525. #define TROMPELOEIL_MAKE_CONST_MOCK12(name, ...) \
  3526. TROMPELOEIL_MAKE_MOCK_(name,const,12, __VA_ARGS__,,)
  3527. #define TROMPELOEIL_MAKE_CONST_MOCK13(name, ...) \
  3528. TROMPELOEIL_MAKE_MOCK_(name,const,13, __VA_ARGS__,,)
  3529. #define TROMPELOEIL_MAKE_CONST_MOCK14(name, ...) \
  3530. TROMPELOEIL_MAKE_MOCK_(name,const,14, __VA_ARGS__,,)
  3531. #define TROMPELOEIL_MAKE_CONST_MOCK15(name, ...) \
  3532. TROMPELOEIL_MAKE_MOCK_(name,const,15, __VA_ARGS__,,)
  3533. #endif
  3534. #define TROMPELOEIL_IMPLEMENT_MOCK0(name) \
  3535. TROMPELOEIL_IMPLEMENT_MOCK_(0, name)
  3536. #define TROMPELOEIL_IMPLEMENT_MOCK1(name) \
  3537. TROMPELOEIL_IMPLEMENT_MOCK_(1, name)
  3538. #define TROMPELOEIL_IMPLEMENT_MOCK2(name) \
  3539. TROMPELOEIL_IMPLEMENT_MOCK_(2, name)
  3540. #define TROMPELOEIL_IMPLEMENT_MOCK3(name) \
  3541. TROMPELOEIL_IMPLEMENT_MOCK_(3, name)
  3542. #define TROMPELOEIL_IMPLEMENT_MOCK4(name) \
  3543. TROMPELOEIL_IMPLEMENT_MOCK_(4, name)
  3544. #define TROMPELOEIL_IMPLEMENT_MOCK5(name) \
  3545. TROMPELOEIL_IMPLEMENT_MOCK_(5, name)
  3546. #define TROMPELOEIL_IMPLEMENT_MOCK6(name) \
  3547. TROMPELOEIL_IMPLEMENT_MOCK_(6, name)
  3548. #define TROMPELOEIL_IMPLEMENT_MOCK7(name) \
  3549. TROMPELOEIL_IMPLEMENT_MOCK_(7, name)
  3550. #define TROMPELOEIL_IMPLEMENT_MOCK8(name) \
  3551. TROMPELOEIL_IMPLEMENT_MOCK_(8, name)
  3552. #define TROMPELOEIL_IMPLEMENT_MOCK9(name) \
  3553. TROMPELOEIL_IMPLEMENT_MOCK_(9, name)
  3554. #define TROMPELOEIL_IMPLEMENT_MOCK10(name) \
  3555. TROMPELOEIL_IMPLEMENT_MOCK_(10, name)
  3556. #define TROMPELOEIL_IMPLEMENT_MOCK11(name) \
  3557. TROMPELOEIL_IMPLEMENT_MOCK_(11, name)
  3558. #define TROMPELOEIL_IMPLEMENT_MOCK12(name) \
  3559. TROMPELOEIL_IMPLEMENT_MOCK_(12, name)
  3560. #define TROMPELOEIL_IMPLEMENT_MOCK13(name) \
  3561. TROMPELOEIL_IMPLEMENT_MOCK_(13, name)
  3562. #define TROMPELOEIL_IMPLEMENT_MOCK14(name) \
  3563. TROMPELOEIL_IMPLEMENT_MOCK_(14, name)
  3564. #define TROMPELOEIL_IMPLEMENT_MOCK15(name) \
  3565. TROMPELOEIL_IMPLEMENT_MOCK_(15, name)
  3566. #define TROMPELOEIL_IMPLEMENT_CONST_MOCK0(name) \
  3567. TROMPELOEIL_IMPLEMENT_CONST_MOCK_(0, name)
  3568. #define TROMPELOEIL_IMPLEMENT_CONST_MOCK1(name) \
  3569. TROMPELOEIL_IMPLEMENT_CONST_MOCK_(1, name)
  3570. #define TROMPELOEIL_IMPLEMENT_CONST_MOCK2(name) \
  3571. TROMPELOEIL_IMPLEMENT_CONST_MOCK_(2, name)
  3572. #define TROMPELOEIL_IMPLEMENT_CONST_MOCK3(name) \
  3573. TROMPELOEIL_IMPLEMENT_CONST_MOCK_(3, name)
  3574. #define TROMPELOEIL_IMPLEMENT_CONST_MOCK4(name) \
  3575. TROMPELOEIL_IMPLEMENT_CONST_MOCK_(4, name)
  3576. #define TROMPELOEIL_IMPLEMENT_CONST_MOCK5(name) \
  3577. TROMPELOEIL_IMPLEMENT_CONST_MOCK_(5, name)
  3578. #define TROMPELOEIL_IMPLEMENT_CONST_MOCK6(name) \
  3579. TROMPELOEIL_IMPLEMENT_CONST_MOCK_(6, name)
  3580. #define TROMPELOEIL_IMPLEMENT_CONST_MOCK7(name) \
  3581. TROMPELOEIL_IMPLEMENT_CONST_MOCK_(7, name)
  3582. #define TROMPELOEIL_IMPLEMENT_CONST_MOCK8(name) \
  3583. TROMPELOEIL_IMPLEMENT_CONST_MOCK_(8, name)
  3584. #define TROMPELOEIL_IMPLEMENT_CONST_MOCK9(name) \
  3585. TROMPELOEIL_IMPLEMENT_CONST_MOCK_(9, name)
  3586. #define TROMPELOEIL_IMPLEMENT_CONST_MOCK10(name) \
  3587. TROMPELOEIL_IMPLEMENT_CONST_MOCK_(10, name)
  3588. #define TROMPELOEIL_IMPLEMENT_CONST_MOCK11(name) \
  3589. TROMPELOEIL_IMPLEMENT_CONST_MOCK_(11, name)
  3590. #define TROMPELOEIL_IMPLEMENT_CONST_MOCK12(name) \
  3591. TROMPELOEIL_IMPLEMENT_CONST_MOCK_(12, name)
  3592. #define TROMPELOEIL_IMPLEMENT_CONST_MOCK13(name) \
  3593. TROMPELOEIL_IMPLEMENT_CONST_MOCK_(13, name)
  3594. #define TROMPELOEIL_IMPLEMENT_CONST_MOCK14(name) \
  3595. TROMPELOEIL_IMPLEMENT_CONST_MOCK_(14, name)
  3596. #define TROMPELOEIL_IMPLEMENT_CONST_MOCK15(name) \
  3597. TROMPELOEIL_IMPLEMENT_CONST_MOCK_(15, name)
  3598. #define TROMPELOEIL_IMPLEMENT_MOCK_(num, name) \
  3599. TROMPELOEIL_MAKE_MOCK_(name,,num, decltype(::trompeloeil::nonconst_member_signature(&trompeloeil_interface_name::name))::type,override,)
  3600. #define TROMPELOEIL_IMPLEMENT_CONST_MOCK_(num, name) \
  3601. TROMPELOEIL_MAKE_MOCK_(name,const,num, decltype(::trompeloeil::const_member_signature(&trompeloeil_interface_name::name))::type,override,)
  3602. #define TROMPELOEIL_MAKE_MOCK_(name, constness, num, sig, spec, ...) \
  3603. using TROMPELOEIL_LINE_ID(cardinality_match) = \
  3604. std::integral_constant<bool, num == ::trompeloeil::param_list<sig>::size>; \
  3605. static_assert(TROMPELOEIL_LINE_ID(cardinality_match)::value, \
  3606. "Function signature does not have " #num " parameters"); \
  3607. using TROMPELOEIL_LINE_ID(matcher_list_t) = ::trompeloeil::call_matcher_list<sig>;\
  3608. using TROMPELOEIL_LINE_ID(expectation_list_t) = ::trompeloeil::expectations<sig>; \
  3609. struct TROMPELOEIL_LINE_ID(tag_type_trompeloeil) \
  3610. { \
  3611. const char* trompeloeil_expectation_file; \
  3612. unsigned long trompeloeil_expectation_line; \
  3613. const char *trompeloeil_expectation_string; \
  3614. \
  3615. /* Work around parsing bug in VS 2015 when a "complex" */ \
  3616. /* decltype() appears in a trailing return type. */ \
  3617. /* Further, work around C2066 defect in VS 2017 15.7.1. */ \
  3618. using trompeloeil_sig_t = typename ::trompeloeil::identity_type<sig>::type;\
  3619. \
  3620. using trompeloeil_call_params_type_t = \
  3621. ::trompeloeil::call_params_type_t<sig>; \
  3622. \
  3623. using trompeloeil_return_of_t = ::trompeloeil::return_of_t<sig>; \
  3624. \
  3625. template <typename ... trompeloeil_param_type> \
  3626. auto name( \
  3627. trompeloeil_param_type&& ... trompeloeil_param) \
  3628. -> ::trompeloeil::modifier_t<trompeloeil_sig_t, \
  3629. TROMPELOEIL_LINE_ID(tag_type_trompeloeil), \
  3630. trompeloeil_param_type...> \
  3631. { \
  3632. using matcher = ::trompeloeil::call_matcher< \
  3633. sig, \
  3634. ::trompeloeil::param_t<trompeloeil_param_type...>>; \
  3635. return { \
  3636. new matcher { \
  3637. trompeloeil_expectation_file, \
  3638. trompeloeil_expectation_line, \
  3639. trompeloeil_expectation_string, \
  3640. std::forward<trompeloeil_param_type>(trompeloeil_param)... \
  3641. } \
  3642. }; \
  3643. } \
  3644. }; \
  3645. \
  3646. TROMPELOEIL_LINE_ID(matcher_list_t)& \
  3647. trompeloeil_matcher_list( \
  3648. TROMPELOEIL_LINE_ID(tag_type_trompeloeil)*) \
  3649. constness \
  3650. noexcept \
  3651. { \
  3652. return TROMPELOEIL_LINE_ID(expectations).active; \
  3653. } \
  3654. \
  3655. ::trompeloeil::return_of_t<sig> \
  3656. name( \
  3657. TROMPELOEIL_PARAM_LIST(num, sig)) \
  3658. constness \
  3659. spec \
  3660. { \
  3661. /* Use the auxiliary functions to avoid unneeded-member-function warning */\
  3662. using T_ ## name = typename std::remove_reference<decltype(*this)>::type; \
  3663. \
  3664. using pmf_s_t = typename ::trompeloeil::signature_to_member_function< \
  3665. T_ ## name, decltype(*this), sig>::type; \
  3666. \
  3667. using pmf_e_t = typename ::trompeloeil::signature_to_member_function< \
  3668. T_ ## name, TROMPELOEIL_LINE_ID(tag_type_trompeloeil), sig>::type; \
  3669. \
  3670. auto s_ptr = static_cast<pmf_s_t>(&T_ ## name::trompeloeil_self_ ## name); \
  3671. auto e_ptr = static_cast<pmf_e_t>(&T_ ## name::trompeloeil_tag_ ## name); \
  3672. \
  3673. ::trompeloeil::ignore(s_ptr, e_ptr); \
  3674. \
  3675. return ::trompeloeil::mock_func<sig>(TROMPELOEIL_LINE_ID(cardinality_match){}, \
  3676. TROMPELOEIL_LINE_ID(expectations), \
  3677. #name, \
  3678. #sig \
  3679. TROMPELOEIL_PARAMS(num)); \
  3680. } \
  3681. \
  3682. auto \
  3683. trompeloeil_self_ ## name(TROMPELOEIL_PARAM_LIST(num, sig)) constness \
  3684. -> decltype(*this) \
  3685. { \
  3686. ::trompeloeil::ignore(#name TROMPELOEIL_PARAMS(num)); \
  3687. return *this; \
  3688. } \
  3689. \
  3690. TROMPELOEIL_LINE_ID(tag_type_trompeloeil) \
  3691. trompeloeil_tag_ ## name(TROMPELOEIL_PARAM_LIST(num, sig)) constness \
  3692. { \
  3693. ::trompeloeil::ignore(#name TROMPELOEIL_PARAMS(num)); \
  3694. return {nullptr, 0ul, nullptr}; \
  3695. } \
  3696. \
  3697. mutable TROMPELOEIL_LINE_ID(expectation_list_t) TROMPELOEIL_LINE_ID(expectations)
  3698. #define TROMPELOEIL_LPAREN (
  3699. #define TROMPELOEIL_MORE_THAN_TWO_ARGS(...) \
  3700. TROMPELOEIL_IDENTITY( \
  3701. TROMPELOEIL_ARG16(__VA_ARGS__, \
  3702. T, T, T, T, T, T, T, T, T, T, T, T, T, F, F, F))
  3703. #define TROMPELOEIL_REQUIRE_CALL_V(...) \
  3704. TROMPELOEIL_IDENTITY(TROMPELOEIL_REQUIRE_CALL_IMPL TROMPELOEIL_LPAREN \
  3705. TROMPELOEIL_MORE_THAN_TWO_ARGS(__VA_ARGS__), __VA_ARGS__))
  3706. // Dispatch to _F (0, 1, or 2 arguments) or _T (> 2 arguments) macro
  3707. #define TROMPELOEIL_REQUIRE_CALL_IMPL(N, ...) \
  3708. TROMPELOEIL_IDENTITY( \
  3709. TROMPELOEIL_REQUIRE_CALL_ ## N TROMPELOEIL_LPAREN __VA_ARGS__))
  3710. // Accept only two arguments
  3711. #define TROMPELOEIL_REQUIRE_CALL_F(obj, func) \
  3712. auto TROMPELOEIL_COUNT_ID(call_obj) = \
  3713. TROMPELOEIL_REQUIRE_CALL_V_LAMBDA(obj, func, #obj, #func, .null_modifier())
  3714. // Accept three or more arguments.
  3715. #define TROMPELOEIL_REQUIRE_CALL_T(obj, func, ...) \
  3716. auto TROMPELOEIL_COUNT_ID(call_obj) = \
  3717. TROMPELOEIL_REQUIRE_CALL_V_LAMBDA(obj, func, #obj, #func, __VA_ARGS__)
  3718. #define TROMPELOEIL_REQUIRE_CALL_V_LAMBDA(obj, func, obj_s, func_s, ...) \
  3719. [&] \
  3720. { \
  3721. using s_t = decltype((obj).TROMPELOEIL_CONCAT(trompeloeil_self_, func)); \
  3722. using e_t = decltype((obj).TROMPELOEIL_CONCAT(trompeloeil_tag_,func)); \
  3723. \
  3724. return TROMPELOEIL_REQUIRE_CALL_LAMBDA_OBJ(obj, func, obj_s, func_s) \
  3725. __VA_ARGS__ \
  3726. ; \
  3727. }()
  3728. #define TROMPELOEIL_REQUIRE_CALL_LAMBDA_OBJ(obj, func, obj_s, func_s) \
  3729. ::trompeloeil::call_validator_t<s_t>{(obj)} + \
  3730. ::trompeloeil::detail::conditional_t<false, \
  3731. decltype((obj).func), \
  3732. e_t> \
  3733. {__FILE__, static_cast<unsigned long>(__LINE__), obj_s "." func_s}.func
  3734. #define TROMPELOEIL_NAMED_REQUIRE_CALL_V(...) \
  3735. TROMPELOEIL_IDENTITY(TROMPELOEIL_NAMED_REQUIRE_CALL_IMPL TROMPELOEIL_LPAREN \
  3736. TROMPELOEIL_MORE_THAN_TWO_ARGS(__VA_ARGS__), __VA_ARGS__))
  3737. // Dispatch to _F (0, 1, or 2 arguments) or _T (> 2 arguments) macro
  3738. #define TROMPELOEIL_NAMED_REQUIRE_CALL_IMPL(N, ...) \
  3739. TROMPELOEIL_IDENTITY( \
  3740. TROMPELOEIL_NAMED_REQUIRE_CALL_ ## N TROMPELOEIL_LPAREN __VA_ARGS__))
  3741. // Accept only two arguments
  3742. #define TROMPELOEIL_NAMED_REQUIRE_CALL_F(obj, func) \
  3743. TROMPELOEIL_REQUIRE_CALL_V_LAMBDA(obj, func, #obj, #func, .null_modifier())
  3744. // Accept three or more arguments.
  3745. #define TROMPELOEIL_NAMED_REQUIRE_CALL_T(obj, func, ...) \
  3746. TROMPELOEIL_REQUIRE_CALL_V_LAMBDA(obj, func, #obj, #func, __VA_ARGS__)
  3747. #define TROMPELOEIL_ALLOW_CALL_V(...) \
  3748. TROMPELOEIL_IDENTITY(TROMPELOEIL_ALLOW_CALL_IMPL TROMPELOEIL_LPAREN \
  3749. TROMPELOEIL_MORE_THAN_TWO_ARGS(__VA_ARGS__), __VA_ARGS__))
  3750. // Dispatch to _F (0, 1, or 2 arguments) or _T (> 2 arguments) macro
  3751. #define TROMPELOEIL_ALLOW_CALL_IMPL(N, ...) \
  3752. TROMPELOEIL_IDENTITY( \
  3753. TROMPELOEIL_ALLOW_CALL_ ## N TROMPELOEIL_LPAREN __VA_ARGS__))
  3754. // Accept only two arguments
  3755. #define TROMPELOEIL_ALLOW_CALL_F(obj, func) \
  3756. TROMPELOEIL_REQUIRE_CALL_T(obj, func, .TROMPELOEIL_TIMES(0, ~0ULL))
  3757. // Accept three or more arguments.
  3758. #define TROMPELOEIL_ALLOW_CALL_T(obj, func, ...) \
  3759. TROMPELOEIL_REQUIRE_CALL_T(obj, \
  3760. func, \
  3761. .TROMPELOEIL_TIMES(0, ~0ULL) __VA_ARGS__)
  3762. #define TROMPELOEIL_NAMED_ALLOW_CALL_V(...) \
  3763. TROMPELOEIL_IDENTITY(TROMPELOEIL_NAMED_ALLOW_CALL_IMPL TROMPELOEIL_LPAREN \
  3764. TROMPELOEIL_MORE_THAN_TWO_ARGS(__VA_ARGS__), __VA_ARGS__))
  3765. // Dispatch to _F (0, 1, or 2 arguments) or _T (> 2 arguments) macro
  3766. #define TROMPELOEIL_NAMED_ALLOW_CALL_IMPL(N, ...) \
  3767. TROMPELOEIL_IDENTITY( \
  3768. TROMPELOEIL_NAMED_ALLOW_CALL_ ## N TROMPELOEIL_LPAREN __VA_ARGS__))
  3769. // Accept only two arguments
  3770. #define TROMPELOEIL_NAMED_ALLOW_CALL_F(obj, func) \
  3771. TROMPELOEIL_NAMED_REQUIRE_CALL_T(obj, func, .TROMPELOEIL_TIMES(0, ~0ULL))
  3772. // Accept three or more arguments.
  3773. #define TROMPELOEIL_NAMED_ALLOW_CALL_T(obj, func, ...) \
  3774. TROMPELOEIL_NAMED_REQUIRE_CALL_T(obj, \
  3775. func, \
  3776. .TROMPELOEIL_TIMES(0, ~0ULL) __VA_ARGS__)
  3777. #define TROMPELOEIL_FORBID_CALL_V(...) \
  3778. TROMPELOEIL_IDENTITY(TROMPELOEIL_FORBID_CALL_IMPL TROMPELOEIL_LPAREN \
  3779. TROMPELOEIL_MORE_THAN_TWO_ARGS(__VA_ARGS__), __VA_ARGS__))
  3780. // Dispatch to _F (0, 1, or 2 arguments) or _T (> 2 arguments) macro
  3781. #define TROMPELOEIL_FORBID_CALL_IMPL(N, ...) \
  3782. TROMPELOEIL_IDENTITY( \
  3783. TROMPELOEIL_FORBID_CALL_ ## N TROMPELOEIL_LPAREN __VA_ARGS__))
  3784. // Accept only two arguments
  3785. #define TROMPELOEIL_FORBID_CALL_F(obj, func) \
  3786. TROMPELOEIL_REQUIRE_CALL_T(obj, func, .TROMPELOEIL_TIMES(0))
  3787. // Accept three or more arguments.
  3788. #define TROMPELOEIL_FORBID_CALL_T(obj, func, ...) \
  3789. TROMPELOEIL_REQUIRE_CALL_T(obj, \
  3790. func, \
  3791. .TROMPELOEIL_TIMES(0) __VA_ARGS__)
  3792. #define TROMPELOEIL_NAMED_FORBID_CALL_V(...) \
  3793. TROMPELOEIL_IDENTITY(TROMPELOEIL_NAMED_FORBID_CALL_IMPL TROMPELOEIL_LPAREN \
  3794. TROMPELOEIL_MORE_THAN_TWO_ARGS(__VA_ARGS__), __VA_ARGS__))
  3795. // Dispatch to _F (0, 1, or 2 arguments) or _T (> 2 arguments) macro
  3796. #define TROMPELOEIL_NAMED_FORBID_CALL_IMPL(N, ...) \
  3797. TROMPELOEIL_IDENTITY( \
  3798. TROMPELOEIL_NAMED_FORBID_CALL_ ## N TROMPELOEIL_LPAREN __VA_ARGS__))
  3799. // Accept only two arguments
  3800. #define TROMPELOEIL_NAMED_FORBID_CALL_F(obj, func) \
  3801. TROMPELOEIL_NAMED_REQUIRE_CALL_T(obj, func, .TROMPELOEIL_TIMES(0))
  3802. // Accept three or more arguments.
  3803. #define TROMPELOEIL_NAMED_FORBID_CALL_T(obj, func, ...) \
  3804. TROMPELOEIL_NAMED_REQUIRE_CALL_T(obj, \
  3805. func, \
  3806. .TROMPELOEIL_TIMES(0) __VA_ARGS__)
  3807. #if (TROMPELOEIL_CPLUSPLUS > 201103L)
  3808. #define TROMPELOEIL_REQUIRE_CALL(obj, func) \
  3809. TROMPELOEIL_REQUIRE_CALL_(obj, func, #obj, #func)
  3810. #define TROMPELOEIL_REQUIRE_CALL_(obj, func, obj_s, func_s) \
  3811. auto TROMPELOEIL_COUNT_ID(call_obj) = TROMPELOEIL_REQUIRE_CALL_OBJ(obj, func,\
  3812. obj_s, func_s)
  3813. #define TROMPELOEIL_NAMED_REQUIRE_CALL(obj, func) \
  3814. TROMPELOEIL_NAMED_REQUIRE_CALL_(obj, func, #obj, #func)
  3815. #define TROMPELOEIL_NAMED_REQUIRE_CALL_(obj, func, obj_s, func_s) \
  3816. TROMPELOEIL_REQUIRE_CALL_OBJ(obj, func, obj_s, func_s)
  3817. #define TROMPELOEIL_REQUIRE_CALL_OBJ(obj, func, obj_s, func_s) \
  3818. ::trompeloeil::call_validator_t<decltype((obj).TROMPELOEIL_CONCAT(trompeloeil_self_, func))>{(obj)} + \
  3819. ::trompeloeil::detail::conditional_t<false, \
  3820. decltype((obj).func), \
  3821. decltype((obj).TROMPELOEIL_CONCAT(trompeloeil_tag_,func))>\
  3822. {__FILE__, static_cast<unsigned long>(__LINE__), obj_s "." func_s}.func
  3823. #define TROMPELOEIL_ALLOW_CALL(obj, func) \
  3824. TROMPELOEIL_ALLOW_CALL_(obj, func, #obj, #func)
  3825. #define TROMPELOEIL_ALLOW_CALL_(obj, func, obj_s, func_s) \
  3826. TROMPELOEIL_REQUIRE_CALL_(obj, func, obj_s, func_s) \
  3827. .TROMPELOEIL_TIMES(0, ~0ULL)
  3828. #define TROMPELOEIL_NAMED_ALLOW_CALL(obj, func) \
  3829. TROMPELOEIL_NAMED_ALLOW_CALL_(obj, func, #obj, #func)
  3830. #define TROMPELOEIL_NAMED_ALLOW_CALL_(obj, func, obj_s, func_s) \
  3831. TROMPELOEIL_NAMED_REQUIRE_CALL_(obj, func, obj_s, func_s) \
  3832. .TROMPELOEIL_TIMES(0, ~0ULL)
  3833. #define TROMPELOEIL_FORBID_CALL(obj, func) \
  3834. TROMPELOEIL_FORBID_CALL_(obj, func, #obj, #func)
  3835. #define TROMPELOEIL_FORBID_CALL_(obj, func, obj_s, func_s) \
  3836. TROMPELOEIL_REQUIRE_CALL_(obj, func, obj_s, func_s) \
  3837. .TROMPELOEIL_TIMES(0)
  3838. #define TROMPELOEIL_NAMED_FORBID_CALL(obj, func) \
  3839. TROMPELOEIL_NAMED_FORBID_CALL_(obj, func, #obj, #func)
  3840. #define TROMPELOEIL_NAMED_FORBID_CALL_(obj, func, obj_s, func_s) \
  3841. TROMPELOEIL_NAMED_REQUIRE_CALL_(obj, func, obj_s, func_s) \
  3842. .TROMPELOEIL_TIMES(0)
  3843. #endif /* (TROMPELOEIL_CPLUSPLUS > 201103L) */
  3844. #define TROMPELOEIL_WITH(...) TROMPELOEIL_WITH_(=,#__VA_ARGS__, __VA_ARGS__)
  3845. #define TROMPELOEIL_LR_WITH(...) TROMPELOEIL_WITH_(&,#__VA_ARGS__, __VA_ARGS__)
  3846. #if (TROMPELOEIL_CPLUSPLUS == 201103L)
  3847. #define TROMPELOEIL_WITH_(capture, arg_s, ...) \
  3848. with( \
  3849. arg_s, \
  3850. [capture](e_t::trompeloeil_call_params_type_t const& trompeloeil_x) \
  3851. { \
  3852. auto& _1 = ::trompeloeil::mkarg<1>(trompeloeil_x); \
  3853. auto& _2 = ::trompeloeil::mkarg<2>(trompeloeil_x); \
  3854. auto& _3 = ::trompeloeil::mkarg<3>(trompeloeil_x); \
  3855. auto& _4 = ::trompeloeil::mkarg<4>(trompeloeil_x); \
  3856. auto& _5 = ::trompeloeil::mkarg<5>(trompeloeil_x); \
  3857. auto& _6 = ::trompeloeil::mkarg<6>(trompeloeil_x); \
  3858. auto& _7 = ::trompeloeil::mkarg<7>(trompeloeil_x); \
  3859. auto& _8 = ::trompeloeil::mkarg<8>(trompeloeil_x); \
  3860. auto& _9 = ::trompeloeil::mkarg<9>(trompeloeil_x); \
  3861. auto&_10 = ::trompeloeil::mkarg<10>(trompeloeil_x); \
  3862. auto&_11 = ::trompeloeil::mkarg<11>(trompeloeil_x); \
  3863. auto&_12 = ::trompeloeil::mkarg<12>(trompeloeil_x); \
  3864. auto&_13 = ::trompeloeil::mkarg<13>(trompeloeil_x); \
  3865. auto&_14 = ::trompeloeil::mkarg<14>(trompeloeil_x); \
  3866. auto&_15 = ::trompeloeil::mkarg<15>(trompeloeil_x); \
  3867. ::trompeloeil::ignore( \
  3868. _1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15); \
  3869. return __VA_ARGS__; \
  3870. })
  3871. #else /* (TROMPELOEIL_CPLUSPLUS == 201103L) */
  3872. #define TROMPELOEIL_WITH_(capture, arg_s, ...) \
  3873. with(arg_s, [capture](auto const& trompeloeil_x) { \
  3874. auto& _1 = ::trompeloeil::mkarg<1>(trompeloeil_x); \
  3875. auto& _2 = ::trompeloeil::mkarg<2>(trompeloeil_x); \
  3876. auto& _3 = ::trompeloeil::mkarg<3>(trompeloeil_x); \
  3877. auto& _4 = ::trompeloeil::mkarg<4>(trompeloeil_x); \
  3878. auto& _5 = ::trompeloeil::mkarg<5>(trompeloeil_x); \
  3879. auto& _6 = ::trompeloeil::mkarg<6>(trompeloeil_x); \
  3880. auto& _7 = ::trompeloeil::mkarg<7>(trompeloeil_x); \
  3881. auto& _8 = ::trompeloeil::mkarg<8>(trompeloeil_x); \
  3882. auto& _9 = ::trompeloeil::mkarg<9>(trompeloeil_x); \
  3883. auto&_10 = ::trompeloeil::mkarg<10>(trompeloeil_x); \
  3884. auto&_11 = ::trompeloeil::mkarg<11>(trompeloeil_x); \
  3885. auto&_12 = ::trompeloeil::mkarg<12>(trompeloeil_x); \
  3886. auto&_13 = ::trompeloeil::mkarg<13>(trompeloeil_x); \
  3887. auto&_14 = ::trompeloeil::mkarg<14>(trompeloeil_x); \
  3888. auto&_15 = ::trompeloeil::mkarg<15>(trompeloeil_x); \
  3889. ::trompeloeil::ignore(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15); \
  3890. return __VA_ARGS__; \
  3891. })
  3892. #endif /* !(TROMPELOEIL_CPLUSPLUS == 201103L) */
  3893. #define TROMPELOEIL_SIDE_EFFECT(...) TROMPELOEIL_SIDE_EFFECT_(=, __VA_ARGS__)
  3894. #define TROMPELOEIL_LR_SIDE_EFFECT(...) TROMPELOEIL_SIDE_EFFECT_(&, __VA_ARGS__)
  3895. #if (TROMPELOEIL_CPLUSPLUS == 201103L)
  3896. #define TROMPELOEIL_SIDE_EFFECT_(capture, ...) \
  3897. sideeffect( \
  3898. [capture](e_t::trompeloeil_call_params_type_t& trompeloeil_x) { \
  3899. auto& _1 = ::trompeloeil::mkarg<1>(trompeloeil_x); \
  3900. auto& _2 = ::trompeloeil::mkarg<2>(trompeloeil_x); \
  3901. auto& _3 = ::trompeloeil::mkarg<3>(trompeloeil_x); \
  3902. auto& _4 = ::trompeloeil::mkarg<4>(trompeloeil_x); \
  3903. auto& _5 = ::trompeloeil::mkarg<5>(trompeloeil_x); \
  3904. auto& _6 = ::trompeloeil::mkarg<6>(trompeloeil_x); \
  3905. auto& _7 = ::trompeloeil::mkarg<7>(trompeloeil_x); \
  3906. auto& _8 = ::trompeloeil::mkarg<8>(trompeloeil_x); \
  3907. auto& _9 = ::trompeloeil::mkarg<9>(trompeloeil_x); \
  3908. auto&_10 = ::trompeloeil::mkarg<10>(trompeloeil_x); \
  3909. auto&_11 = ::trompeloeil::mkarg<11>(trompeloeil_x); \
  3910. auto&_12 = ::trompeloeil::mkarg<12>(trompeloeil_x); \
  3911. auto&_13 = ::trompeloeil::mkarg<13>(trompeloeil_x); \
  3912. auto&_14 = ::trompeloeil::mkarg<14>(trompeloeil_x); \
  3913. auto&_15 = ::trompeloeil::mkarg<15>(trompeloeil_x); \
  3914. ::trompeloeil::ignore( \
  3915. _1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15); \
  3916. __VA_ARGS__; \
  3917. })
  3918. #else /* (TROMPELOEIL_CPLUSPLUS == 201103L) */
  3919. #define TROMPELOEIL_SIDE_EFFECT_(capture, ...) \
  3920. sideeffect([capture](auto& trompeloeil_x) { \
  3921. auto& _1 = ::trompeloeil::mkarg<1>(trompeloeil_x); \
  3922. auto& _2 = ::trompeloeil::mkarg<2>(trompeloeil_x); \
  3923. auto& _3 = ::trompeloeil::mkarg<3>(trompeloeil_x); \
  3924. auto& _4 = ::trompeloeil::mkarg<4>(trompeloeil_x); \
  3925. auto& _5 = ::trompeloeil::mkarg<5>(trompeloeil_x); \
  3926. auto& _6 = ::trompeloeil::mkarg<6>(trompeloeil_x); \
  3927. auto& _7 = ::trompeloeil::mkarg<7>(trompeloeil_x); \
  3928. auto& _8 = ::trompeloeil::mkarg<8>(trompeloeil_x); \
  3929. auto& _9 = ::trompeloeil::mkarg<9>(trompeloeil_x); \
  3930. auto&_10 = ::trompeloeil::mkarg<10>(trompeloeil_x); \
  3931. auto&_11 = ::trompeloeil::mkarg<11>(trompeloeil_x); \
  3932. auto&_12 = ::trompeloeil::mkarg<12>(trompeloeil_x); \
  3933. auto&_13 = ::trompeloeil::mkarg<13>(trompeloeil_x); \
  3934. auto&_14 = ::trompeloeil::mkarg<14>(trompeloeil_x); \
  3935. auto&_15 = ::trompeloeil::mkarg<15>(trompeloeil_x); \
  3936. ::trompeloeil::ignore(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15); \
  3937. __VA_ARGS__; \
  3938. })
  3939. #endif /* !(TROMPELOEIL_CPLUSPLUS == 201103L) */
  3940. #define TROMPELOEIL_RETURN(...) TROMPELOEIL_RETURN_(=, __VA_ARGS__)
  3941. #define TROMPELOEIL_LR_RETURN(...) TROMPELOEIL_RETURN_(&, __VA_ARGS__)
  3942. #if (TROMPELOEIL_CPLUSPLUS == 201103L)
  3943. #define TROMPELOEIL_RETURN_(capture, ...) \
  3944. handle_return( \
  3945. [capture](e_t::trompeloeil_call_params_type_t& trompeloeil_x) \
  3946. -> e_t::trompeloeil_return_of_t \
  3947. { \
  3948. auto& _1 = ::trompeloeil::mkarg<1>(trompeloeil_x); \
  3949. auto& _2 = ::trompeloeil::mkarg<2>(trompeloeil_x); \
  3950. auto& _3 = ::trompeloeil::mkarg<3>(trompeloeil_x); \
  3951. auto& _4 = ::trompeloeil::mkarg<4>(trompeloeil_x); \
  3952. auto& _5 = ::trompeloeil::mkarg<5>(trompeloeil_x); \
  3953. auto& _6 = ::trompeloeil::mkarg<6>(trompeloeil_x); \
  3954. auto& _7 = ::trompeloeil::mkarg<7>(trompeloeil_x); \
  3955. auto& _8 = ::trompeloeil::mkarg<8>(trompeloeil_x); \
  3956. auto& _9 = ::trompeloeil::mkarg<9>(trompeloeil_x); \
  3957. auto&_10 = ::trompeloeil::mkarg<10>(trompeloeil_x); \
  3958. auto&_11 = ::trompeloeil::mkarg<11>(trompeloeil_x); \
  3959. auto&_12 = ::trompeloeil::mkarg<12>(trompeloeil_x); \
  3960. auto&_13 = ::trompeloeil::mkarg<13>(trompeloeil_x); \
  3961. auto&_14 = ::trompeloeil::mkarg<14>(trompeloeil_x); \
  3962. auto&_15 = ::trompeloeil::mkarg<15>(trompeloeil_x); \
  3963. ::trompeloeil::ignore( \
  3964. _1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15); \
  3965. return ::trompeloeil::decay_return_type(__VA_ARGS__); \
  3966. })
  3967. #else /* (TROMPELOEIL_CPLUSPLUS == 201103L) */
  3968. #define TROMPELOEIL_RETURN_(capture, ...) \
  3969. handle_return([capture](auto& trompeloeil_x) -> decltype(auto) { \
  3970. auto& _1 = ::trompeloeil::mkarg<1>(trompeloeil_x); \
  3971. auto& _2 = ::trompeloeil::mkarg<2>(trompeloeil_x); \
  3972. auto& _3 = ::trompeloeil::mkarg<3>(trompeloeil_x); \
  3973. auto& _4 = ::trompeloeil::mkarg<4>(trompeloeil_x); \
  3974. auto& _5 = ::trompeloeil::mkarg<5>(trompeloeil_x); \
  3975. auto& _6 = ::trompeloeil::mkarg<6>(trompeloeil_x); \
  3976. auto& _7 = ::trompeloeil::mkarg<7>(trompeloeil_x); \
  3977. auto& _8 = ::trompeloeil::mkarg<8>(trompeloeil_x); \
  3978. auto& _9 = ::trompeloeil::mkarg<9>(trompeloeil_x); \
  3979. auto&_10 = ::trompeloeil::mkarg<10>(trompeloeil_x); \
  3980. auto&_11 = ::trompeloeil::mkarg<11>(trompeloeil_x); \
  3981. auto&_12 = ::trompeloeil::mkarg<12>(trompeloeil_x); \
  3982. auto&_13 = ::trompeloeil::mkarg<13>(trompeloeil_x); \
  3983. auto&_14 = ::trompeloeil::mkarg<14>(trompeloeil_x); \
  3984. auto&_15 = ::trompeloeil::mkarg<15>(trompeloeil_x); \
  3985. ::trompeloeil::ignore(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15); \
  3986. return ::trompeloeil::decay_return_type(__VA_ARGS__); \
  3987. })
  3988. #endif /* !(TROMPELOEIL_CPLUSPLUS == 201103L) */
  3989. #define TROMPELOEIL_THROW(...) TROMPELOEIL_THROW_(=, __VA_ARGS__)
  3990. #define TROMPELOEIL_LR_THROW(...) TROMPELOEIL_THROW_(&, __VA_ARGS__)
  3991. #if (TROMPELOEIL_CPLUSPLUS == 201103L)
  3992. #define TROMPELOEIL_THROW_(capture, ...) \
  3993. handle_throw( \
  3994. [capture](e_t::trompeloeil_call_params_type_t& trompeloeil_x) { \
  3995. auto& _1 = ::trompeloeil::mkarg<1>(trompeloeil_x); \
  3996. auto& _2 = ::trompeloeil::mkarg<2>(trompeloeil_x); \
  3997. auto& _3 = ::trompeloeil::mkarg<3>(trompeloeil_x); \
  3998. auto& _4 = ::trompeloeil::mkarg<4>(trompeloeil_x); \
  3999. auto& _5 = ::trompeloeil::mkarg<5>(trompeloeil_x); \
  4000. auto& _6 = ::trompeloeil::mkarg<6>(trompeloeil_x); \
  4001. auto& _7 = ::trompeloeil::mkarg<7>(trompeloeil_x); \
  4002. auto& _8 = ::trompeloeil::mkarg<8>(trompeloeil_x); \
  4003. auto& _9 = ::trompeloeil::mkarg<9>(trompeloeil_x); \
  4004. auto&_10 = ::trompeloeil::mkarg<10>(trompeloeil_x); \
  4005. auto&_11 = ::trompeloeil::mkarg<11>(trompeloeil_x); \
  4006. auto&_12 = ::trompeloeil::mkarg<12>(trompeloeil_x); \
  4007. auto&_13 = ::trompeloeil::mkarg<13>(trompeloeil_x); \
  4008. auto&_14 = ::trompeloeil::mkarg<14>(trompeloeil_x); \
  4009. auto&_15 = ::trompeloeil::mkarg<15>(trompeloeil_x); \
  4010. ::trompeloeil::ignore( \
  4011. _1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15); \
  4012. throw __VA_ARGS__; \
  4013. })
  4014. #else /* (TROMPELOEIL_CPLUSPLUS == 201103L) */
  4015. #define TROMPELOEIL_THROW_(capture, ...) \
  4016. handle_throw([capture](auto& trompeloeil_x) { \
  4017. auto& _1 = ::trompeloeil::mkarg<1>(trompeloeil_x); \
  4018. auto& _2 = ::trompeloeil::mkarg<2>(trompeloeil_x); \
  4019. auto& _3 = ::trompeloeil::mkarg<3>(trompeloeil_x); \
  4020. auto& _4 = ::trompeloeil::mkarg<4>(trompeloeil_x); \
  4021. auto& _5 = ::trompeloeil::mkarg<5>(trompeloeil_x); \
  4022. auto& _6 = ::trompeloeil::mkarg<6>(trompeloeil_x); \
  4023. auto& _7 = ::trompeloeil::mkarg<7>(trompeloeil_x); \
  4024. auto& _8 = ::trompeloeil::mkarg<8>(trompeloeil_x); \
  4025. auto& _9 = ::trompeloeil::mkarg<9>(trompeloeil_x); \
  4026. auto&_10 = ::trompeloeil::mkarg<10>(trompeloeil_x); \
  4027. auto&_11 = ::trompeloeil::mkarg<11>(trompeloeil_x); \
  4028. auto&_12 = ::trompeloeil::mkarg<12>(trompeloeil_x); \
  4029. auto&_13 = ::trompeloeil::mkarg<13>(trompeloeil_x); \
  4030. auto&_14 = ::trompeloeil::mkarg<14>(trompeloeil_x); \
  4031. auto&_15 = ::trompeloeil::mkarg<15>(trompeloeil_x); \
  4032. ::trompeloeil::ignore(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15); \
  4033. throw __VA_ARGS__; \
  4034. })
  4035. #endif /* !(TROMPELOEIL_CPLUSPLUS == 201103L) */
  4036. #define TROMPELOEIL_TIMES(...) times(::trompeloeil::multiplicity<__VA_ARGS__>{})
  4037. #define TROMPELOEIL_IN_SEQUENCE(...) \
  4038. in_sequence(TROMPELOEIL_INIT_WITH_STR(::trompeloeil::sequence_matcher::init_type, __VA_ARGS__))
  4039. #define TROMPELOEIL_ANY(type) ::trompeloeil::any_matcher<type>(#type)
  4040. #define TROMPELOEIL_AT_LEAST(num) num, ~0ULL
  4041. #define TROMPELOEIL_AT_MOST(num) 0, num
  4042. #define TROMPELOEIL_REQUIRE_DESTRUCTION(obj) \
  4043. TROMPELOEIL_REQUIRE_DESTRUCTION_(obj, #obj)
  4044. #define TROMPELOEIL_REQUIRE_DESTRUCTION_(obj, obj_s) \
  4045. std::unique_ptr<trompeloeil::expectation> \
  4046. TROMPELOEIL_CONCAT(trompeloeil_death_monitor_, __LINE__) \
  4047. = TROMPELOEIL_NAMED_REQUIRE_DESTRUCTION_(,obj, obj_s)
  4048. #define TROMPELOEIL_NAMED_REQUIRE_DESTRUCTION(obj) \
  4049. TROMPELOEIL_NAMED_REQUIRE_DESTRUCTION_("NAMED_", obj, #obj)
  4050. #define TROMPELOEIL_NAMED_REQUIRE_DESTRUCTION_(prefix, obj, obj_s) \
  4051. trompeloeil::lifetime_monitor_releaser{} + \
  4052. trompeloeil::lifetime_monitor_modifier<false>{ \
  4053. ::trompeloeil::detail::make_unique<trompeloeil::lifetime_monitor>( \
  4054. obj, \
  4055. obj_s, \
  4056. prefix "REQUIRE_DESTRUCTION(" obj_s ")", \
  4057. "destructor for " obj_s, \
  4058. ::trompeloeil::location{__FILE__, \
  4059. static_cast<unsigned long>(__LINE__)}) \
  4060. }
  4061. #ifndef TROMPELOEIL_LONG_MACROS
  4062. #define MAKE_MOCK0 TROMPELOEIL_MAKE_MOCK0
  4063. #define MAKE_MOCK1 TROMPELOEIL_MAKE_MOCK1
  4064. #define MAKE_MOCK2 TROMPELOEIL_MAKE_MOCK2
  4065. #define MAKE_MOCK3 TROMPELOEIL_MAKE_MOCK3
  4066. #define MAKE_MOCK4 TROMPELOEIL_MAKE_MOCK4
  4067. #define MAKE_MOCK5 TROMPELOEIL_MAKE_MOCK5
  4068. #define MAKE_MOCK6 TROMPELOEIL_MAKE_MOCK6
  4069. #define MAKE_MOCK7 TROMPELOEIL_MAKE_MOCK7
  4070. #define MAKE_MOCK8 TROMPELOEIL_MAKE_MOCK8
  4071. #define MAKE_MOCK9 TROMPELOEIL_MAKE_MOCK9
  4072. #define MAKE_MOCK10 TROMPELOEIL_MAKE_MOCK10
  4073. #define MAKE_MOCK11 TROMPELOEIL_MAKE_MOCK11
  4074. #define MAKE_MOCK12 TROMPELOEIL_MAKE_MOCK12
  4075. #define MAKE_MOCK13 TROMPELOEIL_MAKE_MOCK13
  4076. #define MAKE_MOCK14 TROMPELOEIL_MAKE_MOCK14
  4077. #define MAKE_MOCK15 TROMPELOEIL_MAKE_MOCK15
  4078. #define MAKE_CONST_MOCK0 TROMPELOEIL_MAKE_CONST_MOCK0
  4079. #define MAKE_CONST_MOCK1 TROMPELOEIL_MAKE_CONST_MOCK1
  4080. #define MAKE_CONST_MOCK2 TROMPELOEIL_MAKE_CONST_MOCK2
  4081. #define MAKE_CONST_MOCK3 TROMPELOEIL_MAKE_CONST_MOCK3
  4082. #define MAKE_CONST_MOCK4 TROMPELOEIL_MAKE_CONST_MOCK4
  4083. #define MAKE_CONST_MOCK5 TROMPELOEIL_MAKE_CONST_MOCK5
  4084. #define MAKE_CONST_MOCK6 TROMPELOEIL_MAKE_CONST_MOCK6
  4085. #define MAKE_CONST_MOCK7 TROMPELOEIL_MAKE_CONST_MOCK7
  4086. #define MAKE_CONST_MOCK8 TROMPELOEIL_MAKE_CONST_MOCK8
  4087. #define MAKE_CONST_MOCK9 TROMPELOEIL_MAKE_CONST_MOCK9
  4088. #define MAKE_CONST_MOCK10 TROMPELOEIL_MAKE_CONST_MOCK10
  4089. #define MAKE_CONST_MOCK11 TROMPELOEIL_MAKE_CONST_MOCK11
  4090. #define MAKE_CONST_MOCK12 TROMPELOEIL_MAKE_CONST_MOCK12
  4091. #define MAKE_CONST_MOCK13 TROMPELOEIL_MAKE_CONST_MOCK13
  4092. #define MAKE_CONST_MOCK14 TROMPELOEIL_MAKE_CONST_MOCK14
  4093. #define MAKE_CONST_MOCK15 TROMPELOEIL_MAKE_CONST_MOCK15
  4094. #define IMPLEMENT_MOCK0 TROMPELOEIL_IMPLEMENT_MOCK0
  4095. #define IMPLEMENT_MOCK1 TROMPELOEIL_IMPLEMENT_MOCK1
  4096. #define IMPLEMENT_MOCK2 TROMPELOEIL_IMPLEMENT_MOCK2
  4097. #define IMPLEMENT_MOCK3 TROMPELOEIL_IMPLEMENT_MOCK3
  4098. #define IMPLEMENT_MOCK4 TROMPELOEIL_IMPLEMENT_MOCK4
  4099. #define IMPLEMENT_MOCK5 TROMPELOEIL_IMPLEMENT_MOCK5
  4100. #define IMPLEMENT_MOCK6 TROMPELOEIL_IMPLEMENT_MOCK6
  4101. #define IMPLEMENT_MOCK7 TROMPELOEIL_IMPLEMENT_MOCK7
  4102. #define IMPLEMENT_MOCK8 TROMPELOEIL_IMPLEMENT_MOCK8
  4103. #define IMPLEMENT_MOCK9 TROMPELOEIL_IMPLEMENT_MOCK9
  4104. #define IMPLEMENT_MOCK10 TROMPELOEIL_IMPLEMENT_MOCK10
  4105. #define IMPLEMENT_MOCK11 TROMPELOEIL_IMPLEMENT_MOCK11
  4106. #define IMPLEMENT_MOCK12 TROMPELOEIL_IMPLEMENT_MOCK12
  4107. #define IMPLEMENT_MOCK13 TROMPELOEIL_IMPLEMENT_MOCK13
  4108. #define IMPLEMENT_MOCK14 TROMPELOEIL_IMPLEMENT_MOCK14
  4109. #define IMPLEMENT_MOCK15 TROMPELOEIL_IMPLEMENT_MOCK15
  4110. #define IMPLEMENT_CONST_MOCK0 TROMPELOEIL_IMPLEMENT_CONST_MOCK0
  4111. #define IMPLEMENT_CONST_MOCK1 TROMPELOEIL_IMPLEMENT_CONST_MOCK1
  4112. #define IMPLEMENT_CONST_MOCK2 TROMPELOEIL_IMPLEMENT_CONST_MOCK2
  4113. #define IMPLEMENT_CONST_MOCK3 TROMPELOEIL_IMPLEMENT_CONST_MOCK3
  4114. #define IMPLEMENT_CONST_MOCK4 TROMPELOEIL_IMPLEMENT_CONST_MOCK4
  4115. #define IMPLEMENT_CONST_MOCK5 TROMPELOEIL_IMPLEMENT_CONST_MOCK5
  4116. #define IMPLEMENT_CONST_MOCK6 TROMPELOEIL_IMPLEMENT_CONST_MOCK6
  4117. #define IMPLEMENT_CONST_MOCK7 TROMPELOEIL_IMPLEMENT_CONST_MOCK7
  4118. #define IMPLEMENT_CONST_MOCK8 TROMPELOEIL_IMPLEMENT_CONST_MOCK8
  4119. #define IMPLEMENT_CONST_MOCK9 TROMPELOEIL_IMPLEMENT_CONST_MOCK9
  4120. #define IMPLEMENT_CONST_MOCK10 TROMPELOEIL_IMPLEMENT_CONST_MOCK10
  4121. #define IMPLEMENT_CONST_MOCK11 TROMPELOEIL_IMPLEMENT_CONST_MOCK11
  4122. #define IMPLEMENT_CONST_MOCK12 TROMPELOEIL_IMPLEMENT_CONST_MOCK12
  4123. #define IMPLEMENT_CONST_MOCK13 TROMPELOEIL_IMPLEMENT_CONST_MOCK13
  4124. #define IMPLEMENT_CONST_MOCK14 TROMPELOEIL_IMPLEMENT_CONST_MOCK14
  4125. #define IMPLEMENT_CONST_MOCK15 TROMPELOEIL_IMPLEMENT_CONST_MOCK15
  4126. #define REQUIRE_CALL_V TROMPELOEIL_REQUIRE_CALL_V
  4127. #define NAMED_REQUIRE_CALL_V TROMPELOEIL_NAMED_REQUIRE_CALL_V
  4128. #define ALLOW_CALL_V TROMPELOEIL_ALLOW_CALL_V
  4129. #define NAMED_ALLOW_CALL_V TROMPELOEIL_NAMED_ALLOW_CALL_V
  4130. #define FORBID_CALL_V TROMPELOEIL_FORBID_CALL_V
  4131. #define NAMED_FORBID_CALL_V TROMPELOEIL_NAMED_FORBID_CALL_V
  4132. #if (TROMPELOEIL_CPLUSPLUS > 201103L)
  4133. #define REQUIRE_CALL TROMPELOEIL_REQUIRE_CALL
  4134. #define NAMED_REQUIRE_CALL TROMPELOEIL_NAMED_REQUIRE_CALL
  4135. #define ALLOW_CALL TROMPELOEIL_ALLOW_CALL
  4136. #define NAMED_ALLOW_CALL TROMPELOEIL_NAMED_ALLOW_CALL
  4137. #define FORBID_CALL TROMPELOEIL_FORBID_CALL
  4138. #define NAMED_FORBID_CALL TROMPELOEIL_NAMED_FORBID_CALL
  4139. #endif /* (TROMPELOEIL_CPLUSPLUS > 201103L) */
  4140. #define WITH TROMPELOEIL_WITH
  4141. #define LR_WITH TROMPELOEIL_LR_WITH
  4142. #define SIDE_EFFECT TROMPELOEIL_SIDE_EFFECT
  4143. #define LR_SIDE_EFFECT TROMPELOEIL_LR_SIDE_EFFECT
  4144. #define RETURN TROMPELOEIL_RETURN
  4145. #define LR_RETURN TROMPELOEIL_LR_RETURN
  4146. #define THROW TROMPELOEIL_THROW
  4147. #define LR_THROW TROMPELOEIL_LR_THROW
  4148. #define TIMES TROMPELOEIL_TIMES
  4149. #define IN_SEQUENCE TROMPELOEIL_IN_SEQUENCE
  4150. #define ANY TROMPELOEIL_ANY
  4151. #define AT_LEAST TROMPELOEIL_AT_LEAST
  4152. #define AT_MOST TROMPELOEIL_AT_MOST
  4153. #define REQUIRE_DESTRUCTION TROMPELOEIL_REQUIRE_DESTRUCTION
  4154. #define NAMED_REQUIRE_DESTRUCTION TROMPELOEIL_NAMED_REQUIRE_DESTRUCTION
  4155. #endif // TROMPELOEIL_LONG_MACROS
  4156. #endif // include guard