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 <cstddef>
37#include <iostream>
38#include <sstream>
39#include <typeinfo>
40#include <stdexcept>
41#include <string>
42//#include <set>
43
44#include "StringBuilder.h"
45#include "Type.h" // TypeName
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 // void toStream(std::ostream & ostr) const {
333 //, char separator=','
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 << *it;
341 }
342 //return ostr;
343 }
344
345 virtual
346 void toStream(std::ostream & ostr) const {
347 toStreamFormatted(ostr);
348 }
349
350
351 std::string toStr(char separator=',') const {
352 std::stringstream sstr;
353 toStreamFormatted(sstr, separator);
354 return sstr.str();
355 }
356
357
358// protected?
359
360 // AreaGeom etc.
361 virtual inline
362 void updateTuple(){};
363
364
365protected:
366
368 void setIndexed(size_t i){
369 //std::cout << __FUNCTION__ << " complete " << i << '\n';
370 this->updateTuple();
371 }
372
374 template<typename T2, typename ... TT>
375 void setIndexed(size_t i, T2 arg, const TT &... rest){
376 if (i>=N){
377 throw std::runtime_error(StringBuilder<>(__FILE__, ':', __FUNCTION__, ": index (", i, ") overflow in assigning: ", arg, ",..."));
378 return;
379 }
380 // std::cout << __FUNCTION__ << "N=" << N << " arg=" << arg << " remaining:" << i << std::endl;
381 this->at(i) = static_cast<S>(arg);
382 setIndexed(i+1, rest...);
383 }
384
385};
386
387
388template <typename S, size_t N>
389const size_t TupleBase<S,N>::storageTypeSize = sizeof(S);
390
391
392template <class S, size_t N>
393std::ostream & operator<<(std::ostream & ostr, const TupleBase<S,N> & tuple){
394 tuple.toStream(ostr);
395 return ostr;
396}
397
398
399template <typename S, size_t N>
400struct TypeName<TupleBase<S,N> > {
401
402 static const std::string & str(){
403 if (N == 0){
404 static const std::string name = drain::StringBuilder<>("PseudoTuple<", drain::TypeName<S>::str(),',' , drain::TypeName<S>::str(),">");
405 return name;
406 }
407 else {
408 static const std::string name = drain::StringBuilder<>("PseudoTuple<", drain::TypeName<S>::str(),',' , drain::TypeName<S>::str(),',' , N, ">");
409 return name;
410 }
411 }
412
413};
414
415
416
417} // drain
418
419
420#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:368
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:375
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
Definition Type.h:542
static const std::string name
Default implementation: name returned by std::type_info::name()
Definition Type.h:558