kblib 0.2.3
General utilities library for modern C++
enumerate-contrib-tw.h
Go to the documentation of this file.
1/*
2 * MIT License
3 *
4 * Copyright (c) 2018 Tobias Widlund
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 */
24
25#ifndef ENUMERATECONTRIBTW_H
26#define ENUMERATECONTRIBTW_H
27// Original source available at https://github.com/therocode/enumerate
28
29#include "tdecl.h"
30
31#include <iterator>
32#include <utility>
33
34namespace KBLIB_NS {
35
43template <typename It>
45 It it;
46 std::size_t idx;
47
48 using nested_reference = typename std::iterator_traits<It>::reference;
49
50 using difference_type = std::ptrdiff_t;
51 using value_type = std::pair<nested_reference, std::size_t>;
52 using pointer = void;
54 using iterator_category = std::input_iterator_tag;
55
56 constexpr auto operator*() -> value_type { return {*it, idx}; }
57
58 constexpr auto operator++() & -> enumerate_iterator& {
59 ++it;
60 ++idx;
61 return *this;
62 }
63 constexpr auto operator++(int) -> enumerate_iterator {
64 auto tmp = *this;
65 ++(*this);
66 return tmp;
67 }
68
69 template <typename OIt>
70 constexpr auto operator==(OIt rhs)
71 -> decltype(std::declval<It&>() == std::declval<OIt&>()) {
72 return it == rhs;
73 }
74 template <typename OIt>
75 constexpr auto operator!=(OIt rhs)
76 -> decltype(std::declval<It&>() != std::declval<OIt&>()) {
77 return it != rhs;
78 }
79
80 constexpr friend auto operator==(enumerate_iterator lhs,
81 enumerate_iterator rhs) -> bool {
82 return lhs.it == rhs.it;
83 }
84 constexpr friend auto operator!=(enumerate_iterator lhs,
85 enumerate_iterator rhs) -> bool {
86 return lhs.it != rhs.it;
87 }
88};
89
90template <typename Range, typename = void>
91struct enumerate_t;
92
100template <typename Range>
101struct enumerate_t<Range, void> {
103
104 using range_t = typename std::remove_reference_t<Range>;
105 using nested_iterator = decltype(r.begin());
106 using nested_end_iterator = decltype(r.end());
109
110 using nested_const_iterator = typename range_t::const_iterator;
112
113 constexpr auto begin() const& noexcept(noexcept(r.cbegin()))
114 -> const_iterator {
115 return {r.cbegin(), 0};
116 }
117 constexpr auto begin() & noexcept(noexcept(r.begin())) -> iterator {
118 return {r.begin(), 0};
119 }
120
121 constexpr auto end() const& noexcept(noexcept(r.cend())) -> const_iterator {
122 return {r.cend(), -std::size_t{1}};
123 }
124 constexpr auto end() & noexcept(noexcept(r.end())) -> end_iterator {
125 return {r.end(), -std::size_t{1}};
126 }
127};
128
136template <typename It, typename EndIt>
138 using nested_iterator = It;
141
142 constexpr auto begin() const& noexcept -> iterator { return {r_begin, 0}; }
143
144 constexpr auto end() const& noexcept -> end_iterator {
145 return {r_end, -std::size_t{1}};
146 }
147
149 EndIt r_end;
150};
151
158template <typename Range>
159constexpr auto enumerate(Range&& r) -> enumerate_t<Range&&> {
160 return {std::forward<Range>(r)};
161}
162
168template <typename It, typename EIt>
169constexpr auto enumerate(It begin, EIt end) -> enumerate_t<It, EIt> {
170 return {begin, end};
171}
172
173} // namespace KBLIB_NS
174
175#endif // ENUMERATECONTRIBTW_H
typename no_dangle< T >::type no_dangle_t
Definition: tdecl.h:191
constexpr auto enumerate(It begin, EIt end) -> enumerate_t< It, EIt >
Allow access to indexes while using range-based for loops.
constexpr auto operator==(OIt rhs) -> decltype(std::declval< It & >()==std::declval< OIt & >())
constexpr auto operator++() &-> enumerate_iterator &
constexpr auto operator++(int) -> enumerate_iterator
constexpr friend auto operator==(enumerate_iterator lhs, enumerate_iterator rhs) -> bool
constexpr auto operator*() -> value_type
constexpr auto operator!=(OIt rhs) -> decltype(std::declval< It & >() !=std::declval< OIt & >())
std::pair< nested_reference, std::size_t > value_type
constexpr friend auto operator!=(enumerate_iterator lhs, enumerate_iterator rhs) -> bool
typename std::iterator_traits< It >::reference nested_reference
std::input_iterator_tag iterator_category
constexpr auto end() const &noexcept(noexcept(r.cend())) -> const_iterator
typename range_t::const_iterator nested_const_iterator
constexpr auto begin() &noexcept(noexcept(r.begin())) -> iterator
constexpr auto begin() const &noexcept(noexcept(r.cbegin())) -> const_iterator
typename std::remove_reference_t< Range > range_t
constexpr auto end() &noexcept(noexcept(r.end())) -> end_iterator
detail::no_dangle_t< Range > r
constexpr auto end() const &noexcept -> end_iterator
constexpr auto begin() const &noexcept -> iterator
Provides macros and basic templates used by the rest of kblib.
#define KBLIB_NS
Definition: tdecl.h:113