#pragma once //convert any (supported) type to a const char* without constructing a new nall::string //this is used inside string{...} to build nall::string values namespace nall { //booleans template<> struct stringify { stringify(bool value) : _value(value) {} auto data() const -> const char* { return _value ? "true" : "false"; } auto size() const -> uint { return _value ? 4 : 5; } bool _value; }; template<> struct stringify { stringify(bool value) : _value(value) {} auto data() const -> const char* { return _value ? "true" : "false"; } auto size() const -> uint { return _value ? 4 : 5; } bool _value; }; //characters template<> struct stringify { stringify(char source) { _data[0] = source; _data[1] = 0; } auto data() const -> const char* { return _data; } auto size() const -> uint { return 1; } char _data[2]; }; //signed integers template<> struct stringify { stringify(signed char source) { fromInteger(_data, source); } auto data() const -> const char* { return _data; } auto size() const -> uint { return strlen(_data); } char _data[2 + sizeof(signed char) * 3]; }; template<> struct stringify { stringify(signed short source) { fromInteger(_data, source); } auto data() const -> const char* { return _data; } auto size() const -> uint { return strlen(_data); } char _data[2 + sizeof(signed short) * 3]; }; template<> struct stringify { stringify(signed int source) { fromInteger(_data, source); } auto data() const -> const char* { return _data; } auto size() const -> uint { return strlen(_data); } char _data[2 + sizeof(signed int) * 3]; }; template<> struct stringify { stringify(signed long source) { fromInteger(_data, source); } auto data() const -> const char* { return _data; } auto size() const -> uint { return strlen(_data); } char _data[2 + sizeof(signed long) * 3]; }; template<> struct stringify { stringify(signed long long source) { fromInteger(_data, source); } auto data() const -> const char* { return _data; } auto size() const -> uint { return strlen(_data); } char _data[2 + sizeof(signed long long) * 3]; }; #if defined(__SIZEOF_INT128__) template<> struct stringify { stringify(int128_t source) { fromInteger(_data, source); } auto data() const -> const char* { return _data; } auto size() const -> uint { return strlen(_data); } char _data[2 + sizeof(int128_t) * 3]; }; #endif template struct stringify> { stringify(Integer source) { fromInteger(_data, source); } auto data() const -> const char* { return _data; } auto size() const -> uint { return strlen(_data); } char _data[2 + sizeof(int64_t) * 3]; }; //unsigned integers template<> struct stringify { stringify(unsigned char source) { fromNatural(_data, source); } auto data() const -> const char* { return _data; } auto size() const -> uint { return strlen(_data); } char _data[1 + sizeof(unsigned char) * 3]; }; template<> struct stringify { stringify(unsigned short source) { fromNatural(_data, source); } auto data() const -> const char* { return _data; } auto size() const -> uint { return strlen(_data); } char _data[1 + sizeof(unsigned short) * 3]; }; template<> struct stringify { stringify(unsigned int source) { fromNatural(_data, source); } auto data() const -> const char* { return _data; } auto size() const -> uint { return strlen(_data); } char _data[1 + sizeof(unsigned int) * 3]; }; template<> struct stringify { stringify(unsigned long source) { fromNatural(_data, source); } auto data() const -> const char* { return _data; } auto size() const -> uint { return strlen(_data); } char _data[1 + sizeof(unsigned long) * 3]; }; template<> struct stringify { stringify(unsigned long long source) { fromNatural(_data, source); } auto data() const -> const char* { return _data; } auto size() const -> uint { return strlen(_data); } char _data[1 + sizeof(unsigned long long) * 3]; }; #if defined(__SIZEOF_INT128__) template<> struct stringify { stringify(uint128_t source) { fromNatural(_data, source); } auto data() const -> const char* { return _data; } auto size() const -> uint { return strlen(_data); } char _data[1 + sizeof(uint128_t) * 3]; }; #endif template struct stringify> { stringify(Natural source) { fromNatural(_data, source); } auto data() const -> const char* { return _data; } auto size() const -> uint { return strlen(_data); } char _data[1 + sizeof(uint64_t) * 3]; }; //floating-point template<> struct stringify { stringify(float source) { fromReal(_data, source); } auto data() const -> const char* { return _data; } auto size() const -> uint { return strlen(_data); } char _data[256]; }; template<> struct stringify { stringify(double source) { fromReal(_data, source); } auto data() const -> const char* { return _data; } auto size() const -> uint { return strlen(_data); } char _data[256]; }; template<> struct stringify { stringify(long double source) { fromReal(_data, source); } auto data() const -> const char* { return _data; } auto size() const -> uint { return strlen(_data); } char _data[256]; }; template struct stringify> { stringify(Real source) { fromReal(_data, source); } auto data() const -> const char* { return _data; } auto size() const -> uint { return strlen(_data); } char _data[256]; }; //arrays template<> struct stringify> { stringify(const vector& source) { _text.resize(source.size()); memory::copy(_text.data(), source.data(), source.size()); } auto data() const -> const char* { return _text.data(); } auto size() const -> uint { return _text.size(); } vector _text; }; //char arrays template<> struct stringify { stringify(const char* source) : _data(source ? source : "") {} auto data() const -> const char* { return _data; } auto size() const -> uint { return strlen(_data); } const char* _data; }; template<> struct stringify { stringify(const char* source) : _data(source ? source : "") {} auto data() const -> const char* { return _data; } auto size() const -> uint { return strlen(_data); } const char* _data; }; //strings template<> struct stringify { stringify(const string& source) : _text(source) {} auto data() const -> const char* { return _text.data(); } auto size() const -> uint { return _text.size(); } const string& _text; }; template<> struct stringify { stringify(const string_view& source) : _view(source) {} auto data() const -> const char* { return _view.data(); } auto size() const -> uint { return _view.size(); } const string_view& _view; }; template<> struct stringify> { stringify(const array_view& source) : _view(source) {} auto data() const -> const char* { return _view.data(); } auto size() const -> uint { return _view.size(); } const array_view& _view; }; template<> struct stringify { stringify(const string_pascal& source) : _text(source) {} auto data() const -> const char* { return _text.data(); } auto size() const -> uint { return _text.size(); } const string_pascal& _text; }; //pointers //note: T = char* is matched by stringify template struct stringify { stringify(const T* source) { if(!source) { memory::copy(_data, "(nullptr)", 10); } else { memory::copy(_data, "0x", 2); fromNatural(_data + 2, (uintptr)source); } } auto data() const -> const char* { return _data; } auto size() const -> uint { return strlen(_data); } char _data[256]; }; // template auto make_string(const T& value) { return stringify>(value); } }