Loading...
Searching...
No Matches
TupleBase.h
1/*
2
3MIT License
4
5Copyright (c) 2017 FMI Open Development / Markus Peura, first.last@fmi.fi
6
7Permission is hereby granted, free of charge, to any person obtaining a copy
8of this software and associated documentation files (the "Software"), to deal
9in the Software without restriction, including without limitation the rights
10to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11copies of the Software, and to permit persons to whom the Software is
12furnished to do so, subject to the following conditions:
13
14The above copyright notice and this permission notice shall be included in all
15copies or substantial portions of the Software.
16
17THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23SOFTWARE.
24
25*/
26/*
27Part of Rack development has been done in the BALTRAD projects part-financed
28by the European Union (European Regional Development Fund and European
29Neighbourhood Partnership Instrument, Baltic Sea Region Programme 2007-2013)
30*/
31
32
33#ifndef DRAIN_TUPLE_BASE
34#define DRAIN_TUPLE_BASE
35
36#include <drain/TypeName.h> // TypeName
37#include <cstddef>
38#include <iostream>
39#include <sstream>
40#include <stdexcept>
41#include <string>
42#include <typeinfo>
43//#include <set>
44
45#include "StringBuilder.h"
46
47namespace drain {
48
49
50// Consider inheritance TupleType->TupleBase, so all S-typed stuff here?
51template <typename S>
52struct TupleType {
53
55
62 static
64};
65
66template <typename S>
68
69
74template <typename S, size_t N=2>
75class TupleBase {
76
77public:
78
80 typedef S value_type;
81
82 typedef S* iterator;
83 typedef S const* const_iterator;
84
85 static const size_t storageTypeSize;
86
87 TupleBase(){};
88
89 virtual
90 ~TupleBase(){};
91
93
96 static inline
97 size_t size(){
98 return N;
99 }
100
101 virtual
102 const_iterator begin() const = 0;
103
104 virtual
105 const_iterator end() const = 0;
106
107 virtual
108 iterator begin() = 0;
109
110 virtual
111 iterator end() = 0;
112
114
118 const S & at(size_t i) const {
119 //(std::stringstream("UniTuple: ") << __FUNCTION__).r
120 if (i<N)
121 return *(begin() + i);
122 else {
123 /*
124 std::stringstream sstr;
125 sstr << // TypeName<tuple_t>::str() << ':' <<
126 __FUNCTION__ << " index overflow:" << i;
127 throw std::runtime_error(sstr.str());
128 */
129 throw std::runtime_error(StringBuilder<' '>(__FUNCTION__, "index overflow:", i));
130 }
131 }
132
133 const S & operator[](size_t i) const {
134 return at(i);
135 }
136
138
142 S & at(size_t i){
143 if (i<N)
144 return *(begin() + i);
145 else {
146 /*
147 std::stringstream sstr;
148 sstr << // << TypeName<tuple_t>::str() << ':'
149 __FUNCTION__ << " index overflow:" << i;
150 throw std::runtime_error(sstr.str());
151 */
152 throw std::runtime_error(StringBuilder<' '>(__FUNCTION__, "index overflow:", i));
153 }
154 }
155
156 S & operator[](size_t i){
157 return at(i);
158 }
159
160
162 bool operator==(const tuplebase_t &t) const {
163 const_iterator it = begin();
164 const_iterator tit = t.begin();
165 while (it != end()){
166 if (*it != *tit)
167 return false;
168 ++it;
169 ++tit;
170 }
171 return true;
172 }
173
175
178 bool operator==(const value_type &t) const {
179 //
180 for (const auto e: *this){
181 if (e != t){
182 return false;
183 }
184 }
185 /*
186 * const_iterator it = begin();
187 while (it != end()){
188 if (*it != t)
189 return false;
190 ++it;
191 }*/
192 return true;
193 }
194
195
197 bool operator!=(const tuplebase_t &t) const {
198 return !(*this == t);
199 }
200
202 template <class T>
203 T & toSequence(T & sequence) const {
204 sequence.clear();
205 for (const_iterator it = begin(); it != end(); ++it){
206 sequence.insert(sequence.end(), *it);
207 }
208 return sequence;
209 }
210
211
212
214 //tuple_t & set(const tuple_t & t){
215 void set(const tuplebase_t & t){
216 if (&t != this){
217 this->assignSequence(t);
218 }
219 // this->assign(t);
220 /*
221 if (&t != &this->tuple()){
222 this->assign(t);
223 }
224 */
225 //return *this;
226 }
227
229 template <class T2, size_t N2=2>
230 //tuple_t & set(const UniTuple<T2,N2> & t){
231 //void set(const UniTuple<T2,N2> & t){
232 void set(const TupleBase<T2,N2> & t){
233 /*
234 if (&t == this){
235 throw std::runtime_error(StringBuilder<>(__FILE__, ':', __FUNCTION__, ": self-assignment violation: ", t, " [", drain::TypeName<TupleBase<T2,N2> >::str(), "]"));
236 }
237 */
238 this->assignSequence(t, true); // by default LENIENT, or how should it be?
239 // return *this;
240 }
241
242
243 inline
244 void set(const S & arg) {
245 setIndexed(0, arg);
246 this->updateTuple();
247 }
248
250 // Variadic-argument member set function.
251 // https://en.cppreference.com/w/cpp/language/parameter_pack
252 template<typename ... SS>
253 inline
254 void set(const S & arg, const SS &... rest) {
255 setIndexed(0, arg, rest...);
256 this->updateTuple();
257 }
258
259 template<typename T>
260 inline
261 void set(std::initializer_list<T> l){
262 this->assignSequence(l);
263 }
264
265
267 /*
268 tuplebase_t & assign(const tuplebase_t & t){
269 if (&t != this){
270 this->assignSequence(t);
271 }
272 return *this;
273 }
274
275 tuplebase_t & assign(const value_type & value){
276 this->fill(value);
277 updateTuple();
278 return *this;
279 }
280 */
281
283
286 template <class T>
287 tuplebase_t & assignSequence(T & sequence, bool LENIENT = false){
288 typename T::const_iterator cit = sequence.begin();
289 iterator it = begin();
290 while (cit != sequence.end()){
291 if (it == end()){
292 if (LENIENT){
293 return *this;
294 }
295 else {
296 throw std::runtime_error(StringBuilder<':'>(__FILE__, ':', __FUNCTION__, ": index overflow in assigning: ", *cit));
297 /*
298 std::stringstream sstr;
299 sstr << __FILE__ << ':' << __FUNCTION__ << ": run out of indices in assigning: " << *cit;
300 throw std::runtime_error(sstr.str());
301 */
302 }
303 break;
304 }
305 // break;
306 *it = *cit;
307 ++it;
308 ++cit;
309 }
310 return *this;
311 }
312
313
315 void fill(S i){
316 for (iterator it = begin(); it != end(); ++it){
317 *it = i;
318 }
319 }
320
321 inline
322 void clear(){
323 fill(S());
324 }
325
326
330 virtual
331 void toStreamFormatted(std::ostream & ostr, char separator=',') const {
332
333 // Keep for debugging ostr << TypeName<S>::str();
334 char sep = 0;
335 for (const_iterator it = begin(); it != end(); ++it){
336 if (sep)
337 ostr << sep;
338 else
339 sep = separator;
340 ostr << std::boolalpha; // does not work
341 ostr << *it;
342 }
343 //return ostr;
344 }
345
346 virtual
347 void toStream(std::ostream & ostr) const {
348 toStreamFormatted(ostr);
349 }
350
351
352 std::string toStr(char separator=',') const {
353 std::stringstream sstr;
354 toStreamFormatted(sstr, separator);
355 return sstr.str();
356 }
357
358
359// protected?
360
361 // AreaGeom etc.
362 virtual inline
363 void updateTuple(){};
364
365
366protected:
367
369 void setIndexed(size_t i){
370 //std::cout << __FUNCTION__ << " complete " << i << '\n';
371 this->updateTuple();
372 }
373
375 template<typename T2, typename ... TT>
376 void setIndexed(size_t i, T2 arg, const TT &... rest){
377 if (i>=N){
378 throw std::runtime_error(StringBuilder<>(__FILE__, ':', __FUNCTION__, ": index (", i, ") overflow in assigning: ", arg, ",..."));
379 return;
380 }
381 // std::cout << __FUNCTION__ << "N=" << N << " arg=" << arg << " remaining:" << i << std::endl;
382 this->at(i) = static_cast<S>(arg);
383 setIndexed(i+1, rest...);
384 }
385
386};
387
388
389template <typename S, size_t N>
390const size_t TupleBase<S,N>::storageTypeSize = sizeof(S);
391
392
393template <class S, size_t N>
394std::ostream & operator<<(std::ostream & ostr, const TupleBase<S,N> & tuple){
395 tuple.toStream(ostr);
396 return ostr;
397}
398
399
400template <typename S, size_t N>
401struct TypeName<TupleBase<S,N> > {
402
403 static const std::string & str(){
404 if (N == 0){
405 static const std::string name = drain::StringBuilder<>("PseudoTuple<", drain::TypeName<S>::str(),',' , drain::TypeName<S>::str(),">");
406 return name;
407 }
408 else {
409 static const std::string name = drain::StringBuilder<>("PseudoTuple<", drain::TypeName<S>::str(),',' , drain::TypeName<S>::str(),',' , N, ">");
410 return name;
411 }
412 }
413
414};
415
416
417
418} // drain
419
420
421#endif
Definition StringBuilder.h:58
Definition TupleBase.h:75
static size_t size()
Return the number of elements.
Definition TupleBase.h:97
void setIndexed(size_t i)
Argument stack endpoint function; final step of variadic argument set(arg, ...) .
Definition TupleBase.h:369
T & toSequence(T &sequence) const
Copy elements to a Sequence, like stl::list, stl::set or stl::vector.
Definition TupleBase.h:203
bool operator!=(const tuplebase_t &t) const
Inequality operator.
Definition TupleBase.h:197
void fill(S i)
Set all the elements to i.
Definition TupleBase.h:315
bool operator==(const tuplebase_t &t) const
Equality operator.
Definition TupleBase.h:162
tuplebase_t & assignSequence(T &sequence, bool LENIENT=false)
Proposed for tuples only; derived classes should not shadow this.
Definition TupleBase.h:287
void setIndexed(size_t i, T2 arg, const TT &... rest)
Worker called by set(T2 arg, T2 arg2, ...)
Definition TupleBase.h:376
virtual void toStreamFormatted(std::ostream &ostr, char separator=',') const
Definition TupleBase.h:331
const S & at(size_t i) const
Return const reference to element i.
Definition TupleBase.h:118
void set(const TupleBase< T2, N2 > &t)
Assign tuple of different type and/or size.
Definition TupleBase.h:232
S & at(size_t i)
Return reference to element i.
Definition TupleBase.h:142
void set(const S &arg, const SS &... rest)
Set element(s).
Definition TupleBase.h:254
bool operator==(const value_type &t) const
Equality operator against single value.
Definition TupleBase.h:178
Definition DataSelector.cpp:1277
Definition TupleBase.h:52
static const S neutral_value
Zero, by default. For enum types, must be explicitly given.
Definition TupleBase.h:63
Default implementation.
Definition TypeName.h:57