Remove Nz::String and Nz::StringStream

This commit is contained in:
Jérôme Leclercq
2020-09-25 19:31:01 +02:00
parent d665af1f9d
commit 2b6a463a45
212 changed files with 1877 additions and 8721 deletions

View File

@@ -14,6 +14,7 @@
#include <Nazara/Core/Hash/SHA384.hpp>
#include <Nazara/Core/Hash/SHA512.hpp>
#include <Nazara/Core/Hash/Whirlpool.hpp>
#include <Nazara/Math/Algorithm.hpp>
#include <Nazara/Core/Debug.hpp>
namespace Nz
@@ -74,7 +75,7 @@ namespace Nz
return std::make_unique<HashWhirlpool>();
}
NazaraInternalError("Hash type not handled (0x" + String::Number(type, 16) + ')');
NazaraInternalError("Hash type not handled (0x" + NumberToString(type, 16) + ')');
return nullptr;
}
}

View File

@@ -3,7 +3,7 @@
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/AbstractLogger.hpp>
#include <Nazara/Core/StringStream.hpp>
#include <sstream>
#include <Nazara/Core/Debug.hpp>
namespace Nz
@@ -40,14 +40,14 @@ namespace Nz
* \param function Name of the function throwing the error
*/
void AbstractLogger::WriteError(ErrorType type, const String& error, unsigned int line, const char* file, const char* function)
void AbstractLogger::WriteError(ErrorType type, const std::string_view& error, unsigned int line, const char* file, const char* function)
{
StringStream stream;
stream << errorType[type] << error;
std::ostringstream ss;
ss << errorType[type] << error;
if (line != 0 && file && function)
stream << " (" << file << ':' << line << ": " << function << ')';
ss << " (" << file << ':' << line << ": " << function << ')';
Write(stream);
Write(ss.str());
}
}

View File

@@ -3,6 +3,7 @@
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/ByteArray.hpp>
#include <ostream>
#include <Nazara/Core/Debug.hpp>
namespace Nz
@@ -18,11 +19,11 @@ namespace Nz
* \return String in base 16
*/
String ByteArray::ToHex() const
std::string ByteArray::ToHex() const
{
std::size_t length = m_array.size() * 2;
String hexOutput(length, '\0');
std::string hexOutput(length, '\0');
for (std::size_t i = 0; i < m_array.size(); ++i)
std::sprintf(&hexOutput[i * 2], "%02x", m_array[i]);

View File

@@ -45,7 +45,7 @@ namespace Nz
* \param function Optional argument to set last error function
*/
String Error::GetLastError(const char** file, unsigned int* line, const char** function)
std::string Error::GetLastError(const char** file, unsigned int* line, const char** function)
{
if (file)
*file = s_lastErrorFile;
@@ -103,7 +103,7 @@ namespace Nz
#else
#error GetLastSystemError is not implemented on this platform
return String("GetLastSystemError is not implemented on this platform");
return "GetLastSystemError is not implemented on this platform";
#endif
}
@@ -128,12 +128,12 @@ namespace Nz
* \remark Produces a std::runtime_error on AssertFailed or throwing exception
*/
void Error::Trigger(ErrorType type, const String& error)
void Error::Trigger(ErrorType type, std::string error)
{
if (type == ErrorType_AssertFailed || (s_flags & ErrorFlag_Silent) == 0 || (s_flags & ErrorFlag_SilentDisabled) != 0)
Log::WriteError(type, error);
s_lastError = error;
s_lastError = std::move(error);
s_lastErrorFile = "";
s_lastErrorFunction = "";
s_lastErrorLine = 0;
@@ -145,7 +145,7 @@ namespace Nz
if (type == ErrorType_AssertFailed || (type != ErrorType_Warning &&
(s_flags & ErrorFlag_ThrowException) != 0 && (s_flags & ErrorFlag_ThrowExceptionDisabled) == 0))
throw std::runtime_error(error.ToStdString());
throw std::runtime_error(s_lastError);
}
/*!
@@ -161,14 +161,14 @@ namespace Nz
* \remark Produces a std::runtime_error on AssertFailed or throwing exception
*/
void Error::Trigger(ErrorType type, const String& error, unsigned int line, const char* file, const char* function)
void Error::Trigger(ErrorType type, std::string error, unsigned int line, const char* file, const char* function)
{
file = GetCurrentFileRelativeToEngine(file);
if (type == ErrorType_AssertFailed || (s_flags & ErrorFlag_Silent) == 0 || (s_flags & ErrorFlag_SilentDisabled) != 0)
Log::WriteError(type, error, line, file, function);
s_lastError = error;
s_lastError = std::move(error);
s_lastErrorFile = file;
s_lastErrorFunction = function;
s_lastErrorLine = line;
@@ -180,7 +180,7 @@ namespace Nz
if (type == ErrorType_AssertFailed || (type != ErrorType_Warning &&
(s_flags & ErrorFlag_ThrowException) != 0 && (s_flags & ErrorFlag_ThrowExceptionDisabled) == 0))
throw std::runtime_error(error.ToStdString());
throw std::runtime_error(s_lastError);
}
const char* Error::GetCurrentFileRelativeToEngine(const char* file)
@@ -195,7 +195,7 @@ namespace Nz
}
UInt32 Error::s_flags = ErrorFlag_None;
String Error::s_lastError;
std::string Error::s_lastError;
const char* Error::s_lastErrorFunction = "";
const char* Error::s_lastErrorFile = "";
unsigned int Error::s_lastErrorLine = 0;

View File

@@ -7,7 +7,6 @@
#include <Nazara/Core/Config.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Core/ErrorFlags.hpp>
#include <Nazara/Core/StringStream.hpp>
#include <memory>
#if defined(NAZARA_PLATFORM_WINDOWS)

View File

@@ -5,7 +5,6 @@
#include <Nazara/Core/FileLogger.hpp>
#include <Nazara/Core/CallOnExit.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Core/StringStream.hpp>
#include <array>
#include <ctime>
#include <filesystem>
@@ -26,8 +25,8 @@ namespace Nz
* \param logPath Path to log
*/
FileLogger::FileLogger(const String& logPath) :
m_outputPath(logPath.ToStdString()),
FileLogger::FileLogger(std::filesystem::path logPath) :
m_outputPath(std::move(logPath)),
m_forceStdOutput(false),
m_stdReplicationEnabled(true),
m_timeLoggingEnabled(true)
@@ -92,7 +91,7 @@ namespace Nz
* \see WriteError
*/
void FileLogger::Write(const String& string)
void FileLogger::Write(const std::string_view& string)
{
if (m_forceStdOutput || m_stdReplicationEnabled)
{
@@ -148,7 +147,7 @@ namespace Nz
* \see Write
*/
void FileLogger::WriteError(ErrorType type, const String& error, unsigned int line, const char* file, const char* function)
void FileLogger::WriteError(ErrorType type, const std::string_view& error, unsigned int line, const char* file, const char* function)
{
AbstractLogger::WriteError(type, error, line, file, function);
m_outputFile.flush();

View File

@@ -613,7 +613,7 @@ namespace Nz
break;
default:
NazaraError("Split heuristic out of enum (0x" + String::Number(method, 16) + ')');
NazaraError("Split heuristic out of enum (0x" + NumberToString(method, 16) + ')');
splitHorizontal = true;
}
@@ -656,7 +656,7 @@ namespace Nz
return ScoreWorstShortSideFit(width, height, freeRect);
}
NazaraError("Rect choice heuristic out of enum (0x" + String::Number(rectChoice, 16) + ')');
NazaraError("Rect choice heuristic out of enum (0x" + NumberToString(rectChoice, 16) + ')');
return std::numeric_limits<int>::max();
}
}

View File

@@ -107,7 +107,7 @@ namespace Nz
* \remark Produces a NazaraError if not Initialize
*/
String HardwareInfo::GetProcessorBrandString()
std::string_view HardwareInfo::GetProcessorBrandString()
{
if (!Initialize())
NazaraError("Failed to initialize HardwareInfo");
@@ -150,7 +150,7 @@ namespace Nz
* \remark Produces a NazaraError if not Initialize
*/
String HardwareInfo::GetProcessorVendorName()
std::string_view HardwareInfo::GetProcessorVendorName()
{
if (!Initialize())
NazaraError("Failed to initialize HardwareInfo");

View File

@@ -76,7 +76,7 @@ namespace Nz
* \see WriteError
*/
void Log::Write(const String& string)
void Log::Write(const std::string_view& string)
{
if (s_enabled)
s_logger->Write(string);
@@ -96,7 +96,7 @@ namespace Nz
* \see Write
*/
void Log::WriteError(ErrorType type, const String& error, unsigned int line, const char* file, const char* function)
void Log::WriteError(ErrorType type, const std::string_view& error, unsigned int line, const char* file, const char* function)
{
if (s_enabled)
s_logger->WriteError(type, error, line, file, function);

View File

@@ -6,6 +6,7 @@
#include <Nazara/Core/Error.hpp>
#include <Nazara/Core/ErrorFlags.hpp>
#include <Nazara/Core/MemoryHelper.hpp>
#include <Nazara/Core/StringExt.hpp>
#include <cstring>
#include <Nazara/Core/Debug.hpp>
@@ -55,9 +56,9 @@ namespace Nz
* \remark In case of failure, the variable pointed by value keep its value
* \remark If the parameter is not a boolean, a conversion will be performed, compatibles types are:
Integer: 0 is interpreted as false, any other value is interpreted as true
String: Conversion obeys the rule as described by String::ToBool
std::string: Conversion obeys the rule as described by std::string::ToBool
*/
bool ParameterList::GetBooleanParameter(const String& name, bool* value) const
bool ParameterList::GetBooleanParameter(const std::string& name, bool* value) const
{
NazaraAssert(value, "Invalid pointer");
@@ -82,10 +83,14 @@ namespace Nz
case ParameterType_String:
{
bool converted;
if (it->second.value.stringVal.ToBool(&converted, String::CaseInsensitive))
if (it->second.value.stringVal == "1" || it->second.value.stringVal == "yes" || it->second.value.stringVal == "true")
{
*value = converted;
*value = true;
return true;
}
else if (it->second.value.stringVal == "0" || it->second.value.stringVal == "no" || it->second.value.stringVal == "false")
{
*value = false;
return true;
}
@@ -115,7 +120,7 @@ namespace Nz
* \remark In case of failure, the variable pointed by value keep its value
* \remark If the parameter is not a color, the function fails
*/
bool ParameterList::GetColorParameter(const String& name, Color* value) const
bool ParameterList::GetColorParameter(const std::string& name, Color* value) const
{
NazaraAssert(value, "Invalid pointer");
@@ -159,9 +164,9 @@ namespace Nz
* \remark In case of failure, the variable pointed by value keep its value
* \remark If the parameter is not a double, a conversion will be performed, compatibles types are:
Integer: The integer value is converted to its double representation
String: Conversion obeys the rule as described by String::ToDouble
std::string: Conversion obeys the rule as described by std::string::ToDouble
*/
bool ParameterList::GetDoubleParameter(const String& name, double* value) const
bool ParameterList::GetDoubleParameter(const std::string& name, double* value) const
{
NazaraAssert(value, "Invalid pointer");
@@ -185,16 +190,21 @@ namespace Nz
return true;
case ParameterType_String:
{
double converted;
if (it->second.value.stringVal.ToDouble(&converted))
{
*value = converted;
return true;
}
{
const std::string& str = it->second.value.stringVal;
int& err = errno;
err = 0;
char* endStr;
double ret = std::strtod(str.data(), &endStr);
if (str.data() == endStr || err == ERANGE)
break;
}
*value = ret;
return true;
}
case ParameterType_Boolean:
case ParameterType_Color:
@@ -220,9 +230,9 @@ namespace Nz
* \remark If the parameter is not an integer, a conversion will be performed, compatibles types are:
Boolean: The boolean is represented as 1 if true and 0 if false
Double: The floating-point value is truncated and converted to a integer
String: Conversion obeys the rule as described by String::ToInteger
std::string: Conversion obeys the rule as described by std::string::ToInteger
*/
bool ParameterList::GetIntegerParameter(const String& name, long long* value) const
bool ParameterList::GetIntegerParameter(const std::string& name, long long* value) const
{
NazaraAssert(value, "Invalid pointer");
@@ -250,15 +260,21 @@ namespace Nz
return true;
case ParameterType_String:
{
long long converted;
if (it->second.value.stringVal.ToInteger(&converted))
{
*value = converted;
return true;
}
{
const std::string& str = it->second.value.stringVal;
int& err = errno;
err = 0;
char* endStr;
long long ret = std::strtoll(str.data(), &endStr, 0);
if (str.data() == endStr || err == ERANGE)
break;
}
*value = ret;
return true;
}
case ParameterType_Color:
case ParameterType_None:
@@ -280,7 +296,7 @@ namespace Nz
*
* \remark type must be a valid pointer to a ParameterType variable
*/
bool ParameterList::GetParameterType(const String& name, ParameterType* type) const
bool ParameterList::GetParameterType(const std::string& name, ParameterType* type) const
{
NazaraAssert(type, "Invalid pointer");
@@ -305,7 +321,7 @@ namespace Nz
* \remark If the parameter is not a pointer, a conversion will be performed, compatibles types are:
Userdata: The pointer part of the userdata is returned
*/
bool ParameterList::GetPointerParameter(const String& name, void** value) const
bool ParameterList::GetPointerParameter(const std::string& name, void** value) const
{
NazaraAssert(value, "Invalid pointer");
@@ -351,15 +367,15 @@ namespace Nz
* \remark value must be a valid pointer
* \remark In case of failure, the variable pointed by value keep its value
* \remark If the parameter is not a string, a conversion will be performed, all types are compatibles:
Boolean: Conversion obeys the rules of String::Boolean
Boolean: Conversion obeys the rules of std::string::Boolean
Color: Conversion obeys the rules of Color::ToString
Double: Conversion obeys the rules of String::Number
Integer: Conversion obeys the rules of String::Number
Double: Conversion obeys the rules of std::string::Number
Integer: Conversion obeys the rules of std::string::Number
None: An empty string is returned
Pointer: Conversion obeys the rules of String::Pointer
Userdata: Conversion obeys the rules of String::Pointer
Pointer: Conversion obeys the rules of PointerToString
Userdata: Conversion obeys the rules of PointerToString
*/
bool ParameterList::GetStringParameter(const String& name, String* value) const
bool ParameterList::GetStringParameter(const std::string& name, std::string* value) const
{
NazaraAssert(value, "Invalid pointer");
@@ -375,7 +391,7 @@ namespace Nz
switch (it->second.type)
{
case ParameterType_Boolean:
*value = String::Boolean(it->second.value.boolVal);
*value = (it->second.value.boolVal) ? "true" : "false";
return true;
case ParameterType_Color:
@@ -383,11 +399,11 @@ namespace Nz
return true;
case ParameterType_Double:
*value = String::Number(it->second.value.doubleVal);
*value = std::to_string(it->second.value.doubleVal);
return true;
case ParameterType_Integer:
*value = String::Number(it->second.value.intVal);
*value = std::to_string(it->second.value.intVal);
return true;
case ParameterType_String:
@@ -395,15 +411,15 @@ namespace Nz
return true;
case ParameterType_Pointer:
*value = String::Pointer(it->second.value.ptrVal);
*value = PointerToString(it->second.value.ptrVal);
return true;
case ParameterType_Userdata:
*value = String::Pointer(it->second.value.userdataVal->ptr);
*value = PointerToString(it->second.value.userdataVal->ptr);
return true;
case ParameterType_None:
*value = String();
*value = std::string();
return true;
}
@@ -424,7 +440,7 @@ namespace Nz
*
* \see GetPointerParameter
*/
bool ParameterList::GetUserdataParameter(const String& name, void** value) const
bool ParameterList::GetUserdataParameter(const std::string& name, void** value) const
{
NazaraAssert(value, "Invalid pointer");
@@ -437,9 +453,11 @@ namespace Nz
return false;
}
if (it->second.type == ParameterType_Userdata)
const auto& parameter = it->second;
if (parameter.type == ParameterType_Userdata)
{
*value = it->second.value.userdataVal->ptr;
*value = parameter.value.userdataVal->ptr;
return true;
}
else
@@ -455,7 +473,7 @@ namespace Nz
*
* \param name Name of the parameter
*/
bool ParameterList::HasParameter(const String& name) const
bool ParameterList::HasParameter(const std::string& name) const
{
return m_parameters.find(name) != m_parameters.end();
}
@@ -468,7 +486,7 @@ namespace Nz
*
* \param name Name of the parameter
*/
void ParameterList::RemoveParameter(const String& name)
void ParameterList::RemoveParameter(const std::string& name)
{
auto it = m_parameters.find(name);
if (it != m_parameters.end())
@@ -485,7 +503,7 @@ namespace Nz
*
* \param name Name of the parameter
*/
void ParameterList::SetParameter(const String& name)
void ParameterList::SetParameter(const std::string& name)
{
Parameter& parameter = CreateValue(name);
parameter.type = ParameterType_None;
@@ -499,7 +517,7 @@ namespace Nz
* \param name Name of the parameter
* \param value The color value
*/
void ParameterList::SetParameter(const String& name, const Color& value)
void ParameterList::SetParameter(const std::string& name, const Color& value)
{
Parameter& parameter = CreateValue(name);
parameter.type = ParameterType_Color;
@@ -515,7 +533,7 @@ namespace Nz
* \param name Name of the parameter
* \param value The string value
*/
void ParameterList::SetParameter(const String& name, const String& value)
void ParameterList::SetParameter(const std::string& name, const std::string& value)
{
Parameter& parameter = CreateValue(name);
parameter.type = ParameterType_String;
@@ -531,7 +549,7 @@ namespace Nz
* \param name Name of the parameter
* \param value The string value
*/
void ParameterList::SetParameter(const String& name, const char* value)
void ParameterList::SetParameter(const std::string& name, const char* value)
{
Parameter& parameter = CreateValue(name);
parameter.type = ParameterType_String;
@@ -547,7 +565,7 @@ namespace Nz
* \param name Name of the parameter
* \param value The boolean value
*/
void ParameterList::SetParameter(const String& name, bool value)
void ParameterList::SetParameter(const std::string& name, bool value)
{
Parameter& parameter = CreateValue(name);
parameter.type = ParameterType_Boolean;
@@ -562,7 +580,7 @@ namespace Nz
* \param name Name of the parameter
* \param value The double value
*/
void ParameterList::SetParameter(const String& name, double value)
void ParameterList::SetParameter(const std::string& name, double value)
{
Parameter& parameter = CreateValue(name);
parameter.type = ParameterType_Double;
@@ -577,7 +595,7 @@ namespace Nz
* \param name Name of the parameter
* \param value The integer value
*/
void ParameterList::SetParameter(const String& name, long long value)
void ParameterList::SetParameter(const std::string& name, long long value)
{
Parameter& parameter = CreateValue(name);
parameter.type = ParameterType_Integer;
@@ -595,7 +613,7 @@ namespace Nz
* \remark This sets a raw pointer, this class takes no responsibility toward it,
if you wish to destroy the pointed variable along with the parameter list, you should set a userdata
*/
void ParameterList::SetParameter(const String& name, void* value)
void ParameterList::SetParameter(const std::string& name, void* value)
{
Parameter& parameter = CreateValue(name);
parameter.type = ParameterType_Pointer;
@@ -606,36 +624,39 @@ namespace Nz
* \brief Gives a string representation
* \return A string representation of the object: "ParameterList(Name: Type(value), ...)"
*/
String ParameterList::ToString() const
std::string ParameterList::ToString() const
{
StringStream ss;
std::ostringstream ss;
ss << std::boolalpha;
ss << "ParameterList(";
for (auto it = m_parameters.cbegin(); it != m_parameters.cend();)
{
const auto& parameter = it->second;
ss << it->first << ": ";
switch (it->second.type)
{
case ParameterType_Boolean:
ss << "Boolean(" << String::Boolean(it->second.value.boolVal) << ")";
ss << "Boolean(" << parameter.value.boolVal << ")";
break;
case ParameterType_Color:
ss << "Color(" << it->second.value.colorVal.ToString() << ")";
ss << "Color(" << parameter.value.colorVal << ")";
break;
case ParameterType_Double:
ss << "Double(" << it->second.value.doubleVal << ")";
ss << "Double(" << parameter.value.doubleVal << ")";
break;
case ParameterType_Integer:
ss << "Integer(" << it->second.value.intVal << ")";
ss << "Integer(" << parameter.value.intVal << ")";
break;
case ParameterType_String:
ss << "String(" << it->second.value.stringVal << ")";
ss << "std::string(" << parameter.value.stringVal << ")";
break;
case ParameterType_Pointer:
ss << "Pointer(" << String::Pointer(it->second.value.ptrVal) << ")";
ss << "Pointer(" << parameter.value.ptrVal << ")";
break;
case ParameterType_Userdata:
ss << "Userdata(" << String::Pointer(it->second.value.userdataVal->ptr) << ")";
ss << "Userdata(" << parameter.value.userdataVal->ptr << ")";
break;
case ParameterType_None:
ss << "None";
@@ -647,7 +668,7 @@ namespace Nz
}
ss << ")";
return ss;
return ss.str();
}
/*!
@@ -662,7 +683,7 @@ namespace Nz
* \remark The destructor is called once when all copies of the userdata are destroyed, which means
you can safely copy the parameter list around.
*/
void ParameterList::SetParameter(const String& name, void* value, Destructor destructor)
void ParameterList::SetParameter(const std::string& name, void* value, Destructor destructor)
{
Parameter& parameter = CreateValue(name);
parameter.type = ParameterType_Userdata;
@@ -721,7 +742,7 @@ namespace Nz
*
* \remark The previous value if any gets destroyed
*/
ParameterList::Parameter& ParameterList::CreateValue(const String& name)
ParameterList::Parameter& ParameterList::CreateValue(const std::string& name)
{
std::pair<ParameterMap::iterator, bool> pair = m_parameters.insert(std::make_pair(name, Parameter()));
Parameter& parameter = pair.first->second;
@@ -742,7 +763,7 @@ namespace Nz
switch (parameter.type)
{
case ParameterType_String:
parameter.value.stringVal.~String();
PlacementDestroy(&parameter.value.stringVal);
break;
case ParameterType_Userdata:

View File

@@ -4,7 +4,6 @@
#include <Nazara/Core/Posix/DynLibImpl.hpp>
#include <Nazara/Core/DynLib.hpp>
#include <Nazara/Core/String.hpp>
#include <dlfcn.h>
#include <Nazara/Core/Debug.hpp>

View File

@@ -4,6 +4,7 @@
#include <Nazara/Core/Posix/FileImpl.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Core/StringExt.hpp>
#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>
@@ -159,7 +160,7 @@ namespace Nz
break;
default:
NazaraInternalError("Cursor position not handled (0x" + String::Number(pos, 16) + ')');
NazaraInternalError("Cursor position not handled (0x" + NumberToString(pos, 16) + ')');
return false;
}

View File

@@ -37,7 +37,7 @@ namespace Nz
{
#if NAZARA_CORE_SAFE
if (m_referenceCount > 0)
NazaraWarning("Resource destroyed while still referenced " + String::Number(m_referenceCount) + " time(s)");
NazaraWarning("Resource destroyed while still referenced " + std::to_string(m_referenceCount) + " time(s)");
#endif
}

View File

@@ -60,9 +60,9 @@ namespace Nz
* \see WriteError
*/
void StdLogger::Write(const String& string)
void StdLogger::Write(const std::string_view& error)
{
fputs(string.GetConstBuffer(), stdout);
fwrite(error.data(), sizeof(char), error.size(), stdout);
fputc('\n', stdout);
}
@@ -78,9 +78,10 @@ namespace Nz
* \see Write
*/
void StdLogger::WriteError(ErrorType type, const String& error, unsigned int line, const char* file, const char* function)
void StdLogger::WriteError(ErrorType type, const std::string_view& error, unsigned int line, const char* file, const char* function)
{
fprintf(stderr, "%s: %s", errorType[type], error.GetConstBuffer());
fprintf(stderr, "%s: ", errorType[type]);
fwrite(error.data(), sizeof(char), error.size(), stdout);
if (line != 0 && file && function)
fprintf(stderr, " (in %s at %s:%d)", function, file, line);

View File

@@ -5,7 +5,7 @@
#include <Nazara/Core/Stream.hpp>
#include <Nazara/Core/ByteArray.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Core/String.hpp>
#include <Nazara/Core/StringExt.hpp>
#include <cstring>
#include <Nazara/Core/Debug.hpp>
@@ -147,22 +147,24 @@ namespace Nz
* \param string String to write
*/
bool Stream::Write(const String& string)
bool Stream::Write(const std::string_view& string)
{
String temp(string);
if (m_streamOptions & StreamOption_Text)
{
#if defined(NAZARA_PLATFORM_WINDOWS)
temp.Replace("\n", "\r\n");
#elif defined(NAZARA_PLATFORM_LINUX)
#if defined(NAZARA_PLATFORM_WINDOWS)
std::string temp(string);
ReplaceStr(temp, "\n", "\r\n");
#elif defined(NAZARA_PLATFORM_LINUX)
std::string_view temp(string);
// Nothing to do
#elif defined(NAZARA_PLATFORM_MACOS)
temp.Replace('\n', '\r');
#endif
}
#elif defined(NAZARA_PLATFORM_MACOS)
std::string temp(string);
ReplaceStr(temp, "\n", "\r");
#endif
std::size_t size = temp.GetSize();
return Write(temp.GetConstBuffer(), size) == size;
return Write(temp.data(), temp.size()) == temp.size();
}
else
return Write(string.data(), string.size()) == string.size();
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -13,7 +13,18 @@ namespace Nz
{
bool IsSpace(char32_t character)
{
return character == '\t' || Unicode::GetCategory(character) & Unicode::Category_Separator;
switch (character)
{
case '\f':
case '\n':
case '\r':
case '\t':
case '\v':
return true;
default:
return Unicode::GetCategory(character) & Unicode::Category_Separator;
}
}
char ToLower(char character)
@@ -79,12 +90,6 @@ namespace Nz
};
}
std::string FromUtf16String(const char16_t* u16str)
{
std::size_t size = std::char_traits<char16_t>::length(u16str);
return FromUtf16String(std::u16string_view(u16str, size));
}
std::string FromUtf16String(const std::u16string_view& u16str)
{
std::string result;
@@ -93,12 +98,6 @@ namespace Nz
return result;
}
std::string FromUtf32String(const char32_t* u32str)
{
std::size_t size = std::char_traits<char32_t>::length(u32str);
return FromUtf32String(std::u32string_view(u32str, size));
}
std::string FromUtf32String(const std::u32string_view& u32str)
{
std::string result;
@@ -107,17 +106,56 @@ namespace Nz
return result;
}
std::string FromWideString(const wchar_t* wstr)
{
std::size_t size = std::char_traits<wchar_t>::length(wstr);
return WideConverter<sizeof(wchar_t)>::From(wstr, size);
}
std::string FromWideString(const std::wstring_view& wstr)
{
return WideConverter<sizeof(wchar_t)>::From(wstr.data(), wstr.size());
}
std::string_view GetWord(const std::string_view& str, std::size_t wordIndex)
{
std::size_t pos = 0;
std::size_t previousPos = 0;
while ((pos = str.find_first_of(" \f\n\r\t\v", previousPos)) != std::string::npos)
{
std::size_t splitPos = previousPos;
previousPos = pos + 1;
if (pos != splitPos && wordIndex-- == 0)
return str.substr(splitPos, pos - splitPos);
}
return {};
}
std::string_view GetWord(const std::string_view& str, std::size_t wordIndex, UnicodeAware)
{
utf8::unchecked::iterator<const char*> it(str.data());
utf8::unchecked::iterator<const char*> end(str.data() + str.size());
auto FindNextSeparator = [&]() -> std::size_t
{
for (; it != end; ++it)
{
if (IsSpace(*it))
return true;
}
return false;
};
utf8::unchecked::iterator<const char*> lastSplit = it;
while (FindNextSeparator())
{
if (it != lastSplit && wordIndex-- == 0)
return std::string_view(lastSplit.base(), it.base() - lastSplit.base());
++it;
lastSplit = it;
}
return {};
}
bool MatchPattern(const std::string_view& str, const std::string_view& pattern)
{
if (str.empty() || pattern.empty())
@@ -169,27 +207,60 @@ namespace Nz
return patternPtr >= patternPtrEnd;
}
bool StartsWith(const std::string_view& str, const std::string_view& s, CaseIndependent)
std::string PointerToString(const void* ptr)
{
if (s.size() > str.size())
constexpr std::size_t capacity = sizeof(void*) * 2 + 2;
std::string str(capacity, '\0');
str.resize(std::sprintf(str.data(), "0x%p", ptr));
return str;
}
bool StartsWith(const std::string_view& lhs, const std::string_view& rhs, CaseIndependent)
{
if (rhs.size() > lhs.size())
return false;
return std::equal(str.begin(), str.begin() + s.size(), s.begin(), s.end(), [](char c1, char c2)
return std::equal(lhs.begin(), lhs.begin() + rhs.size(), rhs.begin(), rhs.end(), [](char c1, char c2)
{
return ToLower(c1) == ToLower(c2);
});
}
bool StartsWith(const std::string_view& str, const std::string_view& s, CaseIndependent, UnicodeAware)
bool StartsWith(const std::string_view& lhs, const std::string_view& rhs, UnicodeAware)
{
if (str.empty() || s.empty())
return str == s;
if (lhs.empty() || rhs.empty())
return lhs == rhs;
utf8::iterator<const char*> it(str.data(), str.data(), str.data() + str.size());
utf8::iterator<const char*> it2(s.data(), s.data(), s.data() + s.size());
utf8::iterator<const char*> it(lhs.data(), lhs.data(), lhs.data() + lhs.size());
utf8::iterator<const char*> it2(rhs.data(), rhs.data(), rhs.data() + rhs.size());
do
{
if (it2.base() >= s.data() + s.size())
if (it2.base() >= rhs.data() + rhs.size())
return true;
if (*it != *it2)
return false;
++it2;
}
while (*it++);
return true;
}
bool StartsWith(const std::string_view& lhs, const std::string_view& rhs, CaseIndependent, UnicodeAware)
{
if (lhs.empty() || rhs.empty())
return lhs == rhs;
utf8::iterator<const char*> it(lhs.data(), lhs.data(), lhs.data() + lhs.size());
utf8::iterator<const char*> it2(rhs.data(), rhs.data(), rhs.data() + rhs.size());
do
{
if (it2.base() >= rhs.data() + rhs.size())
return true;
if (Unicode::GetLowercase(*it) != Unicode::GetLowercase(*it2))
@@ -202,6 +273,40 @@ namespace Nz
return true;
}
bool StringEqual(const std::string_view& lhs, const std::string_view& rhs, UnicodeAware)
{
if (lhs.empty() || rhs.empty())
return lhs == rhs;
utf8::iterator<const char*> it(lhs.data(), lhs.data(), lhs.data() + lhs.size());
utf8::iterator<const char*> it2(rhs.data(), rhs.data(), rhs.data() + rhs.size());
for (; it.base() < lhs.data() + lhs.size(); ++it, ++it2)
{
if (*it != *it2)
return false;
}
return true;
}
bool StringEqual(const std::string_view& lhs, const std::string_view& rhs, CaseIndependent, UnicodeAware)
{
if (lhs.empty() || rhs.empty())
return lhs == rhs;
utf8::iterator<const char*> it(lhs.data(), lhs.data(), lhs.data() + lhs.size());
utf8::iterator<const char*> it2(rhs.data(), rhs.data(), rhs.data() + rhs.size());
for (; it.base() < lhs.data() + lhs.size(); ++it, ++it2)
{
if (Unicode::GetLowercase(*it) != Unicode::GetLowercase(*it2))
return false;
}
return true;
}
std::string ToLower(const std::string_view& str)
{
std::string result;
@@ -220,9 +325,9 @@ namespace Nz
result.reserve(str.size());
utf8::unchecked::iterator<const char*> it(str.data());
do
utf8::unchecked::iterator<const char*> end(str.data() + str.size());
for (; it != end; ++it)
utf8::append(Unicode::GetLowercase(*it), std::back_inserter(result));
while (*++it);
return result;
}
@@ -244,10 +349,10 @@ namespace Nz
std::string result;
result.reserve(str.size());
utf8::iterator<const char*> it(str.data(), str.data(), str.data() + str.size());
do
utf8::unchecked::iterator<const char*> it(str.data());
utf8::unchecked::iterator<const char*> end(str.data() + str.size());
for (; it != end; ++it)
utf8::append(Unicode::GetUppercase(*it), std::back_inserter(result));
while (*++it);
return result;
}
@@ -272,6 +377,151 @@ namespace Nz
{
return WideConverter<sizeof(wchar_t)>::To(str);
}
std::string_view TrimLeft(std::string_view str)
{
while (!str.empty() && IsSpace(str.front()))
str.remove_prefix(1);
return str;
}
std::string_view TrimLeft(std::string_view str, UnicodeAware)
{
utf8::unchecked::iterator<const char*> it(str.data());
utf8::unchecked::iterator<const char*> end(str.data() + str.size());
while (it != end && IsSpace(*it))
++it;
return std::string_view(it.base(), end.base() - it.base());
}
std::string_view TrimLeft(std::string_view str, char32_t c, UnicodeAware)
{
utf8::unchecked::iterator<const char*> it(str.data());
utf8::unchecked::iterator<const char*> end(str.data() + str.size());
while (it != end && *it == c)
++it;
return std::string_view(it.base(), end.base() - it.base());
}
std::string_view TrimLeft(std::string_view str, char32_t c, CaseIndependent, UnicodeAware)
{
utf8::unchecked::iterator<const char*> it(str.data());
utf8::unchecked::iterator<const char*> end(str.data() + str.size());
c = Unicode::GetLowercase(c);
while (it != end && Unicode::GetLowercase(*it) == c)
++it;
return std::string_view(it.base(), end.base() - it.base());
}
std::string_view TrimLeft(std::string_view str, Unicode::Category category, UnicodeAware)
{
utf8::unchecked::iterator<const char*> it(str.data());
utf8::unchecked::iterator<const char*> end(str.data() + str.size());
while (it != end && (Unicode::GetCategory(*it) & category) == category)
++it;
return std::string_view(it.base(), end.base() - it.base());
}
std::string_view TrimRight(std::string_view str)
{
while (!str.empty() && IsSpace(str.back()))
str.remove_suffix(1);
return str;
}
std::string_view TrimRight(std::string_view str, UnicodeAware)
{
if (str.empty())
return str;
// Find last character head
const char* lastCharacter = str.data() + str.size() - 1;
while (utf8::internal::is_trail(*lastCharacter) && lastCharacter != str.data())
--lastCharacter;
utf8::unchecked::iterator<const char*> start(str.data());
utf8::unchecked::iterator<const char*> it(lastCharacter);
while (it != start && IsSpace(*it))
--it;
++it;
return std::string_view(start.base(), it.base() - start.base());
}
std::string_view TrimRight(std::string_view str, char32_t c, UnicodeAware)
{
if (str.empty())
return str;
// Find last character head
const char* lastCharacter = str.data() + str.size() - 1;
while (utf8::internal::is_trail(*lastCharacter) && lastCharacter != str.data())
--lastCharacter;
utf8::unchecked::iterator<const char*> start(str.data());
utf8::unchecked::iterator<const char*> it(lastCharacter);
while (it != start && *it == c)
--it;
++it;
return std::string_view(start.base(), it.base() - start.base());
}
std::string_view TrimRight(std::string_view str, char32_t c, CaseIndependent, UnicodeAware)
{
if (str.empty())
return str;
// Find last character head
const char* lastCharacter = str.data() + str.size() - 1;
while (utf8::internal::is_trail(*lastCharacter) && lastCharacter != str.data())
--lastCharacter;
utf8::unchecked::iterator<const char*> start(str.data());
utf8::unchecked::iterator<const char*> it(lastCharacter);
c = Unicode::GetLowercase(c);
while (it != start && Unicode::GetLowercase(*it) == c)
--it;
++it;
return std::string_view(start.base(), it.base() - start.base());
}
std::string_view TrimRight(std::string_view str, Unicode::Category category, UnicodeAware)
{
if (str.empty())
return str;
// Find last character head
const char* lastCharacter = str.data() + str.size() - 1;
while (utf8::internal::is_trail(*lastCharacter) && lastCharacter != str.data())
--lastCharacter;
utf8::unchecked::iterator<const char*> start(str.data());
utf8::unchecked::iterator<const char*> it(lastCharacter);
while (it != start && (Unicode::GetCategory(*it) & category) == category)
--it;
++it;
return std::string_view(start.base(), it.base() - start.base());
}
}
#include <Nazara/Core/DebugOff.hpp>

View File

@@ -1,349 +0,0 @@
// Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/StringStream.hpp>
#include <Nazara/Math/Algorithm.hpp>
#include <array>
#include <limits>
#include <Nazara/Core/Debug.hpp>
namespace Nz
{
/*!
* \ingroup core
* \class Nz::StringStream
* \brief Core class that represents a stream of strings
*/
/*!
* \brief Constructs a StringStream object with a string
*
* \param str First value of the stream
*/
StringStream::StringStream(String str) :
m_result(std::move(str))
{
}
/*!
* \brief Resets the state of the stream, erasing every contained text
*/
void StringStream::Clear()
{
m_result.Clear();
}
/*!
* \brief Get the current buffer size
* \return The internal accumulation buffer size, this is equivalent to the size of the final string
*/
std::size_t StringStream::GetBufferSize() const
{
return m_result.GetSize();
}
/*!
* \brief Gives a string representation
* \return A string representation of the object where every objects of the stream has been converted with Nz::String
*/
String StringStream::ToString() const
{
return m_result;
}
/*!
* \brief Adds the representation of the boolean
* \return A reference to this
*
* \param boolean Boolean value
*/
StringStream& StringStream::operator<<(bool boolean)
{
std::size_t size = (boolean) ? 4 : 5;
std::size_t start = m_result.GetSize();
m_result.Resize(start + size);
std::memcpy(&m_result[start], (boolean) ? "true" : "false", size);
return *this;
}
/*!
* \brief Adds the representation of the short
* \return A reference to this
*
* \param number Short value
*/
StringStream& StringStream::operator<<(short number)
{
constexpr std::size_t maxSize = std::numeric_limits<short>::digits10 + 2;
std::size_t start = m_result.GetSize();
m_result.Resize(start + maxSize);
std::size_t written = std::snprintf(&m_result[start], maxSize + 1, "%hd", number);
m_result.Resize(start + written);
return *this;
}
/*!
* \brief Adds the representation of the unsigned short
* \return A reference to this
*
* \param number Short value
*/
StringStream& StringStream::operator<<(unsigned short number)
{
constexpr std::size_t maxSize = std::numeric_limits<unsigned short>::digits10 + 1;
std::size_t start = m_result.GetSize();
m_result.Resize(start + maxSize);
std::size_t written = std::snprintf(&m_result[start], maxSize + 1, "%hu", number);
m_result.Resize(start + written);
return *this;
}
/*!
* \brief Adds the representation of the int
* \return A reference to this
*
* \param number Int value
*/
StringStream& StringStream::operator<<(int number)
{
constexpr std::size_t maxSize = std::numeric_limits<int>::digits10 + 2;
std::size_t start = m_result.GetSize();
m_result.Resize(start + maxSize);
std::size_t written = std::snprintf(&m_result[start], maxSize + 1, "%d", number);
m_result.Resize(start + written);
return *this;
}
/*!
* \brief Adds the representation of the unsigned int
* \return A reference to this
*
* \param number Int value
*/
StringStream& StringStream::operator<<(unsigned int number)
{
constexpr std::size_t maxSize = std::numeric_limits<unsigned int>::digits10 + 1;
std::size_t start = m_result.GetSize();
m_result.Resize(start + maxSize);
std::size_t written = std::snprintf(&m_result[start], maxSize + 1, "%u", number);
m_result.Resize(start + written);
return *this;
}
/*!
* \brief Adds the representation of the long
* \return A reference to this
*
* \param number Long value
*/
StringStream& StringStream::operator<<(long number)
{
constexpr std::size_t maxSize = std::numeric_limits<long>::digits10 + 2;
std::size_t start = m_result.GetSize();
m_result.Resize(start + maxSize);
std::size_t written = std::snprintf(&m_result[start], maxSize + 1, "%ld", number);
m_result.Resize(start + written);
return *this;
}
/*!
* \brief Adds the representation of the unsigned long
* \return A reference to this
*
* \param number Long value
*/
StringStream& StringStream::operator<<(unsigned long number)
{
constexpr std::size_t maxSize = std::numeric_limits<unsigned long>::digits10 + 1;
std::size_t start = m_result.GetSize();
m_result.Resize(start + maxSize);
std::size_t written = std::snprintf(&m_result[start], maxSize + 1, "%lu", number);
m_result.Resize(start + written);
return *this;
}
/*!
* \brief Adds the representation of the long long
* \return A reference to this
*
* \param number Long long value
*/
StringStream& StringStream::operator<<(long long number)
{
constexpr std::size_t maxSize = std::numeric_limits<long long>::digits10 + 2;
std::size_t start = m_result.GetSize();
m_result.Resize(start + maxSize);
std::size_t written = std::snprintf(&m_result[start], maxSize + 1, "%lld", number);
m_result.Resize(start + written);
return *this;
}
/*!
* \brief Adds the representation of the unsigned long long
* \return A reference to this
*
* \param number Long long value
*/
StringStream& StringStream::operator<<(unsigned long long number)
{
constexpr std::size_t maxSize = std::numeric_limits<unsigned long long>::digits10 + 1;
std::size_t start = m_result.GetSize();
m_result.Resize(start + maxSize);
std::size_t written = std::snprintf(&m_result[start], maxSize + 1, "%llu", number);
m_result.Resize(start + written);
return *this;
}
/*!
* \brief Adds the representation of the float
* \return A reference to this
*
* \param number Float value
*/
StringStream& StringStream::operator<<(float number)
{
return operator<<(double(number)); //< snprintf doesn't support float anyway
}
/*!
* \brief Adds the representation of the double
* \return A reference to this
*
* \param number Double value
*/
StringStream& StringStream::operator<<(double number)
{
// https://stackoverflow.com/questions/1701055/what-is-the-maximum-length-in-chars-needed-to-represent-any-double-value
const std::size_t maxSize = 3 + std::numeric_limits<double>::digits - std::numeric_limits<double>::min_exponent;
// Use a temporary buffer to prevent 1kb string capacity growth
std::array<char, maxSize + 1> buffer;
std::size_t written = std::snprintf(buffer.data(), buffer.size(), "%.6f", number);
std::size_t start = m_result.GetSize();
m_result.Resize(start + written);
std::memcpy(&m_result[start], buffer.data(), written);
return *this;
}
/*!
* \brief Adds the representation of the long double
* \return A reference to this
*
* \param number Long double value
*/
StringStream& StringStream::operator<<(long double number)
{
// https://stackoverflow.com/questions/1701055/what-is-the-maximum-length-in-chars-needed-to-represent-any-double-value
const std::size_t maxSize = 3 + std::numeric_limits<long double>::digits - std::numeric_limits<long double>::min_exponent;
// Use a temporary buffer to prevent 1kb string capacity growth
std::array<char, maxSize + 1> buffer;
std::size_t written = std::snprintf(buffer.data(), buffer.size(), "%.6Lf", number);
std::size_t start = m_result.GetSize();
m_result.Resize(start + written);
std::memcpy(&m_result[start], buffer.data(), written);
return *this;
}
/*!
* \brief Adds the representation of the char
* \return A reference to this
*
* \param character Char value
*/
StringStream& StringStream::operator<<(char character)
{
m_result.Append(character);
return *this;
}
/*!
* \brief Adds the representation of the unsigned char
* \return A reference to this
*
* \param character Char value
*/
StringStream& StringStream::operator<<(unsigned char character)
{
m_result.Append(static_cast<unsigned char>(character));
return *this;
}
/*!
* \brief Adds the representation of the const char*
* \return A reference to this
*
* \param string String value
*/
StringStream& StringStream::operator<<(const char* string)
{
m_result.Append(string);
return *this;
}
/*!
* \brief Adds the representation of the std::string
* \return A reference to this
*
* \param string String value
*/
StringStream& StringStream::operator<<(const std::string& string)
{
m_result.Append(string.data(), string.size());
return *this;
}
/*!
* \brief Adds the representation of the Nz::String
* \return A reference to this
*
* \param string String value
*/
StringStream& StringStream::operator<<(const String& string)
{
m_result.Append(string);
return *this;
}
/*!
* \brief Adds the representation of the pointer
* \return A reference to this
*
* \param ptr Pointer value
*/
StringStream& StringStream::operator<<(const void* ptr)
{
constexpr std::size_t maxSize = sizeof(void*) * 2 + 2;
std::size_t start = m_result.GetSize();
m_result.Resize(start + maxSize);
std::size_t written = std::snprintf(&m_result[start], maxSize + 1, "0x%p", ptr);
m_result.Resize(start + written);
return *this;
}
/*!
* \brief Converts this to Nz::String
* \return The string representation of the stream
*/
StringStream::operator String() const
{
return ToString();
}
}

View File

@@ -149,7 +149,7 @@ namespace Nz
break;
default:
NazaraInternalError("Cursor position not handled (0x" + String::Number(pos, 16) + ')');
NazaraInternalError("Cursor position not handled (0x" + NumberToString(pos, 16) + ')');
return false;
}