44 #include <meta/meta.hpp> 58 template <
typename derived_t,
typename ... args_t>
59 struct configuration_fn_proxy;
61 template <
typename derived_fn_t>
62 class configuration_fn_base;
128 template <config_element_concept ... configs_t>
129 class configuration :
public std::tuple<configs_t...>
132 template <config_element_concept ... _configs_t>
133 friend class configuration;
139 using base_type = std::tuple<configs_t...>;
146 constexpr configuration() =
default;
147 constexpr configuration(configuration
const &) =
default;
148 constexpr configuration(configuration &&) =
default;
149 constexpr configuration & operator=(configuration
const &) =
default;
150 constexpr configuration & operator=(configuration &&) =
default;
151 ~configuration() =
default;
154 constexpr configuration(std::tuple<configs_t...>
const & cfg) : base_type{cfg}
158 constexpr configuration(std::tuple<configs_t...> && cfg) : base_type{std::move(cfg)}
178 template <
typename cfg_fn_t>
180 requires is_type_specialisation_of_v<std::remove_reference_t<cfg_fn_t>, configuration_fn_proxy> ||
181 std::is_base_of_v<configuration_fn_base<remove_cvref_t<cfg_fn_t>>, remove_cvref_t<cfg_fn_t>>
183 constexpr configuration(cfg_fn_t && cfg_fn) :
184 configuration{std::invoke(std::forward<cfg_fn_t>(cfg_fn), configuration<>{})}
192 constexpr
size_t size() const noexcept
195 return std::tuple_size_v<base_type>;
218 template <config_element_concept config_element_t>
219 constexpr
auto push_front(config_element_t && cfg_element)
const &
221 return detail::configuration{std::tuple_cat(std::tuple{std::forward<config_element_t>(cfg_element)},
222 static_cast<base_type>(*
this))};
226 template <config_element_concept config_element_t>
227 constexpr
auto push_front(config_element_t && cfg_element) &&
229 return detail::configuration{std::tuple_cat(std::tuple{std::forward<config_element_t>(cfg_element)},
230 std::move(static_cast<base_type>(*
this)))};
250 template <config_element_concept old_config_element_t,
251 config_element_concept new_config_element_t>
252 constexpr
auto replace_with(old_config_element_t
const & SEQAN3_DOXYGEN_ONLY(old_element),
253 new_config_element_t && new_element)
const &
255 static_assert(std::tuple_size_v<base_type> > 0,
"The configuration cannot be empty.");
256 static_assert(meta::find_index<transfer_template_args_onto_t<base_type, type_list>,
257 old_config_element_t>::value != meta::npos::value,
258 "The element to be replaced is not contained in the passed configuration.");
260 auto && [prefix, remainder] = seqan3::tuple_split<old_config_element_t>(
static_cast<base_type
>(*this));
262 return detail::configuration{std::tuple_cat(std::move(prefix),
263 std::tuple{std::forward<new_config_element_t>(new_element)},
268 template <config_element_concept old_config_element_t,
269 config_element_concept new_config_element_t>
270 constexpr
auto replace_with(old_config_element_t
const & SEQAN3_DOXYGEN_ONLY(old_element),
271 new_config_element_t && new_element) &&
273 static_assert(std::tuple_size_v<base_type> > 0,
"The configuration cannot be empty.");
274 static_assert(meta::find_index<transfer_template_args_onto_t<base_type, type_list>,
275 old_config_element_t>::value != meta::npos::value,
276 "The element to be replaced is not contained in the passed configuration.");
278 auto && [prefix, remainder] =
279 seqan3::tuple_split<old_config_element_t>(std::move(static_cast<base_type>(*
this)));
281 return detail::configuration{std::tuple_cat(std::move(prefix),
282 std::tuple{std::forward<new_config_element_t>(new_element)},
293 template <
typename cfg_fn_t>
296 requires is_type_specialisation_of_v<std::remove_reference_t<cfg_fn_t>, configuration_fn_proxy> ||
297 std::is_base_of_v<configuration_fn_base<remove_cvref_t<cfg_fn_t>>, remove_cvref_t<cfg_fn_t>>
299 configuration(cfg_fn_t &&) ->
300 configuration<meta::front<detail::tuple_type_list_t<typename std::invoke_result_t<std::remove_reference_t<cfg_fn_t>,
301 configuration<>>::base_type>>>;
319 template <
typename target_t,
typename query_t>
321 requires !is_algorithm_configuration_v<remove_cvref_t<target_t>>
323 struct is_configuration_combinable_with
326 static constexpr
bool value =
327 (std::is_base_of_v<configuration_fn_base<remove_cvref_t<target_t>>, remove_cvref_t<target_t>> ||
328 is_type_specialisation_of_v<remove_cvref_t<target_t>, configuration_fn_proxy>) &&
329 (is_type_specialisation_of_v<remove_cvref_t<query_t>, configuration_fn_proxy> ||
330 (std::is_base_of_v<configuration_fn_base<remove_cvref_t<query_t>>, remove_cvref_t<query_t>> &&
331 !std::is_same_v<remove_cvref_t<target_t>, remove_cvref_t<query_t>>));
336 template <
typename target_t,
typename query_t>
338 requires !is_algorithm_configuration_v<remove_cvref_t<target_t>>
340 inline constexpr
bool is_configuration_combinable_with_v = is_configuration_combinable_with<target_t, query_t>::value;
356 template <
typename derived_fn_t>
357 class configuration_fn_base
365 configuration_fn_base() =
default;
366 configuration_fn_base(configuration_fn_base
const &) =
default;
367 configuration_fn_base(configuration_fn_base &&) =
default;
368 configuration_fn_base & operator=(configuration_fn_base
const &) =
default;
369 configuration_fn_base & operator=(configuration_fn_base &&) =
default;
370 ~configuration_fn_base() =
default;
385 template <
typename configuration_t,
387 constexpr
auto operator()(configuration_t && configuration,
388 args_t && ... args)
const 390 requires is_algorithm_configuration_v<remove_cvref_t<configuration_t>>
393 return static_cast<derived_fn_t
const &
>(*this).invoke(std::forward<configuration_t>(configuration),
394 std::forward<args_t>(args)...);
404 template <
typename ... args_t>
405 constexpr configuration_fn_proxy<derived_fn_t, args_t...> operator()(args_t && ... args)
const 407 return {std::forward<args_t>(args)...};
425 template <
typename configuration_t,
427 constexpr
auto operator|(configuration_t && cfg,
430 requires is_algorithm_configuration_v<remove_cvref_t<configuration_t>> &&
431 (is_type_specialisation_of_v<remove_cvref_t<fn_t>, configuration_fn_proxy> ||
432 std::is_base_of_v<configuration_fn_base<remove_cvref_t<fn_t>>, remove_cvref_t<fn_t>>)
435 return fn(std::forward<configuration_t>(cfg));
457 template <
typename lhs_fn_t,
459 constexpr
auto operator|(lhs_fn_t && lhs_fn,
462 requires is_configuration_combinable_with_v<lhs_fn_t, rhs_fn_t>
465 return rhs_fn(std::forward<lhs_fn_t>(lhs_fn)(configuration<>{}));
486 template <
typename derived_t,
typename ... args_t>
487 struct configuration_fn_proxy
492 template <
typename t>
493 friend class configuration_fn_base;
496 constexpr configuration_fn_proxy(args_t && ... args) : args_cache{std::forward<args_t>(args)...}
503 template <
typename configuration_t, std::size_t ... Is>
504 constexpr
auto explode(configuration_t && cfg, std::index_sequence<Is...> ) &&
507 return derived_t{}(std::forward<configuration_t>(cfg), std::move(std::get<Is>(args_cache))...);
510 template <
typename configuration_t, std::size_t ... Is>
511 constexpr
auto explode(configuration_t && cfg, std::index_sequence<Is...> )
const &
514 return derived_t{}(std::forward<configuration_t>(cfg), std::get<Is>(args_cache)...);
519 std::tuple<args_t...> args_cache;
525 template <
typename configuration_t>
526 constexpr
auto operator()(configuration_t && cfg) &&
528 return explode(std::forward<configuration_t>(cfg), std::make_index_sequence<
sizeof...(args_t)>{});
531 template <
typename configuration_t>
532 constexpr
auto operator()(configuration_t && cfg)
const &
534 return explode(std::forward<configuration_t>(cfg), std::make_index_sequence<
sizeof...(args_t)>{});
549 template <std::
size_t N,
typename fn_t,
typename config_t>
550 constexpr
auto apply_deferred_configs(fn_t && fn,
552 requires is_algorithm_configuration_v<remove_cvref_t<config_t>>
554 if constexpr (N == 0)
556 return fn(std::forward<config_t>(config));
560 using config_as_list = detail::transfer_template_args_onto_t<remove_cvref_t<config_t>,
type_list>;
561 using current_config_t = meta::at_c<config_as_list, meta::size<config_as_list>::value - N>;
563 auto delegate = [&fn](
auto && new_config)
565 return apply_deferred_configs<N-1>(fn, std::forward<decltype(new_config)>(new_config));
568 if constexpr (std::is_invocable_v<current_config_t, decltype(delegate), remove_cvref_t<config_t>>)
570 return current_config_t{}(delegate, std::forward<config_t>(config));
574 return apply_deferred_configs<N - 1>(fn, std::forward<config_t>(config));
579 template <
typename fn_t,
typename config_t>
580 constexpr
auto apply_deferred_configs(fn_t & fn,
582 requires is_algorithm_configuration_v<remove_cvref_t<config_t>> &&
585 using type_list_t = detail::tuple_type_list_t<typename std::remove_reference_t<config_t>::base_type>;
586 return apply_deferred_configs<meta::size<type_list_t>::value>(std::forward<fn_t>(fn),
587 std::forward<config_t>(config));
599 template <seqan3::detail::config_element_concept ... configs_t>
600 struct tuple_size<
seqan3::detail::configuration<configs_t...>>
603 static constexpr
size_t value = std::tuple_size_v<
typename seqan3::detail::configuration<configs_t...>::base_type>;
609 template <
size_t pos, seqan3::detail::config_element_concept ... configs_t>
610 struct tuple_element<pos,
seqan3::detail::configuration<configs_t...>>
613 using type = std::tuple_element_t<pos,
typename seqan3::detail::configuration<configs_t...>::base_type>;
Provides concepts for the configuration classes.
Provides seqan3::type_list and auxiliary metafunctions.
Specifies whether the given callable is invocable with the given arguments.
SeqAn specific customisations in the standard namespace.
Definition: align_result.hpp:221
::ranges::size size
Alias for ranges::size. Obtains the size of a range whose size can be calculated in constant time...
Definition: ranges:195
The main SeqAn3 namespace.
Definition: aligned_sequence_concept.hpp:58
Provides seqan3::type_list and auxiliary metafunctions.
Provides utility functions for tuple like interfaces.
Definition: aligned_sequence_concept.hpp:288
Provides various metafunctions on generic types.
auto operator|(validator1_type &&vali1, validator2_type &&vali2)
Enables the chaining of validators. !
Definition: validators.hpp:671
constexpr auto tuple_pop_front(tuple_t &&t)
Removes the first element of a tuple.
Definition: tuple_utility.hpp:194
meta::list< types... > type_list
Type that contains multiple types, an alias for meta::list.
Definition: type_list.hpp:54