Loading...
Searching...
No Matches
io/detail/misc.hpp
Go to the documentation of this file.
// 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 <algorithm>
#include <filesystem>
#include <iterator>
#include <variant>
#include <vector>
#include <seqan3/core/detail/template_inspection.hpp>
#include <seqan3/io/exception.hpp>
#include <seqan3/utility/type_list/detail/type_list_algorithm.hpp>
namespace seqan3::detail
{
template <typename list_t, template <typename...> typename output_t>
struct variant_from_tags;
template <template <typename...> typename output_t, typename... ts>
struct variant_from_tags<type_list<ts...>, output_t>
{
using type = std::variant<output_t<ts>...>;
};
template <std::output_iterator<char> it_t>
constexpr void write_eol(it_t & it, bool const add_cr)
{
if (add_cr)
it = '\r';
it = '\n';
}
template <typename format_variant_type>
void set_format(format_variant_type & format, std::filesystem::path const & file_name)
{
using valid_formats = detail::transfer_template_args_onto_t<format_variant_type, type_list>;
bool format_found = false;
std::string extension = file_name.extension().string();
if (extension.size() > 1)
{
extension = extension.substr(1); // drop leading "."
detail::for_each<valid_formats>(
[&](auto fmt)
{
using fm_type = typename decltype(fmt)::type; // remove type_identity wrapper
for (auto const & ext : fm_type::file_extensions)
{
if (std::ranges::equal(ext, extension))
{
format.template emplace<fm_type>();
format_found = true;
return;
}
}
});
}
if (!format_found)
throw unhandled_extension_error("No valid format found for this extension.");
}
template <typename list_t>
inline constexpr bool has_member_file_extensions = false;
template <template <typename...> typename list_t, typename... ts>
requires (
requires { ts::file_extensions; },
...,
true)
inline constexpr bool has_member_file_extensions<list_t<ts...>> = true;
template <typename query_t>
inline constexpr bool has_type_valid_formats = false;
template <typename query_t>
requires requires { typename query_t::valid_formats; }
inline constexpr bool has_type_valid_formats<query_t> = true;
template <typename formats_t>
inline std::vector<std::string> valid_file_extensions()
{
static_assert(has_member_file_extensions<formats_t>,
"Expects that all formats have a static member file_extensions storing the extensions in a range");
std::vector<std::string> extensions;
detail::for_each<formats_t>(
[&extensions](auto t_identity)
{
using format_t = typename decltype(t_identity)::type;
std::ranges::copy(format_t::file_extensions, std::back_inserter(extensions));
});
return extensions;
}
} // namespace seqan3::detail
algorithm
std::back_inserter
T back_inserter(T... args)
std::filesystem::path::extension
T extension(T... args)
filesystem
exception.hpp
Provides exceptions used in the I/O module.
iterator
std::string::size
T size(T... args)
std::string::substr
T substr(T... args)
template_inspection.hpp
Provides type traits for working with templates.
type_list_algorithm.hpp
Provides algorithms for meta programming, parameter packs and seqan3::type_list.
variant
vector
Hide me