Compare commits
	
		
			9 Commits
		
	
	
		
			68cd2c310a
			...
			35f0ba71ab
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 35f0ba71ab | |||
| db7a40cb30 | |||
| 6a70f0c501 | |||
| 5629e31d49 | |||
| c16da1af53 | |||
| 88aba14620 | |||
| 23963e0389 | |||
| 0c6f33762a | |||
| 9024957ff2 | 
@@ -565,29 +565,37 @@ void TestConvert()
 | 
				
			|||||||
	Test(InPlaceType<unicodechar>);
 | 
						Test(InPlaceType<unicodechar>);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void TestStringConversion()
 | 
					void TestFormatting()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	auto Test = []<typename T>(TInPlaceType<T>)
 | 
						auto Test = []<typename T>(TInPlaceType<T>)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		always_check(TString<T>::Format(LITERAL(T, "#{}#"), true ) == LITERAL(T, "#True#" ));
 | 
							always_check(TString<T>::Format(LITERAL(T, "#{0}#"), LITERAL(T, "Hello, World!")) == LITERAL(T, "#Hello, World!#"));
 | 
				
			||||||
		always_check(TString<T>::Format(LITERAL(T, "#{}#"), false) == LITERAL(T, "#False#"));
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		always_check(TString<T>::Format(LITERAL(T, "#{}#"), +0) == LITERAL(T, "#0#"));
 | 
							always_check(TString<T>::Format(LITERAL(T, "#{0}#"), true ) == LITERAL(T, "#True#" ));
 | 
				
			||||||
		always_check(TString<T>::Format(LITERAL(T, "#{}#"),  0) == LITERAL(T, "#0#"));
 | 
							always_check(TString<T>::Format(LITERAL(T, "#{0}#"), false) == LITERAL(T, "#False#"));
 | 
				
			||||||
		always_check(TString<T>::Format(LITERAL(T, "#{}#"), -0) == LITERAL(T, "#0#"));
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		always_check(TString<T>::Format(LITERAL(T, "#{}#"), 42) == LITERAL(T, "#42#"));
 | 
							always_check(TString<T>::Format(LITERAL(T, "#{0}#"), +0) == LITERAL(T, "#0#"));
 | 
				
			||||||
 | 
							always_check(TString<T>::Format(LITERAL(T, "#{0}#"),  0) == LITERAL(T, "#0#"));
 | 
				
			||||||
 | 
							always_check(TString<T>::Format(LITERAL(T, "#{0}#"), -0) == LITERAL(T, "#0#"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		always_check(TString<T>::Format(LITERAL(T, "#{}#"), +0.0) == LITERAL(T,  "#0.000000#"));
 | 
							always_check(TString<T>::Format(LITERAL(T, "#{0}#"), 42) == LITERAL(T, "#42#"));
 | 
				
			||||||
		always_check(TString<T>::Format(LITERAL(T, "#{}#"),  0.0) == LITERAL(T,  "#0.000000#"));
 | 
					 | 
				
			||||||
		always_check(TString<T>::Format(LITERAL(T, "#{}#"), -0.0) == LITERAL(T, "#-0.000000#"));
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		always_check(TString<T>::Format(LITERAL(T, "#{}#"), 3.14) == LITERAL(T, "#3.140000#"));
 | 
							always_check(TString<T>::Format(LITERAL(T, "#{0}#"), +0.0) == LITERAL(T,  "#0#"));
 | 
				
			||||||
 | 
							always_check(TString<T>::Format(LITERAL(T, "#{0}#"),  0.0) == LITERAL(T,  "#0#"));
 | 
				
			||||||
 | 
							always_check(TString<T>::Format(LITERAL(T, "#{0}#"), -0.0) == LITERAL(T, "#-0#"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		always_check(TString<T>::Format(LITERAL(T, "#{}#"), +TNumericLimits<float>::Infinity()) == LITERAL(T,  "#Infinity#"));
 | 
							always_check(TString<T>::Format(LITERAL(T, "#{0}#"), 3.14) == LITERAL(T, "#3.14#"));
 | 
				
			||||||
		always_check(TString<T>::Format(LITERAL(T, "#{}#"), -TNumericLimits<float>::Infinity()) == LITERAL(T, "#-Infinity#"));
 | 
					
 | 
				
			||||||
		always_check(TString<T>::Format(LITERAL(T, "#{}#"), +TNumericLimits<float>::QuietNaN()) == LITERAL(T,  "#NaN#"));
 | 
							always_check(TString<T>::Format(LITERAL(T, "#{0:.6F}#"), +0.0) == LITERAL(T,  "#0.000000#"));
 | 
				
			||||||
		always_check(TString<T>::Format(LITERAL(T, "#{}#"), -TNumericLimits<float>::QuietNaN()) == LITERAL(T, "#-NaN#"));
 | 
							always_check(TString<T>::Format(LITERAL(T, "#{0:.6F}#"),  0.0) == LITERAL(T,  "#0.000000#"));
 | 
				
			||||||
 | 
							always_check(TString<T>::Format(LITERAL(T, "#{0:.6F}#"), -0.0) == LITERAL(T, "#-0.000000#"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							always_check(TString<T>::Format(LITERAL(T, "#{0:.6F}#"), 3.14) == LITERAL(T, "#3.140000#"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							always_check(TString<T>::Format(LITERAL(T, "#{0}#"), +TNumericLimits<float>::Infinity()) == LITERAL(T,  "#Infinity#"));
 | 
				
			||||||
 | 
							always_check(TString<T>::Format(LITERAL(T, "#{0}#"), -TNumericLimits<float>::Infinity()) == LITERAL(T, "#-Infinity#"));
 | 
				
			||||||
 | 
							always_check(TString<T>::Format(LITERAL(T, "#{0}#"), +TNumericLimits<float>::QuietNaN()) == LITERAL(T,  "#NaN#"));
 | 
				
			||||||
 | 
							always_check(TString<T>::Format(LITERAL(T, "#{0}#"), -TNumericLimits<float>::QuietNaN()) == LITERAL(T, "#-NaN#"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			always_check(TString<T>::FromBool(true ) == LITERAL(T, "True" ));
 | 
								always_check(TString<T>::FromBool(true ) == LITERAL(T, "True" ));
 | 
				
			||||||
@@ -632,7 +640,7 @@ void TestString()
 | 
				
			|||||||
	NAMESPACE_PRIVATE::TestStringView();
 | 
						NAMESPACE_PRIVATE::TestStringView();
 | 
				
			||||||
	NAMESPACE_PRIVATE::TestString();
 | 
						NAMESPACE_PRIVATE::TestString();
 | 
				
			||||||
	NAMESPACE_PRIVATE::TestConvert();
 | 
						NAMESPACE_PRIVATE::TestConvert();
 | 
				
			||||||
	NAMESPACE_PRIVATE::TestStringConversion();
 | 
						NAMESPACE_PRIVATE::TestFormatting();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
NAMESPACE_END(Testing)
 | 
					NAMESPACE_END(Testing)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -110,13 +110,13 @@ struct TChar
 | 
				
			|||||||
		// Windows uses UTF-16 encoding for wchar.
 | 
							// Windows uses UTF-16 encoding for wchar.
 | 
				
			||||||
		else if constexpr (PLATFORM_WINDOWS && (CSameAs<FCharType, wchar>))
 | 
							else if constexpr (PLATFORM_WINDOWS && (CSameAs<FCharType, wchar>))
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			return TChar::IsValid(static_cast<u16char>(InChar));
 | 
								return TChar<u16char>::IsValid(static_cast<u16char>(InChar));
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Linux uses UTF-32 encoding for wchar.
 | 
							// Linux uses UTF-32 encoding for wchar.
 | 
				
			||||||
		else if constexpr (PLATFORM_LINUX && (CSameAs<FCharType, wchar>))
 | 
							else if constexpr (PLATFORM_LINUX && (CSameAs<FCharType, wchar>))
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			return TChar::IsValid(static_cast<u32char>(InChar));
 | 
								return TChar<u32char>::IsValid(static_cast<u32char>(InChar));
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		else static_assert(sizeof(FCharType) == -1, "Unsupported character type");
 | 
							else static_assert(sizeof(FCharType) == -1, "Unsupported character type");
 | 
				
			||||||
@@ -153,13 +153,13 @@ struct TChar
 | 
				
			|||||||
		// Windows uses UTF-16 encoding for wchar.
 | 
							// Windows uses UTF-16 encoding for wchar.
 | 
				
			||||||
		else if constexpr (PLATFORM_WINDOWS && (CSameAs<FCharType, wchar>))
 | 
							else if constexpr (PLATFORM_WINDOWS && (CSameAs<FCharType, wchar>))
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			return TChar::IsNonch(static_cast<u16char>(InChar));
 | 
								return TChar<u16char>::IsNonch(static_cast<u16char>(InChar));
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Linux uses UTF-32 encoding for wchar.
 | 
							// Linux uses UTF-32 encoding for wchar.
 | 
				
			||||||
		else if constexpr (PLATFORM_LINUX && (CSameAs<FCharType, wchar>))
 | 
							else if constexpr (PLATFORM_LINUX && (CSameAs<FCharType, wchar>))
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			return TChar::IsNonch(static_cast<u32char>(InChar));
 | 
								return TChar<u32char>::IsNonch(static_cast<u32char>(InChar));
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		else static_assert(sizeof(FCharType) == -1, "Unsupported character type");
 | 
							else static_assert(sizeof(FCharType) == -1, "Unsupported character type");
 | 
				
			||||||
 
 | 
				
			|||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -9,12 +9,14 @@
 | 
				
			|||||||
#include "Containers/Array.h"
 | 
					#include "Containers/Array.h"
 | 
				
			||||||
#include "Containers/ArrayView.h"
 | 
					#include "Containers/ArrayView.h"
 | 
				
			||||||
#include "Iterators/Utility.h"
 | 
					#include "Iterators/Utility.h"
 | 
				
			||||||
#include "Iterators/BasicIterator.h"
 | 
					 | 
				
			||||||
#include "Iterators/Sentinel.h"
 | 
					#include "Iterators/Sentinel.h"
 | 
				
			||||||
 | 
					#include "Iterators/BasicIterator.h"
 | 
				
			||||||
 | 
					#include "Iterators/InsertIterator.h"
 | 
				
			||||||
#include "Ranges/Utility.h"
 | 
					#include "Ranges/Utility.h"
 | 
				
			||||||
#include "Ranges/Factory.h"
 | 
					#include "Ranges/Factory.h"
 | 
				
			||||||
#include "Strings/Char.h"
 | 
					#include "Strings/Char.h"
 | 
				
			||||||
#include "Strings/StringView.h"
 | 
					#include "Strings/StringView.h"
 | 
				
			||||||
 | 
					#include "Strings/Formatting.h"
 | 
				
			||||||
#include "Miscellaneous/AssertionMacros.h"
 | 
					#include "Miscellaneous/AssertionMacros.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <locale>
 | 
					#include <locale>
 | 
				
			||||||
@@ -1231,7 +1233,7 @@ public:
 | 
				
			|||||||
	 * @return The string containing the integer value.
 | 
						 * @return The string containing the integer value.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	template <CIntegral U = int> requires (!CSameAs<U, bool> && !CConst<U> && !CVolatile<U>)
 | 
						template <CIntegral U = int> requires (!CSameAs<U, bool> && !CConst<U> && !CVolatile<U>)
 | 
				
			||||||
	NODISCARD static FORCEINLINE TString FromInt(U Value, unsigned Base = 10)
 | 
						NODISCARD static FORCEINLINE TString FromInt(U Value, uint Base = 10)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		checkf(Base >= 2 && Base <= 36, TEXT("Illegal base. Please check the base."));
 | 
							checkf(Base >= 2 && Base <= 36, TEXT("Illegal base. Please check the base."));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1289,7 +1291,7 @@ public:
 | 
				
			|||||||
	 * @return
 | 
						 * @return
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	template <CFloatingPoint U = float> requires (!CConst<U> && !CVolatile<U>)
 | 
						template <CFloatingPoint U = float> requires (!CConst<U> && !CVolatile<U>)
 | 
				
			||||||
	NODISCARD static FORCEINLINE TString FromFloat(U Value, bool bFixed, bool bScientific, unsigned Precision)
 | 
						NODISCARD static FORCEINLINE TString FromFloat(U Value, bool bFixed, bool bScientific, uint Precision)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		TString Result;
 | 
							TString Result;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1299,23 +1301,84 @@ public:
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/** Converts a boolean value into a string and appends it to the string. */
 | 
						/** Converts a boolean value into a string and appends it to the string. */
 | 
				
			||||||
	void AppendBool(bool Value);
 | 
						FORCEINLINE void AppendBool(bool Value)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							auto Inserter = Ranges::View(MakeBackInserter(*this), UnreachableSentinel);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							Algorithms::Format(Inserter, LITERAL_VIEW(FElementType, "{0}"), Value);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/** Converts an integer value into a string and appends it to the string. */
 | 
						/** Converts an integer value into a string and appends it to the string. */
 | 
				
			||||||
	template <CIntegral U = int> requires (!CSameAs<U, bool> && !CConst<U> && !CVolatile<U>)
 | 
						template <CIntegral U = int> requires (!CSameAs<U, bool> && !CConst<U> && !CVolatile<U>)
 | 
				
			||||||
	void AppendInt(U Value, unsigned Base = 10);
 | 
						FORCEINLINE void AppendInt(U Value, uint Base = 10)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							auto Inserter = Ranges::View(MakeBackInserter(*this), UnreachableSentinel);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							Algorithms::Format(Inserter, LITERAL_VIEW(FElementType, "{0:_{1}I}"), Value, Base);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/** Converts a floating-point value into a string and appends it to the string. */
 | 
						/** Converts a floating-point value into a string and appends it to the string. */
 | 
				
			||||||
	template <CFloatingPoint U = float> requires (!CConst<U> && !CVolatile<U>)
 | 
						template <CFloatingPoint U = float> requires (!CConst<U> && !CVolatile<U>)
 | 
				
			||||||
	void AppendFloat(U Value);
 | 
						FORCEINLINE void AppendFloat(U Value)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							auto Inserter = Ranges::View(MakeBackInserter(*this), UnreachableSentinel);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							Algorithms::Format(Inserter, LITERAL_VIEW(FElementType, "{0}"), Value);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/** Converts a floating-point value into a string and appends it to the string. */
 | 
						/** Converts a floating-point value into a string and appends it to the string. */
 | 
				
			||||||
	template <CFloatingPoint U = float> requires (!CConst<U> && !CVolatile<U>)
 | 
						template <CFloatingPoint U = float> requires (!CConst<U> && !CVolatile<U>)
 | 
				
			||||||
	void AppendFloat(U Value, bool bFixed, bool bScientific);
 | 
						FORCEINLINE void AppendFloat(U Value, bool bFixed, bool bScientific)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							auto Inserter = Ranges::View(MakeBackInserter(*this), UnreachableSentinel);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (bFixed && bScientific)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								Algorithms::Format(Inserter, LITERAL_VIEW(FElementType, "{0:G}"), Value);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							else if (bFixed)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								Algorithms::Format(Inserter, LITERAL_VIEW(FElementType, "{0:F}"), Value);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							else if (bScientific)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								Algorithms::Format(Inserter, LITERAL_VIEW(FElementType, "{0:E}"), Value);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								Algorithms::Format(Inserter, LITERAL_VIEW(FElementType, "{0:A}"), Value);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/** Converts a floating-point value into a string and appends it to the string. */
 | 
						/** Converts a floating-point value into a string and appends it to the string. */
 | 
				
			||||||
	template <CFloatingPoint U = float> requires (!CConst<U> && !CVolatile<U>)
 | 
						template <CFloatingPoint U = float> requires (!CConst<U> && !CVolatile<U>)
 | 
				
			||||||
	void AppendFloat(U Value, bool bFixed, bool bScientific, unsigned Precision);
 | 
						FORCEINLINE void AppendFloat(U Value, bool bFixed, bool bScientific, uint Precision)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							auto Inserter = Ranges::View(MakeBackInserter(*this), UnreachableSentinel);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (bFixed && bScientific)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								Algorithms::Format(Inserter, LITERAL_VIEW(FElementType, "{0:.{1}G}"), Value, Precision);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							else if (bFixed)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								Algorithms::Format(Inserter, LITERAL_VIEW(FElementType, "{0:.{1}F}"), Value, Precision);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							else if (bScientific)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								Algorithms::Format(Inserter, LITERAL_VIEW(FElementType, "{0:.{1}E}"), Value, Precision);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								Algorithms::Format(Inserter, LITERAL_VIEW(FElementType, "{0:.{1}A}"), Value, Precision);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1339,7 +1402,12 @@ public:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	/** Format some objects using a format string and append to the string. */
 | 
						/** Format some objects using a format string and append to the string. */
 | 
				
			||||||
	template <typename... Ts>
 | 
						template <typename... Ts>
 | 
				
			||||||
	void AppendFormat(TStringView<FElementType> Fmt, const Ts&... Args);
 | 
						FORCEINLINE void AppendFormat(TStringView<FElementType> Fmt, const Ts&... Args)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							auto Inserter = Ranges::View(MakeBackInserter(*this), UnreachableSentinel);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							Algorithms::Format(Inserter, Fmt, Args...);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1379,5 +1447,3 @@ template <CCharType T> template <typename Allocator> constexpr TStringView<T>::T
 | 
				
			|||||||
NAMESPACE_MODULE_END(Utility)
 | 
					NAMESPACE_MODULE_END(Utility)
 | 
				
			||||||
NAMESPACE_MODULE_END(Redcraft)
 | 
					NAMESPACE_MODULE_END(Redcraft)
 | 
				
			||||||
NAMESPACE_REDCRAFT_END
 | 
					NAMESPACE_REDCRAFT_END
 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "Strings/Conversion.h.inl"
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user