summaryrefslogtreecommitdiffhomepage
path: root/src/tile-iterator.hpp
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2022-10-07 21:28:23 +0200
committerStanislaw Halik <sthalik@misaki.pl>2022-10-07 21:28:23 +0200
commit6e19e9446b436d9608b5a4931f25d328a5e56f93 (patch)
tree3a26822fb58c1d73583bd8eb790e1bcfdd90e78b /src/tile-iterator.hpp
parentc622ba25379bdab352a73276544a4d68a02e1fb7 (diff)
a
Diffstat (limited to 'src/tile-iterator.hpp')
-rw-r--r--src/tile-iterator.hpp76
1 files changed, 32 insertions, 44 deletions
diff --git a/src/tile-iterator.hpp b/src/tile-iterator.hpp
index a0ffa11c..99a40412 100644
--- a/src/tile-iterator.hpp
+++ b/src/tile-iterator.hpp
@@ -1,17 +1,13 @@
#pragma once
#include "local-coords.hpp"
-#include "tile.hpp"
#include <iterator>
-#include <tuple>
#include <utility>
#include <type_traits>
namespace Magnum::Examples {
-template<typename T>
-class basic_tile_iterator;
-
+template<typename T> class basic_tile_iterator;
struct tile;
} // namespace Magnum::Examples
@@ -19,62 +15,54 @@ struct tile;
namespace std {
template<typename T>
-constexpr void swap(Magnum::Examples::basic_tile_iterator<T>& lhs,
- Magnum::Examples::basic_tile_iterator<T>& rhs) noexcept;
+void swap(Magnum::Examples::basic_tile_iterator<T>& lhs,
+ Magnum::Examples::basic_tile_iterator<T>& rhs) noexcept;
+
+template<typename T> struct tuple_size<Magnum::Examples::basic_tile_iterator<T>> : std::integral_constant<std::size_t, 3> {};
+template<typename T> struct tuple_element<0, Magnum::Examples::basic_tile_iterator<T>> { using type = T&; };
+template<typename T> struct tuple_element<1, Magnum::Examples::basic_tile_iterator<T>> { using type = std::size_t; };
+template<typename T> struct tuple_element<2, Magnum::Examples::basic_tile_iterator<T>> { using type = Magnum::Examples::local_coords; };
} // namespace std
namespace Magnum::Examples {
-namespace detail {
-
-template<typename T>
-class tile_tuple_wrapper final {
- using value_type = std::tuple<T&, std::size_t, local_coords>;
- value_type value;
-
-public:
- constexpr tile_tuple_wrapper(value_type x) : value(x) {}
- constexpr value_type& operator*() noexcept { return value; }
- constexpr value_type* operator->() noexcept { return &value; }
-};
-
-} // namespace detail
-
template<typename T>
class basic_tile_iterator final {
T* ptr;
std::size_t pos = 0;
- friend constexpr void swap(basic_tile_iterator<T>& lhs, basic_tile_iterator<T>& rhs) noexcept;
-
public:
using value_type = std::tuple<T&, std::size_t, local_coords>;
- explicit constexpr basic_tile_iterator(T* ptr, std::size_t pos) noexcept : ptr(ptr), pos(pos) {}
- constexpr ~basic_tile_iterator() noexcept = default;
-
- constexpr basic_tile_iterator<T>& operator=(const basic_tile_iterator<T>&) noexcept = default;
- constexpr basic_tile_iterator<T>& operator++() noexcept { pos++; return *this; }
- constexpr basic_tile_iterator<T> operator++(int) noexcept { auto tmp = *this; operator++(); return tmp; }
- constexpr value_type operator*() const noexcept { // NOLINT(bugprone-exception-escape)
- ASSERT(pos < TILE_COUNT);
- return {ptr[pos], pos, local_coords{pos}};
+ explicit basic_tile_iterator(T* ptr, std::size_t pos) noexcept : ptr(ptr), pos(pos) {}
+ ~basic_tile_iterator() noexcept = default;
+
+ basic_tile_iterator<T>& operator=(const basic_tile_iterator<T>&) = default;
+ basic_tile_iterator<T>& operator++() { pos++; return *this; }
+ basic_tile_iterator<T> operator++(int) { auto tmp = *this; operator++(); return tmp; }
+ basic_tile_iterator<T>* operator->() { return this; }
+ basic_tile_iterator<T>& operator*() { return *this; }
+ auto operator<=>(const basic_tile_iterator<T>&) const noexcept = default;
+ void swap(basic_tile_iterator<T>& other) {
+ using std::swap;
+ swap(ptr, other.ptr);
+ swap(pos, other.pos);
}
- constexpr detail::tile_tuple_wrapper<T> operator->() const noexcept { // NOLINT(bugprone-exception-escape)
- return {operator*()};
+ template<std::size_t N>
+ typename std::tuple_element<N, basic_tile_iterator<T>>::type get()
+ {
+ if constexpr(N == 0)
+ return pos == TILE_COUNT ? ptr[0] : ptr[pos];
+ else if constexpr(N == 1)
+ return pos;
+ else if constexpr(N == 2)
+ return local_coords{pos};
+ else
+ return std::void_t<std::integral_constant<int, N>>();
}
- constexpr auto operator<=>(const basic_tile_iterator<T>&) const noexcept = default;
};
-template<typename T>
-constexpr void swap(basic_tile_iterator<T>& lhs, basic_tile_iterator<T>& rhs) noexcept
-{
- using std::swap;
- swap(lhs.ptr, rhs.ptr);
- swap(lhs.pos, rhs.ptr);
-}
-
extern template class basic_tile_iterator<tile>;
extern template class basic_tile_iterator<const tile>;