17#include "CoreMinimal.h"
18#include "Misc/EngineVersionComparison.h"
27#include "range/v3/all.hpp"
46#if !UE_VERSION_OLDER_THAN(5, 8, 0) && defined(TARRAY_RANGED_FOR_CHECKS) && TARRAY_RANGED_FOR_CHECKS
49 template <
typename ElementType,
typename SizeType,
bool bReverse>
50 struct indirectly_readable_traits<::TCheckedPointerIterator<ElementType, SizeType, bReverse>>
52 using value_type = std::remove_cv_t<ElementType>;
71 template <CRangeMember Range>
79 auto begin()
const {
return Storage.begin(); }
80 auto end()
const {
return Storage.end(); }
89 FORCEINLINE
auto Separator(FString
const& separator)
91 return ranges::make_pipeable([separator] <CRangeMember Input> (Input&& range)
93 if constexpr (CMatchTemplate<Input, Detail::TRangeWithStringFormat>)
95 range.Options.Separator = separator;
105 return ranges::make_pipeable([=] <CRangeMember Input> (Input&& range)
107 if constexpr (CMatchTemplate<Input, Detail::TRangeWithStringFormat>)
109 range.Options.Start = start;
110 range.Options.End =
end;
120 return ranges::make_pipeable([] <CRangeMember Input> (Input&& range)
122 if constexpr (CMatchTemplate<Input, Detail::TRangeWithStringFormat>)
124 range.Options.Separator = {};
134 return ranges::make_pipeable([] <CRangeMember Input> (Input&& range)
136 if constexpr (CMatchTemplate<Input, Detail::TRangeWithStringFormat>)
138 range.Options.Start = {};
139 range.Options.End = {};
153 return ranges::make_pipeable([] <CRangeMember Input> (Input&& range)
155 if constexpr (CMatchTemplate<Input, Detail::TRangeWithStringFormat>)
157 range.Options = {{}, {}, {}};
166 template <
typename CharType>
169 if (buffer.Num() == position) buffer.AddZeroed(chunks);
170 buffer[position] = value;
174 template <CStringOrView String>
177 FMemory::Memcpy(buffer.GetData() + position, GetData(value), value.Len() *
sizeof(TCHAR));
178 position += value.Len();
181 template <CStringOrView String>
182 void CopyStringItemToBuffer(String
const& value, FString
const& separator, int32 chunks, int32& position, TArray<TCHAR>& buffer)
184 int nextLength = value.Len() + separator.Len();
186 if (buffer.Num() <= position + nextLength) buffer.AddZeroed(chunks);
187 if (!separator.IsEmpty())
206 template <CRangeMember Range>
214 constexpr int chunks = 16384;
218 if constexpr (CMatchTemplate<Range, Detail::TRangeWithStringFormat>)
219 rangeFormatOptions = range.Options;
221 if constexpr (CChar<ElementType>)
223 TArray<ElementType> buffer;
224 for (ElementType
const& character : range)
227 if constexpr (CCurrentChar<ElementType>)
235 else if constexpr (CStringOrView<ElementType>)
237 TArray<TCHAR> buffer;
238 for (
auto it = range.begin(); !
IteratorEquals(it, range.end()); ++it)
240 ElementType
const& value = *it;
244 isFirst ? FString() : rangeFormatOptions.
Separator,
250 return rangeFormatOptions.
Start + output + rangeFormatOptions.
End;
254 TArray<TCHAR> buffer;
255 for (
auto it = range.begin(); !
IteratorEquals(it, range.end()); ++it)
257 ElementType
const& value = *it;
258 FString valueString =
AsString(value);
263 isFirst ? FString() : rangeFormatOptions.
Separator,
269 return rangeFormatOptions.
Start + output + rangeFormatOptions.
End;
275 return ranges::make_pipeable([]<CRangeMember Input>(Input&& range)
303 template <
template <
typename>
typename Target>
306 template <CRangeMember From,
typename Value = TRangeElementType<From>>
308 Target<Value> Convert(From&& range)
const
310 Target<Value> result;
311 for (Value
const& value : range)
319 template <CRangeMember From>
322 return functor.Convert(
FWD(range));
325 template <CRangeMember From>
328 return Convert(
FWD(range));
356 template <CUnrealRange Target>
362 template <CRangeMember From, CConvertibleToDecayed<ElementType> Value = TRangeElementType<From>>
363 void Convert(From&& range)
365 auto it = Storage.begin();
366 auto endIt = Storage.end();
367 for (Value
const& value : range)
382 template <CRangeMember From>
385 functor.Convert(
FWD(range));
386 return functor.Storage;
430 static void Convert(From&& range, MapType& result)
432 for (Value
const& value : range)
440 typename MapType = TMap<Value, Value>
442 static void Convert(From&& range, MapType& result)
444 for (InnerRange
const& innerRange : range)
447 auto it = innerRange.begin();
449 Value
const& key = *it;
452 Value
const& value = *it;
453 result.Add(key, value);
463 MapType Convert(From&& range)
const
466 Convert(
FWD(range), result);
474 typename MapType = TMap<Value, Value>
476 MapType Convert(From&& range)
const
479 Convert(
FWD(range), result);
484 template <CMatchTemplate<TMap> Target>
489 template <CRangeMember From>
492 return functor.Convert(
FWD(range));
495 template <CRangeMember From>
498 return Convert(
FWD(range));
536 template <CMatchTemplate<TMap> Target>
539 using KeyType =
typename Target::KeyType;
540 using ValueType =
typename Target::ValueType;
552 RenderAsMap::Convert(
FWD(range), functor.Storage);
553 return functor.Storage;
562 template <CRangeMember Operand>
564 !CDirectStringFormatArgument<Operand>
565 && !CHasToString<Operand>
569 template <CConvertibleToDecayed<Operand> Arg>
This header exists because STL headers in Android doesn't define STL concepts (other than same_as whi...
Use this header and Start.h in tandem to include third-party library headers which may not tolerate U...
#define FWD(...)
Shorten forwarding expression with this macro so one may not need to specify explicit type.
auto end(TArray< T, A > &r) -> T *
Use this header and End.h in tandem to include third-party library headers which may not tolerate Unr...
#define TEXT_
A convenience alternative to Unreal's own TEXT macro but this one doesn't require parenthesis around ...
Output a range of tuples or range of ranges with at least 2 elements to an already existing TMap.
friend Target & operator|(From &&range, OutputToMap &&functor)
OutputToMap(Target &target)
Render a range to an already existing container.
friend Target & operator|(From &&range, OutputTo &&functor)
Render a range of tuples or range of ranges with at least 2 elements as a TMap.
auto Render(From &&range) const
friend auto operator|(From &&range, RenderAsMap &&functor)
Render a range as the given container.
auto Render(From &&range) const
friend auto operator|(From &&range, RenderAs &&functor)
void CopyCharactersToBuffer(CharType const &value, int32 chunks, int32 &position, TArray< CharType > &buffer)
void CopyStringItemToBuffer(String const &value, FString const &separator, int32 chunks, int32 &position, TArray< TCHAR > &buffer)
void CopyStringToBufferUnsafe(String const &value, int32 &position, TArray< TCHAR > &buffer)
Restore range-v3 compatibility for TArray on UE 5.8+.
FORCEINLINE auto NoSeparator()
Don't use a separator when this range is rendered to a string.
FORCEINLINE auto NoEnclosure()
Don't enclose this range in anything when it's rendered to a string.
FORCEINLINE auto Separator(FString const &separator)
Specify a separator sequence for a range when converting it to a string.
FORCEINLINE auto RenderAsString()
bool IteratorEquals(L const &l, R const &r)
FORCEINLINE auto Enclosure(FString const &start, FString const &end)
Specify a start and an end sequence enclosing this range when converting it to a string.
FORCEINLINE auto NoDecorators()
Don't insert anything else than the contents of the input range when that is rendered as a string jus...
TIteratorElementType< decltype(DeclVal< T >().begin())> TRangeElementType
return a range's associated content type determined by dereferencing their iterator.
This namespace provides templating utilities and introspection into template instantiations.
FORCEINLINE FString MakeStringFromPtrSize(const TCHAR *ptr, int32 size)
Mixed text utilities and type traits.
FString UnrealConvert(T const &stdStr)
Create a copy and convert an input STL string to TCHAR.
FString AsString(T &&input)
Attempt to convert anything to string which can tell via some method how to do so.
std::basic_string_view< CharT, Traits > TStdStringView
Unreal style alias for STL string views.
decltype(auto) GetItem(T &&tuple)
std::decay_t< typename TTypeAt_Struct< I, T >::Type > TTypeAtDecayed
consteval size_t GetSize()