Last active
June 10, 2021 09:00
-
-
Save faithandbrave/c61a32e5bff5e0cf52510396abb7b94f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <cstring> | |
#include <limits> | |
#include <stdexcept> | |
template <std::size_t N> | |
class static_string { | |
char buffer_[N] = {}; | |
std::size_t size_ = 0; | |
public: | |
static_string() = default; | |
static_string(const char* s) { | |
std::size_t n = std::strlen(s); | |
if (n >= N) { | |
throw std::invalid_argument("assign too long string"); | |
} | |
std::strcpy(buffer_, s); | |
size_ = n; | |
} | |
static_string& operator=(const char* s) { | |
std::size_t n = std::strlen(s); | |
if (n >= N) { | |
throw std::invalid_argument("assign too long string"); | |
} | |
std::memset(buffer_, 0, N); | |
std::strcpy(buffer_, s); | |
size_ = n; | |
} | |
static_string& append(const char* s) { | |
std::size_t n = std::strlen(s); | |
if (size_ + n >= N) { | |
throw std::invalid_argument("assign too long string"); | |
} | |
std::strcpy(buffer_ + size_, s); | |
size_ += n; | |
return *this; | |
} | |
static_string& append(char c) { | |
if (size_ + 1 >= N) { | |
throw std::invalid_argument("assign too long string"); | |
} | |
buffer_[size_] = c; | |
++size_; | |
return *this; | |
} | |
template <std::size_t M> | |
static_string& append(static_string<M> s) { | |
return append(s.c_str()); | |
} | |
static_string& operator+=(const char* s) { | |
append(s); | |
return *this; | |
} | |
static_string& operator+=(char c) { | |
append(c); | |
return *this; | |
} | |
const char* c_str() const noexcept { | |
return buffer_; | |
} | |
template <class OStream> | |
friend OStream& operator<<(OStream& os, const static_string& s) { | |
os << s.c_str(); | |
return os; | |
} | |
friend static_string operator+(static_string a, const char* b) { | |
a += b; | |
return a; | |
} | |
friend static_string operator+(const char* a, static_string b) { | |
return static_string{a} + b; | |
} | |
friend static_string operator+(static_string a, char b) { | |
a += b; | |
return a; | |
} | |
friend static_string operator+(char a, static_string b) { | |
return static_string{a} + b; | |
} | |
}; | |
template <std::size_t N> | |
class static_stringstream { | |
static_string<N> buffer_; | |
public: | |
static_string<N> str() const noexcept { | |
return buffer_; | |
} | |
static_stringstream& operator<<(char c) { | |
buffer_ += c; | |
return *this; | |
} | |
static_stringstream& operator<<(const char* s) { | |
buffer_ += s; | |
return *this; | |
} | |
static_stringstream& operator<<(int val) { | |
char s[std::numeric_limits<int>::digits10 + 1 | |
+ 2]; // '-' + '\0' | |
std::sprintf(s, "%d", val); | |
buffer_ += s; | |
return *this; | |
} | |
static_stringstream& operator<<(unsigned int val) { | |
char s[std::numeric_limits<unsigned int>::digits10 + 1 | |
+ 1]; // '\0' | |
std::sprintf(s, "%u", val); | |
buffer_ += s; | |
return *this; | |
} | |
static_stringstream& operator<<(long long val) { | |
char s[std::numeric_limits<long long>::digits10 + 1 | |
+ 2]; // '-' + '\0' | |
std::sprintf(s, "%lld", val); | |
buffer_ += s; | |
return *this; | |
} | |
static_stringstream& operator<<(unsigned long long val) { | |
char s[std::numeric_limits<unsigned long long>::digits10 + 1 | |
+ 1]; // '\0' | |
std::sprintf(s, "%llu", val); | |
buffer_ += s; | |
return *this; | |
} | |
static_stringstream& operator<<(float val) { | |
char s[std::numeric_limits<float>::max_exponent10 + 1 | |
+ 6 // fixed precision (printf's default) | |
+ 3]; // '-' + '.' + '\0' | |
std::sprintf(s, "%g", val); | |
buffer_ += s; | |
return *this; | |
} | |
static_stringstream& operator<<(double val) { | |
char s[std::numeric_limits<double>::max_exponent10 + 1 | |
+ 6 // fixed precision (printf's default) | |
+ 3]; // '-' + '.' + '\0' | |
std::sprintf(s, "%g", val); | |
buffer_ += s; | |
return *this; | |
} | |
}; | |
#include <iostream> | |
int main() | |
{ | |
static_stringstream<16> s; | |
s << "Hello " << 123 << ' ' << 3.14; | |
std::cout << s.str() << std::endl; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment