Elementa v8.0.0
Minimalistic library for any C++ application (C++11 and up)
Loading...
Searching...
No Matches
comprstack.h
Go to the documentation of this file.
1
3#include "elementa/license.inc"
4#include "elementa/checks.inc"
5
6#ifndef ELEMENTA_ADTS_COMPRESSEDSTACK_H
7#define ELEMENTA_ADTS_COMPRESSEDSTACK_H
8
9#include <stack>
11
13
14
15namespace elementa
16{
17
18namespace adts
19{
20
41/* ***************************************************************************
42
43 Template class: CSHolder
44
45*******************************************************************************/
46
48
50template <class Obj>
51struct CSHolder final
52{
53 const bool interesting;
55 {
56 size_t howmanyunint;
57 Obj object;
58
59 HeldData(void):howmanyunint{1} {}
60 HeldData(const Obj & o):object{o} {}
61 HeldData(Obj && o):object{std::move(o)} {}
62
63 ~HeldData(void) {}
64 } held;
65
66
68 CSHolder(void): interesting{false}, held{} {}
69
71 CSHolder(const Obj & o): interesting{true}, held{o} {}
72
73 CSHolder(const CSHolder &) = delete;
74 CSHolder(CSHolder &&) = delete;
75 CSHolder & operator=(const CSHolder &) = delete;
76 CSHolder & operator=(CSHolder &&) = delete;
77
78 ~CSHolder(void) {}
79
80};
81
82
83/* ***************************************************************************
84
85 Template class: ComprStack
86
87*******************************************************************************/
88
90
91template <class Obj>
92class ComprStack: public std::stack<CSHolder<Obj>>
93{
94 public:
95
97 using Base = std::stack<CSHolder<Obj>>;
98
100 using Base::Base;
101
102
104
106 double comprRatio(void) const noexcept;
107
108 bool empty() const
109 { return(Base::empty()); }
110
112 typename Base::size_type size(void) const
113 { return(size_); }
114
116 void push(void);
117
119 void push(const Obj & o);
120
122 void push(Obj && o);
123
125 void pop(void);
126
128
130 const CSHolder<Obj> & top(void) const;
131
132
133 private:
134
135 typename Base::size_type size_{0};
136
137};
138
139
140
141/* ===========================================================================
142
143 ========== IMPLEMENTATION OF TEMPLATES ==========
144
145============================================================================= */
146
147
148/* ***************************************************************************
149
150 Template class: ComprStack
151
152*******************************************************************************/
153
154template <class Obj>
155double ComprStack<Obj>::comprRatio(void) const noexcept
156{
157 if (Base::size() <= 1) return(1.0);
158 return(static_cast<double>(size()-Base::size()) /
159 static_cast<double>(size()));
160}
161
162template <class Obj>
165
166 if ( (Base::empty())||(top().interesting) ) Base::emplace();
167 else ++(const_cast<typename Base::reference>(Base::top()).
168 held.howmanyunint);
169 ++size_;
170 ELE_CODE_TRACE({},"Pushed un-interesting element in stack."
171 " Stack acc size = " << size() <<
172 " (in memory: " << Base::size() << ")");
173}
174
175template <class Obj>
176void ComprStack<Obj>::push(const Obj & o)
178
179 Base::emplace(o);
180 ++size_;
181 ELE_CODE_TRACE({},"Pushed interesting element in stack."
182 " Stack acc size = " << size() <<
183 " (in memory: " << Base::size() << ")");
184}
185
186template <class Obj>
189
190 Base::emplace(std::move(o));
191 ++size_;
192 ELE_CODE_TRACE({},"Moved interesting element into stack."
193 " Stack acc size = " << size() <<
194 " (in memory: " << Base::size() << ")");
195}
196
197template <class Obj>
200
201 if (!top().interesting)
202 {
203 ELE_CODE_TRACE({},"Popping un-interesting element from stack");
204 --(const_cast<typename Base::reference>(top()).held.howmanyunint);
205 if (Base::top().held.howmanyunint == 0) Base::pop();
206 }
207 else
208 {
209 ELE_CODE_TRACE({},"Popping interesting element from stack");
210 Base::pop();
211 }
212 --size_;
213}
214
215template <class Obj>
217{
218 if (empty()) ELE_CODE_INVSTATE("No top in empty stack");
219 return(Base::top());
220}
221
222 // ComprStack
224
225
226} // end adts namespace
227
228} // end elementa namespace
229
230
231#endif
232
CSHolder(const Obj &o)
Construct an interesting element.
Definition: comprstack.h:71
CSHolder(void)
Construct an un-interesting element.
Definition: comprstack.h:68
Base::size_type size(void) const
Return the total size of the stack by counting all, not compressed.
Definition: comprstack.h:112
const bool interesting
TRUE if it holds an interesting element.
Definition: comprstack.h:53
std::stack< CSHolder< Obj > > Base
Shortcut.
Definition: comprstack.h:97
union elementa::adts::CSHolder::HeldData held
Data held by the holder.
A compressed stack that only stores some objects and not others.
Definition: comprstack.h:93
double comprRatio(void) const noexcept
Return the compression ratio in [0,1].
Definition: comprstack.h:155
void pop(void)
Pop an element from stack.
Definition: comprstack.h:198
const CSHolder< Obj > & top(void) const
Consult the top.
Definition: comprstack.h:216
void push(void)
Push an un-interesting element without storing anything.
Definition: comprstack.h:163
Holder for elements in a compressed stack.
Definition: comprstack.h:52
#define ELE_CODE_TRACE_OFF
Place this inside local scope (e.g., routine) to deactivate traces there.
Definition: debugging.h:283
#define ELE_CODE_INVSTATE(expl)
To throw an invalid-state exception with an explanation.
Definition: exceptions.h:306
Obj object
Interesting element.
Definition: comprstack.h:57
size_t howmanyunint
Number of compressed un-interested elems.
Definition: comprstack.h:56