Utopia 2
Framework for studying models of complex & adaptive systems.
Loading...
Searching...
No Matches
zip.hh
Go to the documentation of this file.
1#ifndef UTOPIA_CORE_ZIP_HH
2#define UTOPIA_CORE_ZIP_HH
3
4#include <iterator>
5#include <tuple>
6#include <type_traits>
7#include <iterator>
8#include <iostream>
9
10#include <boost/hana/ext/std/tuple.hpp>
11#include <boost/hana/transform.hpp>
12#include <boost/hana/for_each.hpp>
13
14#include "type_traits.hh"
15
16namespace Utopia
17{
18
20
22namespace Itertools
23{
24
26
40template <typename... Iters>
42{
43private:
44 using Tuple = std::tuple<Iters...>;
45
46 using RefTuple = std::tuple<decltype(*std::declval<Iters>())...>;
47
48 using PtrTuple = std::tuple<typename std::iterator_traits<Iters>::pointer...>;
49
51
52 using This = ZipIterator<Iters...>;
53
54public:
55 using value_type = std::tuple<typename std::iterator_traits<Iters>::value_type...>;
60 std::common_type_t<typename std::iterator_traits<Iters>::iterator_category...>;
61
63
66 {
67 boost::hana::for_each(_iterators, [](auto&& iter) { ++iter; });
68 return *this;
69 }
70
72
74 template<typename category = iterator_category,
75 typename std::enable_if_t<
76 std::is_base_of_v<std::bidirectional_iterator_tag,
77 category>, int> = 0>
79 {
80 boost::hana::for_each(_iterators, [](auto&& iter) { --iter; });
81 return *this;
82 }
83
85
88 {
89 This copy(*this);
90 boost::hana::for_each(_iterators, [](auto&& iter) { iter++; });
91 return copy;
92 }
93
95
97 template<typename category = iterator_category,
98 typename std::enable_if_t<
99 std::is_base_of_v<std::bidirectional_iterator_tag,
100 category>, int> = 0>
102 {
103 This copy(*this);
104 boost::hana::for_each(_iterators, [](auto&& iter) { iter--; });
105 return copy;
106 }
107
109
112 template<typename category = iterator_category,
113 typename std::enable_if_t<
114 std::is_base_of_v<std::random_access_iterator_tag,
115 category>, int> = 0>
117 {
118 This copy(*this);
119 return copy += n;
120 }
121
123
126 template<typename category = iterator_category,
127 typename std::enable_if_t<
128 std::is_base_of_v<std::random_access_iterator_tag,
129 category>, int> = 0>
131 {
132 This copy(*this);
133 return copy -= n;
134 }
135
137
140 template<typename category = iterator_category,
141 typename std::enable_if_t<
142 std::is_base_of_v<std::random_access_iterator_tag,
143 category>, int> = 0>
145 {
146 return std::get<0>(_iterators) - std::get<0>(other._iterators);
147 }
148
150
153 template<typename category = iterator_category,
154 typename std::enable_if_t<
155 std::is_base_of_v<std::random_access_iterator_tag,
156 category>, int> = 0>
158 {
159 boost::hana::for_each(_iterators, [&n](auto&& iter) { iter += n; });
160 return *this;
161 }
162
164
167 template<typename category = iterator_category,
168 typename std::enable_if_t<
169 std::is_base_of_v<std::random_access_iterator_tag,
170 category>, int> = 0>
172 {
173 boost::hana::for_each(_iterators, [&n](auto&& iter) { iter -= n; });
174 return *this;
175 }
176
178
180 const reference operator*() const
181 {
182 return boost::hana::transform(
184 [](auto&& iter) { return std::ref(*iter); });
185 }
186
188
191 {
192 return boost::hana::transform(
194 [](auto&& iter) { return std::ref(*iter); });
195 }
196
198
200 const pointer operator->() const
201 {
202 return boost::hana::transform(
204 [](auto&& iter) { return &(*iter); });
205 }
206
208
211 {
212 return boost::hana::transform(
214 [](auto&& iter) { return &(*iter); });
215 }
216
218 ZipIterator() = default;
219
221
223 ZipIterator(const ZipIterator& other) = default;
224
226
230
232
237
239
243
245
249 {
250 }
251
253
255 template <typename... Iterators>
256 ZipIterator(std::tuple<Iterators...> iters) : _iterators(iters)
257 {
258 }
259
261
265 template<typename... It>
267 {
268 return _iterators == other._iterators;
269 }
270
272
276 template<typename... It>
278 {
279 return _iterators != other._iterators;
280 }
281
283
287 template<typename category = iterator_category,
288 typename std::enable_if_t<
289 std::is_base_of_v<std::random_access_iterator_tag,
290 category>, int> = 0>
291 bool operator<(const ZipIterator& other) const
292 {
293 return _iterators < other._iterators;
294 }
295
297
301 template<typename category = iterator_category,
302 typename std::enable_if_t<
303 std::is_base_of_v<std::random_access_iterator_tag,
304 category>, int> = 0>
305 bool operator<=(const ZipIterator& other) const
306 {
307 return _iterators <= other._iterators;
308 }
309
311
315 template<typename category = iterator_category,
316 typename std::enable_if_t<
317 std::is_base_of_v<std::random_access_iterator_tag,
318 category>, int> = 0>
319 bool operator>(const ZipIterator& other) const
320 {
321 return _iterators > other._iterators;
322 }
323
325
329 template<typename category = iterator_category,
330 typename std::enable_if_t<
331 std::is_base_of_v<std::random_access_iterator_tag,
332 category>, int> = 0>
333 bool operator>=(const ZipIterator& other) const
334 {
335 return _iterators >= other._iterators;
336 }
337
345
352 template<typename category = iterator_category,
353 typename std::enable_if_t<
354 std::is_base_of_v<std::random_access_iterator_tag,
355 category>, int> = 0>
357 {
358 return *(*this + n);
359 }
360
362 ~ZipIterator() = default;
363
365
367 friend std::ostream& operator<< (std::ostream& ostr,
368 const ZipIterator& right
369 )
370 {
371 // using Utopia::Utils::operator<<;
372 ostr << "->" << *right;
373 return ostr;
374 }
375};
376
378template <typename... Iterators>
379ZipIterator(std::tuple<Iterators...> iters)->ZipIterator<Iterators...>;
380
381// iterator adaptors
382
384
395template <typename Adaptor, typename... Containers>
400
402
408template <typename... Containers>
409class zip
410{
411protected:
412 using Tuple = std::tuple<std::reference_wrapper<Containers>...>;
414
415public:
422 auto begin()
423 {
424 return ZipIterator(boost::hana::transform(
425 _containers, [](auto& cont) { return cont.get().begin(); }));
426 }
427
434 auto end()
435 {
436 return ZipIterator(boost::hana::transform(
437 _containers, [](auto& cont) { return cont.get().end(); }));
438 }
439
446 auto cbegin()
447 {
448 return ZipIterator(boost::hana::transform(
449 _containers, [](auto& cont) { return cont.get().cbegin(); }));
450 }
451
458 auto cend()
459 {
460 return ZipIterator(boost::hana::transform(
461 _containers, [](auto& cont) { return cont.get().cend(); }));
462 }
463
470 auto rbegin()
471 {
472 return ZipIterator(boost::hana::transform(
473 _containers, [](auto& cont) { return cont.get().rbegin(); }));
474 }
475
482 auto rend()
483 {
484 return ZipIterator(boost::hana::transform(
485 _containers, [](auto& cont) { return cont.get().rend(); }));
486 }
487
493 zip(const zip& other) = delete;
494
501 zip& operator=(const zip& other) = delete;
502
509 zip& operator=(zip&& other) = default;
510
516 zip(zip&& other) = default;
517
519 ~zip() = default;
520
522
525 {
526 }
527};
528
536template <typename... Containers>
538{
539 return zipper.begin();
540}
541
549template <typename... Containers>
551{
552 return zipper.end();
553}
554
562template <typename... Containers>
564{
565 return zipper.cbegin();
566}
567
575template <typename... Containers>
577{
578 return zipper.cend();
579}
580
588template <typename... Containers>
590{
591 return zipper.rbegin();
592}
593
601template <typename... Containers>
603{
604 return zipper.rend();
605}
606
611} // namespace Itertools
612} // namespace Utopia
613
614#endif // UTOPIA_CORE_ZIP_HH
Iterator over an arbitrary number of collections.
Definition zip.hh:42
reference operator*()
Dereference this iterator at its current position.
Definition zip.hh:190
bool operator<=(const ZipIterator &other) const
Less-than or equal compare this object with another zip iterator.
Definition zip.hh:305
ZipIterator & operator=(const ZipIterator &other)=default
Copy-assign a zip iterator.
const pointer operator->() const
Indirect this pointer at its current position.
Definition zip.hh:200
std::tuple< typename std::iterator_traits< Iters >::value_type... > value_type
Definition zip.hh:55
ZipIterator operator--(int)
Decrement by postfix.
Definition zip.hh:101
difference_type operator-(const ZipIterator &other) const
Compute the difference between two iterators.
Definition zip.hh:144
std::tuple< typename std::iterator_traits< Iters >::pointer... > PtrTuple
Definition zip.hh:48
ZipIterator & operator=(ZipIterator &&other)=default
Move-assign a zip iterator.
ZipIterator(Iters... iters)
Construct from a pack of iterators.
Definition zip.hh:247
reference operator[](const difference_type n) const
offset dereference operator for purely random accesss iterators held by ZipIterator
Definition zip.hh:356
bool operator==(const ZipIterator< It... > &other) const
Compare this object with another zip iterator.
Definition zip.hh:266
bool operator<(const ZipIterator &other) const
Less-than compare this object with another zip iterator.
Definition zip.hh:291
ZipIterator operator++(int)
Increment by postfix.
Definition zip.hh:87
ZipIterator & operator--()
Decrement by prefix.
Definition zip.hh:78
ZipIterator()=default
Default-construct a zip iterator. Dereferencing it is undefined.
bool operator!=(const ZipIterator< It... > &other) const
Compare this object with another zip iterator.
Definition zip.hh:277
ZipIterator & operator+=(const difference_type n)
Increment in-place by a number of steps.
Definition zip.hh:157
ZipIterator(const ZipIterator &other)=default
Copy-construct a zip iterator.
std::tuple< decltype(*std::declval< Iters >())... > RefTuple
Definition zip.hh:46
~ZipIterator()=default
Destroy this object.
ZipIterator operator-(const difference_type n) const
Decrement by a number of steps.
Definition zip.hh:130
ZipIterator & operator++()
Increment by prefix.
Definition zip.hh:65
const reference operator*() const
Dereference this iterator at its current position.
Definition zip.hh:180
std::common_type_t< typename std::iterator_traits< Iters >::iterator_category... > iterator_category
Definition zip.hh:60
PtrTuple pointer
Definition zip.hh:57
ZipIterator operator+(const difference_type n) const
Increment by a number of steps.
Definition zip.hh:116
ZipIterator(ZipIterator &&other)=default
Move-construct a zip iterator.
ZipIterator & operator-=(const difference_type n)
Decrement in-place by a number of steps.
Definition zip.hh:171
int difference_type
Definition zip.hh:56
friend std::ostream & operator<<(std::ostream &ostr, const ZipIterator &right)
Write the contents of this iterator into an outstream.
Definition zip.hh:367
std::tuple< Iters... > Tuple
Definition zip.hh:44
pointer operator->()
Indirect this pointer at its current position.
Definition zip.hh:210
Tuple _iterators
Definition zip.hh:50
bool operator>=(const ZipIterator &other) const
Greater-than or equal compare this object with another zip iterator.
Definition zip.hh:333
RefTuple reference
Definition zip.hh:58
ZipIterator(std::tuple< Iterators... > iters)
Construct from a tuple of iterators.
Definition zip.hh:256
bool operator>(const ZipIterator &other) const
Greater-than compare this object with another zip iterator.
Definition zip.hh:319
A range defined by instances of ZipIterator.
Definition zip.hh:410
zip(zip &&other)=default
Construct a new zip object.
zip & operator=(zip &&other)=default
assign zip object
zip(Containers &... conts)
Instantiate a new zip range.
Definition zip.hh:524
auto begin()
make Zipiterator containing the begin iterators of the containers 'zip' refers to
Definition zip.hh:422
auto rbegin()
make Zipiterator containing the reverse begin iterators of the containers 'zip' refers to
Definition zip.hh:470
auto rend()
make Zipiterator containing the reverse end iterators of the containers 'zip' refers to
Definition zip.hh:482
auto cend()
make Zipiterator containing the const end iterators of the containers 'zip' refers to
Definition zip.hh:458
auto cbegin()
make Zipiterator containing the const begin iterators of the containers 'zip' refers to
Definition zip.hh:446
auto end()
make Zipiterator containing the end iterators of the containers 'zip' refers to
Definition zip.hh:434
zip(const zip &other)=delete
Construct a new zip object.
zip & operator=(const zip &other)=delete
deleted copy assignment
~zip()=default
Destroy the range.
std::tuple< std::reference_wrapper< Containers >... > Tuple
Definition zip.hh:412
Tuple _containers
Definition zip.hh:413
Container select_entities(const Manager &mngr, const DataIO::Config &sel_cfg)
Select entities according to parameters specified in a configuration.
Definition select.hh:213
auto adapt_zip(Adaptor &&adaptor, Containers &... containers)
Return a zip iterator built from an adapter applied to containers.
Definition zip.hh:396
auto end(zip< Containers... > &zipper)
end function like std::end
Definition zip.hh:550
auto begin(zip< Containers... > &zipper)
Begin function like std::begin.
Definition zip.hh:537
auto cend(zip< Containers... > &zipper)
end function like std::end
Definition zip.hh:576
auto rbegin(zip< Containers... > &zipper)
Begin function like std::begin.
Definition zip.hh:589
auto rend(zip< Containers... > &zipper)
end function like std::end
Definition zip.hh:602
auto cbegin(zip< Containers... > &zipper)
Begin function like std::begin.
Definition zip.hh:563
Definition agent.hh:11
Definition parallel.hh:235