core: added iterable_adaptor

This commit is contained in:
Michele Caini
2021-12-16 12:29:20 +01:00
parent cc9b1b0a05
commit db9e59ede1
2 changed files with 75 additions and 0 deletions

View File

@@ -1,6 +1,7 @@
#ifndef ENTT_CORE_ITERATOR_HPP
#define ENTT_CORE_ITERATOR_HPP
#include <iterator>
#include <memory>
#include <utility>
#include "../config/config.h"
@@ -53,6 +54,63 @@ private:
Type value;
};
/**
* @brief Utility class to create an iterable object from a pair of iterators.
* @tparam It Type of iterators.
*/
template<typename It>
struct iterable_adaptor final {
/*! @brief Type of the objects returned during iteration. */
using value_type = typename std::iterator_traits<It>::value_type;
/*! @brief Iterator type. */
using iterator = It;
/*! @brief Const iterator type. */
using const_iterator = It;
/*! @brief Default constructor. */
iterable_adaptor() = default;
/**
* @brief Creates an iterable object from a pair of iterators.
* @param from Begin iterator.
* @param to End iterator.
*/
iterable_adaptor(It from, It to)
: first{from},
last{to} {}
/**
* @brief Returns an iterator to the beginning.
* @return An iterator to the first element of the range.
*/
[[nodiscard]] const_iterator begin() const ENTT_NOEXCEPT {
return first;
}
/*! @copydoc begin */
[[nodiscard]] const_iterator cbegin() const ENTT_NOEXCEPT {
return begin();
}
/**
* @brief Returns an iterator to the end.
* @return An iterator to the element following the last element of the
* range.
*/
[[nodiscard]] const_iterator end() const ENTT_NOEXCEPT {
return last;
}
/*! @copydoc end */
[[nodiscard]] const_iterator cend() const ENTT_NOEXCEPT {
return end();
}
private:
It first;
It last;
};
} // namespace entt
#endif

View File

@@ -1,4 +1,5 @@
#include <utility>
#include <vector>
#include <gtest/gtest.h>
#include <entt/core/iterator.hpp>
@@ -20,3 +21,19 @@ TEST(Iterator, InputIteratorPointer) {
ASSERT_EQ(instance.value, 0);
ASSERT_EQ(ptr->value, 42);
}
TEST(Iterator, IterableAdaptor) {
std::vector<int> vec{1, 2};
entt::iterable_adaptor iterable{vec.begin(), vec.end()};
decltype(iterable) other{};
ASSERT_NO_THROW(other = iterable);
ASSERT_NO_THROW(std::swap(other, iterable));
ASSERT_EQ(iterable.begin(), vec.begin());
ASSERT_EQ(iterable.end(), vec.end());
ASSERT_EQ(*iterable.cbegin(), 1);
ASSERT_EQ(*++iterable.cbegin(), 2);
ASSERT_EQ(++iterable.cbegin(), --iterable.end());
}