OpenGothic
Open source reimplementation of Gothic I and II
Loading...
Searching...
No Matches
string_frm.h
Go to the documentation of this file.
1#pragma once
2
3#include <cstdio>
4#include <cstring>
5#include <string_view>
6
7template<size_t storageSz = 64 /* one cache-line :D */ >
8class alignas(64) string_frm {
9 public:
10 template<class ... Args>
11 inline string_frm(const Args&... arg) {
12 size_t at = 0;
13 implFormat(stk, sizeof(stk)-1, at, arg...);
14 if(at+1<sizeof(stk)) {
15 stk[at] = '\0';
16 return;
17 }
18 heap = new char[at+1];
19 heap[at] = '\0';
20 stk[sizeof(stk)-1] = '*';
21 at = 0;
22 implFormat(heap, size_t(-1), at, arg...);
23 }
24
25 inline ~string_frm() {
26 if(stk[sizeof(stk)-1]!=0)
27 delete[] heap;
28 }
29
31 std::swap(stk,other.stk);
32 }
33
35 std::swap(stk,other.stk);
36 return *this;
37 }
38
39 inline operator std::string_view() const {
40 if(stk[storageSz-1])
41 return heap;
42 return stk;
43 }
44
45 inline bool empty() const {
46 if(stk[storageSz-1])
47 return heap[0]=='\0';
48 return stk[0]=='\0';
49 }
50
51 inline char* c_str() {
52 if(stk[storageSz-1])
53 return heap;
54 return stk;
55 }
56
57 inline char* begin() {
58 if(stk[storageSz-1])
59 return heap;
60 return stk;
61 }
62
63 inline char* end() {
64 if(stk[storageSz-1])
65 return heap+std::strlen(heap);
66 return stk+std::strlen(stk);
67 }
68
69 inline const char* begin() const {
70 if(stk[storageSz-1])
71 return heap;
72 return stk;
73 }
74
75 inline const char* end() const {
76 if(stk[storageSz-1])
77 return heap+std::strlen(heap);
78 return stk+std::strlen(stk);
79 }
80
81 template<size_t sz>
82 friend bool operator == (const string_frm<sz>& l, std::string_view v);
83 template<size_t sz>
84 friend bool operator == (std::string_view v, const string_frm<sz>& l);
85
86 private:
87 union {
88 char stk[storageSz] = {};
89 char* heap;
90 };
91
92 void implFormat(char* out, size_t maxSz, size_t& at) {
93 at = 0;
94 }
95
96 template<class ... Args>
97 void implFormat(char* out, size_t maxSz, size_t& at, const Args&... arg) {
98 (implWrite(out,maxSz,at,arg),... );
99 }
100
101 // NOTE: const-ref is better for inline-pass in optimizer
102 void implWrite(char* out, size_t maxSz, size_t& at, const std::string_view& arg) {
103 for(size_t i=0; i<arg.size(); ++i) {
104 if(at+i>=maxSz)
105 break;
106 out[at+i] = arg[i];
107 }
108 at += arg.size();
109 }
110
111 void implWrite(char* out, size_t maxSz, size_t& at, const char* arg) {
112 for(size_t i=0; arg[i]; ++i) {
113 if(at>=maxSz)
114 break;
115 out[at] = arg[i];
116 at++;
117 }
118 }
119
120 void implWrite(char* out, size_t maxSz, size_t& at, char arg) {
121 if(at<maxSz)
122 out[at] = arg;
123 ++at;
124 }
125
126 void implWrite(char* out, size_t maxSz, size_t& at, int arg) {
127 char buf[20] = {};
128 std::snprintf(buf,sizeof(buf),"%d",arg);
129 implWrite(out, maxSz, at, buf);
130 }
131
132 void implWrite(char* out, size_t maxSz, size_t& at, unsigned arg) {
133 char buf[20] = {};
134 std::snprintf(buf,sizeof(buf),"%u",arg);
135 implWrite(out, maxSz, at, buf);
136 }
137
138 void implWrite(char* out, size_t maxSz, size_t& at, size_t arg) {
139 char buf[20] = {};
140 std::snprintf(buf,sizeof(buf),"%u",uint32_t(arg));
141 implWrite(out, maxSz, at, buf);
142 }
143
144 void implWrite(char* out, size_t maxSz, size_t& at, float arg) {
145 char buf[20] = {};
146 std::snprintf(buf,sizeof(buf),"%f",arg);
147 implWrite(out, maxSz, at, buf);
148 }
149
150 void implWrite(char* out, size_t maxSz, size_t& at, double arg) {
151 char buf[20] = {};
152 std::snprintf(buf,sizeof(buf),"%f",arg);
153 implWrite(out, maxSz, at, buf);
154 }
155
156 void implWrite(char* out, size_t maxSz, size_t& at, const void* arg) {
157 char buf[20] = {};
158 std::snprintf(buf,sizeof(buf),"%p",arg);
159 implWrite(out, maxSz, at, buf);
160 }
161 };
162
163template<size_t sz>
164bool operator == (const string_frm<sz>& l, std::string_view v) {
165 auto ptr = l.begin();
166 return v==ptr;
167 }
168
169template<size_t sz>
170bool operator == (std::string_view v, const string_frm<sz>& l) {
171 auto ptr = l.begin();
172 return v==ptr;
173 }
string_frm(string_frm &&other)
Definition string_frm.h:30
char * end()
Definition string_frm.h:63
char * heap
Definition string_frm.h:89
char * begin()
Definition string_frm.h:57
const char * end() const
Definition string_frm.h:75
char * c_str()
Definition string_frm.h:51
const char * begin() const
Definition string_frm.h:69
bool empty() const
Definition string_frm.h:45
string_frm(const Args &... arg)
Definition string_frm.h:11
friend bool operator==(const string_frm< sz > &l, std::string_view v)
Definition string_frm.h:164
string_frm & operator=(string_frm &&other)
Definition string_frm.h:34
char stk[storageSz]
Definition string_frm.h:88
bool operator==(const string_frm< sz > &l, std::string_view v)
Definition string_frm.h:164