{"action":"created","comment":{"url":"https://api.github.com/repos/seqan/seqan3/pulls/comments/207891923","pull_request_review_id":143585666,"id":207891923,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDIwNzg5MTkyMw==","diff_hunk":"@@ -0,0 +1,1071 @@\n+// ============================================================================\n+//                 SeqAn - The Library for Sequence Analysis\n+// ============================================================================\n+//\n+// Copyright (c) 2006-2018, Knut Reinert & Freie Universitaet Berlin\n+// Copyright (c) 2016-2018, Knut Reinert & MPI Molekulare Genetik\n+// All rights reserved.\n+//\n+// Redistribution and use in source and binary forms, with or without\n+// modification, are permitted provided that the following conditions are met:\n+//\n+//     * Redistributions of source code must retain the above copyright\n+//       notice, this list of conditions and the following disclaimer.\n+//     * Redistributions in binary form must reproduce the above copyright\n+//       notice, this list of conditions and the following disclaimer in the\n+//       documentation and/or other materials provided with the distribution.\n+//     * Neither the name of Knut Reinert or the FU Berlin nor the names of\n+//       its contributors may be used to endorse or promote products derived\n+//       from this software without specific prior written permission.\n+//\n+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n+// ARE DISCLAIMED. IN NO EVENT SHALL KNUT REINERT OR THE FU BERLIN BE LIABLE\n+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n+// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH\n+// DAMAGE.\n+//\n+// ============================================================================\n+\n+/*!\\file\n+ * \\brief Provides seqan3::detail::configuration and utility functions.\n+ * \\author Rene Rahn <rene.rahn AT fu-berlin.de>\n+ */\n+\n+#pragma once\n+\n+#include <tuple>\n+\n+#include <meta/meta.hpp>\n+\n+#include <seqan3/core/algorithm/concept.hpp>\n+#include <seqan3/core/metafunction/basic.hpp>\n+#include <seqan3/core/metafunction/template_inspection.hpp>\n+#include <seqan3/core/type_list.hpp>\n+#include <seqan3/std/concept/callable.hpp>\n+#include <seqan3/std/concept/core_language.hpp>\n+\n+// Forward declaration for providing get interface for top-level namespace.\n+namespace seqan3\n+{\n+//!\\cond\n+template <size_t elem_no, typename ... _configs_t>\n+constexpr auto & get(detail::configuration<_configs_t...> &) noexcept;\n+\n+template <size_t elem_no, typename ... _configs_t>\n+constexpr auto const & get(detail::configuration<_configs_t...> const &) noexcept;\n+\n+template <size_t elem_no, typename ... _configs_t>\n+constexpr auto && get(detail::configuration<_configs_t...> &&) noexcept;\n+\n+template <size_t elem_no, typename ... _configs_t>\n+constexpr auto const && get(detail::configuration<_configs_t...> const &&) noexcept;\n+\n+template <typename target_t, typename ... _configs_t>\n+constexpr auto & get(detail::configuration<_configs_t...> &) noexcept;\n+\n+template <typename target_t, typename ... _configs_t>\n+constexpr auto const & get(detail::configuration<_configs_t...> const &) noexcept;\n+\n+template <typename target_t, typename ... _configs_t>\n+constexpr auto && get(detail::configuration<_configs_t...> &&) noexcept;\n+\n+template <typename target_t, typename ... _configs_t>\n+constexpr auto const && get(detail::configuration<_configs_t...> const &&) noexcept;\n+//!\\endcond\n+}\n+\n+namespace seqan3::detail\n+{\n+\n+//!\\cond\n+// Forward declaration.\n+template <typename ... args_t>\n+struct configuration_fn_proxy;\n+\n+template <typename derived_fn_t>\n+class configuration_fn_base;\n+//!\\endcond\n+\n+// ----------------------------------------------------------------------------\n+// configuration\n+// ----------------------------------------------------------------------------\n+\n+/*!\\brief Collection of configurations objects used to specify the runtime behavior of algorithms.\n+ * \\ingroup core_algorithm\n+ *\n+ * \\tparam configs_t Template parameter pack containing all the inherited configs. Must satisfy the\n+ *                   seqan3::detail::config_element_concept\n+ *\n+ * \\details\n+ *\n+ * This class provides a unified interface and additional helper functions to create and query configurations\n+ * for a specific algorithm. Certain bioinformatics algorithms, e.g. alignment or find interfaces, support a various set\n+ * of different configurations and policies that alter the execution of the algorithm. These configurations can be\n+ * orthogonal or might be mutual exclusive. Using this configuration the interface for the user becomes much more easier,\n+ * and incompatible configurations can be checked at compile time.\n+ *\n+ * \\attention\n+ *\n+ * This class uses multiple inheritance to inherit from the actual configuration types. This also means, that the same\n+ * configuration type cannot occur more than once in the type definition of the configuration class.\n+ *\n+ * ### Usage\n+ *\n+ * The entire configuration system is designed to work completely in the background of any algorithm. The implementor\n+ * of an algorithm only needs to provide the configurations for the algorithm.\n+ * In general the type of a configuration is static (see seqan3::detail::config_element_base) within the context of an algorithm\n+ * to select the correct code branches based on a policy-driven design, albeit the stored state might still be a runtime\n+ * parameter.\n+ * However, in some cases a specific configuration might be known first at runtime but needs to be converted to a static\n+ * type for the algorithm in use. To enable a transparent conversion from the runtime parameters to a static type\n+ * configuration one can use deferred configs (seqan3::detail::deferred_config_element_base), which are invocable\n+ * configurations, that store the runtime parameter and on invocation translate this runtime parameter to a static\n+ * configuration. The implementor of an algorithm can achieve this by using the function\n+ * seqan3::detail::apply_deferred_configs, which iterates through all configurations and in case\n+ * it is a deferred configuration it will invoke the translation function and continue with the modified configuration,\n+ * which contains now the static type for the specific configuration.\n+ *\n+ * ### Pipe Notation\n+ *\n+ * To enable simple extension of configurations the configuration provides a generic pipe interface for the different\n+ * configurations. Thus, a config class can be easily constructed by chaining together different properties.\n+ * Consider the following example, where we assume that the config `bar` and the config functor `with_foo` are already\n+ * given:\n+ *\n+ * ```cpp\n+ * auto my_cfg = configuration<bar>{} | with_foo;  // my_cfg is now of type configuration<foo, bar>\n+ * ```\n+ * The `with_foo` functor captures the `configuration<bar>` object and returns a new configuration with the added\n+ * `foo`-config.\n+\n+ * ### Tuple interface\n+ *\n+ * The configuration exposes a tuple interface. The type_trait functions std::tuple_size and std::tuple_element are\n+ * overloaded for this class. To access a specific element one can either use `seqan3::get` or `std::get` to query\n+ * the state of the configuration. Considering the example from above one can get the state of\n+ * the bar-config either as:\n+ *\n+ * ```cpp\n+ * auto bar_state = get<1>(my_cfg);\n+ * ```\n+ *\n+ * or as:\n+ *\n+ * ```cpp\n+ * auto bar_state = get<bar>(my_cfg);\n+ * ```\n+ *\n+ * In addition every algorithm specific config implementation can overload the get-interface with a enum based\n+ * get-interface, such that the correct config is extracted based on some type-independent enum value.\n+ * This is necessary for the algorithm implementation, as the algorithm neither knows the order nor the exact type of\n+ * all configs (the config type could be a template class).\n+ */\n+template <config_element_concept ... configs_t>\n+class configuration\n+{\n+    //!\\brief Friend declaration for other instances of the configuration.\n+    template <typename ... _configs_t>\n+    friend class configuration;\n+\n+    //!\\brief Helper function for constructing a configuration from the predecessor prior it's modification.\n+    template <typename ... old_configs_t,\n+              size_t ... Is>\n+    constexpr void transfer_config_elements(configuration<old_configs_t...> const & other,\n+                                            std::index_sequence<Is...> const & /*idx*/)\n+    {\n+        ((std::get<Is + 1>(this->config_elements) =\n+            std::get<std::tuple_element_t<Is + 1, std::tuple<configs_t...>>>(other.config_elements)), ...);\n+    }\n+\n+    //!\\copydoc configuration::transfer_config_elements\n+    template <typename ... old_configs_t,\n+              size_t ... Is>\n+    constexpr void transfer_config_elements(configuration<old_configs_t...> && other,\n+                                            std::index_sequence<Is...> const & /*idx*/)\n+    {\n+        ((std::get<Is + 1>(this->config_elements) =\n+            std::get<std::tuple_element_t<Is + 1, std::tuple<configs_t...>>>(std::move(other.config_elements))), ...);\n+    }\n+\n+public:\n+    /*!\\name Member types\n+     * \\{\n+     */\n+    //!\\brief Exposes the configurations as a seqan3::type_list to allow meta operations on this list.\n+    using type_list_type = type_list<configs_t...>;\n+    //!\\}\n+\n+    /*!\\name Constructor, destructor and assignment\n+     * \\brief Defaulted all standard constructor.\n+     * \\{\n+     */\n+    configuration()                                  = default;\n+    configuration(configuration const &)             = default;\n+    configuration(configuration &&)                  = default;\n+    configuration & operator=(configuration const &) = default;\n+    configuration & operator=(configuration &&)      = default;\n+    ~configuration()                                 = default;\n+\n+    /*!\\brief Constructs a configuration from the configuration prior to the modification with the new config.\n+     * \\tparam other_configs_t The other configs.\n+     * \\param cfg The configuration immediately prior to it's extension by another configuration.\n+     *\n+     * \\details\n+     *\n+     * Note, that this constructor is only enabled for types that are in direct relation to this class, namely for\n+     * types for which the following invariant holds: `configuration<configs...>` corresponds to\n+     * `configuration<head, configs...>`, with `decltype(*this) = configuration<head, configs...>`.\n+     */\n+    template <typename ... other_configs_t>\n+    constexpr configuration(configuration<other_configs_t ...> const & cfg) : configuration{}\n+    {\n+        if constexpr (sizeof...(configs_t) > 0)\n+            transfer_config_elements(cfg, std::make_index_sequence<sizeof...(configs_t) - 1>{});\n+    }\n+\n+    //!\\copydoc configuration::configuration(configuration<other_configs_t ...> const & cfg)\n+    template <typename ... other_configs_t>\n+    constexpr configuration(configuration<other_configs_t ...> && cfg) : configuration{}\n+    {\n+        if constexpr (sizeof...(configs_t) > 0)\n+            transfer_config_elements(std::move(cfg), std::make_index_sequence<sizeof...(configs_t) - 1>{});\n+    }\n+\n+    /*!\\brief Constructs a configuration from a variable of type seqan3::detail::configuration_fn_proxy or\n+     *        seqan3::detail::configuration_fn_base\n+     * \\tparam cfg_fn_t Either seqan3::detail::configuration_fn_proxy or seqan3::detail::configuration_fn_base.\n+     * \\param cfg_fn    A variable of type `cfg_fn_t`.\n+     *\n+     * \\details\n+     *\n+     * In some scenarios it might be possible, that only a single configuration element is used. In this case, the\n+     * configuration must be constructed from a variable of type seqan3::detail::configuration_fn_proxy\n+     * or seqan3::detail::configuration_fn_base. In order to construct a configuration object from it, this constructor\n+     * invokes the functor with an empty configuration.\n+     *\n+     * ### Example\n+     *\n+     * ```cpp\n+     * detail::configuration cfg = my_cfg(1, 2, 3);\n+     * ```\n+     * In the above example, we assume, that `my_cfg` is a variable of type seqan3::detail::configuration_fn_base.\n+     */\n+    template <typename cfg_fn_t>\n+    //!\\cond\n+        requires is_type_specialisation_of_v<std::remove_reference_t<cfg_fn_t>, configuration_fn_proxy> ||\n+                 std::is_base_of_v<configuration_fn_base<remove_cvref_t<cfg_fn_t>>, remove_cvref_t<cfg_fn_t>>\n+    //!\\endcond\n+    constexpr configuration(cfg_fn_t && cfg_fn) :\n+        configuration{std::invoke(std::forward<cfg_fn_t>(cfg_fn), configuration<>{})}\n+    {}\n+    //!\\}\n+\n+    //!\\cond\n+    template <size_t elem_no, typename ... _configs_t>\n+        requires (std::is_same_v<configs_t, _configs_t> && ...)\n+    friend constexpr auto & seqan3::get(configuration<_configs_t...> & cfg) noexcept;\n+\n+    //!\\copydoc seqan3::get()\n+    template <size_t elem_no, typename ... _configs_t>\n+        requires (std::is_same_v<configs_t, _configs_t> && ...)\n+    friend constexpr auto const & seqan3::get(configuration<_configs_t...> const &) noexcept;\n+\n+    //!\\copydoc seqan3::get<elem_no>(seqan3::detail::configuration)\n+    template <size_t elem_no, typename ... _configs_t>\n+        requires (std::is_same_v<configs_t, _configs_t> && ...)\n+    friend constexpr auto && seqan3::get(configuration<_configs_t...> &&) noexcept;\n+\n+    //!\\copydoc seqan3::get<elem_no>(seqan3::detail::configuration)\n+    template <size_t elem_no, typename ... _configs_t>\n+        requires (std::is_same_v<configs_t, _configs_t> && ...)\n+    friend constexpr auto const && seqan3::get(configuration<_configs_t...> const &&) noexcept;\n+\n+    template <typename target_t, typename ... _configs_t>\n+        requires (std::is_same_v<configs_t, _configs_t> && ...)\n+    friend constexpr auto & seqan3::get(configuration<_configs_t...> &) noexcept;\n+\n+    //!\\copydoc configuration::get()\n+    template <typename target_t, typename ... _configs_t>\n+        requires (std::is_same_v<configs_t, _configs_t> && ...)\n+    friend constexpr auto const & seqan3::get(configuration<_configs_t...> const &) noexcept;\n+\n+    //!\\copydoc configuration::get()\n+    template <typename target_t, typename ... _configs_t>\n+        requires (std::is_same_v<configs_t, _configs_t> && ...)\n+    friend constexpr auto && seqan3::get(configuration<_configs_t...> &&) noexcept;\n+\n+    //!\\copydoc configuration::get()\n+    template <typename target_t, typename ... _configs_t>\n+        requires (std::is_same_v<configs_t, _configs_t> && ...)\n+    friend constexpr auto const && seqan3::get(configuration<_configs_t...> const &&) noexcept;\n+    //!\\endcond\n+\n+private:\n+\n+    //!\\brief The cached config elements.\n+    std::tuple<configs_t...> config_elements;\n+};\n+\n+/*!\\name Deduction guide\n+ * \\relates seqan3::detail::configuration\n+ * \\{\n+ */\n+\n+//!\\brief Deduces the correct templates from a seqan3::detail::configuration_fn_proxy\n+template <typename cfg_proxy_t>\n+//!\\cond\n+    requires is_type_specialisation_of_v<std::remove_reference_t<cfg_proxy_t>, configuration_fn_proxy>\n+//!\\endcond\n+configuration(cfg_proxy_t &&) ->\n+    configuration<meta::front<typename std::invoke_result_t<std::remove_reference_t<cfg_proxy_t>,\n+                                                            configuration<>>::type_list_type>>;\n+\n+//!\\brief Deduces the correct templates from a seqan3::detail::configuration_fn_base\n+template <typename cfg_fn_t>\n+//!\\cond\n+    requires std::is_base_of_v<configuration_fn_base<remove_cvref_t<cfg_fn_t>>, remove_cvref_t<cfg_fn_t>>\n+//!\\endcond\n+configuration(cfg_fn_t &&) ->\n+    configuration<meta::front<typename std::invoke_result_t<std::remove_reference_t<cfg_fn_t>,\n+                                                                configuration<>>::type_list_type>>;\n+//!\\}\n+// ----------------------------------------------------------------------------\n+// Metafunction replace_config_with\n+// ----------------------------------------------------------------------------\n+\n+//!\\cond\n+template <typename configuration_t, detail::config_element_concept old_config_t, detail::config_element_concept new_config_t>\n+struct replace_config_with;\n+//!\\endcond\n+\n+/*!\\brief Helper traits meta-function to replace one configuration type with another by pushing it to the front of\n+ *        the configurations for a specific seqan3::detail::configuration.\n+ * \\ingroup core_algorithm\n+ * \\relates seqan3::detail::configuration\n+ *\n+ * \\tparam configuration_t The configuration type to be altered. Must be a template class.\n+ * \\tparam old_config_t   The old_config_t to be removed.\n+ * \\tparam new_config_t   The new_config_t to be added at the front of the configurations.\n+ *\n+ * \\details\n+ *\n+ * This meta-function parses the list of config types contained in the given seqan3::detail::configuration and\n+ * removes the `old_config_t` from the list if it exists, and adds `new_config_t` at the front of\n+ * the type list. Subsequently a new `configuration_t` type is defined containing the new config type list.\n+ *\n+ * \\see seqan3::detail::push_front_config\n+ * \\see seqan3::detail::replace_config_with_t\n+ */\n+template <template <typename ...> class configuration_t,\n+          detail::config_element_concept old_config_t,\n+          detail::config_element_concept new_config_t,\n+          detail::config_element_concept ... configs_t>\n+struct replace_config_with<configuration_t<configs_t...>, old_config_t, new_config_t>\n+{\n+protected:\n+\n+    //!\\cond\n+    template <typename target_t>\n+    struct invoke_exclude\n+    {\n+        /*!\\brief A template type which is used by meta::invoke.\n+         * \\tparam query_t The type to query.\n+         * \\returns `std::true_type` if `query_t` and `target_t` are not the same, `std::false_type` otherwise.\n+         */\n+        template <typename query_t>\n+        using invoke = std::negation<std::is_same<query_t, target_t>>;\n+    };\n+\n+    //!\\brief Helper typedef with the modified type_list.\n+    using _new_list = meta::push_front<meta::filter<seqan3::type_list<configs_t...>,\n+                                                    invoke_exclude<old_config_t>>,\n+                                       new_config_t>;\n+    //!\\endcond\n+public:\n+\n+    //!\\brief Typedef with the modified configuration type.\n+    using type = detail::transfer_template_args_onto_t<_new_list, configuration_t>;\n+};\n+\n+/*!\\brief Shortcut typedef for seqan3::detail::replace_config_with.\n+ * \\ingroup core_algorithm\n+ * \\see seqan3::detail::replace_config_with\n+ */\n+template <typename configuration_t, typename old_config_t, typename new_config_t>\n+using replace_config_with_t = typename replace_config_with<configuration_t, old_config_t, new_config_t>::type;\n+\n+//!\\cond\n+template <typename configuration_t, detail::config_element_concept new_config_t>\n+struct push_front_config;\n+//!\\endcond\n+\n+// ----------------------------------------------------------------------------\n+// Metafunction push_front_config\n+// ----------------------------------------------------------------------------\n+\n+/*!\\brief Helper traits meta-function to replace one configuration type with another by pushing it to the front of\n+ *        the configurations for a specific seqan3::detail::configuration.\n+ * \\ingroup core_algorithm\n+ *\n+ * \\tparam configuration_t The configuration type to be altered. Must be a template class.\n+ * \\tparam new_config_t   The new_config_t to be added at the front of the configurations.\n+ *\n+ * \\details\n+ *\n+ * This meta-function adds `new_config_t` at the front of the configuration.\n+ *\n+ * \\see seqan3::detail::push_front_config_t\n+ * \\see seqan3::detail::replace_config_with\n+ */\n+template <template <typename ...> class configuration_t,\n+          detail::config_element_concept new_config_t,\n+          detail::config_element_concept ... configs_t>\n+struct push_front_config<configuration_t<configs_t...>, new_config_t>\n+{\n+private:\n+    //!\\brief Helper typedef with the modified type_list.\n+    using _new_list = meta::push_front<seqan3::type_list<configs_t...>, new_config_t>;\n+public:\n+\n+    //!\\brief Typedef with the modified configuration type.\n+    using type = detail::transfer_template_args_onto_t<_new_list, configuration_t>;\n+};\n+\n+/*!\\brief Shortcut typedef for seqan3::detail::push_front_config.\n+ * \\ingroup core_algorithm\n+ * \\see seqan3::detail::push_front_config\n+ */\n+template <typename configuration_t, typename new_config_t>\n+using push_front_config_t = typename push_front_config<configuration_t, new_config_t>::type;\n+\n+// ----------------------------------------------------------------------------\n+// configuration_fn_base\n+// ----------------------------------------------------------------------------\n+\n+/*!\\brief An abstract crtp-base class to add pipeable concept for configuration functors in combination with\n+          seqan3::detail::configuration.\n+ * \\ingroup core_algorithm\n+ * \\tparam derived_t The derived type to be extended with functionality from this base class.\n+ *\n+ * \\details\n+ *\n+ * This abstract crtp-base class provides the configuration adaptor interface and the pipeable interface\n+ * for configurations and configuration elements.\n+ */\n+template <typename derived_fn_t>\n+class configuration_fn_base\n+{\n+protected:\n+\n+    /*!\\name Constructor, destructor and assignment\n+     * \\brief Abstract base class has no public constructor.\n+     * \\{\n+     */\n+    configuration_fn_base()                                          = default;\n+    configuration_fn_base(configuration_fn_base const &)             = default;\n+    configuration_fn_base(configuration_fn_base &&)                  = default;\n+    configuration_fn_base & operator=(configuration_fn_base const &) = default;\n+    configuration_fn_base & operator=(configuration_fn_base &&)      = default;\n+    ~configuration_fn_base()                                         = default;\n+    //!}\n+\n+public:\n+\n+    /*!\\brief Invokes the configuration specific functor to extend the seqan3::detail::configuration with the associated\n+     *        config.\n+     * \\tparam configuration_t The configuration to be extended with the new configuration type. Must be of type\n+     *                        seqan3::detail::configuration.\n+     * \\tparam args_t A template parameter pack with the arguments applied to the configuration functor call.\n+     *\n+     * \\param configuration The configuration to be extended.\n+     * \\param args         The argument pack to be passed to the functor.\n+     * \\returns A new seqan3::detail::configuration with the extended configuration.\n+     */\n+    template <typename configuration_t,\n+              typename ... args_t>\n+    constexpr auto operator()(configuration_t && configuration,\n+                              args_t && ... args) const\n+        requires is_algorithm_configuration_v<remove_cvref_t<configuration_t>>\n+    {\n+        return static_cast<derived_fn_t const &>(*this).invoke(std::forward<configuration_t>(configuration),\n+                                                               std::forward<args_t>(args)...);\n+    }\n+\n+    /*!\\brief Creates a proxy caching the arguments that should be applied when invoking the configuration specific\n+     *        configuration.\n+     * \\tparam args_t A template parameter pack with the arguments applied to the configuration functor call.\n+     *\n+     * \\param args A pack containing the arguments.\n+     * \\returns A proxy type used to defer configuration invocation.\n+     */\n+    template <typename ... args_t>\n+    constexpr configuration_fn_proxy<derived_fn_t, args_t...> operator()(args_t && ... args) const\n+    {\n+        return {{std::forward<args_t>(args)...}};\n+    }\n+};\n+\n+/*!\\name Pipe Interface\n+ * \\relates seqan3::detail::configuration_fn_base\n+ * \\{\n+ */\n+\n+/*!\\brief Combines a seqan3::detail::configuration with an configuration adaptor.\n+ * \\tparam configuration_t The configuration type to be extended. Must be of type seqan3::detail::configuration.\n+ * \\tparam fn_t            Either an instance of seqan3::detail::configuration_fn_proxy or\n+ *                         seqan3::detail::configuration_fn_base\n+ *\n+ * \\param[in] cfg The configuration to be extended.\n+ * \\param[in] fn  The functor implementation, invoking the associated configuration adaptor.\n+ * \\returns The result of invoking the configuration adaptor with the passed `cfg` object.\n+ */\n+template <typename configuration_t,\n+          typename fn_t>\n+constexpr auto operator|(configuration_t && cfg,\n+                         fn_t && fn)\n+//!\\cond\n+    requires is_algorithm_configuration_v<remove_cvref_t<configuration_t>> &&\n+             (is_type_specialisation_of_v<remove_cvref_t<fn_t>, configuration_fn_proxy> ||\n+              std::is_base_of_v<configuration_fn_base<remove_cvref_t<fn_t>>, remove_cvref_t<fn_t>>)\n+//!\\endcond\n+{\n+    return fn(std::forward<configuration_t>(cfg));\n+}","path":"include/seqan3/core/algorithm/configuration.hpp","position":539,"original_position":539,"commit_id":"f72e95398c26a0851bbcece86a343466eb3f33d6","original_commit_id":"f72e95398c26a0851bbcece86a343466eb3f33d6","user":{"login":"h-2","id":2996863,"node_id":"MDQ6VXNlcjI5OTY4NjM=","avatar_url":"https://avatars2.githubusercontent.com/u/2996863?v=4","gravatar_id":"","url":"https://api.github.com/users/h-2","html_url":"https://github.com/h-2","followers_url":"https://api.github.com/users/h-2/followers","following_url":"https://api.github.com/users/h-2/following{/other_user}","gists_url":"https://api.github.com/users/h-2/gists{/gist_id}","starred_url":"https://api.github.com/users/h-2/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/h-2/subscriptions","organizations_url":"https://api.github.com/users/h-2/orgs","repos_url":"https://api.github.com/users/h-2/repos","events_url":"https://api.github.com/users/h-2/events{/privacy}","received_events_url":"https://api.github.com/users/h-2/received_events","type":"User","site_admin":false},"body":"why not friend of the CRTP-base","created_at":"2018-08-06T13:31:51Z","updated_at":"2018-08-06T13:34:53Z","html_url":"https://github.com/seqan/seqan3/pull/346#discussion_r207891923","pull_request_url":"https://api.github.com/repos/seqan/seqan3/pulls/346","author_association":"MEMBER","_links":{"self":{"href":"https://api.github.com/repos/seqan/seqan3/pulls/comments/207891923"},"html":{"href":"https://github.com/seqan/seqan3/pull/346#discussion_r207891923"},"pull_request":{"href":"https://api.github.com/repos/seqan/seqan3/pulls/346"}}},"pull_request":{"url":"https://api.github.com/repos/seqan/seqan3/pulls/346","id":205878139,"node_id":"MDExOlB1bGxSZXF1ZXN0MjA1ODc4MTM5","html_url":"https://github.com/seqan/seqan3/pull/346","diff_url":"https://github.com/seqan/seqan3/pull/346.diff","patch_url":"https://github.com/seqan/seqan3/pull/346.patch","issue_url":"https://api.github.com/repos/seqan/seqan3/issues/346","number":346,"state":"open","locked":false,"title":"Feature/global align configuration","user":{"login":"rrahn","id":1529364,"node_id":"MDQ6VXNlcjE1MjkzNjQ=","avatar_url":"https://avatars2.githubusercontent.com/u/1529364?v=4","gravatar_id":"","url":"https://api.github.com/users/rrahn","html_url":"https://github.com/rrahn","followers_url":"https://api.github.com/users/rrahn/followers","following_url":"https://api.github.com/users/rrahn/following{/other_user}","gists_url":"https://api.github.com/users/rrahn/gists{/gist_id}","starred_url":"https://api.github.com/users/rrahn/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rrahn/subscriptions","organizations_url":"https://api.github.com/users/rrahn/orgs","repos_url":"https://api.github.com/users/rrahn/repos","events_url":"https://api.github.com/users/rrahn/events{/privacy}","received_events_url":"https://api.github.com/users/rrahn/received_events","type":"User","site_admin":false},"body":"@marehr and @cpockrandt so you can see how the usage is meant to be in combination with the configuration module.\r\n\r\nFixes #319 \r\n\r\nBlocked by #295.\r\nPlease only focus on the last commit.","created_at":"2018-08-02T22:24:35Z","updated_at":"2018-08-06T13:34:53Z","closed_at":null,"merged_at":null,"merge_commit_sha":"8ce430ecff4075af43a34d3140efe1c335105807","assignee":{"login":"h-2","id":2996863,"node_id":"MDQ6VXNlcjI5OTY4NjM=","avatar_url":"https://avatars2.githubusercontent.com/u/2996863?v=4","gravatar_id":"","url":"https://api.github.com/users/h-2","html_url":"https://github.com/h-2","followers_url":"https://api.github.com/users/h-2/followers","following_url":"https://api.github.com/users/h-2/following{/other_user}","gists_url":"https://api.github.com/users/h-2/gists{/gist_id}","starred_url":"https://api.github.com/users/h-2/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/h-2/subscriptions","organizations_url":"https://api.github.com/users/h-2/orgs","repos_url":"https://api.github.com/users/h-2/repos","events_url":"https://api.github.com/users/h-2/events{/privacy}","received_events_url":"https://api.github.com/users/h-2/received_events","type":"User","site_admin":false},"assignees":[{"login":"h-2","id":2996863,"node_id":"MDQ6VXNlcjI5OTY4NjM=","avatar_url":"https://avatars2.githubusercontent.com/u/2996863?v=4","gravatar_id":"","url":"https://api.github.com/users/h-2","html_url":"https://github.com/h-2","followers_url":"https://api.github.com/users/h-2/followers","following_url":"https://api.github.com/users/h-2/following{/other_user}","gists_url":"https://api.github.com/users/h-2/gists{/gist_id}","starred_url":"https://api.github.com/users/h-2/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/h-2/subscriptions","organizations_url":"https://api.github.com/users/h-2/orgs","repos_url":"https://api.github.com/users/h-2/repos","events_url":"https://api.github.com/users/h-2/events{/privacy}","received_events_url":"https://api.github.com/users/h-2/received_events","type":"User","site_admin":false}],"requested_reviewers":[{"login":"marehr","id":103778,"node_id":"MDQ6VXNlcjEwMzc3OA==","avatar_url":"https://avatars1.githubusercontent.com/u/103778?v=4","gravatar_id":"","url":"https://api.github.com/users/marehr","html_url":"https://github.com/marehr","followers_url":"https://api.github.com/users/marehr/followers","following_url":"https://api.github.com/users/marehr/following{/other_user}","gists_url":"https://api.github.com/users/marehr/gists{/gist_id}","starred_url":"https://api.github.com/users/marehr/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/marehr/subscriptions","organizations_url":"https://api.github.com/users/marehr/orgs","repos_url":"https://api.github.com/users/marehr/repos","events_url":"https://api.github.com/users/marehr/events{/privacy}","received_events_url":"https://api.github.com/users/marehr/received_events","type":"User","site_admin":false},{"login":"cpockrandt","id":7328307,"node_id":"MDQ6VXNlcjczMjgzMDc=","avatar_url":"https://avatars1.githubusercontent.com/u/7328307?v=4","gravatar_id":"","url":"https://api.github.com/users/cpockrandt","html_url":"https://github.com/cpockrandt","followers_url":"https://api.github.com/users/cpockrandt/followers","following_url":"https://api.github.com/users/cpockrandt/following{/other_user}","gists_url":"https://api.github.com/users/cpockrandt/gists{/gist_id}","starred_url":"https://api.github.com/users/cpockrandt/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/cpockrandt/subscriptions","organizations_url":"https://api.github.com/users/cpockrandt/orgs","repos_url":"https://api.github.com/users/cpockrandt/repos","events_url":"https://api.github.com/users/cpockrandt/events{/privacy}","received_events_url":"https://api.github.com/users/cpockrandt/received_events","type":"User","site_admin":false}],"requested_teams":[],"labels":[{"id":856552582,"node_id":"MDU6TGFiZWw4NTY1NTI1ODI=","url":"https://api.github.com/repos/seqan/seqan3/labels/blocked","name":"blocked","color":"b60205","default":false},{"id":568314043,"node_id":"MDU6TGFiZWw1NjgzMTQwNDM=","url":"https://api.github.com/repos/seqan/seqan3/labels/feature/proposal","name":"feature/proposal","color":"0e8a16","default":false}],"milestone":{"url":"https://api.github.com/repos/seqan/seqan3/milestones/11","html_url":"https://github.com/seqan/seqan3/milestone/11","labels_url":"https://api.github.com/repos/seqan/seqan3/milestones/11/labels","id":3539456,"node_id":"MDk6TWlsZXN0b25lMzUzOTQ1Ng==","number":11,"title":"Alignment Module","description":"For the workshop in September we need the following items from the Alignment module.\r\n\r\n* Compute Global/Semi-Global Alignment\r\n* Compute Mapping Coordinates\r\n* Compute Myers\r\n* Alignment Representation\r\n* CIGAR-view over alignment representation\r\n\r\nDependencies:\r\n* Configuration Module\r\n   * Output Configuration\r\n   * Scoring Scheme Configuration\r\n   * Gap Configuration\r\n   * Execution Configuration","creator":{"login":"rrahn","id":1529364,"node_id":"MDQ6VXNlcjE1MjkzNjQ=","avatar_url":"https://avatars2.githubusercontent.com/u/1529364?v=4","gravatar_id":"","url":"https://api.github.com/users/rrahn","html_url":"https://github.com/rrahn","followers_url":"https://api.github.com/users/rrahn/followers","following_url":"https://api.github.com/users/rrahn/following{/other_user}","gists_url":"https://api.github.com/users/rrahn/gists{/gist_id}","starred_url":"https://api.github.com/users/rrahn/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rrahn/subscriptions","organizations_url":"https://api.github.com/users/rrahn/orgs","repos_url":"https://api.github.com/users/rrahn/repos","events_url":"https://api.github.com/users/rrahn/events{/privacy}","received_events_url":"https://api.github.com/users/rrahn/received_events","type":"User","site_admin":false},"open_issues":26,"closed_issues":0,"state":"open","created_at":"2018-08-01T14:30:15Z","updated_at":"2018-08-05T17:30:01Z","due_on":"2018-08-31T07:00:00Z","closed_at":null},"commits_url":"https://api.github.com/repos/seqan/seqan3/pulls/346/commits","review_comments_url":"https://api.github.com/repos/seqan/seqan3/pulls/346/comments","review_comment_url":"https://api.github.com/repos/seqan/seqan3/pulls/comments{/number}","comments_url":"https://api.github.com/repos/seqan/seqan3/issues/346/comments","statuses_url":"https://api.github.com/repos/seqan/seqan3/statuses/f72e95398c26a0851bbcece86a343466eb3f33d6","head":{"label":"rrahn:feature/global_align_configuration","ref":"feature/global_align_configuration","sha":"f72e95398c26a0851bbcece86a343466eb3f33d6","user":{"login":"rrahn","id":1529364,"node_id":"MDQ6VXNlcjE1MjkzNjQ=","avatar_url":"https://avatars2.githubusercontent.com/u/1529364?v=4","gravatar_id":"","url":"https://api.github.com/users/rrahn","html_url":"https://github.com/rrahn","followers_url":"https://api.github.com/users/rrahn/followers","following_url":"https://api.github.com/users/rrahn/following{/other_user}","gists_url":"https://api.github.com/users/rrahn/gists{/gist_id}","starred_url":"https://api.github.com/users/rrahn/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rrahn/subscriptions","organizations_url":"https://api.github.com/users/rrahn/orgs","repos_url":"https://api.github.com/users/rrahn/repos","events_url":"https://api.github.com/users/rrahn/events{/privacy}","received_events_url":"https://api.github.com/users/rrahn/received_events","type":"User","site_admin":false},"repo":{"id":85306117,"node_id":"MDEwOlJlcG9zaXRvcnk4NTMwNjExNw==","name":"seqan3","full_name":"rrahn/seqan3","owner":{"login":"rrahn","id":1529364,"node_id":"MDQ6VXNlcjE1MjkzNjQ=","avatar_url":"https://avatars2.githubusercontent.com/u/1529364?v=4","gravatar_id":"","url":"https://api.github.com/users/rrahn","html_url":"https://github.com/rrahn","followers_url":"https://api.github.com/users/rrahn/followers","following_url":"https://api.github.com/users/rrahn/following{/other_user}","gists_url":"https://api.github.com/users/rrahn/gists{/gist_id}","starred_url":"https://api.github.com/users/rrahn/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rrahn/subscriptions","organizations_url":"https://api.github.com/users/rrahn/orgs","repos_url":"https://api.github.com/users/rrahn/repos","events_url":"https://api.github.com/users/rrahn/events{/privacy}","received_events_url":"https://api.github.com/users/rrahn/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/rrahn/seqan3","description":"The modern C++ library for sequence analysis. Contains version 3 of the library and API docs.","fork":true,"url":"https://api.github.com/repos/rrahn/seqan3","forks_url":"https://api.github.com/repos/rrahn/seqan3/forks","keys_url":"https://api.github.com/repos/rrahn/seqan3/keys{/key_id}","collaborators_url":"https://api.github.com/repos/rrahn/seqan3/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/rrahn/seqan3/teams","hooks_url":"https://api.github.com/repos/rrahn/seqan3/hooks","issue_events_url":"https://api.github.com/repos/rrahn/seqan3/issues/events{/number}","events_url":"https://api.github.com/repos/rrahn/seqan3/events","assignees_url":"https://api.github.com/repos/rrahn/seqan3/assignees{/user}","branches_url":"https://api.github.com/repos/rrahn/seqan3/branches{/branch}","tags_url":"https://api.github.com/repos/rrahn/seqan3/tags","blobs_url":"https://api.github.com/repos/rrahn/seqan3/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/rrahn/seqan3/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/rrahn/seqan3/git/refs{/sha}","trees_url":"https://api.github.com/repos/rrahn/seqan3/git/trees{/sha}","statuses_url":"https://api.github.com/repos/rrahn/seqan3/statuses/{sha}","languages_url":"https://api.github.com/repos/rrahn/seqan3/languages","stargazers_url":"https://api.github.com/repos/rrahn/seqan3/stargazers","contributors_url":"https://api.github.com/repos/rrahn/seqan3/contributors","subscribers_url":"https://api.github.com/repos/rrahn/seqan3/subscribers","subscription_url":"https://api.github.com/repos/rrahn/seqan3/subscription","commits_url":"https://api.github.com/repos/rrahn/seqan3/commits{/sha}","git_commits_url":"https://api.github.com/repos/rrahn/seqan3/git/commits{/sha}","comments_url":"https://api.github.com/repos/rrahn/seqan3/comments{/number}","issue_comment_url":"https://api.github.com/repos/rrahn/seqan3/issues/comments{/number}","contents_url":"https://api.github.com/repos/rrahn/seqan3/contents/{+path}","compare_url":"https://api.github.com/repos/rrahn/seqan3/compare/{base}...{head}","merges_url":"https://api.github.com/repos/rrahn/seqan3/merges","archive_url":"https://api.github.com/repos/rrahn/seqan3/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/rrahn/seqan3/downloads","issues_url":"https://api.github.com/repos/rrahn/seqan3/issues{/number}","pulls_url":"https://api.github.com/repos/rrahn/seqan3/pulls{/number}","milestones_url":"https://api.github.com/repos/rrahn/seqan3/milestones{/number}","notifications_url":"https://api.github.com/repos/rrahn/seqan3/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/rrahn/seqan3/labels{/name}","releases_url":"https://api.github.com/repos/rrahn/seqan3/releases{/id}","deployments_url":"https://api.github.com/repos/rrahn/seqan3/deployments","created_at":"2017-03-17T11:48:48Z","updated_at":"2017-03-15T02:18:16Z","pushed_at":"2018-08-05T16:42:12Z","git_url":"git://github.com/rrahn/seqan3.git","ssh_url":"git@github.com:rrahn/seqan3.git","clone_url":"https://github.com/rrahn/seqan3.git","svn_url":"https://github.com/rrahn/seqan3","homepage":"http://www.seqan.de","size":1123,"stargazers_count":0,"watchers_count":0,"language":null,"has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":0,"license":null,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"seqan:master","ref":"master","sha":"77427cc81ec0dfaef75aa223bffcbbaa26146ba7","user":{"login":"seqan","id":1752144,"node_id":"MDEyOk9yZ2FuaXphdGlvbjE3NTIxNDQ=","avatar_url":"https://avatars2.githubusercontent.com/u/1752144?v=4","gravatar_id":"","url":"https://api.github.com/users/seqan","html_url":"https://github.com/seqan","followers_url":"https://api.github.com/users/seqan/followers","following_url":"https://api.github.com/users/seqan/following{/other_user}","gists_url":"https://api.github.com/users/seqan/gists{/gist_id}","starred_url":"https://api.github.com/users/seqan/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/seqan/subscriptions","organizations_url":"https://api.github.com/users/seqan/orgs","repos_url":"https://api.github.com/users/seqan/repos","events_url":"https://api.github.com/users/seqan/events{/privacy}","received_events_url":"https://api.github.com/users/seqan/received_events","type":"Organization","site_admin":false},"repo":{"id":55410078,"node_id":"MDEwOlJlcG9zaXRvcnk1NTQxMDA3OA==","name":"seqan3","full_name":"seqan/seqan3","owner":{"login":"seqan","id":1752144,"node_id":"MDEyOk9yZ2FuaXphdGlvbjE3NTIxNDQ=","avatar_url":"https://avatars2.githubusercontent.com/u/1752144?v=4","gravatar_id":"","url":"https://api.github.com/users/seqan","html_url":"https://github.com/seqan","followers_url":"https://api.github.com/users/seqan/followers","following_url":"https://api.github.com/users/seqan/following{/other_user}","gists_url":"https://api.github.com/users/seqan/gists{/gist_id}","starred_url":"https://api.github.com/users/seqan/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/seqan/subscriptions","organizations_url":"https://api.github.com/users/seqan/orgs","repos_url":"https://api.github.com/users/seqan/repos","events_url":"https://api.github.com/users/seqan/events{/privacy}","received_events_url":"https://api.github.com/users/seqan/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/seqan/seqan3","description":"The modern C++ library for sequence analysis. Contains version 3 of the library and API docs.","fork":false,"url":"https://api.github.com/repos/seqan/seqan3","forks_url":"https://api.github.com/repos/seqan/seqan3/forks","keys_url":"https://api.github.com/repos/seqan/seqan3/keys{/key_id}","collaborators_url":"https://api.github.com/repos/seqan/seqan3/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/seqan/seqan3/teams","hooks_url":"https://api.github.com/repos/seqan/seqan3/hooks","issue_events_url":"https://api.github.com/repos/seqan/seqan3/issues/events{/number}","events_url":"https://api.github.com/repos/seqan/seqan3/events","assignees_url":"https://api.github.com/repos/seqan/seqan3/assignees{/user}","branches_url":"https://api.github.com/repos/seqan/seqan3/branches{/branch}","tags_url":"https://api.github.com/repos/seqan/seqan3/tags","blobs_url":"https://api.github.com/repos/seqan/seqan3/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/seqan/seqan3/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/seqan/seqan3/git/refs{/sha}","trees_url":"https://api.github.com/repos/seqan/seqan3/git/trees{/sha}","statuses_url":"https://api.github.com/repos/seqan/seqan3/statuses/{sha}","languages_url":"https://api.github.com/repos/seqan/seqan3/languages","stargazers_url":"https://api.github.com/repos/seqan/seqan3/stargazers","contributors_url":"https://api.github.com/repos/seqan/seqan3/contributors","subscribers_url":"https://api.github.com/repos/seqan/seqan3/subscribers","subscription_url":"https://api.github.com/repos/seqan/seqan3/subscription","commits_url":"https://api.github.com/repos/seqan/seqan3/commits{/sha}","git_commits_url":"https://api.github.com/repos/seqan/seqan3/git/commits{/sha}","comments_url":"https://api.github.com/repos/seqan/seqan3/comments{/number}","issue_comment_url":"https://api.github.com/repos/seqan/seqan3/issues/comments{/number}","contents_url":"https://api.github.com/repos/seqan/seqan3/contents/{+path}","compare_url":"https://api.github.com/repos/seqan/seqan3/compare/{base}...{head}","merges_url":"https://api.github.com/repos/seqan/seqan3/merges","archive_url":"https://api.github.com/repos/seqan/seqan3/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/seqan/seqan3/downloads","issues_url":"https://api.github.com/repos/seqan/seqan3/issues{/number}","pulls_url":"https://api.github.com/repos/seqan/seqan3/pulls{/number}","milestones_url":"https://api.github.com/repos/seqan/seqan3/milestones{/number}","notifications_url":"https://api.github.com/repos/seqan/seqan3/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/seqan/seqan3/labels{/name}","releases_url":"https://api.github.com/repos/seqan/seqan3/releases{/id}","deployments_url":"https://api.github.com/repos/seqan/seqan3/deployments","created_at":"2016-04-04T12:39:15Z","updated_at":"2018-08-02T21:58:54Z","pushed_at":"2018-08-06T11:22:00Z","git_url":"git://github.com/seqan/seqan3.git","ssh_url":"git@github.com:seqan/seqan3.git","clone_url":"https://github.com/seqan/seqan3.git","svn_url":"https://github.com/seqan/seqan3","homepage":"http://www.seqan.de","size":1048,"stargazers_count":30,"watchers_count":30,"language":"C++","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":25,"mirror_url":null,"archived":false,"open_issues_count":130,"license":{"key":"other","name":"Other","spdx_id":null,"url":null,"node_id":"MDc6TGljZW5zZTA="},"forks":25,"open_issues":130,"watchers":30,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/seqan/seqan3/pulls/346"},"html":{"href":"https://github.com/seqan/seqan3/pull/346"},"issue":{"href":"https://api.github.com/repos/seqan/seqan3/issues/346"},"comments":{"href":"https://api.github.com/repos/seqan/seqan3/issues/346/comments"},"review_comments":{"href":"https://api.github.com/repos/seqan/seqan3/pulls/346/comments"},"review_comment":{"href":"https://api.github.com/repos/seqan/seqan3/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/seqan/seqan3/pulls/346/commits"},"statuses":{"href":"https://api.github.com/repos/seqan/seqan3/statuses/f72e95398c26a0851bbcece86a343466eb3f33d6"}},"author_association":"COLLABORATOR"}}
{"actor":{"display_login":"h-2"}}