coveo::linq
Implementation of .NET-like LINQ operators in C++
Classes | Public Types | Public Member Functions | Static Public Member Functions | List of all members
coveo::enumerable< T > Class Template Reference

Type-erased sequence wrapper. More...

Classes

class  iterator
 Iterator for elements in the sequence. More...
 

Public Types

using value_type = typename seq_element_traits< T >::value_type
 Type of element in the sequence. More...
 
using raw_value_type = typename seq_element_traits< T >::raw_value_type
 Raw type of element in the sequence. More...
 
using pointer = typename seq_element_traits< T >::pointer
 Pointer to a sequence element. More...
 
using reference = typename seq_element_traits< T >::reference
 Reference to a sequence element. More...
 
using next_delegate = std::function< pointer()>
 Delegate to fetch next element. More...
 
using size_delegate = std::function< std::size_t()>
 Delegate to fetch sequence size. More...
 
using const_iterator = iterator
 iterator alias. More...
 

Public Member Functions

 enumerable ()
 Default constructor. More...
 
template<typename F , typename _S = std::nullptr_t, typename = typename std::enable_if<!is_enumerable<typename std::decay<F>::type>::value && (!detail::has_begin<typename std::decay<F>::type>::value || !detail::has_end<typename std::decay<F>::type>::value), void>::type>
 enumerable (F &&next, _S &&siz=nullptr)
 Constructor with delegates. More...
 
template<typename C , typename = typename std::enable_if<!is_enumerable<typename std::decay<C>::type>::value && detail::has_begin<typename std::decay<C>::type>::value && detail::has_end<typename std::decay<C>::type>::value, void>::type>
 enumerable (C &&cnt)
 Constructor with container. More...
 
template<typename U , typename = typename std::enable_if<!std::is_const<U>::value && std::is_same<T, typename std::add_const<U>::type>::value, void>::type>
 enumerable (enumerable< U > e)
 Constructor for non-const to const conversion. More...
 
template<typename U , typename = typename std::enable_if<!std::is_const<U>::value && std::is_same<T, typename std::add_const<U>::type>::value, void>::type>
enumerableoperator= (enumerable< U > e)
 Assignment operator for non-const to const conversion. More...
 
iterator begin () const
 Iterator to beginning of sequence. More...
 
iterator cbegin () const
 Alias for begin(). More...
 
iterator end () const
 Iterator to end of sequence. More...
 
iterator cend () const
 Alias for end(). More...
 
bool has_fast_size () const
 Determines if size() is fast. More...
 
std::size_t size () const
 Size of sequence. More...
 
auto as_const () const -> enumerable< typename std::add_const< T >::type >
 Non-const to const explicit conversion. More...
 

Static Public Member Functions

static enumerable< T > empty ()
 Returns enumerable over empty sequence. More...
 
template<typename U >
static enumerable< T > for_one (U &&obj)
 Returns enumerable over sequence of one element (stored internally). More...
 
static enumerable< T > for_one_ref (reference obj)
 Returns enumerable over sequence of one element (stored externally). More...
 
template<typename It >
static enumerable< T > for_range (It ibeg, It iend)
 Returns enumerable over sequence bound by iterators. More...
 
template<typename C >
static enumerable< T > for_container (C &cnt)
 Returns enumerable over container's sequence (stored externally). More...
 
template<typename C , typename = typename std::enable_if<!std::is_reference<C>::value, void>::type>
static enumerable< T > for_container (C &&cnt)
 Returns enumerable over container's sequence (stored internally). More...
 
static enumerable< T > for_array (pointer parr, size_t siz)
 Returns enumerable over array's sequence. More...
 

Detailed Description

template<typename T>
class coveo::enumerable< T >

Inspired by .NET's IEnumerable<T>, coveo::enumerable is a type-erased wrapper for a multipass, forward-only sequence of elements. It is possible to iterate over the elements using begin() / end() (or cbegin() / cend(), which is equivalent since this class is immutable).

In order to fetch the elements to return, this class uses a next delegate - a function that returns a pointer to the next element every time it is called, finally returning nullptr when the enumeration is over. The next delegate is provided at construction time and cannot change.

Optionally, it is also possible to specify a size delegeate for the enumerable at construction time. If provided, it will be used to fetch the number of elements in the sequence when size() is called; otherwise, a slower algorithm is used (iterating over the entire sequence using std::distance()). It is possible to determine if the enumerable has a fast size delegate by using has_fast_size().

While this class is immutable, the elements it returns are not necessarily so. In order to wrap a sequence of const elements, const must also be specified in this class' template argument:

coveo::enumerable<const int> e1; // Iterates over const integers
coveo::enumerable<int> e2; // Iterates over non-const integers
Template Parameters
TType of elements stored in the sequence.

Member Typedef Documentation

◆ value_type

template<typename T>
using coveo::enumerable< T >::value_type = typename seq_element_traits<T>::value_type

Type of element stored in the sequence.

◆ raw_value_type

template<typename T>
using coveo::enumerable< T >::raw_value_type = typename seq_element_traits<T>::raw_value_type

Same as coveo::enumerable::value_type, but "raw", e.g. without const or volatile.

◆ pointer

template<typename T>
using coveo::enumerable< T >::pointer = typename seq_element_traits<T>::pointer

Pointer to an element in the sequence. Corresponds to coveo::enumerable::value_type*. This is the type of pointer returned by the coveo::enumerable::next_delegate.

◆ reference

template<typename T>
using coveo::enumerable< T >::reference = typename seq_element_traits<T>::reference

Reference to an element in the sequence. Corresponds to coveo::enumerable::value_type&. This is the type of reference returned by the coveo::enumerable::iterators.

◆ next_delegate

template<typename T>
using coveo::enumerable< T >::next_delegate = std::function<pointer()>

Delegate that will be called by the enumerable to fetch the next element in the sequence when needed. The delegate must return a coveo::enumerable::pointer to the next element if there is one, or nullptr when done.

◆ size_delegate

template<typename T>
using coveo::enumerable< T >::size_delegate = std::function<std::size_t()>

Delegate that will be called by the enumerable to fetch the number of elements in the sequence when size() is called.

◆ const_iterator

template<typename T>
using coveo::enumerable< T >::const_iterator = iterator

Alias for coveo::enumerable::iterator. Provided because even though begin() and end() are already const, some generic code might want to use const_iterator.

Constructor & Destructor Documentation

◆ enumerable() [1/4]

template<typename T>
coveo::enumerable< T >::enumerable ( )
inline

Default constructor. Wraps an empty sequence.

Using this constructor is equivalent to calling empty().

See also
empty()

◆ enumerable() [2/4]

template<typename T>
template<typename F , typename _S = std::nullptr_t, typename = typename std::enable_if<!is_enumerable<typename std::decay<F>::type>::value && (!detail::has_begin<typename std::decay<F>::type>::value || !detail::has_end<typename std::decay<F>::type>::value), void>::type>
coveo::enumerable< T >::enumerable ( F &&  next,
_S &&  siz = nullptr 
)
inline

Constructor that accepts a coveo::enumerable::next_delegate as well as an optional coveo::enumerable::size_delegate. The next delegate is used to fetch the elements to return during iteration. The size delegate, if provided, will be called to know the size() of the sequence.

Parameters
nextFunction object to use as next delegate.
sizOptional function object to use as size delegate. Defaults to nullptr.
See also
coveo::enumerable::next_delegate
coveo::enumerable::size_delegate
size()
has_fast_size()

◆ enumerable() [3/4]

template<typename T>
template<typename C , typename = typename std::enable_if<!is_enumerable<typename std::decay<C>::type>::value && detail::has_begin<typename std::decay<C>::type>::value && detail::has_end<typename std::decay<C>::type>::value, void>::type>
coveo::enumerable< T >::enumerable ( C &&  cnt)
inline

Constructor that wraps a container. The container must have the following methods to be accepted by this constructor:

  • begin (or a specialization of std::begin())
  • end (or a specialization of std::end())

The container will be wrapped in the enumerable, either by keeping a reference to it or by storing it internally, depending on how the container is passed to the method (if it is moved, it will be stored internally).

Using this constructor is equivalent to calling for_container(). It is provided implicitely so that it is possible to call a function declared as accepting a coveo::enumerable with a container instance directly.

Parameters
cntContainer to wrap.
See also
for_container()

◆ enumerable() [4/4]

template<typename T>
template<typename U , typename = typename std::enable_if<!std::is_const<U>::value && std::is_same<T, typename std::add_const<U>::type>::value, void>::type>
coveo::enumerable< T >::enumerable ( enumerable< U >  e)
inline

Constructor that creates an enumerable over const elements from an enumerable over non-const elements of the same type. Allows implicit non-const to const conversion.

Parameters
ecoveo::enumerable to convert.

Member Function Documentation

◆ operator=()

template<typename T>
template<typename U , typename = typename std::enable_if<!std::is_const<U>::value && std::is_same<T, typename std::add_const<U>::type>::value, void>::type>
enumerable& coveo::enumerable< T >::operator= ( enumerable< U >  e)
inline

Assignment operator that allows an enumerable over non-const elements to be assigned to an enumerable over const elements of the same type. Allows non-const to const conversion.

Parameters
ecoveo::enumerable to convert.
Returns
Reference to this enumerable.

◆ begin()

template<typename T>
iterator coveo::enumerable< T >::begin ( ) const
inline

Returns a coveo::enumerable::iterator pointing at the beginning of the sequence. Together with end(), it can be used to enumerate the elements in the sequence.

The iterator allows the elements to be modified if the enumerable's type T is not const.

Returns
iterator to beginning of sequence.
See also
end()

◆ cbegin()

template<typename T>
iterator coveo::enumerable< T >::cbegin ( ) const
inline

Since this class is immutable, calling this is equivalent to calling begin().

Returns
iterator to beginning of sequence.
See also
begin()
cend()

◆ end()

template<typename T>
iterator coveo::enumerable< T >::end ( ) const
inline

Returns a coveo::enumerable::iterator pointing at the end of the sequence. Together with begin(), it can be used to enumerable the elements in the sequence.

Returns
iterator to end of sequence.
See also
begin()

◆ cend()

template<typename T>
iterator coveo::enumerable< T >::cend ( ) const
inline

Since this class is immutable, calling this is equivalent to calling end().

Returns
iterator to end of sequence.
See also
end()
cbegin()

◆ has_fast_size()

template<typename T>
bool coveo::enumerable< T >::has_fast_size ( ) const
inline

Method that can be used to know if this enumerable has a coveo::enumerable::size_delegate. If so, calling size() should be reasonably fast; otherwise, size() will have to iterate over the entire sequence in order to return a result.

Returns
true if size() should be reasonably fast.
See also
size()

◆ size()

template<typename T>
std::size_t coveo::enumerable< T >::size ( ) const
inline

Returns the number of elements in the sequence. If this enumerable has a coveo::enumerable::size_delegate, it will be used to fetch the information; otherwise, a more lenghty process is used (e.g., using std::distance(), which forces the iteration over the entire sequence).

Returns
Number of elements in the sequence.
See also
has_fast_size()

◆ as_const()

template<typename T>
auto coveo::enumerable< T >::as_const ( ) const -> enumerable<typename std::add_const<T>::type>
inline

Returns a copy of this enumerable, but iterating over const elements. Can be used to explicitely perform a non-const to const conversion.

Returns
enumerable over const elements.

◆ empty()

template<typename T>
static enumerable<T> coveo::enumerable< T >::empty ( )
inlinestatic

Static method that returns a coveo::enumerable over an empty sequence. Equivalent to using the default constructor.

Returns
enumerable over empty sequence.

◆ for_one()

template<typename T>
template<typename U >
static enumerable<T> coveo::enumerable< T >::for_one ( U &&  obj)
inlinestatic

Static method that returns a coveo::enumerable over a sequence of one element. The enumerable will store the element internally, moving it if possible.

In order to auto-discover the enumerable's type, use coveo::enumerate_one().

Parameters
objObject to store as the sequence's only element.
Returns
enumerable over sequence of one element.
See also
coveo::enumerate_one()

◆ for_one_ref()

template<typename T>
static enumerable<T> coveo::enumerable< T >::for_one_ref ( reference  obj)
inlinestatic

Static method that returns a coveo::enumerable over a sequence of one element. The enumerable will only store a reference to the element.

In order to auto-discover the enumerable's type, use coveo::enumerate_one_ref().

Parameters
objObject to use as the sequence's only element.
Returns
enumerable over sequence of one element.
See also
coveo::enumerate_one_ref()

◆ for_range()

template<typename T>
template<typename It >
static enumerable<T> coveo::enumerable< T >::for_range ( It  ibeg,
It  iend 
)
inlinestatic

Static method that returns a coveo::enumerable over a sequence bound by two iterators.

In order to auto-discover the enumerable's type, use coveo::enumerate_range().

Parameters
ibegIterator pointing at beginning of range.
iendIterator pointing at end of range.
Returns
enumerable over sequence bound by [ibeg, iend[.
See also
coveo::enumerate_range()

◆ for_container() [1/2]

template<typename T>
template<typename C >
static enumerable<T> coveo::enumerable< T >::for_container ( C &  cnt)
inlinestatic

Static method that returns a coveo::enumerable over a sequence stored in a container. Only a reference to the container is kept by the enumerable.

In order to auto-discover the enumerable's type, use coveo::enumerate_container().

Parameters
cntContainer whose elements to wrap.
Returns
enumerable over sequence of elements from cnt.
See also
coveo::enumerate_container()

◆ for_container() [2/2]

template<typename T>
template<typename C , typename = typename std::enable_if<!std::is_reference<C>::value, void>::type>
static enumerable<T> coveo::enumerable< T >::for_container ( C &&  cnt)
inlinestatic

Static method that returns a coveo::enumerable over a sequence stored in a container. The container is moved to the enumerable and stored internally.

In order to auto-discover the enumerable's type, use coveo::enumerate_container().

Parameters
cntContainer to store in the enumerable.
Returns
enumerable over sequence of elements from cnt.
See also
coveo::enumerate_container()

◆ for_array()

template<typename T>
static enumerable<T> coveo::enumerable< T >::for_array ( pointer  parr,
size_t  siz 
)
inlinestatic

Static method that returns a coveo::enumerable over a sequence stored in a dynamic array. Equivalent to using for_range() without using pointer arithmetic.

In order to auto-discover the enumerable's type, use coveo::enumerate_array().

Parameters
parrPointer to beginning of array.
sizSize of array.
Returns
enumerable over sequence in array.
See also
coveo::enumerate_array()

The documentation for this class was generated from the following file: