選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

3759 行
103KB

  1. /*
  2. * Trompeloeil C++ mocking framework
  3. *
  4. * Copyright Björn Fahller 2014-2017
  5. *
  6. * Use, modification and distribution is subject to the
  7. * Boost Software License, Version 1.0. (See accompanying
  8. * file LICENSE_1_0.txt or copy at
  9. * http://www.boost.org/LICENSE_1_0.txt)
  10. *
  11. * Project home: https://github.com/rollbear/trompeloeil
  12. */
  13. #ifndef TROMPELOEIL_HPP_
  14. #define TROMPELOEIL_HPP_
  15. // trompe l'oeil noun (Concise Encyclopedia)
  16. // Style of representation in which a painted object is intended
  17. // to deceive the viewer into believing it is the object itself...
  18. // project home: https://github.com/rollbear/trompeloeil
  19. // Deficiencies and missing features
  20. // * Mocking function templates is not supported
  21. // * If a macro kills a kitten, this threatens extinction of all felines!
  22. #if defined(_MSC_VER)
  23. # define TROMPELOEIL_NORETURN
  24. # if (!defined(__cplusplus) || _MSC_VER < 1900)
  25. # error requires C++ in Visual Studio 2015 RC or later
  26. # endif
  27. #else
  28. # define TROMPELOEIL_NORETURN [[noreturn]]
  29. # if (!defined(__cplusplus) || __cplusplus <= 201103)
  30. # error requires C++14 or higher
  31. # endif
  32. #endif
  33. #include <tuple>
  34. #include <iomanip>
  35. #include <sstream>
  36. #include <exception>
  37. #include <functional>
  38. #include <memory>
  39. #include <cstring>
  40. #include <regex>
  41. #include <mutex>
  42. #include <atomic>
  43. #include <type_traits>
  44. #ifdef TROMPELOEIL_SANITY_CHECKS
  45. #include <cassert>
  46. #define TROMPELOEIL_ASSERT(x) assert(x)
  47. #else
  48. #define TROMPELOEIL_ASSERT(x) do {} while (false)
  49. #endif
  50. #define TROMPELOEIL_IDENTITY(...) __VA_ARGS__ // work around stupid MS VS2015 RC bug
  51. #define TROMPELOEIL_ARG16(_0,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15, ...) _15
  52. #define TROMPELOEIL_COUNT(...) \
  53. TROMPELOEIL_IDENTITY(TROMPELOEIL_ARG16(__VA_ARGS__, \
  54. 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0))
  55. #define TROMPELOEIL_CONCAT_(x, y) x ## y
  56. #define TROMPELOEIL_CONCAT(x, y) TROMPELOEIL_CONCAT_(x, y)
  57. #define TROMPELOEIL_INIT_WITH_STR15(base, x, ...) \
  58. base{#x, x}, TROMPELOEIL_INIT_WITH_STR14(base, __VA_ARGS__)
  59. #define TROMPELOEIL_INIT_WITH_STR14(base, x, ...) \
  60. base{#x, x}, TROMPELOEIL_INIT_WITH_STR13(base, __VA_ARGS__)
  61. #define TROMPELOEIL_INIT_WITH_STR13(base, x, ...) \
  62. base{#x, x}, TROMPELOEIL_INIT_WITH_STR12(base, __VA_ARGS__)
  63. #define TROMPELOEIL_INIT_WITH_STR12(base, x, ...) \
  64. base{#x, x}, TROMPELOEIL_INIT_WITH_STR11(base, __VA_ARGS__)
  65. #define TROMPELOEIL_INIT_WITH_STR11(base, x, ...) \
  66. base{#x, x}, TROMPELOEIL_INIT_WITH_STR10(base, __VA_ARGS__)
  67. #define TROMPELOEIL_INIT_WITH_STR10(base, x, ...) \
  68. base{#x, x}, TROMPELOEIL_INIT_WITH_STR9(base, __VA_ARGS__)
  69. #define TROMPELOEIL_INIT_WITH_STR9(base, x, ...) \
  70. base{#x, x}, TROMPELOEIL_INIT_WITH_STR8(base, __VA_ARGS__)
  71. #define TROMPELOEIL_INIT_WITH_STR8(base, x, ...) \
  72. base{#x, x}, TROMPELOEIL_INIT_WITH_STR7(base, __VA_ARGS__)
  73. #define TROMPELOEIL_INIT_WITH_STR7(base, x, ...) \
  74. base{#x, x}, TROMPELOEIL_INIT_WITH_STR6(base, __VA_ARGS__)
  75. #define TROMPELOEIL_INIT_WITH_STR6(base, x, ...) \
  76. base{#x, x}, TROMPELOEIL_INIT_WITH_STR5(base, __VA_ARGS__)
  77. #define TROMPELOEIL_INIT_WITH_STR5(base, x, ...) \
  78. base{#x, x}, TROMPELOEIL_INIT_WITH_STR4(base, __VA_ARGS__)
  79. #define TROMPELOEIL_INIT_WITH_STR4(base, x, ...) \
  80. base{#x, x}, TROMPELOEIL_INIT_WITH_STR3(base, __VA_ARGS__)
  81. #define TROMPELOEIL_INIT_WITH_STR3(base, x, ...) \
  82. base{#x, x}, TROMPELOEIL_INIT_WITH_STR2(base, __VA_ARGS__)
  83. #define TROMPELOEIL_INIT_WITH_STR2(base, x, ...) \
  84. base{#x, x}, TROMPELOEIL_INIT_WITH_STR1(base, __VA_ARGS__)
  85. #define TROMPELOEIL_INIT_WITH_STR1(base, x) \
  86. base{#x, x}
  87. #define TROMPELOEIL_INIT_WITH_STR0(base)
  88. #define TROMPELOEIL_INIT_WITH_STR(base, ...) \
  89. TROMPELOEIL_CONCAT(TROMPELOEIL_INIT_WITH_STR, \
  90. TROMPELOEIL_COUNT(__VA_ARGS__))(base, __VA_ARGS__)
  91. #define TROMPELOEIL_PARAM_LIST15(func_type) \
  92. TROMPELOEIL_PARAM_LIST14(func_type), \
  93. ::trompeloeil::param_list_t<func_type, 14> p15
  94. #define TROMPELOEIL_PARAM_LIST14(func_type) \
  95. TROMPELOEIL_PARAM_LIST13(func_type), \
  96. ::trompeloeil::param_list_t<func_type, 13> p14
  97. #define TROMPELOEIL_PARAM_LIST13(func_type) \
  98. TROMPELOEIL_PARAM_LIST12(func_type), \
  99. ::trompeloeil::param_list_t<func_type, 12> p13
  100. #define TROMPELOEIL_PARAM_LIST12(func_type) \
  101. TROMPELOEIL_PARAM_LIST11(func_type), \
  102. ::trompeloeil::param_list_t<func_type, 11> p12
  103. #define TROMPELOEIL_PARAM_LIST11(func_type) \
  104. TROMPELOEIL_PARAM_LIST10(func_type), \
  105. ::trompeloeil::param_list_t<func_type, 10> p11
  106. #define TROMPELOEIL_PARAM_LIST10(func_type) \
  107. TROMPELOEIL_PARAM_LIST9(func_type), \
  108. ::trompeloeil::param_list_t<func_type, 9> p10
  109. #define TROMPELOEIL_PARAM_LIST9(func_type) \
  110. TROMPELOEIL_PARAM_LIST8(func_type), \
  111. ::trompeloeil::param_list_t<func_type, 8> p9
  112. #define TROMPELOEIL_PARAM_LIST8(func_type) \
  113. TROMPELOEIL_PARAM_LIST7(func_type), \
  114. ::trompeloeil::param_list_t<func_type, 7> p8
  115. #define TROMPELOEIL_PARAM_LIST7(func_type) \
  116. TROMPELOEIL_PARAM_LIST6(func_type), \
  117. ::trompeloeil::param_list_t<func_type, 6> p7
  118. #define TROMPELOEIL_PARAM_LIST6(func_type) \
  119. TROMPELOEIL_PARAM_LIST5(func_type), \
  120. ::trompeloeil::param_list_t<func_type, 5> p6
  121. #define TROMPELOEIL_PARAM_LIST5(func_type) \
  122. TROMPELOEIL_PARAM_LIST4(func_type), \
  123. ::trompeloeil::param_list_t<func_type, 4> p5
  124. #define TROMPELOEIL_PARAM_LIST4(func_type) \
  125. TROMPELOEIL_PARAM_LIST3(func_type), \
  126. ::trompeloeil::param_list_t<func_type, 3> p4
  127. #define TROMPELOEIL_PARAM_LIST3(func_type) \
  128. TROMPELOEIL_PARAM_LIST2(func_type), \
  129. ::trompeloeil::param_list_t<func_type, 2> p3
  130. #define TROMPELOEIL_PARAM_LIST2(func_type) \
  131. TROMPELOEIL_PARAM_LIST1(func_type), \
  132. ::trompeloeil::param_list_t<func_type, 1> p2
  133. #define TROMPELOEIL_PARAM_LIST1(func_type) \
  134. ::trompeloeil::param_list_t<func_type, 0> p1
  135. #define TROMPELOEIL_PARAM_LIST0(func_type)
  136. #define TROMPELOEIL_PARAM_LIST(num, func_type) \
  137. TROMPELOEIL_CONCAT(TROMPELOEIL_PARAM_LIST, num)(func_type)
  138. #define TROMPELOEIL_PARAMS15 TROMPELOEIL_PARAMS14, p15
  139. #define TROMPELOEIL_PARAMS14 TROMPELOEIL_PARAMS13, p14
  140. #define TROMPELOEIL_PARAMS13 TROMPELOEIL_PARAMS12, p13
  141. #define TROMPELOEIL_PARAMS12 TROMPELOEIL_PARAMS11, p12
  142. #define TROMPELOEIL_PARAMS11 TROMPELOEIL_PARAMS10, p11
  143. #define TROMPELOEIL_PARAMS10 TROMPELOEIL_PARAMS9, p10
  144. #define TROMPELOEIL_PARAMS9 TROMPELOEIL_PARAMS8, p9
  145. #define TROMPELOEIL_PARAMS8 TROMPELOEIL_PARAMS7, p8
  146. #define TROMPELOEIL_PARAMS7 TROMPELOEIL_PARAMS6, p7
  147. #define TROMPELOEIL_PARAMS6 TROMPELOEIL_PARAMS5, p6
  148. #define TROMPELOEIL_PARAMS5 TROMPELOEIL_PARAMS4, p5
  149. #define TROMPELOEIL_PARAMS4 TROMPELOEIL_PARAMS3, p4
  150. #define TROMPELOEIL_PARAMS3 TROMPELOEIL_PARAMS2, p3
  151. #define TROMPELOEIL_PARAMS2 TROMPELOEIL_PARAMS1, p2
  152. #define TROMPELOEIL_PARAMS1 , p1
  153. #define TROMPELOEIL_PARAMS0
  154. #define TROMPELOEIL_PARAMS(num) TROMPELOEIL_CONCAT(TROMPELOEIL_PARAMS, num)
  155. namespace trompeloeil
  156. {
  157. class specialized;
  158. template <typename T = void>
  159. std::unique_lock<std::recursive_mutex> get_lock()
  160. {
  161. static std::recursive_mutex lock;
  162. return std::unique_lock<std::recursive_mutex>{ lock };
  163. }
  164. template <size_t N, typename T>
  165. using conditional_tuple_element
  166. = std::conditional_t<(N < std::tuple_size<T>::value),
  167. typename std::tuple_element<N, T>::type,
  168. int>;
  169. template <typename T>
  170. struct param_list;
  171. template <typename R, typename ... P>
  172. struct param_list<R(P...)>
  173. {
  174. static size_t constexpr const size = sizeof...(P);
  175. template <size_t N>
  176. using type = conditional_tuple_element<N, std::tuple<P...>>;
  177. };
  178. template <typename Sig, size_t N>
  179. using param_list_t = typename param_list<Sig>::template type<N>;
  180. class expectation_violation : public std::logic_error
  181. {
  182. public:
  183. using std::logic_error::logic_error;
  184. };
  185. struct location
  186. {
  187. location()
  188. noexcept
  189. : file("")
  190. , line(0U)
  191. {}
  192. location(
  193. char const* file_,
  194. unsigned long line_
  195. )
  196. noexcept
  197. : file{file_}
  198. , line{line_}
  199. {}
  200. char const *file;
  201. unsigned long line;
  202. };
  203. inline
  204. std::ostream&
  205. operator<<(
  206. std::ostream& os,
  207. const location& loc)
  208. {
  209. if (loc.line != 0U) os << loc.file << ':' << loc.line;
  210. return os;
  211. }
  212. enum class severity { fatal, nonfatal };
  213. using reporter_func = std::function<void(severity,
  214. char const *file,
  215. unsigned long line,
  216. std::string const &msg)>;
  217. inline
  218. void default_reporter(
  219. severity,
  220. char const *file,
  221. unsigned long line,
  222. std::string const &msg)
  223. {
  224. if (!std::current_exception())
  225. {
  226. std::stringstream os;
  227. os << location{ file, line } << "\n" << msg;
  228. throw expectation_violation(os.str());
  229. }
  230. }
  231. inline
  232. reporter_func&
  233. reporter_obj()
  234. {
  235. static reporter_func obj = default_reporter;
  236. return obj;
  237. }
  238. inline
  239. reporter_func set_reporter(
  240. reporter_func f)
  241. {
  242. return std::exchange(reporter_obj(), std::move(f));
  243. }
  244. class tracer;
  245. inline
  246. tracer*&
  247. tracer_obj()
  248. noexcept
  249. {
  250. static tracer* ptr = nullptr;
  251. return ptr;
  252. }
  253. inline
  254. tracer*
  255. set_tracer(
  256. tracer* obj)
  257. noexcept
  258. {
  259. // std::exchange would be sane here, but it costs compilation time
  260. auto& ptr = tracer_obj();
  261. auto rv = ptr;
  262. ptr = obj;
  263. return rv;
  264. }
  265. class tracer
  266. {
  267. public:
  268. virtual
  269. void
  270. trace(
  271. char const *file,
  272. unsigned long line,
  273. std::string const &call) = 0;
  274. protected:
  275. tracer()
  276. noexcept
  277. : previous{set_tracer(this)} {}
  278. tracer(tracer const&) = delete;
  279. tracer& operator=(tracer const&) = delete;
  280. virtual
  281. ~tracer()
  282. {
  283. set_tracer(previous);
  284. }
  285. private:
  286. tracer* previous = nullptr;
  287. };
  288. class stream_tracer : public tracer
  289. {
  290. public:
  291. stream_tracer(
  292. std::ostream& stream_)
  293. : stream(stream_) {}
  294. void
  295. trace(
  296. char const *file,
  297. unsigned long line,
  298. std::string const &call)
  299. override
  300. {
  301. stream << location{file, line} << '\n' << call << '\n';
  302. }
  303. private:
  304. std::ostream& stream;
  305. };
  306. class trace_agent;
  307. template <typename T>
  308. struct reporter;
  309. template <typename T>
  310. void
  311. send_report(
  312. severity s,
  313. location loc,
  314. std::string const &msg)
  315. {
  316. reporter<T>::send(s, loc.file, loc.line, msg.c_str());
  317. }
  318. template <typename T>
  319. struct reporter
  320. {
  321. static
  322. void
  323. send(
  324. severity s,
  325. char const *file,
  326. unsigned long line,
  327. char const *msg);
  328. };
  329. template <typename T>
  330. void reporter<T>::
  331. send(
  332. severity s,
  333. char const *file,
  334. unsigned long line,
  335. char const *msg)
  336. {
  337. reporter_obj()(s, file, line, msg);
  338. }
  339. template <typename ... T>
  340. inline
  341. constexpr
  342. bool
  343. ignore(
  344. T const& ...)
  345. noexcept
  346. {
  347. return true;
  348. }
  349. struct illegal_argument
  350. {
  351. template <bool b = false>
  352. constexpr
  353. illegal_argument const& operator&() const
  354. {
  355. static_assert(b, "illegal argument");
  356. return *this;
  357. }
  358. template <bool b = false>
  359. constexpr
  360. illegal_argument const& operator*() const
  361. {
  362. static_assert(b, "illegal argument");
  363. return *this;
  364. }
  365. template <typename T, bool b = false>
  366. constexpr
  367. illegal_argument const& operator=(T const&) const
  368. {
  369. static_assert(b, "illegal argument");
  370. return *this;
  371. }
  372. template <typename T, bool b = false>
  373. constexpr
  374. operator T() const
  375. {
  376. static_assert(b, "illegal argument");
  377. return {};
  378. }
  379. };
  380. template <typename ...>
  381. struct void_t_
  382. {
  383. using type = void;
  384. };
  385. template <typename ... T>
  386. using void_t = typename void_t_<T...>::type;
  387. template <template <typename ...> class, typename, typename ...>
  388. struct is_detected_{
  389. using type = std::false_type;
  390. };
  391. template <template <typename ...> class D, typename ... Ts>
  392. struct is_detected_<D, void_t<D<Ts...>>, Ts...>
  393. {
  394. using type = std::true_type;
  395. };
  396. template <template <typename ...> class D, typename ... Ts>
  397. using is_detected = typename is_detected_<D, void, Ts...>::type;
  398. struct matcher { };
  399. template <typename T>
  400. using matcher_access = decltype(static_cast<matcher*>(std::declval<typename std::add_pointer<T>::type>()));
  401. template <typename T>
  402. using is_matcher = typename is_detected<matcher_access, T>::type;
  403. template <typename T>
  404. struct typed_matcher : matcher
  405. {
  406. operator T() const;
  407. };
  408. template <>
  409. struct typed_matcher<std::nullptr_t> : matcher
  410. {
  411. template <typename T, typename = decltype(std::declval<T>() == nullptr)>
  412. operator T&&() const;
  413. template <typename T,
  414. typename = decltype(std::declval<T>() == nullptr),
  415. typename = std::enable_if_t<std::is_copy_constructible<T>::value>>
  416. operator T&()const;
  417. template <typename T, typename C>
  418. operator T C::*() const;
  419. };
  420. template <typename Pred, typename ... T>
  421. class duck_typed_matcher : public matcher
  422. {
  423. public:
  424. template <typename V,
  425. typename = decltype(std::declval<Pred>()(std::declval<V&&>(), std::declval<T>()...))>
  426. operator V&&() const;
  427. template <typename V,
  428. typename = decltype(std::declval<Pred>()(std::declval<V&>(), std::declval<T>()...))>
  429. operator V&() const;
  430. };
  431. template <typename T>
  432. using ostream_insertion = decltype(std::declval<std::ostream&>() << std::declval<T>());
  433. template <typename T>
  434. using is_output_streamable = std::integral_constant<bool, is_detected<ostream_insertion, T>::value && !std::is_array<T>::value>;
  435. struct stream_sentry
  436. {
  437. stream_sentry(
  438. std::ostream& os_)
  439. : os(os_)
  440. , width(os.width(0))
  441. , flags(os.flags(std::ios_base::dec | std::ios_base::left))
  442. , fill(os.fill(' '))
  443. { }
  444. ~stream_sentry()
  445. {
  446. os.flags(flags);
  447. os.fill(fill);
  448. os.width(width);
  449. }
  450. private:
  451. std::ostream& os;
  452. std::streamsize width;
  453. std::ios_base::fmtflags flags;
  454. char fill;
  455. };
  456. template <typename T, typename U>
  457. using equality_comparison = decltype(std::declval<T>() == std::declval<U>());
  458. template <typename T, typename U>
  459. using is_equal_comparable = is_detected<equality_comparison, T, U>;
  460. template <typename T>
  461. using is_null_comparable = is_equal_comparable<T, std::nullptr_t>;
  462. template <typename T>
  463. inline
  464. constexpr
  465. bool
  466. is_null(
  467. T const &t,
  468. std::true_type)
  469. noexcept(noexcept(std::declval<const T&>() == nullptr))
  470. {
  471. return t == nullptr;
  472. }
  473. template <typename T>
  474. inline
  475. constexpr
  476. bool
  477. is_null(
  478. T const &,
  479. std::false_type)
  480. noexcept
  481. {
  482. return false;
  483. }
  484. template <typename T>
  485. inline
  486. constexpr
  487. bool
  488. is_null(
  489. T const &t)
  490. {
  491. // g++-4.9 uses C++11 rules for constexpr function, so can't
  492. // break this up into smaller bits
  493. using tag = std::integral_constant<bool, is_null_comparable<T>::value
  494. && !is_matcher<T>::value
  495. && !std::is_array<T>::value>;
  496. return ::trompeloeil::is_null(t, tag{});
  497. }
  498. template <typename T>
  499. void
  500. print(
  501. std::ostream& os,
  502. T const &t);
  503. template <typename T>
  504. using iterable = decltype(std::begin(std::declval<T&>()) == std::end(std::declval<T&>()));
  505. template <typename T>
  506. using is_collection = is_detected<iterable, T>;
  507. template <typename T,
  508. bool = is_output_streamable<T>::value,
  509. bool = is_collection<std::remove_reference_t<T>>::value>
  510. struct streamer
  511. {
  512. static
  513. void
  514. print(
  515. std::ostream& os,
  516. T const &t)
  517. {
  518. stream_sentry s(os);
  519. os << t;
  520. }
  521. };
  522. template <typename ... T>
  523. struct streamer<std::tuple<T...>, false, false>
  524. {
  525. static
  526. void
  527. print(
  528. std::ostream& os,
  529. std::tuple<T...> const& t)
  530. {
  531. print_tuple(os, t, std::index_sequence_for<T...>{});
  532. }
  533. template <size_t ... I>
  534. static
  535. void
  536. print_tuple(
  537. std::ostream& os,
  538. std::tuple<T...> const& t,
  539. std::index_sequence<I...>)
  540. {
  541. os << "{ ";
  542. const char* sep = "";
  543. std::initializer_list<const char*> v{((os << sep),
  544. ::trompeloeil::print(os, std::get<I>(t)),
  545. (sep = ", "))...};
  546. ignore(v);
  547. os << " }";
  548. }
  549. };
  550. template <typename T, typename U>
  551. struct streamer<std::pair<T, U>, false, false>
  552. {
  553. static
  554. void
  555. print(
  556. std::ostream& os,
  557. std::pair<T, U> const& t)
  558. {
  559. os << "{ ";
  560. ::trompeloeil::print(os, t.first);
  561. os << ", ";
  562. ::trompeloeil::print(os, t.second);
  563. os << " }";
  564. }
  565. };
  566. template <typename T>
  567. struct streamer<T, false, true>
  568. {
  569. static
  570. void
  571. print(
  572. std::ostream& os,
  573. T const& t)
  574. {
  575. os << "{ ";
  576. const char* sep = "";
  577. for (auto& elem : t)
  578. {
  579. os << sep;
  580. ::trompeloeil::print(os, elem);
  581. sep = ", ";
  582. }
  583. os << " }";
  584. }
  585. };
  586. template <typename T>
  587. struct streamer<T, false, false>
  588. {
  589. static
  590. void
  591. print(
  592. std::ostream& os,
  593. T const &t)
  594. {
  595. stream_sentry s(os);
  596. static const char *linebreak = "\n";
  597. os << sizeof(T) << "-byte object={";
  598. os << (linebreak + (sizeof(T) <= 8)); // stupid construction silences VS2015 warining
  599. os << std::setfill('0') << std::hex;
  600. auto p = reinterpret_cast<uint8_t const*>(&t);
  601. for (size_t i = 0; i < sizeof(T); ++i)
  602. {
  603. os << " 0x" << std::setw(2) << unsigned(p[i]);
  604. if ((i & 0xf) == 0xf) os << '\n';
  605. }
  606. os << " }";
  607. }
  608. };
  609. template <typename T>
  610. void
  611. print(
  612. std::ostream& os,
  613. T const &t)
  614. {
  615. if (is_null(t))
  616. {
  617. os << "nullptr";
  618. }
  619. else
  620. {
  621. streamer<T>::print(os, t);
  622. }
  623. }
  624. inline
  625. constexpr
  626. auto
  627. param_compare_operator(
  628. ...)
  629. {
  630. return " == ";
  631. }
  632. inline
  633. constexpr
  634. auto
  635. param_compare_operator(
  636. matcher const*)
  637. {
  638. return "";
  639. }
  640. template <typename T>
  641. void
  642. print_expectation(
  643. std::ostream& os,
  644. T const& t)
  645. {
  646. os << param_compare_operator(&t);
  647. print(os, t);
  648. os << '\n';
  649. }
  650. template <typename T>
  651. class list_elem
  652. {
  653. public:
  654. list_elem(
  655. const list_elem&)
  656. = delete;
  657. list_elem(
  658. list_elem &&r)
  659. noexcept
  660. {
  661. *this = std::move(r);
  662. }
  663. list_elem&
  664. operator=(
  665. list_elem &&r)
  666. noexcept
  667. {
  668. if (this != &r)
  669. {
  670. next = r.next;
  671. prev = &r;
  672. r.invariant_check();
  673. next->prev = this;
  674. r.next = this;
  675. TROMPELOEIL_ASSERT(next->prev == this);
  676. TROMPELOEIL_ASSERT(prev->next == this);
  677. r.unlink();
  678. TROMPELOEIL_ASSERT(!r.is_linked());
  679. invariant_check();
  680. }
  681. return *this;
  682. }
  683. list_elem&
  684. operator=(
  685. const list_elem&)
  686. = delete;
  687. virtual
  688. ~list_elem()
  689. {
  690. unlink();
  691. }
  692. void
  693. unlink()
  694. noexcept
  695. {
  696. invariant_check();
  697. auto n = next;
  698. auto p = prev;
  699. n->prev = p;
  700. p->next = n;
  701. next = this;
  702. prev = this;
  703. invariant_check();
  704. }
  705. void
  706. invariant_check()
  707. const
  708. noexcept
  709. {
  710. #ifdef TROMPELOEIL_SANITY_CHECKS
  711. TROMPELOEIL_ASSERT(next->prev == this);
  712. TROMPELOEIL_ASSERT(prev->next == this);
  713. TROMPELOEIL_ASSERT((next == this) == (prev == this));
  714. TROMPELOEIL_ASSERT((prev->next == next) == (next == this));
  715. TROMPELOEIL_ASSERT((next->prev == prev) == (prev == this));
  716. auto pp = prev;
  717. auto nn = next;
  718. do {
  719. TROMPELOEIL_ASSERT((nn == this) == (pp == this));
  720. TROMPELOEIL_ASSERT(nn->next->prev == nn);
  721. TROMPELOEIL_ASSERT(nn->prev->next == nn);
  722. TROMPELOEIL_ASSERT(pp->next->prev == pp);
  723. TROMPELOEIL_ASSERT(pp->prev->next == pp);
  724. TROMPELOEIL_ASSERT((nn->next == nn) == (nn == this));
  725. TROMPELOEIL_ASSERT((pp->prev == pp) == (pp == this));
  726. nn = nn->next;
  727. pp = pp->prev;
  728. } while (nn != this);
  729. #endif
  730. }
  731. bool
  732. is_linked()
  733. const
  734. noexcept
  735. {
  736. invariant_check();
  737. return next != this;
  738. }
  739. protected:
  740. list_elem() noexcept = default;
  741. public:
  742. list_elem* next = this;
  743. list_elem* prev = this;
  744. };
  745. class ignore_disposer
  746. {
  747. protected:
  748. template <typename T>
  749. TROMPELOEIL_NORETURN
  750. void
  751. dispose(
  752. T*)
  753. const
  754. noexcept
  755. {
  756. std::abort(); // must never be called
  757. }
  758. };
  759. class delete_disposer
  760. {
  761. protected:
  762. template <typename T>
  763. void
  764. dispose(
  765. T* t)
  766. const
  767. {
  768. delete t;
  769. }
  770. };
  771. template <typename T, typename Disposer = ignore_disposer>
  772. class list : private list_elem<T>, private Disposer
  773. {
  774. public:
  775. list() noexcept;
  776. list(list&&) noexcept;
  777. list(const list&) = delete;
  778. list& operator=(list&&) noexcept;
  779. list& operator=(const list&) = delete;
  780. ~list();
  781. class iterator;
  782. iterator begin() const noexcept;
  783. iterator end() const noexcept;
  784. iterator push_front(T* t) noexcept;
  785. iterator push_back(T* t) noexcept;
  786. bool empty() const noexcept { return begin() == end(); }
  787. private:
  788. using list_elem<T>::invariant_check;
  789. using list_elem<T>::next;
  790. using list_elem<T>::prev;
  791. };
  792. template <typename T, typename Disposer>
  793. class list<T, Disposer>::iterator
  794. : public std::iterator<std::bidirectional_iterator_tag, T>
  795. {
  796. friend class list<T, Disposer>;
  797. public:
  798. iterator()
  799. noexcept
  800. : p{nullptr}
  801. {}
  802. friend
  803. bool
  804. operator==(
  805. iterator const &lh,
  806. iterator const &rh)
  807. noexcept
  808. {
  809. return lh.p == rh.p;
  810. }
  811. friend
  812. bool
  813. operator!=(
  814. iterator const &lh,
  815. iterator const &rh)
  816. noexcept
  817. {
  818. return !(lh == rh);
  819. }
  820. iterator&
  821. operator++()
  822. noexcept
  823. {
  824. p = p->next;
  825. return *this;
  826. }
  827. iterator
  828. operator++(int)
  829. noexcept
  830. {
  831. auto rv = *this;
  832. operator++();
  833. return rv;
  834. }
  835. T&
  836. operator*()
  837. noexcept
  838. {
  839. return static_cast<T&>(*p);
  840. }
  841. T*
  842. operator->()
  843. noexcept
  844. {
  845. return static_cast<T*>(p);
  846. }
  847. private:
  848. iterator(
  849. list_elem<T> const *t)
  850. noexcept
  851. : p{const_cast<list_elem<T>*>(t)}
  852. {}
  853. list_elem<T>* p;
  854. };
  855. template <typename T, typename Disposer>
  856. list<T, Disposer>::list() noexcept = default;
  857. template <typename T, typename Disposer>
  858. list<T, Disposer>::list(list&&) noexcept = default;
  859. template <typename T, typename Disposer>
  860. list<T, Disposer>& list<T, Disposer>::operator=(list&&) noexcept = default;
  861. template <typename T, typename Disposer>
  862. list<T, Disposer>::~list()
  863. {
  864. auto i = this->begin();
  865. while (i != this->end())
  866. {
  867. auto p = i++;
  868. Disposer::dispose(&*p);
  869. }
  870. }
  871. template <typename T, typename Disposer>
  872. auto
  873. list<T, Disposer>::begin()
  874. const
  875. noexcept
  876. -> iterator
  877. {
  878. return {next};
  879. }
  880. template <typename T, typename Disposer>
  881. auto
  882. list<T, Disposer>::end()
  883. const
  884. noexcept
  885. -> iterator
  886. {
  887. return {this};
  888. }
  889. template <typename T, typename Disposer>
  890. auto
  891. list<T, Disposer>::push_front(
  892. T* t)
  893. noexcept
  894. -> iterator
  895. {
  896. invariant_check();
  897. t->next = next;
  898. t->prev = this;
  899. next->prev = t;
  900. next = t;
  901. invariant_check();
  902. return {t};
  903. }
  904. template <typename T, typename Disposer>
  905. auto
  906. list<T, Disposer>::push_back(
  907. T* t)
  908. noexcept
  909. -> iterator
  910. {
  911. invariant_check();
  912. t->prev = prev;
  913. t->next = this;
  914. prev->next = t;
  915. prev = t;
  916. invariant_check();
  917. return {t};
  918. }
  919. class sequence_matcher;
  920. class sequence_type
  921. {
  922. public:
  923. sequence_type() noexcept = default;
  924. sequence_type(sequence_type&&) noexcept = delete;
  925. sequence_type(const sequence_type&) = delete;
  926. sequence_type& operator=(sequence_type&&) noexcept = delete;
  927. sequence_type& operator=(const sequence_type&) = delete;
  928. ~sequence_type();
  929. bool
  930. is_completed()
  931. const
  932. noexcept;
  933. bool
  934. is_first(
  935. sequence_matcher const *m)
  936. const
  937. noexcept;
  938. void
  939. add_last(
  940. sequence_matcher *m)
  941. noexcept;
  942. void
  943. validate_match(
  944. severity s,
  945. sequence_matcher const *matcher,
  946. char const *seq_name,
  947. char const *match_name,
  948. location loc)
  949. const;
  950. private:
  951. list<sequence_matcher> matchers;
  952. };
  953. class sequence
  954. {
  955. public:
  956. sequence() : obj(new sequence_type) {}
  957. sequence_type& operator*() { return *obj; }
  958. bool is_completed() const { return obj->is_completed(); }
  959. private:
  960. std::unique_ptr<sequence_type> obj;
  961. };
  962. class sequence_matcher : public list_elem<sequence_matcher>
  963. {
  964. public:
  965. using init_type = std::pair<char const*, sequence&>;
  966. sequence_matcher(
  967. char const *exp,
  968. location loc,
  969. init_type i)
  970. noexcept
  971. : seq_name(i.first)
  972. , exp_name(exp)
  973. , exp_loc(loc)
  974. , seq(*i.second)
  975. {
  976. seq.add_last(this);
  977. }
  978. void
  979. validate_match(
  980. severity s,
  981. char const *match_name,
  982. location loc)
  983. const
  984. {
  985. seq.validate_match(s, this, seq_name, match_name, loc);
  986. }
  987. bool
  988. is_first()
  989. const
  990. noexcept
  991. {
  992. return seq.is_first(this);
  993. }
  994. void
  995. retire()
  996. noexcept
  997. {
  998. this->unlink();
  999. }
  1000. void
  1001. print_expectation(std::ostream& os)
  1002. const
  1003. {
  1004. os << exp_name << " at " << exp_loc;
  1005. }
  1006. char const*
  1007. sequence_name()
  1008. noexcept
  1009. {
  1010. return seq_name;
  1011. }
  1012. private:
  1013. char const *seq_name;
  1014. char const *exp_name;
  1015. location exp_loc;
  1016. sequence_type& seq;
  1017. };
  1018. inline
  1019. bool
  1020. sequence_type::is_completed()
  1021. const
  1022. noexcept
  1023. {
  1024. return matchers.empty();
  1025. }
  1026. inline
  1027. bool
  1028. sequence_type::is_first(
  1029. sequence_matcher const *m)
  1030. const
  1031. noexcept
  1032. {
  1033. return !matchers.empty() && &*matchers.begin() == m;
  1034. }
  1035. inline
  1036. void
  1037. sequence_type::validate_match(
  1038. severity s,
  1039. sequence_matcher const *matcher,
  1040. char const* seq_name,
  1041. char const* match_name,
  1042. location loc)
  1043. const
  1044. {
  1045. if (is_first(matcher)) return;
  1046. for (auto& m : matchers)
  1047. {
  1048. std::ostringstream os;
  1049. os << "Sequence mismatch for sequence \"" << seq_name
  1050. << "\" with matching call of " << match_name
  1051. << " at " << loc
  1052. << ". Sequence \"" << seq_name << "\" has ";
  1053. m.print_expectation(os);
  1054. os << " first in line\n";
  1055. send_report<specialized>(s, loc, os.str());
  1056. }
  1057. }
  1058. inline
  1059. sequence_type::~sequence_type()
  1060. {
  1061. bool touched = false;
  1062. std::ostringstream os;
  1063. while (!matchers.empty())
  1064. {
  1065. auto m = matchers.begin();
  1066. if (!touched)
  1067. {
  1068. os << "Sequence expectations not met at destruction of sequence object \""
  1069. << m->sequence_name() << "\":";
  1070. touched = true;
  1071. }
  1072. os << "\n missing ";
  1073. m->print_expectation(os);
  1074. m->unlink();
  1075. }
  1076. if (touched)
  1077. {
  1078. os << "\n";
  1079. send_report<specialized>(severity::nonfatal, location{}, os.str());
  1080. }
  1081. }
  1082. inline
  1083. void
  1084. sequence_type::add_last(
  1085. sequence_matcher *m)
  1086. noexcept
  1087. {
  1088. matchers.push_back(m);
  1089. }
  1090. struct wildcard : public matcher
  1091. {
  1092. // This abomination of constructor seems necessary for g++ 4.9 and 5.1
  1093. template <typename ... T>
  1094. constexpr
  1095. wildcard(
  1096. T&& ...)
  1097. noexcept
  1098. {}
  1099. template<typename T,
  1100. typename = std::enable_if_t<!std::is_lvalue_reference<T>::value>>
  1101. operator T&&()
  1102. const;
  1103. template<typename T,
  1104. typename = std::enable_if_t<std::is_copy_constructible<T>::value
  1105. || !std::is_move_constructible<T>::value>>
  1106. operator T&()
  1107. const;
  1108. template <typename T>
  1109. constexpr
  1110. bool
  1111. matches(
  1112. T const&)
  1113. const
  1114. noexcept
  1115. {
  1116. return true;
  1117. }
  1118. friend
  1119. std::ostream&
  1120. operator<<(
  1121. std::ostream& os,
  1122. wildcard const&)
  1123. noexcept
  1124. {
  1125. return os << " matching _";
  1126. }
  1127. };
  1128. static constexpr wildcard const _{};
  1129. template <typename T>
  1130. void can_match_parameter(T&);
  1131. template <typename T>
  1132. void can_match_parameter(T&&);
  1133. template <typename M>
  1134. class ptr_deref : public matcher
  1135. {
  1136. public:
  1137. template <typename U,
  1138. typename = decltype(can_match_parameter<std::remove_reference_t<decltype(*std::declval<U>())>>(std::declval<M>()))>
  1139. operator U() const;
  1140. template <typename U>
  1141. explicit
  1142. ptr_deref(
  1143. U&& m_)
  1144. : m( std::forward<U>(m_) )
  1145. {}
  1146. template <typename U>
  1147. bool
  1148. matches(
  1149. const U& u)
  1150. const
  1151. noexcept(noexcept(std::declval<M>().matches(*u)))
  1152. {
  1153. return (u != nullptr) && m.matches(*u);
  1154. }
  1155. friend
  1156. std::ostream&
  1157. operator<<(
  1158. std::ostream& os,
  1159. ptr_deref<M> const& p)
  1160. {
  1161. return os << p.m;
  1162. }
  1163. private:
  1164. M m;
  1165. };
  1166. template <typename M>
  1167. class neg_matcher : public matcher
  1168. {
  1169. public:
  1170. template <typename U,
  1171. typename = decltype(can_match_parameter<std::remove_reference_t<decltype(std::declval<U>())>>(std::declval<M>()))>
  1172. operator U() const;
  1173. template <typename U>
  1174. explicit
  1175. neg_matcher(
  1176. U&& m_)
  1177. : m( std::forward<U>(m_) )
  1178. {}
  1179. template <typename U>
  1180. bool
  1181. matches(
  1182. const U& u)
  1183. const
  1184. noexcept(noexcept(!std::declval<M>().matches(u)))
  1185. {
  1186. return !m.matches(u);
  1187. }
  1188. friend
  1189. std::ostream&
  1190. operator<<(
  1191. std::ostream& os,
  1192. neg_matcher<M> const& p)
  1193. {
  1194. return os << p.m;
  1195. }
  1196. private:
  1197. M m;
  1198. };
  1199. template <typename MatchType, typename Predicate, typename ... ActualType>
  1200. struct matcher_kind
  1201. {
  1202. using type = typed_matcher<MatchType>;
  1203. };
  1204. template <typename Predicate, typename ... ActualType>
  1205. struct matcher_kind<wildcard, Predicate, ActualType...>
  1206. {
  1207. using type = duck_typed_matcher<Predicate, ActualType...>;
  1208. };
  1209. template <typename MatchType, typename Predicate, typename ... ActualType>
  1210. using matcher_kind_t =
  1211. typename matcher_kind<MatchType, Predicate, ActualType...>::type;
  1212. template <typename Predicate, typename Printer, typename MatcherType, typename ... T>
  1213. class predicate_matcher
  1214. : private Predicate
  1215. , private Printer
  1216. , public MatcherType
  1217. {
  1218. public:
  1219. template <typename ... U>
  1220. constexpr
  1221. predicate_matcher(
  1222. Predicate&& pred,
  1223. Printer&& printer,
  1224. U&& ... v)
  1225. noexcept(noexcept(std::tuple<T...>(std::declval<U>()...)) && noexcept(Predicate(std::declval<Predicate&&>())) && noexcept(Printer(std::declval<Printer&&>())))
  1226. : Predicate(std::move(pred))
  1227. , Printer(std::move(printer))
  1228. , value(std::forward<U>(v)...)
  1229. {}
  1230. template <typename V>
  1231. constexpr
  1232. bool
  1233. matches(
  1234. V&& v)
  1235. const
  1236. noexcept(noexcept(std::declval<Predicate const&>()(std::declval<V&&>(), std::declval<const T&>()...)))
  1237. {
  1238. return matches_(std::forward<V>(v), std::make_index_sequence<sizeof...(T)>{});
  1239. }
  1240. friend
  1241. std::ostream&
  1242. operator<<(
  1243. std::ostream& os,
  1244. predicate_matcher const& v)
  1245. {
  1246. return v.print_(os, std::make_index_sequence<sizeof...(T)>{});
  1247. }
  1248. private:
  1249. // The below function call operator must be declared to
  1250. // work around gcc bug 78446
  1251. //
  1252. // For some reason microsoft compiler from VS2015 update 3
  1253. // requires the function call operator to be private to avoid
  1254. // ambiguities.
  1255. template <typename ... U>
  1256. void operator()(U&&...) const = delete;
  1257. template <typename V, size_t ... I>
  1258. bool matches_(V&& v, std::index_sequence<I...>) const
  1259. {
  1260. return Predicate::operator()(std::forward<V>(v), std::get<I>(value)...);
  1261. }
  1262. template <size_t ... I>
  1263. std::ostream& print_(std::ostream& os_, std::index_sequence<I...>) const
  1264. {
  1265. Printer::operator()(os_, std::get<I>(value)...);
  1266. return os_;
  1267. }
  1268. std::tuple<T...> value;
  1269. };
  1270. namespace lambdas {
  1271. // The below must be classes/structs to work with VS 2015 update 3
  1272. // since it doesn't respect the trailing return type declaration on
  1273. // the lambdas of template deduction context
  1274. #define TROMPELOEIL_MK_PRED_BINOP(name, op) \
  1275. struct name { \
  1276. template <typename X, typename Y> \
  1277. auto operator()(X const& x, Y const& y) const -> decltype(x op y) \
  1278. { \
  1279. ::trompeloeil::ignore(x,y); \
  1280. return x op y; \
  1281. } \
  1282. }
  1283. TROMPELOEIL_MK_PRED_BINOP(equal, ==);
  1284. TROMPELOEIL_MK_PRED_BINOP(not_equal, !=);
  1285. TROMPELOEIL_MK_PRED_BINOP(less, <);
  1286. TROMPELOEIL_MK_PRED_BINOP(less_equal, <=);
  1287. TROMPELOEIL_MK_PRED_BINOP(greater, >);
  1288. TROMPELOEIL_MK_PRED_BINOP(greater_equal, >=);
  1289. #undef TROMPELOEIL_MK_PRED_BINOP
  1290. }
  1291. template <typename MatchType, typename Predicate, typename Printer, typename ... T>
  1292. inline
  1293. predicate_matcher <Predicate, Printer, matcher_kind_t<MatchType, Predicate, std::decay_t<T>...>, std::decay_t<T>...>
  1294. make_matcher(Predicate pred, Printer print, T&& ... t)
  1295. {
  1296. return {std::move(pred), std::move(print), std::forward<T>(t)...};
  1297. }
  1298. template <typename T>
  1299. inline
  1300. auto
  1301. any_matcher(char const* type_name)
  1302. {
  1303. return make_matcher<T>([](auto&&) { return true; },
  1304. [type_name](std::ostream& os)
  1305. { os << " matching ANY(" << type_name << ")";});
  1306. }
  1307. template <typename T = wildcard, typename V>
  1308. inline
  1309. auto
  1310. eq(
  1311. V&& v)
  1312. {
  1313. return make_matcher<T>(lambdas::equal(),
  1314. [](std::ostream& os, auto const& value) {
  1315. os << " == ";
  1316. ::trompeloeil::print(os, value);
  1317. },
  1318. std::forward<V>(v));
  1319. }
  1320. template <typename T = wildcard, typename V>
  1321. inline
  1322. auto
  1323. ne(
  1324. V&& v)
  1325. {
  1326. return make_matcher<T>(lambdas::not_equal(),
  1327. [](std::ostream& os, auto const& value) {
  1328. os << " != ";
  1329. ::trompeloeil::print(os, value);
  1330. },
  1331. std::forward<V>(v));
  1332. }
  1333. template <typename T = wildcard, typename V>
  1334. inline
  1335. auto
  1336. ge(
  1337. V&& v)
  1338. {
  1339. return make_matcher<T>(lambdas::greater_equal(),
  1340. [](std::ostream& os, auto const& value) {
  1341. os << " >= ";
  1342. ::trompeloeil::print(os, value);
  1343. },
  1344. std::forward<V>(v));
  1345. }
  1346. template <typename T = wildcard, typename V>
  1347. inline
  1348. auto
  1349. gt(
  1350. V&& v)
  1351. {
  1352. return make_matcher<T>(lambdas::greater(),
  1353. [](std::ostream& os, auto const& value) {
  1354. os << " > ";
  1355. ::trompeloeil::print(os, value);
  1356. },
  1357. std::forward<V>(v));
  1358. }
  1359. template <typename T = wildcard, typename V>
  1360. inline
  1361. auto
  1362. lt(
  1363. V&& v)
  1364. {
  1365. return make_matcher<T>(lambdas::less(),
  1366. [](std::ostream& os, auto const& value) {
  1367. os << " < ";
  1368. ::trompeloeil::print(os, value);
  1369. },
  1370. std::forward<V>(v));
  1371. }
  1372. template <typename T = wildcard, typename V>
  1373. inline
  1374. auto
  1375. le(
  1376. V&& v)
  1377. {
  1378. return make_matcher<T>(lambdas::less_equal(),
  1379. [](std::ostream& os, auto const& value) {
  1380. os << " <= ";
  1381. ::trompeloeil::print(os, value);
  1382. },
  1383. std::forward<V>(v));
  1384. }
  1385. namespace lambdas {
  1386. inline
  1387. auto
  1388. regex_check(
  1389. std::regex&& re,
  1390. std::regex_constants::match_flag_type match_type)
  1391. {
  1392. class string_helper // a vastly simplified string_view type of class
  1393. {
  1394. public:
  1395. string_helper(
  1396. std::string const& s)
  1397. noexcept
  1398. : str(s.c_str())
  1399. {}
  1400. constexpr
  1401. string_helper(
  1402. char const* s)
  1403. noexcept
  1404. : str(s)
  1405. {}
  1406. char const*
  1407. c_str()
  1408. const
  1409. noexcept
  1410. {
  1411. return str;
  1412. }
  1413. private:
  1414. char const* str;
  1415. };
  1416. return [re, match_type](string_helper str, auto const&)
  1417. -> decltype(std::regex_search(str.c_str(), re, match_type))
  1418. {
  1419. return !::trompeloeil::is_null(str.c_str())
  1420. && std::regex_search(str.c_str(), re, match_type);
  1421. };
  1422. }
  1423. inline auto regex_printer()
  1424. {
  1425. return [](std::ostream& os, auto const& str)
  1426. {
  1427. os << " matching regular expression /" << str << "/";
  1428. };
  1429. }
  1430. }
  1431. template <typename Kind = wildcard>
  1432. auto
  1433. re(
  1434. std::string s,
  1435. std::regex_constants::syntax_option_type opt = std::regex_constants::ECMAScript,
  1436. std::regex_constants::match_flag_type match_type = std::regex_constants::match_default)
  1437. {
  1438. return make_matcher<Kind>(lambdas::regex_check(std::regex(s, opt),
  1439. match_type),
  1440. lambdas::regex_printer(),
  1441. std::move(s));
  1442. }
  1443. template <typename Kind = wildcard>
  1444. auto
  1445. re(
  1446. std::string s,
  1447. std::regex_constants::match_flag_type match_type)
  1448. {
  1449. return make_matcher<Kind>(lambdas::regex_check(std::regex(s), match_type),
  1450. lambdas::regex_printer(),
  1451. std::move(s));
  1452. }
  1453. inline
  1454. std::string
  1455. param_name_prefix(
  1456. ...)
  1457. {
  1458. return "";
  1459. }
  1460. template <typename M>
  1461. std::string
  1462. param_name_prefix(
  1463. const ptr_deref<M>*)
  1464. {
  1465. return "*" + ::trompeloeil::param_name_prefix(static_cast<M*>(nullptr));
  1466. }
  1467. template <typename M>
  1468. std::string
  1469. param_name_prefix(
  1470. const neg_matcher<M>*)
  1471. {
  1472. return "not " + ::trompeloeil::param_name_prefix(static_cast<M*>(nullptr));
  1473. }
  1474. template <typename T>
  1475. struct null_on_move
  1476. {
  1477. public:
  1478. null_on_move()
  1479. noexcept
  1480. : p{nullptr}
  1481. {}
  1482. null_on_move(
  1483. T* p_)
  1484. noexcept
  1485. : p{p_}
  1486. {}
  1487. null_on_move(
  1488. null_on_move&&)
  1489. noexcept
  1490. : p{nullptr}
  1491. {}
  1492. null_on_move(
  1493. null_on_move const&)
  1494. noexcept
  1495. : p{nullptr}
  1496. {}
  1497. null_on_move&
  1498. operator=(
  1499. const null_on_move&)
  1500. noexcept
  1501. {
  1502. p = nullptr;
  1503. return *this;
  1504. }
  1505. null_on_move&
  1506. operator=(
  1507. null_on_move&&)
  1508. noexcept
  1509. {
  1510. p = nullptr;
  1511. return *this;
  1512. }
  1513. null_on_move&
  1514. operator=(
  1515. T* t)
  1516. noexcept
  1517. {
  1518. p = t;
  1519. return *this;
  1520. }
  1521. T*&
  1522. leak()
  1523. noexcept
  1524. {
  1525. return p;
  1526. }
  1527. T&
  1528. operator*()
  1529. const
  1530. noexcept
  1531. {
  1532. return *p;
  1533. }
  1534. T*
  1535. operator->()
  1536. const
  1537. noexcept
  1538. {
  1539. return p;
  1540. }
  1541. explicit
  1542. operator bool()
  1543. const
  1544. noexcept
  1545. {
  1546. return p != nullptr;
  1547. }
  1548. private:
  1549. T* p;
  1550. };
  1551. struct sequence_handler_base
  1552. {
  1553. virtual
  1554. ~sequence_handler_base()
  1555. noexcept = default;
  1556. virtual
  1557. void
  1558. validate(severity s, char const *, location) = 0;
  1559. virtual
  1560. bool
  1561. is_first()
  1562. const
  1563. noexcept = 0;
  1564. virtual
  1565. void
  1566. retire()
  1567. noexcept = 0;
  1568. };
  1569. template <size_t N>
  1570. struct sequence_handler : public sequence_handler_base
  1571. {
  1572. public:
  1573. template <typename ... S>
  1574. sequence_handler(
  1575. char const *name,
  1576. location loc,
  1577. S&& ... s)
  1578. noexcept
  1579. : matchers{{name, loc, std::forward<S>(s)}...}
  1580. {
  1581. }
  1582. void
  1583. validate(
  1584. severity s,
  1585. char const *match_name,
  1586. location loc)
  1587. override
  1588. {
  1589. for (auto& e : matchers)
  1590. {
  1591. e.validate_match(s, match_name, loc);
  1592. }
  1593. }
  1594. bool
  1595. is_first()
  1596. const
  1597. noexcept
  1598. override
  1599. {
  1600. // std::all_of() is almost always preferable. The only reason
  1601. // for using a hand rolled loop is because it cuts compilation
  1602. // times quite noticeably (almost 10% with g++5.1)
  1603. for (auto& m : matchers)
  1604. {
  1605. if (!m.is_first()) return false;
  1606. }
  1607. return true;
  1608. }
  1609. void
  1610. retire()
  1611. noexcept
  1612. override
  1613. {
  1614. for (auto& e : matchers)
  1615. {
  1616. e.retire();
  1617. }
  1618. }
  1619. private:
  1620. sequence_matcher matchers[N];
  1621. };
  1622. struct lifetime_monitor;
  1623. template <typename T>
  1624. class deathwatched : public T
  1625. {
  1626. static_assert(std::has_virtual_destructor<T>::value,
  1627. "virtual destructor is a necessity for deathwatched to work");
  1628. public:
  1629. template <typename ... U,
  1630. typename = std::enable_if_t<std::is_constructible<T,U...>::value>>
  1631. deathwatched(
  1632. U&& ...u)
  1633. noexcept(noexcept(T(std::declval<U>()...)))
  1634. : T(std::forward<U>(u)...)
  1635. {}
  1636. ~deathwatched();
  1637. trompeloeil::lifetime_monitor*&
  1638. trompeloeil_expect_death(
  1639. trompeloeil::lifetime_monitor* monitor)
  1640. const
  1641. noexcept
  1642. {
  1643. auto lock = get_lock();
  1644. trompeloeil_lifetime_monitor = monitor;
  1645. return trompeloeil_lifetime_monitor.leak();
  1646. }
  1647. private:
  1648. mutable null_on_move<trompeloeil::lifetime_monitor> trompeloeil_lifetime_monitor;
  1649. };
  1650. struct expectation {
  1651. virtual ~expectation() = default;
  1652. virtual bool is_satisfied() const noexcept = 0;
  1653. virtual bool is_saturated() const noexcept = 0;
  1654. };
  1655. struct lifetime_monitor : public expectation
  1656. {
  1657. template <typename T>
  1658. lifetime_monitor(
  1659. ::trompeloeil::deathwatched<T> const &obj,
  1660. char const* obj_name_,
  1661. char const* invocation_name_,
  1662. char const* call_name_,
  1663. location loc_)
  1664. noexcept
  1665. : object_monitor(obj.trompeloeil_expect_death(this))
  1666. , loc(loc_)
  1667. , object_name(obj_name_)
  1668. , invocation_name(invocation_name_)
  1669. , call_name(call_name_)
  1670. {
  1671. }
  1672. bool is_satisfied() const noexcept override
  1673. {
  1674. return died;
  1675. }
  1676. bool is_saturated() const noexcept override
  1677. {
  1678. return died;
  1679. }
  1680. lifetime_monitor(lifetime_monitor const&) = delete;
  1681. ~lifetime_monitor()
  1682. {
  1683. auto lock = get_lock();
  1684. if (!died)
  1685. {
  1686. std::ostringstream os;
  1687. os << "Object " << object_name << " is still alive";
  1688. send_report<specialized>(severity::nonfatal, loc, os.str());
  1689. object_monitor = nullptr; // prevent its death poking this cadaver
  1690. }
  1691. }
  1692. void
  1693. notify()
  1694. noexcept
  1695. {
  1696. died = true;
  1697. if (sequences) sequences->validate(severity::nonfatal, call_name, loc);
  1698. }
  1699. template <typename ... T>
  1700. void
  1701. set_sequence(
  1702. T&& ... t)
  1703. {
  1704. auto seq = new sequence_handler<sizeof...(T)>(invocation_name,
  1705. loc,
  1706. std::forward<T>(t)...);
  1707. sequences.reset(seq);
  1708. }
  1709. private:
  1710. std::atomic<bool> died{false};
  1711. lifetime_monitor *&object_monitor;
  1712. location loc;
  1713. char const *object_name;
  1714. char const *invocation_name;
  1715. char const *call_name;
  1716. std::unique_ptr<sequence_handler_base> sequences;
  1717. };
  1718. template <typename T>
  1719. deathwatched<T>::~deathwatched()
  1720. {
  1721. auto lock = get_lock();
  1722. if (trompeloeil_lifetime_monitor)
  1723. {
  1724. trompeloeil_lifetime_monitor->notify();
  1725. return;
  1726. }
  1727. std::ostringstream os;
  1728. os << "Unexpected destruction of "
  1729. << typeid(T).name() << "@" << this << '\n';
  1730. send_report<specialized>(severity::nonfatal,
  1731. location{},
  1732. os.str());
  1733. }
  1734. template<typename T>
  1735. struct return_of;
  1736. template<typename R, typename ... A>
  1737. struct return_of<R(A...)>
  1738. {
  1739. using type = R;
  1740. };
  1741. template<typename T>
  1742. using return_of_t = typename return_of<T>::type;
  1743. template<typename T>
  1744. struct call_params_type;
  1745. template<typename R, typename ... T>
  1746. struct call_params_type<R(T...)>
  1747. {
  1748. using type = std::tuple<typename std::add_lvalue_reference<T>::type...>;
  1749. };
  1750. template<typename T>
  1751. using call_params_type_t = typename call_params_type<T>::type;
  1752. template <typename R>
  1753. struct default_return_t
  1754. {
  1755. TROMPELOEIL_NORETURN static R value()
  1756. {
  1757. std::abort(); // must never be called
  1758. }
  1759. };
  1760. template <typename R>
  1761. inline
  1762. R
  1763. default_return()
  1764. {
  1765. return default_return_t<R>::value();
  1766. }
  1767. template <>
  1768. inline
  1769. void
  1770. default_return<void>()
  1771. {
  1772. }
  1773. template<typename Sig>
  1774. struct call_matcher_base;
  1775. template <typename Sig>
  1776. struct call_matcher_list : public list<call_matcher_base<Sig>>
  1777. {
  1778. void decommission()
  1779. {
  1780. auto lock = get_lock();
  1781. auto iter = this->begin();
  1782. auto const e = this->end();
  1783. while (iter != e)
  1784. {
  1785. auto i = iter++;
  1786. auto &m = *i;
  1787. m.mock_destroyed();
  1788. m.unlink();
  1789. }
  1790. }
  1791. };
  1792. template<typename Sig>
  1793. struct call_matcher_base : public list_elem<call_matcher_base<Sig> >
  1794. {
  1795. call_matcher_base(
  1796. location loc_,
  1797. char const* name_)
  1798. : loc{loc_}
  1799. , name{name_}
  1800. {
  1801. }
  1802. call_matcher_base(call_matcher_base&&) = delete;
  1803. virtual
  1804. ~call_matcher_base() = default;
  1805. virtual
  1806. void
  1807. mock_destroyed() = 0;
  1808. virtual
  1809. bool
  1810. matches(
  1811. call_params_type_t<Sig> const&)
  1812. const = 0;
  1813. virtual
  1814. bool
  1815. first_in_sequence()
  1816. const
  1817. noexcept = 0;
  1818. virtual
  1819. void
  1820. run_actions(
  1821. call_params_type_t<Sig> &,
  1822. call_matcher_list<Sig> &saturated_list
  1823. ) = 0;
  1824. virtual
  1825. std::ostream&
  1826. report_signature(
  1827. std::ostream&)
  1828. const = 0;
  1829. TROMPELOEIL_NORETURN
  1830. virtual
  1831. std::ostream&
  1832. report_mismatch(
  1833. std::ostream&,
  1834. call_params_type_t<Sig> const &) = 0;
  1835. virtual
  1836. return_of_t<Sig>
  1837. return_value(
  1838. trace_agent&,
  1839. call_params_type_t<Sig>& p) = 0;
  1840. virtual
  1841. void
  1842. report_missed(
  1843. char const *reason) = 0;
  1844. location loc;
  1845. char const *name;
  1846. };
  1847. template <typename T, typename U>
  1848. bool
  1849. param_matches_impl(
  1850. T const& t,
  1851. U const& u,
  1852. matcher const*)
  1853. noexcept(noexcept(t.matches(u)))
  1854. {
  1855. return t.matches(u);
  1856. }
  1857. template <typename T,
  1858. typename U,
  1859. typename = std::enable_if_t<is_equal_comparable<T, U>::value>>
  1860. inline
  1861. U&
  1862. identity(
  1863. U& t)
  1864. noexcept
  1865. {
  1866. return t;
  1867. }
  1868. template <typename T,
  1869. typename U,
  1870. typename = std::enable_if_t<!is_equal_comparable<T, U>::value>>
  1871. inline
  1872. T
  1873. identity(
  1874. const U& u)
  1875. noexcept(noexcept(T(u)))
  1876. {
  1877. return u;
  1878. }
  1879. template <typename T, typename U>
  1880. bool
  1881. param_matches_impl(
  1882. T const& t,
  1883. U const& u,
  1884. ...)
  1885. noexcept(noexcept(::trompeloeil::identity<U>(t) == u))
  1886. {
  1887. return ::trompeloeil::identity<U>(t) == u;
  1888. }
  1889. template <typename T, typename U>
  1890. bool
  1891. param_matches(
  1892. T const& t,
  1893. U const& u)
  1894. noexcept(noexcept(param_matches_impl(t, u, &t)))
  1895. {
  1896. return ::trompeloeil::param_matches_impl(t, u, &t);
  1897. }
  1898. template <size_t ... I, typename T, typename U>
  1899. bool
  1900. match_parameters(
  1901. std::index_sequence<I...>,
  1902. T const& t,
  1903. U const& u)
  1904. noexcept(noexcept(std::initializer_list<bool>{trompeloeil::param_matches(std::get<I>(t),std::get<I>(u))...}))
  1905. {
  1906. bool all_true = true;
  1907. ::trompeloeil::ignore(t, u); // Kills unmotivated VS2015 warning in the empty case
  1908. ::trompeloeil::ignore(std::initializer_list<bool>{all_true = all_true && ::trompeloeil::param_matches(std::get<I>(t), std::get<I>(u))...});
  1909. return all_true;
  1910. }
  1911. template <typename ... T, typename ... U>
  1912. bool
  1913. match_parameters(
  1914. std::tuple<T...> const& t,
  1915. std::tuple<U...> const& u)
  1916. noexcept(noexcept(match_parameters(std::make_index_sequence<sizeof...(T)>{}, t, u)))
  1917. {
  1918. return ::trompeloeil::match_parameters(std::make_index_sequence<sizeof...(T)>{}, t, u);
  1919. }
  1920. template <typename V, typename P>
  1921. void print_mismatch(
  1922. std::ostream& os,
  1923. size_t num,
  1924. V const& v,
  1925. P const& p)
  1926. {
  1927. if (!::trompeloeil::param_matches(v, p))
  1928. {
  1929. auto prefix = ::trompeloeil::param_name_prefix(&v) + "_";
  1930. os << " Expected " << std::setw((num < 9) + 1) << prefix << num+1;
  1931. ::trompeloeil::print_expectation(os, v);
  1932. }
  1933. }
  1934. template <typename ... V, typename ... P, size_t ... I>
  1935. void print_mismatch(
  1936. std::ostream& os,
  1937. std::index_sequence<I...>,
  1938. std::tuple<V...> const& v,
  1939. std::tuple<P...> const& p)
  1940. {
  1941. ::trompeloeil::ignore(os, v, p); // Kills unmotivated VS2015 warning in the empty case
  1942. ::trompeloeil::ignore(std::initializer_list<int>{(print_mismatch(os, I, std::get<I>(v), std::get<I>(p)),0)...});
  1943. }
  1944. template <typename ... V, typename ... P>
  1945. void print_mismatch(
  1946. std::ostream& os,
  1947. std::tuple<V...> const& v,
  1948. std::tuple<P...> const& p)
  1949. {
  1950. print_mismatch(os, std::make_index_sequence<sizeof...(V)>{}, v, p);
  1951. }
  1952. template <typename T>
  1953. void missed_value(
  1954. std::ostream& os,
  1955. int i,
  1956. T const& t)
  1957. {
  1958. auto prefix = ::trompeloeil::param_name_prefix(&t) + "_";
  1959. os << " param " << std::setw((i < 9) + 1) << prefix << i + 1
  1960. << ::trompeloeil::param_compare_operator(&t);
  1961. ::trompeloeil::print(os, t);
  1962. os << '\n';
  1963. }
  1964. template <size_t ... I, typename ... T>
  1965. void stream_params(
  1966. std::ostream &os,
  1967. std::index_sequence<I...>,
  1968. std::tuple<T...> const &t)
  1969. {
  1970. ::trompeloeil::ignore(os, t); // Kills unmotivated VS2015 warning in the empty case
  1971. ::trompeloeil::ignore(std::initializer_list<int>{(missed_value(os, I, std::get<I>(t)),0)...});
  1972. }
  1973. template <typename ... T>
  1974. void
  1975. stream_params(
  1976. std::ostream &os,
  1977. std::tuple<T...> const &t)
  1978. {
  1979. stream_params(os, std::make_index_sequence<sizeof...(T)>{}, t);
  1980. }
  1981. template <typename ... T>
  1982. std::string
  1983. params_string(
  1984. std::tuple<T...> const& t)
  1985. {
  1986. std::ostringstream os;
  1987. stream_params(os, t);
  1988. return os.str();
  1989. }
  1990. class trace_agent
  1991. {
  1992. public:
  1993. trace_agent(
  1994. location loc_,
  1995. char const* name_,
  1996. tracer* t_)
  1997. : loc{loc_}
  1998. , t{t_}
  1999. {
  2000. if (t)
  2001. {
  2002. os << name_ << " with.\n";
  2003. }
  2004. }
  2005. trace_agent(trace_agent const&) = delete;
  2006. trace_agent(trace_agent &&) = delete;
  2007. ~trace_agent()
  2008. {
  2009. if (t)
  2010. {
  2011. t->trace(loc.file, loc.line, os.str());
  2012. }
  2013. }
  2014. trace_agent&
  2015. operator=(trace_agent const&) = delete;
  2016. trace_agent&
  2017. operator=(trace_agent &&) = delete;
  2018. template <typename ... T>
  2019. void
  2020. trace_params(
  2021. std::tuple<T...> const& params)
  2022. {
  2023. if (t)
  2024. {
  2025. stream_params(os, params);
  2026. }
  2027. }
  2028. template <typename T>
  2029. auto
  2030. trace_return(
  2031. T&& rv)
  2032. -> T
  2033. {
  2034. if (t)
  2035. {
  2036. os << " -> ";
  2037. print(os, rv);
  2038. os << '\n';
  2039. }
  2040. return std::forward<T>(rv);
  2041. }
  2042. void
  2043. trace_exception()
  2044. {
  2045. if (t)
  2046. {
  2047. try {
  2048. throw;
  2049. }
  2050. catch (std::exception& e)
  2051. {
  2052. os << "threw exception: what() = " << e.what() << '\n';
  2053. }
  2054. catch (...)
  2055. {
  2056. os << "threw unknown exception\n";
  2057. }
  2058. }
  2059. }
  2060. private:
  2061. location loc;
  2062. tracer* t;
  2063. std::ostringstream os;
  2064. };
  2065. template <typename Sig>
  2066. call_matcher_base <Sig> *
  2067. find(
  2068. call_matcher_list <Sig> &list,
  2069. call_params_type_t <Sig> const &p)
  2070. noexcept
  2071. {
  2072. call_matcher_base<Sig>* first_match = nullptr;
  2073. for (auto& i : list)
  2074. {
  2075. if (i.matches(p))
  2076. {
  2077. if (i.first_in_sequence())
  2078. {
  2079. return &i;
  2080. }
  2081. if (!first_match)
  2082. {
  2083. first_match = &i;
  2084. }
  2085. }
  2086. }
  2087. return first_match;
  2088. }
  2089. template <typename Sig>
  2090. TROMPELOEIL_NORETURN
  2091. void
  2092. report_mismatch(
  2093. call_matcher_list <Sig> &matcher_list,
  2094. call_matcher_list <Sig> &saturated_list,
  2095. std::string const &name,
  2096. call_params_type_t <Sig> const &p)
  2097. {
  2098. std::ostringstream os;
  2099. os << "No match for call of " << name << " with.\n";
  2100. stream_params(os, p);
  2101. bool saturated_match = false;
  2102. for (auto& m : saturated_list)
  2103. {
  2104. if (m.matches(p))
  2105. {
  2106. if (!saturated_match)
  2107. {
  2108. os << "\nMatches saturated call requirement\n";
  2109. saturated_match = true;
  2110. }
  2111. os << " ";
  2112. m.report_signature(os) << '\n';
  2113. }
  2114. }
  2115. if (!saturated_match)
  2116. {
  2117. for (auto& m : matcher_list)
  2118. {
  2119. os << "\nTried ";
  2120. m.report_mismatch(os, p);
  2121. }
  2122. }
  2123. send_report<specialized>(severity::fatal, location{}, os.str());
  2124. std::abort(); // must never get here.
  2125. }
  2126. template <typename Sig>
  2127. class return_handler
  2128. {
  2129. public:
  2130. virtual
  2131. ~return_handler() = default;
  2132. virtual
  2133. return_of_t<Sig>
  2134. call(
  2135. trace_agent&,
  2136. call_params_type_t<Sig>& params) = 0;
  2137. };
  2138. template <typename Ret, typename F, typename P, typename = std::enable_if_t<std::is_void<Ret>::value>>
  2139. void
  2140. trace_return(
  2141. trace_agent&,
  2142. F& func,
  2143. P& params)
  2144. {
  2145. func(params);
  2146. }
  2147. template <typename Ret, typename F, typename P, typename = std::enable_if_t<!std::is_void<Ret>::value>>
  2148. Ret
  2149. trace_return(
  2150. trace_agent& agent,
  2151. F& func,
  2152. P& params)
  2153. {
  2154. return agent.trace_return(func(params));
  2155. }
  2156. template <typename Sig, typename T>
  2157. class return_handler_t : public return_handler<Sig>
  2158. {
  2159. public:
  2160. template <typename U>
  2161. return_handler_t(
  2162. U&& u)
  2163. : func(std::forward<U>(u))
  2164. {}
  2165. return_of_t<Sig>
  2166. call(
  2167. trace_agent& agent,
  2168. call_params_type_t<Sig>& params)
  2169. override
  2170. {
  2171. return trace_return<return_of_t<Sig>>(agent, func, params);
  2172. }
  2173. private:
  2174. T func;
  2175. };
  2176. template<typename Sig>
  2177. class condition_base : public list_elem<condition_base<Sig> >
  2178. {
  2179. public:
  2180. condition_base(
  2181. char const *n)
  2182. noexcept
  2183. : id(n)
  2184. {}
  2185. virtual
  2186. ~condition_base() = default;
  2187. virtual
  2188. bool
  2189. check(
  2190. call_params_type_t<Sig> const&)
  2191. const = 0;
  2192. virtual
  2193. char const*
  2194. name()
  2195. const
  2196. noexcept
  2197. {
  2198. return id;
  2199. }
  2200. private:
  2201. char const *id;
  2202. };
  2203. template <typename Sig>
  2204. using condition_list = list<condition_base<Sig>, delete_disposer >;
  2205. template<typename Sig, typename Cond>
  2206. struct condition : public condition_base<Sig>
  2207. {
  2208. condition(
  2209. char const *str_,
  2210. Cond c_)
  2211. : condition_base<Sig>(str_)
  2212. , c(c_) {}
  2213. bool
  2214. check(
  2215. call_params_type_t<Sig> const & t)
  2216. const
  2217. override
  2218. {
  2219. return c(t);
  2220. }
  2221. private:
  2222. Cond c;
  2223. };
  2224. template<typename Sig>
  2225. struct side_effect_base : public list_elem<side_effect_base<Sig> >
  2226. {
  2227. virtual
  2228. ~side_effect_base() = default;
  2229. virtual
  2230. void
  2231. action(
  2232. call_params_type_t<Sig> &)
  2233. const = 0;
  2234. };
  2235. template<typename Sig>
  2236. using side_effect_list = list<side_effect_base<Sig>, delete_disposer>;
  2237. template<typename Sig, typename Action>
  2238. struct side_effect : public side_effect_base<Sig>
  2239. {
  2240. template <typename A>
  2241. side_effect(
  2242. A&& a_)
  2243. : a(std::forward<A>(a_))
  2244. {}
  2245. void
  2246. action(
  2247. call_params_type_t<Sig> &t)
  2248. const
  2249. override
  2250. {
  2251. a(t);
  2252. }
  2253. private:
  2254. Action a;
  2255. };
  2256. template <unsigned long long L, unsigned long long H = L>
  2257. struct multiplicity { };
  2258. template<typename R, typename Parent>
  2259. struct return_injector : Parent
  2260. {
  2261. using return_type = R;
  2262. };
  2263. template <typename Parent>
  2264. struct throw_injector : Parent
  2265. {
  2266. static bool const throws = true;
  2267. };
  2268. template <typename Parent>
  2269. struct sideeffect_injector : Parent
  2270. {
  2271. static bool const side_effects = true;
  2272. };
  2273. template <typename Parent, unsigned long long H>
  2274. struct call_limit_injector : Parent
  2275. {
  2276. static bool const call_limit_set = true;
  2277. static unsigned long long const upper_call_limit = H;
  2278. };
  2279. template <typename Parent>
  2280. struct call_limit_injector<Parent, 0ULL> : Parent
  2281. {
  2282. static bool const call_limit_set = true;
  2283. static unsigned long long const upper_call_limit = 0ULL;
  2284. };
  2285. template <typename Parent>
  2286. struct sequence_injector : Parent
  2287. {
  2288. static bool const sequence_set = true;
  2289. };
  2290. template <typename Matcher, typename modifier_tag, typename Parent>
  2291. struct call_modifier : public Parent
  2292. {
  2293. using typename Parent::signature;
  2294. using typename Parent::return_type;
  2295. using Parent::call_limit_set;
  2296. using Parent::upper_call_limit;
  2297. using Parent::sequence_set;
  2298. using Parent::throws;
  2299. using Parent::side_effects;
  2300. call_modifier(
  2301. Matcher* m)
  2302. noexcept
  2303. : matcher{m}
  2304. {}
  2305. template <typename D>
  2306. call_modifier&&
  2307. with(
  2308. char const* str,
  2309. D&& d)
  2310. &&
  2311. {
  2312. matcher->add_condition(str, std::forward<D>(d));
  2313. return std::move(*this);
  2314. }
  2315. template <typename A>
  2316. call_modifier<Matcher, modifier_tag, sideeffect_injector<Parent>>
  2317. sideeffect(
  2318. A&& a)
  2319. {
  2320. constexpr bool forbidden = upper_call_limit == 0U;
  2321. static_assert(!forbidden,
  2322. "SIDE_EFFECT for forbidden call does not make sense");
  2323. matcher->add_side_effect(std::forward<A>(a));
  2324. return {std::move(matcher)};
  2325. }
  2326. template <typename H>
  2327. call_modifier<Matcher, modifier_tag, return_injector<return_of_t<signature>, Parent >>
  2328. handle_return(
  2329. H&& h)
  2330. {
  2331. using params_type = call_params_type_t<signature>&;
  2332. using sigret = return_of_t<signature>;
  2333. using ret = decltype(std::declval<H>()(std::declval<params_type>()));
  2334. // don't know why MS VS 2015 RC doesn't like std::result_of
  2335. constexpr bool is_illegal_type = std::is_same<std::decay_t<ret>, illegal_argument>::value;
  2336. constexpr bool is_first_return = std::is_same<return_type, void>::value;
  2337. constexpr bool void_signature = std::is_same<sigret, void>::value;
  2338. constexpr bool is_pointer_sigret = std::is_pointer<sigret>::value;
  2339. constexpr bool is_pointer_ret = std::is_pointer<std::decay_t<ret>>::value;
  2340. constexpr bool ptr_const_mismatch = is_pointer_ret && is_pointer_sigret && !std::is_const<std::remove_pointer_t<sigret>>{} && std::is_const<std::remove_pointer_t<std::decay_t<ret>>>{};
  2341. constexpr bool is_ref_sigret = std::is_reference<sigret>::value;
  2342. constexpr bool is_ref_ret = std::is_reference<ret>::value;
  2343. constexpr bool ref_const_mismatch=
  2344. is_ref_ret &&
  2345. is_ref_sigret &&
  2346. !std::is_const<std::remove_reference_t<sigret>>::value &&
  2347. std::is_const<std::remove_reference_t<ret>>::value;
  2348. constexpr bool matching_ret_type = std::is_constructible<sigret, ret>::value;
  2349. constexpr bool ref_value_mismatch = !is_ref_ret && is_ref_sigret;
  2350. static_assert(matching_ret_type || !void_signature,
  2351. "RETURN does not make sense for void-function");
  2352. static_assert(!is_illegal_type,
  2353. "RETURN illegal argument");
  2354. static_assert(!ptr_const_mismatch,
  2355. "RETURN const* from function returning pointer to non-const");
  2356. static_assert(!ref_value_mismatch || matching_ret_type,
  2357. "RETURN non-reference from function returning reference");
  2358. static_assert(ref_value_mismatch || !ref_const_mismatch,
  2359. "RETURN const& from function returning non-const reference");
  2360. static_assert(ptr_const_mismatch || ref_const_mismatch || is_illegal_type || matching_ret_type || void_signature,
  2361. "RETURN value is not convertible to the return type of the function");
  2362. static_assert(is_first_return,
  2363. "Multiple RETURN does not make sense");
  2364. static_assert(!throws || upper_call_limit == 0,
  2365. "THROW and RETURN does not make sense");
  2366. static_assert(upper_call_limit > 0ULL,
  2367. "RETURN for forbidden call does not make sense");
  2368. constexpr bool valid = !is_illegal_type && matching_ret_type && is_first_return && !throws && upper_call_limit > 0ULL;
  2369. using tag = std::integral_constant<bool, valid>;
  2370. matcher->set_return(tag{}, std::forward<H>(h));
  2371. return {matcher};
  2372. }
  2373. template <typename H>
  2374. call_modifier<Matcher, modifier_tag, throw_injector<Parent> >
  2375. handle_throw(
  2376. H&& h)
  2377. {
  2378. static_assert(!throws,
  2379. "Multiple THROW does not make sense");
  2380. constexpr bool has_return = !std::is_same<return_type, void>::value;
  2381. static_assert(!has_return,
  2382. "THROW and RETURN does not make sense");
  2383. constexpr bool forbidden = upper_call_limit == 0U;
  2384. static_assert(!forbidden,
  2385. "THROW for forbidden call does not make sense");
  2386. constexpr bool valid = !throws && !has_return;// && !forbidden;
  2387. using tag = std::integral_constant<bool, valid>;
  2388. auto handler = [=](auto& p) -> decltype(auto)
  2389. {
  2390. h(p);
  2391. return trompeloeil::default_return<return_of_t<signature>>();
  2392. };
  2393. matcher->set_return(tag{}, std::move(handler));
  2394. return {matcher};
  2395. }
  2396. template <unsigned long long L,
  2397. unsigned long long H,
  2398. bool times_set = call_limit_set>
  2399. call_modifier<Matcher, modifier_tag, call_limit_injector<Parent, H>>
  2400. times(
  2401. multiplicity<L, H>)
  2402. {
  2403. static_assert(!times_set,
  2404. "Only one TIMES call limit is allowed, but it can express an interval");
  2405. static_assert(H >= L,
  2406. "In TIMES the first value must not exceed the second");
  2407. static_assert(H > 0 || !throws,
  2408. "THROW and TIMES(0) does not make sense");
  2409. static_assert(H > 0 || std::is_same<return_type, void>::value,
  2410. "RETURN and TIMES(0) does not make sense");
  2411. static_assert(H > 0 || !side_effects,
  2412. "SIDE_EFFECT and TIMES(0) does not make sense");
  2413. static_assert(H > 0 || !sequence_set,
  2414. "IN_SEQUENCE and TIMES(0) does not make sense");
  2415. matcher->min_calls = L;
  2416. matcher->max_calls = H;
  2417. return {matcher};
  2418. }
  2419. template <typename ... T,
  2420. bool b = sequence_set>
  2421. call_modifier<Matcher, modifier_tag, sequence_injector<Parent>>
  2422. in_sequence(
  2423. T&& ... t)
  2424. {
  2425. static_assert(!b,
  2426. "Multiple IN_SEQUENCE does not make sense."
  2427. " You can list several sequence objects at once");
  2428. static_assert(upper_call_limit > 0ULL,
  2429. "IN_SEQUENCE for forbidden call does not make sense");
  2430. matcher->set_sequence(std::forward<T>(t)...);
  2431. return {matcher};
  2432. }
  2433. Matcher* matcher;
  2434. };
  2435. inline
  2436. void
  2437. report_unfulfilled(
  2438. const char* reason,
  2439. char const *name,
  2440. std::string const &values,
  2441. unsigned long long min_calls,
  2442. unsigned long long call_count,
  2443. location loc)
  2444. {
  2445. std::ostringstream os;
  2446. os << reason
  2447. << ":\nExpected " << name << " to be called ";
  2448. if (min_calls == 1)
  2449. os << "once";
  2450. else
  2451. os << min_calls << " times";
  2452. os << ", actually ";
  2453. switch (call_count)
  2454. {
  2455. case 0:
  2456. os << "never called\n"; break;
  2457. case 1:
  2458. os << "called once\n"; break;
  2459. default:
  2460. os << "called " << call_count << " times\n";
  2461. }
  2462. os << values;
  2463. send_report<specialized>(severity::nonfatal, loc, os.str());
  2464. }
  2465. inline
  2466. void
  2467. report_forbidden_call(
  2468. char const *name,
  2469. location loc,
  2470. std::string const& values)
  2471. {
  2472. std::ostringstream os;
  2473. os << "Match of forbidden call of " << name
  2474. << " at " << loc << '\n' << values;
  2475. send_report<specialized>(severity::fatal, loc, os.str());
  2476. }
  2477. template <typename Sig>
  2478. struct matcher_info
  2479. {
  2480. using signature = Sig;
  2481. using return_type = void;
  2482. static unsigned long long const upper_call_limit = 1;
  2483. static bool const throws = false;
  2484. static bool const call_limit_set = false;
  2485. static bool const sequence_set = false;
  2486. static bool const side_effects = false;
  2487. };
  2488. template<typename Sig, typename Value>
  2489. struct call_matcher : public call_matcher_base<Sig>, expectation
  2490. {
  2491. using call_matcher_base<Sig>::name;
  2492. using call_matcher_base<Sig>::loc;
  2493. template<typename ... U>
  2494. call_matcher(
  2495. char const *file,
  2496. unsigned long line,
  2497. char const *call_string,
  2498. U &&... u)
  2499. : call_matcher_base<Sig>(location{file, line}, call_string)
  2500. , val(std::forward<U>(u)...)
  2501. {}
  2502. call_matcher(call_matcher &&r) = delete;
  2503. ~call_matcher()
  2504. {
  2505. auto lock = get_lock();
  2506. if (is_unfulfilled())
  2507. {
  2508. report_missed("Unfulfilled expectation");
  2509. }
  2510. this->unlink();
  2511. }
  2512. bool
  2513. is_satisfied()
  2514. const
  2515. noexcept
  2516. override
  2517. {
  2518. auto lock = get_lock();
  2519. return call_count >= min_calls;
  2520. }
  2521. bool
  2522. is_saturated()
  2523. const
  2524. noexcept
  2525. override
  2526. {
  2527. auto lock = get_lock();
  2528. return call_count >= max_calls;
  2529. }
  2530. bool
  2531. is_unfulfilled()
  2532. const
  2533. noexcept
  2534. {
  2535. return !reported && this->is_linked() && call_count < min_calls;
  2536. }
  2537. void
  2538. mock_destroyed()
  2539. override
  2540. {
  2541. if (is_unfulfilled())
  2542. {
  2543. report_missed("Pending expectation on destroyed mock object");
  2544. }
  2545. }
  2546. call_matcher*
  2547. hook_last(
  2548. call_matcher_list<Sig> &list)
  2549. noexcept
  2550. {
  2551. list.push_front(this);
  2552. return this;
  2553. }
  2554. bool
  2555. matches(
  2556. call_params_type_t<Sig> const& params)
  2557. const
  2558. override
  2559. {
  2560. return match_parameters(val, params) && match_conditions(params);
  2561. }
  2562. bool
  2563. match_conditions(
  2564. call_params_type_t<Sig> const & params)
  2565. const
  2566. {
  2567. // std::all_of() is almost always preferable. The only reason
  2568. // for using a hand rolled loop is because it cuts compilation
  2569. // times quite noticeably (almost 10% with g++5.1)
  2570. for (auto& c : conditions)
  2571. {
  2572. if (!c.check(params)) return false;
  2573. }
  2574. return true;
  2575. }
  2576. bool
  2577. first_in_sequence()
  2578. const
  2579. noexcept
  2580. override
  2581. {
  2582. auto saturated = call_count >= min_calls;
  2583. return saturated || !sequences || sequences->is_first();
  2584. }
  2585. return_of_t<Sig>
  2586. return_value(
  2587. trace_agent& agent,
  2588. call_params_type_t<Sig>& params)
  2589. override
  2590. {
  2591. if (!return_handler_obj) return default_return<return_of_t<Sig>>();
  2592. return return_handler_obj->call(agent, params);
  2593. }
  2594. void
  2595. run_actions(
  2596. call_params_type_t<Sig>& params,
  2597. call_matcher_list<Sig> &saturated_list)
  2598. override
  2599. {
  2600. if (max_calls == 0)
  2601. {
  2602. reported = true;
  2603. report_forbidden_call(name, loc, params_string(params));
  2604. }
  2605. auto lock = get_lock();
  2606. {
  2607. if (call_count < min_calls && sequences)
  2608. {
  2609. sequences->validate(severity::fatal, name, loc);
  2610. }
  2611. if (++call_count == min_calls && sequences)
  2612. {
  2613. sequences->retire();
  2614. }
  2615. if (call_count == max_calls)
  2616. {
  2617. this->unlink();
  2618. saturated_list.push_back(this);
  2619. }
  2620. }
  2621. for (auto& a : actions) a.action(params);
  2622. }
  2623. std::ostream&
  2624. report_signature(
  2625. std::ostream& os)
  2626. const override
  2627. {
  2628. return os << name << " at " << loc;
  2629. }
  2630. std::ostream&
  2631. report_mismatch(
  2632. std::ostream& os,
  2633. call_params_type_t<Sig> const & params)
  2634. override
  2635. {
  2636. reported = true;
  2637. report_signature(os);
  2638. if (match_parameters(val, params))
  2639. {
  2640. for (auto& cond : conditions)
  2641. {
  2642. if (!cond.check(params))
  2643. {
  2644. os << "\n Failed WITH(" << cond.name() << ')';
  2645. }
  2646. }
  2647. }
  2648. else
  2649. {
  2650. os << '\n';
  2651. ::trompeloeil::print_mismatch(os, val, params);
  2652. }
  2653. return os;
  2654. }
  2655. void
  2656. report_missed(
  2657. char const *reason)
  2658. override
  2659. {
  2660. reported = true;
  2661. report_unfulfilled(
  2662. reason,
  2663. name,
  2664. params_string(val),
  2665. min_calls,
  2666. call_count,
  2667. loc);
  2668. }
  2669. template <typename C>
  2670. void
  2671. add_condition(
  2672. char const *str,
  2673. C&& c)
  2674. {
  2675. auto cond = new condition<Sig, C>(str, std::forward<C>(c));
  2676. conditions.push_back(cond);
  2677. }
  2678. template <typename S>
  2679. void
  2680. add_side_effect(
  2681. S&& s)
  2682. {
  2683. auto effect = new side_effect<Sig, S>(std::forward<S>(s));
  2684. actions.push_back(effect);
  2685. }
  2686. template <typename ... T>
  2687. void
  2688. set_sequence(
  2689. T&& ... t)
  2690. {
  2691. auto seq = new sequence_handler<sizeof...(T)>(name,
  2692. loc,
  2693. std::forward<T>(t)...);
  2694. sequences.reset(seq);
  2695. }
  2696. template <typename T>
  2697. inline
  2698. void
  2699. set_return(
  2700. std::true_type,
  2701. T&& h)
  2702. {
  2703. using basic_t = typename std::remove_reference<T>::type;
  2704. using handler = return_handler_t<Sig, basic_t>;
  2705. return_handler_obj.reset(new handler(std::forward<T>(h)));
  2706. }
  2707. template <typename T>
  2708. inline // Never called. Used to limit errmsg
  2709. static // with RETURN of wrong type and after:
  2710. void // FORBIDDEN_CALL
  2711. set_return(std::false_type, T&&t)// RETURN
  2712. noexcept; // THROW
  2713. condition_list<Sig> conditions;
  2714. side_effect_list<Sig> actions;
  2715. std::unique_ptr<return_handler<Sig>> return_handler_obj;
  2716. std::unique_ptr<sequence_handler_base> sequences;
  2717. unsigned long long call_count = 0;
  2718. std::atomic<unsigned long long> min_calls{1};
  2719. std::atomic<unsigned long long> max_calls{1};
  2720. Value val;
  2721. bool reported = false;
  2722. };
  2723. template<int N, typename T>
  2724. constexpr
  2725. inline
  2726. decltype(auto)
  2727. arg(
  2728. T* t,
  2729. std::true_type)
  2730. {
  2731. return std::get<N-1>(*t);
  2732. }
  2733. template <int N>
  2734. inline
  2735. constexpr
  2736. illegal_argument const
  2737. arg(
  2738. void const*,
  2739. std::false_type)
  2740. noexcept
  2741. {
  2742. return {};
  2743. }
  2744. template <int N, typename T>
  2745. decltype(auto)
  2746. mkarg(
  2747. T& t)
  2748. noexcept
  2749. {
  2750. return arg<N>(&t, std::integral_constant<bool, (N <= std::tuple_size<T>::value)>{});
  2751. }
  2752. template <typename Mock>
  2753. struct call_validator_t
  2754. {
  2755. template <typename M, typename Tag, typename Info>
  2756. auto
  2757. make_expectation(
  2758. std::true_type,
  2759. call_modifier<M, Tag, Info>&& m)
  2760. const
  2761. noexcept
  2762. {
  2763. auto lock = get_lock();
  2764. m.matcher->hook_last(obj.trompeloeil_matcher_list(static_cast<Tag*>(nullptr)));
  2765. return std::unique_ptr<expectation>(m.matcher);
  2766. }
  2767. template <typename T>
  2768. static // Never called. Used to
  2769. std::unique_ptr<expectation> // limit errmsg when RETURN
  2770. make_expectation(std::false_type, T&&) noexcept; // is missing in non-void
  2771. // function
  2772. template <typename M, typename Tag, typename Info>
  2773. inline
  2774. auto
  2775. operator+(
  2776. call_modifier<M, Tag, Info>&& t)
  2777. const
  2778. {
  2779. using call = call_modifier<M, Tag, Info>;
  2780. using sigret = return_of_t<typename call::signature>;
  2781. using ret = typename call::return_type;
  2782. constexpr bool retmatch = std::is_same<ret, sigret>::value;
  2783. constexpr bool forbidden = call::upper_call_limit == 0ULL;
  2784. constexpr bool valid_return_type = call::throws || retmatch || forbidden;
  2785. static_assert(valid_return_type, "RETURN missing for non-void function");
  2786. auto tag = std::integral_constant<bool, valid_return_type>{};
  2787. return make_expectation(tag, std::move(t));
  2788. }
  2789. Mock& obj;
  2790. };
  2791. template <typename T,
  2792. typename = std::enable_if_t<std::is_lvalue_reference<T&&>::value>>
  2793. inline
  2794. T&&
  2795. decay_return_type(
  2796. T&& t)
  2797. {
  2798. return std::forward<T>(t);
  2799. }
  2800. template <typename T,
  2801. typename = std::enable_if_t<std::is_rvalue_reference<T&&>::value>>
  2802. inline
  2803. T
  2804. decay_return_type(
  2805. T&& t)
  2806. {
  2807. return std::forward<T>(t);
  2808. }
  2809. template <typename T, size_t N>
  2810. inline
  2811. T*
  2812. decay_return_type(
  2813. T (&t)[N])
  2814. {
  2815. return t;
  2816. }
  2817. template <bool sequence_set>
  2818. struct lifetime_monitor_modifier
  2819. {
  2820. operator std::unique_ptr<lifetime_monitor>() { return std::move(monitor);}
  2821. template <typename ... T, bool b = sequence_set>
  2822. lifetime_monitor_modifier<true>
  2823. in_sequence(T&& ... t)
  2824. {
  2825. static_assert(!b,
  2826. "Multiple IN_SEQUENCE does not make sense."
  2827. " You can list several sequence objects at once");
  2828. monitor->set_sequence(std::forward<T>(t)...);
  2829. return { std::move(monitor) };
  2830. }
  2831. std::unique_ptr<lifetime_monitor> monitor;
  2832. };
  2833. struct lifetime_monitor_releaser
  2834. {
  2835. template <bool b>
  2836. std::unique_ptr<trompeloeil::lifetime_monitor>
  2837. operator+(
  2838. lifetime_monitor_modifier<b>&& m)
  2839. const
  2840. {
  2841. return m;
  2842. }
  2843. };
  2844. template <typename Sig>
  2845. struct expectations
  2846. {
  2847. ~expectations() {
  2848. active.decommission();
  2849. saturated.decommission();
  2850. }
  2851. call_matcher_list<Sig> active;
  2852. call_matcher_list<Sig> saturated;
  2853. };
  2854. template <typename Sig, typename ... P>
  2855. return_of_t<Sig> mock_func(std::false_type, P&& ...);
  2856. template <typename Sig, typename ... P>
  2857. return_of_t<Sig>
  2858. mock_func(std::true_type,
  2859. expectations<Sig>& e,
  2860. char const *func_name,
  2861. char const *sig_name,
  2862. P&& ... p)
  2863. {
  2864. auto lock = get_lock();
  2865. call_params_type_t<void(P...)> param_value(std::forward<P>(p)...);
  2866. auto i = find(e.active, param_value);
  2867. if (!i)
  2868. {
  2869. report_mismatch(e.active,
  2870. e.saturated,
  2871. func_name + std::string(" with signature ") + sig_name,
  2872. param_value);
  2873. }
  2874. trace_agent ta{i->loc, i->name, tracer_obj()};
  2875. try
  2876. {
  2877. ta.trace_params(param_value);
  2878. i->run_actions(param_value, e.saturated);
  2879. return i->return_value(ta, param_value);
  2880. }
  2881. catch (...)
  2882. {
  2883. ta.trace_exception();
  2884. throw;
  2885. }
  2886. }
  2887. template <typename ... U>
  2888. struct param_helper {
  2889. using type = decltype(std::make_tuple(std::declval<U>()...));
  2890. };
  2891. template <typename ... U>
  2892. using param_t = typename param_helper<U...>::type;
  2893. template <typename sig, typename tag, typename... U>
  2894. using modifier_t = call_modifier<call_matcher<sig, param_t<U...>>,
  2895. tag,
  2896. matcher_info<sig>>;
  2897. template <typename M,
  2898. typename = std::enable_if_t<::trompeloeil::is_matcher<M>::value>>
  2899. inline
  2900. ::trompeloeil::ptr_deref<std::decay_t<M>>
  2901. operator*(
  2902. M&& m)
  2903. {
  2904. return ::trompeloeil::ptr_deref<std::decay_t<M>>{std::forward<M>(m)};
  2905. }
  2906. template <typename M,
  2907. typename = std::enable_if_t<::trompeloeil::is_matcher<M>::value>>
  2908. inline
  2909. ::trompeloeil::neg_matcher<std::decay_t<M>>
  2910. operator!(
  2911. M&& m)
  2912. {
  2913. return ::trompeloeil::neg_matcher<std::decay_t<M>>{std::forward<M>(m)};
  2914. }
  2915. }
  2916. #define TROMPELOEIL_LINE_ID(name) \
  2917. TROMPELOEIL_CONCAT(trompeloeil_l_ ## name ## _, __LINE__)
  2918. #define TROMPELOEIL_COUNT_ID(name) \
  2919. TROMPELOEIL_CONCAT(trompeloeil_c_ ## name ## _, __COUNTER__)
  2920. #ifdef _MSC_VER
  2921. #define TROMPELOEIL_MAKE_MOCK0(name, sig, ...) \
  2922. TROMPELOEIL_MAKE_MOCK_(name,,0, sig, __VA_ARGS__,,)
  2923. #define TROMPELOEIL_MAKE_MOCK1(name, sig, ...) \
  2924. TROMPELOEIL_MAKE_MOCK_(name,,1, sig, __VA_ARGS__,,)
  2925. #define TROMPELOEIL_MAKE_MOCK2(name, sig, ...) \
  2926. TROMPELOEIL_MAKE_MOCK_(name,,2, sig, __VA_ARGS__,,)
  2927. #define TROMPELOEIL_MAKE_MOCK3(name, sig, ...) \
  2928. TROMPELOEIL_MAKE_MOCK_(name,,3, sig, __VA_ARGS__,,)
  2929. #define TROMPELOEIL_MAKE_MOCK4(name, sig, ...) \
  2930. TROMPELOEIL_MAKE_MOCK_(name,,4, sig, __VA_ARGS__,,)
  2931. #define TROMPELOEIL_MAKE_MOCK5(name, sig, ...) \
  2932. TROMPELOEIL_MAKE_MOCK_(name,,5, sig, __VA_ARGS__,,)
  2933. #define TROMPELOEIL_MAKE_MOCK6(name, sig, ...) \
  2934. TROMPELOEIL_MAKE_MOCK_(name,,6, sig, __VA_ARGS__,,)
  2935. #define TROMPELOEIL_MAKE_MOCK7(name, sig, ...) \
  2936. TROMPELOEIL_MAKE_MOCK_(name,,7, sig, __VA_ARGS__,,)
  2937. #define TROMPELOEIL_MAKE_MOCK8(name, sig, ...) \
  2938. TROMPELOEIL_MAKE_MOCK_(name,,8, sig, __VA_ARGS__,,)
  2939. #define TROMPELOEIL_MAKE_MOCK9(name, sig, ...) \
  2940. TROMPELOEIL_MAKE_MOCK_(name,,9, sig, __VA_ARGS__,,)
  2941. #define TROMPELOEIL_MAKE_MOCK10(name, sig, ...) \
  2942. TROMPELOEIL_MAKE_MOCK_(name,,10, sig, __VA_ARGS__,,)
  2943. #define TROMPELOEIL_MAKE_MOCK11(name, sig, ...) \
  2944. TROMPELOEIL_MAKE_MOCK_(name,,11, sig, __VA_ARGS__,,)
  2945. #define TROMPELOEIL_MAKE_MOCK12(name, sig, ...) \
  2946. TROMPELOEIL_MAKE_MOCK_(name,,12, sig, __VA_ARGS__,,)
  2947. #define TROMPELOEIL_MAKE_MOCK13(name, sig, ...) \
  2948. TROMPELOEIL_MAKE_MOCK_(name,,13, sig, __VA_ARGS__,,)
  2949. #define TROMPELOEIL_MAKE_MOCK14(name, sig, ...) \
  2950. TROMPELOEIL_MAKE_MOCK_(name,,14, sig, __VA_ARGS__,,)
  2951. #define TROMPELOEIL_MAKE_MOCK15(name, sig, ...) \
  2952. TROMPELOEIL_MAKE_MOCK_(name,,15, sig, __VA_ARGS__,,)
  2953. #define TROMPELOEIL_MAKE_CONST_MOCK0(name, sig, ...) \
  2954. TROMPELOEIL_MAKE_MOCK_(name,const,0, sig, __VA_ARGS__,,)
  2955. #define TROMPELOEIL_MAKE_CONST_MOCK1(name, sig, ...) \
  2956. TROMPELOEIL_MAKE_MOCK_(name,const,1, sig, __VA_ARGS__,,)
  2957. #define TROMPELOEIL_MAKE_CONST_MOCK2(name, sig, ...) \
  2958. TROMPELOEIL_MAKE_MOCK_(name,const,2, sig, __VA_ARGS__,,)
  2959. #define TROMPELOEIL_MAKE_CONST_MOCK3(name, sig, ...) \
  2960. TROMPELOEIL_MAKE_MOCK_(name,const,3, sig, __VA_ARGS__,,)
  2961. #define TROMPELOEIL_MAKE_CONST_MOCK4(name, sig, ...) \
  2962. TROMPELOEIL_MAKE_MOCK_(name,const,4, sig, __VA_ARGS__,,)
  2963. #define TROMPELOEIL_MAKE_CONST_MOCK5(name, sig, ...) \
  2964. TROMPELOEIL_MAKE_MOCK_(name,const,5, sig, __VA_ARGS__,,)
  2965. #define TROMPELOEIL_MAKE_CONST_MOCK6(name, sig, ...) \
  2966. TROMPELOEIL_MAKE_MOCK_(name,const,6, sig, __VA_ARGS__,,)
  2967. #define TROMPELOEIL_MAKE_CONST_MOCK7(name, sig, ...) \
  2968. TROMPELOEIL_MAKE_MOCK_(name,const,7, sig, __VA_ARGS__,,)
  2969. #define TROMPELOEIL_MAKE_CONST_MOCK8(name, sig, ...) \
  2970. TROMPELOEIL_MAKE_MOCK_(name,const,8, sig, __VA_ARGS__,,)
  2971. #define TROMPELOEIL_MAKE_CONST_MOCK9(name, sig, ...) \
  2972. TROMPELOEIL_MAKE_MOCK_(name,const,9, sig, __VA_ARGS__,,)
  2973. #define TROMPELOEIL_MAKE_CONST_MOCK10(name, sig, ...) \
  2974. TROMPELOEIL_MAKE_MOCK_(name,const,10, sig, __VA_ARGS__,,)
  2975. #define TROMPELOEIL_MAKE_CONST_MOCK11(name, sig, ...) \
  2976. TROMPELOEIL_MAKE_MOCK_(name,const,11, sig, __VA_ARGS__,,)
  2977. #define TROMPELOEIL_MAKE_CONST_MOCK12(name, sig, ...) \
  2978. TROMPELOEIL_MAKE_MOCK_(name,const,12, sig, __VA_ARGS__,,)
  2979. #define TROMPELOEIL_MAKE_CONST_MOCK13(name, sig, ...) \
  2980. TROMPELOEIL_MAKE_MOCK_(name,const,13, sig, __VA_ARGS__,,)
  2981. #define TROMPELOEIL_MAKE_CONST_MOCK14(name, sig, ...) \
  2982. TROMPELOEIL_MAKE_MOCK_(name,const,14, sig, __VA_ARGS__,,)
  2983. #define TROMPELOEIL_MAKE_CONST_MOCK15(name, sig, ...) \
  2984. TROMPELOEIL_MAKE_MOCK_(name,const,15, sig, __VA_ARGS__,,)
  2985. #else
  2986. // sane standards compliant preprocessor
  2987. #define TROMPELOEIL_MAKE_MOCK0(name, ...) \
  2988. TROMPELOEIL_MAKE_MOCK_(name,,0, __VA_ARGS__,,)
  2989. #define TROMPELOEIL_MAKE_MOCK1(name, ...) \
  2990. TROMPELOEIL_MAKE_MOCK_(name,,1, __VA_ARGS__,,)
  2991. #define TROMPELOEIL_MAKE_MOCK2(name, ...) \
  2992. TROMPELOEIL_MAKE_MOCK_(name,,2, __VA_ARGS__,,)
  2993. #define TROMPELOEIL_MAKE_MOCK3(name, ...) \
  2994. TROMPELOEIL_MAKE_MOCK_(name,,3, __VA_ARGS__,,)
  2995. #define TROMPELOEIL_MAKE_MOCK4(name, ...) \
  2996. TROMPELOEIL_MAKE_MOCK_(name,,4, __VA_ARGS__,,)
  2997. #define TROMPELOEIL_MAKE_MOCK5(name, ...) \
  2998. TROMPELOEIL_MAKE_MOCK_(name,,5, __VA_ARGS__,,)
  2999. #define TROMPELOEIL_MAKE_MOCK6(name, ...) \
  3000. TROMPELOEIL_MAKE_MOCK_(name,,6, __VA_ARGS__,,)
  3001. #define TROMPELOEIL_MAKE_MOCK7(name, ...) \
  3002. TROMPELOEIL_MAKE_MOCK_(name,,7, __VA_ARGS__,,)
  3003. #define TROMPELOEIL_MAKE_MOCK8(name, ...) \
  3004. TROMPELOEIL_MAKE_MOCK_(name,,8, __VA_ARGS__,,)
  3005. #define TROMPELOEIL_MAKE_MOCK9(name, ...) \
  3006. TROMPELOEIL_MAKE_MOCK_(name,,9, __VA_ARGS__,,)
  3007. #define TROMPELOEIL_MAKE_MOCK10(name, ...) \
  3008. TROMPELOEIL_MAKE_MOCK_(name,,10, __VA_ARGS__,,)
  3009. #define TROMPELOEIL_MAKE_MOCK11(name, ...) \
  3010. TROMPELOEIL_MAKE_MOCK_(name,,11, __VA_ARGS__,,)
  3011. #define TROMPELOEIL_MAKE_MOCK12(name, ...) \
  3012. TROMPELOEIL_MAKE_MOCK_(name,,12, __VA_ARGS__,,)
  3013. #define TROMPELOEIL_MAKE_MOCK13(name, ...) \
  3014. TROMPELOEIL_MAKE_MOCK_(name,,13, __VA_ARGS__,,)
  3015. #define TROMPELOEIL_MAKE_MOCK14(name, ...) \
  3016. TROMPELOEIL_MAKE_MOCK_(name,,14,__VA_ARGS__,,)
  3017. #define TROMPELOEIL_MAKE_MOCK15(name, ...) \
  3018. TROMPELOEIL_MAKE_MOCK_(name,,15, __VA_ARGS__,,)
  3019. #define TROMPELOEIL_MAKE_CONST_MOCK0(name, ...) \
  3020. TROMPELOEIL_MAKE_MOCK_(name,const,0, __VA_ARGS__,,)
  3021. #define TROMPELOEIL_MAKE_CONST_MOCK1(name, ...) \
  3022. TROMPELOEIL_MAKE_MOCK_(name,const,1, __VA_ARGS__,,)
  3023. #define TROMPELOEIL_MAKE_CONST_MOCK2(name, ...) \
  3024. TROMPELOEIL_MAKE_MOCK_(name,const,2, __VA_ARGS__,,)
  3025. #define TROMPELOEIL_MAKE_CONST_MOCK3(name, ...) \
  3026. TROMPELOEIL_MAKE_MOCK_(name,const,3, __VA_ARGS__,,)
  3027. #define TROMPELOEIL_MAKE_CONST_MOCK4(name, ...) \
  3028. TROMPELOEIL_MAKE_MOCK_(name,const,4, __VA_ARGS__,,)
  3029. #define TROMPELOEIL_MAKE_CONST_MOCK5(name, ...) \
  3030. TROMPELOEIL_MAKE_MOCK_(name,const,5, __VA_ARGS__,,)
  3031. #define TROMPELOEIL_MAKE_CONST_MOCK6(name, ...) \
  3032. TROMPELOEIL_MAKE_MOCK_(name,const,6, __VA_ARGS__,,)
  3033. #define TROMPELOEIL_MAKE_CONST_MOCK7(name, ...) \
  3034. TROMPELOEIL_MAKE_MOCK_(name,const,7, __VA_ARGS__,,)
  3035. #define TROMPELOEIL_MAKE_CONST_MOCK8(name, ...) \
  3036. TROMPELOEIL_MAKE_MOCK_(name,const,8, __VA_ARGS__,,)
  3037. #define TROMPELOEIL_MAKE_CONST_MOCK9(name, ...) \
  3038. TROMPELOEIL_MAKE_MOCK_(name,const,9, __VA_ARGS__,,)
  3039. #define TROMPELOEIL_MAKE_CONST_MOCK10(name, ...) \
  3040. TROMPELOEIL_MAKE_MOCK_(name,const,10, __VA_ARGS__,,)
  3041. #define TROMPELOEIL_MAKE_CONST_MOCK11(name, ...) \
  3042. TROMPELOEIL_MAKE_MOCK_(name,const,11, __VA_ARGS__,,)
  3043. #define TROMPELOEIL_MAKE_CONST_MOCK12(name, ...) \
  3044. TROMPELOEIL_MAKE_MOCK_(name,const,12, __VA_ARGS__,,)
  3045. #define TROMPELOEIL_MAKE_CONST_MOCK13(name, ...) \
  3046. TROMPELOEIL_MAKE_MOCK_(name,const,13, __VA_ARGS__,,)
  3047. #define TROMPELOEIL_MAKE_CONST_MOCK14(name, ...) \
  3048. TROMPELOEIL_MAKE_MOCK_(name,const,14, __VA_ARGS__,,)
  3049. #define TROMPELOEIL_MAKE_CONST_MOCK15(name, ...) \
  3050. TROMPELOEIL_MAKE_MOCK_(name,const,15, __VA_ARGS__,,)
  3051. #endif
  3052. #define TROMPELOEIL_MAKE_MOCK_(name, constness, num, sig, spec, ...) \
  3053. using TROMPELOEIL_LINE_ID(cardinality_match) = \
  3054. std::integral_constant<bool, num == ::trompeloeil::param_list<sig>::size>; \
  3055. static_assert(TROMPELOEIL_LINE_ID(cardinality_match)::value, \
  3056. "Function signature does not have " #num " parameters"); \
  3057. using TROMPELOEIL_LINE_ID(matcher_list_t) = ::trompeloeil::call_matcher_list<sig>;\
  3058. using TROMPELOEIL_LINE_ID(expectation_list_t) = ::trompeloeil::expectations<sig>; \
  3059. mutable TROMPELOEIL_LINE_ID(expectation_list_t) TROMPELOEIL_LINE_ID(expectations);\
  3060. struct TROMPELOEIL_LINE_ID(tag_type_trompeloeil) \
  3061. { \
  3062. const char* trompeloeil_expectation_file; \
  3063. unsigned long trompeloeil_expectation_line; \
  3064. const char *trompeloeil_expectation_string; \
  3065. \
  3066. template <typename ... trompeloeil_param_type> \
  3067. auto name( \
  3068. trompeloeil_param_type&& ... trompeloeil_param) \
  3069. -> ::trompeloeil::modifier_t<sig, \
  3070. TROMPELOEIL_LINE_ID(tag_type_trompeloeil), \
  3071. trompeloeil_param_type...> \
  3072. { \
  3073. using matcher = ::trompeloeil::call_matcher< \
  3074. sig, \
  3075. ::trompeloeil::param_t<trompeloeil_param_type...>>; \
  3076. return { \
  3077. new matcher { \
  3078. trompeloeil_expectation_file, \
  3079. trompeloeil_expectation_line, \
  3080. trompeloeil_expectation_string, \
  3081. std::forward<trompeloeil_param_type>(trompeloeil_param)... \
  3082. } \
  3083. }; \
  3084. } \
  3085. }; \
  3086. \
  3087. TROMPELOEIL_LINE_ID(matcher_list_t)& \
  3088. trompeloeil_matcher_list( \
  3089. TROMPELOEIL_LINE_ID(tag_type_trompeloeil)*) \
  3090. constness \
  3091. noexcept \
  3092. { \
  3093. return TROMPELOEIL_LINE_ID(expectations).active; \
  3094. } \
  3095. ::trompeloeil::return_of_t<sig> \
  3096. name( \
  3097. TROMPELOEIL_PARAM_LIST(num, sig)) \
  3098. constness \
  3099. spec \
  3100. { \
  3101. return ::trompeloeil::mock_func<sig>(TROMPELOEIL_LINE_ID(cardinality_match){}, \
  3102. TROMPELOEIL_LINE_ID(expectations), \
  3103. #name, \
  3104. #sig \
  3105. TROMPELOEIL_PARAMS(num)); \
  3106. } \
  3107. \
  3108. auto \
  3109. trompeloeil_self_ ## name(TROMPELOEIL_PARAM_LIST(num, sig)) constness \
  3110. -> decltype(*this); \
  3111. \
  3112. TROMPELOEIL_LINE_ID(tag_type_trompeloeil) \
  3113. trompeloeil_tag_ ## name(TROMPELOEIL_PARAM_LIST(num, sig)) constness
  3114. #define TROMPELOEIL_REQUIRE_CALL(obj, func) \
  3115. TROMPELOEIL_REQUIRE_CALL_(obj, func, #obj, #func)
  3116. #define TROMPELOEIL_REQUIRE_CALL_(obj, func, obj_s, func_s) \
  3117. auto TROMPELOEIL_COUNT_ID(call_obj) = TROMPELOEIL_REQUIRE_CALL_OBJ(obj, func,\
  3118. obj_s, func_s)
  3119. #define TROMPELOEIL_NAMED_REQUIRE_CALL(obj, func) \
  3120. TROMPELOEIL_NAMED_REQUIRE_CALL_(obj, func, #obj, #func)
  3121. #define TROMPELOEIL_NAMED_REQUIRE_CALL_(obj, func, obj_s, func_s) \
  3122. TROMPELOEIL_REQUIRE_CALL_OBJ(obj, func, obj_s, func_s)
  3123. #define TROMPELOEIL_REQUIRE_CALL_OBJ(obj, func, obj_s, func_s) \
  3124. ::trompeloeil::call_validator_t<decltype((obj).TROMPELOEIL_CONCAT(trompeloeil_self_, func))>{(obj)} + \
  3125. std::conditional_t<false, \
  3126. decltype((obj).func), \
  3127. decltype((obj).TROMPELOEIL_CONCAT(trompeloeil_tag_,func))>\
  3128. {__FILE__, static_cast<unsigned long>(__LINE__), obj_s "." func_s}.func
  3129. #define TROMPELOEIL_ALLOW_CALL(obj, func) \
  3130. TROMPELOEIL_ALLOW_CALL_(obj, func, #obj, #func)
  3131. #define TROMPELOEIL_ALLOW_CALL_(obj, func, obj_s, func_s) \
  3132. TROMPELOEIL_REQUIRE_CALL_(obj, func, obj_s, func_s) \
  3133. .TROMPELOEIL_TIMES(0, ~0ULL)
  3134. #define TROMPELOEIL_NAMED_ALLOW_CALL(obj, func) \
  3135. TROMPELOEIL_NAMED_ALLOW_CALL_(obj, func, #obj, #func)
  3136. #define TROMPELOEIL_NAMED_ALLOW_CALL_(obj, func, obj_s, func_s) \
  3137. TROMPELOEIL_NAMED_REQUIRE_CALL_(obj, func, obj_s, func_s) \
  3138. .TROMPELOEIL_TIMES(0, ~0ULL)
  3139. #define TROMPELOEIL_FORBID_CALL(obj, func) \
  3140. TROMPELOEIL_FORBID_CALL_(obj, func, #obj, #func)
  3141. #define TROMPELOEIL_FORBID_CALL_(obj, func, obj_s, func_s) \
  3142. TROMPELOEIL_REQUIRE_CALL_(obj, func, obj_s, func_s) \
  3143. .TROMPELOEIL_TIMES(0)
  3144. #define TROMPELOEIL_NAMED_FORBID_CALL(obj, func) \
  3145. TROMPELOEIL_NAMED_FORBID_CALL_(obj, func, #obj, #func)
  3146. #define TROMPELOEIL_NAMED_FORBID_CALL_(obj, func, obj_s, func_s) \
  3147. TROMPELOEIL_NAMED_REQUIRE_CALL_(obj, func, obj_s, func_s) \
  3148. .TROMPELOEIL_TIMES(0)
  3149. #define TROMPELOEIL_WITH(...) TROMPELOEIL_WITH_(=,#__VA_ARGS__, __VA_ARGS__)
  3150. #define TROMPELOEIL_LR_WITH(...) TROMPELOEIL_WITH_(&,#__VA_ARGS__, __VA_ARGS__)
  3151. #define TROMPELOEIL_WITH_(capture, arg_s, ...) \
  3152. with(arg_s, [capture](auto const& trompeloeil_x) { \
  3153. auto& _1 = ::trompeloeil::mkarg<1>(trompeloeil_x); \
  3154. auto& _2 = ::trompeloeil::mkarg<2>(trompeloeil_x); \
  3155. auto& _3 = ::trompeloeil::mkarg<3>(trompeloeil_x); \
  3156. auto& _4 = ::trompeloeil::mkarg<4>(trompeloeil_x); \
  3157. auto& _5 = ::trompeloeil::mkarg<5>(trompeloeil_x); \
  3158. auto& _6 = ::trompeloeil::mkarg<6>(trompeloeil_x); \
  3159. auto& _7 = ::trompeloeil::mkarg<7>(trompeloeil_x); \
  3160. auto& _8 = ::trompeloeil::mkarg<8>(trompeloeil_x); \
  3161. auto& _9 = ::trompeloeil::mkarg<9>(trompeloeil_x); \
  3162. auto&_10 = ::trompeloeil::mkarg<10>(trompeloeil_x); \
  3163. auto&_11 = ::trompeloeil::mkarg<11>(trompeloeil_x); \
  3164. auto&_12 = ::trompeloeil::mkarg<12>(trompeloeil_x); \
  3165. auto&_13 = ::trompeloeil::mkarg<13>(trompeloeil_x); \
  3166. auto&_14 = ::trompeloeil::mkarg<14>(trompeloeil_x); \
  3167. auto&_15 = ::trompeloeil::mkarg<15>(trompeloeil_x); \
  3168. ::trompeloeil::ignore(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15); \
  3169. return __VA_ARGS__; \
  3170. })
  3171. #define TROMPELOEIL_SIDE_EFFECT(...) TROMPELOEIL_SIDE_EFFECT_(=, __VA_ARGS__)
  3172. #define TROMPELOEIL_LR_SIDE_EFFECT(...) TROMPELOEIL_SIDE_EFFECT_(&, __VA_ARGS__)
  3173. #define TROMPELOEIL_SIDE_EFFECT_(capture, ...) \
  3174. sideeffect([capture](auto& trompeloeil_x) { \
  3175. auto& _1 = ::trompeloeil::mkarg<1>(trompeloeil_x); \
  3176. auto& _2 = ::trompeloeil::mkarg<2>(trompeloeil_x); \
  3177. auto& _3 = ::trompeloeil::mkarg<3>(trompeloeil_x); \
  3178. auto& _4 = ::trompeloeil::mkarg<4>(trompeloeil_x); \
  3179. auto& _5 = ::trompeloeil::mkarg<5>(trompeloeil_x); \
  3180. auto& _6 = ::trompeloeil::mkarg<6>(trompeloeil_x); \
  3181. auto& _7 = ::trompeloeil::mkarg<7>(trompeloeil_x); \
  3182. auto& _8 = ::trompeloeil::mkarg<8>(trompeloeil_x); \
  3183. auto& _9 = ::trompeloeil::mkarg<9>(trompeloeil_x); \
  3184. auto&_10 = ::trompeloeil::mkarg<10>(trompeloeil_x); \
  3185. auto&_11 = ::trompeloeil::mkarg<11>(trompeloeil_x); \
  3186. auto&_12 = ::trompeloeil::mkarg<12>(trompeloeil_x); \
  3187. auto&_13 = ::trompeloeil::mkarg<13>(trompeloeil_x); \
  3188. auto&_14 = ::trompeloeil::mkarg<14>(trompeloeil_x); \
  3189. auto&_15 = ::trompeloeil::mkarg<15>(trompeloeil_x); \
  3190. ::trompeloeil::ignore(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15); \
  3191. __VA_ARGS__; \
  3192. })
  3193. #define TROMPELOEIL_RETURN(...) TROMPELOEIL_RETURN_(=, __VA_ARGS__)
  3194. #define TROMPELOEIL_LR_RETURN(...) TROMPELOEIL_RETURN_(&, __VA_ARGS__)
  3195. #define TROMPELOEIL_RETURN_(capture, ...) \
  3196. handle_return([capture](auto& trompeloeil_x) -> decltype(auto) { \
  3197. auto& _1 = ::trompeloeil::mkarg<1>(trompeloeil_x); \
  3198. auto& _2 = ::trompeloeil::mkarg<2>(trompeloeil_x); \
  3199. auto& _3 = ::trompeloeil::mkarg<3>(trompeloeil_x); \
  3200. auto& _4 = ::trompeloeil::mkarg<4>(trompeloeil_x); \
  3201. auto& _5 = ::trompeloeil::mkarg<5>(trompeloeil_x); \
  3202. auto& _6 = ::trompeloeil::mkarg<6>(trompeloeil_x); \
  3203. auto& _7 = ::trompeloeil::mkarg<7>(trompeloeil_x); \
  3204. auto& _8 = ::trompeloeil::mkarg<8>(trompeloeil_x); \
  3205. auto& _9 = ::trompeloeil::mkarg<9>(trompeloeil_x); \
  3206. auto&_10 = ::trompeloeil::mkarg<10>(trompeloeil_x); \
  3207. auto&_11 = ::trompeloeil::mkarg<11>(trompeloeil_x); \
  3208. auto&_12 = ::trompeloeil::mkarg<12>(trompeloeil_x); \
  3209. auto&_13 = ::trompeloeil::mkarg<13>(trompeloeil_x); \
  3210. auto&_14 = ::trompeloeil::mkarg<14>(trompeloeil_x); \
  3211. auto&_15 = ::trompeloeil::mkarg<15>(trompeloeil_x); \
  3212. ::trompeloeil::ignore(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15); \
  3213. return ::trompeloeil::decay_return_type(__VA_ARGS__); \
  3214. })
  3215. #define TROMPELOEIL_THROW(...) TROMPELOEIL_THROW_(=, __VA_ARGS__)
  3216. #define TROMPELOEIL_LR_THROW(...) TROMPELOEIL_THROW_(&, __VA_ARGS__)
  3217. #define TROMPELOEIL_THROW_(capture, ...) \
  3218. handle_throw([capture](auto& trompeloeil_x) { \
  3219. auto& _1 = ::trompeloeil::mkarg<1>(trompeloeil_x); \
  3220. auto& _2 = ::trompeloeil::mkarg<2>(trompeloeil_x); \
  3221. auto& _3 = ::trompeloeil::mkarg<3>(trompeloeil_x); \
  3222. auto& _4 = ::trompeloeil::mkarg<4>(trompeloeil_x); \
  3223. auto& _5 = ::trompeloeil::mkarg<5>(trompeloeil_x); \
  3224. auto& _6 = ::trompeloeil::mkarg<6>(trompeloeil_x); \
  3225. auto& _7 = ::trompeloeil::mkarg<7>(trompeloeil_x); \
  3226. auto& _8 = ::trompeloeil::mkarg<8>(trompeloeil_x); \
  3227. auto& _9 = ::trompeloeil::mkarg<9>(trompeloeil_x); \
  3228. auto&_10 = ::trompeloeil::mkarg<10>(trompeloeil_x); \
  3229. auto&_11 = ::trompeloeil::mkarg<11>(trompeloeil_x); \
  3230. auto&_12 = ::trompeloeil::mkarg<12>(trompeloeil_x); \
  3231. auto&_13 = ::trompeloeil::mkarg<13>(trompeloeil_x); \
  3232. auto&_14 = ::trompeloeil::mkarg<14>(trompeloeil_x); \
  3233. auto&_15 = ::trompeloeil::mkarg<15>(trompeloeil_x); \
  3234. ::trompeloeil::ignore(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15); \
  3235. throw __VA_ARGS__; \
  3236. })
  3237. #define TROMPELOEIL_TIMES(...) times(::trompeloeil::multiplicity<__VA_ARGS__>{})
  3238. #define TROMPELOEIL_IN_SEQUENCE(...) \
  3239. in_sequence(TROMPELOEIL_INIT_WITH_STR(::trompeloeil::sequence_matcher::init_type, __VA_ARGS__))
  3240. #define TROMPELOEIL_ANY(type) ::trompeloeil::any_matcher<type>(#type)
  3241. #define TROMPELOEIL_AT_LEAST(num) num, ~0ULL
  3242. #define TROMPELOEIL_AT_MOST(num) 0, num
  3243. #define TROMPELOEIL_REQUIRE_DESTRUCTION(obj) \
  3244. TROMPELOEIL_REQUIRE_DESTRUCTION_(obj, #obj)
  3245. #define TROMPELOEIL_REQUIRE_DESTRUCTION_(obj, obj_s) \
  3246. std::unique_ptr<trompeloeil::expectation> \
  3247. TROMPELOEIL_CONCAT(trompeloeil_death_monitor_, __LINE__) \
  3248. = TROMPELOEIL_NAMED_REQUIRE_DESTRUCTION_(,obj, obj_s)
  3249. #define TROMPELOEIL_NAMED_REQUIRE_DESTRUCTION(obj) \
  3250. TROMPELOEIL_NAMED_REQUIRE_DESTRUCTION_("NAMED_", obj, #obj)
  3251. #define TROMPELOEIL_NAMED_REQUIRE_DESTRUCTION_(prefix, obj, obj_s) \
  3252. trompeloeil::lifetime_monitor_releaser{} + \
  3253. trompeloeil::lifetime_monitor_modifier<false>{ \
  3254. std::make_unique<trompeloeil::lifetime_monitor>( \
  3255. obj, \
  3256. obj_s, \
  3257. prefix "REQUIRE_DESTRUCTION(" obj_s ")", \
  3258. "destructor for " obj_s, \
  3259. ::trompeloeil::location{__FILE__, \
  3260. static_cast<unsigned long>(__LINE__)}) \
  3261. }
  3262. #ifndef TROMPELOEIL_LONG_MACROS
  3263. #define MAKE_MOCK0 TROMPELOEIL_MAKE_MOCK0
  3264. #define MAKE_MOCK1 TROMPELOEIL_MAKE_MOCK1
  3265. #define MAKE_MOCK2 TROMPELOEIL_MAKE_MOCK2
  3266. #define MAKE_MOCK3 TROMPELOEIL_MAKE_MOCK3
  3267. #define MAKE_MOCK4 TROMPELOEIL_MAKE_MOCK4
  3268. #define MAKE_MOCK5 TROMPELOEIL_MAKE_MOCK5
  3269. #define MAKE_MOCK6 TROMPELOEIL_MAKE_MOCK6
  3270. #define MAKE_MOCK7 TROMPELOEIL_MAKE_MOCK7
  3271. #define MAKE_MOCK8 TROMPELOEIL_MAKE_MOCK8
  3272. #define MAKE_MOCK9 TROMPELOEIL_MAKE_MOCK9
  3273. #define MAKE_MOCK10 TROMPELOEIL_MAKE_MOCK10
  3274. #define MAKE_MOCK11 TROMPELOEIL_MAKE_MOCK11
  3275. #define MAKE_MOCK12 TROMPELOEIL_MAKE_MOCK12
  3276. #define MAKE_MOCK13 TROMPELOEIL_MAKE_MOCK13
  3277. #define MAKE_MOCK14 TROMPELOEIL_MAKE_MOCK14
  3278. #define MAKE_MOCK15 TROMPELOEIL_MAKE_MOCK15
  3279. #define MAKE_CONST_MOCK0 TROMPELOEIL_MAKE_CONST_MOCK0
  3280. #define MAKE_CONST_MOCK1 TROMPELOEIL_MAKE_CONST_MOCK1
  3281. #define MAKE_CONST_MOCK2 TROMPELOEIL_MAKE_CONST_MOCK2
  3282. #define MAKE_CONST_MOCK3 TROMPELOEIL_MAKE_CONST_MOCK3
  3283. #define MAKE_CONST_MOCK4 TROMPELOEIL_MAKE_CONST_MOCK4
  3284. #define MAKE_CONST_MOCK5 TROMPELOEIL_MAKE_CONST_MOCK5
  3285. #define MAKE_CONST_MOCK6 TROMPELOEIL_MAKE_CONST_MOCK6
  3286. #define MAKE_CONST_MOCK7 TROMPELOEIL_MAKE_CONST_MOCK7
  3287. #define MAKE_CONST_MOCK8 TROMPELOEIL_MAKE_CONST_MOCK8
  3288. #define MAKE_CONST_MOCK9 TROMPELOEIL_MAKE_CONST_MOCK9
  3289. #define MAKE_CONST_MOCK10 TROMPELOEIL_MAKE_CONST_MOCK10
  3290. #define MAKE_CONST_MOCK11 TROMPELOEIL_MAKE_CONST_MOCK11
  3291. #define MAKE_CONST_MOCK12 TROMPELOEIL_MAKE_CONST_MOCK12
  3292. #define MAKE_CONST_MOCK13 TROMPELOEIL_MAKE_CONST_MOCK13
  3293. #define MAKE_CONST_MOCK14 TROMPELOEIL_MAKE_CONST_MOCK14
  3294. #define MAKE_CONST_MOCK15 TROMPELOEIL_MAKE_CONST_MOCK15
  3295. #define REQUIRE_CALL TROMPELOEIL_REQUIRE_CALL
  3296. #define NAMED_REQUIRE_CALL TROMPELOEIL_NAMED_REQUIRE_CALL
  3297. #define ALLOW_CALL TROMPELOEIL_ALLOW_CALL
  3298. #define NAMED_ALLOW_CALL TROMPELOEIL_NAMED_ALLOW_CALL
  3299. #define FORBID_CALL TROMPELOEIL_FORBID_CALL
  3300. #define NAMED_FORBID_CALL TROMPELOEIL_NAMED_FORBID_CALL
  3301. #define WITH TROMPELOEIL_WITH
  3302. #define LR_WITH TROMPELOEIL_LR_WITH
  3303. #define SIDE_EFFECT TROMPELOEIL_SIDE_EFFECT
  3304. #define LR_SIDE_EFFECT TROMPELOEIL_LR_SIDE_EFFECT
  3305. #define RETURN TROMPELOEIL_RETURN
  3306. #define LR_RETURN TROMPELOEIL_LR_RETURN
  3307. #define THROW TROMPELOEIL_THROW
  3308. #define LR_THROW TROMPELOEIL_LR_THROW
  3309. #define TIMES TROMPELOEIL_TIMES
  3310. #define IN_SEQUENCE TROMPELOEIL_IN_SEQUENCE
  3311. #define ANY TROMPELOEIL_ANY
  3312. #define AT_LEAST TROMPELOEIL_AT_LEAST
  3313. #define AT_MOST TROMPELOEIL_AT_MOST
  3314. #define REQUIRE_DESTRUCTION TROMPELOEIL_REQUIRE_DESTRUCTION
  3315. #define NAMED_REQUIRE_DESTRUCTION TROMPELOEIL_NAMED_REQUIRE_DESTRUCTION
  3316. #endif // TROMPELOEIL_LONG_MACROS
  3317. #endif // include guard