|
|
@@ -15,15 +15,16 @@
|
|
|
#include <iterator/detail/macro.h>
|
|
|
|
|
|
namespace iterator {
|
|
|
-// TODO: I should be respecting the underlying type
|
|
|
template <typename It>
|
|
|
class indexed_iterator
|
|
|
- : public facade<indexed_iterator<It>, category::random_access> {
|
|
|
+ : public facade<indexed_iterator<It>, detail::category_for_v<It>> {
|
|
|
public:
|
|
|
- using reference =
|
|
|
- std::pair<size_t, typename std::iterator_traits<It>::reference>;
|
|
|
+ using reference = std::pair<size_t, DEREF_TYPE(It)>;
|
|
|
using difference_type = typename std::iterator_traits<It>::difference_type;
|
|
|
|
|
|
+private:
|
|
|
+ using super_t = facade<indexed_iterator<It>, detail::category_for_v<It>>;
|
|
|
+
|
|
|
public:
|
|
|
indexed_iterator() = default;
|
|
|
indexed_iterator(It base) : base_(base) {}
|
|
|
@@ -35,19 +36,32 @@ public:
|
|
|
|
|
|
reference dereference() const { return {index_, *base_}; }
|
|
|
|
|
|
+ SFINAE(super_t::category_enum >= category::forward) void decrement() {
|
|
|
+ ++base_;
|
|
|
+ ++index_;
|
|
|
+ }
|
|
|
+
|
|
|
+ SFINAE(super_t::category_enum >= category::bidirectional) void increment() {
|
|
|
+ --base_;
|
|
|
+ --index_;
|
|
|
+ }
|
|
|
+
|
|
|
+ SFINAE(super_t::category_enum >= category::random_access)
|
|
|
void advance(difference_type off) {
|
|
|
base_ += off;
|
|
|
index_ += off;
|
|
|
}
|
|
|
|
|
|
- // SFINAE means that if Iterator is not random access, then this still works
|
|
|
- // TODO: Investigate using _index for comparisons instead of _base
|
|
|
+ SFINAE(super_t::category_enum < category::random_access)
|
|
|
bool equal_to(indexed_iterator const & other) const {
|
|
|
return base_ == other.base_;
|
|
|
}
|
|
|
+
|
|
|
+ SFINAE(super_t::category_enum >= category::random_access)
|
|
|
difference_type distance_to(indexed_iterator const & other) const {
|
|
|
return other.base_ - base_;
|
|
|
}
|
|
|
+
|
|
|
SFINAE(detail::has_sentinel_type_v<It>) bool at_end() const {
|
|
|
return base_ == typename It::sentinel_type();
|
|
|
}
|