bux API Reference 1.9.0
Static library of whatever are seen required in general purpose but not directly supported from Modern C++. Or whatever reusable originated from my side projects.
Loading...
Searching...
No Matches
Xtack.h
Go to the documentation of this file.
1#pragma once
2
3#include <iterator> // std::iterator_traits<>, std::distance()
4#include <ostream> // std::basic_ostream<>
5#include <string> // std::char_traits<>
6
7namespace bux {
8
9//
10// Types
11//
16template<class T>
18{
19public:
20
21 // Types
22 typedef size_t size_type;
23 typedef T value_type;
24 typedef T *iterator;
25 typedef const T *const_iterator;
26
27 // Nonvirtuals
28 explicit C_StackBase(size_t minAlloc =4) noexcept;
30 C_StackBase(const C_StackBase &) = delete;
31
32 // Nonvirtuals
33 auto &operator[](size_type i) noexcept
34 { return m_RawSpace[i]; }
35 auto &operator[](size_type i) const noexcept
36 { return m_RawSpace[i]; }
37 auto &operator=(const C_StackBase &other)
38 { assign(other.begin(), other.end()); return *this; }
39#if !defined(_MSC_VER) || _MSC_VER >= 1300
40 template<class T_Iter> void assign(T_Iter beg, T_Iter end)
41#else
42 void assign(const T *beg, const T *end)
43#endif
44 { clear(); push(beg, end); }
45 auto begin() const noexcept
46 { return m_RawSpace; }
47 auto begin() noexcept
48 { return m_RawSpace; }
49 auto capacity() const
50 { return m_ArrLimit; }
51 void clear();
52 //
53 bool empty() const noexcept
54 { return !m_ArrSize; }
55 auto end() const noexcept
56 { return m_RawSpace + m_ArrSize; }
57 auto end() noexcept
58 { return m_RawSpace + m_ArrSize; }
59 void pop(size_t n =1);
60 //
61 auto &push()
62 { return *new(pushRaw()) T; }
63#if !defined(_MSC_VER) || _MSC_VER >= 1300
64 template<class T_Iter> void push(T_Iter beg, T_Iter end);
65#else
66 void push(const T *beg, const T *end);
67#endif
68 auto size() const noexcept
69 { return m_ArrSize; }
70 auto &top()
71 { return m_RawSpace[m_ArrSize-1]; }
72 auto &top() const
73 { return m_RawSpace[m_ArrSize-1]; }
74
75protected:
76
77 // Nonvirtuals
78 auto copyMinAlloc() const noexcept
79 { return m_ArrSize? m_ArrSize: m_MinAlloc; }
80 T *pushRaw();
81 //
82
83private:
84
85 // Data
86 T *m_RawSpace; // owned
87 size_t m_ArrSize; // counted in type T
88 size_t m_ArrLimit; // counted in type T
89 const size_t m_MinAlloc;
90};
91
94template<class T>
95class C_Stack: public C_StackBase<T>
96{
97 typedef C_StackBase<T> C_Super;
98
99public:
100
101 // Nonvirtuals
102 explicit C_Stack(size_t minAlloc =4) noexcept: C_Super(minAlloc)
103 {}
104 C_Stack(const C_Stack &other): C_Super(other.copyMinAlloc())
105 { push(other.begin(), other.end()); }
106#if !defined(_MSC_VER) || _MSC_VER >= 1300
107 template<class T_Iter> C_Stack(T_Iter beg, T_Iter end): C_Super(1)
108#else
109 C_Stack(const T *beg, const T *end): C_Super(1)
110#endif
111 { push(beg, end); }
112 C_Stack &operator=(const C_Stack &other)
113 { this->assign(other.begin(), other.end()); return *this; }
114 auto &push()
115 { return C_Super::push(); }
116#if !defined(_MSC_VER) || _MSC_VER >= 1300
117 template<class T_Elem> auto &push(const T_Elem &t)
118#else
119 auto &push(const T &t)
120#endif
121 { return *new(C_Super::pushRaw()) T(t); }
122#if !defined(_MSC_VER) || _MSC_VER >= 1300
123 template<class T_Iter> void push(T_Iter beg, T_Iter end)
124#else
125 void push(const T *beg, const T *end)
126#endif
127 { C_Super::push(beg, end); }
128#if !defined(_MSC_VER) || _MSC_VER >= 1300
129#else
130 void push(const T *beg, size_t n)
131 { C_Super::push(beg, beg+n); }
132#endif
133};
134
139template<class T>
141{
142 typedef C_StackBase<T> C_Super;
143
144public:
145
146 // Nonvirtuals
147 explicit C_ResourceStack(size_t minAlloc =4) noexcept: C_Super(minAlloc)
148 {}
150 { push(other.begin(), other.end()); }
151#if !defined(_MSC_VER) || _MSC_VER >= 1300
152 template<class T_Iter> C_ResourceStack(T_Iter beg, T_Iter end): C_Super(1)
153#else
154 C_ResourceStack(const T *beg, const T *end): C_Super(1)
155#endif
156 { push(beg, end); }
158 { assign(other.begin(), other.end()); return *this; }
159 auto &push()
160 { T t; return push(t); }
161#if !defined(_MSC_VER) || _MSC_VER >= 1300
162 template<class T_Elem> auto &push(T_Elem &t)
163#else
164 auto &push(T &t)
165#endif
166 { return *new(C_Super::pushRaw()) T(t); }
167#if !defined(_MSC_VER) || _MSC_VER >= 1300
168 template<class T_Iter> void push(T_Iter beg, T_Iter end)
169#else
170 void push(const T *beg, const T *end)
171#endif
172 { C_Super::push(beg, end); }
173};
174
178template<class T>
180{
181public:
182
183 // Types
184 typedef size_t size_type;
185 typedef T value_type;
186 typedef T *iterator;
187 typedef const T *const_iterator;
188
189 // Nonvirtuals
190 C_DtorFreeStack() noexcept: m_RawSpace(0), m_ArrSize(0), m_ArrLimit(0)
191 {}
193 { delete[] m_RawSpace; }
194 auto &operator=(const C_DtorFreeStack &other)
195 { assign(other.begin(), other.size()); return *this; }
197 { return m_RawSpace[i]; }
198 auto &operator[](size_type i) const
199 { return m_RawSpace[i]; }
200#if !defined(_MSC_VER) || _MSC_VER >= 1300
201 template<class T_Elem> void assign(const T_Elem *p, size_t n)
202#else
203 void assign(const T *p, size_t n)
204#endif
205 { clear(); push(p, n); }
206#if !defined(_MSC_VER) || _MSC_VER >= 1300
207 template<class T_Iter> void assign(T_Iter beg, T_Iter end)
208#else
209 void assign(const T *beg, const T *end)
210#endif
211 { clear(); push(beg, end); }
212 auto begin() const noexcept
213 { return m_RawSpace; }
214 auto begin() noexcept
215 { return m_RawSpace; }
216 void clear() noexcept
217 { m_ArrSize =0; }
218 bool empty() const noexcept
219 { return !m_ArrSize; }
220 auto end() const noexcept
221 { return m_RawSpace + m_ArrSize; }
222 auto end() noexcept
223 { return m_RawSpace + m_ArrSize; }
224 void pop(size_t n =1);
225 //
226 auto &push()
227 { return *new(pushRaw(1)) T; }
228#if !defined(_MSC_VER) || _MSC_VER >= 1300
229 template<class T_Elem> auto &push(const T_Elem &t)
230#else
231 auto &push(const T &t)
232#endif
233 { return *new(pushRaw(1)) T(t); }
234#if !defined(_MSC_VER) || _MSC_VER >= 1300
235 template<class T_Iter> void push(T_Iter p, size_t n);
236#else
237 void push(const T *p, size_t n);
238#endif
239 //
240#if !defined(_MSC_VER) || _MSC_VER >= 1300
241 template<class T_Iter> void push(T_Iter beg, T_Iter end)
242 { pushByTraits(beg, end, typename std::iterator_traits<T_Iter>::iterator_category()); }
243#else
244 void push(const T *beg, const T *end)
245 { push(beg, end-beg); }
246#endif
247 auto size() const noexcept
248 { return m_ArrSize; }
249 auto &top() const noexcept
250 { return m_RawSpace[m_ArrSize-1]; }
251 auto &top() noexcept
252 { return m_RawSpace[m_ArrSize-1]; }
253
254private:
255
256 // Data
257 T *m_RawSpace;
258 size_t m_ArrSize;
259 size_t m_ArrLimit;
260
261 // Nonvirtuals
262#if !defined(_MSC_VER) || _MSC_VER >= 1300
263 template<class T_Iter> inline void pushByTraits(T_Iter beg, T_Iter end,
264 const std::random_access_iterator_tag&)
265 { push(beg, end-beg); }
266 template<class T_Iter> inline void pushByTraits(T_Iter beg, T_Iter end,
267 const std::input_iterator_tag&)
268 { push(beg, std::distance(beg,end)); }
269#endif
270 T *pushRaw(size_t n);
272};
273
274//
275// Function Templates
276//
279template<class T>
280bool operator <(const C_Stack<T> &a, const C_Stack<T> &b) noexcept
281{
282 size_t n = a.size();
283 const bool shorterA = n < b.size();
284 if (!shorterA)
285 n = b.size();
286
287 if (const int cmp =std::char_traits<T>::compare(a.begin(), b.begin(), n))
288 return cmp < 0;
289
290 return shorterA;
291}
292
293template<class T>
294bool operator ==(const C_Stack<T> &a, const C_Stack<T> &b) noexcept
295{
296 return a.size() == b.size() &&
297 !std::char_traits<T>::compare(a.begin(), b.begin(), a.size());
298}
299
300template<class T>
301bool operator !=(const C_Stack<T> &a, const C_Stack<T> &b) noexcept
302{
303 return !(a == b);
304}
305
306template<class T>
308{
309 a.push(b.begin(), b.end());
310}
311
312template<class T>
313void operator +=(C_Stack<T> &out, const T *s)
314{
315 out.push(s, std::char_traits<T>::length(s));
316}
317
318template<class T>
320{
321 a.push(b.begin(), b.end());
322}
323
324template<class T>
326{
327 a.push(b.begin(), b.size());
328 return a;
329}
330
331template<class T>
332auto &operator <<(C_Stack<T> &out, const T *s)
333{
334 out.push(s, std::char_traits<T>::length(s));
335 return out;
336}
337
338template<class T>
340{
341 a.push(b.begin(), b.end());
342 return a;
343}
344
345template<class T>
346auto &operator <<(C_Stack<T> &out, const T &c)
347{
348 out.push(c);
349 return out;
350}
351
352template<class T>
354{
355 out.push(t);
356 return out;
357}
358
359template<class T>
360auto &operator <<(std::basic_ostream<T> &out, const C_Stack<T> &s)
361{
362 if (!s.empty())
363 out.write(s.begin(), s.size());
364 return out;
365}
366
367//
368// Implementation of Class Templates
369//
370template<class T>
371C_StackBase<T>::C_StackBase(size_t minAlloc) noexcept:
372 m_RawSpace(0), m_ArrSize(0), m_ArrLimit(0), m_MinAlloc(minAlloc)
373{
374}
375
376template<class T>
378{
379 clear();
380 delete[] reinterpret_cast<char*>(m_RawSpace);
381}
382
383template<class T>
385{
386 while (!empty())
387 pop();
388}
389
390template<class T>
392{
393 while (m_ArrSize > 0 && n-- > 0)
394#if __BORLANDC__ >= 0x530
395 m_RawSpace[--m_ArrSize].~T();
396#else
397 m_RawSpace[--m_ArrSize].T::~T();
398#endif
399}
400
401template<class T>
402#if !defined(_MSC_VER) || _MSC_VER >= 1300
403template<class T_Iter> void C_StackBase<T>::push(T_Iter beg, T_Iter end)
404#else
405void C_StackBase<T>::push(const T *beg, const T *end)
406#endif
407{
408 while (beg != end)
409 {
410 new(pushRaw()) T(*beg);
411 ++beg;
412 }
413}
414
415template<class T>
417{
418 if (m_ArrSize >= m_ArrLimit)
419 {
420 const size_t limit =m_ArrLimit? m_ArrLimit *2: m_MinAlloc;
421 T *const rebuf =reinterpret_cast<T*>(new char[limit*sizeof(T[1])]);
422 size_t i;
423 for (i =0; i < m_ArrSize; ++i)
424 new(rebuf+i) T(m_RawSpace[i]);
425
426 clear();
427 delete[] reinterpret_cast<char*>(m_RawSpace);
428 m_RawSpace =rebuf;
429 m_ArrSize =i; // m_ArrSize is reset by clear()
430 m_ArrLimit =limit;
431 }
432 return m_RawSpace +m_ArrSize++;
433}
434
435template<class T>
437{
438 if (m_ArrSize > n)
439 m_ArrSize -=n;
440 else
441 m_ArrSize =0;
442}
443
444template<class T>
445#if !defined(_MSC_VER) || _MSC_VER >= 1300
446template<class T_Iter> void C_DtorFreeStack<T>::push(T_Iter src, size_t n)
447#else
448void C_DtorFreeStack<T>::push(const T *src, size_t n)
449#endif
450{
451 for (T *dst =pushRaw(n); n--; ++src)
452 new(dst++) T(*src);
453}
454
455template<class T>
457{
458 if (m_ArrSize +n > m_ArrLimit)
459 {
460 size_t limit =m_ArrLimit? m_ArrLimit: (15 +sizeof(T)) /sizeof(T);
461 while (m_ArrSize +n > limit)
462 limit <<=1;
463
464 T *const rebuf =new T[limit];
465 for (size_t i =0; i < m_ArrSize; ++i)
466 new(rebuf+i) T(m_RawSpace[i]);
467 delete[] m_RawSpace;
468 m_RawSpace =rebuf;
469 m_ArrLimit =limit;
470 }
471 T *const ret =m_RawSpace +m_ArrSize;
472 m_ArrSize +=n;
473 return ret;
474}
475
476} //namespace bux
477
478#ifndef _MSC_VER
479# define SPECIALIZE_DTORFREESTACK(classX,X) \
480 namespace bux { \
481 template<classX> struct C_Stack<X>: C_DtorFreeStack<X> \
482 { \
483 C_Stack() \
484 {} \
485 C_Stack(const C_Stack &other) \
486 { push(other.begin(), other.size()); } \
487 template<class T_Elem> C_Stack(T_Elem const *p) \
488 { push(p, std::char_traits<T_Elem>::length(p)); } \
489 template<class T_Elem> C_Stack(T_Elem const *p, size_t n) \
490 { push(p, n); } \
491 template<class T_Iter> C_Stack(T_Iter beg, T_Iter end) \
492 { push(beg, end); } \
493 C_Stack &operator=(const C_Stack &other) \
494 { assign(other.begin(), other.size()); return *this; } \
495 C_Stack &operator=(X const *s) \
496 { assign(s, std::char_traits<X>::length(s)); return *this; }\
497 }; }
498
499// C++ Standard Builins
503SPECIALIZE_DTORFREESTACK(,signed char)
511SPECIALIZE_DTORFREESTACK(class T,T*)
512
513#endif // #ifndef _MSC_VER
#define SPECIALIZE_DTORFREESTACK(classX, X)
Definition Xtack.h:479
Safe instantiation for types which's destructor does exactly nothing.
Definition Xtack.h:180
auto & top() noexcept
Definition Xtack.h:251
~C_DtorFreeStack() noexcept
Definition Xtack.h:192
void push(T_Iter beg, T_Iter end)
Definition Xtack.h:241
auto & top() const noexcept
Definition Xtack.h:249
auto end() noexcept
Definition Xtack.h:222
bool empty() const noexcept
Definition Xtack.h:218
auto begin() const noexcept
Definition Xtack.h:212
auto & operator[](size_type i) const
Definition Xtack.h:198
void assign(const T_Elem *p, size_t n)
Definition Xtack.h:201
auto & operator=(const C_DtorFreeStack &other)
Definition Xtack.h:194
void pop(size_t n=1)
Definition Xtack.h:436
const T * const_iterator
Definition Xtack.h:187
void clear() noexcept
Definition Xtack.h:216
C_DtorFreeStack() noexcept
Definition Xtack.h:190
auto end() const noexcept
Definition Xtack.h:220
void assign(T_Iter beg, T_Iter end)
Definition Xtack.h:207
auto size() const noexcept
Definition Xtack.h:247
auto begin() noexcept
Definition Xtack.h:214
auto & operator[](size_type i)
Definition Xtack.h:196
auto & push(const T_Elem &t)
Definition Xtack.h:229
If ctor of type T properly handles ownership transfer, so does C_ResourceStack<T>
Definition Xtack.h:141
auto & operator=(C_ResourceStack &other)
Definition Xtack.h:157
auto & push(T_Elem &t)
Definition Xtack.h:162
C_ResourceStack(size_t minAlloc=4) noexcept
Definition Xtack.h:147
C_ResourceStack(T_Iter beg, T_Iter end)
Definition Xtack.h:152
C_ResourceStack(C_ResourceStack &other)
Definition Xtack.h:149
void push(T_Iter beg, T_Iter end)
Definition Xtack.h:168
Any given type is safely instantiated even though C_DtorFreeStack<T> does better for bytewise types.
Definition Xtack.h:18
auto begin() noexcept
Definition Xtack.h:47
C_StackBase(size_t minAlloc=4) noexcept
Definition Xtack.h:371
void pop(size_t n=1)
Definition Xtack.h:391
auto begin() const noexcept
Definition Xtack.h:45
auto & top() const
Definition Xtack.h:72
auto & operator[](size_type i) const noexcept
Definition Xtack.h:35
bool empty() const noexcept
Definition Xtack.h:53
const T * const_iterator
Definition Xtack.h:25
auto size() const noexcept
Definition Xtack.h:68
void assign(T_Iter beg, T_Iter end)
Definition Xtack.h:40
auto capacity() const
Definition Xtack.h:49
size_t size_type
Definition Xtack.h:22
auto end() noexcept
Definition Xtack.h:57
void push(T_Iter beg, T_Iter end)
Definition Xtack.h:403
auto & top()
Definition Xtack.h:70
auto copyMinAlloc() const noexcept
Definition Xtack.h:78
auto end() const noexcept
Definition Xtack.h:55
T * pushRaw()
Definition Xtack.h:416
auto & push()
Definition Xtack.h:61
auto & operator=(const C_StackBase &other)
Definition Xtack.h:37
void clear()
Definition Xtack.h:384
A much more succinct substitute of std::stack<std::vector<T> >
Definition Xtack.h:96
C_Stack(size_t minAlloc=4) noexcept
Definition Xtack.h:102
auto & push(const T_Elem &t)
Definition Xtack.h:117
auto & push()
Definition Xtack.h:114
void push(T_Iter beg, T_Iter end)
Definition Xtack.h:123
C_Stack(T_Iter beg, T_Iter end)
Definition Xtack.h:107
C_Stack & operator=(const C_Stack &other)
Definition Xtack.h:112
C_Stack(const C_Stack &other)
Definition Xtack.h:104
THE common namespace of bux library.
Definition AtomiX.cpp:3
bool operator==(const C_SourcePos &a, const C_SourcePos &b) noexcept
Equivalence relation.
Definition LexBase.cpp:83
std::basic_ostream< charT, traits > & operator<<(std::basic_ostream< charT, traits > &out, const C_Intervals< T > &x)
Definition Intervals.h:84
void operator+=(C_Stack< T > &a, const C_Stack< T > &b)
Definition Xtack.h:307
bool operator!=(const C_Stack< T > &a, const C_Stack< T > &b) noexcept
Definition Xtack.h:301
bool operator<(const C_SourcePos &a, const C_SourcePos &b) noexcept
Partial relation.
Definition LexBase.cpp:90