From c3ec3c183b43db31ddceabead5aba6c56b4232ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Winkler?= Date: Wed, 4 Dec 2019 15:51:17 +0100 Subject: [PATCH 1/2] [MISC] remove column-based interface for structure input --- CHANGELOG.md | 7 +- include/seqan3/io/structure_file/input.hpp | 299 ------------------ .../structure_file_input_col_read.cpp | 38 --- .../structure_file_input_test.cpp | 90 ------ 4 files changed, 6 insertions(+), 428 deletions(-) delete mode 100644 test/snippet/io/structure_file/structure_file_input_col_read.cpp diff --git a/CHANGELOG.md b/CHANGELOG.md index 6850f19efe..bcc4e4eaeb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,7 +33,7 @@ If possible, provide tooling that performs the changes, e.g. a shell-script. #### Core * Added traits for "metaprogramming" with `seqan3::type_list` and type packs. -#### Input/Output +#### I/O * Asynchronous input (background file reading) supported via seqan3::view::async_input_buffer. * Reading field::CIGAR into a vector over seqan3::cigar is supported via seqan3::alignment_file_input. @@ -58,6 +58,11 @@ If possible, provide tooling that performs the changes, e.g. a shell-script. * **The `type_list` header has moved:** If you included `` you need to change the path to ``. +#### I/O + +* The field-based in- and output interface for structure files through std::get and std::tie has been removed. + Output can instead be achieved with seqan3::views:zip(), for input we will implement unzip() in the future. + #### Range * **The `seqan3::concatenated_sequences::data()` function has been deprecated:** diff --git a/include/seqan3/io/structure_file/input.hpp b/include/seqan3/io/structure_file/input.hpp index bef0bacfd4..ec5f217969 100644 --- a/include/seqan3/io/structure_file/input.hpp +++ b/include/seqan3/io/structure_file/input.hpp @@ -85,10 +85,6 @@ namespace seqan3 * \brief Type template of the seqan3::field::SEQ, a container template over `seq_alphabet`; * must satisfy seqan3::sequence_container. */ -/*!\typedef using seq_container_container - * \brief Type template of a column of seqan3::field::SEQ, a container template that can hold multiple - * `seq_container`; must satisfy seqan3::sequence_container. - */ /*!\typedef using id_alphabet * \brief Alphabet of the characters for the seqan3::field::ID; must satisfy seqan3::alphabet. */ @@ -96,10 +92,6 @@ namespace seqan3 * \brief Type template of the seqan3::field::ID, a container template over `id_alphabet`; * must satisfy seqan3::sequence_container. */ -/*!\typedef using id_container_container - * \brief Type template of a column of seqan3::field::ID, a container template that can hold multiple - * `id_container`; must satisfy seqan3::sequence_container. - */ /*!\typedef using bpp_prob * \brief Data type for the base pair probabilities in seqan3::field::BPP; must satisfy std::is_floating_point. */ @@ -116,10 +108,6 @@ namespace seqan3 * \brief Type template of the seqan3::field::BPP, a container template over a set (bpp_queue) of interactions; * must satisfy seqan3::sequence_container. */ -/*!\typedef using bpp_container_container - * \brief Type template of a column of seqan3::field::BPP, a container template that can hold multiple - * `bpp_container`; must satisfy seqan3::sequence_container. - */ /*!\typedef using structure_alphabet * \brief Alphabet of the characters for the seqan3::field::STRUCTURE; must satisfy seqan3::rna_structure_alphabet. */ @@ -127,20 +115,12 @@ namespace seqan3 * \brief Type template of the seqan3::field::STRUCTURE, a container template over `structure_alphabet`; * must satisfy seqan3::sequence_container. */ -/*!\typedef using structure_container_container - * \brief Type template of a column of seqan3::field::STRUCTURE, a container template that can hold multiple - * `structure_container`; must satisfy seqan3::sequence_container. - */ /*!\typedef using energy_type * \brief Type template of the seqan3::field::ENERGY; must be std::optional of a type satisfying std::is_floating_point. * \details * If the file record contains an energy, the value can be obtained through dereference or std::optional::value. * Otherwise, operator bool or std::optional::has_value return false. */ -/*!\typedef using energy_container - * \brief Type template of a column of seqan3::field::ENERGY, a container template that can hold multiple `energy_type`; - * must satisfy seqan3::sequence_container. - */ /*!\typedef using react_type * \brief Data type for the reactivity and reactivity error in seqan3::field::REACT and seqan3::field::REACT_ERR, * respectively; must satisfy std::is_floating_point. @@ -149,10 +129,6 @@ namespace seqan3 * \brief Type template of the seqan3::field::REACT and seqan3::field::REACT_ERR, a container template over * `react_type`; must satisfy seqan3::sequence_container. */ -/*!\typedef using react_container_container - * \brief Type template of a column of seqan3::field::REACT and seqan3::field::REACT_ERR, a container template that - * can hold multiple `react_container`; must satisfy seqan3::sequence_container. - */ /*!\typedef using comment_alphabet * \brief Alphabet of the characters for the seqan3::field::COMMENT; must satisfy seqan3::alphabet. */ @@ -160,17 +136,9 @@ namespace seqan3 * \brief Type template of the seqan3::field::COMMENT, a container template over `comment_alphabet`; * must satisfy seqan3::sequence_container. */ -/*!\typedef using comment_container_container - * \brief Type template of a column of seqan3::field::COMMENT, a container template that can hold multiple - * `comment_container`; must satisfy seqan3::sequence_container. - */ /*!\typedef using offset_type * \brief Type template of the seqan3::field::OFFSET; must statisfy std::numeric_limits::is_integer. */ -/*!\typedef using offset_container - * \brief Type template of a column of seqan3::field::OFFSET, a container template that can hold multiple `offset_type`; - * must satisfy seqan3::sequence_container. - */ //!\} //!\cond template @@ -182,18 +150,10 @@ SEQAN3_CONCEPT structure_file_input_traits = requires(t v) requires writable_alphabet; requires explicitly_convertible_to; requires sequence_container>; -// requires sequence_container -// >>; // id requires writable_alphabet; requires sequence_container>; -// requires sequence_container -// >>; // bpp requires std::is_floating_point_v; @@ -211,21 +171,11 @@ SEQAN3_CONCEPT structure_file_input_traits = requires(t v) // >>>; -// requires sequence_container -// >>>>; // structure requires std::is_same_v // TODO(joergi-w) add aa_structure_concept || rna_structure_alphabet; requires sequence_container>; -// requires sequence_container -// >>; // structured sequence: tuple composites of seq and structure requires std::is_base_of_v>>; -// requires sequence_container -// >>>; // energy: std::optional of floating point number requires std::is_floating_point_v; - requires sequence_container>; // reactivity [error] requires std::is_floating_point_v; requires sequence_container>; -// requires sequence_container -// >>; // comment requires writable_alphabet; requires sequence_container>; -// requires sequence_container -// >>; // offset requires std::numeric_limits::is_integer; - requires sequence_container>; }; //!\endcond @@ -305,10 +240,6 @@ struct structure_file_input_default_traits_rna template using seq_container = std::vector<_seq_alphabet>; - //!\brief The container for sequences is seqan3::concatenated_sequences. - template - using seq_container_container = concatenated_sequences<_seq_container>; - // id //!\brief The alphabet for an identifier string is char. @@ -318,10 +249,6 @@ struct structure_file_input_default_traits_rna template using id_container = std::basic_string<_id_alphabet>; - //!\brief The container for identifier strings is seqan3::concatenated_sequences. - template - using id_container_container = concatenated_sequences<_id_container>; - // base pair probability structure //!\brief The type for a base pair probability is double. @@ -342,10 +269,6 @@ struct structure_file_input_default_traits_rna template using bpp_container = std::vector<_bpp_queue>; - //!\brief The container for interaction strings is std::vector. - template - using bpp_container_container = std::vector<_bpp_container>; - // fixed structure //!\brief The alphabet for a structure annotation is seqan3::phred42. @@ -355,10 +278,6 @@ struct structure_file_input_default_traits_rna template using structure_container = std::vector<_structure_alphabet>; - //!\brief The container for structure annotation strings is seqan3::concatenated_sequences. - template - using structure_container_container = concatenated_sequences<_structure_container>; - // combined sequence and structure //!\brief The combined structured sequence alphabet is seqan3::structured_rna. @@ -369,19 +288,11 @@ struct structure_file_input_default_traits_rna template using structured_seq_container = std::vector<_structured_seq_alphabet>; - //!\brief The container for sequences is seqan3::concatenated_sequences. - template - using structured_seq_container_container = concatenated_sequences<_structured_seq_container>; - // energy //!\brief The type of the energy is std::optional. using energy_type = std::optional; - //!\brief The type of a container of energy values is std::vector. - template - using energy_container = std::vector<_energy_type>; - // reactivity [error] //!\brief The type of the reactivity and reactivity error is double. @@ -391,10 +302,6 @@ struct structure_file_input_default_traits_rna template using react_container = std::vector<_react_type>; - //!\brief The type of a container of reactivity strings is std::vector. - template - using react_container_container = std::vector<_react_container>; - // comment //!\brief The alphabet for a comment string is char. @@ -404,18 +311,10 @@ struct structure_file_input_default_traits_rna template using comment_container = std::basic_string<_comment_alphabet>; - //!\brief The container for comments is seqan3::concatenated_sequences. - template - using comment_container_container = concatenated_sequences<_comment_container>; - // offset //!\brief The type of the offset is size_t. using offset_type = size_t; - - //!\brief The type of a container of offset values is std::vector. - template - using offset_container = std::vector<_offset_type>; //!\} }; @@ -560,20 +459,6 @@ struct structure_file_input_default_traits_aa : structure_file_input_default_tra * * You can check whether a file is at end by comparing begin() and end() (if they are the same, the file is at end). * - * ### Column-based reading - * - * The record-based interface treats the file as a range of tuples (the records), but in certain situations it - * is desirable to read the file by field, i.e. column wise (tuple-of-ranges, instead of range-of-tuples). - * - * This interface is less flexible, but can save you copy operations in certain scenarios, given that - * you have sufficient memory to load the entire file at once: - * - * \include test/snippet/io/structure_file/structure_file_input_col_read.cpp - * - * Note that for this to make sense, your storage data types need to be identical to the corresponding column types - * of the file. If you require different column types you can specify you own traits, see - * seqan3::structure_file_input_traits. - * * ### Formats * * Currently, the only implemented format is seqan3::format_vienna. More formats will follow soon. @@ -672,47 +557,6 @@ class structure_file_input selected_field_ids>; //!\} - /*!\name Field column types and tuple type - * \brief These types are relevant for field/column-wise reading; they may be manipulated via the \ref traits_type - * to achieve different storage behaviour. - * \{ - */ - //!\brief Column type of field::SEQ (seqan3::concatenated_sequences by default). - using seq_column_type = typename traits_type::template seq_container_container; - //!\brief Column type of field::ID (seqan3::concatenated_sequences by default). - using id_column_type = typename traits_type::template id_container_container; - //!\brief Column type of field::BPP (std::vector by default). - using bpp_column_type = typename traits_type::template bpp_container_container; - //!\brief Column type of field::STRUCTURE (seqan3::concatenated_sequences by default). - using structure_column_type = typename traits_type::template structure_container_container; - //!\brief Column type of field::STRUCTURED_SEQ (seqan3::concatenated_sequences by default). - using structured_seq_column_type = typename traits_type::template structured_seq_container_container - ; - //!\brief Column type of field::ENERGY (std::vector by default). - using energy_column_type = typename traits_type::template energy_container; - //!\brief Column type of field::REACT and field::REACT_ERR (std::vector by default). - using react_column_type = typename traits_type::template react_container_container; - //!\brief Column type of field::COMMENT (seqan3::concatenated_sequences by default). - using comment_column_type = typename traits_type::template comment_container_container; - //!\brief Column type of field::OFFSET (std::vector by default). - using offset_column_type = typename traits_type::template offset_container; - - //!\brief The previously defined types aggregated in a seqan3::type_list. - using field_column_types = type_list; - //!\brief The type emulated by the file when read column-wise. - using file_as_tuple_type = record, selected_field_ids>; - //!\} - /*!\name Range associated types * \brief The types necessary to facilitate the behaviour of an input range (used in record-wise reading). * \{ @@ -903,64 +747,6 @@ class structure_file_input } //!\} - /*!\name Tuple interface - * \brief Provides functions for field-based ("column"-based) reading. - * \{ - */ - //!\brief Read the entire file into internal buffers and retrieve the specified column. - template - friend auto & get(structure_file_input & file) - { - static_assert(structure_file_input::selected_field_ids::contains(f), - "You requested a field via get that was not selected for the file."); - - file.read_columns(); - - return seqan3::get(file.columns_buffer); - } - - //!\copydoc get - template - friend auto && get(structure_file_input && file) - { - return std::move(get(file)); - } - - //!\copydoc get - template - friend auto & get(structure_file_input & file) - { - static_assert(i < structure_file_input::selected_field_ids::as_array.size(), - "You requested a field number larger than the number of selected fields for the file."); - file.read_columns(); - - return std::get(file.columns_buffer); - } - - //!\copydoc get - template - friend auto && get(structure_file_input && file) - { - return std::move(get(file)); - } - - //!\copydoc get - template - friend auto & get(structure_file_input & file) - { - file.read_columns(); - - return std::get(file.columns_buffer); - } - - //!\copydoc get - template - friend auto && get(structure_file_input && file) - { - return std::move(get(file)); - } - //!\} - //!\brief The options are public and its members can be set directly. structure_file_input_options options; @@ -972,8 +758,6 @@ class structure_file_input */ //!\brief Buffer for a single record. record_type record_buffer; - //!\brief Buffer of the entire file in columns. - file_as_tuple_type columns_buffer; //!\} /*!\name Stream / file access @@ -1057,48 +841,6 @@ class structure_file_input }, format); } - //!\brief Read the entire file into the internal column buffers. - void read_columns() - { - //TODO don't do multiple visits - //TODO create specialised version for concatenated_sequences where we append on the concat - auto & seq_column_buffer = detail::get_or_ignore(columns_buffer); - auto & id_column_buffer = detail::get_or_ignore(columns_buffer); - auto & bpp_column_buffer = detail::get_or_ignore(columns_buffer); - auto & structure_column_buffer = detail::get_or_ignore(columns_buffer); - auto & structured_seq_column_buffer = detail::get_or_ignore(columns_buffer); - auto & energy_column_buffer = detail::get_or_ignore(columns_buffer); - auto & react_column_buffer = detail::get_or_ignore(columns_buffer); - auto & react_err_column_buffer = detail::get_or_ignore(columns_buffer); - auto & comment_column_buffer = detail::get_or_ignore(columns_buffer); - auto & offset_column_buffer = detail::get_or_ignore(columns_buffer); - - // read the remaining records and split into column buffers - for (auto & rec : *this) - { - if constexpr (selected_field_ids::contains(field::SEQ)) - seq_column_buffer.push_back(std::move(seqan3::get(rec))); - if constexpr (selected_field_ids::contains(field::ID)) - id_column_buffer.push_back(std::move(seqan3::get(rec))); - if constexpr (selected_field_ids::contains(field::BPP)) - bpp_column_buffer.push_back(std::move(seqan3::get(rec))); - if constexpr (selected_field_ids::contains(field::STRUCTURE)) - structure_column_buffer.push_back(std::move(seqan3::get(rec))); - if constexpr (selected_field_ids::contains(field::STRUCTURED_SEQ)) - structured_seq_column_buffer.push_back(std::move(seqan3::get(rec))); - if constexpr (selected_field_ids::contains(field::ENERGY)) - energy_column_buffer.push_back(std::move(seqan3::get(rec))); - if constexpr (selected_field_ids::contains(field::REACT)) - react_column_buffer.push_back(std::move(seqan3::get(rec))); - if constexpr (selected_field_ids::contains(field::REACT_ERR)) - react_err_column_buffer.push_back(std::move(seqan3::get(rec))); - if constexpr (selected_field_ids::contains(field::COMMENT)) - comment_column_buffer.push_back(std::move(seqan3::get(rec))); - if constexpr (selected_field_ids::contains(field::OFFSET)) - offset_column_buffer.push_back(std::move(seqan3::get(rec))); - } - } - //!\brief Befriend iterator so it can access the buffers. friend iterator; }; @@ -1131,45 +873,4 @@ structure_file_input(stream_type & stream, file_format const &, selected_field_i } // namespace seqan3 -// ------------------------------------------------------------------ -// std-overloads for the tuple-like interface -// ------------------------------------------------------------------ - -namespace std -{ - -/*!\brief Provides access to the number of elements in a tuple as a compile-time constant expression. - * \implements seqan3::unary_type_trait - * \ingroup structure_file - * \see std::tuple_size_v - */ -template -struct tuple_size> -{ - //!\brief The value equals the number of selected fields in the file. - static constexpr size_t value = selected_field_ids::as_array.size(); -}; - -/*!\brief Obtains the type of the specified element. - * \implements seqan3::transformation_trait - * \ingroup structure_file - * \see [std::tuple_element](https://en.cppreference.com/w/cpp/utility/tuple/tuple_element) - */ -template -struct tuple_element> - : tuple_element::file_as_tuple_type> -{}; - -} // namespace std #pragma GCC diagnostic pop diff --git a/test/snippet/io/structure_file/structure_file_input_col_read.cpp b/test/snippet/io/structure_file/structure_file_input_col_read.cpp deleted file mode 100644 index 1355a8482d..0000000000 --- a/test/snippet/io/structure_file/structure_file_input_col_read.cpp +++ /dev/null @@ -1,38 +0,0 @@ -#include -#include -#include -#include - -#include -#include -#include -#include - -// Create a data struct used to hold the sequence information. -struct data_storage_t -{ - seqan3::concatenated_sequences sequences; - seqan3::concatenated_sequences ids; - seqan3::concatenated_sequences> structures; -}; - -auto input = R"(> S.cerevisiae_tRNA-PHE M10740/1-73 -GCGGAUUUAGCUCAGUUGGGAGAGCGCCAGACUGAAGAUUUGGAGGUCCUGUGUUCGAUCCACAGAAUUCGCA -(((((((..((((........)))).((((.........)))).....(((((.......)))))))))))). (-17.50) -> example -UUGGAGUACACAACCUGUACACUCUUUC -..(((((..(((...)))..)))))... (-3.71))"; - -int main() -{ - using seqan3::get; - - data_storage_t data_storage{}; - - seqan3::structure_file_input fin{std::istringstream{input}, seqan3::format_vienna{}}; - - // we move the buffer directly into our storage: - data_storage.sequences = std::move(get(fin)); - data_storage.ids = std::move(get(fin)); - data_storage.structures = std::move(get(fin)); -} diff --git a/test/unit/io/structure_file/structure_file_input_test.cpp b/test/unit/io/structure_file/structure_file_input_test.cpp index cdd6ef49be..3e8b79a873 100644 --- a/test/unit/io/structure_file/structure_file_input_test.cpp +++ b/test/unit/io/structure_file/structure_file_input_test.cpp @@ -385,96 +385,6 @@ TEST_F(structure_file_input_read, record_file_view) EXPECT_EQ(counter, num_records); } -TEST_F(structure_file_input_read, column_general) -{ - structure_file_input fin{std::istringstream{input}, format_vienna{}, - fields{}}; - - auto & seqs = get(fin); // by field - auto & ids = get<1>(fin); // by index - auto & bpps = get(fin); - auto & struc = get(fin); // by type - auto & energies = get(fin); - - ASSERT_EQ(seqs.size(), num_records); - ASSERT_EQ(ids.size(), num_records); - ASSERT_EQ(bpps.size(), num_records); - ASSERT_EQ(struc.size(), num_records); - ASSERT_EQ(energies.size(), num_records); - - for (size_t idx = 0ul; idx < num_records; ++idx) - { - EXPECT_TRUE((std::ranges::equal(seqs[idx], seq_comp[idx]))); - EXPECT_TRUE((std::ranges::equal(ids[idx], id_comp[idx]))); - bpp_test(bpps[idx], interaction_comp[idx]); - EXPECT_TRUE((std::ranges::equal(struc[idx], structure_comp[idx]))); - EXPECT_DOUBLE_EQ(energies[idx].value(), energy_comp[idx]); - } -} - -TEST_F(structure_file_input_read, column_temporary) -{ - structure_file_input{std::istringstream{input}, format_vienna{}}; - - auto seqs = get(structure_file_input{std::istringstream{input}, format_vienna{}}); - - ASSERT_EQ(seqs.size(), num_records); - - for (size_t idx = 0ul; idx < num_records; ++idx) - { - EXPECT_TRUE((std::ranges::equal(seqs[idx], seq_comp[idx]))); - } -} - -TEST_F(structure_file_input_read, column_decomposed) -{ - structure_file_input fin{std::istringstream{input}, format_vienna{}, - fields{}}; - - auto & [ seqs, ids, struc, energies, bpps ] = fin; - - ASSERT_EQ(seqs.size(), num_records); - ASSERT_EQ(ids.size(), num_records); - ASSERT_EQ(struc.size(), num_records); - ASSERT_EQ(energies.size(), num_records); - ASSERT_EQ(bpps.size(), num_records); - - for (size_t idx = 0ul; idx < num_records; ++idx) - { - EXPECT_TRUE((std::ranges::equal(seqs[idx], seq_comp[idx]))); - EXPECT_TRUE((std::ranges::equal(ids[idx], id_comp[idx]))); - EXPECT_TRUE((std::ranges::equal(struc[idx], structure_comp[idx]))); - EXPECT_DOUBLE_EQ(energies[idx].value(), energy_comp[idx]); - bpp_test(bpps[idx], interaction_comp[idx]); - } -} - -TEST_F(structure_file_input_read, column_decomposed_temporary) -{ - auto && [ seqs, ids, struc, energies, bpps ] = structure_file_input{std::istringstream{input}, - format_vienna{}, - fields{}}; - - ASSERT_EQ(seqs.size(), num_records); - ASSERT_EQ(ids.size(), num_records); - ASSERT_EQ(struc.size(), num_records); - ASSERT_EQ(energies.size(), num_records); - ASSERT_EQ(bpps.size(), num_records); - - for (size_t idx = 0ul; idx < num_records; ++idx) - { - EXPECT_TRUE((std::ranges::equal(seqs[idx], seq_comp[idx]))); - EXPECT_TRUE((std::ranges::equal(ids[idx], id_comp[idx]))); - EXPECT_TRUE((std::ranges::equal(struc[idx], structure_comp[idx]))); - EXPECT_DOUBLE_EQ(energies[idx].value(), energy_comp[idx]); - bpp_test(bpps[idx], interaction_comp[idx]); - } -} - // ---------------------------------------------------------------------------- // decompression // ---------------------------------------------------------------------------- From b6e51bd0169469bbb67e9c7bd92957c1344a291b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Winkler?= Date: Wed, 4 Dec 2019 15:52:43 +0100 Subject: [PATCH 2/2] [MISC] remove column-based interface for structure output, change snippet and test to implementation with zip iterator --- include/seqan3/io/structure_file/output.hpp | 167 +----------------- .../structure_file_output_col_based.cpp | 4 +- .../structure_file_output_test.cpp | 17 +- 3 files changed, 5 insertions(+), 183 deletions(-) diff --git a/include/seqan3/io/structure_file/output.hpp b/include/seqan3/io/structure_file/output.hpp index c1cb544c14..a5595b881a 100644 --- a/include/seqan3/io/structure_file/output.hpp +++ b/include/seqan3/io/structure_file/output.hpp @@ -154,7 +154,7 @@ namespace seqan3 * The record-based interface treats the file as a range of tuples (the records), but in certain situations * you might have the data as columns, i.e. a tuple-of-ranges, instead of range-of-tuples. * - * You can use column-based writing in that case, it uses operator=() : + * You can use column-based writing in that case, it uses operator=() and views::zip(): * * \include test/snippet/io/structure_file/structure_file_output_col_based.cpp * @@ -543,89 +543,6 @@ class structure_file_output } //!\} - /*!\name Tuple interface - * \brief Provides functions for field-based ("column"-based) writing. - * \{ - */ - /*!\brief Write columns (wrapped in a seqan3::record) to the file. - * \tparam typelist Template argument to seqan3::record, each type must be a column (range-of-range). - * \tparam field_ids Template argument to seqan3::record, the IDs corresponding to the columns. - * \param[in] r The record of columns. - * - * \details - * - * \attention This is not part of the row-based file writing; the seqan3::record does not represent a file record, - * it is a tuple of the columns (with field information). - * - * ### Complexity - * - * Linear in the size of the columns. - * - * ### Exceptions - * - * Basic exception safety. - * - * ### Example - * - * \include test/snippet/io/structure_file/structure_file_output_col_based.cpp - */ - template - structure_file_output & operator=(record const & r) - { - write_columns(detail::range_wrap_ignore(detail::get_or_ignore(r)), - detail::range_wrap_ignore(detail::get_or_ignore(r)), - detail::range_wrap_ignore(detail::get_or_ignore(r)), - detail::range_wrap_ignore(detail::get_or_ignore(r)), - detail::range_wrap_ignore(detail::get_or_ignore(r)), - detail::range_wrap_ignore(detail::get_or_ignore(r)), - detail::range_wrap_ignore(detail::get_or_ignore(r)), - detail::range_wrap_ignore(detail::get_or_ignore(r)), - detail::range_wrap_ignore(detail::get_or_ignore(r)), - detail::range_wrap_ignore(detail::get_or_ignore(r))); - return *this; - } - - /*!\brief Write columns (wrapped in a std::tuple) to the file. - * \tparam arg_types The column types, each type must be a range-of-range. - * \param[in] t The tuple of columns. - * - * \details - * - * The columns are assumed to correspond to the field IDs given in selected_field_ids, however passing less - * is accepted if the format does not require all of them. - * - * ### Complexity - * - * Linear in the size of the columns. - * - * ### Exceptions - * - * Basic exception safety. - * - * ### Example - * - * \include test/snippet/io/structure_file/structure_file_output_col_based.cpp - * - */ - template - structure_file_output & operator=(std::tuple const & t) - { - // index_of might return npos, but this will be handled well by get_or_ignore (and just return ignore) - write_columns( - detail::range_wrap_ignore(detail::get_or_ignore(t)), - detail::range_wrap_ignore(detail::get_or_ignore(t)), - detail::range_wrap_ignore(detail::get_or_ignore(t)), - detail::range_wrap_ignore(detail::get_or_ignore(t)), - detail::range_wrap_ignore(detail::get_or_ignore(t)), - detail::range_wrap_ignore(detail::get_or_ignore(t)), - detail::range_wrap_ignore(detail::get_or_ignore(t)), - detail::range_wrap_ignore(detail::get_or_ignore(t)), - detail::range_wrap_ignore(detail::get_or_ignore(t)), - detail::range_wrap_ignore(detail::get_or_ignore(t))); - return *this; - } - //!\} - //!\brief The options are public and its members can be set directly. structure_file_output_options options; @@ -723,88 +640,6 @@ class structure_file_output }, format); } - //!\brief Write columns to file format, only tag-dispatch once. - template - void write_columns(seq_type && seq, - id_type && id, - bpp_type && bpp, - structure_type && structure, - structured_seq_type && structured_seq, - energy_type && energy, - react_type && react, - react_type && react_error, - comment_type && comment, - offset_type && offset) - { - static_assert(!(detail::decays_to_ignore_v> && - detail::decays_to_ignore_v> && - detail::decays_to_ignore_v> && - detail::decays_to_ignore_v> && - detail::decays_to_ignore_v> && - detail::decays_to_ignore_v> && - detail::decays_to_ignore_v> && - detail::decays_to_ignore_v> && - detail::decays_to_ignore_v>), - "At least one of the columns must not be set to std::ignore."); - - static_assert(detail::decays_to_ignore_v> || - (detail::decays_to_ignore_v> && - detail::decays_to_ignore_v>), - "You may not select field::STRUCTURED_SEQ and either of field::SEQ and field::STRUCTURE " - "at the same time."); - - assert(!format.valueless_by_exception()); - std::visit([&] (auto & f) - { - if constexpr (!detail::decays_to_ignore_v>) - { - auto zipped = views::zip(structured_seq, id, bpp, energy, react, react_error, comment, offset); - - for (auto && v : zipped) - { - f.write_structure_record(*secondary_stream, - options, - std::get<0>(v) | views::get<0>, // seq - std::get<1>(v), // id - std::get<2>(v), // bpp - std::get<0>(v) | views::get<1>, // structure - std::get<3>(v), // energy - std::get<4>(v), // react - std::get<5>(v), // react_error - std::get<6>(v), // comment - std::get<7>(v)); // offset - } - } - else - { - auto zipped = views::zip(seq, id, bpp, structure, energy, react, react_error, comment, offset); - - for (auto && v : zipped) - { - f.write_structure_record(*secondary_stream, - options, - std::get<0>(v), - std::get<1>(v), - std::get<2>(v), - std::get<3>(v), - std::get<4>(v), - std::get<5>(v), - std::get<6>(v), - std::get<7>(v), - std::get<8>(v)); - } - } - }, format); - } - //!\brief Befriend iterator so it can access the buffers. friend iterator; }; diff --git a/test/snippet/io/structure_file/structure_file_output_col_based.cpp b/test/snippet/io/structure_file/structure_file_output_col_based.cpp index 8de7e1f90d..dada5b85ec 100644 --- a/test/snippet/io/structure_file/structure_file_output_col_based.cpp +++ b/test/snippet/io/structure_file/structure_file_output_col_based.cpp @@ -1,12 +1,12 @@ #include #include -#include #include #include #include #include #include +#include using seqan3::operator""_rna5; using seqan3::operator""_wuss51; @@ -26,5 +26,5 @@ int main() seqan3::structure_file_output fout{std::ostringstream{}, seqan3::format_vienna{}}; - fout = std::tie(data_storage.sequences, data_storage.ids, data_storage.structures); + fout = seqan3::views::zip(data_storage.sequences, data_storage.ids, data_storage.structures); } diff --git a/test/unit/io/structure_file/structure_file_output_test.cpp b/test/unit/io/structure_file/structure_file_output_test.cpp index ab6a986185..5eee949f1b 100644 --- a/test/unit/io/structure_file/structure_file_output_test.cpp +++ b/test/unit/io/structure_file/structure_file_output_test.cpp @@ -396,22 +396,9 @@ TEST_F(structure_file_output_rows, assign_structure_file_pipes) struct structure_file_output_columns : public structure_file_output_rows{}; -TEST_F(structure_file_output_columns, assign_record_of_columns) +TEST_F(structure_file_output_columns, assign_columns) { - record, std::vector, std::vector>>, - fields> columns - { - seqs, - ids, - structures - }; - - assign_impl(columns); -} - -TEST_F(structure_file_output_columns, assign_tuple_of_columns) -{ - assign_impl(std::tie(seqs, ids, structures)); + assign_impl(views::zip(seqs, ids, structures)); } // ----------------------------------------------------------------------------