15 template <
typename T >
20 static inline const std::type_index
type = std::type_index(
typeid(T));
32 template <
typename V >
35 struct iterator_vtable
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);
42 get_input_f v_get_input = {};
44 advance_f v_advance = {};
45 delete_f v_delete = {};
49 template <
typename T >
50 static constexpr iterator_vtable vtable = {
51 .v_get_input = [](
void* self) -> V
53 return **
static_cast< T*
>(self);
55 .v_copy = [](
void const* self) ->
void*
57 return new T(*
static_cast< T const*
>(self));
59 .v_advance = [](
void* self) ->
void
61 ++(*
static_cast< T*
>(self));
63 .v_delete = [](
void* self) ->
void
65 delete static_cast< T*
>(self);
70 iterator_vtable
const* m_vtable;
80 template <
typename It >
81 dyn_input_iter(It it) : m_vtable(&vtable< It >), m_self(new It(std::move(it)))
93 other.m_vtable =
nullptr;
94 other.m_self =
nullptr;
105 void* copy = other.m_vtable ==
nullptr ? nullptr : other.m_vtable->v_copy(other.m_self);
107 if (m_vtable !=
nullptr)
109 m_vtable->v_delete(m_self);
112 m_vtable = other.m_vtable;
125 if (m_vtable !=
nullptr)
127 m_vtable->v_delete(m_self);
130 m_vtable = other.m_vtable;
131 m_self = other.m_self;
132 other.m_vtable =
nullptr;
133 other.m_self =
nullptr;
139 if (m_vtable !=
nullptr)
141 m_vtable->v_delete(m_self);
148 return m_vtable->v_get_input(m_self);
154 m_vtable->v_advance(m_self);
162 m_vtable->v_advance(m_self);
177 template <
typename V >
180 struct iterator_vtable
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);
189 get_input_f v_get_input = {};
191 advance_f v_advance = {};
193 equal_f v_equal = {};
194 delete_f v_delete = {};
198 template <
typename T >
199 static constexpr iterator_vtable vtable = {
200 .v_get_input = [](
void* self) -> V
202 return **
static_cast< T*
>(self);
204 .v_copy = [](
void const* self) ->
void*
206 return new T(*
static_cast< T const*
>(self));
208 .v_advance = [](
void* self) ->
void
210 ++(*
static_cast< T*
>(self));
212 .v_less = [](
void const* self,
void const* other) ->
bool
214 return *
static_cast< T const*
>(self) < *
static_cast< T const*
>(other);
216 .v_equal = [](
void const* self,
void const* other) ->
bool
218 return *
static_cast< T const*
>(self) == *
static_cast< T const*
>(other);
220 .v_delete = [](
void* self) ->
void
222 delete static_cast< T*
>(self);
227 iterator_vtable
const* m_vtable;
237 template <
typename It >
250 other.m_vtable =
nullptr;
251 other.m_self =
nullptr;
262 void* copy = other.m_vtable ==
nullptr ? nullptr : other.m_vtable->v_copy(other.m_self);
264 if (m_vtable !=
nullptr)
266 m_vtable->v_delete(m_self);
269 m_vtable = other.m_vtable;
282 if (m_vtable !=
nullptr)
284 m_vtable->v_delete(m_self);
287 m_vtable = other.m_vtable;
288 m_self = other.m_self;
289 other.m_vtable =
nullptr;
290 other.m_self =
nullptr;
296 if (m_vtable !=
nullptr)
298 m_vtable->v_delete(m_self);
305 return m_vtable->v_get_input(m_self);
311 m_vtable->v_advance(m_self);
319 m_vtable->v_advance(m_self);
326 if (m_vtable ==
nullptr && other.m_vtable ==
nullptr)
330 if (m_vtable ==
nullptr)
334 if (other.m_vtable ==
nullptr)
338 if (m_vtable->v_type != other.m_vtable->v_type)
340 return m_vtable->v_type < other.m_vtable->v_type;
343 if (m_vtable->v_less(m_self, other.m_self))
354 if (m_vtable ==
nullptr && other.m_vtable ==
nullptr)
358 if (m_vtable ==
nullptr || other.m_vtable ==
nullptr)
363 if (m_vtable->v_type != other.m_vtable->v_type)
368 return m_vtable->v_equal(m_self, other.m_self);
374 return !(*
this == other);
387 template <
typename V >
390 struct iterator_vtable
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);
400 get_value_f v_get_value = {};
402 advance_f v_advance = {};
403 recede_f v_recede = {};
405 equal_f v_equal = {};
406 delete_f v_delete = {};
410 template <
typename T >
411 static constexpr iterator_vtable vtable = {
412 .v_get_value = [](
void* self) -> V
const&
414 return **
static_cast< T*
>(self);
416 .v_copy = [](
void const* self) ->
void*
418 return new T(*
static_cast< T const*
>(self));
420 .v_advance = [](
void* self) ->
void
422 ++(*
static_cast< T*
>(self));
424 .v_recede = [](
void* self) ->
void
426 --(*
static_cast< T*
>(self));
429 .v_equal = [](
void const* self,
void const* other) ->
bool
431 return *
static_cast< T const*
>(self) == *
static_cast< T const*
>(other);
433 .v_delete = [](
void* self) ->
void
435 delete static_cast< T*
>(self);
440 iterator_vtable
const* m_vtable;
450 template <
typename It >
463 other.m_vtable =
nullptr;
464 other.m_self =
nullptr;
475 void* copy = other.m_vtable ==
nullptr ? nullptr : other.m_vtable->v_copy(other.m_self);
477 if (m_vtable !=
nullptr)
479 m_vtable->v_delete(m_self);
482 m_vtable = other.m_vtable;
495 if (m_vtable !=
nullptr)
497 m_vtable->v_delete(m_self);
500 m_vtable = other.m_vtable;
501 m_self = other.m_self;
502 other.m_vtable =
nullptr;
503 other.m_self =
nullptr;
509 if (m_vtable !=
nullptr)
511 m_vtable->v_delete(m_self);
518 return m_vtable->v_get_value(m_self);
524 m_vtable->v_advance(m_self);
532 m_vtable->v_advance(m_self);
539 m_vtable->v_recede(m_self);
547 m_vtable->v_recede(m_self);
577 if (m_vtable ==
nullptr && other.m_vtable ==
nullptr)
581 if (m_vtable ==
nullptr || other.m_vtable ==
nullptr)
586 if (m_vtable->v_type != other.m_vtable->v_type)
591 return m_vtable->v_equal(m_self, other.m_self);
597 return !(*
this == other);
602 template <
typename V >
635 template <
typename V >
638 struct iterator_vtable
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);
645 set_output_f v_set_output = {};
647 advance_f v_advance = {};
648 delete_f v_delete = {};
652 template <
typename T >
653 static constexpr iterator_vtable vtable = {
655 [](
void* self, V
const& value)
657 *(*
static_cast< T*
>(self)) = value;
659 .v_copy = [](
void const* self) ->
void*
661 return new T(*
static_cast< T const*
>(self));
663 .v_advance = [](
void* self) ->
void
665 ++(*
static_cast< T*
>(self));
667 .v_delete = [](
void* self) ->
void
669 delete static_cast< T*
>(self);
674 iterator_vtable
const* m_vtable;
683 m_self->m_vtable->v_set_output(m_self->m_self, value);
694 template <
typename It >
702 other.m_vtable =
nullptr;
703 other.m_self =
nullptr;
712 template <
typename It >
715 auto vt = &vtable< It >;
716 auto self =
new It(std::move(it));
720 m_vtable->v_delete(m_self);
737 if (other.m_vtable ==
nullptr)
741 m_vtable->v_delete(m_self);
747 auto copy = other.m_vtable->v_copy(other.m_self);
751 m_vtable->v_delete(m_self);
754 m_vtable = other.m_vtable;
768 if (other.m_vtable ==
nullptr)
772 m_vtable->v_delete(m_self);
781 m_vtable->v_delete(m_self);
784 m_vtable = other.m_vtable;
785 m_self = other.m_self;
786 other.m_vtable =
nullptr;
787 other.m_self =
nullptr;
800 if (other.m_vtable ==
nullptr)
804 m_vtable->v_delete(m_self);
810 auto copy = other.m_vtable->v_copy(other.m_self);
814 m_vtable->v_delete(m_self);
817 m_vtable = other.m_vtable;
826 return proxy{.m_self =
this};
832 m_vtable->v_advance(m_self);
840 m_vtable->v_advance(m_self);
848 m_vtable->v_delete(m_self);
860 void* (*v_copy)(
void* self);
861 void (*v_destroy)(
void* self);
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