#pragma once #include "local-coords.hpp" #include #include #include namespace Magnum::Examples { template class basic_tile_iterator; struct tile; } // namespace Magnum::Examples namespace std { template void swap(Magnum::Examples::basic_tile_iterator& lhs, Magnum::Examples::basic_tile_iterator& rhs) noexcept; template struct tuple_size> : std::integral_constant {}; template struct tuple_element<0, Magnum::Examples::basic_tile_iterator> { using type = T&; }; template struct tuple_element<1, Magnum::Examples::basic_tile_iterator> { using type = std::size_t; }; template struct tuple_element<2, Magnum::Examples::basic_tile_iterator> { using type = Magnum::Examples::local_coords; }; } // namespace std namespace Magnum::Examples { template class basic_tile_iterator final { T* ptr; std::size_t pos = 0; public: using value_type = std::tuple; explicit basic_tile_iterator(T* ptr, std::size_t pos) noexcept : ptr(ptr), pos(pos) {} ~basic_tile_iterator() noexcept = default; basic_tile_iterator& operator=(const basic_tile_iterator&) = default; basic_tile_iterator& operator++() { pos++; return *this; } basic_tile_iterator operator++(int) { auto tmp = *this; operator++(); return tmp; } basic_tile_iterator* operator->() { return this; } basic_tile_iterator& operator*() { return *this; } auto operator<=>(const basic_tile_iterator&) const noexcept = default; void swap(basic_tile_iterator& other); template typename std::tuple_element>::type get(); }; extern template class basic_tile_iterator; extern template class basic_tile_iterator; extern template typename std::tuple_element<0, basic_tile_iterator>::type basic_tile_iterator::get<0>(); extern template typename std::tuple_element<1, basic_tile_iterator>::type basic_tile_iterator::get<1>(); extern template typename std::tuple_element<2, basic_tile_iterator>::type basic_tile_iterator::get<2>(); extern template typename std::tuple_element<0, basic_tile_iterator>::type basic_tile_iterator::get<0>(); extern template typename std::tuple_element<1, basic_tile_iterator>::type basic_tile_iterator::get<1>(); extern template typename std::tuple_element<2, basic_tile_iterator>::type basic_tile_iterator::get<2>(); } // namespace Magnum::Examples namespace std { template class iterator_traits> { using T = Magnum::Examples::basic_tile_iterator; public: using difference_type = std::ptrdiff_t; using value_type = T; using reference = T&; using pointer = T*; using iterator_category = std::input_iterator_tag; //usually std::forward_iterator_tag or similar }; } // namespace std