UniTuple.h
1 /*
2 
3 MIT License
4 
5 Copyright (c) 2017 FMI Open Development / Markus Peura, first.last@fmi.fi
6 
7 Permission is hereby granted, free of charge, to any person obtaining a copy
8 of this software and associated documentation files (the "Software"), to deal
9 in the Software without restriction, including without limitation the rights
10 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 copies of the Software, and to permit persons to whom the Software is
12 furnished to do so, subject to the following conditions:
13 
14 The above copyright notice and this permission notice shall be included in all
15 copies or substantial portions of the Software.
16 
17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 SOFTWARE.
24 
25 */
26 /*
27 Part of Rack development has been done in the BALTRAD projects part-financed
28 by the European Union (European Regional Development Fund and European
29 Neighbourhood Partnership Instrument, Baltic Sea Region Programme 2007-2013)
30 */
31 
32 
33 #ifndef DRAIN_UNITUPLE
34 #define DRAIN_UNITUPLE
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 <drain/StringBuilder.h>
45 #include <drain/TupleBase.h>
46 #include <drain/Type.h> // Utils
47 // #include <drain/Sprinter.h> lower == cannot use Sprinter, as long as SprinterLayouit uses UniTuple...
48 // #include <drain/VariableT.h> lower
49 
50 namespace drain {
51 
52 
53 
54 //class VariableT<VariableInitializer<VariableBase> >;
55 //class VariableT<VariableInitializer<ReferenceT<VariableBase> > >;
56 //class VariableT<ReferenceT<Castable> >;
57 
58 
60 
64 template <class T, size_t N=2>
65 class UniTuple : public TupleBase<T,N> {
66 
67 
68 public:
69 
70  typedef T value_type; // why value_type, not value_t (ok, STL also )
71  typedef UniTuple<T,N> tuple_t;
72  static const size_t tuple_size = N;
73 
74  typedef T* iterator;
75  typedef const T* const_iterator;
76 
77 
78  inline
79  UniTuple() : start(this->arr), init(nullptr){ // start(this->arr),
80  this->fill(0);
81  };
82 
83 
84  template<typename ... TT>
85  inline
86  UniTuple(const TT &... args) : start(this->arr), init(nullptr){ //
87  this->fill(0);
88  this->set(args...);
89  }
90 
91 
93  inline
94  UniTuple(const UniTuple<T,N> & t) : start(this->arr), init(nullptr){ // start(this->arr),
95  this->set(t);
96  };
97 
98 
99 
100  template<typename S>
101  inline
102  UniTuple(std::initializer_list<S> l) : start(this->arr), init(nullptr){ // start(this->arr),
103  this->set(l);
104  };
105 
106 
107 
108  virtual inline
109  ~UniTuple(){};
110 
111  tuple_t & operator=(const tuple_t &t){
112  if (&t != this){ // this check should be unneeded, as it is in assign().
113  this->assignSequence(t);
114  }
115  return *this;
116  }
117 
118  tuple_t & operator=(const value_type & value){
119  this->assign(value);
120  return *this;
121  }
122 
123 
124  template<typename S>
125  tuple_t & operator=(std::initializer_list<S> l){
126  this->assignSequence(l);
127  return *this;
128  }
129 
130 
131 
132 
133  virtual inline
134  const_iterator begin() const override final {
135  return start; // this->arr
136  // return this->arr; //start;
137  }
138 
139  virtual inline
140  const_iterator end() const override final {
141  return start + N; // this->arr
142  // return this->arr + N;
143  }
144 
145  virtual inline
146  iterator begin() override final {
147  return start; // this->arr
148  // return this->arr; //start;
149  //return (iterator)this;
150  }
151 
152  virtual inline
153  iterator end() override final {
154  return start + N; // this->arr
155  // return (iterator)this + N;
156  }
157 
158 
159 
160 
161  // Self-reference for casting
162  tuple_t & tuple(){
163  return *this;
164  }
165 
166  // Self-reference for casting
167  const tuple_t & tuple() const{
168  return *this;
169  }
170 
171 
172  void debug(std::ostream & ostr) const {
173  ostr << "UniTuple<" << typeid(T).name() << sizeof(T) << ',' << N << ">: {" << *this << '}';
174  }
175 
176 
177 protected:
178 
179  const iterator start;
180 
181 
182 private:
183 
184  // Utility for initializing references is derived classes Point(x,y): x(init), y(++init),
185  iterator init;
186 
187 protected:
188 
189  T & next(){
190  if (init==nullptr){
191  //std::cerr << __FILE__ << ':' << __FUNCTION__ << "warning: null ptr" << *this << std::endl;
192  return *(init=begin());
193  }
194  else if (init==end()){
195  std::cerr << __FILE__ << ':' << __FUNCTION__ << "warning: exceeded inits: " << *this << std::endl;
196  return *(init=begin());
197  }
198  return *(++init);
199  }
200 
201 
202  // Parasite
203 
204  template <size_t N2>
205  UniTuple(UniTuple<T,N2> &tuple, size_t i): start(tuple.begin()+i), init(nullptr){ // 2023/04/24
206  if ((i+N)> N2){
207  throw std::runtime_error(drain::StringBuilder<>(drain::TypeName<UniTuple<T,N2> >::str(), "(", tuple, "): constructor index[", i,"] overflow with referenced tuple") );
208  }
209  };
210 
211 
212 
213 private:
214 
216  T arr[N];
217 
218 };
219 
220 /*
221 template <class T, size_t N>
222 std::ostream & operator<<(std::ostream & ostr, const UniTuple<T,N> & tuple){
223  return tuple.toStream(ostr);
224 }
225 */
226 
227 
228 template <class T, size_t N>
229 struct TypeName<UniTuple<T,N> > {
230 
231  static const std::string & str(){
232  static const std::string name = drain::StringBuilder<>("UniTuple<", drain::TypeName<T>::str(), ',', N, ">");
233  return name;
234  }
235 
236 };
237 
238 
239 /*
240  // NOTE: cannot use Sprinter, as long as SprinterLayout uses UniTuple...
241 template <class T, size_t N>
242 std::ostream & Sprinter::toStream(std::ostream & ostr, const UniTuple<T,N> & tuple, const SprinterLayout & layout) {
243  return Sprinter::sequenceToStream(ostr, tuple, layout);
244 }
245 */
246 
247 } // drain
248 
249 
250 #endif
Definition: StringBuilder.h:58
Definition: TupleBase.h:54
tuplebase_t & assignSequence(T &sequence, bool LENIENT=false)
Proposed for tuples only; derived classes should not shadow this.
Definition: TupleBase.h:244
void fill(T i)
Set all the elements to i.
Definition: TupleBase.h:272
Tuple of N elements of type T.
Definition: UniTuple.h:65
UniTuple(const UniTuple< T, N > &t)
Copy constructor.
Definition: UniTuple.h:94
Definition: DataSelector.cpp:1277
Definition: Type.h:542
static const std::string name
Default implementation: name returned by std::type_info::name()
Definition: Type.h:558