40 template <std::size_t...>
struct IndexSequence{};
41 template <std::size_t Size, std::size_t... Indices>
struct MakeIndexSequence : MakeIndexSequence<Size - 1, Size - 1, Indices...>{};
42 template <std::size_t... Indices>
struct MakeIndexSequence<0, Indices...> {
using Type = IndexSequence<Indices...>; };
45 template <
typename Operation,
typename Holder,
typename Arguments, std::size_t... Indices>
47 Operation::apply(std::forward<Holder>(message), std::get<Indices>(std::forward<Arguments>(arguments))...))
49 return Operation::apply(
50 std::forward<Holder>(message), std::get<Indices>(std::forward<Arguments>(arguments))...);
53 template <
typename Operation,
typename... Arguments>
59 template <
typename Holder>
61 std::forward<Holder>(message), std::declval<
const std::tuple<Arguments...>&>(),
62 typename MakeIndexSequence<
sizeof...(Arguments)>::Type()))
65 std::forward<Holder>(message), arguments_,
typename MakeIndexSequence<
sizeof...(Arguments)>::Type());
68 template <
typename Holder>
70 std::forward<Holder>(message), std::declval<std::tuple<Arguments...>&&>(),
71 typename MakeIndexSequence<
sizeof...(Arguments)>::Type()))
74 std::forward<Holder>(message), std::move(arguments_),
typename MakeIndexSequence<
sizeof...(Arguments)>::Type());
78 std::tuple<Arguments...> arguments_;
81 template <
typename Operation,
typename... Arguments>
85 return Result(std::forward<Arguments>(arguments)...);
88 template <Messaging::UpdateAction::Enum Action>
91 template <
typename Holder,
typename... Arguments>
92 static auto apply(Holder& message, Arguments&&... arguments) ->
decltype(
94 message, std::forward<Arguments>(arguments)...))
97 message, std::forward<Arguments>(arguments)...);
104 std::forward<Arguments>(arguments)...))
107 std::forward<Arguments>(arguments)...);
110 template <
typename Factory>
115 : factory_(
std::move(factory))
124 std::is_nothrow_move_constructible<Factory>::value)
125 : factory_(
std::move(other.factory_))
126 , consumed_(other.consumed_)
128 other.consumed_ =
true;
148 template <
typename Callable>
164 return std::move(factory_);
172 template <
typename Factory>
177 return Result(std::forward<Factory>(factory));
182 template <
typename Holder,
typename Callable>
183 static auto apply(Holder& holder, Callable&& callable) ->
decltype(
184 std::forward<Callable>(callable)(holder.message()), holder)
186 std::forward<Callable>(callable)(holder.message());
191 template <
typename Callable>
195 template <
typename Argument>
197 : callable_(
std::forward<Argument>(callable))
211 template <
typename Result>
229 template <
typename SourceOperation,
typename CustomizationOperation>
234 : source_(
std::move(source))
235 , customization_(
std::move(customization))
239 template <
typename Holder>
240 auto apply(Holder& holder)
const ->
decltype(
241 std::declval<const CustomizationOperation&>().apply(
243 std::declval<const SourceOperation&>().
apply(std::declval<Holder&>()))>::type>&>()),
244 std::declval<const SourceOperation&>().apply(std::declval<Holder&>()))
246 using Result =
decltype(source_.apply(holder));
247 using Value =
typename std::remove_reference<Result>::type;
249 auto&& result = source_.apply(holder);
251 customization_.apply(resultHolder);
252 return std::forward<Result>(result);
256 SourceOperation source_;
257 CustomizationOperation customization_;
260 template <
typename SourceOperation,
typename CustomizationOperation>
261 BoundMessageOperation<typename std::decay<SourceOperation>::type,
typename std::decay<CustomizationOperation>::type>
265 typename std::decay<SourceOperation>::type,
266 typename std::decay<CustomizationOperation>::type>;
267 return Result(std::forward<SourceOperation>(source), std::forward<CustomizationOperation>(customization));
270 template <
typename SourceFactory,
typename CustomizationFactory>
275 : source_(
std::move(source))
276 , customization_(
std::move(customization))
281 std::declval<SourceFactory&>()(), std::declval<CustomizationFactory&>()()))
283 auto source = source_();
284 auto customization = customization_();
289 SourceFactory source_;
290 CustomizationFactory customization_;
293 template <
typename Factory>
294 template <
typename Callable>
302 std::move(*this).releaseFactory(), CustomizationFactory(std::forward<Callable>(callable))));
305 template <std::
size_t Index, std::
size_t Size>
308 template <
typename Holder,
typename Operations>
309 static void apply(Holder& holder,
const Operations& operations)
311 std::get<Index>(operations).apply(holder);
316 template <std::
size_t Size>
319 template <
typename Holder,
typename Operations>
320 static void apply(Holder&,
const Operations&)
325 template <
typename Holder,
typename Operation,
typename Result,
typename =
void>
330 template <
typename Holder,
typename Operation,
typename Result>
332 std::declval<const typename std::decay<Operation>::type&>().apply(std::declval<Holder&>()), void())>
346template <
typename Holder,
typename... Operations>
359 : operations_(
std::move(operations))
394 template <
typename Operation>
396 Holder, Operation,
MessageRecipe<Holder, Operations...,
typename std::decay<Operation>::type>>::Type
398 using Result =
MessageRecipe<Holder, Operations...,
typename std::decay<Operation>::type>;
399 return Result(std::tuple_cat(operations_, std::make_tuple(std::forward<Operation>(operation))));
408 template <
typename Operation>
410 Holder, Operation,
MessageRecipe<Holder, Operations...,
typename std::decay<Operation>::type>>::Type
412 using Result =
MessageRecipe<Holder, Operations...,
typename std::decay<Operation>::type>;
413 return Result(std::tuple_cat(std::move(operations_), std::make_tuple(std::forward<Operation>(operation))));
429 template <
typename Callable>
430 auto operator%(Callable&& callable)
const & ->
decltype(
431 std::declval<const MessageRecipe&>().append(
435 return append(std::move(operation));
451 template <
typename Callable>
453 std::move(*this).append(
457 return std::move(*this).append(std::move(operation));
461 std::tuple<Operations...> operations_;
469 template <
typename Holder,
typename... Operations>
472 template <
typename Holder,
typename Operation>
476 return Result(std::make_tuple(std::forward<Operation>(operation)));
490template <
typename Holder,
typename Factory>
493 decltype(std::move(deferredOperation).materialize().apply(message), message)>::type
495 auto operation = std::move(deferredOperation).materialize();
496 std::move(operation).apply(message);
512template <
typename Holder,
typename... Operations,
typename Factory>
516 recipe.append(std::move(deferredOperation).materialize()))
518 auto operation = std::move(deferredOperation).materialize();
519 return recipe.append(std::move(operation));
534template <
typename Holder,
typename... Operations,
typename Factory>
538 std::move(recipe).append(std::move(deferredOperation).materialize()))
540 auto operation = std::move(deferredOperation).materialize();
541 return std::move(recipe).append(std::move(operation));
545template <
typename Holder,
typename Operation>
546auto operator|(Holder&, Operation&&) ->
typename std::enable_if<
547 !details::IsMessageRecipe<typename std::decay<Holder>::type>::value &&
548 std::is_base_of<details::MessageOperationBase, typename std::decay<Operation>::type>::value,
549 void>::type =
delete;
552template <
typename Holder,
typename... Operations,
typename Operation>
553auto operator|(
const MessageRecipe<Holder, Operations...>&, Operation&&) ->
typename std::enable_if<
554 std::is_base_of<details::MessageOperationBase, typename std::decay<Operation>::type>::value,
555 void>::type =
delete;
558template <
typename Holder,
typename... Operations,
typename Operation>
559auto operator|(MessageRecipe<Holder, Operations...>&&, Operation&&) ->
typename std::enable_if<
560 std::is_base_of<details::MessageOperationBase, typename std::decay<Operation>::type>::value,
561 void>::type =
delete;
585#define ONIXS_CMEMDH_ENTRY(Action, ...) \
586 ONIXS_CME_MDH_TESTING_NAMESPACE::details::deferMessageOperation([&]() { \
587 return ONIXS_CME_MDH_TESTING_NAMESPACE::details::makeContextualEntryOperation< \
588 ONIXS_CMEMDH_MESSAGING_NAMESPACE::UpdateAction::Action>(__VA_ARGS__); \
#define ONIXS_CME_MDH_TESTING_NAMESPACE_END
#define ONIXS_CME_MDH_TESTING_NAMESPACE_BEGIN
#define ONIXS_CMEMDH_NODISCARD
Owns a reusable recipe for constructing a held test message.
auto append(Operation &&operation) &&-> typename details::ApplicableMessageOperationResult< Holder, Operation, MessageRecipe< Holder, Operations..., typename std::decay< Operation >::type > >::Type
Returns a recipe with one operation appended.
friend class MessageRecipe
Holder & operator()(Holder &holder) const
Initializes and populates a holder from this recipe.
auto operator%(Callable &&callable) const &-> decltype(std::declval< const MessageRecipe & >().append(details::makeMessageOperation< details::CallableOperation >(std::forward< Callable >(callable))))
Returns a recipe with an underlying-message customization appended.
auto append(Operation &&operation) const &-> typename details::ApplicableMessageOperationResult< Holder, Operation, MessageRecipe< Holder, Operations..., typename std::decay< Operation >::type > >::Type
Returns a recipe with one operation appended.
MessageRecipe(std::tuple< Operations... > operations)
Constructs a recipe from its owned operations.
Holder HolderType
Holder type materialized by this recipe.
void applyTo(Holder &holder) const
Initializes and populates a holder from this recipe.
auto operator%(Callable &&callable) &&-> decltype(std::move(*this).append(details::makeMessageOperation< details::CallableOperation >(std::forward< Callable >(callable))))
Returns a recipe with an underlying-message customization appended.
BoundMessageOperationFactory(SourceFactory source, CustomizationFactory customization)
auto operator()() -> decltype(makeBoundMessageOperation(std::declval< SourceFactory & >()(), std::declval< CustomizationFactory & >()()))
auto apply(Holder &holder) const -> decltype(std::declval< const CustomizationOperation & >().apply(std::declval< OperationResultHolder< typename std::remove_reference< decltype(std::declval< const SourceOperation & >().apply(std::declval< Holder & >()))>::type > & >()), std::declval< const SourceOperation & >().apply(std::declval< Holder & >()))
BoundMessageOperation(SourceOperation source, CustomizationOperation customization)
auto operator()() -> decltype(makeMessageOperation< CallableOperation >(std::declval< Callable && >()))
CallableOperationFactory(Argument &&callable)
auto operator%(Callable &&callable) &&-> DeferredMessageOperation< BoundMessageOperationFactory< Factory, CallableOperationFactory< typename std::decay< Callable >::type > > >
Binds a callable customization to this deferred operation's result.
DeferredMessageOperation(DeferredMessageOperation &&other) noexcept(std::is_nothrow_move_constructible< Factory >::value)
DeferredMessageOperation & operator=(const DeferredMessageOperation &)=delete
auto materialize() &&-> decltype(std::declval< Factory & >()())
Factory releaseFactory() &&
DeferredMessageOperation(Factory factory)
DeferredMessageOperation(const DeferredMessageOperation &)=delete
MessageOperation(Arguments... arguments)
auto apply(Holder &&message) const &-> decltype(applyMessageOperation< Operation >(std::forward< Holder >(message), std::declval< const std::tuple< Arguments... > & >(), typename MakeIndexSequence< sizeof...(Arguments)>::Type()))
auto apply(Holder &&message) &&-> decltype(applyMessageOperation< Operation >(std::forward< Holder >(message), std::declval< std::tuple< Arguments... > && >(), typename MakeIndexSequence< sizeof...(Arguments)>::Type()))
OperationResultHolder(Result &result) noexcept
Result & message() noexcept
DeferredMessageOperation< typename std::decay< Factory >::type > deferMessageOperation(Factory &&factory)
auto applyMessageOperation(Holder &&message, Arguments &&arguments, IndexSequence< Indices... >) -> decltype(Operation::apply(std::forward< Holder >(message), std::get< Indices >(std::forward< Arguments >(arguments))...))
MessageRecipe< Holder, typename std::decay< Operation >::type > makeMessageRecipe(Operation &&operation)
auto makeContextualEntryOperation(Arguments &&... arguments) -> decltype(makeMessageOperation< ContextualEntryOperation< Action > >(std::forward< Arguments >(arguments)...))
MessageOperation< Operation, typename std::decay< Arguments >::type... > makeMessageOperation(Arguments &&... arguments)
BoundMessageOperation< typename std::decay< SourceOperation >::type, typename std::decay< CustomizationOperation >::type > makeBoundMessageOperation(SourceOperation &&source, CustomizationOperation &&customization)
auto operator|(Holder &message, details::DeferredMessageOperation< Factory > &&deferredOperation) -> typename std::enable_if< !details::IsMessageRecipe< typename std::decay< Holder >::type >::value, decltype(std::move(deferredOperation).materialize().apply(message), message)>::type
Materializes and applies a deferred message operation to a named holder.
static void apply(Holder &, const Operations &)
static void apply(Holder &holder, const Operations &operations)
static auto apply(Holder &holder, Callable &&callable) -> decltype(std::forward< Callable >(callable)(holder.message()), holder)
static auto apply(Holder &message, Arguments &&... arguments) -> decltype(EntryOperationSelector< typename std::decay< Holder >::type::MessageType >::template apply< Action >(message, std::forward< Arguments >(arguments)...))