| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152 |
- export module Core.ToString;
- import Core.Math;
- import Core.Meta;
- import Core.Types;
- export import Core.StringFormat;
- #define TO_STRING(type) \
- size_t toString(type t, char* s, size_t n, const StringFormat& format = {})
- export namespace Core {
- TO_STRING(signed char);
- TO_STRING(char);
- TO_STRING(short);
- TO_STRING(int);
- TO_STRING(long);
- TO_STRING(long long);
- TO_STRING(unsigned char);
- TO_STRING(unsigned short);
- TO_STRING(unsigned int);
- TO_STRING(unsigned long);
- TO_STRING(unsigned long long);
- TO_STRING(float);
- TO_STRING(double);
- TO_STRING(const char*);
- TO_STRING(const unsigned char*);
- TO_STRING(unsigned char*);
- TO_STRING(bool);
- template<typename T>
- void addString(
- const T& t, char*& s, size_t& n, size_t& total,
- const StringFormat& format = {});
- template<Core::Iterable T>
- size_t toString(
- const T& t, char* s, size_t n, const StringFormat& format = {}) {
- (void)format;
- size_t total = 0;
- addString("[", s, n, total);
- auto current = t.begin();
- auto end = t.end();
- if(current != end) {
- addString(*current, s, n, total);
- ++current;
- }
- while(current != end) {
- addString(", ", s, n, total);
- addString(*current, s, n, total);
- ++current;
- }
- addString("]", s, n, total);
- return total;
- }
- template<typename T>
- concept ToString =
- requires(const T& t, char* s, size_t n) { t.toString(s, n); };
- template<ToString T>
- size_t toString(
- const T& t, char* s, size_t n, const StringFormat& format = {}) {
- (void)format;
- return t.toString(s, n);
- }
- template<typename T>
- void addString(
- const T& t, char*& s, size_t& n, size_t& total,
- const StringFormat& format) {
- size_t w = toString(t, s, n, format);
- total += w;
- w = Core::min(n, w);
- s += w;
- n -= w;
- }
- size_t copyFormatUntil(
- const char*& format, char*& s, size_t& n, StringFormat& f);
- template<typename T, typename... Args>
- void formatR(
- const char*& format, char*& s, size_t& n, size_t& total, const T& t,
- Args&&... args) {
- StringFormat f;
- total += copyFormatUntil(format, s, n, f);
- addString(t, s, n, total, f);
- if constexpr(sizeof...(args) > 0) {
- formatR(format, s, n, total, Core::forward<Args>(args)...);
- }
- }
- template<typename... Args>
- size_t formatBuffer(char* s, size_t n, const char* format, Args&&... args) {
- StringFormat f;
- size_t total = 0;
- if constexpr(sizeof...(args) > 0) {
- formatR(format, s, n, total, Core::forward<Args>(args)...);
- }
- return total + copyFormatUntil(format, s, n, f);
- }
- struct StringBase {
- size_t index = 0;
- size_t capacity = 0;
- char* buffer = nullptr;
- StringBase() {
- }
- StringBase(StringBase&& other) = default;
- StringBase(const StringBase& other) = delete;
- StringBase& operator=(StringBase&& other) = default;
- StringBase& operator=(const StringBase& other) = delete;
- template<typename... Args>
- size_t format(const char* format, Args&&... args) {
- size_t total = formatBuffer(
- buffer + index, capacity - index, format,
- Core::forward<Args>(args)...);
- index = Core::min(index + total, capacity);
- return total;
- }
- template<typename T>
- size_t add(const T& t) {
- size_t total = toString(t, buffer + index, capacity - index);
- index = Core::min(index + total, capacity);
- return total;
- }
- void print();
- };
- template<size_t N>
- struct String : public StringBase {
- char data[N]{};
- String() {
- buffer = data;
- capacity = N;
- }
- };
- template<typename... Args>
- void print(const char* format, Args&&... args) {
- String<256> s;
- s.format(format, Core::forward<Args>(args)...);
- s.print();
- }
- }
|