Loading...
Searching...
No Matches
iterator_util.h
Go to the documentation of this file.
1#ifndef _BBM_ITERATOR_UTIL_H_
2#define _BBM_ITERATOR_UTIL_H_
3
4#include <memory>
5#include <utility>
6#include <iterator>
7#include <ranges>
8
9#include "concepts/util.h"
10
11/***********************************************************************/
12/*! \file iterator_util.h
13 \brief Extensions for STL iterators/ranges.
14************************************************************************/
15
16namespace bbm {
17
18 /*********************************************************************/
19 /*! @{ \name Extensions of size, begin, and end to non-iterable types
20 **********************************************************************/
21 template<typename T>
22 size_t size(T&& t)
23 {
24 if constexpr (std::ranges::range<T>) return std::ranges::size(t);
25 else return 1;
26 }
27
28 template<typename T>
29 auto begin(T&& t)
30 {
31 if constexpr (std::ranges::range<T>) return std::ranges::begin(t);
32 else return std::addressof(t);
33 }
34
35 template<typename T>
36 auto cbegin(T&& t)
37 {
38 if constexpr (std::ranges::range<T>) return std::ranges::cbegin(t);
39 else return bbm::begin(std::as_const(t));
40 }
41
42 template<typename T>
43 auto end(T&& t)
44 {
45 if constexpr (std::ranges::range<T>) return std::ranges::end(t);
46 else return std::next(bbm::begin(t));
47 }
48
49 template<typename T>
50 auto cend(T&& t)
51 {
52 if constexpr (std::ranges::range<T>) return std::ranges::cend(t);
53 else return bbm::end(std::as_const(t));
54 }
55 //! @}
56
57 /*********************************************************************/
58 /*! @{ \name Iterable container type traits
59 *********************************************************************/
60 template<typename T> requires std::ranges::range<T>
61 using iterable_value_t = std::decay_t<decltype( *bbm::begin(std::declval<T>()) )>;
62 //! @}
63
64 /*********************************************************************/
65 /*! \brief Cast iterator; cast the result after deferencing.
66 **********************************************************************/
67 template<typename CASTTYPE, typename ITR> requires std::input_or_output_iterator<ITR>
69 {
70 public:
71 using iterator_category = typename std::iterator_traits<ITR>::iterator_category;
72 using difference_type = typename std::iterator_traits<ITR>::difference_type;
73 using value_type = std::remove_reference_t<CASTTYPE>;
76
77 //! \brief empty constructor
78 cast_itr(void) : _itr() {}
79
80 //! \brief constructor
81 cast_itr(const ITR& itr) : _itr(itr) {}
82
83 //! \brief construct from cast_itr
84 template<typename C, typename I>
85 cast_itr(const cast_itr<C,I>& itr) : _itr(itr.raw_iterator()) {}
86
87 //! @{ \name comparison
88 bool operator==(const cast_itr& itr) const { return (_itr == itr._itr); }
89 bool operator!=(const cast_itr& itr) const { return (_itr != itr._itr); }
90 bool operator<=(const cast_itr& itr) const { return (_itr <= itr._itr); }
91 bool operator<(const cast_itr& itr) const { return (_itr < itr._itr); }
92 bool operator>=(const cast_itr& itr) const { return (_itr >= itr._itr); }
93 bool operator>(const cast_itr& itr) const { return (_itr > itr._itr); }
94 //! @}
95
96 //! @{ \name math operations
97 cast_itr& operator++(void) { ++_itr; return *this; }
98 cast_itr operator++(int) { cast_itr ret = *this; ++(*this); return ret; }
99 cast_itr& operator+=(size_t step) { _itr += step; return *this; }
100 cast_itr operator+(size_t step) const { return cast_itr(_itr + step); }
101
102 cast_itr& operator--(void) { --_itr; return *this; }
103 cast_itr operator--(int) { cast_itr ret = *this; --(*this); return ret; }
104 cast_itr& operator-=(size_t step) { _itr -= step; return *this; }
105 cast_itr operator-(size_t step) const { return cast_itr(_itr - step); }
106
107 difference_type operator-(const cast_itr& itr) { return _itr - itr._itr; }
108
109 auto operator[](size_t idx) const { return *(*this + idx); }
110 //! @}
111
112 //! \brief cast the derefenced value to CASTYPE&
113 reference operator*(void) const { return static_cast<reference>(*_itr); }
114
115 //! \brief cast the dereferenced value to CASTTYPE*
116 pointer operator->(void) const { return &(this->operator*()); }
117
118 //! \brief dereference without casting
119 decltype(auto) raw_dereference(void) const { return *_itr; }
120
121 //! \brief underlying iterator
122 auto raw_iterator(void) const { return _itr; }
123
124 private:
125 ITR _itr;
126 };
127
128 /*** Implementation Details ***/
129 namespace detail {
130 template<typename T> struct is_cast_itr_impl : std::false_type {};
131 template<typename C, typename T> struct is_cast_itr_impl<cast_itr<C, T>> : std::true_type{};
132
133 template<typename T> struct underlying_itr_impl { using type = T; };
134 template<typename C, typename T> struct underlying_itr_impl<cast_itr<C, T>> { using type = T; };
135 } // end detail namespace
136
137 /*********************************************************************/
138 /*! @{ Type traits
139 *********************************************************************/
140 template<typename T>
141 using is_cast_itr = bbm::detail::is_cast_itr_impl<std::decay_t<T>>;
142
143 template<typename T>
144 inline constexpr bool is_cast_itr_v = is_cast_itr<T>::value;
145
146 template<typename T>
147 using underlying_itr_t = typename bbm::detail::underlying_itr_impl<std::decay_t<T>>::type;
148 //! @}
149
150} // end bbm namespace
151
152#endif /* _BBM_ITERATOR_UTIL_H_ */
Cast iterator; cast the result after deferencing.
Definition: iterator_util.h:69
reference operator*(void) const
cast the derefenced value to CASTYPE&
Definition: iterator_util.h:113
cast_itr & operator--(void)
Definition: iterator_util.h:102
cast_itr(const cast_itr< C, I > &itr)
construct from cast_itr
Definition: iterator_util.h:85
cast_itr(const ITR &itr)
constructor
Definition: iterator_util.h:81
bool operator!=(const cast_itr &itr) const
Definition: iterator_util.h:89
bool operator<=(const cast_itr &itr) const
Definition: iterator_util.h:90
value_type * pointer
Definition: iterator_util.h:75
ITR _itr
Definition: iterator_util.h:125
cast_itr operator-(size_t step) const
Definition: iterator_util.h:105
cast_itr(void)
empty constructor
Definition: iterator_util.h:78
cast_itr operator+(size_t step) const
Definition: iterator_util.h:100
cast_itr & operator++(void)
Definition: iterator_util.h:97
cast_itr & operator-=(size_t step)
Definition: iterator_util.h:104
value_type & reference
Definition: iterator_util.h:74
typename std::iterator_traits< ITR >::iterator_category iterator_category
Definition: iterator_util.h:71
cast_itr & operator+=(size_t step)
Definition: iterator_util.h:99
pointer operator->(void) const
cast the dereferenced value to CASTTYPE*
Definition: iterator_util.h:116
std::remove_reference_t< CASTTYPE > value_type
Definition: iterator_util.h:73
bool operator>(const cast_itr &itr) const
Definition: iterator_util.h:93
auto raw_iterator(void) const
underlying iterator
Definition: iterator_util.h:122
bool operator==(const cast_itr &itr) const
Definition: iterator_util.h:88
typename std::iterator_traits< ITR >::difference_type difference_type
Definition: iterator_util.h:72
auto operator[](size_t idx) const
Definition: iterator_util.h:109
cast_itr operator++(int)
Definition: iterator_util.h:98
difference_type operator-(const cast_itr &itr)
Definition: iterator_util.h:107
cast_itr operator--(int)
Definition: iterator_util.h:103
bool operator>=(const cast_itr &itr) const
Definition: iterator_util.h:92
decltype(auto) raw_dereference(void) const
dereference without casting
Definition: iterator_util.h:119
bool operator<(const cast_itr &itr) const
Definition: iterator_util.h:91
Definition: aggregatebsdf.h:29
constexpr bool is_cast_itr_v
Definition: iterator_util.h:144
typename bbm::detail::underlying_itr_impl< std::decay_t< T > >::type underlying_itr_t
Definition: iterator_util.h:147
auto end(T &&t)
Definition: iterator_util.h:43
size_t size(T &&t)
Definition: iterator_util.h:22
auto cend(T &&t)
Definition: iterator_util.h:50
bbm::detail::is_cast_itr_impl< std::decay_t< T > > is_cast_itr
Definition: iterator_util.h:141
std::decay_t< decltype(*bbm::begin(std::declval< T >()))> iterable_value_t
Definition: iterator_util.h:61
auto begin(T &&t)
Definition: iterator_util.h:29
auto cbegin(T &&t)
Definition: iterator_util.h:36
Additional basic helper concepts.