mimic++ v9.2.1
Loading...
Searching...
No Matches
ScopedSequence.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_SCOPED_SEQUENCE_HPP
7#define MIMICPP_SCOPED_SEQUENCE_HPP
8
9#pragma once
10
13#include "mimic++/Sequence.hpp"
16
17#ifndef MIMICPP_DETAIL_IS_MODULE
18 #include <deque>
19 #include <functional>
20 #include <utility>
21#endif
22
23namespace mimicpp::sequence::detail
24{
25 template <typename Sequence>
26 class ExpectationBuilderFinalizer
27 {
28 public:
29 ExpectationBuilderFinalizer(ExpectationBuilderFinalizer const&) = delete;
30 ExpectationBuilderFinalizer& operator=(ExpectationBuilderFinalizer const&) = delete;
31 ExpectationBuilderFinalizer(ExpectationBuilderFinalizer&&) = delete;
32 ExpectationBuilderFinalizer& operator=(ExpectationBuilderFinalizer&&) = delete;
33
34 ~ExpectationBuilderFinalizer() = default;
35
36 template <bool timesConfigured, typename... Args>
37 [[nodiscard]]
38 explicit(false) constexpr ExpectationBuilderFinalizer(
39 BasicExpectationBuilder<timesConfigured, Args...>&& builder,
40 util::SourceLocation loc = {})
41 : m_Builder{&builder},
42 m_SourceLocation{std::move(loc)},
43 m_FinalizeFn{
44 +[](void* storage, util::SourceLocation finalLoc, Sequence& sequence) {
45 auto* builderPtr = static_cast<BasicExpectationBuilder<timesConfigured, Args...>*>(storage);
46 return ScopedExpectation{
47 std::move(*builderPtr) and expect::in_sequence(sequence),
48 std::move(finalLoc)};
49 }}
50 {
51 }
52
53 [[nodiscard]]
54 ScopedExpectation finalize(Sequence& sequence)
55 {
56 MIMICPP_ASSERT(m_Builder, "Builder is nullptr.");
57 MIMICPP_ASSERT(m_FinalizeFn, "FinalizeFn is nullptr.");
58
59 return std::invoke(
60 std::exchange(m_FinalizeFn, nullptr),
61 std::exchange(m_Builder, nullptr),
62 std::move(m_SourceLocation),
63 sequence);
64 }
65
66 private:
67 void* m_Builder;
68 util::SourceLocation m_SourceLocation;
69
70 using FinalizeFn = ScopedExpectation (*)(void*, util::SourceLocation, Sequence&);
71 FinalizeFn m_FinalizeFn;
72 };
73}
74
76{
95 template <auto Strategy>
97 : public sequence::detail::BasicSequenceInterface<sequence::Id, Strategy>
98 {
99 public:
103 [[nodiscard]]
105
110
114 ~BasicScopedSequence() noexcept(false)
115 {
116 auto expectations = std::exchange(m_Expectations, {});
117 while (!expectations.empty())
118 {
119 // Prevent the `pop_front() noexcept` from raising an exception and thus terminating.
120 auto const expectation = std::move(expectations.front());
121 expectations.pop_front();
122 }
123 }
124
128 [[nodiscard]]
129 explicit BasicScopedSequence([[maybe_unused]] auto&&... canary, util::SourceLocation loc = {})
130 : sequence::detail::BasicSequenceInterface<sequence::Id, Strategy>{std::move(loc)}
131 {
132 static_assert(0u == sizeof...(canary), "ScopedSequence does not accept constructor arguments.");
133 }
134
138 [[nodiscard]]
140
146
155 BasicScopedSequence& operator+=(sequence::detail::ExpectationBuilderFinalizer<BasicScopedSequence>&& builder)
156 {
157 m_Expectations.emplace_back(builder.finalize(*this));
158
159 return *this;
160 }
161
168 [[nodiscard]]
169 std::deque<ScopedExpectation> const& expectations() const noexcept
170 {
171 return m_Expectations;
172 }
173
174 private:
175 std::deque<ScopedExpectation> m_Expectations{};
176 };
177
182 using GreedyScopedSequence = BasicScopedSequence<sequence::detail::GreedyStrategy{}>;
183
188 using LazyScopedSequence = BasicScopedSequence<sequence::detail::LazyStrategy{}>;
189
195}
196
197#endif
#define MIMICPP_ASSERT(condition, msg)
Definition Config.hpp:51
#define MIMICPP_DETAIL_MODULE_EXPORT
Definition Config.hpp:19
A sequence type that verifies its owned expectations during destruction.
Definition ScopedSequence.hpp:98
BasicScopedSequence(auto &&... canary, util::SourceLocation loc={})
Default-constructor.
Definition ScopedSequence.hpp:129
BasicScopedSequence & operator=(BasicScopedSequence const &)=delete
Deleted copy-assignment operator.
~BasicScopedSequence() noexcept(false)
Possibly throwing destructor, checking the owned expectations in order of construction.
Definition ScopedSequence.hpp:114
BasicScopedSequence(BasicScopedSequence const &)=delete
Deleted copy-constructor.
std::deque< ScopedExpectation > const & expectations() const noexcept
Retrieves the collection of explicitly owned expectations.
Definition ScopedSequence.hpp:169
BasicScopedSequence & operator=(BasicScopedSequence &&)=default
Defaulted move-assignment operator.
BasicScopedSequence(BasicScopedSequence &&)=default
Defaulted move-constructor.
BasicScopedSequence & operator+=(sequence::detail::ExpectationBuilderFinalizer< BasicScopedSequence > &&builder)
Attaches a newly constructed expectation.
Definition ScopedSequence.hpp:155
A thin wrapper around general source-location info.
Definition SourceLocation.hpp:38
LazySequence Sequence
The default sequence type (LazySequence).
Definition Sequence.hpp:472
BasicScopedSequence< sequence::detail::LazyStrategy{}> LazyScopedSequence
The scoped-sequence type with lazy strategy.
Definition ScopedSequence.hpp:188
LazyScopedSequence ScopedSequence
The default scoped-sequence type (lazy strategy).
Definition ScopedSequence.hpp:194
BasicScopedSequence< sequence::detail::GreedyStrategy{}> GreedyScopedSequence
The scoped-sequence type with greedy strategy.
Definition ScopedSequence.hpp:182
constexpr auto in_sequence(sequence::detail::BasicSequenceInterface< Id, priorityStrategy > &sequence)
Attaches the expectation onto a sequence.
Definition Sequence.hpp:513
Definition Fwd.hpp:400
Definition Call.hpp:24