Loading...
Searching...
No Matches
detail/record.hpp
// SPDX-FileCopyrightText: 2006-2025 Knut Reinert & Freie Universität Berlin
// SPDX-FileCopyrightText: 2016-2025 Knut Reinert & MPI für molekulare Genetik
// SPDX-License-Identifier: BSD-3-Clause
#pragma once
#include <ranges>
#include <seqan3/io/record.hpp>
#include <seqan3/utility/tuple/concept.hpp>
#include <seqan3/utility/type_list/traits.hpp>
#include <seqan3/utility/views/repeat.hpp>
namespace seqan3::detail
{
// ----------------------------------------------------------------------------
// Fields
// ----------------------------------------------------------------------------
template <typename t>
concept fields_specialisation = is_value_specialisation_of_v<t, fields>;
// ----------------------------------------------------------------------------
// select_types_with_ids
// ----------------------------------------------------------------------------
template <typename field_types,
typename field_types_as_ids,
typename selected_field_ids,
size_t field_no = 0,
typename... return_types>
struct select_types_with_ids // unconstrained template is recursion anchor
{
using type = type_list<return_types...>;
};
template <typename field_types,
typename field_types_as_ids,
typename selected_field_ids,
size_t field_no = 0,
typename... return_types>
using select_types_with_ids_t =
typename select_types_with_ids<field_types, field_types_as_ids, selected_field_ids, field_no, return_types...>::
type;
template <typename field_types,
typename field_types_as_ids,
typename selected_field_ids,
size_t field_no,
typename... return_types>
requires (field_no < selected_field_ids::as_array.size()) // perform recursion while not at end
struct select_types_with_ids<field_types, field_types_as_ids, selected_field_ids, field_no, return_types...>
{
static_assert(field_types_as_ids::contains(selected_field_ids::as_array[field_no]),
"You selected a field that was not in field_types_as_ids.");
// call this type trait again, but increase index by one and append a type to the returned type list.
using type = select_types_with_ids_t<
field_types,
field_types_as_ids,
selected_field_ids,
field_no + 1,
return_types...,
list_traits::at<field_types_as_ids::index_of(selected_field_ids::as_array[field_no]), field_types>>;
};
// ----------------------------------------------------------------------------
// get_or_ignore
// ----------------------------------------------------------------------------
template <field f, typename field_types, typename field_ids>
auto & get_or_ignore(record<field_types, field_ids> & r)
{
if constexpr (field_ids::contains(f))
return std::get<field_ids::index_of(f)>(r);
else
return std::ignore;
}
template <field f, typename field_types, typename field_ids>
auto const & get_or_ignore(record<field_types, field_ids> const & r)
{
if constexpr (field_ids::contains(f))
return std::get<field_ids::index_of(f)>(r);
else
return std::ignore;
}
template <size_t i, tuple_like tuple_t>
auto & get_or_ignore(tuple_t & t)
{
if constexpr (i < std::tuple_size_v<tuple_t>)
return std::get<i>(t);
else
return std::ignore;
}
template <size_t i, tuple_like tuple_t>
auto const & get_or_ignore(tuple_t const & t)
{
if constexpr (i < std::tuple_size_v<tuple_t>)
return std::get<i>(t);
else
return std::ignore;
}
// ----------------------------------------------------------------------------
// get_or
// ----------------------------------------------------------------------------
template <field f, typename field_types, typename field_ids, typename or_type>
decltype(auto) get_or(record<field_types, field_ids> & r, or_type && or_value)
{
if constexpr (field_ids::contains(f))
return std::get<field_ids::index_of(f)>(r);
else
return std::forward<or_type>(or_value);
}
template <field f, typename field_types, typename field_ids, typename or_type>
decltype(auto) get_or(record<field_types, field_ids> const & r, or_type && or_value)
{
if constexpr (field_ids::contains(f))
return std::get<field_ids::index_of(f)>(r);
else
return std::forward<or_type>(or_value);
}
template <size_t i, typename or_type, typename... types>
decltype(auto) get_or(std::tuple<types...> & t, or_type && or_value)
{
if constexpr (i < sizeof...(types))
return std::get<i>(t);
else
return std::forward<or_type>(or_value);
}
template <size_t i, typename or_type, typename... types>
decltype(auto) get_or(std::tuple<types...> const & t, or_type && or_value)
{
if constexpr (i < sizeof...(types))
return std::get<i>(t);
else
return std::forward<or_type>(or_value);
}
// ----------------------------------------------------------------------------
// range_wrap_ignore
// ----------------------------------------------------------------------------
template <std::ranges::input_range rng_t>
inline auto & range_wrap_ignore(rng_t & range)
{
return range;
}
inline auto range_wrap_ignore(ignore_t const &)
{
return views::repeat(std::ignore);
}
} // namespace seqan3::detail
std::forward
T forward(T... args)
seqan3::list_traits::at
typename decltype(detail::at< idx >(list_t{}))::type at
Return the type at given index from the type list.
Definition type_list/traits.hpp:276
seqan3::views::repeat
constexpr detail::repeat_fn repeat
A view factory that repeats a given value infinitely.
Definition repeat.hpp:344
record.hpp
Provides the seqan3::record template and the seqan3::field enum.
repeat.hpp
Provides the seqan3::views::repeat.
is_value_specialisation_of_v
constexpr bool is_value_specialisation_of_v
Helper variable template for seqan3::detail::is_value_specialisation_of (unary_type_trait shortcut).
Definition template_inspection.hpp:179
traits.hpp
Provides traits for seqan3::type_list.
concept.hpp
Provides seqan3::tuple_like.
Hide me