From f3dcea48560bb9b1c694eb5ad40064206b3cbaff Mon Sep 17 00:00:00 2001 From: marehr Date: Fri, 29 Dec 2023 18:26:17 +0100 Subject: [PATCH] FEATURE: add seqan3::default_printer This PR will resolve seqan/product_backlog#63. This issue is a long-standing regret of mine. I hope that you can take it over and push it over the finishing line. The state of the current PR is just a draft of an idea. I'll comment on multiple code locations to point out the advantages of the new design. # The old design The major idea of the design is due to the following observation: > We use overload resolution and in particular overload ordering via concepts to determine the order in which we should print Just to give a small example (the more down, the more specialized): ```cpp std::cout //-printable [1] < seqan3::tuple_like // [4] < std::ranges::input_range // [2] < std::vector // [3] < seqan3::sequence // [3] < char * // [2] std::cout //-printable [1] < char // [5] < seqan3::tuple_like // [4] < seqan3::alphabet // [5] < seqan3::mask // [6] ``` NOTE: that using concepts as overload resolution always uses a partially ordered set, which can be depicted by as a [Hasse Diagram](https://en.wikipedia.org/wiki/Hasse_diagram), and by using the except clauses via `requires` we give it a total order. # The new design ### Before anything, note that the new design does not break any existing code. As existing `seqan3::debugstream << ` overloads, still take place in overload resolution (). The idea is simple: * Have a list of printers. * The order of the printers dictates in which order an object should be printed. * We allow that multiple printers might be viable to print a type. * Each `printer` either has a function object / lambda `print` or not; depending on whether the `printer` can print that `type` or not (implemented by [template specialization](https://en.cppreference.com/w/cpp/language/template_specialization) ) So put together: For a given type, ask every printer in order whether it can print that type and the first one to answer yes, is the selected printer. ---- [1] If all overloads do not work, use `std::ostream` https://github.com/seqan/seqan3/blob/6b681fb2eae5ab2997d293e99fc6a7f869a20316/include/seqan3/core/debug_stream/debug_stream_type.hpp#L242-L247 [2] Use this for all `std::ranges::input_range`s except if type is something like `std::filesystem` (type == range_value_t) or `char *` https://github.com/seqan/seqan3/blob/6b681fb2eae5ab2997d293e99fc6a7f869a20316/include/seqan3/core/debug_stream/range.hpp#L96-L98 https://github.com/seqan/seqan3/blob/6b681fb2eae5ab2997d293e99fc6a7f869a20316/include/seqan3/core/debug_stream/range.hpp#L38-L45 [3] Same as [2] where value_type is an alphabet but only if the alphabet is not an `unsigned int` (this condition has no test case?!) https://github.com/seqan/seqan3/blob/6b681fb2eae5ab2997d293e99fc6a7f869a20316/include/seqan3/core/debug_stream/range.hpp#L138-L141 [4] Use this for all `std::tuple`-like types except if it is a `std::ranges::input_range` (what is a tuple and ranges at the same time?!) and an `seqan3::alphabet` (basically `seqan3::alphabet_tuple_base` derived types) https://github.com/seqan/seqan3/blob/6b681fb2eae5ab2997d293e99fc6a7f869a20316/include/seqan3/core/debug_stream/tuple.hpp#L53-L56 [5] Use this for all `seqan3::alphabet`s except if it can be printed by `std::cout` (like `char`) https://github.com/seqan/seqan3/blob/6b681fb2eae5ab2997d293e99fc6a7f869a20316/include/seqan3/alphabet/detail/debug_stream_alphabet.hpp#L30-L32 [6] Type must be `seqan3::semialphabet` and `seqan3::mask` https://github.com/seqan/seqan3/blob/6b681fb2eae5ab2997d293e99fc6a7f869a20316/include/seqan3/alphabet/detail/debug_stream_alphabet.hpp#L46-L48 --- .../debug_stream_alignment.hpp | 13 +++ .../advanceable_alignment_coordinate.hpp | 14 ++++ .../alignment/matrix/detail/debug_matrix.hpp | 15 ++++ .../matrix/detail/trace_directions.hpp | 13 +++ .../alignment/pairwise/alignment_result.hpp | 19 +++++ include/seqan3/alphabet/cigar/cigar.hpp | 2 + .../alphabet/detail/debug_stream_alphabet.hpp | 24 ++++++ include/seqan3/argument_parser/auxiliary.hpp | 2 + include/seqan3/core/debug_stream/byte.hpp | 2 + .../core/debug_stream/debug_stream_type.hpp | 67 +++++++++++++++ .../core/debug_stream/default_printer.hpp | 81 +++++++++++++++++++ include/seqan3/core/debug_stream/optional.hpp | 29 +++++++ include/seqan3/core/debug_stream/range.hpp | 28 +++++++ include/seqan3/core/debug_stream/tuple.hpp | 14 ++++ include/seqan3/core/debug_stream/variant.hpp | 2 + include/seqan3/core/detail/strong_type.hpp | 2 + include/seqan3/io/sam_file/sam_flag.hpp | 2 + include/seqan3/search/search_result.hpp | 2 + .../utility/container/dynamic_bitset.hpp | 2 + .../utility/simd/detail/debug_stream_simd.hpp | 2 + test/unit/io/record_test.cpp | 2 + test/unit/search/helper.hpp | 2 + test/unit/test/pretty_printing_test.cpp | 4 + 23 files changed, 343 insertions(+) create mode 100644 include/seqan3/core/debug_stream/default_printer.hpp diff --git a/include/seqan3/alignment/aligned_sequence/debug_stream_alignment.hpp b/include/seqan3/alignment/aligned_sequence/debug_stream_alignment.hpp index 5c8396ff837..eb9784bdea8 100644 --- a/include/seqan3/alignment/aligned_sequence/debug_stream_alignment.hpp +++ b/include/seqan3/alignment/aligned_sequence/debug_stream_alignment.hpp @@ -104,17 +104,30 @@ namespace seqan3 * * \return The given stream to which the alignment representation is appended. */ +#if 0 template requires (detail::debug_streamable_tuple && detail::all_model_aligned_seq>>) inline debug_stream_type & operator<<(debug_stream_type & stream, alignment_t && alignment) { +#else +template + requires (tuple_like> && detail::all_model_aligned_seq>>) +struct alignment_printer +{ + constexpr static auto print = [](auto & stream, auto && alignment) + { constexpr size_t sequence_count = std::tuple_size_v>; static_assert(sequence_count >= 2, "An alignment requires at least two sequences."); detail::stream_alignment(stream, alignment, std::make_index_sequence{}); + }; +}; +#endif +#if 0 return stream; } +#endif } // namespace seqan3 diff --git a/include/seqan3/alignment/matrix/detail/advanceable_alignment_coordinate.hpp b/include/seqan3/alignment/matrix/detail/advanceable_alignment_coordinate.hpp index 31f16c1653a..143eb7a3afb 100644 --- a/include/seqan3/alignment/matrix/detail/advanceable_alignment_coordinate.hpp +++ b/include/seqan3/alignment/matrix/detail/advanceable_alignment_coordinate.hpp @@ -307,13 +307,27 @@ namespace seqan3 * * Prints the alignment coordinate as a tuple. */ +#if 0 template requires detail::is_value_specialisation_of_v, detail::advanceable_alignment_coordinate> inline debug_stream_type & operator<<(debug_stream_type & s, coordinate_type && c) { +#else +template + requires detail::is_value_specialisation_of_v, + detail::advanceable_alignment_coordinate> +struct advanceable_alignment_coordinate_printer +{ + constexpr static auto print = [](auto & s, coordinate_type const & c) + { s << std::tie(c.first, c.second); + }; +}; +#endif +#if 0 return s; } +#endif } // namespace seqan3 diff --git a/include/seqan3/alignment/matrix/detail/debug_matrix.hpp b/include/seqan3/alignment/matrix/detail/debug_matrix.hpp index 96264f3bc6b..90a03ab411f 100644 --- a/include/seqan3/alignment/matrix/detail/debug_matrix.hpp +++ b/include/seqan3/alignment/matrix/detail/debug_matrix.hpp @@ -479,17 +479,31 @@ namespace seqan3 * * This prints out an alignment matrix which can be a score matrix or a trace matrix. */ +#if 0 template inline debug_stream_type & operator<<(debug_stream_type & s, alignment_matrix_t && matrix) { +#else +template + requires detail::matrix> +struct alignment_matrix_printer +{ + constexpr static auto print = [](auto & s, auto && matrix) + { detail::debug_matrix debug{std::forward(matrix)}; std::stringstream sstream{}; debug.stream_matrix(sstream, s.flags2()); s << sstream.str(); + }; +}; +#endif +#if 0 return s; } +#endif +#if 0 //!\overload template requires detail::debug_stream_range_guard && detail::matrix @@ -497,5 +511,6 @@ inline debug_stream_type & operator<<(debug_stream_type & s, ali { return s << detail::debug_matrix{std::forward(matrix)}; } +#endif } // namespace seqan3 diff --git a/include/seqan3/alignment/matrix/detail/trace_directions.hpp b/include/seqan3/alignment/matrix/detail/trace_directions.hpp index 4d1ca11615d..2e72c4aecae 100644 --- a/include/seqan3/alignment/matrix/detail/trace_directions.hpp +++ b/include/seqan3/alignment/matrix/detail/trace_directions.hpp @@ -75,9 +75,17 @@ constexpr bool add_enum_bitwise_operators = tr * | seqan3::detail::trace_directions::left_open | ← | L | * | seqan3::detail::trace_directions::left | ⇠ | l | */ +#if 0 template inline debug_stream_type & operator<<(debug_stream_type & s, detail::trace_directions const trace) { +#else +template + requires std::is_same_v, detail::trace_directions> +struct trace_directions_printer +{ + constexpr static auto print = [](auto & s, detail::trace_directions const trace) + { static char const * unicode[32]{"↺", "↖", "↑", "↖↑", "⇡", "↖⇡", "↑⇡", "↖↑⇡", "←", "↖←", "↑←", "↖↑←", "⇡←", "↖⇡←", "↑⇡←", "↖↑⇡←", "⇠", "↖⇠", "↑⇠", "↖↑⇠", "⇡⇠", "↖⇡⇠", "↑⇡⇠", "↖↑⇡⇠", "←⇠", "↖←⇠", "↑←⇠", "↖↑←⇠", "⇡←⇠", "↖⇡←⇠", "↑⇡←⇠", "↖↑⇡←⇠"}; @@ -90,7 +98,12 @@ inline debug_stream_type & operator<<(debug_stream_type & s, det auto const & trace_dir = is_unicode ? unicode : csv; s << trace_dir[static_cast(trace)]; + }; +}; +#endif +#if 0 return s; } +#endif } // namespace seqan3 diff --git a/include/seqan3/alignment/pairwise/alignment_result.hpp b/include/seqan3/alignment/pairwise/alignment_result.hpp index 798d7737f90..960759fbbf9 100644 --- a/include/seqan3/alignment/pairwise/alignment_result.hpp +++ b/include/seqan3/alignment/pairwise/alignment_result.hpp @@ -384,10 +384,24 @@ namespace seqan3 * \param[in] result The alignment result to print. * \relates seqan3::debug_stream_type */ +#if 0 template requires detail::is_type_specialisation_of_v, alignment_result> inline debug_stream_type & operator<<(debug_stream_type & stream, alignment_result_t && result) { +#else +template + requires (!std::is_same_v>) +struct alignment_result_printer : public alignment_result_printer> +{ +}; + +template +struct alignment_result_printer> +{ + constexpr static auto print = [](auto & stream, alignment_result const & result) + { + using alignment_result_t = alignment_result; using disabled_t = std::nullopt_t *; using result_data_t = typename detail::alignment_result_value_type_accessor>::type; @@ -423,6 +437,11 @@ inline debug_stream_type & operator<<(debug_stream_type & stream append_to_stream("\nalignment:\n", result.alignment()); stream << '}'; + }; +}; +#endif +#if 0 return stream; } +#endif } // namespace seqan3 diff --git a/include/seqan3/alphabet/cigar/cigar.hpp b/include/seqan3/alphabet/cigar/cigar.hpp index 5b24ba41af6..5ec4e5205db 100644 --- a/include/seqan3/alphabet/cigar/cigar.hpp +++ b/include/seqan3/alphabet/cigar/cigar.hpp @@ -210,6 +210,7 @@ class cigar : public alphabet_tuple_base inline debug_stream_type & operator<<(debug_stream_type & s, cigar const c) @@ -217,6 +218,7 @@ inline debug_stream_type & operator<<(debug_stream_type & s, cig s << c.to_string(); return s; } +#endif inline namespace literals { diff --git a/include/seqan3/alphabet/detail/debug_stream_alphabet.hpp b/include/seqan3/alphabet/detail/debug_stream_alphabet.hpp index c85a41d4f16..32a6268fdf6 100644 --- a/include/seqan3/alphabet/detail/debug_stream_alphabet.hpp +++ b/include/seqan3/alphabet/detail/debug_stream_alphabet.hpp @@ -18,6 +18,7 @@ namespace seqan3 { +#if 0 /*!\name Formatted output overloads * \{ */ @@ -33,10 +34,22 @@ inline debug_stream_type & operator<<(debug_stream_type & s, alp { return s << to_char(l); } +#else +template + requires alphabet +struct alphabet_printer +{ + constexpr static auto print = [](auto & s, alphabet_t l) + { + s << to_char(l); + }; +}; +#endif // forward declare seqan3::mask class mask; +#if 0 /*!\brief Overload for the seqan3::mask alphabet. * \tparam char_t Type char type of the debug_stream. * \param s The seqan3::debug_stream. @@ -51,5 +64,16 @@ inline debug_stream_type & operator<<(debug_stream_type & s, alp } //!\} +#else +template + requires std::same_as, mask> +struct mask_printer +{ + constexpr static auto print = [](auto & s, alphabet_t const l) + { + s << (l == std::remove_cvref_t{} ? "UNMASKED" : "MASKED"); + }; +}; +#endif } // namespace seqan3 diff --git a/include/seqan3/argument_parser/auxiliary.hpp b/include/seqan3/argument_parser/auxiliary.hpp index 53fb59b96d3..f94df10669f 100644 --- a/include/seqan3/argument_parser/auxiliary.hpp +++ b/include/seqan3/argument_parser/auxiliary.hpp @@ -222,6 +222,7 @@ concept argument_parser_compatible_option = * This searches the seqan3::enumeration_names of the respective type for the value \p op and prints the * respective string if found or '\' if the value cannot be found in the map. */ +#if 1 template requires named_enumeration> inline debug_stream_type & operator<<(debug_stream_type & s, option_type && op) @@ -234,6 +235,7 @@ inline debug_stream_type & operator<<(debug_stream_type & s, opt return s << ""; } +#endif //!\} /*!\brief Used to further specify argument_parser options/flags. diff --git a/include/seqan3/core/debug_stream/byte.hpp b/include/seqan3/core/debug_stream/byte.hpp index cbcec8479e7..4342ac259ab 100644 --- a/include/seqan3/core/debug_stream/byte.hpp +++ b/include/seqan3/core/debug_stream/byte.hpp @@ -28,6 +28,7 @@ namespace seqan3 * \param[in] arg The std::byte. * \relates seqan3::debug_stream_type */ +#if 1 template requires std::same_as, std::byte> inline debug_stream_type & operator<<(debug_stream_type & s, byte_type && arg) @@ -35,6 +36,7 @@ inline debug_stream_type & operator<<(debug_stream_type & s, byt s << std::to_integer(arg); return s; } +#endif //!\} diff --git a/include/seqan3/core/debug_stream/debug_stream_type.hpp b/include/seqan3/core/debug_stream/debug_stream_type.hpp index f4b346a9179..9612c9cc2b5 100644 --- a/include/seqan3/core/debug_stream/debug_stream_type.hpp +++ b/include/seqan3/core/debug_stream/debug_stream_type.hpp @@ -13,8 +13,10 @@ #pragma once #include +#include #include +#include namespace seqan3 { @@ -124,7 +126,22 @@ class debug_stream_type */ //!\brief Forwards to the underlying stream object. template +#if 0 friend debug_stream_type & operator<<(debug_stream_type & s, t && v); +#else + friend debug_stream_type & operator<<(debug_stream_type & s, t && v) + { + using t_ = std::remove_cvref_t; + + if constexpr(default_printer::is_printable) { + default_printer::print(s, v); + } else { + std::string const msg = std::string{"debug_stream has no print overload for type: "} + typeid(v).name(); + throw std::runtime_error{msg}; + } + return s; + } +#endif //!\brief This overloads enables forwarding std::endl and other manipulators. debug_stream_type & operator<<(std::ostream & (*fp)(std::ostream &)) @@ -133,6 +150,7 @@ class debug_stream_type return *this; } +#if 0 //!\cond debug_stream_type & operator<<(int8_t const v) { @@ -151,6 +169,15 @@ class debug_stream_type *stream << v; return *this; } +#else + + template + friend struct debug_stream_printer; + + template + friend struct std_printer; + +#endif //!\endcond //!\} @@ -185,6 +212,7 @@ class debug_stream_type stream->unsetf(flag); } +#if 0 //!\copybrief setf() debug_stream_type & operator<<(fmtflags const flag) { @@ -192,6 +220,7 @@ class debug_stream_type return *this; } //!\} +#endif /*!\name Format flags (seqan3::fmtflags2) * \brief SeqAn specific debug flags for the debug stream. @@ -222,6 +251,7 @@ class debug_stream_type flgs2 &= ~flag; } +#if 0 //!\copybrief setf() debug_stream_type & operator<<(fmtflags2 const flag) { @@ -229,6 +259,7 @@ class debug_stream_type return *this; } //!\} +#endif private: //!\brief Pointer to the output stream. @@ -238,6 +269,41 @@ class debug_stream_type fmtflags2 flgs2{fmtflags2::default_}; }; +template + requires (std::is_same_v, int8_t> || std::is_same_v, uint8_t> || std::is_same_v, fmtflags2>) +struct debug_stream_printer +{ + struct print_fn + { + template + constexpr void operator()(stream_t & s, int8_t const v) const + { + if ((s.flags2() & fmtflags2::small_int_as_number) == fmtflags2::small_int_as_number) + *s.stream << static_cast(v); + else + *s.stream << v; + } + + template + constexpr void operator()(stream_t & s, uint8_t const v) const + { + if ((s.flags2() & fmtflags2::small_int_as_number) == fmtflags2::small_int_as_number) + *s.stream << static_cast(v); + else + *s.stream << v; + } + + template + constexpr void operator()(stream_t & s, fmtflags2 const flag) const + { + s.setf(flag); + } + }; + + static constexpr print_fn print{}; +}; + +#if 0 //!\brief Forwards to the underlying stream object. template debug_stream_type & operator<<(debug_stream_type & s, t && v) @@ -245,5 +311,6 @@ debug_stream_type & operator<<(debug_stream_type & s, t && v) (*s.stream) << v; return s; } +#endif } // namespace seqan3 diff --git a/include/seqan3/core/debug_stream/default_printer.hpp b/include/seqan3/core/debug_stream/default_printer.hpp new file mode 100644 index 00000000000..39606c905ea --- /dev/null +++ b/include/seqan3/core/debug_stream/default_printer.hpp @@ -0,0 +1,81 @@ +#pragma once + +#include + +namespace seqan3 +{ + +struct no_printer_found{}; +template struct advanceable_alignment_coordinate_printer {}; +template struct alignment_matrix_printer {}; +template struct alignment_printer {}; +template struct alignment_result_printer {}; +template struct alphabet_printer {}; +template struct debug_stream_printer {}; +template struct mask_printer {}; +template struct optional_printer {}; +template struct range_printer {}; +template struct sequence_printer {}; +template struct std_printer {}; +template struct trace_directions_printer {}; +template struct tuple_printer {}; + +template + requires requires(std::ostream & cout, type_t value) + { + {cout << value}; + } +struct std_printer +{ + static constexpr auto print = [](auto & s, auto && value) + { + *s.stream << std::forward(value); + }; +}; + +template +concept printable = requires() { { printer_t::print }; }; + +template typename ...printers_t> +struct printer_order +{ + template + static constexpr std::ptrdiff_t find_index() + { + std::ptrdiff_t i = 0; + return ((printable ? false : ++i) && ...) ? -1 : i; + } + + template ...>()> + using printer_for_t = std::tuple_element_t< + i == -1 ? sizeof...(printers_t) : i, + std::tuple..., no_printer_found>>; + + template + static constexpr bool is_printable = printable>; + + static constexpr auto print = [](auto & s, auto && arg) + { + using printer_t = printer_for_t; + printer_t::print(s, std::forward(arg)); + }; +}; + +struct default_printer : printer_order< + debug_stream_printer, + std_printer, + advanceable_alignment_coordinate_printer, + alignment_result_printer, + alignment_matrix_printer, + alignment_printer, + trace_directions_printer, + mask_printer, + alphabet_printer, + sequence_printer, + range_printer, + optional_printer, + tuple_printer +> +{}; + +} // namespace seqan3 diff --git a/include/seqan3/core/debug_stream/optional.hpp b/include/seqan3/core/debug_stream/optional.hpp index 637e791fdec..5e5b74d05a3 100644 --- a/include/seqan3/core/debug_stream/optional.hpp +++ b/include/seqan3/core/debug_stream/optional.hpp @@ -29,6 +29,7 @@ namespace seqan3 * \param[in] arg This is std::nullopt. * \relates seqan3::debug_stream_type */ +#if 0 template inline debug_stream_type & operator<<(debug_stream_type & s, std::nullopt_t SEQAN3_DOXYGEN_ONLY(arg)) { @@ -52,6 +53,34 @@ inline debug_stream_type & operator<<(debug_stream_type & s, opt s << ""; return s; } +#else +template + requires (!std::is_same_v>) +struct optional_printer : public optional_printer> +{ +}; + +template <> +struct optional_printer +{ + constexpr static auto print = [](auto & s, std::nullopt_t SEQAN3_DOXYGEN_ONLY(arg)) + { + s << ""; + }; +}; + +template +struct optional_printer> +{ + constexpr static auto print = [](auto & s, auto && arg) + { + if (arg.has_value()) + s << *arg; + else + s << ""; + }; +}; +#endif //!\} diff --git a/include/seqan3/core/debug_stream/range.hpp b/include/seqan3/core/debug_stream/range.hpp index d56cd132f77..9afae8026a1 100644 --- a/include/seqan3/core/debug_stream/range.hpp +++ b/include/seqan3/core/debug_stream/range.hpp @@ -93,12 +93,22 @@ namespace seqan3 * to avoid ambiguous function calls. * \endif */ +#if 0 template inline debug_stream_type & operator<<(debug_stream_type & s, rng_t && r) requires detail::debug_stream_range_guard { +#else +template + requires std::ranges::range +struct range_printer +{ + constexpr static auto print = [](auto & s, auto && r) + { +#if 0 static_assert(detail::reference_type_is_streamable_v, "The reference type of the passed range cannot be streamed into the debug_stream."); +#endif s << '['; auto b = std::ranges::begin(r); @@ -115,9 +125,14 @@ inline debug_stream_type & operator<<(debug_stream_type & s, rng ++b; } s << ']'; + }; +}; +#endif +#if 0 return s; } +#endif /*!\brief All biological sequences can be printed to the seqan3::debug_stream. * \tparam sequence_t Type of the (biological) sequence to be printed; must model seqan3::sequence. @@ -135,15 +150,28 @@ inline debug_stream_type & operator<<(debug_stream_type & s, rng * to avoid ambiguous function calls. * \endif */ +#if 0 template inline debug_stream_type & operator<<(debug_stream_type & s, sequence_t && sequence) requires detail::debug_stream_range_guard && (!detail::is_uint_adaptation_v>>) { +#else +template + requires sequence +struct sequence_printer +{ + constexpr static auto print = [](auto & s, auto && sequence) + { for (auto && chr : sequence) s << chr; + }; +}; +#endif +#if 0 return s; } +#endif //!\} diff --git a/include/seqan3/core/debug_stream/tuple.hpp b/include/seqan3/core/debug_stream/tuple.hpp index e4430e6a57c..a25a3943bf2 100644 --- a/include/seqan3/core/debug_stream/tuple.hpp +++ b/include/seqan3/core/debug_stream/tuple.hpp @@ -60,6 +60,7 @@ std::ranges::input_range && !alphabet && // exclude alphabet_t namespace seqan3 { +#if 0 /*!\brief All tuples can be printed by printing their elements separately. * \tparam tuple_t Type of the tuple to be printed; must model seqan3::tuple_like. * \param s The seqan3::debug_stream. @@ -70,11 +71,24 @@ template requires (detail::debug_streamable_tuple) inline debug_stream_type & operator<<(debug_stream_type & s, tuple_t && t) { +#else +template + requires tuple_like +struct tuple_printer +{ + constexpr static auto print = [](auto & s, auto && t) + { + using tuple_t = decltype(t); detail::print_tuple(s, std::forward(t), std::make_index_sequence>>{}); + }; +}; +#endif +#if 0 return s; } +#endif //!\} diff --git a/include/seqan3/core/debug_stream/variant.hpp b/include/seqan3/core/debug_stream/variant.hpp index 1d7ba97760b..a4badc597e2 100644 --- a/include/seqan3/core/debug_stream/variant.hpp +++ b/include/seqan3/core/debug_stream/variant.hpp @@ -33,6 +33,7 @@ namespace seqan3 * * Note that in case the variant is valueless(_by_exception), nothing is printed. */ +#if 1 template requires detail::is_type_specialisation_of_v, std::variant> inline debug_stream_type & operator<<(debug_stream_type & s, variant_type && v) @@ -48,6 +49,7 @@ inline debug_stream_type & operator<<(debug_stream_type & s, var s << ""; return s; } +#endif //!\} diff --git a/include/seqan3/core/detail/strong_type.hpp b/include/seqan3/core/detail/strong_type.hpp index ef0b12fe44b..0d556eb1aa0 100644 --- a/include/seqan3/core/detail/strong_type.hpp +++ b/include/seqan3/core/detail/strong_type.hpp @@ -475,12 +475,14 @@ class strong_type * * \returns `stream_t &` A reference to the given stream. */ +#if 1 template debug_stream_type & operator<<(debug_stream_type & stream, strong_type_t && value) { stream << value.get(); return stream; } +#endif //!\} } // namespace seqan3::detail diff --git a/include/seqan3/io/sam_file/sam_flag.hpp b/include/seqan3/io/sam_file/sam_flag.hpp index 63838164224..089230c5ecb 100644 --- a/include/seqan3/io/sam_file/sam_flag.hpp +++ b/include/seqan3/io/sam_file/sam_flag.hpp @@ -103,10 +103,12 @@ constexpr bool add_enum_bitwise_operators = true; * \param flag The flag to print. * \relates seqan3::debug_stream_type */ +#if 1 template inline debug_stream_type & operator<<(debug_stream_type & stream, sam_flag const flag) { return stream << static_cast(flag); } +#endif } // namespace seqan3 diff --git a/include/seqan3/search/search_result.hpp b/include/seqan3/search/search_result.hpp index c9a82022590..058ee6dc369 100644 --- a/include/seqan3/search/search_result.hpp +++ b/include/seqan3/search/search_result.hpp @@ -191,6 +191,7 @@ class search_result * \param result The search result to print. * \relates seqan3::debug_stream_type */ +#if 1 template requires detail::is_type_specialisation_of_v, search_result> inline debug_stream_type & operator<<(debug_stream_type & stream, search_result_t && result) @@ -210,5 +211,6 @@ inline debug_stream_type & operator<<(debug_stream_type & stream return stream; } +#endif } // namespace seqan3 diff --git a/include/seqan3/utility/container/dynamic_bitset.hpp b/include/seqan3/utility/container/dynamic_bitset.hpp index c8a2b097be5..7e9247ee10f 100644 --- a/include/seqan3/utility/container/dynamic_bitset.hpp +++ b/include/seqan3/utility/container/dynamic_bitset.hpp @@ -1939,6 +1939,7 @@ class dynamic_bitset * * \experimentalapi{Experimental since version 3.1.} */ +#if 1 template friend debug_stream_type & operator<<(debug_stream_type & s, dynamic_bitset arg) { @@ -1946,6 +1947,7 @@ class dynamic_bitset | ranges::to()); return s; } +#endif //!\} //!\cond DEV diff --git a/include/seqan3/utility/simd/detail/debug_stream_simd.hpp b/include/seqan3/utility/simd/detail/debug_stream_simd.hpp index 59ffb168d88..ea7a82ca2f2 100644 --- a/include/seqan3/utility/simd/detail/debug_stream_simd.hpp +++ b/include/seqan3/utility/simd/detail/debug_stream_simd.hpp @@ -27,6 +27,7 @@ namespace seqan3 * the API was not in shape yet. Remove the `private` and `todo` commands and remove `seqan3::simd` from * SEQAN3_DOXYGEN_EXCLUDE_SYMBOLS in `seqan3-doxygen.cmake`. */ +#if 1 template requires simd::simd_concept> inline debug_stream_type & operator<<(debug_stream_type & s, simd_t && simd) @@ -41,5 +42,6 @@ inline debug_stream_type & operator<<(debug_stream_type & s, sim s << array; return s; } +#endif } // namespace seqan3 diff --git a/test/unit/io/record_test.cpp b/test/unit/io/record_test.cpp index 5dede3aba73..75153de1145 100644 --- a/test/unit/io/record_test.cpp +++ b/test/unit/io/record_test.cpp @@ -24,12 +24,14 @@ using default_fields = seqan3::fields inline debug_stream_type & operator<<(debug_stream_type & stream, field f) { stream << "(f) << ">"; return stream; } +#endif } // namespace seqan3 // ---------------------------------------------------------------------------- diff --git a/test/unit/search/helper.hpp b/test/unit/search/helper.hpp index c4b550b3d1f..874faf3344e 100644 --- a/test/unit/search/helper.hpp +++ b/test/unit/search/helper.hpp @@ -18,6 +18,7 @@ namespace seqan3 { +#if 1 template inline debug_stream_type & operator<<(debug_stream_type & s, seqan3::fm_index_cursor const &) { @@ -30,6 +31,7 @@ inline debug_stream_type & operator<<(debug_stream_type & s, { return s << ("bi_fm_index_cursor"); } +#endif template std::vector> uniquify(result_range_t && result_range) diff --git a/test/unit/test/pretty_printing_test.cpp b/test/unit/test/pretty_printing_test.cpp index f618ec95cf7..74dfad43ef7 100644 --- a/test/unit/test/pretty_printing_test.cpp +++ b/test/unit/test/pretty_printing_test.cpp @@ -121,6 +121,7 @@ struct my_type namespace seqan3 { +#if 1 template requires std::same_as, detail::my_type> inline debug_stream_type & operator<<(debug_stream_type & s, my_type && m) @@ -128,6 +129,7 @@ inline debug_stream_type & operator<<(debug_stream_type & s, my_ s << m.str; return s; } +#endif } // namespace seqan3 @@ -144,6 +146,7 @@ namespace seqan3 struct your_type : public detail::my_type {}; +#if 1 template requires std::same_as, ::seqan3::your_type> inline debug_stream_type & operator<<(debug_stream_type & s, your_type && m) @@ -151,6 +154,7 @@ inline debug_stream_type & operator<<(debug_stream_type & s, you s << m.str; return s; } +#endif } // namespace seqan3