mimic++ v9.2.1
Loading...
Searching...
No Matches
Expectation.hpp
Go to the documentation of this file.
1// Copyright Dominic (DNKpp) Koepke 2024 - 2025.
2// Distributed under the Boost Software License, Version 1.0.
3// (See accompanying file LICENSE_1_0.txt or copy at
4// https://www.boost.org/LICENSE_1_0.txt)
5
6#ifndef MIMICPP_EXPECTATION_HPP
7#define MIMICPP_EXPECTATION_HPP
8
9#pragma once
10
11#include "mimic++/Call.hpp"
12#include "mimic++/Fwd.hpp"
13#include "mimic++/Sequence.hpp"
23
24#ifndef MIMICPP_DETAIL_IS_MODULE
25 #include <algorithm>
26 #include <concepts>
27 #include <functional>
28 #include <memory>
29 #include <mutex>
30 #include <optional>
31 #include <ranges>
32 #include <tuple>
33 #include <utility>
34 #include <vector>
35#endif
36
37namespace mimicpp::detail
38{
39 template <typename Return, typename... Params, typename Signature>
40 [[nodiscard]]
41 std::optional<reporting::RequirementOutcomes> determine_requirement_outcomes(
42 reporting::TargetReport const& target,
43 call::Info<Return, Params...> const& call,
44 Expectation<Signature> const& expectation) noexcept
45 {
46 try
47 {
48 return expectation.matches(call);
49 }
50 catch (...)
51 {
52 reporting::detail::report_unhandled_exception(
54 target,
55 call,
56 util::stacktrace::current(3u + call.baseStacktraceSkip)),
57 expectation.report(),
58 std::current_exception());
59 }
60
61 return std::nullopt;
62 }
63
64 [[nodiscard]]
65 std::vector<reporting::ExpectationReport> gather_expectation_reports(auto&& expectationPtrs)
66 {
67 auto view = std::views::transform(expectationPtrs, [](auto const& exp) { return exp->report(); });
68 return std::vector<reporting::ExpectationReport>{
69 view.begin(),
70 view.end()};
71 }
72
73 template <typename Signature>
74 [[nodiscard]]
75 std::vector<reporting::NoMatchReport> make_no_match_reports(
76 std::vector<std::tuple<Expectation<Signature>*, reporting::RequirementOutcomes>>&& outcomes)
77 {
78 std::vector<reporting::NoMatchReport> reports{};
79 reports.reserve(outcomes.size());
80 for (auto const& [expectationPtr, outcome] : outcomes)
81 {
82 reports.emplace_back(
83 expectationPtr->report(),
84 std::move(outcome));
85 }
86
87 return reports;
88 }
89
90 [[nodiscard]]
91 constexpr auto find_best_match(std::span<reporting::ExpectationReport const> const matches)
92 {
93 constexpr auto ratings = [](auto const& el) noexcept -> const auto& {
94 return std::get<reporting::state_applicable>(el.controlReport)
95 .sequenceRatings;
96 };
97
98 auto best = std::ranges::begin(matches);
99 for (auto iter = best + 1;
100 iter != std::ranges::end(matches);
101 ++iter)
102 {
103 if (!sequence::detail::has_better_rating(
104 ratings(*best),
105 ratings(*iter)))
106 {
107 best = iter;
108 }
109 }
110
111 return std::ranges::distance(std::ranges::begin(matches), best);
112 }
113}
114
116{
140
145 template <typename Signature>
146 requires std::same_as<Signature, signature_decay_t<Signature>>
148 {
149 public:
154
159
163 virtual ~Expectation() = default;
164
168 [[nodiscard]]
169 Expectation() = default;
170
174 Expectation(const Expectation&) = delete;
175
180
185
190
195 [[nodiscard]]
197
202 [[nodiscard]]
203 virtual bool is_satisfied() const noexcept = 0;
204
209 [[nodiscard]]
210 virtual bool is_applicable() const noexcept = 0;
211
217 [[nodiscard]]
218 virtual reporting::RequirementOutcomes matches(const CallInfoT& call) const = 0;
219
225 virtual void consume(const CallInfoT& call) = 0;
226
233 [[nodiscard]]
234 virtual constexpr ReturnT finalize_call(const CallInfoT& call) = 0;
235
240 [[nodiscard]]
241 virtual constexpr util::SourceLocation const& from() const noexcept = 0;
242
247 [[nodiscard]]
248 virtual constexpr StringT const& mock_name() const noexcept = 0;
249 };
250
255 template <typename Signature>
256 requires std::same_as<Signature, signature_decay_t<Signature>>
258 {
259 public:
264
269
274
279
283 [[nodiscard]]
285
290
295
299 [[nodiscard]]
301
306
313 void push(std::shared_ptr<ExpectationT> expectation)
314 {
315 const std::scoped_lock lock{m_ExpectationsMx};
316
317 MIMICPP_ASSERT(std::ranges::find(m_Expectations, expectation) == std::ranges::end(m_Expectations), "Expectation already belongs to this storage.");
318
319 m_Expectations.emplace_back(std::move(expectation));
320 }
321
329 void remove(std::shared_ptr<ExpectationT> expectation)
330 {
331 const std::scoped_lock lock{m_ExpectationsMx};
332
333 auto iter = std::ranges::find(m_Expectations, expectation);
334 MIMICPP_ASSERT(iter != std::ranges::end(m_Expectations), "Expectation does not belong to this storage.");
335 m_Expectations.erase(iter);
336
337 if (!expectation->is_satisfied())
338 {
339 reporting::detail::report_unfulfilled_expectation(
340 expectation->report());
341 }
342 }
343
354 [[nodiscard]]
356 {
357 std::vector<ExpectationT*> matches{};
358 std::vector<ExpectationT*> inapplicableMatches{};
359 std::vector<std::tuple<ExpectationT*, reporting::RequirementOutcomes>> noMatches{};
360
361 std::scoped_lock const lock{m_ExpectationsMx};
362 evaluate_expectations(target, call, matches, inapplicableMatches, noMatches);
363
364 std::size_t const stacktraceSkip{1u + call.baseStacktraceSkip};
365 if (!std::ranges::empty(matches))
366 {
367 std::vector reports = detail::gather_expectation_reports(matches);
368 MIMICPP_ASSERT(matches.size() == reports.size(), "Size mismatch.");
369 auto const bestIndex = detail::find_best_match(reports);
370 MIMICPP_ASSERT(0 <= bestIndex && bestIndex < std::ssize(reports), "Invalid index.");
371
372 auto& expectation = *matches[bestIndex];
373
375 {
376 auto& report = reports[bestIndex];
377
378 // Todo: Avoid the call copy
379 // Maybe we can prevent the copy here, but we should keep the instruction order as-is, because
380 // in cases of a throwing finalizer, we might introduce bugs. At least there are some tests, which
381 // will fail if done wrong.
382 reporting::detail::report_full_match(
383 reporting::make_call_report(std::move(target), call, util::stacktrace::current(stacktraceSkip)),
384 std::move(report));
385 }
386
387 expectation.consume(call);
388 return expectation.finalize_call(call);
389 }
390
391 if (!std::ranges::empty(inapplicableMatches))
392 {
393 reporting::detail::report_inapplicable_matches(
394 reporting::make_call_report(std::move(target), std::move(call), util::stacktrace::current(stacktraceSkip)),
395 detail::gather_expectation_reports(inapplicableMatches));
396 }
397
398 reporting::detail::report_no_matches(
399 reporting::make_call_report(std::move(target), std::move(call), util::stacktrace::current(stacktraceSkip)),
400 detail::make_no_match_reports(std::move(noMatches)));
401 }
402
403 private:
404 std::vector<std::shared_ptr<ExpectationT>> m_Expectations{};
405 std::mutex m_ExpectationsMx{};
406
407 void evaluate_expectations(
408 reporting::TargetReport const& target,
409 CallInfoT const& call,
410 std::vector<ExpectationT*>& matches,
411 std::vector<ExpectationT*>& inapplicableMatches,
412 std::vector<std::tuple<ExpectationT*, reporting::RequirementOutcomes>>& noMatches)
413 {
414 for (auto const& exp : std::views::reverse(m_Expectations))
415 {
416 if (std::optional outcomes = detail::determine_requirement_outcomes(target, call, *exp))
417 {
418 if (std::ranges::any_of(outcomes->outcomes, [](auto const& el) { return el == false; }))
419 {
420 noMatches.emplace_back(exp.get(), *std::move(outcomes));
421 }
422 else if (!exp->is_applicable())
423 {
424 inapplicableMatches.emplace_back(exp.get());
425 }
426 else
427 {
428 matches.emplace_back(exp.get());
429 }
430 }
431 }
432 }
433 };
434
438 template <typename T, typename Signature>
439 concept expectation_policy_for = std::is_move_constructible_v<T>
440 && std::is_destructible_v<T>
441 && std::same_as<T, std::remove_cvref_t<T>>
442 && requires(T& policy, const call::info_for_signature_t<Signature>& info) {
443 { std::as_const(policy).is_satisfied() } noexcept -> util::boolean_testable;
444 { std::as_const(policy).matches(info) } -> util::boolean_testable;
445 { std::as_const(policy).describe() } -> util::explicitly_convertible_to<std::optional<StringT>>;
446 { policy.consume(info) };
447 };
448
452 template <typename T, typename Signature>
453 concept finalize_policy_for = std::is_move_constructible_v<T>
454 && std::is_destructible_v<T>
455 && std::same_as<T, std::remove_cvref_t<T>>
456 && requires(T& policy, const call::info_for_signature_t<Signature>& info) {
457 { policy.finalize_call(info) } -> std::convertible_to<signature_return_type_t<Signature>>;
458 };
459
463 template <typename T>
464 concept control_policy = std::is_move_constructible_v<T>
465 && std::is_destructible_v<T>
466 && std::same_as<T, std::remove_cvref_t<T>>
467 && requires(T& policy) {
468 { std::as_const(policy).is_satisfied() } noexcept -> util::boolean_testable;
469 { std::as_const(policy).state() } -> std::convertible_to<reporting::control_state_t>;
470 policy.consume();
471 };
472
480 template <
481 typename Signature,
483 finalize_policy_for<Signature> FinalizePolicy,
486 : public Expectation<Signature>
487 {
488 public:
490 using FinalizerT = FinalizePolicy;
491 using PolicyListT = std::tuple<Policies...>;
494
506 template <typename ControlPolicyArg, typename FinalizerArg, typename... PolicyArgs>
507 requires std::constructible_from<ControlPolicyT, ControlPolicyArg>
508 && std::constructible_from<FinalizerT, FinalizerArg>
509 && std::constructible_from<PolicyListT, PolicyArgs...>
510 constexpr explicit BasicExpectation(
513 ControlPolicyArg&& controlArg,
514 FinalizerArg&& finalizerArg,
515 PolicyArgs&&... args)
516 noexcept(
517 std::is_nothrow_constructible_v<ControlPolicyT, ControlPolicyArg>
518 && std::is_nothrow_constructible_v<FinalizerT, FinalizerArg>
519 && (std::is_nothrow_constructible_v<Policies, PolicyArgs> && ...))
520 : m_From{std::move(from)},
521 m_Target{std::move(target)},
522 m_ControlPolicy{std::forward<ControlPolicyArg>(controlArg)},
523 m_Policies{std::forward<PolicyArgs>(args)...},
524 m_Finalizer{std::forward<FinalizerArg>(finalizerArg)}
525 {
526 }
527
531 [[nodiscard]]
533 {
535 .from = m_From,
536 .target = m_Target,
537 .controlReport = m_ControlPolicy.state(),
538 .finalizerDescription = std::nullopt,
539 .requirementDescriptions = std::apply(
540 [&](auto const&... policies) {
541 return std::vector<std::optional<StringT>>{
542 std::optional<StringT>{policies.describe()}...};
543 },
544 m_Policies)};
545 }
546
550 [[nodiscard]]
551 constexpr bool is_satisfied() const noexcept override
552 {
553 return m_ControlPolicy.is_satisfied()
554 && std::apply(
555 [](const auto&... policies) noexcept {
556 return (... && policies.is_satisfied());
557 },
558 m_Policies);
559 }
560
564 [[nodiscard]]
565 constexpr bool is_applicable() const noexcept override
566 {
567 return std::holds_alternative<reporting::state_applicable>(
568 m_ControlPolicy.state());
569 }
570
574 [[nodiscard]]
576 {
578 .outcomes = gather_requirement_outcomes(call)};
579 }
580
584 constexpr void consume(const CallInfoT& call) override
585 {
586 m_ControlPolicy.consume();
587 std::apply(
588 [&](auto&... policies) noexcept {
589 (..., policies.consume(call));
590 },
591 m_Policies);
592 }
593
597 [[nodiscard]]
598 constexpr ReturnT finalize_call(const CallInfoT& call) override
599 {
600 return m_Finalizer.finalize_call(call);
601 }
602
606 [[nodiscard]]
607 constexpr util::SourceLocation const& from() const noexcept override
608 {
609 return m_From;
610 }
611
615 [[nodiscard]]
616 constexpr StringT const& mock_name() const noexcept override
617 {
618 return m_Target.name;
619 }
620
621 private:
624 ControlPolicyT m_ControlPolicy;
625 PolicyListT m_Policies;
626 [[no_unique_address]] FinalizerT m_Finalizer{};
627
628 [[nodiscard]]
629 std::vector<bool> gather_requirement_outcomes(CallInfoT const& call) const
630 {
631 return std::apply(
632 [&](auto const&... policies) {
633 return std::vector<bool>{policies.matches(call)...};
634 },
635 m_Policies);
636 }
637 };
638
645 {
646 private:
647 class Concept
648 {
649 public:
650 virtual ~Concept() noexcept(false)
651 {
652 }
653
654 Concept(const Concept&) = delete;
655 Concept& operator=(const Concept&) = delete;
656 Concept(Concept&&) = delete;
657 Concept& operator=(Concept&&) = delete;
658
659 [[nodiscard]]
660 virtual bool is_satisfied() const = 0;
661 [[nodiscard]]
662 virtual bool is_applicable() const = 0;
663
664 [[nodiscard]]
665 virtual util::SourceLocation const& from() const noexcept = 0;
666 [[nodiscard]]
667 virtual StringT const& mock_name() const noexcept = 0;
668
669 protected:
670 Concept() = default;
671 };
672
673 template <typename Signature>
674 class Model final
675 : public Concept
676 {
677 public:
678 using StorageT = ExpectationCollection<Signature>;
679 using ExpectationT = Expectation<Signature>;
680
681 ~Model() noexcept(false) override
682 {
683 m_Storage->remove(m_Expectation);
684 }
685
686 [[nodiscard]]
687 explicit Model(
688 std::shared_ptr<StorageT>&& storage,
689 std::shared_ptr<ExpectationT>&& expectation) noexcept
690 : m_Storage{std::move(storage)},
691 m_Expectation{std::move(expectation)}
692 {
693 MIMICPP_ASSERT(m_Storage, "Storage is nullptr.");
694 MIMICPP_ASSERT(m_Expectation, "Expectation is nullptr.");
695
696 m_Storage->push(m_Expectation);
697 }
698
699 [[nodiscard]]
700 bool is_satisfied() const override
701 {
702 return m_Expectation->is_satisfied();
703 }
704
705 [[nodiscard]]
706 bool is_applicable() const override
707 {
708 return m_Expectation->is_applicable();
709 }
710
711 [[nodiscard]]
712 util::SourceLocation const& from() const noexcept override
713 {
714 return m_Expectation->from();
715 }
716
717 [[nodiscard]]
718 StringT const& mock_name() const noexcept override
719 {
720 return m_Expectation->mock_name();
721 }
722
723 private:
724 std::shared_ptr<StorageT> m_Storage;
725 std::shared_ptr<ExpectationT> m_Expectation;
726 };
727
728 public:
733 ~ScopedExpectation() noexcept(false)
734 {
735 // we must call the dtor manually here, because std::unique_ptr's dtor mustn't throw.
736 delete m_Inner.release(); // NOLINT(*-uniqueptr-delete-release)
737 }
738
745 template <typename Signature>
746 [[nodiscard]]
748 std::shared_ptr<ExpectationCollection<Signature>> collection,
749 std::shared_ptr<typename ExpectationCollection<Signature>::ExpectationT> expectation) noexcept
750 : m_Inner{
751 std::make_unique<Model<Signature>>(
752 std::move(collection),
753 std::move(expectation))}
754 {
755 }
756
763 template <typename T>
764 requires requires(util::SourceLocation loc) {
765 { std::declval<T&&>().finalize(loc) } -> std::convertible_to<ScopedExpectation>;
766 }
767 [[nodiscard]]
768 explicit(false) constexpr ScopedExpectation(T&& object, util::SourceLocation loc = {})
769 : ScopedExpectation{std::forward<T>(object).finalize(std::move(loc))}
770 {
771 }
772
776 ScopedExpectation(ScopedExpectation const&) = delete;
777
782
786 [[nodiscard]]
788
793
798 [[nodiscard]]
799 bool is_satisfied() const
800 {
801 return m_Inner->is_satisfied();
802 }
803
808 [[nodiscard]]
809 bool is_applicable() const
810 {
811 return m_Inner->is_applicable();
812 }
813
818 [[nodiscard]]
819 util::SourceLocation const& from() const noexcept
820 {
821 return m_Inner->from();
822 }
823
828 [[nodiscard]]
829 StringT const& mock_name() const noexcept
830 {
831 return m_Inner->mock_name();
832 }
833
834 private:
835 std::unique_ptr<Concept> m_Inner;
836 };
837
841}
842
843#endif
#define MIMICPP_ASSERT(condition, msg)
Definition Config.hpp:51
#define MIMICPP_DETAIL_MODULE_EXPORT
Definition Config.hpp:19
FinalizePolicy FinalizerT
Definition Expectation.hpp:490
constexpr BasicExpectation(util::SourceLocation from, reporting::TargetReport target, ControlPolicyArg &&controlArg, FinalizerArg &&finalizerArg, PolicyArgs &&... args) noexcept(std::is_nothrow_constructible_v< ControlPolicyT, ControlPolicyArg > &&std::is_nothrow_constructible_v< FinalizerT, FinalizerArg > &&(std::is_nothrow_constructible_v< Policies, PolicyArgs > &&...))
Constructs the expectation with the given arguments.
Definition Expectation.hpp:510
constexpr void consume(const CallInfoT &call) override
Informs all policies, that the given call has been accepted.
Definition Expectation.hpp:584
ControlPolicy ControlPolicyT
Definition Expectation.hpp:489
constexpr bool is_satisfied() const noexcept override
Queries all policies, whether they are satisfied.
Definition Expectation.hpp:551
constexpr util::SourceLocation const & from() const noexcept override
Returns the source-location, where this expectation has been created.
Definition Expectation.hpp:607
typename Expectation< Signature >::ReturnT ReturnT
Definition Expectation.hpp:493
constexpr ReturnT finalize_call(const CallInfoT &call) override
Requests the given call to be finalized.
Definition Expectation.hpp:598
call::info_for_signature_t< Signature > CallInfoT
Definition Expectation.hpp:492
reporting::RequirementOutcomes matches(const CallInfoT &call) const override
Queries all policies, whether they accept the given call.
Definition Expectation.hpp:575
constexpr StringT const & mock_name() const noexcept override
Returns the name of the related mock.
Definition Expectation.hpp:616
constexpr bool is_applicable() const noexcept override
Queries the control policy, whether it's in the applicable state.
Definition Expectation.hpp:565
reporting::ExpectationReport report() const override
Creates a report of the internal state.
Definition Expectation.hpp:532
std::tuple< Policies... > PolicyListT
Definition Expectation.hpp:491
Definition ControlPolicies.hpp:161
Collects all expectations for a specific (decayed) signature.
Definition Expectation.hpp:258
ExpectationCollection(const ExpectationCollection &)=delete
Deleted copy-constructor.
~ExpectationCollection()=default
Defaulted destructor.
signature_return_type_t< Signature > ReturnT
The return type.
Definition Expectation.hpp:273
ExpectationCollection & operator=(const ExpectationCollection &)=delete
Deleted copy-assignment-operator.
ExpectationCollection(ExpectationCollection &&)=default
Defaulted move-constructor.
void push(std::shared_ptr< ExpectationT > expectation)
Inserts the given expectation into the internal storage.
Definition Expectation.hpp:313
ReturnT handle_call(reporting::TargetReport target, CallInfoT call)
Handles the incoming call.
Definition Expectation.hpp:355
ExpectationCollection()=default
Defaulted default constructor.
call::info_for_signature_t< Signature > CallInfoT
The expected call type.
Definition Expectation.hpp:263
ExpectationCollection & operator=(ExpectationCollection &&)=default
Defaulted move-assignment-operator.
void remove(std::shared_ptr< ExpectationT > expectation)
Removes the given expectation from the internal storage.
Definition Expectation.hpp:329
Expectation< Signature > ExpectationT
The interface type of the stored expectations.
Definition Expectation.hpp:268
The base interface for expectations.
Definition Expectation.hpp:148
virtual constexpr StringT const & mock_name() const noexcept=0
Returns the name of the related mock.
virtual constexpr util::SourceLocation const & from() const noexcept=0
Returns the source-location, where this expectation has been created.
Expectation(Expectation &&)=delete
Deleted move-constructor.
virtual reporting::ExpectationReport report() const =0
Creates a report of the internal state.
virtual reporting::RequirementOutcomes matches(const CallInfoT &call) const =0
Queries all policies, whether they accept the given call.
call::info_for_signature_t< Signature > CallInfoT
The expected call type.
Definition Expectation.hpp:153
virtual bool is_applicable() const noexcept=0
Queries the control policy, whether it's in the applicable state.
virtual bool is_satisfied() const noexcept=0
Queries all policies, whether they are satisfied.
virtual ~Expectation()=default
Defaulted virtual destructor.
signature_return_type_t< Signature > ReturnT
The return type.
Definition Expectation.hpp:158
Expectation()=default
Defaulted default constructor.
Expectation(const Expectation &)=delete
Deleted copy-constructor.
virtual constexpr ReturnT finalize_call(const CallInfoT &call)=0
Requests the given call to be finalized.
Expectation & operator=(const Expectation &)=delete
Deleted copy-assignment-operator.
virtual void consume(const CallInfoT &call)=0
Informs all policies, that the given call has been accepted.
Expectation & operator=(Expectation &&)=delete
Deleted move-assignment-operator.
Takes the ownership of an expectation and check whether it's satisfied during destruction.
Definition Expectation.hpp:645
bool is_satisfied() const
Queries the stored expectation, whether it's satisfied.
Definition Expectation.hpp:799
StringT const & mock_name() const noexcept
Queries the stored expectation for the name of the related mock.
Definition Expectation.hpp:829
ScopedExpectation(ScopedExpectation &&)=default
Defaulted move-constructor.
util::SourceLocation const & from() const noexcept
Queries the stored expectation for it's stored source-location.
Definition Expectation.hpp:819
ScopedExpectation & operator=(ScopedExpectation const &)=delete
Deleted copy-assignment-operator.
ScopedExpectation(std::shared_ptr< ExpectationCollection< Signature > > collection, std::shared_ptr< typename ExpectationCollection< Signature >::ExpectationT > expectation) noexcept
Constructor, which generates the type-erase storage.
Definition Expectation.hpp:747
ScopedExpectation & operator=(ScopedExpectation &&)=default
Defaulted move-assignment-operator.
bool is_applicable() const
Queries the stored expectation, whether it's applicable.
Definition Expectation.hpp:809
util::SourceLocation loc
Definition Expectation.hpp:768
~ScopedExpectation() noexcept(false)
Removes the owned expectation from the ExpectationCollection and checks, whether it's satisfied.
Definition Expectation.hpp:733
Contains the extracted info from a typed expectation.
Definition ExpectationReport.hpp:85
Contains the boolean outcomes of a match-test.
Definition ExpectationReport.hpp:102
Contains the extracted mock info.
Definition TargetReport.hpp:22
A thin wrapper around general source-location info.
Definition SourceLocation.hpp:38
Determines, whether the given type satisfies the requirements of a control-policy.
Definition Expectation.hpp:464
Determines, whether the given type satisfies the requirements of an expectation-policy for the given ...
Definition Expectation.hpp:439
Determines, whether the given type satisfies the requirements of a finalize-policy for the given sign...
Definition Expectation.hpp:453
Determines, whether B behaves as a the builtin type bool.
Definition Concepts.hpp:66
Determines, whether From can be explicitly converted to To.
Definition Concepts.hpp:34
CallReport make_call_report(TargetReport target, call::Info< Return, Params... > callInfo, util::Stacktrace stacktrace)
Generates the call report for a given call info.
Definition CallReport.hpp:79
std::atomic_bool & report_success() noexcept
Controls whether successful matches are reported.
Definition Settings.hpp:32
typename signature_decay< Signature >::type signature_decay_t
Convenience alias, exposing the type member alias of the actual type-trait.
Definition Fwd.hpp:214
typename signature_return_type< Signature >::type signature_return_type_t
Convenience alias, exposing the type member alias of the actual type-trait.
Definition Fwd.hpp:230
constexpr detail::current_fn current
Function object, which generates the current-stacktrace.
Definition Stacktrace.hpp:473
Definition Call.hpp:24
typename info_for_signature< Signature >::type info_for_signature_t
Definition Call.hpp:47
Definition FloatingPointMatchers.hpp:25
Definition BasicReporter.hpp:27
Definition Fwd.hpp:445
Definition Call.hpp:24
std::basic_string< CharT, CharTraitsT > StringT
Definition Fwd.hpp:391