From fc873328455dfbb6ae9e42595f5970af47b97980 Mon Sep 17 00:00:00 2001 From: Redstone1024 <2824517378@qq.com> Date: Fri, 3 Jan 2025 01:05:35 +0800 Subject: [PATCH] fix(iterators): fix insert iterators to be assignable --- .../Source/Public/Iterators/InsertIterator.h | 61 +++++++++++++++++-- 1 file changed, 56 insertions(+), 5 deletions(-) diff --git a/Redcraft.Utility/Source/Public/Iterators/InsertIterator.h b/Redcraft.Utility/Source/Public/Iterators/InsertIterator.h index 3494c57..9f1a5f2 100644 --- a/Redcraft.Utility/Source/Public/Iterators/InsertIterator.h +++ b/Redcraft.Utility/Source/Public/Iterators/InsertIterator.h @@ -6,6 +6,7 @@ #include "Templates/Utility.h" #include "Templates/Noncopyable.h" #include "Templates/Invoke.h" +#include "Memory/Address.h" #include "Miscellaneous/AssertionMacros.h" NAMESPACE_REDCRAFT_BEGIN @@ -124,27 +125,77 @@ private: static_assert(COutputIterator, int>); +template +class FFrontInserter +{ +public: + + FORCEINLINE constexpr explicit FFrontInserter(C& InContainer) : Container(AddressOf(InContainer)) { } + + template + FORCEINLINE constexpr void operator()(T&& A) { Container->PushFront(Forward(A)); } + +private: + + C* Container; + +}; + +template +class FBackInserter +{ +public: + + FORCEINLINE constexpr explicit FBackInserter(C& InContainer) : Container(AddressOf(InContainer)) { } + + template + FORCEINLINE constexpr void operator()(T&& A) { Container->PushBack(Forward(A)); } + +private: + + C* Container; + +}; + +template +class FInserter +{ +public: + + template + FORCEINLINE constexpr FInserter(C& InContainer, I&& InIter) : Container(AddressOf(InContainer)), Iter(Forward(InIter)) { } + + template + FORCEINLINE constexpr void operator()(T&& A) { Iter = Container->Insert(Iter, Forward(A)); ++Iter; } + +private: + + C* Container; + typename C::FConstIterator Iter; + +}; + NAMESPACE_PRIVATE_END /** Creates an iterator adapter inserted in the front of the container. */ template NODISCARD FORCEINLINE constexpr auto MakeFrontInserter(C& Container) { - return NAMESPACE_PRIVATE::TInsertIterator([&Container](T&& A) { Container.PushFront(Forward(A)); }); + return NAMESPACE_PRIVATE::TInsertIterator(NAMESPACE_PRIVATE::FFrontInserter(Container)); } /** Creates an iterator adapter inserted in the back of the container. */ template NODISCARD FORCEINLINE constexpr auto MakeBackInserter(C& Container) { - return NAMESPACE_PRIVATE::TInsertIterator([&Container](T&& A) { Container.PushBack(Forward(A)); }); + return NAMESPACE_PRIVATE::TInsertIterator(NAMESPACE_PRIVATE::FBackInserter(Container)); } /** Creates an iterator adapter inserted in the container. */ -template -NODISCARD FORCEINLINE constexpr auto MakeInserter(C& Container, const typename C::FConstIterator& InIter) +template +NODISCARD FORCEINLINE constexpr auto MakeInserter(C& Container, I&& InIter) { - return NAMESPACE_PRIVATE::TInsertIterator([&Container, Iter = InIter](T&& A) mutable { Iter = Container.Insert(Iter, Forward(A)); ++Iter; }); + return NAMESPACE_PRIVATE::TInsertIterator(NAMESPACE_PRIVATE::FInserter(Container, Forward(InIter))); } NAMESPACE_MODULE_END(Utility)