#include <Corrade/Containers/Iterable.h>
template<class T>
Iterable class new in Git master
Wrapper for any sequential container of values or references.
Useful in scenarios where, given a heavy or a move-only T
, it's desirable to have an API accept ArrayView<const Reference<T>> to account for cases where instances are scattered around and can't be put into a linear container, but also accept just plain ArrayView<T> and other variants for convenience.
This class adds extra indirection to allow iterating over various input containers with a single code path. Assuming the API itself isn't bottlenecked on iteration performance, it should be an acceptable tradeoff compared to having to implement multiple code paths or have extra overloads that unify the process by copying the data to a temporary container first. In contrast, if the type doesn't need to be taken via a reference, it's preferable to accept just ArrayView<T> or StridedArrayView*D<T> instead of using this class.
Usage
An Iterable<T> can be implicitly created from an ArrayView<T>, StridedArrayView1D<T>; (strided) array view of (const
) Reference<T>, MoveReference<T> or AnyReference<T>; std::
Example usage — passing a list of non-copyable Utility::
void foo(const Containers::Iterable<Utility::FileWatcher>&); Utility::FileWatcher a{…}, b{…}; Utility::FileWatcher cArray[3]{…}; Containers::Array<Containers::Reference<Utility::FileWatcher>> array{…}; std::vector<Utility::FileWatcher> vector{…}; foo({a, b}); /* passing (references to) variables directly */ foo(cArray); /* passing a C array */ foo(array); /* passing an array of references */ foo(vector); /* passing a STL vector */
On the API implementation side, the usual container interface is exposed — in particular isEmpty(), size(), operator[](), front(), back() as well as range-for access:
void foo(const Containers::Iterable<Utility::FileWatcher>& watchers) { for(Utility::FileWatcher& watcher: watchers) { … } }
Public types
- using Type = T
- Element type.
Constructors, destructors, conversion operators
-
Iterable(std::
nullptr_t = nullptr) constexpr noexcept - Default constructor.
-
template<class U, class = decltype(Iterable{std::Iterable(U&& data) noexcept
declval<U && >(), Implementation::IterableOverloadPriority<1>{}})> - Construct from any sequential iterable container.
-
Iterable(std::
initializer_list<AnyReference<T>> view) noexcept - Construct from an initializer list.
-
template<class U = typename std::Iterable(std::
remove_const<T>::type, class = typename std:: enable_if<!std:: is_same<T, U>::value>::type> initializer_list<AnyReference<typename std:: remove_const<T>::type>> view) noexcept -
Iterable(const void* data,
std::
size_t size, std:: ptrdiff_t stride, T&(*)(const void*) accessor) explicit noexcept - Construct a custom iterable.
- operator bool() const explicit
- Whether the iterable is non-empty.
Public functions
- auto data() const -> const void*
- Data pointer.
-
auto size() const -> std::
size_t - Number of items in the container.
-
auto stride() const -> std::
ptrdiff_t - Stride between items in the container.
- auto isEmpty() const -> bool
- Whether the container is empty.
-
auto operator[](std::
size_t i) const -> T& - Element access.
- auto begin() const -> IterableIterator<T>
- Iterator to first element.
- auto cbegin() const -> IterableIterator<T>
- auto end() const -> IterableIterator<T>
- Iterator to (one item after) last element.
- auto cend() const -> IterableIterator<T>
- auto front() const -> T&
- First element.
- auto back() const -> T&
- Last element.
Function documentation
template<class T>
Corrade:: Containers:: Iterable<T>:: Iterable(std:: nullptr_t = nullptr) constexpr noexcept
Default constructor.
Creates an instance with nullptr
data and size and stride set to 0
.
template<class T>
template<class U, class = decltype(Iterable{std:: declval<U && >(), Implementation::IterableOverloadPriority<1>{}})>
Corrade:: Containers:: Iterable<T>:: Iterable(U&& data) noexcept
Construct from any sequential iterable container.
U
can be an ArrayView<T>, StridedArrayView1D<T>; (strided) array view of (const
) Reference<T>, MoveReference<T> or AnyReference<T>; and any other type convertible to these — see ArrayView and StridedArrayView docs for more information.
template<class T>
Corrade:: Containers:: Iterable<T>:: Iterable(std:: initializer_list<AnyReference<T>> view) noexcept
Construct from an initializer list.
In order to be able to accept also lists of non-copyable types, the constructor takes a reference type. Then, to accept both {a, b, c}
and {T{…}, T{…}, T{…}}
, it's an AnyReference instead of a Reference.
template<class T>
template<class U = typename std:: remove_const<T>::type, class = typename std:: enable_if<!std:: is_same<T, U>::value>::type>
Corrade:: Containers:: Iterable<T>:: Iterable(std:: initializer_list<AnyReference<typename std:: remove_const<T>::type>> view) noexcept
This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.
template<class T>
Corrade:: Containers:: Iterable<T>:: Iterable(const void* data,
std:: size_t size,
std:: ptrdiff_t stride,
T&(*)(const void*) accessor) explicit noexcept
Construct a custom iterable.
Parameters | |
---|---|
data | Container data pointer |
size | Number of items in the container |
stride | Stride between items in the container |
accessor | Accessor function |
For item i
, the accessor
gets data + i*stride
in the argument.
template<class T>
const void* Corrade:: Containers:: Iterable<T>:: data() const
Data pointer.
Not meant to be used directly, as the returned value may point to an actual value but also to a reference to the value, with no possibility to distinguish between the two. The returned pointer is const
even when T
is mutable as the data may point to const Reference<T> and similar.
template<class T>
std:: size_t Corrade:: Containers:: Iterable<T>:: size() const
Number of items in the container.
template<class T>
std:: ptrdiff_t Corrade:: Containers:: Iterable<T>:: stride() const
Stride between items in the container.
For a contiguous array of T
it's equal to sizeof(T)
, for references it's sizeof(void*)
, for a strided view it's equivalent to StridedArrayView::
template<class T>
bool Corrade:: Containers:: Iterable<T>:: isEmpty() const
Whether the container is empty.
template<class T>
T& Corrade:: Containers:: Iterable<T>:: operator[](std:: size_t i) const
Element access.
Expects that i
is less than size().
template<class T>
IterableIterator<T> Corrade:: Containers:: Iterable<T>:: begin() const
Iterator to first element.
template<class T>
IterableIterator<T> Corrade:: Containers:: Iterable<T>:: cbegin() const
This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.
template<class T>
IterableIterator<T> Corrade:: Containers:: Iterable<T>:: end() const
Iterator to (one item after) last element.
template<class T>
IterableIterator<T> Corrade:: Containers:: Iterable<T>:: cend() const
This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.
template<class T>
T& Corrade:: Containers:: Iterable<T>:: front() const
First element.
Expects there is at least one element.
template<class T>
T& Corrade:: Containers:: Iterable<T>:: back() const
Last element.
Expects there is at least one element.