17#include "CoreMinimal.h"
26#include "range/v3/all.hpp"
43 template <CRangeMember Range>
51 auto begin()
const {
return Storage.begin(); }
52 auto end()
const {
return Storage.end(); }
61 FORCEINLINE
auto Separator(FString
const& separator)
63 return ranges::make_pipeable([separator] <CRangeMember Input> (Input&& range)
65 if constexpr (CIsTemplate<Input, Detail::TRangeWithStringFormat>)
67 range.Options.Separator = separator;
75 FORCEINLINE
auto Enclosure(FString
const& start, FString
const&
end)
77 return ranges::make_pipeable([=] <CRangeMember Input> (Input&& range)
79 if constexpr (CIsTemplate<Input, Detail::TRangeWithStringFormat>)
81 range.Options.Start = start;
82 range.Options.End =
end;
75 FORCEINLINE
auto Enclosure(FString
const& start, FString
const&
end) {
…}
92 return ranges::make_pipeable([] <CRangeMember Input> (Input&& range)
94 if constexpr (CIsTemplate<Input, Detail::TRangeWithStringFormat>)
96 range.Options.Separator = {};
106 return ranges::make_pipeable([] <CRangeMember Input> (Input&& range)
108 if constexpr (CIsTemplate<Input, Detail::TRangeWithStringFormat>)
110 range.Options.Start = {};
111 range.Options.End = {};
125 return ranges::make_pipeable([] <CRangeMember Input> (Input&& range)
127 if constexpr (CIsTemplate<Input, Detail::TRangeWithStringFormat>)
129 range.Options = {{}, {}, {}};
138 template <
typename CharType>
141 if (buffer.Num() == position) buffer.AddZeroed(chunks);
142 buffer[position] = value;
146 template <CStringOrView String>
149 FMemory::Memcpy(buffer.GetData() + position, GetData(value), value.Len() *
sizeof(TCHAR));
150 position += value.Len();
153 template <CStringOrView String>
154 void CopyStringItemToBuffer(String
const& value, FString
const& separator, int32 chunks, int32& position, TArray<TCHAR>& buffer)
156 int nextLength = value.Len() + separator.Len();
158 if (buffer.Num() <= position + nextLength) buffer.AddZeroed(chunks);
159 if (!separator.IsEmpty())
154 void CopyStringItemToBuffer(String
const& value, FString
const& separator, int32 chunks, int32& position, TArray<TCHAR>& buffer) {
…}
178 template <CRangeMember Range>
186 constexpr int chunks = 16384;
190 if constexpr (CIsTemplate<Range, Detail::TRangeWithStringFormat>)
191 rangeFormatOptions = range.Options;
193 if constexpr (CChar<ElementType>)
195 TArray<ElementType> buffer;
196 for (ElementType
const& character : range)
199 if constexpr (CCurrentChar<ElementType>)
200 return FString::ConstructFromPtrSize(buffer.GetData(), position);
207 else if constexpr (CStringOrView<ElementType>)
209 TArray<TCHAR> buffer;
210 for (
auto it = range.begin(); !
IteratorEquals(it, range.end()); ++it)
212 ElementType
const& value = *it;
216 isFirst ? FString() : rangeFormatOptions.
Separator,
221 FString output = FString::ConstructFromPtrSize(buffer.GetData(), position);
222 return rangeFormatOptions.
Start + output + rangeFormatOptions.
End;
226 TArray<TCHAR> buffer;
227 for (
auto it = range.begin(); !
IteratorEquals(it, range.end()); ++it)
229 ElementType
const& value = *it;
230 FString valueString =
AsString(value);
235 isFirst ? FString() : rangeFormatOptions.
Separator,
240 FString output = FString::ConstructFromPtrSize(buffer.GetData(), position);
241 return rangeFormatOptions.
Start + output + rangeFormatOptions.
End;
247 return ranges::make_pipeable([](
auto&& range) {
return RenderAsString(range); });
272 template <
template <
typename>
typename Target>
275 template <CRangeMember From,
typename Value = TRangeElementType<From>>
277 Target<Value> Convert(From&& range)
const
279 Target<Value> result;
280 for (Value
const& value : range)
288 template <CRangeMember From>
291 return functor.Convert(range);
294 template <CRangeMember From>
297 return Convert(range);
325 template <CUnrealRange Target>
331 template <CRangeMember From, CConvertibleToDecayed<ElementType> Value = TRangeElementType<From>>
332 void Convert(From&& range)
334 auto it = Storage.begin();
335 auto endIt = Storage.end();
336 for (Value
const& value : range)
351 template <CRangeMember From>
354 functor.Convert(range);
355 return functor.Storage;
399 static void Convert(From&& range, MapType& result)
401 for (Value
const& value : range)
409 typename MapType = TMap<Value, Value>
411 static void Convert(From&& range, MapType& result)
413 for (InnerRange
const& innerRange : range)
416 auto it = innerRange.begin();
418 Value
const& key = *it;
421 Value
const& value = *it;
422 result.Add(key, value);
432 MapType Convert(From&& range)
const
435 Convert(range, result);
443 typename MapType = TMap<Value, Value>
445 MapType Convert(From&& range)
const
448 Convert(range, result);
453 template <CIsTemplate<TMap> Target>
458 template <CRangeMember From>
461 return functor.Convert(range);
464 template <CRangeMember From>
467 return Convert(range);
505 template <CIsTemplate<TMap> Target>
508 using KeyType =
typename Target::KeyType;
509 using ValueType =
typename Target::ValueType;
521 RenderAsMap::Convert(range, functor.Storage);
522 return functor.Storage;
531 template <CRangeMember Operand>
533 !CDirectStringFormatArgument<Operand>
534 && !CHasToString<Operand>
538 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...
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)
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 provide some introspection into template instantiations.
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()