Skip to content
This repository has been archived by the owner on Jan 19, 2024. It is now read-only.

Commit

Permalink
Take out enumerable::const_iterator
Browse files Browse the repository at this point in the history
Having iterator and const_iterator in enumerable did
not make much sense since enumerable is in itself a
front for a sequence. It would've been trivial to copy
the enumerable to access the non-const methods.
So now enumerable only has an iterator and begin
and end are both const methods. If you want const,
use enumerable<const foo> (added a new as_const
method to simplify this).
  • Loading branch information
clechasseur committed Sep 25, 2017
1 parent dfbe935 commit 75742f6
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 83 deletions.
95 changes: 12 additions & 83 deletions lib/coveo/enumerable/enumerable.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ namespace coveo {

// Wrapper for a multipass, forward-only sequence of elements.
// Uses a delegate to fetch the elements to return. The sequence
// supports iteration via the standard begin/cbegin and end/cend methods.
// supports iteration via the standard begin/end methods.
template<typename T>
class enumerable
{
Expand All @@ -32,20 +32,15 @@ class enumerable
typedef typename detail::seq_element_traits<T>::pointer pointer; // Pointer to a sequence element.
typedef typename detail::seq_element_traits<T>::reference reference; // Reference to a sequence element.

typedef typename detail::seq_element_traits<T>::const_value_type const_value_type; // Same as above for const_iterator
typedef typename detail::seq_element_traits<T>::const_pointer const_pointer;
typedef typename detail::seq_element_traits<T>::const_reference const_reference;

// Delegate that returns next element in sequence, or nullptr when done.
// Receives a stable unique_ptr<raw_value_type> each time that can be used to store next value.
typedef std::function<pointer(std::unique_ptr<raw_value_type>&)> next_delegate;

// Delegate that returns number of elements in sequence.
typedef std::function<std::size_t()> size_delegate;

// Forward declaration of iterator classes.
// Forward declaration of iterator class.
class iterator;
class const_iterator;

private:
next_delegate zero_; // Next delegate which we will clone to iterate sequence.
Expand Down Expand Up @@ -107,26 +102,13 @@ class enumerable
}

// Access to beginning or end of sequence
iterator begin() {
iterator begin() const {
return iterator(*this, false);
}
const_iterator begin() const {
return cbegin();
}
const_iterator cbegin() const {
return const_iterator(*this, false);
}

iterator end() {
iterator end() const {
return iterator(*this, true);
}
const_iterator end() const {
return cend();
}
const_iterator cend() const {
return const_iterator(*this, true);
}


// Access to size of sequence
bool has_fast_size() const {
// If we have a delegate, size() should be reasonably fast
Expand All @@ -135,7 +117,12 @@ class enumerable
std::size_t size() const {
// If we have a delegate, use it, otherwise use distance.
return size_ != nullptr ? size_()
: static_cast<std::size_t>(std::distance(cbegin(), cend()));
: static_cast<std::size_t>(std::distance(begin(), end()));
}

// Returns const version of this enumerable
auto as_const() const -> enumerable<typename std::add_const<T>::type> {
return enumerable<typename std::add_const<T>::type>(*this);
}

public:
Expand Down Expand Up @@ -192,7 +179,7 @@ class enumerable
: pparent_(nullptr), next_(), upopt_(), pcur_(nullptr), has_cur_(true), pos_(0) { }

// Constructor from enumerable
iterator(enumerable<T>& parent, bool is_end)
iterator(const enumerable<T>& parent, bool is_end)
: pparent_(&parent), next_(!is_end ? parent.zero_ : next_delegate()),
upopt_(), pcur_(nullptr), has_cur_(is_end), pos_(0) { }

Expand Down Expand Up @@ -273,64 +260,6 @@ class enumerable
}
};

// Const iterator for the elements in an enumerable's sequence.
class const_iterator
{
public:
// Standard iterator typedefs, plus a few
typedef std::forward_iterator_tag iterator_category;
typedef typename enumerable<T>::const_value_type value_type;
typedef typename enumerable<T>::raw_value_type raw_value_type; // Non-standard
typedef std::ptrdiff_t difference_type;
typedef typename enumerable<T>::const_pointer pointer;
typedef typename enumerable<T>::const_reference reference;

private:
iterator it_; // Wrapped iterator implementation

public:
// Default constructor
const_iterator()
: it_() { }

// Constructor from enumerable
const_iterator(const enumerable<T>& parent, bool is_end)
: it_(const_cast<enumerable<T>&>(parent), is_end) { }

// Constructors from non-const iterator
const_iterator(const iterator& it)
: it_(it) { }
const_iterator(iterator&& it)
: it_(std::move(it)) { }

// Element access
reference operator*() const {
return *it_;
}
pointer operator->() const {
return it_.operator->();
}

// Move to next element (pre/post versions)
const_iterator& operator++() {
++it_;
return *this;
}
const_iterator operator++(int) {
const_iterator it(*this);
++*this;
return it;
}

// Iterator comparison
friend bool operator==(const const_iterator& left, const const_iterator& right) {
return left.it_ == right.it_;
}
friend bool operator!=(const const_iterator& left, const const_iterator& right) {
return !(left == right);
}
};

public:
// Helper static methods

Expand Down
25 changes: 25 additions & 0 deletions tests/coveo/enumerable/enumerable_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,8 @@ void enumerable_tests()
std::vector<int> vempty;
auto empty_seq = coveo::enumerable<int>::empty();
detail::validate_sequence(empty_seq, vempty, true);
auto empty_cseq = empty_seq.as_const();
detail::validate_sequence(empty_cseq, vempty, true);
}
{
const std::vector<int> vempty;
Expand All @@ -128,6 +130,8 @@ void enumerable_tests()
}
});
detail::validate_sequence(seq_i, vi, false);
auto seq_ci = seq_i.as_const();
detail::validate_sequence(seq_ci, vi, false);
}
{
const std::vector<int> vi = { 42 };
Expand All @@ -147,6 +151,8 @@ void enumerable_tests()
std::vector<int> vone = { 42 };
auto seq_one = coveo::enumerable<int>::for_one(42);
detail::validate_sequence(seq_one, vone, true);
auto seq_cone = seq_one.as_const();
detail::validate_sequence(seq_cone, vone, true);
}
{
std::vector<int> vone = { 42 };
Expand All @@ -171,6 +177,8 @@ void enumerable_tests()
std::vector<int> vone = { 23 };
auto seq_one_ref = coveo::enumerable<int>::for_one_ref(hangar);
detail::validate_sequence(seq_one_ref, vone, true);
auto seq_cone_ref = seq_one_ref.as_const();
detail::validate_sequence(seq_cone_ref, vone, true);
}
{
int hangar = 23;
Expand All @@ -197,6 +205,8 @@ void enumerable_tests()
std::vector<int> vexpected = { 42, 23, 66 };
auto seq_range = coveo::enumerable<int>::for_range(vforseq.begin(), vforseq.end());
detail::validate_sequence(seq_range, vexpected, true);
auto seq_crange = seq_range.as_const();
detail::validate_sequence(seq_crange, vexpected, true);
}
{
std::vector<int> vforseq = { 42, 23, 66 };
Expand All @@ -223,6 +233,8 @@ void enumerable_tests()
std::vector<int> vexpected = { 42, 23, 66 };
auto seq_cnt = coveo::enumerable<int>(vcnt);
detail::validate_sequence(seq_cnt, vexpected, true);
auto seq_ccnt = seq_cnt.as_const();
detail::validate_sequence(seq_ccnt, vexpected, true);
}
{
std::vector<int> vcnt = { 42, 23, 66 };
Expand Down Expand Up @@ -260,6 +272,8 @@ void enumerable_tests()
std::vector<int> vexpected = { 42, 23, 66 };
auto seq_cnt_mv = coveo::enumerable<int>(std::vector<int> { 42, 23, 66 });
detail::validate_sequence(seq_cnt_mv, vexpected, true);
auto seq_ccnt_mv = seq_cnt_mv.as_const();
detail::validate_sequence(seq_ccnt_mv, vexpected, true);
}
{
std::vector<int> vexpected = { 42, 23, 66 };
Expand All @@ -281,6 +295,11 @@ void enumerable_tests()
auto seq_cnt_mv = coveo::enumerable<const int>::for_container(std::vector<int> { 42, 23, 66 });
detail::validate_sequence(seq_cnt_mv, vexpected, true);
}
{
const std::vector<int> vexpected = { 42, 23, 66 };
auto seq_cnt_mv = coveo::enumerable<const int>::for_container(std::vector<int> { 42, 23, 66 });
detail::validate_sequence(seq_cnt_mv, vexpected, true);
}

// sequence in array
{
Expand All @@ -289,6 +308,8 @@ void enumerable_tests()
std::vector<int> vexpected = { 42, 23, 66 };
auto seq_arr = coveo::enumerable<int>::for_array(arr, arr_size);
detail::validate_sequence(seq_arr, vexpected, true);
auto seq_carr = seq_arr.as_const();
detail::validate_sequence(seq_carr, vexpected, true);
}
{
int arr[] = { 42, 23, 66 };
Expand Down Expand Up @@ -327,6 +348,8 @@ void enumerable_tests()
std::list<detail::no_copy> lexpected;
lexpected.emplace_back(42);
detail::validate_sequence(seq, lexpected, false);
auto cseq = seq.as_const();
detail::validate_sequence(cseq, lexpected, false);
}
{
const detail::no_copy an_obj(42);
Expand All @@ -353,6 +376,8 @@ void enumerable_tests()
std::vector<int> vexpected = { 42, 23, 66 };
auto seq_cnt = coveo::enumerate_container(vcnt);
detail::validate_sequence(seq_cnt, vexpected, true);
auto seq_ccnt = seq_cnt.as_const();
detail::validate_sequence(seq_ccnt, vexpected, true);
}

// non-const to const
Expand Down

0 comments on commit 75742f6

Please sign in to comment.