-
Notifications
You must be signed in to change notification settings - Fork 1
/
mapiterator.hpp
126 lines (97 loc) · 2.44 KB
/
mapiterator.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#ifndef XSG_MAPITERATOR_HPP
# define XSG_MAPITERATOR_HPP
# pragma once
#include <iterator>
#include <type_traits>
#include <utility>
namespace xsg
{
template <typename T>
class mapiterator
{
using iterator_t = mapiterator<std::remove_const_t<T>>;
friend mapiterator<T const>;
T* n_, *p_;
T* const* r_;
public:
using iterator_category = std::bidirectional_iterator_tag;
using difference_type = detail::difference_type;
using value_type = std::conditional_t<
std::is_const_v<T>,
typename T::value_type const,
typename T::value_type
>;
using pointer = value_type*;
using reference = value_type&;
template <typename, typename, class> friend class map;
template <typename, class> friend class set;
public:
mapiterator() = default;
mapiterator(T* const* const r) noexcept:
n_(),
r_(r)
{
}
mapiterator(T* const* const r, auto&& t) noexcept:
n_(std::get<0>(t)),
p_(std::get<1>(t)),
r_(r)
{
}
mapiterator(T* const* const r, T* const n, T* const p) noexcept:
n_(n),
p_(p),
r_(r)
{
}
mapiterator(mapiterator const&) = default;
mapiterator(mapiterator&&) = default;
mapiterator(iterator_t const& o) noexcept requires(std::is_const_v<T>):
n_(o.n_),
p_(o.p_),
r_(o.r_)
{
}
//
mapiterator& operator=(mapiterator const&) = default;
mapiterator& operator=(mapiterator&&) = default;
mapiterator& operator=(iterator_t const& o) noexcept
requires(std::is_const_v<T>)
{
n_ = o.n_; p_ = o.p_; r_ = o.r_; return *this;
}
bool operator==(mapiterator const& o) const noexcept { return n_ == o.n_; }
// increment, decrement
auto& operator++() noexcept
{
std::tie(n_, p_) = detail::next_node(n_, p_); return *this;
}
auto& operator--() noexcept
{
std::tie(n_, p_) = n_ ?
detail::prev_node(n_, p_) :
detail::last_node(*r_, {});
return *this;
}
mapiterator operator++(int) noexcept
{
auto const n(n_), p(p_);
std::tie(n_, p_) = detail::next_node(n_, p_);
return {r_, n, p};
}
mapiterator operator--(int) noexcept
{
auto const n(n_), p(p_);
std::tie(n_, p_) = n_ ?
detail::prev_node(n_, p_) :
detail::last_node(*r_, {});
return {r_, n, p};
}
// member access
auto operator->() const noexcept { return &n_->kv_; }
auto& operator*() const noexcept { return n_->kv_; }
//
explicit operator bool() const noexcept { return n_; }
};
}
#endif // XSG_MAPITERATOR_HPP