RPNX::DataStructures
Header-only C++ data structures and supporting utilities.
Loading...
Searching...
No Matches
dyn_iterator.hpp
1// Copyright 2024 Ryan P. Nicholl, rnicholl@protonmail.com
2// Copyright (c) 2024 Ryan Nicholl $USER_EMAIL
3
4#ifndef RANGE_HPP
5#define RANGE_HPP
6#include <typeindex>
7
8#include <typeindex>
9#include <typeinfo>
10#include <utility>
11
12namespace rpnx
13{
15 template < typename T >
17 {
18 public:
20 static inline const std::type_index type = std::type_index(typeid(T));
21 };
22
32 template < typename V >
34 {
35 struct iterator_vtable
36 {
37 using get_input_f = V (*)(void* self);
38 using copy_f = void* (*)(void const* self);
39 using advance_f = void (*)(void* self);
40 using delete_f = void (*)(void* self);
41
42 get_input_f v_get_input = {};
43 copy_f v_copy = {};
44 advance_f v_advance = {};
45 delete_f v_delete = {};
46 std::type_index const* v_type = &type_info_holder< void >::type;
47 };
48
49 template < typename T >
50 static constexpr iterator_vtable vtable = {
51 .v_get_input = [](void* self) -> V
52 {
53 return **static_cast< T* >(self);
54 },
55 .v_copy = [](void const* self) -> void*
56 {
57 return new T(*static_cast< T const* >(self));
58 },
59 .v_advance = [](void* self) -> void
60 {
61 ++(*static_cast< T* >(self));
62 },
63 .v_delete = [](void* self) -> void
64 {
65 delete static_cast< T* >(self);
66 },
68 };
69
70 iterator_vtable const* m_vtable;
71 void* m_self;
72
73 public:
75 dyn_input_iter() : m_vtable(nullptr), m_self(nullptr)
76 {
77 }
78
80 template < typename It >
81 dyn_input_iter(It it) : m_vtable(&vtable< It >), m_self(new It(std::move(it)))
82 {
83 }
84
86 dyn_input_iter(dyn_input_iter< V > const& other) : m_vtable(other.m_vtable), m_self(other.m_vtable == nullptr ? nullptr : other.m_vtable->v_copy(other.m_self))
87 {
88 }
89
91 dyn_input_iter(dyn_input_iter< V >&& other) noexcept : m_vtable(other.m_vtable), m_self(other.m_self)
92 {
93 other.m_vtable = nullptr;
94 other.m_self = nullptr;
95 }
96
99 {
100 if (this == &other)
101 {
102 return *this;
103 }
104
105 void* copy = other.m_vtable == nullptr ? nullptr : other.m_vtable->v_copy(other.m_self);
106
107 if (m_vtable != nullptr)
108 {
109 m_vtable->v_delete(m_self);
110 }
111
112 m_vtable = other.m_vtable;
113 m_self = copy;
114 return *this;
115 }
116
119 {
120 if (this == &other)
121 {
122 return *this;
123 }
124
125 if (m_vtable != nullptr)
126 {
127 m_vtable->v_delete(m_self);
128 }
129
130 m_vtable = other.m_vtable;
131 m_self = other.m_self;
132 other.m_vtable = nullptr;
133 other.m_self = nullptr;
134 return *this;
135 }
136
138 {
139 if (m_vtable != nullptr)
140 {
141 m_vtable->v_delete(m_self);
142 }
143 }
144
146 V operator*() const
147 {
148 return m_vtable->v_get_input(m_self);
149 }
150
153 {
154 m_vtable->v_advance(m_self);
155 return *this;
156 }
157
160 {
161 dyn_input_iter< V > copy(*this);
162 m_vtable->v_advance(m_self);
163 return copy;
164 }
165 };
166
177 template < typename V >
179 {
180 struct iterator_vtable
181 {
182 using get_input_f = V (*)(void* self);
183 using copy_f = void* (*)(void const* self);
184 using advance_f = void (*)(void* self);
185 using less_f = bool (*)(void const* self, void const* other);
186 using equal_f = bool (*)(void const* self, void const* other);
187 using delete_f = void (*)(void* self);
188
189 get_input_f v_get_input = {};
190 copy_f v_copy = {};
191 advance_f v_advance = {};
192 less_f v_less = {};
193 equal_f v_equal = {};
194 delete_f v_delete = {};
195 std::type_index const* v_type = &type_info_holder< void >::type;
196 };
197
198 template < typename T >
199 static constexpr iterator_vtable vtable = {
200 .v_get_input = [](void* self) -> V
201 {
202 return **static_cast< T* >(self);
203 },
204 .v_copy = [](void const* self) -> void*
205 {
206 return new T(*static_cast< T const* >(self));
207 },
208 .v_advance = [](void* self) -> void
209 {
210 ++(*static_cast< T* >(self));
211 },
212 .v_less = [](void const* self, void const* other) -> bool
213 {
214 return *static_cast< T const* >(self) < *static_cast< T const* >(other);
215 },
216 .v_equal = [](void const* self, void const* other) -> bool
217 {
218 return *static_cast< T const* >(self) == *static_cast< T const* >(other);
219 },
220 .v_delete = [](void* self) -> void
221 {
222 delete static_cast< T* >(self);
223 },
225 };
226
227 iterator_vtable const* m_vtable;
228 void* m_self;
229
230 public:
232 dyn_comparable_input_iter() : m_vtable(nullptr), m_self(nullptr)
233 {
234 }
235
237 template < typename It >
238 dyn_comparable_input_iter(It it) : m_vtable(&vtable< It >), m_self(new It(std::move(it)))
239 {
240 }
241
243 dyn_comparable_input_iter(dyn_comparable_input_iter< V > const& other) : m_vtable(other.m_vtable), m_self(other.m_vtable == nullptr ? nullptr : other.m_vtable->v_copy(other.m_self))
244 {
245 }
246
248 dyn_comparable_input_iter(dyn_comparable_input_iter< V >&& other) noexcept : m_vtable(other.m_vtable), m_self(other.m_self)
249 {
250 other.m_vtable = nullptr;
251 other.m_self = nullptr;
252 }
253
256 {
257 if (this == &other)
258 {
259 return *this;
260 }
261
262 void* copy = other.m_vtable == nullptr ? nullptr : other.m_vtable->v_copy(other.m_self);
263
264 if (m_vtable != nullptr)
265 {
266 m_vtable->v_delete(m_self);
267 }
268
269 m_vtable = other.m_vtable;
270 m_self = copy;
271 return *this;
272 }
273
276 {
277 if (this == &other)
278 {
279 return *this;
280 }
281
282 if (m_vtable != nullptr)
283 {
284 m_vtable->v_delete(m_self);
285 }
286
287 m_vtable = other.m_vtable;
288 m_self = other.m_self;
289 other.m_vtable = nullptr;
290 other.m_self = nullptr;
291 return *this;
292 }
293
295 {
296 if (m_vtable != nullptr)
297 {
298 m_vtable->v_delete(m_self);
299 }
300 }
301
303 V operator*() const
304 {
305 return m_vtable->v_get_input(m_self);
306 }
307
310 {
311 m_vtable->v_advance(m_self);
312 return *this;
313 }
314
317 {
319 m_vtable->v_advance(m_self);
320 return copy;
321 }
322
325 {
326 if (m_vtable == nullptr && other.m_vtable == nullptr)
327 {
328 return false;
329 }
330 if (m_vtable == nullptr)
331 {
332 return true;
333 }
334 if (other.m_vtable == nullptr)
335 {
336 return false;
337 }
338 if (m_vtable->v_type != other.m_vtable->v_type)
339 {
340 return m_vtable->v_type < other.m_vtable->v_type;
341 }
342
343 if (m_vtable->v_less(m_self, other.m_self))
344 {
345 return true;
346 }
347
348 return false;
349 }
350
353 {
354 if (m_vtable == nullptr && other.m_vtable == nullptr)
355 {
356 return true;
357 }
358 if (m_vtable == nullptr || other.m_vtable == nullptr)
359 {
360 return false;
361 }
362
363 if (m_vtable->v_type != other.m_vtable->v_type)
364 {
365 return false;
366 }
367
368 return m_vtable->v_equal(m_self, other.m_self);
369 }
370
373 {
374 return !(*this == other);
375 }
376 };
377
387 template < typename V >
389 {
390 struct iterator_vtable
391 {
392 using get_value_f = V const& (*)(void* self);
393 using copy_f = void* (*)(void const* self);
394 using advance_f = void (*)(void* self);
395 using recede_f = void (*)(void* self);
396 using less_f = bool (*)(void const* self, void const* other);
397 using equal_f = bool (*)(void const* self, void const* other);
398 using delete_f = void (*)(void* self);
399
400 get_value_f v_get_value = {};
401 copy_f v_copy = {};
402 advance_f v_advance = {};
403 recede_f v_recede = {};
404 // less_f v_less = {};
405 equal_f v_equal = {};
406 delete_f v_delete = {};
407 std::type_index const* v_type = &type_info_holder< void >::type;
408 };
409
410 template < typename T >
411 static constexpr iterator_vtable vtable = {
412 .v_get_value = [](void* self) -> V const&
413 {
414 return **static_cast< T* >(self);
415 },
416 .v_copy = [](void const* self) -> void*
417 {
418 return new T(*static_cast< T const* >(self));
419 },
420 .v_advance = [](void* self) -> void
421 {
422 ++(*static_cast< T* >(self));
423 },
424 .v_recede = [](void* self) -> void
425 {
426 --(*static_cast< T* >(self));
427 },
428 // .v_less = [](void const* self, void const* other) -> bool { return *static_cast< T const* >(self) < *static_cast< T const* >(other); },
429 .v_equal = [](void const* self, void const* other) -> bool
430 {
431 return *static_cast< T const* >(self) == *static_cast< T const* >(other);
432 },
433 .v_delete = [](void* self) -> void
434 {
435 delete static_cast< T* >(self);
436 },
438 };
439
440 iterator_vtable const* m_vtable;
441 void* m_self;
442
443 public:
445 dyn_bidirectional_input_iter() : m_vtable(nullptr), m_self(nullptr)
446 {
447 }
448
450 template < typename It >
451 dyn_bidirectional_input_iter(It it) : m_vtable(&vtable< It >), m_self(new It(std::move(it)))
452 {
453 }
454
456 dyn_bidirectional_input_iter(dyn_bidirectional_input_iter< V > const& other) : m_vtable(other.m_vtable), m_self(other.m_vtable == nullptr ? nullptr : other.m_vtable->v_copy(other.m_self))
457 {
458 }
459
461 dyn_bidirectional_input_iter(dyn_bidirectional_input_iter< V >&& other) noexcept : m_vtable(other.m_vtable), m_self(other.m_self)
462 {
463 other.m_vtable = nullptr;
464 other.m_self = nullptr;
465 }
466
469 {
470 if (this == &other)
471 {
472 return *this;
473 }
474
475 void* copy = other.m_vtable == nullptr ? nullptr : other.m_vtable->v_copy(other.m_self);
476
477 if (m_vtable != nullptr)
478 {
479 m_vtable->v_delete(m_self);
480 }
481
482 m_vtable = other.m_vtable;
483 m_self = copy;
484 return *this;
485 }
486
489 {
490 if (this == &other)
491 {
492 return *this;
493 }
494
495 if (m_vtable != nullptr)
496 {
497 m_vtable->v_delete(m_self);
498 }
499
500 m_vtable = other.m_vtable;
501 m_self = other.m_self;
502 other.m_vtable = nullptr;
503 other.m_self = nullptr;
504 return *this;
505 }
506
508 {
509 if (m_vtable != nullptr)
510 {
511 m_vtable->v_delete(m_self);
512 }
513 }
514
516 V operator*() const
517 {
518 return m_vtable->v_get_value(m_self);
519 }
520
523 {
524 m_vtable->v_advance(m_self);
525 return *this;
526 }
527
530 {
532 m_vtable->v_advance(m_self);
533 return copy;
534 }
535
538 {
539 m_vtable->v_recede(m_self);
540 return *this;
541 }
542
545 {
547 m_vtable->v_recede(m_self);
548 return copy;
549 }
550 /*
551
552 bool operator<(dyn_bidirectional_input_iter< V > const& other) const
553 {
554 if (m_vtable == nullptr && other.m_vtable == nullptr)
555 {
556 return false;
557 }
558 if (m_vtable == nullptr)
559 {
560 return true;
561 }
562 if (other.m_vtable == nullptr)
563 {
564 return false;
565 }
566 if (m_vtable->v_type != other.m_vtable->v_type)
567 {
568 return m_vtable->v_type < other.m_vtable->v_type;
569 }
570
571 return m_vtable->v_less(m_self, other.m_self);
572 }
573*/
576 {
577 if (m_vtable == nullptr && other.m_vtable == nullptr)
578 {
579 return true;
580 }
581 if (m_vtable == nullptr || other.m_vtable == nullptr)
582 {
583 return false;
584 }
585
586 if (m_vtable->v_type != other.m_vtable->v_type)
587 {
588 return false;
589 }
590
591 return m_vtable->v_equal(m_self, other.m_self);
592 }
593
596 {
597 return !(*this == other);
598 }
599 };
600
602 template < typename V >
604 {
607
608 public:
613
616 {
617 return m_pos;
618 }
619
622 {
623 return m_end;
624 }
625 };
626
635 template < typename V >
637 {
638 struct iterator_vtable
639 {
640 using set_output_f = void (*)(void* self, V const& value);
641 using copy_f = void* (*)(void const* self);
642 using advance_f = void (*)(void* self);
643 using delete_f = void (*)(void* self);
644
645 set_output_f v_set_output = {};
646 copy_f v_copy = {};
647 advance_f v_advance = {};
648 delete_f v_delete = {};
649 std::type_index const* v_type = &type_info_holder< void >::type;
650 };
651
652 template < typename T >
653 static constexpr iterator_vtable vtable = {
654 .v_set_output =
655 [](void* self, V const& value)
656 {
657 *(*static_cast< T* >(self)) = value;
658 },
659 .v_copy = [](void const* self) -> void*
660 {
661 return new T(*static_cast< T const* >(self));
662 },
663 .v_advance = [](void* self) -> void
664 {
665 ++(*static_cast< T* >(self));
666 },
667 .v_delete = [](void* self) -> void
668 {
669 delete static_cast< T* >(self);
670 },
672 };
673
674 iterator_vtable const* m_vtable;
675 void* m_self;
676
677 struct proxy
678 {
679 dyn_output_iter< V > const* m_self;
680
681 void operator=(V const& value)
682 {
683 m_self->m_vtable->v_set_output(m_self->m_self, value);
684 }
685 };
686
687 public:
689 dyn_output_iter() : m_vtable(nullptr), m_self(nullptr)
690 {
691 }
692
694 template < typename It >
695 dyn_output_iter(It it) : m_vtable(&vtable< It >), m_self(new It(std::move(it)))
696 {
697 }
698
700 dyn_output_iter(dyn_output_iter< V >&& other) : m_vtable(other.m_vtable), m_self(other.m_self)
701 {
702 other.m_vtable = nullptr;
703 other.m_self = nullptr;
704 }
705
707 dyn_output_iter(dyn_output_iter< V > const& other) : m_vtable(other.m_vtable), m_self(other.m_vtable == nullptr ? nullptr : other.m_vtable->v_copy(other.m_self))
708 {
709 }
710
712 template < typename It >
714 {
715 auto vt = &vtable< It >;
716 auto self = new It(std::move(it));
717
718 if (m_vtable)
719 {
720 m_vtable->v_delete(m_self);
721 }
722
723 m_vtable = vt;
724 m_self = self;
725
726 return *this;
727 }
728
731 {
732 if (this == &other)
733 {
734 return *this;
735 }
736
737 if (other.m_vtable == nullptr)
738 {
739 if (m_vtable)
740 {
741 m_vtable->v_delete(m_self);
742 }
743 m_vtable = nullptr;
744 m_self = nullptr;
745 return *this;
746 }
747 auto copy = other.m_vtable->v_copy(other.m_self);
748
749 if (m_vtable)
750 {
751 m_vtable->v_delete(m_self);
752 }
753
754 m_vtable = other.m_vtable;
755 m_self = copy;
756
757 return *this;
758 }
759
762 {
763 if (this == &other)
764 {
765 return *this;
766 }
767
768 if (other.m_vtable == nullptr)
769 {
770 if (m_vtable)
771 {
772 m_vtable->v_delete(m_self);
773 }
774 m_vtable = nullptr;
775 m_self = nullptr;
776 return *this;
777 }
778
779 if (m_vtable)
780 {
781 m_vtable->v_delete(m_self);
782 }
783
784 m_vtable = other.m_vtable;
785 m_self = other.m_self;
786 other.m_vtable = nullptr;
787 other.m_self = nullptr;
788
789 return *this;
790 }
791
794 {
795 if (this == &other)
796 {
797 return *this;
798 }
799
800 if (other.m_vtable == nullptr)
801 {
802 if (m_vtable)
803 {
804 m_vtable->v_delete(m_self);
805 }
806 m_vtable = nullptr;
807 m_self = nullptr;
808 return *this;
809 }
810 auto copy = other.m_vtable->v_copy(other.m_self);
811
812 if (m_vtable)
813 {
814 m_vtable->v_delete(m_self);
815 }
816
817 m_vtable = other.m_vtable;
818 m_self = copy;
819
820 return *this;
821 }
822
824 proxy operator*() const
825 {
826 return proxy{.m_self = this};
827 }
828
831 {
832 m_vtable->v_advance(m_self);
833 return *this;
834 }
835
838 {
839 dyn_output_iter copy(*this);
840 m_vtable->v_advance(m_self);
841 return copy;
842 }
843
845 {
846 if (m_self)
847 {
848 m_vtable->v_delete(m_self);
849 }
850 }
851
852 // Note: Comparison operators (==, !=, <) are typically not used for output iterators
853 // but could be implemented similarly to dyn_input_iter if needed.
854 };
855
856 class writer
857 {
858 struct writer_vtable
859 {
860 void* (*v_copy)(void* self);
861 void (*v_destroy)(void* self);
862 void (*v_write)(void* self, dyn_input_range< std::byte > data);
863 };
864 };
865} // namespace rpnx
866
867#endif // RANGE_HPP
Owning type-erased bidirectional input iterator.
Definition dyn_iterator.hpp:389
dyn_bidirectional_input_iter(dyn_bidirectional_input_iter< V > const &other)
Copies the erased iterator.
Definition dyn_iterator.hpp:456
dyn_bidirectional_input_iter< V > operator++(int)
Advances and returns the previous position.
Definition dyn_iterator.hpp:529
dyn_bidirectional_input_iter< V > & operator=(dyn_bidirectional_input_iter< V > &&other) noexcept
Move-assigns the erased iterator and leaves the source empty.
Definition dyn_iterator.hpp:488
dyn_bidirectional_input_iter(It it)
Erases and owns a bidirectional iterator value.
Definition dyn_iterator.hpp:451
dyn_bidirectional_input_iter< V > & operator--()
Retreats one position.
Definition dyn_iterator.hpp:537
dyn_bidirectional_input_iter(dyn_bidirectional_input_iter< V > &&other) noexcept
Moves the erased iterator and leaves the source empty.
Definition dyn_iterator.hpp:461
V operator*() const
Reads the current element by value.
Definition dyn_iterator.hpp:516
bool operator==(dyn_bidirectional_input_iter< V > const &other) const
Compares erased iterators for equality.
Definition dyn_iterator.hpp:575
dyn_bidirectional_input_iter< V > & operator++()
Advances one position.
Definition dyn_iterator.hpp:522
dyn_bidirectional_input_iter< V > operator--(int)
Retreats and returns the previous position.
Definition dyn_iterator.hpp:544
dyn_bidirectional_input_iter()
Constructs an empty iterator.
Definition dyn_iterator.hpp:445
bool operator!=(dyn_bidirectional_input_iter< V > const &other) const
Compares erased iterators for inequality.
Definition dyn_iterator.hpp:595
dyn_bidirectional_input_iter< V > & operator=(dyn_bidirectional_input_iter< V > const &other)
Copy-assigns the erased iterator.
Definition dyn_iterator.hpp:468
Owning type-erased input iterator with equality and ordering.
Definition dyn_iterator.hpp:179
bool operator<(dyn_comparable_input_iter< V > const &other) const
Orders erased iterators.
Definition dyn_iterator.hpp:324
dyn_comparable_input_iter< V > & operator++()
Advances the erased iterator.
Definition dyn_iterator.hpp:309
dyn_comparable_input_iter(dyn_comparable_input_iter< V > &&other) noexcept
Moves the erased iterator and leaves the source empty.
Definition dyn_iterator.hpp:248
V operator*() const
Reads the current element by value.
Definition dyn_iterator.hpp:303
dyn_comparable_input_iter< V > operator++(int)
Advances and returns the previous position.
Definition dyn_iterator.hpp:316
dyn_comparable_input_iter(It it)
Erases and owns a comparable iterator value.
Definition dyn_iterator.hpp:238
dyn_comparable_input_iter(dyn_comparable_input_iter< V > const &other)
Copies the erased iterator.
Definition dyn_iterator.hpp:243
dyn_comparable_input_iter< V > & operator=(dyn_comparable_input_iter< V > &&other) noexcept
Move-assigns the erased iterator and leaves the source empty.
Definition dyn_iterator.hpp:275
dyn_comparable_input_iter()
Constructs an empty iterator.
Definition dyn_iterator.hpp:232
bool operator!=(dyn_comparable_input_iter< V > const &other) const
Compares erased iterators for inequality.
Definition dyn_iterator.hpp:372
dyn_comparable_input_iter< V > & operator=(dyn_comparable_input_iter< V > const &other)
Copy-assigns the erased iterator.
Definition dyn_iterator.hpp:255
bool operator==(dyn_comparable_input_iter< V > const &other) const
Compares erased iterators for equality.
Definition dyn_iterator.hpp:352
Owning type-erased input iterator that yields values by copy.
Definition dyn_iterator.hpp:34
dyn_input_iter< V > & operator=(dyn_input_iter< V > &&other) noexcept
Move-assigns the erased iterator and leaves the source empty.
Definition dyn_iterator.hpp:118
V operator*() const
Reads the current element by value.
Definition dyn_iterator.hpp:146
dyn_input_iter(dyn_input_iter< V > &&other) noexcept
Moves the erased iterator and leaves the source empty.
Definition dyn_iterator.hpp:91
dyn_input_iter< V > & operator=(dyn_input_iter< V > const &other)
Copy-assigns the erased iterator.
Definition dyn_iterator.hpp:98
dyn_input_iter(It it)
Erases and owns an iterator value.
Definition dyn_iterator.hpp:81
dyn_input_iter< V > operator++(int)
Advances and returns the previous position.
Definition dyn_iterator.hpp:159
dyn_input_iter(dyn_input_iter< V > const &other)
Copies the erased iterator.
Definition dyn_iterator.hpp:86
dyn_input_iter< V > & operator++()
Advances the erased iterator.
Definition dyn_iterator.hpp:152
dyn_input_iter()
Constructs an empty iterator.
Definition dyn_iterator.hpp:75
Lightweight range of type-erased comparable input iterators.
Definition dyn_iterator.hpp:604
dyn_comparable_input_iter< V > end() const
Returns the one-past-last position by value.
Definition dyn_iterator.hpp:621
dyn_input_range(dyn_comparable_input_iter< V > begin, dyn_comparable_input_iter< V > end)
Constructs a half-open range.
Definition dyn_iterator.hpp:610
dyn_comparable_input_iter< V > begin() const
Returns the first position by value.
Definition dyn_iterator.hpp:615
Owning type-erased output iterator.
Definition dyn_iterator.hpp:637
dyn_output_iter(dyn_output_iter< V > &&other)
Moves the erased output iterator and leaves the source empty.
Definition dyn_iterator.hpp:700
dyn_output_iter operator++(int)
Advances and returns the previous position.
Definition dyn_iterator.hpp:837
dyn_output_iter()
Constructs an empty output iterator.
Definition dyn_iterator.hpp:689
dyn_output_iter & operator++()
Advances one output position.
Definition dyn_iterator.hpp:830
dyn_output_iter(dyn_output_iter< V > const &other)
Copies the erased output iterator.
Definition dyn_iterator.hpp:707
dyn_output_iter & operator=(dyn_output_iter< V > &other)
Copy-assigns from a mutable erased output iterator.
Definition dyn_iterator.hpp:793
dyn_output_iter & operator=(dyn_output_iter< V > const &other)
Copy-assigns the erased output iterator.
Definition dyn_iterator.hpp:730
dyn_output_iter(It it)
Erases and owns an output iterator value.
Definition dyn_iterator.hpp:695
dyn_output_iter & operator=(dyn_output_iter< V > &&other)
Move-assigns the erased output iterator and leaves the source empty.
Definition dyn_iterator.hpp:761
proxy operator*() const
Returns a proxy for writing the current output position.
Definition dyn_iterator.hpp:824
dyn_output_iter & operator=(It it)
Replaces the target with a newly erased output iterator.
Definition dyn_iterator.hpp:713
Provides one stable RTTI identity object per type.
Definition dyn_iterator.hpp:17
static const std::type_index type
Runtime type identity for T.
Definition dyn_iterator.hpp:20
Definition dyn_iterator.hpp:857
Containers, iterator adapters, callable wrappers, and value utilities.
Definition annex.hpp:14