text: // -----------------------------------------------------------------------------------------------------
  // Copyright (c) 2006-2020, Knut Reinert & Freie Universität Berlin
  // Copyright (c) 2016-2020, Knut Reinert & MPI für molekulare Genetik
  // This file may be used, modified and/or redistributed under the terms of the 3-clause BSD-License
  // shipped with this file and also available at: https://github.com/seqan/seqan3/blob/master/LICENSE.md
  // -----------------------------------------------------------------------------------------------------
  
  /*!\file
   * \brief Provides compatibility matrix for search configurations.
   * \author Rene Rahn <rene.rahn AT fu-berlin.de>
   * \author Lydia Buntrock <lydia.buntrock AT fu-berlin.de>
   */
  
  #pragma once
  
  #include <seqan3/core/configuration/detail/configuration_utility.hpp>
  
  namespace seqan3::detail
  {
  
  // ----------------------------------------------------------------------------
  // search_config_id
  // ----------------------------------------------------------------------------
  
  /*!\brief Specifies an id for every configuration element.
   * \ingroup search_configuration
   *
   * \details
   *
   * The seqan3::detail::search_config_id used to identify a specific search configuration element independent of
   * its concrete type and position within the \ref seqan3::search_cfg "search configuration object".
   * Thus one can access the value of the corresponding configuration element via the special get interface.
   *
   * ### Example
   *
   * ```cpp
   * search_cfg cfg = search_cfg::max_total_errors(3);
   * auto max_total_errors = get<search_cfg::id::max_total_errors>(cfg);  // max_total_errors = 3;
   * ```
   */
  enum struct search_config_id : uint8_t
  {
      max_error_total, //!< Identifier for the max_error_total configuration.
      max_error_substitution, //!< Identifier for the max_error_substitution configuration.
      max_error_insertion, //!< Identifier for the max_error_insertion configuration.
      max_error_deletion, //!< Identifier for the max_error_deletion configuration.
      on_result, //!< Identifier for the configuration to pass a user defined callable.
      output_query_id, //!< Identifier for the output configuration of the query_id.
      output_reference_id, //!< Identifier for the output configuration of the reference_id.
      output_reference_begin_position, //!< Identifier for the output configuration of the reference_begin_position.
      output_index_cursor, //!< Identifier for the output configuration of the index_cursor.
      hit, //!< Identifier for the hit configuration (all, all_best, single_best, strata).
      parallel, //!< Identifier for the parallel execution configuration.
      result_type, //!< Identifier for the configured search result type.
      //!\cond
      // ATTENTION: Must always be the last item; will be used to determine the number of ids.
      SIZE //!< Determines the size of the enum.
      //!\endcond
  };
  
  // ----------------------------------------------------------------------------
  // search_config_validation_matrix
  // ----------------------------------------------------------------------------
  
  /*!\brief Compatibility matrix to check how search configuration elements can be combined.
   * \ingroup search_configuration
   *
   * \details
   *
   * This matrix is used to check if the specified search configurations can be combined with each other.
   * A cell value `true`, indicates that the corresponding seqan3::detail::search_config_id in the current column can
   * be combined with the associated seqan3::detail::search_config in the current row. The size of the matrix is
   * determined by the enum value `SIZE` of seqan3::detail::search_config_id.
   */
  template <>
  inline constexpr std::array<std::array<bool, static_cast<uint8_t>(search_config_id::SIZE)>,
                              static_cast<uint8_t>(search_config_id::SIZE)> compatibility_table<search_config_id> =
  {
      {
         // max_error_total,
         // |  max_error_substitution,
         // |  |  max_error_insertion,
         // |  |  |  max_error_deletion,
         // |  |  |  |  on_result,
         // |  |  |  |  |  output_query_id,
         // |  |  |  |  |  |  output_reference_id,
         // |  |  |  |  |  |  |  output_reference_begin_position,
         // |  |  |  |  |  |  |  |  output_index_cursor,
         // |  |  |  |  |  |  |  |  |  hit,
         // |  |  |  |  |  |  |  |  |  |  parallel,
         // |  |  |  |  |  |  |  |  |  |  |  result_type
          { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, // max_error_total
          { 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, // max_error_substitution
          { 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1}, // max_error_insertion
          { 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1}, // max_error_deletion
          { 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1}, // on_result
          { 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1}, // output_query_id
          { 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1}, // output_reference_id
          { 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1}, // output_reference_begin_position
          { 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1}, // output_index_cursor
          { 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1}, // hit
          { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1}, // parallel
          { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}  // result_type
      }
  };
  
  } // namespace seqan3::detail
  