refactor(*): refactor the tool library's parent folder to plural form
This commit is contained in:
152
Redcraft.Utility/Source/Public/Iterators/InsertIterator.h
Normal file
152
Redcraft.Utility/Source/Public/Iterators/InsertIterator.h
Normal file
@ -0,0 +1,152 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreTypes.h"
|
||||
#include "TypeTraits/TypeTraits.h"
|
||||
#include "Iterators/Utility.h"
|
||||
#include "Templates/Utility.h"
|
||||
#include "Templates/Noncopyable.h"
|
||||
#include "Templates/Invoke.h"
|
||||
#include "Miscellaneous/AssertionMacros.h"
|
||||
|
||||
NAMESPACE_REDCRAFT_BEGIN
|
||||
NAMESPACE_MODULE_BEGIN(Redcraft)
|
||||
NAMESPACE_MODULE_BEGIN(Utility)
|
||||
|
||||
NAMESPACE_PRIVATE_BEGIN
|
||||
|
||||
template <typename F> class TInsertProxy;
|
||||
template <typename F> class TPostIncrementProxy;
|
||||
template <typename F> class TInsertIterator;
|
||||
|
||||
template <typename F>
|
||||
class TInsertProxy final : private FSingleton
|
||||
{
|
||||
public:
|
||||
|
||||
# if DO_CHECK
|
||||
FORCEINLINE ~TInsertProxy() { checkf(bIsProduced, TEXT("Exception insert, Ensures that the value is assigned to the inserter.")); }
|
||||
# endif
|
||||
|
||||
template <typename T> requires (CInvocable<F, T>)
|
||||
FORCEINLINE constexpr void operator=(T&& InValue) const
|
||||
{
|
||||
checkf(!bIsProduced, TEXT("Exception insert, Ensure that no multiple values are assigned to the inserter."));
|
||||
Invoke(Iter.Storage, Forward<T>(InValue));
|
||||
check_code({ bIsProduced = true; });
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
TInsertIterator<F>& Iter;
|
||||
|
||||
# if DO_CHECK
|
||||
mutable bool bIsProduced;
|
||||
# endif
|
||||
|
||||
FORCEINLINE constexpr TInsertProxy(TInsertIterator<F>& InIter) : Iter(InIter) { check_code({ bIsProduced = false; }); }
|
||||
|
||||
template <typename> friend class TPostIncrementProxy;
|
||||
template <typename> friend class TInsertIterator;
|
||||
};
|
||||
|
||||
static_assert(CAssignableFrom<TInsertProxy<void(*)(int)>, int>);
|
||||
|
||||
template <typename F>
|
||||
class TPostIncrementProxy : private FSingleton
|
||||
{
|
||||
public:
|
||||
|
||||
# if DO_CHECK
|
||||
FORCEINLINE ~TPostIncrementProxy() { checkf(bIsProduced, TEXT("Exception insert, Ensures that the value is assigned to the inserter.")); }
|
||||
# endif
|
||||
|
||||
NODISCARD FORCEINLINE constexpr TInsertProxy<F> operator*() const
|
||||
{
|
||||
checkf(!bIsProduced, TEXT("Exception insert, Ensure that no multiple values are assigned to the inserter."));
|
||||
check_code({ bIsProduced = true; });
|
||||
return TInsertProxy(Iter);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
TInsertIterator<F>& Iter;
|
||||
|
||||
# if DO_CHECK
|
||||
mutable bool bIsProduced;
|
||||
# endif
|
||||
|
||||
FORCEINLINE constexpr TPostIncrementProxy(TInsertIterator<F>& InIter) : Iter(InIter) { check_code({ bIsProduced = false; }); }
|
||||
|
||||
template <typename> friend class TInsertProxy;
|
||||
template <typename> friend class TInsertIterator;
|
||||
};
|
||||
|
||||
static_assert(CIndirectlyWritable<TPostIncrementProxy<void(*)(int)>, int>);
|
||||
|
||||
template <typename F>
|
||||
class TInsertIterator final : private FNoncopyable
|
||||
{
|
||||
public:
|
||||
|
||||
FORCEINLINE constexpr TInsertIterator() requires (CDefaultConstructible<F>) = default;
|
||||
|
||||
FORCEINLINE constexpr explicit TInsertIterator(F InInserter) : Storage(MoveTemp(InInserter)) { check_code({ bIsProduced = false; }); }
|
||||
|
||||
FORCEINLINE constexpr TInsertIterator(TInsertIterator&&) = default;
|
||||
FORCEINLINE constexpr TInsertIterator& operator=(TInsertIterator&&) = default;
|
||||
|
||||
NODISCARD FORCEINLINE constexpr TInsertProxy<F> operator*()
|
||||
{
|
||||
checkf(!bIsProduced, TEXT("Exception insert, Ensure that no multiple values are assigned to the inserter."));
|
||||
check_code({ bIsProduced = true; });
|
||||
return TInsertProxy<F>(*this);
|
||||
}
|
||||
|
||||
FORCEINLINE constexpr TInsertIterator& operator++() { check_code({ bIsProduced = false; }); return *this; }
|
||||
|
||||
FORCEINLINE constexpr TPostIncrementProxy<F> operator++(int)
|
||||
{
|
||||
checkf(!bIsProduced, TEXT("Exception insert, Ensure that no multiple values are assigned to the inserter."));
|
||||
return TPostIncrementProxy<F>(*this);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
F Storage;
|
||||
|
||||
# if DO_CHECK
|
||||
bool bIsProduced;
|
||||
# endif
|
||||
|
||||
template <typename> friend class TInsertProxy;
|
||||
template <typename> friend class TPostIncrementProxy;
|
||||
};
|
||||
|
||||
static_assert(COutputIterator<TInsertIterator<void(*)(int)>, int>);
|
||||
|
||||
NAMESPACE_PRIVATE_END
|
||||
|
||||
/** Creates an iterator adapter inserted in the front of the container. */
|
||||
template <typename C>
|
||||
NODISCARD FORCEINLINE constexpr auto MakeFrontInserter(C& Container)
|
||||
{
|
||||
return NAMESPACE_PRIVATE::TInsertIterator([&Container]<typename T>(T&& A) { Container.PushFront(Forward<T>(A)); });
|
||||
}
|
||||
|
||||
/** Creates an iterator adapter inserted in the back of the container. */
|
||||
template <typename C>
|
||||
NODISCARD FORCEINLINE constexpr auto MakeBackInserter(C& Container)
|
||||
{
|
||||
return NAMESPACE_PRIVATE::TInsertIterator([&Container]<typename T>(T&& A) { Container.PushBack(Forward<T>(A)); });
|
||||
}
|
||||
|
||||
/** Creates an iterator adapter inserted in the container. */
|
||||
template <typename C>
|
||||
NODISCARD FORCEINLINE constexpr auto MakeInserter(C& Container, const typename C::FConstIterator& InIter)
|
||||
{
|
||||
return NAMESPACE_PRIVATE::TInsertIterator([&Container, Iter = InIter]<typename T>(T&& A) mutable { Iter = Container.Insert(Iter, Forward<T>(A)); ++Iter; });
|
||||
}
|
||||
|
||||
NAMESPACE_MODULE_END(Utility)
|
||||
NAMESPACE_MODULE_END(Redcraft)
|
||||
NAMESPACE_REDCRAFT_END
|
Reference in New Issue
Block a user