Dash Core Source Documentation (0.16.0.1)

Find detailed information regarding the Dash Core source code.

iterator_facade.hpp
Go to the documentation of this file.
1 //
2 // immer: immutable data structures for C++
3 // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente
4 //
5 // This software is distributed under the Boost Software License, Version 1.0.
6 // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt
7 //
8 
9 #pragma once
10 
11 #include <cstddef>
12 #include <iterator>
13 #include <type_traits>
14 
15 namespace immer {
16 namespace detail {
17 
19 {
20  template <typename T>
21  static decltype(auto) dereference(T&& x)
22  { return x.dereference(); }
23 
24  template <typename T>
25  static decltype(auto) increment(T&& x)
26  { return x.increment(); }
27 
28  template <typename T>
29  static decltype(auto) decrement(T&& x)
30  { return x.decrement(); }
31 
32  template <typename T1, typename T2>
33  static decltype(auto) equal(T1&& x1, T2&& x2)
34  { return x1.equal(x2); }
35 
36  template <typename T, typename D>
37  static decltype(auto) advance(T&& x, D d)
38  { return x.advance(d); }
39 
40  template <typename T1, typename T2>
41  static decltype(auto) distance_to(T1&& x1, T2&& x2)
42  { return x1.distance_to(x2); }
43 };
44 
48 template <typename DerivedT,
49  typename IteratorCategoryT,
50  typename T,
51  typename ReferenceT = T&,
52  typename DifferenceTypeT = std::ptrdiff_t,
53  typename PointerT = T*>
55  : public std::iterator<IteratorCategoryT,
56  T,
57  DifferenceTypeT,
58  PointerT,
59  ReferenceT>
60 {
61 protected:
63 
64  constexpr static auto is_random_access =
65  std::is_base_of<std::random_access_iterator_tag,
66  IteratorCategoryT>::value;
67  constexpr static auto is_bidirectional =
68  std::is_base_of<std::bidirectional_iterator_tag,
69  IteratorCategoryT>::value;
70 
72  {
74  DerivedT iter_;
75 
76  reference_proxy(DerivedT iter)
77  : iter_{std::move(iter)} {}
78  public:
79  operator ReferenceT() const { return *iter_; }
80  };
81 
82  const DerivedT& derived() const
83  {
84  static_assert(std::is_base_of<iterator_facade, DerivedT>::value,
85  "must pass a derived thing");
86  return *static_cast<const DerivedT*>(this);
87  }
88  DerivedT& derived()
89  {
90  static_assert(std::is_base_of<iterator_facade, DerivedT>::value,
91  "must pass a derived thing");
92  return *static_cast<DerivedT*>(this);
93  }
94 
95 public:
96  ReferenceT operator*() const
97  {
99  }
100  PointerT operator->() const
101  {
102  return &access_t::dereference(derived());
103  }
104  reference_proxy operator[](DifferenceTypeT n) const
105  {
106  static_assert(is_random_access, "");
107  return derived() + n;
108  }
109 
110  bool operator==(const DerivedT& rhs) const
111  {
112  return access_t::equal(derived(), rhs);
113  }
114  bool operator!=(const DerivedT& rhs) const
115  {
116  return !access_t::equal(derived(), rhs);
117  }
118 
119  DerivedT& operator++()
120  {
122  return derived();
123  }
124  DerivedT operator++(int)
125  {
126  auto tmp = derived();
128  return tmp;
129  }
130 
131  DerivedT& operator--()
132  {
133  static_assert(is_bidirectional || is_random_access, "");
135  return derived();
136  }
137  DerivedT operator--(int)
138  {
139  static_assert(is_bidirectional || is_random_access, "");
140  auto tmp = derived();
142  return tmp;
143  }
144 
145  DerivedT& operator+=(DifferenceTypeT n)
146  {
148  return derived();
149  }
150  DerivedT& operator-=(DifferenceTypeT n)
151  {
152  access_t::advance(derived(), -n);
153  return derived();
154  }
155 
156  DerivedT operator+(DifferenceTypeT n) const
157  {
158  static_assert(is_random_access, "");
159  auto tmp = derived();
160  return tmp += n;
161  }
162  friend DerivedT operator+(DifferenceTypeT n, const DerivedT& i)
163  {
164  static_assert(is_random_access, "");
165  return i + n;
166  }
167  DerivedT operator-(DifferenceTypeT n) const
168  {
169  static_assert(is_random_access, "");
170  auto tmp = derived();
171  return tmp -= n;
172  }
173  DifferenceTypeT operator-(const DerivedT& rhs) const
174  {
175  static_assert(is_random_access, "");
176  return access_t::distance_to(rhs, derived());
177  }
178 
179  bool operator<(const DerivedT& rhs) const
180  {
181  static_assert(is_random_access, "");
182  return access_t::distance_to(derived(), rhs) > 0;
183  }
184  bool operator<=(const DerivedT& rhs) const
185  {
186  static_assert(is_random_access, "");
187  return access_t::distance_to(derived(), rhs) >= 0;
188  }
189  bool operator>(const DerivedT& rhs) const
190  {
191  static_assert(is_random_access, "");
192  return access_t::distance_to(derived(), rhs) < 0;
193  }
194  bool operator>=(const DerivedT& rhs) const
195  {
196  static_assert(is_random_access, "");
197  return access_t::distance_to(derived(), rhs) <= 0;
198  }
199 };
200 
201 } // namespace detail
202 } // namespace immer
static constexpr auto is_random_access
static decltype(auto) dereference(T &&x)
bool operator>(const DerivedT &rhs) const
static decltype(auto) distance_to(T1 &&x1, T2 &&x2)
static decltype(auto) equal(T1 &&x1, T2 &&x2)
DerivedT operator+(DifferenceTypeT n) const
reference_proxy operator[](DifferenceTypeT n) const
bool operator<(const DerivedT &rhs) const
static decltype(auto) decrement(T &&x)
bool operator<=(const DerivedT &rhs) const
DerivedT & operator+=(DifferenceTypeT n)
bool operator==(const DerivedT &rhs) const
DifferenceTypeT operator-(const DerivedT &rhs) const
static decltype(auto) increment(T &&x)
bool operator>=(const DerivedT &rhs) const
static constexpr auto is_bidirectional
friend DerivedT operator+(DifferenceTypeT n, const DerivedT &i)
bool operator!=(const DerivedT &rhs) const
const DerivedT & derived() const
static decltype(auto) advance(T &&x, D d)
DerivedT operator-(DifferenceTypeT n) const
DerivedT & operator-=(DifferenceTypeT n)
Released under the MIT license