CodePorting.Translator Cs2Cpp
CodePorting.Translator.Cs2Cpp.Framework
virtualized_iterator.h
1
2#pragma once
3
4#include <iterator>
5#include <utility>
6#include <memory>
7#include <system/diagnostics/debug.h>
8#include <type_traits>
9#include <cstring>
10#include <limits>
11
12#include <system/exceptions.h>
13#include <system/smart_ptr.h>
14#include <defines.h>
15
16namespace System { namespace Collections { namespace Generic {
17
18template <typename T> class IEnumerable;
19
20}}} // namespace System::Collections::Generic
21
22namespace System { namespace Details {
23
27template <typename Element>
28class VirtualizedIteratorBase
29{
30public:
32 virtual ~VirtualizedIteratorBase() = default;
36 virtual Element OffsetDereferenceIterator(std::ptrdiff_t offset) const
37 {
38 ASPOSE_UNUSED(offset);
39 throw System::NotImplementedException(u"Iterator offset dereference");
40 }
44 virtual void OffsetDereferenceAssignIterator(std::ptrdiff_t offset, const Element &value) const
45 {
46 ASPOSE_UNUSED(offset);
47 ASPOSE_UNUSED(value);
48 throw System::NotImplementedException(u"Iterator offset assignment");
49 }
53 virtual void OffsetDereferenceAssignIterator(std::ptrdiff_t offset, Element &&value) const
54 {
55 ASPOSE_UNUSED(offset);
56 ASPOSE_UNUSED(value);
57 throw System::NotImplementedException(u"Iterator offset assignment");
58 }
61 virtual void IncrementIterator() = 0;
64 virtual void DecrementIterator()
65 {
66 throw System::NotImplementedException(u"Iterator decrement");
67 }
71 virtual void ShiftIteratorBy(std::ptrdiff_t offset)
72 {
73 ASPOSE_UNUSED(offset);
74 throw System::NotImplementedException(u"Iterator offset shift");
75 }
79 virtual bool IteratorEquals(VirtualizedIteratorBase *other) const = 0;
83 virtual bool IteratorLess(VirtualizedIteratorBase *other) const
84 {
85 ASPOSE_UNUSED(other);
86 throw System::NotImplementedException(u"Iterator less-comparison");
87 }
91 virtual std::ptrdiff_t DiffIterators(VirtualizedIteratorBase *other) const
92 {
93 ASPOSE_UNUSED(other);
94 throw System::NotImplementedException(u"Iterator subtraction");
95 }
98 virtual VirtualizedIteratorBase* CloneIterator() const = 0;
99
102 bool AssignsContainerValue() const
103 {
104 return m_points_to_container_element;
105 }
108 bool IsEndIterator() const
109 {
110 return m_is_end;
111 }
114 Element* GetElementPointer() const
115 {
116 return m_pointer;
117 }
118
119 VirtualizedIteratorBase(const VirtualizedIteratorBase&) = delete;
120 VirtualizedIteratorBase(VirtualizedIteratorBase&&) = delete;
121 VirtualizedIteratorBase& operator = (const VirtualizedIteratorBase&) = delete;
122 VirtualizedIteratorBase& operator = (VirtualizedIteratorBase&&) = delete;
123
124protected:
128 VirtualizedIteratorBase(bool points_to_container_element, bool is_end_iterator)
129 : m_points_to_container_element(points_to_container_element)
130 , m_is_end(is_end_iterator)
131 {}
132
134 const bool m_points_to_container_element;
136 bool m_is_end;
138 Element *m_pointer;
139};
140
141
145template <typename Iterator>
146struct UnderlyingIteratorExtractor
147{
149 using type = Iterator;
150};
154template <typename Iterator>
155struct UnderlyingIteratorExtractor<std::reverse_iterator<Iterator>>
156{
158 using type = Iterator;
159};
162template <typename Iterator>
163using UnderlyingIteratorType = typename UnderlyingIteratorExtractor<typename std::remove_cv<typename std::remove_reference<Iterator>::type>::type>::type;
164
165
170template <typename Iterator, typename Value, typename = void>
171struct IteratorOffsetDereferencer
172{
175 static Value get(const Iterator&, std::ptrdiff_t)
176 {
177 throw System::NotSupportedException(u"Iterator offset dereference");
178 }
179};
184template <typename Iterator, typename Value>
185struct IteratorOffsetDereferencer<Iterator, Value, decltype(std::declval<const UnderlyingIteratorType<Iterator>>()[std::declval<std::ptrdiff_t>()], (void)0)>
186{
191 static Value get(const Iterator &iterator, std::ptrdiff_t offset)
192 {
193 return iterator[offset];
194 }
195};
196
201template <typename Iterator, typename Value, typename = void>
202struct IteratorOffsetAssigner
203{
206 static void assign(const Iterator&, std::ptrdiff_t, const Value&)
207 {
208 throw System::NotSupportedException(u"Iterator offset assignment");
209 }
210};
215template <typename Iterator, typename Value>
216struct IteratorOffsetAssigner<Iterator, Value, decltype((void)(std::declval<const UnderlyingIteratorType<Iterator>>()[std::declval<std::ptrdiff_t>()] = std::declval<Value>()))>
217{
222 static void assign(const Iterator &iterator, std::ptrdiff_t offset, const Value &value)
223 {
224 iterator[offset] = value;
225 }
230 static void assign(const Iterator &iterator, std::ptrdiff_t offset, Value &&value)
231 {
232 iterator[offset] = std::move(value);
233 }
234};
235
239template <typename Iterator, typename = void>
240struct IteratorDecrementer
241{
244 static void decrement(Iterator&)
245 {
246 throw System::NotSupportedException(u"Iterator decrement");
247 }
248};
252template <typename Iterator>
253struct IteratorDecrementer<Iterator, decltype(--std::declval<UnderlyingIteratorType<Iterator>>(), (void)0)>
254{
257 static void decrement(Iterator &iterator)
258 {
259 --iterator;
260 }
261};
262
266template <typename Iterator, typename = void>
267struct IteratorShifter
268{
271 static void shift(Iterator&, std::ptrdiff_t)
272 {
273 throw System::NotSupportedException(u"Iterator decrement");
274 }
275};
279template <typename Iterator>
280struct IteratorShifter<Iterator, decltype(std::declval<UnderlyingIteratorType<Iterator>>() += std::declval<std::ptrdiff_t>(), (void)0)>
281{
285 static void shift(Iterator &iterator, std::ptrdiff_t offset)
286 {
287 iterator += offset;
288 }
289};
290
294template <typename Iterator, typename = void>
295struct IteratorDiffer
296{
299 static std::ptrdiff_t diff(const Iterator&, const Iterator&)
300 {
301 throw System::NotSupportedException(u"Iterator difference");
302 }
303};
307template <typename Iterator>
308struct IteratorDiffer<Iterator, decltype(std::declval<UnderlyingIteratorType<Iterator>>() - std::declval<UnderlyingIteratorType<Iterator>>(), (void)0)>
309{
314 static std::ptrdiff_t diff(const Iterator &lhs, const Iterator &rhs)
315 {
316 return lhs - rhs;
317 }
318};
319
323template <typename Iterator, typename = void>
324struct IteratorLessComparer
325{
328 static bool less(const Iterator&, const Iterator&)
329 {
330 throw System::NotSupportedException(u"Iterator less-comparison");
331 }
332};
336template <typename Iterator>
337struct IteratorLessComparer<Iterator, decltype(std::declval<UnderlyingIteratorType<Iterator>>() < std::declval<UnderlyingIteratorType<Iterator>>(), (void)0)>
338{
343 static bool less(const Iterator &lhs, const Iterator &rhs)
344 {
345 return lhs < rhs;
346 }
347};
348
349
354template <typename Element, bool iterator_provides_direct_reference,
355 bool = std::is_arithmetic<Element>::value || std::is_enum<Element>::value || IsSmartPtr<Element>::value || System::detail::is_a<Element, System::ExceptionWrapper>::value>
356struct IteratorPointerUpdater
357{
359 void InitializeIteratorPointer(Element*&)
360 {}
365 void UpdateIteratorPointer(Element *&pointer, Element &value)
366 {
367 pointer = &value;
368 }
373 void UpdateIteratorPointer(Element *&pointer, const Element &value)
374 {
375 // This is to make const iterators compatible with VirtualizedIteratorBase interface and to avoid having separate VirtualizedConstIteratorBase one.
376 // Actually, this pointer will never be used as a non-const for const iterators.
377 pointer = const_cast<Element*>(&value);
378 }
379};
380
385template <typename Element>
386struct IteratorPointerUpdater<Element, false, true>
387{
390 void InitializeIteratorPointer(Element *&pointer)
391 {
392 pointer = &m_cache;
393 }
397 void UpdateIteratorPointer(Element*&, const Element &value)
398 {
399 m_cache = value;
400 }
404 void UpdateIteratorPointer(Element*&, Element &&value)
405 {
406 m_cache = std::move(value);
407 }
408
413 Element* HoldTemporaryObject(Element &&value)
414 {
415 m_cache = std::move(value);
416 return &m_cache;
417 }
422 Element* HoldTemporaryObject(const Element &value)
423 {
424 m_cache = value;
425 return &m_cache;
426 }
431 Element* HoldIfTemporary(Element &&value)
432 {
433 m_cache = std::move(value);
434 return &m_cache;
435 }
440 Element* HoldIfTemporary(const Element &value)
441 {
442 m_cache = value;
443 return &m_cache;
444 }
448 Element* HoldIfTemporary(Element &value)
449 {
450 return &value;
451 }
452
457 const Element& HoldAndGetReference(Element &&value) const
458 {
459 m_cache = std::move(value);
460 return m_cache;
461 }
466 const Element& HoldAndGetReference(const Element &value) const
467 {
468 m_cache = value;
469 return m_cache;
470 }
475 const Element& HoldIfTemporaryAndGetReference(Element &&value) const
476 {
477 m_cache = std::move(value);
478 return m_cache;
479 }
484 const Element& HoldIfTemporaryAndGetReference(const Element &value) const
485 {
486 return value;
487 }
488
489private:
491 mutable Element m_cache;
492};
493
498template <typename Element>
499struct IteratorPointerUpdater<Element, false, false>
500{
502 IteratorPointerUpdater() = default;
504 IteratorPointerUpdater(const IteratorPointerUpdater &)
505 : m_allocated(false)
506 {}
508 ~IteratorPointerUpdater()
509 {
510 if (m_allocated)
511 reinterpret_cast<Element&>(m_cache).~Element();
512 }
515 void InitializeIteratorPointer(Element *&pointer)
516 {
517 pointer = reinterpret_cast<Element*>(&m_cache);
518 }
522 void UpdateIteratorPointer(Element*&, const Element &value)
523 {
524 if (!m_allocated)
525 {
526 new (reinterpret_cast<Element*>(&m_cache)) Element(value);
527 m_allocated = true;
528 }
529 else
530 {
531 reinterpret_cast<Element&>(m_cache) = value;
532 }
533 }
537 void UpdateIteratorPointer(Element*&, Element &&value)
538 {
539 if (!m_allocated)
540 {
541 new (reinterpret_cast<Element*>(&m_cache)) Element(std::move(value));
542 m_allocated = true;
543 }
544 else
545 {
546 reinterpret_cast<Element&>(m_cache) = std::move(value);
547 }
548 }
549
554 Element* HoldTemporaryObject(Element &&value)
555 {
556 if (!m_allocated)
557 {
558 new (reinterpret_cast<Element*>(&m_cache)) Element(std::move(value));
559 m_allocated = true;
560 }
561 else
562 {
563 reinterpret_cast<Element&>(m_cache) = std::move(value);
564 }
565 return reinterpret_cast<Element*>(&m_cache);
566 }
571 Element* HoldTemporaryObject(const Element &value)
572 {
573 if (!m_allocated)
574 {
575 new (reinterpret_cast<Element*>(&m_cache)) Element(value);
576 m_allocated = true;
577 }
578 else
579 {
580 reinterpret_cast<Element&>(m_cache) = value;
581 }
582 return reinterpret_cast<Element*>(&m_cache);
583 }
588 Element* HoldIfTemporary(Element &&value)
589 {
590 if (!m_allocated)
591 {
592 new (reinterpret_cast<Element*>(&m_cache)) Element(std::move(value));
593 m_allocated = true;
594 }
595 else
596 {
597 reinterpret_cast<Element&>(m_cache) = std::move(value);
598 }
599 return reinterpret_cast<Element*>(&m_cache);
600 }
605 Element* HoldIfTemporary(const Element &value)
606 {
607 if (!m_allocated)
608 {
609 new (reinterpret_cast<Element*>(&m_cache)) Element(value);
610 m_allocated = true;
611 }
612 else
613 {
614 reinterpret_cast<Element&>(m_cache) = value;
615 }
616 return reinterpret_cast<Element*>(&m_cache);
617 }
621 Element* HoldIfTemporary(Element &value)
622 {
623 return &value;
624 }
625
630 const Element& HoldAndGetReference(Element &&value) const
631 {
632 if (!m_allocated)
633 {
634 new (reinterpret_cast<Element*>(&m_cache)) Element(std::move(value));
635 m_allocated = true;
636 }
637 else
638 {
639 reinterpret_cast<Element&>(m_cache) = std::move(value);
640 }
641 return *reinterpret_cast<Element*>(&m_cache);
642 }
647 const Element& HoldAndGetReference(const Element &value) const
648 {
649 if (!m_allocated)
650 {
651 new (reinterpret_cast<Element*>(&m_cache)) Element(value);
652 m_allocated = true;
653 }
654 else
655 {
656 reinterpret_cast<Element&>(m_cache) = value;
657 }
658 return *reinterpret_cast<Element*>(&m_cache);
659 }
664 const Element& HoldIfTemporaryAndGetReference(Element &&value) const
665 {
666 if (!m_allocated)
667 {
668 new (reinterpret_cast<Element*>(&m_cache)) Element(std::move(value));
669 m_allocated = true;
670 }
671 else
672 {
673 reinterpret_cast<Element&>(m_cache) = std::move(value);
674 }
675 return *reinterpret_cast<Element*>(&m_cache);
676 }
681 const Element& HoldIfTemporaryAndGetReference(const Element &value) const
682 {
683 return value;
684 }
685
686private:
688 mutable bool m_allocated = false;
690 mutable typename std::aligned_storage<sizeof(Element), alignof(Element)>::type m_cache;
691};
692
693
698template <typename Element, typename Iterator>
699class NativeIteratorWrapperBase : public VirtualizedIteratorBase<Element>
700{
702 static constexpr bool is_pointer_assignable = std::is_same<decltype(*std::declval<Iterator>()), Element&>::value;
703
704public:
708 NativeIteratorWrapperBase(const Iterator &iterator, const Iterator &end)
709 : VirtualizedIteratorBase<Element>(is_pointer_assignable, iterator == end)
710 , m_iterator(iterator)
711 , m_end(end)
712 {}
716 NativeIteratorWrapperBase(Iterator &&iterator, Iterator &&end) noexcept
717 : VirtualizedIteratorBase<Element>(is_pointer_assignable, iterator == end)
718 , m_iterator(std::forward<Iterator>(iterator))
719 , m_end(std::forward<Iterator>(end))
720 {}
722 virtual ~NativeIteratorWrapperBase() = default;
724 bool IteratorEquals(VirtualizedIteratorBase<Element> *other) const override
725 {
726 CODEPORTING_DEBUG_ASSERT(dynamic_cast<NativeIteratorWrapperBase*>(other) != nullptr);
727 return m_iterator == static_cast<NativeIteratorWrapperBase*>(other)->m_iterator;
728 }
730 bool IteratorLess(VirtualizedIteratorBase<Element> *other) const override
731 {
732 CODEPORTING_DEBUG_ASSERT(dynamic_cast<NativeIteratorWrapperBase*>(other) != nullptr);
733 return IteratorLessComparer<Iterator>::less(m_iterator, static_cast<NativeIteratorWrapperBase*>(other)->m_iterator);
734 }
736 std::ptrdiff_t DiffIterators(VirtualizedIteratorBase<Element> *other) const override
737 {
738 CODEPORTING_DEBUG_ASSERT(dynamic_cast<NativeIteratorWrapperBase*>(other) != nullptr);
739 return IteratorDiffer<Iterator>::diff(m_iterator, static_cast<NativeIteratorWrapperBase*>(other)->m_iterator);
740 }
741
742 NativeIteratorWrapperBase(const NativeIteratorWrapperBase&) = delete;
743 NativeIteratorWrapperBase(NativeIteratorWrapperBase&&) = delete;
744
745protected:
747 Iterator m_iterator;
749 const Iterator m_end;
750
753 bool IteratorIncrementImplementation()
754 {
755 ++m_iterator;
756 VirtualizedIteratorBase<Element>::m_is_end = m_iterator == m_end;
757 if (VirtualizedIteratorBase<Element>::m_is_end)
758 VirtualizedIteratorBase<Element>::m_pointer = nullptr;
759 return !VirtualizedIteratorBase<Element>::m_is_end;
760 }
764 bool IteratorShiftImplementation(std::ptrdiff_t offset)
765 {
766 IteratorShifter<Iterator>::shift(m_iterator, offset);
767 VirtualizedIteratorBase<Element>::m_is_end = m_iterator == m_end;
768 if (VirtualizedIteratorBase<Element>::m_is_end)
769 VirtualizedIteratorBase<Element>::m_pointer = nullptr;
770 return !VirtualizedIteratorBase<Element>::m_is_end;
771 }
772};
773
774
778template <typename Element, typename Iterator>
779class NativeIteratorWrapper
780 : public NativeIteratorWrapperBase<Element, Iterator>
781 , private IteratorPointerUpdater<Element, std::is_same<Element&, decltype(*std::declval<Iterator>())>::value>
782{
783 // Parent members to use.
784 using NativeIteratorWrapperBase<Element, Iterator>::m_iterator;
785 using NativeIteratorWrapperBase<Element, Iterator>::m_end;
786 using VirtualizedIteratorBase<Element>::m_pointer;
787 using IteratorPointerUpdater<Element, std::is_same<Element&, decltype(*std::declval<Iterator>())>::value>::InitializeIteratorPointer;
788 using IteratorPointerUpdater<Element, std::is_same<Element&, decltype(*std::declval<Iterator>())>::value>::UpdateIteratorPointer;
789
790public:
794 NativeIteratorWrapper(const Iterator &iterator, const Iterator &end)
795 : NativeIteratorWrapperBase<Element, Iterator>(iterator, end)
796 {
797 InitializeIteratorPointer(m_pointer);
798 if (!VirtualizedIteratorBase<Element>::IsEndIterator())
799 UpdateIteratorPointer(m_pointer, *m_iterator);
800 }
804 NativeIteratorWrapper(Iterator &&iterator, Iterator &&end) noexcept
805 : NativeIteratorWrapperBase<Element, Iterator>(std::forward<Iterator>(iterator), std::forward<Iterator>(end))
806 {
807 InitializeIteratorPointer(m_pointer);
808 if (!VirtualizedIteratorBase<Element>::IsEndIterator())
809 UpdateIteratorPointer(m_pointer, *m_iterator);
810 }
812 virtual ~NativeIteratorWrapper() = default;
814 void IncrementIterator() override
815 {
816 if (NativeIteratorWrapperBase<Element, Iterator>::IteratorIncrementImplementation())
817 UpdateIteratorPointer(m_pointer, *m_iterator);
818 }
820 void DecrementIterator() override
821 {
822 IteratorDecrementer<Iterator>::decrement(m_iterator);
823 VirtualizedIteratorBase<Element>::m_is_end = false;
824 UpdateIteratorPointer(m_pointer, *m_iterator);
825 }
827 void ShiftIteratorBy(std::ptrdiff_t offset) override
828 {
829 if (NativeIteratorWrapperBase<Element, Iterator>::IteratorShiftImplementation(offset))
830 UpdateIteratorPointer(m_pointer, *m_iterator);
831 }
833 Element OffsetDereferenceIterator(std::ptrdiff_t offset) const override
834 {
835 return IteratorOffsetDereferencer<Iterator, Element>::get(m_iterator, offset);
836 }
838 void OffsetDereferenceAssignIterator(std::ptrdiff_t offset, const Element &value) const override
839 {
840 IteratorOffsetAssigner<Iterator, Element>::assign(m_iterator, offset, value);
841 }
843 void OffsetDereferenceAssignIterator(std::ptrdiff_t offset, Element &&value) const override
844 {
845 IteratorOffsetAssigner<Iterator, Element>::assign(m_iterator, offset, std::move(value));
846 }
848 VirtualizedIteratorBase<Element>* CloneIterator() const override
849 {
850 return new NativeIteratorWrapper(m_iterator, m_end);
851 }
852
853 NativeIteratorWrapper(NativeIteratorWrapper&&) = delete;
854
855private:
858 NativeIteratorWrapper(const NativeIteratorWrapper &other)
859 : NativeIteratorWrapper(other.m_iterator, other.VirtualizedIteratorBase<Element>::m_end)
860 {}
861};
862
866template <typename Element, typename Iterator>
867class NativeConstIteratorWrapper
868 : public NativeIteratorWrapperBase<Element, Iterator>
869 , private IteratorPointerUpdater<Element, std::is_same<Element&, decltype(*std::declval<Iterator>())>::value || std::is_same<const Element&, decltype(*std::declval<Iterator>())>::value>
870{
871 // Parent members to use.
872 using NativeIteratorWrapperBase<Element, Iterator>::m_iterator;
873 using NativeIteratorWrapperBase<Element, Iterator>::m_end;
874 using VirtualizedIteratorBase<Element>::m_pointer;
875 using IteratorPointerUpdater<Element, std::is_same<Element&, decltype(*std::declval<Iterator>())>::value || std::is_same<const Element&, decltype(*std::declval<Iterator>())>::value>
876 ::InitializeIteratorPointer;
877 using IteratorPointerUpdater<Element, std::is_same<Element&, decltype(*std::declval<Iterator>())>::value || std::is_same<const Element&, decltype(*std::declval<Iterator>())>::value>
878 ::UpdateIteratorPointer;
879
880public:
884 NativeConstIteratorWrapper(const Iterator &iterator, const Iterator &end)
885 : NativeIteratorWrapperBase<Element, Iterator>(iterator, end)
886 {
887 InitializeIteratorPointer(m_pointer);
888 if (!VirtualizedIteratorBase<Element>::IsEndIterator())
889 UpdateIteratorPointer(m_pointer, *m_iterator);
890 }
894 NativeConstIteratorWrapper(Iterator &&iterator, Iterator &&end) noexcept
895 : NativeIteratorWrapperBase<Element, Iterator>(std::forward<Iterator>(iterator), std::forward<Iterator>(end))
896 {
897 InitializeIteratorPointer(m_pointer);
898 if (!VirtualizedIteratorBase<Element>::IsEndIterator())
899 UpdateIteratorPointer(m_pointer, *m_iterator);
900 }
902 virtual ~NativeConstIteratorWrapper() = default;
904 void IncrementIterator() override
905 {
906 if (NativeIteratorWrapperBase<Element, Iterator>::IteratorIncrementImplementation())
907 UpdateIteratorPointer(m_pointer, *m_iterator);
908 }
910 void DecrementIterator() override
911 {
912 IteratorDecrementer<Iterator>::decrement(m_iterator);
913 VirtualizedIteratorBase<Element>::m_is_end = false;
914 UpdateIteratorPointer(m_pointer, *m_iterator);
915 }
917 void ShiftIteratorBy(std::ptrdiff_t offset) override
918 {
919 if (NativeIteratorWrapperBase<Element, Iterator>::IteratorShiftImplementation(offset))
920 UpdateIteratorPointer(m_pointer, *m_iterator);
921 }
923 Element OffsetDereferenceIterator(std::ptrdiff_t offset) const override
924 {
925 return IteratorOffsetDereferencer<Iterator, Element>::get(m_iterator, offset);
926 }
928 void OffsetDereferenceAssignIterator(std::ptrdiff_t, const Element&) const override
929 {
930 throw System::NotSupportedException(u"Assigning element through const iterator");
931 }
933 void OffsetDereferenceAssignIterator(std::ptrdiff_t, Element&&) const override
934 {
935 throw System::NotSupportedException(u"Assigning element through const iterator");
936 }
938 VirtualizedIteratorBase<Element>* CloneIterator() const override
939 {
940 return new NativeConstIteratorWrapper(m_iterator, m_end);
941 }
942
943 NativeConstIteratorWrapper(NativeConstIteratorWrapper&&) = delete;
944
945private:
948 NativeConstIteratorWrapper(const NativeConstIteratorWrapper& other)
949 : NativeConstIteratorWrapper(other.m_iterator, other.VirtualizedIteratorBase<Element>::m_end)
950 {}
951};
952
953
956template <typename Element>
957class EnumeratorBasedIterator : public VirtualizedIteratorBase<Element>
958{
959public:
961 virtual ~EnumeratorBasedIterator() = default;
962
964 bool IteratorEquals(VirtualizedIteratorBase<Element> *other) const override
965 {
966 CODEPORTING_DEBUG_ASSERT(dynamic_cast<EnumeratorBasedIterator*>(other) != nullptr);
967 return static_cast<EnumeratorBasedIterator*>(other)->m_offset == m_offset;
968 }
970 bool IteratorLess(VirtualizedIteratorBase<Element> *other) const override
971 {
972 CODEPORTING_DEBUG_ASSERT(dynamic_cast<EnumeratorBasedIterator*>(other) != nullptr);
973 return static_cast<EnumeratorBasedIterator*>(other)->m_offset > m_offset;
974 }
976 virtual void InitializeIterator()
977 {}
978
979protected:
981 EnumeratorBasedIterator()
982 : VirtualizedIteratorBase<Element>(false, true)
983 , m_offset(std::numeric_limits<std::ptrdiff_t>::max())
984 {}
987 EnumeratorBasedIterator(std::ptrdiff_t offset)
988 : VirtualizedIteratorBase<Element>(false, offset == std::numeric_limits<std::ptrdiff_t>::max())
989 , m_offset(offset)
990 {}
992 EnumeratorBasedIterator(const EnumeratorBasedIterator &other)
993 : VirtualizedIteratorBase<Element>(false, other.m_offset == std::numeric_limits<std::ptrdiff_t>::max())
994 , m_offset(other.m_offset)
995 {}
996
998 std::ptrdiff_t m_offset;
999};
1000
1003template <typename Element>
1004class EnumeratorBasedEndIterator : public EnumeratorBasedIterator<Element>
1005{
1006public:
1008 EnumeratorBasedEndIterator()
1009 : EnumeratorBasedIterator<Element>(std::numeric_limits<std::ptrdiff_t>::max())
1010 {}
1012 virtual ~EnumeratorBasedEndIterator() = default;
1013
1015 void IncrementIterator() override
1016 {
1017 throw InvalidOperationException(u"Moving past the container's end");
1018 }
1020 System::Details::VirtualizedIteratorBase<Element>* CloneIterator() const override
1021 {
1022 return new EnumeratorBasedEndIterator();
1023 }
1024};
1025
1026
1030template <typename Element>
1031class VirtualizedIteratorOffsetPointer
1032{
1033public:
1037 VirtualizedIteratorOffsetPointer(VirtualizedIteratorBase<Element> *iterator, std::ptrdiff_t offset)
1038 : m_value(iterator->OffsetDereferenceIterator(offset))
1039 {}
1042 VirtualizedIteratorOffsetPointer(VirtualizedIteratorOffsetPointer &&other) noexcept
1043 : m_value(std::move(other.m_value))
1044 {}
1045
1048 decltype(std::declval<Element>().operator ->()) operator -> () const
1049 {
1050 return m_value.operator ->();
1051 }
1052
1053 VirtualizedIteratorOffsetPointer(const VirtualizedIteratorOffsetPointer&) = delete;
1054 VirtualizedIteratorOffsetPointer& operator = (const VirtualizedIteratorOffsetPointer&) = delete;
1055 VirtualizedIteratorOffsetPointer& operator = (VirtualizedIteratorOffsetPointer&&) = delete;
1056
1057private:
1059 Element m_value;
1060};
1061
1064template <typename Element>
1065class VirtualizedIteratorOffsetReference
1066{
1067public:
1071 VirtualizedIteratorOffsetReference(VirtualizedIteratorBase<Element> *iterator, std::ptrdiff_t offset)
1072 : m_iterator(iterator), m_offset(offset)
1073 {}
1075 VirtualizedIteratorOffsetReference(const VirtualizedIteratorOffsetReference&) = default;
1077 VirtualizedIteratorOffsetReference(VirtualizedIteratorOffsetReference&&) noexcept = default;
1078
1081 operator Element () const
1082 {
1083 if (m_offset == 0)
1084 return *m_iterator->GetElementPointer();
1085 else
1086 return m_iterator->OffsetDereferenceIterator(m_offset);
1087 }
1091 VirtualizedIteratorOffsetReference& operator = (const Element &value)
1092 {
1093 m_iterator->OffsetDereferenceAssignIterator(m_offset, value);
1094 return *this;
1095 }
1099 VirtualizedIteratorOffsetReference& operator = (Element &&value)
1100 {
1101 m_iterator->OffsetDereferenceAssignIterator(m_offset, std::move(value));
1102 return *this;
1103 }
1106 VirtualizedIteratorOffsetPointer<Element> operator -> () const
1107 {
1108 return VirtualizedIteratorOffsetPointer<Element>(m_iterator, m_offset);
1109 }
1110
1111 VirtualizedIteratorOffsetReference& operator = (const VirtualizedIteratorOffsetReference&) = delete;
1112 VirtualizedIteratorOffsetReference& operator = (VirtualizedIteratorOffsetReference&&) = delete;
1113
1114private:
1116 VirtualizedIteratorBase<Element> *const m_iterator;
1118 const std::ptrdiff_t m_offset;
1119};
1120
1121
1122template <typename Element> class VirtualizedConstIterator;
1123
1158template <typename Element>
1159class VirtualizedIterator : public BaseIterator<std::random_access_iterator_tag, Element, std::ptrdiff_t, Element*, Element&>
1160{
1161public:
1164 VirtualizedIterator() = default;
1167 VirtualizedIterator(const VirtualizedIterator &other)
1168 : m_iterator(other.m_iterator->CloneIterator())
1169 {}
1172 VirtualizedIterator(VirtualizedIterator &&other) noexcept
1173 : m_iterator(other.m_iterator.release())
1174 {}
1177 explicit VirtualizedIterator(VirtualizedIteratorBase<Element> *virtualizedIterator)
1178 : m_iterator(virtualizedIterator)
1179 {}
1180
1183 VirtualizedIterator& operator = (const VirtualizedIterator &other)
1184 {
1185 m_iterator.reset(other.m_iterator->CloneIterator());
1186 return *this;
1187 }
1190 VirtualizedIterator& operator = (VirtualizedIterator &&other) noexcept
1191 {
1192 m_iterator = std::move(other.m_iterator);
1193 return *this;
1194 }
1195
1198 VirtualizedIterator& operator ++ ()
1199 {
1200 m_iterator->IncrementIterator();
1201 return *this;
1202 }
1205 VirtualizedIterator& operator -- ()
1206 {
1207 m_iterator->DecrementIterator();
1208 return *this;
1209 }
1212 VirtualizedIterator operator ++ (int)
1213 {
1214 VirtualizedIterator copy(*this);
1215 operator++();
1216 return copy;
1217 }
1220 VirtualizedIterator operator -- (int)
1221 {
1222 VirtualizedIterator copy(*this);
1223 operator --();
1224 return copy;
1225 }
1226
1230 VirtualizedIterator& operator += (std::ptrdiff_t offset)
1231 {
1232 m_iterator->ShiftIteratorBy(offset);
1233 return *this;
1234 }
1238 VirtualizedIterator& operator -= (std::ptrdiff_t offset)
1239 {
1240 m_iterator->ShiftIteratorBy(-offset);
1241 return *this;
1242 }
1246 VirtualizedIterator operator + (std::ptrdiff_t offset) const
1247 {
1248 VirtualizedIterator copy(*this);
1249 copy += offset;
1250 return copy;
1251 }
1255 VirtualizedIterator operator - (std::ptrdiff_t offset) const
1256 {
1257 VirtualizedIterator copy(*this);
1258 copy -= offset;
1259 return copy;
1260 }
1264 std::ptrdiff_t operator - (const VirtualizedIterator &other) const
1265 {
1266 return m_iterator->DiffIterators(other.m_iterator.get());
1267 }
1268
1271 Element& operator * () const
1272 {
1273 return *m_iterator->GetElementPointer();
1274 }
1277 Element* operator -> () const
1278 {
1279 return m_iterator->GetElementPointer();
1280 }
1284 VirtualizedIteratorOffsetReference<Element> operator [] (std::ptrdiff_t offset) const
1285 {
1286 return VirtualizedIteratorOffsetReference<Element>(m_iterator.get(), offset);
1287 }
1288
1292 bool operator == (const VirtualizedIterator &other) const
1293 {
1294 if (m_iterator->IsEndIterator() != other.m_iterator->IsEndIterator())
1295 return false;
1296 else if (m_iterator->IsEndIterator())
1297 return true;
1298 else
1299 return m_iterator->IteratorEquals(other.m_iterator.get());
1300 }
1304 bool operator != (const VirtualizedIterator &other) const
1305 {
1306 if (m_iterator->IsEndIterator() != other.m_iterator->IsEndIterator())
1307 return true;
1308 else if (m_iterator->IsEndIterator())
1309 return false;
1310 else
1311 return !m_iterator->IteratorEquals(other.m_iterator.get());
1312 }
1316 bool operator < (const VirtualizedIterator &other) const
1317 {
1318 if (other.m_iterator->IsEndIterator())
1319 return !m_iterator->IsEndIterator();
1320 else
1321 return m_iterator->IteratorLess(other.m_iterator.get());
1322 }
1326 bool operator >= (const VirtualizedIterator &other) const
1327 {
1328 return !(*this < other);
1329 }
1333 bool operator > (const VirtualizedIterator &other) const
1334 {
1335 return other < *this;
1336 }
1340 bool operator <= (const VirtualizedIterator &other) const
1341 {
1342 return !(other < *this);
1343 }
1344
1347 void swap(VirtualizedIterator &other)
1348 {
1349 std::swap(m_iterator, other.m_iterator);
1350 }
1351
1352private:
1354 std::unique_ptr<VirtualizedIteratorBase<std::remove_const_t<Element>>> m_iterator;
1355
1356 friend class VirtualizedConstIterator<Element>;
1357};
1358
1394template <typename Element>
1395class VirtualizedConstIterator : public BaseIterator<std::random_access_iterator_tag, Element, std::ptrdiff_t, const Element*, const Element&>
1396{
1397public:
1400 VirtualizedConstIterator()
1401 : m_iterator(nullptr)
1402 {}
1405 VirtualizedConstIterator(const VirtualizedConstIterator &other)
1406 : m_iterator(other.m_iterator->CloneIterator())
1407 {}
1410 VirtualizedConstIterator(VirtualizedConstIterator &&other) noexcept
1411 : m_iterator(other.m_iterator.release())
1412 {}
1415 VirtualizedConstIterator(const VirtualizedIterator<Element> &other)
1416 : m_iterator(other.m_iterator->CloneIterator())
1417 {}
1420 VirtualizedConstIterator(VirtualizedIterator<Element> &&other) noexcept
1421 : m_iterator(other.m_iterator.release())
1422 {}
1425 explicit VirtualizedConstIterator(VirtualizedIteratorBase<Element> *virtualizedIterator)
1426 : m_iterator(virtualizedIterator)
1427 {}
1428
1431 VirtualizedConstIterator& operator = (const VirtualizedConstIterator &other)
1432 {
1433 m_iterator.reset(other.m_iterator->CloneIterator());
1434 return *this;
1435 }
1438 VirtualizedConstIterator& operator = (VirtualizedConstIterator &&other) noexcept
1439 {
1440 m_iterator = std::move(other.m_iterator);
1441 return *this;
1442 }
1443
1446 VirtualizedConstIterator& operator ++ ()
1447 {
1448 m_iterator->IncrementIterator();
1449 return *this;
1450 }
1453 VirtualizedConstIterator& operator -- ()
1454 {
1455 m_iterator->DecrementIterator();
1456 return *this;
1457 }
1460 VirtualizedConstIterator operator ++ (int)
1461 {
1462 VirtualizedConstIterator copy(*this);
1463 operator++();
1464 return copy;
1465 }
1468 VirtualizedConstIterator operator -- (int)
1469 {
1470 VirtualizedConstIterator copy(*this);
1471 operator --();
1472 return copy;
1473 }
1474
1478 VirtualizedConstIterator& operator += (std::ptrdiff_t offset)
1479 {
1480 m_iterator->ShiftIteratorBy(offset);
1481 return *this;
1482 }
1486 VirtualizedConstIterator& operator -= (std::ptrdiff_t offset)
1487 {
1488 m_iterator->ShiftIteratorBy(-offset);
1489 return *this;
1490 }
1494 VirtualizedConstIterator operator + (std::ptrdiff_t offset) const
1495 {
1496 VirtualizedConstIterator copy(*this);
1497 copy += offset;
1498 return copy;
1499 }
1503 VirtualizedConstIterator operator - (std::ptrdiff_t offset) const
1504 {
1505 VirtualizedConstIterator copy(*this);
1506 copy -= offset;
1507 return copy;
1508 }
1512 std::ptrdiff_t operator - (const VirtualizedConstIterator &other) const
1513 {
1514 return m_iterator->DiffIterators(other.m_iterator.get());
1515 }
1516
1519 const Element& operator * () const
1520 {
1521 return *m_iterator->GetElementPointer();
1522 }
1525 const Element* operator -> () const
1526 {
1527 return m_iterator->GetElementPointer();
1528 }
1532 Element operator [] (std::ptrdiff_t offset) const
1533 {
1534 if (offset == 0)
1535 return *m_iterator->GetElementPointer();
1536 else
1537 return m_iterator->OffsetDereferenceIterator(offset);
1538 }
1539
1543 bool operator == (const VirtualizedConstIterator &other) const
1544 {
1545 if (m_iterator->IsEndIterator() != other.m_iterator->IsEndIterator())
1546 return false;
1547 else if (m_iterator->IsEndIterator())
1548 return true;
1549 else
1550 return m_iterator->IteratorEquals(other.m_iterator.get());
1551 }
1555 bool operator != (const VirtualizedConstIterator &other) const
1556 {
1557 if (m_iterator->IsEndIterator() != other.m_iterator->IsEndIterator())
1558 return true;
1559 else if (m_iterator->IsEndIterator())
1560 return false;
1561 else
1562 return !m_iterator->IteratorEquals(other.m_iterator.get());
1563 }
1567 bool operator < (const VirtualizedConstIterator &other) const
1568 {
1569 if (other.m_iterator->IsEndIterator())
1570 return !m_iterator->IsEndIterator();
1571 else
1572 return m_iterator->IteratorLess(other.m_iterator.get());
1573 }
1577 bool operator >= (const VirtualizedConstIterator &other) const
1578 {
1579 return !(*this < other);
1580 }
1584 bool operator > (const VirtualizedConstIterator &other) const
1585 {
1586 return other < *this;
1587 }
1591 bool operator <= (const VirtualizedConstIterator &other) const
1592 {
1593 return !(other < *this);
1594 }
1595
1598 void swap(VirtualizedConstIterator &other)
1599 {
1600 std::swap(m_iterator, other.m_iterator);
1601 }
1602
1603private:
1605 std::unique_ptr<VirtualizedIteratorBase<std::remove_const_t<Element>>> m_iterator;
1606};
1607
1613template <typename Element>
1614VirtualizedIterator<Element> operator + (std::ptrdiff_t offset, const VirtualizedIterator<Element> &iterator)
1615{
1616 return iterator + offset;
1617}
1623template <typename Element>
1624VirtualizedConstIterator<Element> operator + (std::ptrdiff_t offset, const VirtualizedConstIterator<Element> &iterator)
1625{
1626 return iterator + offset;
1627}
1628
1629}} // namespace System::Details
1630
1631using System::Details::operator +;
1632
1633namespace std
1634{
1635
1640template <typename Element>
1641void swap(System::Details::VirtualizedIterator<Element> &lhs, System::Details::VirtualizedIterator<Element> &rhs)
1642{
1643 lhs.swap(rhs);
1644}
1649template <typename Element>
1650void swap(System::Details::VirtualizedConstIterator<Element> &lhs, System::Details::VirtualizedConstIterator<Element> &rhs)
1651{
1652 lhs.swap(rhs);
1653}
1654
1655}
@ Element
This value is used for internal purposes and is not intended to be used directly from your code.
Definition: db_command.h:9
bool operator!=(ArraySegment< T > a, ArraySegment< T > b)
Definition: array_segment.h:157
Decimal operator+(const T &x, const Decimal &d)
Returns a new instance of Decimal class that represents a value that is a sum of the specified value ...
Definition: decimal.h:542
constexpr bool operator>(std::nullptr_t, DateTime)
Definition: date_time.h:714
Decimal operator*(const T &x, const Decimal &d)
Returns a new instance of Decimal class that represents a value that is a result of multiplication of...
Definition: decimal.h:556
auto operator-(DayOfWeek a, DayOfWeek b)
Calculates the number of days between two days of week.
Definition: day_of_week.h:25
constexpr bool operator<(std::nullptr_t, DateTime)
Definition: date_time.h:712
constexpr bool operator<=(std::nullptr_t, DateTime)
Definition: date_time.h:713
constexpr bool operator>=(std::nullptr_t, DateTime)
Definition: date_time.h:715
bool operator==(ArraySegment< T > a, ArraySegment< T > b)
Definition: array_segment.h:151
Tests if specific type is a specialization of specific template. If it is, inherits std::true_type,...
Definition: detail.h:80