You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

4903 satır
145KB

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