Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deprecate/take exactly #2601

Merged
merged 2 commits into from
May 11, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -243,14 +243,16 @@ regression test suite and patches at https://github.com/seqan/seqan3/tree/master
* Deprecated `seqan3::views::drop`, use `std::views::drop` or `seqan3::views::type_reduce | std::views::drop`.
([\#2540](https://github.com/seqan/seqan3/pull/2540))
* We deprecated `seqan3::views::join`. Please use `std::views::join` or `seqan3::views::join_with` instead
[\#2526](https://github.com/seqan/seqan3/pull/2526).
([\#2526](https://github.com/seqan/seqan3/pull/2526)).
* Deprecated `seqan3::views::move`, use the `std::ranges::move` algorithm, `std::[cpp20::]move_iterator` or an explicit
for loop where you move the value.
([\#2563](https://github.com/seqan/seqan3/pull/2563))
* We deprecated `seqan3::views::take` and it will be removed in 3.1.0. Use `std::views::take` instead
[\#2541](https://github.com/seqan/seqan3/pull/2541).
([\#2541](https://github.com/seqan/seqan3/pull/2541)).
* We deprecated `seqan3::views::take_line` and it will be removed in 3.1.0
[\#2525](https://github.com/seqan/seqan3/pull/2525).
([\#2525](https://github.com/seqan/seqan3/pull/2525)).
* We deprecated `seqan3::views::take_exactly`. Please use `std::views::take` or `std::views::counted` instead
([\#2601](https://github.com/seqan/seqan3/pull/2601)).
* We deprecated `seqan3::views::to_upper` and it will be removed in 3.1.0, use
`std::views::transform([](auto && chr){return std::toupper(chr)})`.
([\#2540](https://github.com/seqan/seqan3/pull/2538))
Expand Down
115 changes: 115 additions & 0 deletions include/seqan3/io/detail/take_exactly_view.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
// -----------------------------------------------------------------------------------------------------
// Copyright (c) 2006-2020, Knut Reinert & Freie Universität Berlin
// Copyright (c) 2016-2020, Knut Reinert & MPI für molekulare Genetik
// This file may be used, modified and/or redistributed under the terms of the 3-clause BSD-License
// shipped with this file and also available at: https://github.com/seqan/seqan3/blob/master/LICENSE.md
// -----------------------------------------------------------------------------------------------------

/*!\file
* \author Hannes Hauswedell <hannes.hauswedell AT fu-berlin.de>
* \brief Provides seqan3::views::take_exactly and seqan3::views::take_exactly_or_throw.
*/

#pragma once

#include <seqan3/io/detail/take_view.hpp>

// ============================================================================
// detail::take_exactly (adaptor instance definition)
// ============================================================================

namespace seqan3::detail
{

/*!\name General purpose views
* \{
*/

/*!\brief A view adaptor that returns the first `size` elements from the underlying range (or less if the
* underlying range is shorter); also provides size information.
* \tparam urng_t The type of the range being processed. See below for requirements. [template parameter is
* omitted in pipe notation]
* \param[in] urange The range being processed. [parameter is omitted in pipe notation]
* \param[in] size The target size of the view.
* \returns Up to `size` elements of the underlying range.
* \ingroup io
*
* \details
*
* \header_file{seqan3/io/detail/take_exactly_view.hpp}
*
* ### View properties
*
* | Concepts and traits | `urng_t` (underlying range type) | `rrng_t` (returned range type) |
* |----------------------------------|:-------------------------------------:|:--------------------------------------------------:|
* | std::ranges::input_range | *required* | *preserved* |
* | std::ranges::forward_range | | *preserved* |
* | std::ranges::bidirectional_range | | *preserved* |
* | std::ranges::random_access_range | | *preserved* |
* | std::ranges::contiguous_range | | *preserved* |
* | | | |
* | std::ranges::viewable_range | *required* | *guaranteed* |
* | std::ranges::view | | *guaranteed* |
* | std::ranges::sized_range | | ***guaranteed*** |
* | std::ranges::common_range | | *preserved* |
* | std::ranges::output_range | | *preserved* except if `urng_t` is std::basic_string|
* | seqan3::const_iterable_range | | *preserved* |
* | | | |
* | std::ranges::range_reference_t | | std::ranges::range_reference_t<urng_t> |
*
* See the \link views views submodule documentation \endlink for detailed descriptions of the view properties.
*
* The difference to seqan3::views::take is that this view always exposes size information – even if the underlying
* range is not sized. You should only use this if you know that the underlying range will always be
* at least `size` long.
*
* For seqan3::detail::take_exactly if the underlying range is shorter than `size`, the behaviour is undefined.
* seqan3::detail::take_exactly_or_throw is a safer alternative, because it throws an exception when an iterator before
* the `size`-th one compares equal to the end sentinel; and it also throws on construction if it knows that the
* underlying range is smaller.
*
* ### Example
*
* \include test/snippet/io/detail/take_exactly.cpp
*
* \hideinitializer
*/
inline auto constexpr take_exactly = take_fn<true, false>{};

// ============================================================================
// detail::take_exactly_or_throw (adaptor instance definition)
// ============================================================================

/*!\brief A view adaptor that returns the first `size` elements from the underlying range and also exposes size
* information; throws if the underlying range is smaller than `size`.
* \throws seqan3::unexpected_end_of_input If the underlying range is smaller than `size`.
* \ingroup io
*
* \copydetails seqan3::detail::take_exactly
* \hideinitializer
*/
inline auto constexpr take_exactly_or_throw = take_fn<true, true>{};

//!\}
} // namespace seqan3::detail

#ifdef SEQAN3_DEPRECATED_310
namespace seqan3::views
{

/*!\brief A view adaptor that returns the first `size` elements from the underlying range (or less if the
* underlying range is shorter); also provides size information.
* \ingroup io
* \deprecated Use std::views::take or std::views::counted instead.
*/
SEQAN3_DEPRECATED_310 inline auto constexpr take_exactly = detail::take_exactly;

/*!\brief A view adaptor that returns the first `size` elements from the underlying range and also exposes size
* information; throws if the underlying range is smaller than `size`.
* \ingroup io
* \deprecated Use std::views::take or std::views::counted instead.
*/
SEQAN3_DEPRECATED_310 inline auto constexpr take_exactly_or_throw = detail::take_exactly_or_throw;

} // namespace seqan3::views
#endif // SEQAN3_DEPRECATED_310
7 changes: 4 additions & 3 deletions include/seqan3/io/detail/take_view.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ namespace seqan3::detail
// view_take
// ============================================================================

/*!\brief The type returned by seqan3::views::take, seqan3::view::take_exactly and seqan3::views::take_exactly_or_throw.
/*!\brief The type returned by seqan3::views::take, seqan3::detail::take_exactly and
* seqan3::detail::take_exactly_or_throw.
* \tparam urng_t The type of the underlying ranges, must satisfy seqan3::views::concept.
* \tparam exactly Whether to expose sized'ness on the view.
* \tparam or_throw Whether to throw an exception when the input is exhausted before the end of line is reached.
Expand Down Expand Up @@ -103,7 +104,7 @@ class view_take : public std::ranges::view_interface<view_take<urng_t, exactly,
{
throw std::invalid_argument
{
"You are trying to construct a views::take_exactly_or_throw from a range that is strictly "
"You are trying to construct a detail::take_exactly_or_throw from a range that is strictly "
"smaller."
};
}
Expand Down Expand Up @@ -488,7 +489,7 @@ struct take_fn
{
if (target_size > std::ranges::size(urange))
{
throw std::invalid_argument{"You are trying to construct a views::take_exactly_or_throw from a "
throw std::invalid_argument{"You are trying to construct a detail::take_exactly_or_throw from a "
"range that is strictly smaller."};
}
}
Expand Down
18 changes: 9 additions & 9 deletions include/seqan3/io/sam_file/format_bam.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include <seqan3/core/range/type_traits.hpp>
#include <seqan3/io/detail/ignore_output_iterator.hpp>
#include <seqan3/io/detail/misc.hpp>
#include <seqan3/io/detail/take_exactly_view.hpp>
#include <seqan3/io/sam_file/detail/cigar.hpp>
#include <seqan3/io/sam_file/detail/format_sam_base.hpp>
#include <seqan3/io/sam_file/header.hpp>
Expand All @@ -37,7 +38,6 @@
#include <seqan3/io/sam_file/sam_flag.hpp>
#include <seqan3/io/sam_file/sam_tag_dictionary.hpp>
#include <seqan3/io/stream/detail/fast_ostreambuf_iterator.hpp>
#include <seqan3/range/views/take_exactly.hpp>
#include <seqan3/range/views/take_until.hpp>
#include <seqan3/utility/char_operations/predicate.hpp>
#include <seqan3/utility/detail/exposition_only_concept.hpp>
Expand Down Expand Up @@ -328,7 +328,7 @@ inline void format_bam::read_alignment_record(stream_type & stream,
if (!header_was_read)
{
// magic BAM string
if (!std::ranges::equal(stream_view | views::take_exactly_or_throw(4), std::string_view{"BAM\1"}))
if (!std::ranges::equal(stream_view | detail::take_exactly_or_throw(4), std::string_view{"BAM\1"}))
throw format_error{"File is not in BAM format."};

int32_t l_text{}; // length of header text including \0 character
Expand All @@ -339,7 +339,7 @@ inline void format_bam::read_alignment_record(stream_type & stream,
read_field(stream_view, l_text);

if (l_text > 0) // header text is present
read_header(stream_view | views::take_exactly_or_throw(l_text), header, ref_seqs);
read_header(stream_view | detail::take_exactly_or_throw(l_text), header, ref_seqs);

read_field(stream_view, n_ref);

Expand Down Expand Up @@ -399,7 +399,7 @@ inline void format_bam::read_alignment_record(stream_type & stream,
// read alignment record into buffer
// -------------------------------------------------------------------------------------------------------------
alignment_record_core core;
std::ranges::copy(stream_view | views::take_exactly_or_throw(sizeof(core)), reinterpret_cast<char *>(&core));
std::ranges::copy(stream_view | detail::take_exactly_or_throw(sizeof(core)), reinterpret_cast<char *>(&core));

if (core.refID >= static_cast<int32_t>(header.ref_ids().size()) || core.refID < -1) // [[unlikely]]
{
Expand Down Expand Up @@ -430,7 +430,7 @@ inline void format_bam::read_alignment_record(stream_type & stream,

// read id
// -------------------------------------------------------------------------------------------------------------
read_field(stream_view | views::take_exactly_or_throw(core.l_read_name - 1), id); // field::id
read_field(stream_view | detail::take_exactly_or_throw(core.l_read_name - 1), id); // field::id
std::ranges::next(std::ranges::begin(stream_view)); // skip '\0'

// read cigar string
Expand All @@ -443,7 +443,7 @@ inline void format_bam::read_alignment_record(stream_type & stream,
}
else
{
detail::consume(stream_view | views::take_exactly_or_throw(core.n_cigar_op * 4));
detail::consume(stream_view | detail::take_exactly_or_throw(core.n_cigar_op * 4));
}

offset = offset_tmp;
Expand All @@ -453,7 +453,7 @@ inline void format_bam::read_alignment_record(stream_type & stream,
if (core.l_seq > 0) // sequence information is given
{
auto seq_stream = stream_view
| views::take_exactly_or_throw(core.l_seq / 2) // one too short if uneven
| detail::take_exactly_or_throw(core.l_seq / 2) // one too short if uneven
| std::views::transform([] (char c) -> std::pair<dna16sam, dna16sam>
{
return {dna16sam{}.assign_rank(std::min(15, static_cast<uint8_t>(c) >> 4)),
Expand Down Expand Up @@ -549,15 +549,15 @@ inline void format_bam::read_alignment_record(stream_type & stream,

// read qual string
// -------------------------------------------------------------------------------------------------------------
read_field(stream_view | views::take_exactly_or_throw(core.l_seq)
read_field(stream_view | detail::take_exactly_or_throw(core.l_seq)
| std::views::transform([] (char chr) { return static_cast<char>(chr + 33); }), qual);

// All remaining optional fields if any: SAM tags dictionary
// -------------------------------------------------------------------------------------------------------------
int32_t remaining_bytes = core.block_size - (sizeof(alignment_record_core) - 4/*block_size excluded*/) -
core.l_read_name - core.n_cigar_op * 4 - (core.l_seq + 1) / 2 - core.l_seq;
assert(remaining_bytes >= 0);
auto tags_view = stream_view | views::take_exactly_or_throw(remaining_bytes);
auto tags_view = stream_view | detail::take_exactly_or_throw(remaining_bytes);

while (tags_view.size() > 0)
read_field(tags_view, tag_dict);
Expand Down
2 changes: 1 addition & 1 deletion include/seqan3/io/sam_file/format_sam.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -971,7 +971,7 @@ inline void format_sam::read_sam_byte_vector(seqan3::detail::sam_tag_variant & v
{
try
{
read_field(stream_view | views::take_exactly_or_throw(2), value);
read_field(stream_view | detail::take_exactly_or_throw(2), value);
}
catch (std::exception const & e)
{
Expand Down
2 changes: 1 addition & 1 deletion include/seqan3/io/sequence_file/format_fasta.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,14 @@
#include <seqan3/io/detail/ignore_output_iterator.hpp>
#include <seqan3/io/detail/istreambuf_view.hpp>
#include <seqan3/io/detail/misc.hpp>
#include <seqan3/io/detail/take_exactly_view.hpp>
#include <seqan3/io/detail/take_line_view.hpp>
#include <seqan3/io/detail/take_view.hpp>
#include <seqan3/io/sequence_file/input_format_concept.hpp>
#include <seqan3/io/sequence_file/input_options.hpp>
#include <seqan3/io/sequence_file/output_format_concept.hpp>
#include <seqan3/io/sequence_file/output_options.hpp>
#include <seqan3/io/stream/detail/fast_ostreambuf_iterator.hpp>
#include <seqan3/range/views/take_exactly.hpp>
#include <seqan3/range/views/take_until.hpp>
#include <seqan3/utility/char_operations/predicate.hpp>
#include <seqan3/utility/detail/type_name_as_string.hpp>
Expand Down
4 changes: 2 additions & 2 deletions include/seqan3/io/sequence_file/format_fastq.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,14 @@
#include <seqan3/io/detail/ignore_output_iterator.hpp>
#include <seqan3/io/detail/istreambuf_view.hpp>
#include <seqan3/io/detail/misc.hpp>
#include <seqan3/io/detail/take_exactly_view.hpp>
#include <seqan3/io/detail/take_line_view.hpp>
#include <seqan3/io/detail/take_view.hpp>
#include <seqan3/io/sequence_file/input_format_concept.hpp>
#include <seqan3/io/sequence_file/input_options.hpp>
#include <seqan3/io/sequence_file/output_format_concept.hpp>
#include <seqan3/io/sequence_file/output_options.hpp>
#include <seqan3/io/stream/detail/fast_ostreambuf_iterator.hpp>
#include <seqan3/range/views/take_exactly.hpp>
#include <seqan3/range/views/take_until.hpp>
#include <seqan3/utility/char_operations/predicate.hpp>
#include <seqan3/utility/detail/type_name_as_string.hpp>
Expand Down Expand Up @@ -185,7 +185,7 @@ class format_fastq

/* Qualities */
auto qview = stream_view | std::views::filter(!is_space) // this consumes trailing newline
| views::take_exactly_or_throw(sequence_size_after - sequence_size_before);
| detail::take_exactly_or_throw(sequence_size_after - sequence_size_before);
if constexpr (seq_qual_combined)
{
// seq_qual field implies that they are the same variable
Expand Down
7 changes: 3 additions & 4 deletions include/seqan3/range/views/all.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@
#ifdef SEQAN3_DEPRECATED_310
#include <seqan3/core/detail/persist_view.hpp>
#include <seqan3/io/detail/istreambuf_view.hpp>
#include <seqan3/io/detail/take_exactly_view.hpp>
#endif // SEQAN3_DEPRECATED_310
#include <seqan3/range/views/move.hpp>
#include <seqan3/range/views/take_exactly.hpp>
#include <seqan3/range/views/take_until.hpp>
#include <seqan3/utility/views/convert.hpp>
#include <seqan3/utility/views/deep.hpp>
Expand Down Expand Up @@ -143,9 +143,8 @@
* **Return range guarantees:** All view adaptors that are not *sink-only* return a range that meets at least
* `std::ranges::input_range` and also `std::ranges::view` (and conversely also `std::ranges::viewable_range`,
* because all views are viewable). Most views also preserve stronger
* properties, e.g. `std::ranges::random_access_range`, but this depends on the view. Some views also add
* properties not present on the input range, e.g. the range returned by `std::views::take_exactly` meets
* `std::ranges::sized_range`, independent of whether this was met by the input range.
* properties, e.g. `std::ranges::random_access_range`, but this depends on the view. Some views may add
* properties not present on the input range.
* * *preserved* in this context means that the returned range satisfies this concept if it is also satisfied by the
* underlying range.
* * *lost* means that this concept is never satisfied by the returned range, independent of whether the underlying
Expand Down
Loading