34 {
return m_RawSpace[i]; }
36 {
return m_RawSpace[i]; }
39#if !defined(_MSC_VER) || _MSC_VER >= 1300
40 template<
class T_Iter>
void assign(T_Iter beg, T_Iter
end)
46 {
return m_RawSpace; }
48 {
return m_RawSpace; }
50 {
return m_ArrLimit; }
54 {
return !m_ArrSize; }
55 auto end() const noexcept
56 {
return m_RawSpace + m_ArrSize; }
58 {
return m_RawSpace + m_ArrSize; }
59 void pop(
size_t n =1);
63#if !defined(_MSC_VER) || _MSC_VER >= 1300
64 template<
class T_Iter>
void push(T_Iter beg, T_Iter
end);
66 void push(
const T *beg,
const T *
end);
71 {
return m_RawSpace[m_ArrSize-1]; }
73 {
return m_RawSpace[m_ArrSize-1]; }
79 {
return m_ArrSize? m_ArrSize: m_MinAlloc; }
89 const size_t m_MinAlloc;
106#if !defined(_MSC_VER) || _MSC_VER >= 1300
116#if !defined(_MSC_VER) || _MSC_VER >= 1300
117 template<
class T_Elem>
auto &
push(
const T_Elem &t)
119 auto &
push(
const T &t)
122#if !defined(_MSC_VER) || _MSC_VER >= 1300
123 template<
class T_Iter>
void push(T_Iter beg, T_Iter
end)
125 void push(
const T *beg,
const T *
end)
128#if !defined(_MSC_VER) || _MSC_VER >= 1300
130 void push(
const T *beg,
size_t n)
151#if !defined(_MSC_VER) || _MSC_VER >= 1300
160 { T t;
return push(t); }
161#if !defined(_MSC_VER) || _MSC_VER >= 1300
162 template<
class T_Elem>
auto &
push(T_Elem &t)
167#if !defined(_MSC_VER) || _MSC_VER >= 1300
168 template<
class T_Iter>
void push(T_Iter beg, T_Iter
end)
170 void push(
const T *beg,
const T *
end)
193 {
delete[] m_RawSpace; }
197 {
return m_RawSpace[i]; }
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)
203 void assign(
const T *p,
size_t n)
206#if !defined(_MSC_VER) || _MSC_VER >= 1300
207 template<
class T_Iter>
void assign(T_Iter beg, T_Iter
end)
213 {
return m_RawSpace; }
215 {
return m_RawSpace; }
219 {
return !m_ArrSize; }
221 {
return m_RawSpace + m_ArrSize; }
223 {
return m_RawSpace + m_ArrSize; }
224 void pop(
size_t n =1);
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)
231 auto &
push(
const T &t)
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);
237 void push(
const T *p,
size_t n);
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()); }
244 void push(
const T *beg,
const T *
end)
248 {
return m_ArrSize; }
249 auto &
top() const noexcept
250 {
return m_RawSpace[m_ArrSize-1]; }
252 {
return m_RawSpace[m_ArrSize-1]; }
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&)
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)); }
270 T *pushRaw(
size_t n);
283 const bool shorterA = n < b.size();
287 if (
const int cmp =std::char_traits<T>::compare(a.begin(), b.begin(), n))
296 return a.size() == b.size() &&
297 !std::char_traits<T>::compare(a.begin(), b.begin(), a.size());
315 out.
push(s, std::char_traits<T>::length(s));
334 out.
push(s, std::char_traits<T>::length(s));
372 m_RawSpace(0), m_ArrSize(0), m_ArrLimit(0), m_MinAlloc(minAlloc)
380 delete[]
reinterpret_cast<char*
>(m_RawSpace);
393 while (m_ArrSize > 0 && n-- > 0)
394#if __BORLANDC__ >= 0x530
395 m_RawSpace[--m_ArrSize].~T();
397 m_RawSpace[--m_ArrSize].T::~T();
402#if !defined(_MSC_VER) || _MSC_VER >= 1300
410 new(pushRaw()) T(*beg);
418 if (m_ArrSize >= m_ArrLimit)
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])]);
423 for (i =0; i < m_ArrSize; ++i)
424 new(rebuf+i) T(m_RawSpace[i]);
427 delete[]
reinterpret_cast<char*
>(m_RawSpace);
432 return m_RawSpace +m_ArrSize++;
445#if !defined(_MSC_VER) || _MSC_VER >= 1300
451 for (T *dst =pushRaw(n); n--; ++src)
458 if (m_ArrSize +n > m_ArrLimit)
460 size_t limit =m_ArrLimit? m_ArrLimit: (15 +
sizeof(T)) /
sizeof(T);
461 while (m_ArrSize +n > limit)
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]);
471 T *
const ret =m_RawSpace +m_ArrSize;
479# define SPECIALIZE_DTORFREESTACK(classX,X) \
481 template<classX> struct C_Stack<X>: C_DtorFreeStack<X> \
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) \
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; }\
#define SPECIALIZE_DTORFREESTACK(classX, X)
Safe instantiation for types which's destructor does exactly nothing.
~C_DtorFreeStack() noexcept
void push(T_Iter beg, T_Iter end)
auto & top() const noexcept
bool empty() const noexcept
auto begin() const noexcept
auto & operator[](size_type i) const
void assign(const T_Elem *p, size_t n)
auto & operator=(const C_DtorFreeStack &other)
C_DtorFreeStack() noexcept
auto end() const noexcept
void assign(T_Iter beg, T_Iter end)
auto size() const noexcept
auto & operator[](size_type i)
auto & push(const T_Elem &t)
If ctor of type T properly handles ownership transfer, so does C_ResourceStack<T>
auto & operator=(C_ResourceStack &other)
C_ResourceStack(size_t minAlloc=4) noexcept
C_ResourceStack(T_Iter beg, T_Iter end)
C_ResourceStack(C_ResourceStack &other)
void push(T_Iter beg, T_Iter end)
Any given type is safely instantiated even though C_DtorFreeStack<T> does better for bytewise types.
C_StackBase(size_t minAlloc=4) noexcept
auto begin() const noexcept
auto & operator[](size_type i) const noexcept
bool empty() const noexcept
auto size() const noexcept
void assign(T_Iter beg, T_Iter end)
void push(T_Iter beg, T_Iter end)
auto copyMinAlloc() const noexcept
auto end() const noexcept
auto & operator=(const C_StackBase &other)
A much more succinct substitute of std::stack<std::vector<T> >
C_Stack(size_t minAlloc=4) noexcept
auto & push(const T_Elem &t)
void push(T_Iter beg, T_Iter end)
C_Stack(T_Iter beg, T_Iter end)
C_Stack & operator=(const C_Stack &other)
C_Stack(const C_Stack &other)
THE common namespace of bux library.
bool operator==(const C_SourcePos &a, const C_SourcePos &b) noexcept
Equivalence relation.
std::basic_ostream< charT, traits > & operator<<(std::basic_ostream< charT, traits > &out, const C_Intervals< T > &x)
void operator+=(C_Stack< T > &a, const C_Stack< T > &b)
bool operator!=(const C_Stack< T > &a, const C_Stack< T > &b) noexcept
bool operator<(const C_SourcePos &a, const C_SourcePos &b) noexcept
Partial relation.