9 #ifndef _GU_STRING_HPP_
10 #define _GU_STRING_HPP_
12 #include "gu_vector.hpp"
22 #include "gu_macros.h"
30 explicit Fmt(
const char* f) : fmt_(f) {}
31 const char*
const fmt_;
35 template <
typename T =
char>
42 typedef const T* const_pointer;
43 typedef size_t size_type;
45 size_type size()
const {
return size_; }
46 size_type length()
const {
return size(); }
48 pointer c_str() {
return str_; }
49 const_pointer c_str()
const {
return str_; }
59 size_type
const n(s.size());
60 append_string (s.c_str(), n);
66 size_type
const n(::strlen(s));
73 append_string (s.c_str(), s.length());
81 append_string (
"true", 4);
83 append_string (
"false", 5);
90 convert (
"%f", std::numeric_limits<double>::digits10, d);
97 static size_type
const ptr_len(
sizeof(ptr) == 4 ? 11 : 19 );
98 static const char*
const fmt(
sizeof(ptr) == 4 ?
"0x%08lx":
"0x%016lx");
100 convert (fmt, ptr_len, reinterpret_cast<unsigned long>(ptr));
106 convert (
"%lld", 21, i);
110 StringBase& operator<< (
const unsigned long long &i)
112 convert (
"%llu", 20, i);
118 convert (
"%d", 11, i);
122 StringBase& operator<< (
const unsigned int &i)
124 convert (
"%u", 10, i);
130 convert (
"%hd", 6, i);
134 StringBase& operator<< (
const unsigned short &i)
136 convert (
"%hu", 5, i);
142 convert (
"%c", 1, c);
146 StringBase& operator<< (
const unsigned char &c)
148 convert (
"%hhu", 3, c);
152 template <
typename X>
153 StringBase& operator+= (
const X& x) {
return operator<<(x); }
157 return (size() == other.size() && !::strcmp(c_str(), other.c_str()));
160 bool operator== (
const std::string& other)
162 return (size() == other.size() && !::strcmp(c_str(), other.c_str()));
165 bool operator== (
const char* s)
167 size_type
const s_size(::strlen(s));
168 return (size() == s_size && !::strcmp(c_str(), s));
171 template <
typename X>
172 bool operator!= (
const X& x) {
return !operator==(x); }
174 void clear() { derived_clear(); };
179 append_string (other.c_str(), other.size());
183 StringBase& operator= (
const char*
const other)
186 append_string (other, ::strlen(other));
196 virtual void reserve (size_type n) = 0;
197 virtual void derived_clear() = 0;
199 void append_string (const_pointer
const s, size_type
const n)
201 reserve(size_ + n + 1);
202 std::copy(s, s + n, &str_[size_]);
207 template <
typename X>
208 void convert (
const char*
const format, size_type max_len,
const X& x)
211 reserve(size_ + max_len);
212 int const n(snprintf(&str_[size_], max_len, fmt_ ? fmt_ : format, x));
214 assert(size_type(n) < max_len);
215 if (gu_likely(n > 0)) size_ += n;
220 StringBase(pointer init_buf) : str_(init_buf), fmt_(NULL), size_(0) {}
230 template <
typename T>
231 std::ostream& operator<< (std::ostream& os, const gu::StringBase<T>& s)
237 template <
size_t capacity = 256,
typename T =
char>
242 typedef T value_type;
244 typedef const T* const_pointer;
245 typedef size_t size_type;
256 append_string (s.c_str(), s.size());
259 String(
const T* s, size_type n)
262 append_string (s, n);
269 size_type
const n(strlen(s));
270 append_string (s, n);
274 String(
const std::string& s)
277 append_string (s.c_str(), s.length());
289 template <
typename X>
290 String& operator= (
const X& x)
298 if (base::str_ != buf_) ::free(base::str_);
304 value_type buf_[capacity];
308 void reserve (size_type
const n)
310 if (n <= reserved_)
return;
312 assert (n > capacity);
314 bool const overflow(buf_ == base::str_);
317 (static_cast<pointer>
318 (::realloc(overflow ? NULL : base::str_, n *
sizeof(value_type))));
320 if (NULL == tmp)
throw std::bad_alloc();
322 if (overflow) std::copy(buf_, buf_ + base::size_, tmp);
330 if (base::str_ != buf_) ::free(base::str_);
335 reserved_ = capacity;
338 void append_string (const_pointer s, size_type n)
340 base::append_string(s, n);
Definition: gu_string.hpp:36
Definition: gu_string.hpp:28
Definition: gu_string.hpp:238