Skip to content

Commit

Permalink
Merge pull request #1697 from smehringer/range_fix
Browse files Browse the repository at this point in the history
[FIX] Fix constexpr and noexcept usage in the gap_decorator
  • Loading branch information
smehringer committed Apr 14, 2020
2 parents c9b27e3 + d4f1445 commit 5194c4f
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 59 deletions.
107 changes: 48 additions & 59 deletions include/seqan3/range/decorator/gap_decorator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,9 @@ class gap_decorator
//! sequence cannot be modified through the iterator there is no need for const.
using const_iterator = iterator;

//!\brief The type of the underlying view wrapped in seqan3::views::type_reduce.
using ungapped_view_type = decltype(views::type_reduce(std::declval<inner_type &&>()));

public:
/*!\name Range-associated member types
* \{
Expand All @@ -118,17 +121,12 @@ class gap_decorator
*/
//!\brief Default constructor. Attention: all operations on a solely default constructed decorator,
//! except assigning a new range, are UB.
constexpr gap_decorator() = default;
//!\brief Copy constructor.
constexpr gap_decorator(gap_decorator const &) = default;
//!\brief Copy construction via assignment.
constexpr gap_decorator & operator=(gap_decorator const &) = default;
//!\brief Move constructor.
constexpr gap_decorator(gap_decorator && rhs) = default;
//!\brief Move assignment.
constexpr gap_decorator & operator=(gap_decorator && rhs) = default;
//!\brief Use default deconstructor.
~gap_decorator() = default;
gap_decorator() = default;
gap_decorator(gap_decorator const &) = default; //!< Defaulted.
gap_decorator & operator=(gap_decorator const &) = default; //!< Defaulted.
gap_decorator(gap_decorator && rhs) = default; //!< Defaulted.
gap_decorator & operator=(gap_decorator && rhs) = default; //!< Defaulted.
~gap_decorator() = default; //!< Defaulted.

//!\brief Construct with the ungapped range type.
template <typename other_range_t>
Expand All @@ -150,9 +148,9 @@ class gap_decorator
*
* ### Exceptions
*
* No-throw guarantee.
* Strong exception guarantee.
*/
size_type size() const noexcept
size_type size() const
{
if (anchors.size())
return anchors.rbegin()->second + ungapped_view.size();
Expand Down Expand Up @@ -391,7 +389,7 @@ class gap_decorator
* \f$O(\log k)\f$ where \f$k\f$ is the number of gaps.
*
*/
constexpr reference operator[](size_type const i) const noexcept
reference operator[](size_type const i) const
{
return *iterator{*this, i};
}
Expand All @@ -412,12 +410,12 @@ class gap_decorator
*
* ### Exceptions
*
* No-throw guarantee. Does not modify the aligned sequences.
* Strong exception guarantee.
* \{
*/

//!\brief Checks whether `lhs` is equal to `rhs`.
friend bool operator==(gap_decorator const & lhs, gap_decorator const & rhs) noexcept
friend bool operator==(gap_decorator const & lhs, gap_decorator const & rhs)
{
if (lhs.size() == rhs.size() &&
lhs.anchors == rhs.anchors &&
Expand All @@ -430,13 +428,13 @@ class gap_decorator
}

//!\brief Checks whether `lhs` is not equal to `rhs`.
friend bool operator!=(gap_decorator const & lhs, gap_decorator const & rhs) noexcept
friend bool operator!=(gap_decorator const & lhs, gap_decorator const & rhs)
{
return !(lhs == rhs);
}

//!\brief Checks whether `lhs` is less than `rhs`.
friend bool operator<(gap_decorator const & lhs, gap_decorator const & rhs) noexcept
friend bool operator<(gap_decorator const & lhs, gap_decorator const & rhs)
{
auto lit = lhs.begin();
auto rit = rhs.begin();
Expand All @@ -453,7 +451,7 @@ class gap_decorator
}

//!\brief Checks whether `lhs` is less than or equal to `rhs`.
friend bool operator<=(gap_decorator const & lhs, gap_decorator const & rhs) noexcept
friend bool operator<=(gap_decorator const & lhs, gap_decorator const & rhs)
{
auto lit = lhs.begin();
auto rit = rhs.begin();
Expand All @@ -470,13 +468,13 @@ class gap_decorator
}

//!\brief Checks whether `lhs` is greater than `rhs`.
friend bool operator>(gap_decorator const & lhs, gap_decorator const & rhs) noexcept
friend bool operator>(gap_decorator const & lhs, gap_decorator const & rhs)
{
return !(lhs <= rhs);
}

//!\brief Checks whether `lhs` is greater than or equal to `rhs`.
friend bool operator>=(gap_decorator const & lhs, gap_decorator const & rhs) noexcept
friend bool operator>=(gap_decorator const & lhs, gap_decorator const & rhs)
{
return !(lhs < rhs);
}
Expand Down Expand Up @@ -505,9 +503,9 @@ class gap_decorator
* (second tuple position) and the one of its predecessor (if existing).
*
* ### Exceptions
* No-throw guarantee.
* Strong exception guarantee.
*/
constexpr size_type gap_length(set_iterator_type it) const noexcept
size_type gap_length(set_iterator_type it) const
{
return (it == anchors.begin()) ? it->second : it->second - (*std::prev(it)).second;
}
Expand Down Expand Up @@ -557,7 +555,7 @@ class gap_decorator
}

//!\brief Stores a (copy of a) view to the ungapped, underlying sequence.
decltype(views::type_reduce(std::declval<inner_type &&>())) ungapped_view{};
ungapped_view_type ungapped_view{};

//!\brief Set storing the anchor gaps.
anchor_set_type anchors{};
Expand Down Expand Up @@ -664,15 +662,15 @@ class gap_decorator<inner_type>::gap_decorator_iterator
/*!\name Constructors, destructor and assignment
* \{
*/
constexpr gap_decorator_iterator() = default; //!< Defaulted.
constexpr gap_decorator_iterator(gap_decorator_iterator const &) = default; //!< Defaulted.
constexpr gap_decorator_iterator & operator=(gap_decorator_iterator const &) = default; //!< Defaulted.
constexpr gap_decorator_iterator(gap_decorator_iterator &&) = default; //!< Defaulted.
constexpr gap_decorator_iterator & operator=(gap_decorator_iterator &&) = default; //!< Defaulted.
gap_decorator_iterator() = default; //!< Defaulted.
gap_decorator_iterator(gap_decorator_iterator const &) = default; //!< Defaulted.
gap_decorator_iterator & operator=(gap_decorator_iterator const &) = default; //!< Defaulted.
gap_decorator_iterator(gap_decorator_iterator &&) = default; //!< Defaulted.
gap_decorator_iterator & operator=(gap_decorator_iterator &&) = default; //!< Defaulted.
~gap_decorator_iterator() = default; //!< Defaulted.

//!\brief Construct from seqan3::gap_decorator and initialising to first position.
explicit constexpr gap_decorator_iterator(gap_decorator const & host_) noexcept :
explicit gap_decorator_iterator(gap_decorator const & host_) :
host(&host_), anchor_set_it{host_.anchors.begin()}
{
if (host_.anchors.size() && (*host_.anchors.begin()).first == 0) // there are gaps at the very front
Expand All @@ -688,8 +686,7 @@ class gap_decorator<inner_type>::gap_decorator_iterator
}

//!\brief Construct from seqan3::gap_decorator and explicit position.
constexpr gap_decorator_iterator(gap_decorator const & host_,
typename gap_decorator::size_type const pos_) noexcept : host(&host_)
gap_decorator_iterator(gap_decorator const & host_, typename gap_decorator::size_type const pos_) : host(&host_)
{
jump(pos_); // random access to pos
}
Expand All @@ -699,7 +696,7 @@ class gap_decorator<inner_type>::gap_decorator_iterator
* \{
*/
//!\brief Increments iterator.
constexpr gap_decorator_iterator & operator++() noexcept
gap_decorator_iterator & operator++()
{
assert(host); // host is set
++pos;
Expand Down Expand Up @@ -728,35 +725,34 @@ class gap_decorator<inner_type>::gap_decorator_iterator
}

//!\brief Returns an incremented iterator copy.
constexpr gap_decorator_iterator operator++(int) noexcept
gap_decorator_iterator operator++(int)
{
gap_decorator_iterator cpy{*this};
++(*this);
return cpy;
}

//!\brief Advances iterator by `skip` many positions.
constexpr gap_decorator_iterator & operator+=(difference_type const skip) noexcept
gap_decorator_iterator & operator+=(difference_type const skip)
{
this->jump(this->pos + skip);
return *this;
}

//!\brief Returns an iterator copy advanced by `skip` many positions.
constexpr gap_decorator_iterator operator+(difference_type const skip) const noexcept
gap_decorator_iterator operator+(difference_type const skip) const
{
return gap_decorator_iterator{*(this->host), this->pos + skip};
}

//!\brief Returns an iterator copy advanced by `skip` many positions.
constexpr friend gap_decorator_iterator operator+(difference_type const skip,
gap_decorator_iterator const & it) noexcept
friend gap_decorator_iterator operator+(difference_type const skip, gap_decorator_iterator const & it)
{
return it + skip;
}

//!\brief Decrements iterator.
constexpr gap_decorator_iterator & operator--() noexcept
gap_decorator_iterator & operator--()
{
assert(host); // host is set
--pos;
Expand Down Expand Up @@ -788,35 +784,34 @@ class gap_decorator<inner_type>::gap_decorator_iterator
}

//!\brief Returns a decremented iterator copy.
constexpr gap_decorator_iterator operator--(int) noexcept
gap_decorator_iterator operator--(int)
{
gap_decorator_iterator cpy{*this};
--(*this);
return cpy;
}

//!\brief Advances iterator by `skip` many positions.
constexpr gap_decorator_iterator & operator-=(difference_type const skip) noexcept
gap_decorator_iterator & operator-=(difference_type const skip)
{
this->jump(this->pos - skip);
return *this;
}

//!\brief Returns an iterator copy advanced by `skip` many positions.
constexpr gap_decorator_iterator operator-(difference_type const skip) const noexcept
gap_decorator_iterator operator-(difference_type const skip) const
{
return gap_decorator_iterator{*(this->host), this->pos - skip};
}

//!\brief Returns an iterator copy advanced by `skip` many positions.
constexpr friend gap_decorator_iterator operator-(difference_type const skip,
gap_decorator_iterator const & it) noexcept
friend gap_decorator_iterator operator-(difference_type const skip, gap_decorator_iterator const & it)
{
return it - skip;
}

//!\brief Returns the distance between two iterators.
constexpr difference_type operator-(gap_decorator_iterator const lhs) const noexcept
difference_type operator-(gap_decorator_iterator const lhs) const noexcept
{
return static_cast<difference_type>(this->pos - lhs.pos);
}
Expand All @@ -826,13 +821,13 @@ class gap_decorator<inner_type>::gap_decorator_iterator
* \{
*/
//!\brief Dereference operator returns a copy of the element currently pointed at.
constexpr reference operator*() const noexcept
reference operator*() const
{
return (is_at_gap) ? reference{gap{}} : reference{host->ungapped_view[ungapped_view_pos]};
}

//!\brief Return underlying container value currently pointed at.
constexpr reference operator[](difference_type const n) const noexcept
reference operator[](difference_type const n) const
{
return *(*this + n);
}
Expand All @@ -844,43 +839,37 @@ class gap_decorator<inner_type>::gap_decorator_iterator
*/

//!\brief Checks whether `*this` is equal to `rhs`.
constexpr friend bool operator==(gap_decorator_iterator const & lhs, gap_decorator_iterator const & rhs)
noexcept
friend bool operator==(gap_decorator_iterator const & lhs, gap_decorator_iterator const & rhs) noexcept
{
return lhs.pos == rhs.pos;
}

//!\brief Checks whether `*this` is not equal to `rhs`.
constexpr friend bool operator!=(gap_decorator_iterator const & lhs, gap_decorator_iterator const & rhs)
noexcept
friend bool operator!=(gap_decorator_iterator const & lhs, gap_decorator_iterator const & rhs) noexcept
{
return lhs.pos != rhs.pos;
}

//!\brief Checks whether `*this` is less than `rhs`.
constexpr friend bool operator<(gap_decorator_iterator const & lhs, gap_decorator_iterator const & rhs)
noexcept
friend bool operator<(gap_decorator_iterator const & lhs, gap_decorator_iterator const & rhs) noexcept
{
return lhs.pos < rhs.pos;
}

//!\brief Checks whether `*this` is greater than `rhs`.
constexpr friend bool operator>(gap_decorator_iterator const & lhs, gap_decorator_iterator const & rhs)
noexcept
friend bool operator>(gap_decorator_iterator const & lhs, gap_decorator_iterator const & rhs) noexcept
{
return lhs.pos > rhs.pos;
}

//!\brief Checks whether `*this` is less than or equal to `rhs`.
constexpr friend bool operator<=(gap_decorator_iterator const & lhs, gap_decorator_iterator const & rhs)
noexcept
friend bool operator<=(gap_decorator_iterator const & lhs, gap_decorator_iterator const & rhs) noexcept
{
return lhs.pos <= rhs.pos;
}

//!\brief Checks whether `*this` is greater than or equal to `rhs`.
constexpr friend bool operator>=(gap_decorator_iterator const & lhs, gap_decorator_iterator const & rhs)
noexcept
friend bool operator>=(gap_decorator_iterator const & lhs, gap_decorator_iterator const & rhs) noexcept
{
return lhs.pos >= rhs.pos;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,11 @@ TYPED_TEST_P(alignment_file_read, read_in_alignment_only_without_ref)

size_t i{0};
for (auto & [alignment] : fin)
{
EXPECT_TRUE(std::ranges::equal(std::get<1>(alignment), std::get<1>(this->alignments[i++])));
auto & ref_aln = std::get<0>(alignment);
EXPECT_THROW((ref_aln[0]), std::logic_error); // access on a dummy seq is not allowed
}
}

{ // empty cigar
Expand Down

0 comments on commit 5194c4f

Please sign in to comment.