SeqAn3 3.2.0
The Modern C++ library for sequence analysis.
misc.hpp
Go to the documentation of this file.
1// -----------------------------------------------------------------------------------------------------
2// Copyright (c) 2006-2022, Knut Reinert & Freie Universität Berlin
3// Copyright (c) 2016-2022, 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 <algorithm>
16#include <filesystem>
17#include <iterator>
18#include <variant>
19#include <vector>
20
24
25namespace seqan3::detail
26{
27
30template <typename list_t, template <typename...> typename output_t>
31struct variant_from_tags;
32
35template <template <typename...> typename output_t, typename... ts>
36struct variant_from_tags<type_list<ts...>, output_t>
37{
39 using type = std::variant<output_t<ts>...>;
40};
41
48template <std::output_iterator<char> it_t>
49constexpr void write_eol(it_t & it, bool const add_cr)
50{
51 if (add_cr)
52 it = '\r';
53
54 it = '\n';
55}
56
67template <typename format_variant_type>
68void set_format(format_variant_type & format, 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>(
78 [&](auto fmt)
79 {
80 using fm_type = typename decltype(fmt)::type; // remove type_identity wrapper
81
82 for (auto const & ext : fm_type::file_extensions)
83 {
84 if (std::ranges::equal(ext, extension))
85 {
86 format.template emplace<fm_type>();
87 format_found = true;
88 return;
89 }
90 }
91 });
92 }
93
94 if (!format_found)
95 throw unhandled_extension_error("No valid format found for this extension.");
96}
97
103template <typename list_t>
104inline constexpr bool has_member_file_extensions = false;
105
107template <template <typename...> typename list_t, typename... ts>
108 requires (
109 requires { ts::file_extensions; },
110 ...,
111 true)
112inline constexpr bool has_member_file_extensions<list_t<ts...>> = true;
114
120template <typename query_t>
121inline constexpr bool has_type_valid_formats = false;
122
124template <typename query_t>
125 requires requires { typename query_t::valid_formats; }
126inline constexpr bool has_type_valid_formats<query_t> = true;
128
149template <typename formats_t>
150inline std::vector<std::string> valid_file_extensions()
151{
152 static_assert(has_member_file_extensions<formats_t>,
153 "Expects that all formats have a static member file_extensions storing the extensions in a range");
154
155 std::vector<std::string> extensions;
156 detail::for_each<formats_t>(
157 [&extensions](auto t_identity)
158 {
159 using format_t = typename decltype(t_identity)::type;
160 std::ranges::copy(format_t::file_extensions, std::back_inserter(extensions));
161 });
162
163 return extensions;
164}
165} // namespace seqan3::detail
T back_inserter(T... args)
T copy(T... args)
T equal(T... args)
T extension(T... args)
T format(T... args)
Provides exceptions used in the I/O module.
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.