core: iota_iterator (waiting for C++20)

This commit is contained in:
Michele Caini
2022-06-03 19:25:47 +02:00
parent c36d5e4a9c
commit a31c492c83
3 changed files with 100 additions and 0 deletions
+1
View File
@@ -9,6 +9,7 @@ DOC:
* storage<void>
* custom storage/view
* examples (and credits) from @alanjfs :)
* document iterator.hpp (see core.md)
WIP:
* handle: replace visit with an iterable object
+84
View File
@@ -38,6 +38,90 @@ private:
Type value;
};
/**
* @brief Plain iota iterator (waiting for C++20).
* @tparam Type Value type.
*/
template<typename Type>
class iota_iterator final {
static_assert(std::is_integral_v<Type>, "Not an integral type");
public:
/*! @brief Value type, likely an integral one. */
using value_type = Type;
/*! @brief Invalid pointer type. */
using pointer = void;
/*! @brief Non-reference type, same as value type. */
using reference = value_type;
/*! @brief Difference type. */
using difference_type = std::ptrdiff_t;
/*! @brief Iterator category. */
using iterator_category = std::input_iterator_tag;
/*! @brief Default constructor. */
constexpr iota_iterator() noexcept
: current{} {}
/**
* @brief Constructs an iota iterator from a given value.
* @param init The initial value assigned to the iota iterator.
*/
constexpr iota_iterator(const value_type init) noexcept
: current{init} {}
/**
* @brief Pre-increment operator.
* @return This iota iterator.
*/
constexpr iota_iterator &operator++() noexcept {
return ++current, *this;
}
/**
* @brief Post-increment operator.
* @return This iota iterator.
*/
constexpr iota_iterator operator++(int) noexcept {
iota_iterator orig = *this;
return ++(*this), orig;
}
/**
* @brief Dereference operator.
* @return The underlying value.
*/
[[nodiscard]] constexpr reference operator*() const noexcept {
return current;
}
private:
value_type current;
};
/**
* @brief Comparison operator.
* @tparam Type Value type of the iota iterator.
* @param lhs A properly initialized iota iterator.
* @param rhs A properly initialized iota iterator.
* @return True if the two iterators are identical, false otherwise.
*/
template<typename Type>
[[nodiscard]] constexpr bool operator==(const iota_iterator<Type> &lhs, const iota_iterator<Type> &rhs) noexcept {
return *lhs == *rhs;
}
/**
* @brief Comparison operator.
* @tparam Type Value type of the iota iterator.
* @param lhs A properly initialized iota iterator.
* @param rhs A properly initialized iota iterator.
* @return True if the two iterators differ, false otherwise.
*/
template<typename Type>
[[nodiscard]] constexpr bool operator!=(const iota_iterator<Type> &lhs, const iota_iterator<Type> &rhs) noexcept {
return !(lhs == rhs);
}
/**
* @brief Utility class to create an iterable object from a pair of iterators.
* @tparam It Type of iterator.
+15
View File
@@ -1,3 +1,4 @@
#include <cstddef>
#include <type_traits>
#include <utility>
#include <vector>
@@ -17,6 +18,20 @@ TEST(InputIteratorPointer, Functionalities) {
ASSERT_EQ(ptr->value, 42);
}
TEST(IotaIterator, Functionalities) {
entt::iota_iterator<std::size_t> first{};
const entt::iota_iterator<std::size_t> last{2u};
ASSERT_NE(first, last);
ASSERT_FALSE(first == last);
ASSERT_TRUE(first != last);
ASSERT_EQ(*first++, 0u);
ASSERT_EQ(*first, 1u);
ASSERT_EQ(*++first, *last);
ASSERT_EQ(*first, 2u);
}
TEST(IterableAdaptor, Functionalities) {
std::vector<int> vec{1, 2};
entt::iterable_adaptor iterable{vec.begin(), vec.end()};