mirror of
https://github.com/The-Powder-Toy/The-Powder-Toy.git
synced 2025-08-10 02:16:37 +02:00
StringBuilder mockup
This commit is contained in:
@@ -2,6 +2,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <locale>
|
#include <locale>
|
||||||
#include <codecvt>
|
#include <codecvt>
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
#include "String.h"
|
#include "String.h"
|
||||||
|
|
||||||
@@ -88,6 +89,164 @@ ByteString String::ToUtf8() const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline String::value_type widen_wchar(wchar_t ch)
|
||||||
|
{
|
||||||
|
return std::make_unsigned<wchar_t>::type(ch);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool representable_wchar(String::value_type ch)
|
||||||
|
{
|
||||||
|
return ch < String::value_type(std::make_unsigned<wchar_t>::type(std::numeric_limits<wchar_t>::max()));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline wchar_t narrow_wchar(String::value_type ch)
|
||||||
|
{
|
||||||
|
return wchar_t(ch);
|
||||||
|
}
|
||||||
|
|
||||||
|
static thread_local struct LocaleImpl
|
||||||
|
{
|
||||||
|
std::basic_stringstream<char> stream;
|
||||||
|
std::basic_stringstream<wchar_t> wstream;
|
||||||
|
|
||||||
|
LocaleImpl()
|
||||||
|
{
|
||||||
|
stream.imbue(std::locale::classic());
|
||||||
|
wstream.imbue(std::locale::classic());
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void PrepareWStream(StringBuilder &b)
|
||||||
|
{
|
||||||
|
wstream.flags(b.flags);
|
||||||
|
wstream.width(b.width);
|
||||||
|
wstream.precision(b.precision);
|
||||||
|
wstream.fill(b.fill);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void FlushWStream(StringBuilder &b)
|
||||||
|
{
|
||||||
|
std::basic_string<wchar_t> wstr = wstream.str();
|
||||||
|
std::vector<String::value_type> chars; // operator new?
|
||||||
|
chars.reserve(wstr.size());
|
||||||
|
for(wchar_t ch : wstream.str())
|
||||||
|
chars.push_back(widen_wchar(ch));
|
||||||
|
b.AddChars(chars.data(), chars.size());
|
||||||
|
wstream.str(std::basic_string<wchar_t>());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LocaleImpl;
|
||||||
|
|
||||||
|
String StringBuilder::Build() const
|
||||||
|
{
|
||||||
|
return String(buffer.begin(), buffer.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
void StringBuilder::AddChars(String::value_type const *data, size_t count)
|
||||||
|
{
|
||||||
|
buffer.reserve(buffer.size() + count);
|
||||||
|
buffer.insert(buffer.end(), data, data + count);
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuilder &operator<<(StringBuilder &b, short int data)
|
||||||
|
{
|
||||||
|
LocaleImpl.PrepareWStream(b);
|
||||||
|
LocaleImpl.wstream << data;
|
||||||
|
LocaleImpl.FlushWStream(b);
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuilder &operator<<(StringBuilder &b, int data)
|
||||||
|
{
|
||||||
|
LocaleImpl.PrepareWStream(b);
|
||||||
|
LocaleImpl.wstream << data;
|
||||||
|
LocaleImpl.FlushWStream(b);
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuilder &operator<<(StringBuilder &b, long int data)
|
||||||
|
{
|
||||||
|
LocaleImpl.PrepareWStream(b);
|
||||||
|
LocaleImpl.wstream << data;
|
||||||
|
LocaleImpl.FlushWStream(b);
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuilder &operator<<(StringBuilder &b, long long int data)
|
||||||
|
{
|
||||||
|
LocaleImpl.PrepareWStream(b);
|
||||||
|
LocaleImpl.wstream << data;
|
||||||
|
LocaleImpl.FlushWStream(b);
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuilder &operator<<(StringBuilder &b, unsigned short int data)
|
||||||
|
{
|
||||||
|
LocaleImpl.PrepareWStream(b);
|
||||||
|
LocaleImpl.wstream << data;
|
||||||
|
LocaleImpl.FlushWStream(b);
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuilder &operator<<(StringBuilder &b, unsigned int data)
|
||||||
|
{
|
||||||
|
LocaleImpl.PrepareWStream(b);
|
||||||
|
LocaleImpl.wstream << data;
|
||||||
|
LocaleImpl.FlushWStream(b);
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuilder &operator<<(StringBuilder &b, unsigned long int data)
|
||||||
|
{
|
||||||
|
LocaleImpl.PrepareWStream(b);
|
||||||
|
LocaleImpl.wstream << data;
|
||||||
|
LocaleImpl.FlushWStream(b);
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuilder &operator<<(StringBuilder &b, unsigned long long int data)
|
||||||
|
{
|
||||||
|
LocaleImpl.PrepareWStream(b);
|
||||||
|
LocaleImpl.wstream << data;
|
||||||
|
LocaleImpl.FlushWStream(b);
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuilder &operator<<(StringBuilder &b, ByteString::value_type data)
|
||||||
|
{
|
||||||
|
String::value_type ch = data;
|
||||||
|
b.AddChars(&ch, 1);
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuilder &operator<<(StringBuilder &b, String::value_type data)
|
||||||
|
{
|
||||||
|
b.AddChars(&data, 1);
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuilder &operator<<(StringBuilder &b, String const &data)
|
||||||
|
{
|
||||||
|
b.AddChars(data.data(), data.size());
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuilder &operator<<(StringBuilder &b, float data)
|
||||||
|
{
|
||||||
|
LocaleImpl.PrepareWStream(b);
|
||||||
|
LocaleImpl.wstream << data;
|
||||||
|
LocaleImpl.FlushWStream(b);
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuilder &operator<<(StringBuilder &b, double data)
|
||||||
|
{
|
||||||
|
LocaleImpl.PrepareWStream(b);
|
||||||
|
LocaleImpl.wstream << data;
|
||||||
|
LocaleImpl.FlushWStream(b);
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
template<> std::ctype<char32_t>::~ctype()
|
template<> std::ctype<char32_t>::~ctype()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@@ -3,9 +3,13 @@
|
|||||||
|
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <ios>
|
||||||
|
|
||||||
|
class ByteStringBuilder;
|
||||||
class String;
|
class String;
|
||||||
|
class StringBuilder;
|
||||||
|
|
||||||
template<typename T> class SplitBase
|
template<typename T> class SplitBase
|
||||||
{
|
{
|
||||||
@@ -244,4 +248,41 @@ public:
|
|||||||
inline ConversionError(bool to): std::runtime_error(to ? "Could not convert to UTF-8" : "Could not convert from UTF-8") {}
|
inline ConversionError(bool to): std::runtime_error(to ? "Could not convert to UTF-8" : "Could not convert from UTF-8") {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class StringBuilder
|
||||||
|
{
|
||||||
|
std::vector<String::value_type> buffer; // TODO: std::list<std::vector<String::value_type> > ?
|
||||||
|
public:
|
||||||
|
std::ios_base::fmtflags flags;
|
||||||
|
String::value_type fill;
|
||||||
|
size_t width, precision;
|
||||||
|
inline StringBuilder(): flags(std::ios_base::skipws | std::ios_base::dec), fill(' '), width(0), precision(6) {}
|
||||||
|
|
||||||
|
void AddChars(String::value_type const *, size_t);
|
||||||
|
size_t Size() const { return buffer.size(); }
|
||||||
|
String Build() const;
|
||||||
|
|
||||||
|
template<typename T> StringBuilder &operator<<(T) = delete;
|
||||||
|
|
||||||
|
template<typename T, typename... Ts> StringBuilder &Add(T &&arg, Ts&&... args)
|
||||||
|
{
|
||||||
|
return (*this << std::forward<T>(arg)).Add(std::forward<Ts>(args)...);
|
||||||
|
}
|
||||||
|
StringBuilder &Add() { return *this; }
|
||||||
|
};
|
||||||
|
|
||||||
|
StringBuilder &operator<<(StringBuilder &, short int);
|
||||||
|
StringBuilder &operator<<(StringBuilder &, int);
|
||||||
|
StringBuilder &operator<<(StringBuilder &, long int);
|
||||||
|
StringBuilder &operator<<(StringBuilder &, long long int);
|
||||||
|
StringBuilder &operator<<(StringBuilder &, unsigned short int);
|
||||||
|
StringBuilder &operator<<(StringBuilder &, unsigned int);
|
||||||
|
StringBuilder &operator<<(StringBuilder &, unsigned long int);
|
||||||
|
StringBuilder &operator<<(StringBuilder &, unsigned long long int);
|
||||||
|
StringBuilder &operator<<(StringBuilder &, ByteString::value_type);
|
||||||
|
StringBuilder &operator<<(StringBuilder &, String::value_type);
|
||||||
|
StringBuilder &operator<<(StringBuilder &, String const &);
|
||||||
|
StringBuilder &operator<<(StringBuilder &, float);
|
||||||
|
StringBuilder &operator<<(StringBuilder &, double);
|
||||||
|
template<size_t N> StringBuilder &operator<<(StringBuilder &b, ByteString::value_type const (&data)[N]) { return b << ByteString(data).FromUtf8(); }
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Reference in New Issue
Block a user