libostd
Public Types | Public Member Functions | List of all members
ostd::input_range< B > Struct Template Reference

A base type for all input-type ranges to derive from. More...

Public Types

using full_iterator = detail::full_range_iterator< B >
 A complete input iterator type for the range. More...
 

Public Member Functions

auto begin () const
 Creates a very simple iterator for range-based for loop. More...
 
std::nullptr_t end () const
 Gets a sentinel for begin().
 
full_iterator iter_begin () const
 Constructs a full_iterator for the range.
 
full_iterator iter_end () const
 Constructs a full_iterator end.
 
iter () const
 Creates a copy of the range. More...
 
auto reverse () const
 Gets a reverse range to the current range. More...
 
auto movable () const
 Gets a wrapper range that moves all the elements. More...
 
auto enumerate () const
 Gets an enumerated range for the range. More...
 
auto take (std::size_t n) const
 Gets a range representing several elements of the range. More...
 
auto chunks (std::size_t n) const
 Splits the range into range of chunks. More...
 
template<typename R1 , typename ... RR>
auto join (R1 r1, RR ...rr) const
 Joins multiple ranges together. More...
 
template<typename R1 , typename ... RR>
auto zip (R1 r1, RR ...rr) const
 Zips multiple ranges together. More...
 
auto operator* () const
 Simpler syntax for accessing the front element.
 
B & operator++ ()
 Simpler syntax for popping out the front element.
 
operator++ (int)
 Simpler syntax for popping out the front element. More...
 
template<typename F >
auto operator| (F &&func)
 A necessary overload for pipeable algorithm support.
 
template<typename F >
auto operator| (F &&func) const
 A necessary overload for pipeable algorithm support.
 
 operator bool () const
 Checks if the range is not empty.
 

Detailed Description

template<typename B>
struct ostd::input_range< B >

A base type for all input-type ranges to derive from.

Every input range type derives from this, see Ranges. It implements functionality every range type is supposed to have.

Pure output ranges will need to derive from ostd::output_range.

The pipe operator overloads call the given function with this range. This allows pipeable algorithms which essentially return a lambda taking the range which then performs the needed algorithm.

Member Typedef Documentation

◆ full_iterator

template<typename B>
using ostd::input_range< B >::full_iterator = detail::full_range_iterator<B>

A complete input iterator type for the range.

This is a complete iterator type that you can create with iter_begin(). This iterator can only be used to represent the full range sequence - i.e. from the beginning to the end of the range, with the end always being iter_end().

Using an incremented version of iter_begin() as an ending is undefined as the ending iterator is not used by itself, this is why it's an input iterator type (if the function this is used with tried to use a temporary copy of the iterator as an end, it'd result in incorrect behavior). Thus, this is mostly meant to insert ranges into data structures that take input iterators in their insertion methods.

Member Function Documentation

◆ begin()

template<typename B>
auto ostd::input_range< B >::begin ( ) const
inline

Creates a very simple iterator for range-based for loop.

Thanks to this, you can use the range-based for loop with ranges effortlessly. It's not a proper full iterator type, it only has the necessary functionality for iteration and has no end iterator, see end().

◆ chunks()

template<typename B>
auto ostd::input_range< B >::chunks ( std::size_t  n) const
inline

Splits the range into range of chunks.

The resulting range is at most ostd::forward_range_tag. Each element of it is the result of take() on the current stored range. Each call to pop_front() pops out at most n elements from the wrapped range.

If the wrapped range's length is not a multiple of n, the last chunk will have fewer elements than n.

◆ enumerate()

template<typename B>
auto ostd::input_range< B >::enumerate ( ) const
inline

Gets an enumerated range for the range.

An enumerated range wraps the original range in a way where the accesses remain mostly the same, but an index counter is kept and incremented on each pop.

It's always at most ostd::forward_range_tag. The value and size types stay the same, the new reference type is like this:

struct enumerated_value_t {
range_size_t<R> index;
range_reference_t<R> value;
};

This is useful when you need to iterate over a range using the range based for loop but still need a numerical index. An example:

auto il = { 5, 10, 15};
// prints "0: 5", "1: 10", "2: 15"
for (auto v: ostd::iter(il).enumerate()) {
ostd::writefln("%s: %s", v.index, v.value);
}

◆ iter()

template<typename B>
B ostd::input_range< B >::iter ( ) const
inline

Creates a copy of the range.

This is just like copy-constructing the range.

◆ join()

template<typename B>
template<typename R1 , typename ... RR>
auto ostd::input_range< B >::join ( R1  r1,
RR ...  rr 
) const
inline

Joins multiple ranges together.

The ranges don't have to be the same. The types of ostd::range_traits will be std::common_type_t of all ranges' trait types. The range itself is at most ostd::forward_range_tag, but can be ostd::input_range_tag if any of the joined ranges are.

The range is empty when all joined ranges are empty. Access to front is undefined if all joined ranges are empty.

◆ movable()

template<typename B>
auto ostd::input_range< B >::movable ( ) const
inline

Gets a wrapper range that moves all the elements.

The range is an ostd::input_range_tag. The base range is required to have real references for its reference type and those references must be references to the range's value type, i.e.

std::is_reference_v<ostd::range_reference_t<R>> == true
std::is_same_v<
std::remove_reference_t<ostd::range_reference_t<T>
> == true

The value and size types remain the same. The new reference type becomes ostd::range_value_t<R> &&.

Accesses to the front member result in the element being moved.

◆ operator++()

template<typename B>
B ostd::input_range< B >::operator++ ( int  )
inline

Simpler syntax for popping out the front element.

Returns the range before the pop happened.

◆ reverse()

template<typename B>
auto ostd::input_range< B >::reverse ( ) const
inline

Gets a reverse range to the current range.

A reverse range is a wrapper range that lazily reveses the direction. Only defined for ranges that are at least bidirectional. It re-routes the access so that front accesses back and vice versa.

If this range is at least ostd::finite_ranodm_access_range_tag, the wrapped range will be always ostd::finite_random_access_range_tag. Otherwise, it will be ostd::bidirectional_range_tag.

The value, reference and size types are the same.

◆ take()

template<typename B>
auto ostd::input_range< B >::take ( std::size_t  n) const
inline

Gets a range representing several elements of the range.

Wraps the range in a way where at most n elements are considered when manipulating the range. The result is at always at most ostd::forward_range_tag.

It is undefined behavior to try to pop_front() past the internal counter (i.e. empty() must not be true when calling it).

◆ zip()

template<typename B>
template<typename R1 , typename ... RR>
auto ostd::input_range< B >::zip ( R1  r1,
RR ...  rr 
) const
inline

Zips multiple ranges together.

The ranges will all be iterated at the same time up until the shortest range's length. The wrapper range is at most ostd::forward_range_tag.

The value type can be a pair (for two ranges) or a tuple (for more) of the value types. The reference type is also a pair or a tuple, but of the reference types. The size type is the common type between the zipped ranges.


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