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 
34 namespace kblib {
35 
43 template <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, enumerate_iterator rhs)
81  -> bool {
82  return lhs.it == rhs.it;
83  }
84  constexpr friend auto operator!=(enumerate_iterator lhs, enumerate_iterator rhs)
85  -> bool {
86  return lhs.it != rhs.it;
87  }
88 };
89 
90 template <typename Range, typename = void>
91 struct enumerate_t;
92 
100 template <typename Range>
101 struct 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())) -> const_iterator {
114  return {r.cbegin(), 0};
115  }
116  constexpr auto begin() & noexcept(noexcept(r.begin())) -> iterator {
117  return {r.begin(), 0};
118  }
119 
120  constexpr auto end() const& noexcept(noexcept(r.cend())) -> const_iterator {
121  return {r.cend(), -std::size_t{1}};
122  }
123  constexpr auto end() & noexcept(noexcept(r.end())) -> end_iterator {
124  return {r.end(), -std::size_t{1}};
125  }
126 };
127 
135 template <typename It, typename EndIt>
136 struct enumerate_t {
137  using nested_iterator = It;
140 
141  constexpr auto begin() const& noexcept -> iterator { return {r_begin, 0}; }
142 
143  constexpr auto end() const& noexcept -> end_iterator {
144  return {r_end, -std::size_t{1}};
145  }
146 
148  EndIt r_end;
149 };
150 
157 template <typename Range>
158 constexpr auto enumerate(Range&& r) -> enumerate_t<Range&&> {
159  return {std::forward<Range>(r)};
160 }
161 
167 template <typename It, typename EIt>
168 constexpr auto enumerate(It begin, EIt end) -> enumerate_t<It, EIt> {
169  return {begin, end};
170 }
171 
172 } // namespace kblib
173 
174 #endif // ENUMERATECONTRIBTW_H
typename no_dangle< T >::type no_dangle_t
Definition: tdecl.h:161
The main namespace in which all entities from kblib are defined.
Definition: algorithm.h:44
constexpr auto enumerate(Range &&r) -> enumerate_t< Range && >
Allow access to indexes while using range-based for loops. Safe to use with rvalues.
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.