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.

4852 lines
143KB

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