SeqAn3 3.1.0
The Modern C++ library for sequence analysis.
misc.hpp
Go to the documentation of this file.
1// -----------------------------------------------------------------------------------------------------
2// Copyright (c) 2006-2021, Knut Reinert & Freie Universität Berlin
3// Copyright (c) 2016-2021, Knut Reinert & MPI für molekulare Genetik
4// This file may be used, modified and/or redistributed under the terms of the 3-clause BSD-License
5// shipped with this file and also available at: https://github.com/seqan/seqan3/blob/master/LICENSE.md
6// -----------------------------------------------------------------------------------------------------
7
13#pragma once
14
15#include <seqan3/std/algorithm>
16#include <seqan3/std/filesystem>
17#include <seqan3/std/iterator>
18#include <variant>
19
23
24namespace seqan3::detail
25{
26
29template <typename list_t, template <typename ...> typename output_t>
30struct variant_from_tags;
31
34template <template <typename...> typename output_t, typename ...ts>
35struct variant_from_tags<type_list<ts...>, output_t>
36{
38 using type = std::variant<output_t<ts>...>;
39};
40
47template <std::output_iterator<char> it_t>
48constexpr void write_eol(it_t & it, bool const add_cr)
49{
50 if (add_cr)
51 it = '\r';
52
53 it = '\n';
54}
55
66template <typename format_variant_type>
67void set_format(format_variant_type & format,
68 std::filesystem::path const & file_name)
69{
70 using valid_formats = detail::transfer_template_args_onto_t<format_variant_type, type_list>;
71
72 bool format_found = false;
73 std::string extension = file_name.extension().string();
74 if (extension.size() > 1)
75 {
76 extension = extension.substr(1); // drop leading "."
77 detail::for_each<valid_formats>([&] (auto fmt)
78 {
79 using fm_type = typename decltype(fmt)::type; // remove type_identity wrapper
80
81 for (auto const & ext : fm_type::file_extensions)
82 {
83 if (std::ranges::equal(ext, extension))
84 {
85 format.template emplace<fm_type>();
86 format_found = true;
87 return;
88 }
89 }
90 });
91 }
92
93 if (!format_found)
94 throw unhandled_extension_error("No valid format found for this extension.");
95}
96
102template <typename list_t>
103inline constexpr bool has_member_file_extensions = false;
104
106template <template <typename ...> typename list_t, typename ...ts>
107 requires (requires { ts::file_extensions; }, ..., true)
108inline constexpr bool has_member_file_extensions<list_t<ts...>> = true;
110
116template <typename query_t>
117inline constexpr bool has_type_valid_formats = false;
118
120template <typename query_t>
121 requires requires { typename query_t::valid_formats; }
122inline constexpr bool has_type_valid_formats<query_t> = true;
124
145template <typename formats_t>
146inline std::vector<std::string> valid_file_extensions()
147{
148 static_assert(has_member_file_extensions<formats_t>,
149 "Expects that all formats have a static member file_extensions storing the extensions in a range");
150
151 std::vector<std::string> extensions;
152 detail::for_each<formats_t>([&extensions] (auto t_identity)
153 {
154 using format_t = typename decltype(t_identity)::type;
155 std::ranges::copy(format_t::file_extensions, std::cpp20::back_inserter(extensions));
156 });
157
158 return extensions;
159}
160} // namespace seqan3::detail
The <algorithm> header from C++20's standard library.
T extension(T... args)
The <filesystem> header from C++17's standard library.
T format(T... args)
Provides exceptions used in the I/O module.
The <iterator> header from C++20's standard library.
T size(T... args)
T substr(T... args)
Provides type traits for working with templates.
Provides algorithms for meta programming, parameter packs and seqan3::type_list.