Cloner.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 #ifndef Cloner_H_
32 #define Cloner_H_
33 
34 //#include <list>
35 #include <map>
36 #include <exception>
37 #include <iostream>
38 #include <sstream>
39 
40 namespace drain {
41 
45 template <class T>
46 struct ClonerBase {
47 
49 
52  typedef size_t index_t;
53 
54  // If
55  typedef std::pair<index_t, T*> entry_t;
56 
57  ClonerBase(){};
58 
59  virtual
60  ~ClonerBase(){
61  };
62 
63 
64  virtual
65  T & getCloned() const = 0; // could be const (if mutable ptrs )
66 
67  virtual
68  entry_t getClonerEntry() const = 0;
69 
70 
72  // virtual const T & getCloned(index_t i) const = 0;
73 
75  virtual
76  T & getCloned(index_t i) const = 0;
77 
78 
80  virtual
81  const T & getSource() const = 0;
82 
84  virtual
85  T & getSource() = 0;
86 
87 
88 
89  // Return the number of cloned instances.
90  virtual
91  size_t count() const = 0;
92 
94 
97  virtual // clear
98  bool drop(index_t i) const = 0;
99 
100  //experimental
101  // virtual bool dropUnique() = 0;
102 
103  protected:
104 
105 
106 
107 };
108 
109 
111 
116 template <class B, class S>
117 struct Cloner : public ClonerBase<B> {
118 
119  typedef ClonerBase<B> clonerbase_t;
120 
121  // "inherit" a type
122  typedef typename clonerbase_t::index_t index_t;
123 
124  // "inherit" a type
125  typedef typename clonerbase_t::entry_t entry_t;
126 
127  typedef std::map<index_t,S *> ptr_container_t;
128 
129 
130  Cloner(){};
131 
133  Cloner(const Cloner<B,S> & c) : src(c.src){
134  };
135 
137  Cloner(const S & s) : src(s){
138  };
139 
140  virtual
141  ~Cloner(){
142  for (typename ptr_container_t::iterator it=ptrs.begin(); it!= ptrs.end(); ++it){
143  //std::cerr << "deleting instance, id=" << it->first << '\n';
144  delete it->second;
145  }
146  };
147 
149  B & getCloned() const {
150  return getClonedSrc();
151  };
152 
153 
155  /*
156  *
157  virtual
158  const B & getCloned(index_t i) const {
159  typename ptr_container_t::const_iterator it = ptrs.find(i);
160  if (it == ptrs.end()){
161  std::stringstream sstr;
162  sstr << __FILE__ << ':' << __FUNCTION__ << ": index not found: "<< i;
163  throw std::runtime_error(sstr.str());
164  }
165  return *it->second;
166  };
167  */
168 
170  /*
171  * \param i - index (id) of the instance.
172  */
173  virtual
174  B & getCloned(index_t i) const {
175  typename ptr_container_t::iterator it = ptrs.find(i);
176  if (it == ptrs.end()){
177  std::stringstream sstr;
178  sstr << __FILE__ << ':' << __FUNCTION__ << ": index not found: "<< i;
179  throw std::runtime_error(sstr.str());
180  }
181  return *it->second;
182  };
183 
184 
186  S & getClonedSrc() const{
187  S *ptr = new S(src); // NOTE: parameterReferences must be done
188  //this->ptrs.insert(ptr); //push_front(p);
189  this->ptrs[getNewIndex()] = ptr;
190  return *ptr;
191  };
192 
193 
194  virtual
195  entry_t getClonerEntry() const {
196  S *ptr = new S(src); // NOTE: parameterReferences must be done
197  index_t i = getNewIndex();
198  this->ptrs[i] = ptr; //.insert(ptr); //push_front(p);
199  return entry_t(i, ptr);
200  };
201 
202 
203  /* Consider separating these to "Provider" or "Factory" etc. */
204 
206  /*
207  * The returned object is possibly static.
208  */
209  virtual
210  const B & getSource() const {
211  return getSourceOrig();
212  };
213 
215  /*
216  * The returned object is possibly static.
217  */
218  virtual
219  B & getSource() {
220  return getSourceOrig();
221  };
222 
224  /*
225  * The returned object is possibly static.
226  */
227  virtual
228  const S & getSourceOrig() const {
229  return src;
230  };
231 
233  /*
234  * The returned object is possibly static.
235  */
236  virtual
238  return src;
239  };
240 
241 
242  virtual inline
243  size_t count() const {
244  return ptrs.size();
245  }
246 
247 
249  virtual inline // clear
250  bool drop(index_t i) const {
251 
252  const typename ptr_container_t::iterator it = ptrs.find(i);
253 
254  if (it != ptrs.end()){
255  // std::cout << "deleting " << *ptr << ", at #" << (long int)ptr << '\n';
256  // std::cout << "deleting " << (long int)ptr << '\n';
257  delete it->second;
258  ptrs.erase(it); // TODO!
259  return true;
260  }
261  else {
262  std::cerr << "already deleted or does not exist: " << i << '\n';
263  // warn?
264  return false;
265  }
266 
267  }
268 
269 
270  //protected:
271 
273  //static S entry; // Consider non-static
274  S src; // Consider non-static
275 
277  /*
278  inline
279  void clear(){
280  for (typename ptr_container_t::iterator it=ptrs.begin(); it!= ptrs.end(); ++it){
281  S *ptr = *it;
282  std::cout << "deleting " << *ptr << ", at #" << (long int)ptr << '\n';
283  delete ptr;
284  }
285  ptrs.clear();
286  }
287  */
288 
289 
290 
291 protected:
292 
293  // TODO: re-allocate empty slots
294  inline
295  index_t getNewIndex() const {
296  // pra gma omp critical
297  {
298  if (this->ptrs.empty())
299  return 1;
300  else {
301  // std::cerr << "getNewIndex: " << this->ptrs.rbegin()->first << '\n';
302  return this->ptrs.rbegin()->first + 1;
303  }
304  }
305  }
306 
307  // Structure for storing pointers until the target objects should be deleted.
308  mutable
309  ptr_container_t ptrs;
310 
311 
312 };
313 
314 
315 
316 
317 }
318 
319 #endif /* Cloner_H_ */
320 
321 // Drain
Definition: DataSelector.cpp:1277
Definition: Cloner.h:46
size_t index_t
Each cloned entry has an index.
Definition: Cloner.h:52
virtual T & getCloned(index_t i) const =0
Returns an instance at index i.
virtual T & getSource()=0
Returns a reference to an instance.
virtual bool drop(index_t i) const =0
Remove cloned entry (experimental)
virtual const T & getSource() const =0
Returns a reference to an instance (possibly a static one?).
Wrapper for derived class S, returning base class T.
Definition: Cloner.h:117
index_t getNewIndex() const
Remove cloned entries.
Definition: Cloner.h:295
virtual const B & getSource() const
Returns a const reference to a default instance.
Definition: Cloner.h:210
S src
Default instance, also the source for cloning.
Definition: Cloner.h:274
Cloner(const S &s)
Constructor with source object (copied)
Definition: Cloner.h:137
Cloner(const Cloner< B, S > &c)
Copy constructor.
Definition: Cloner.h:133
B & getCloned() const
Implements interface.
Definition: Cloner.h:149
virtual bool drop(index_t i) const
Remove cloned entry.
Definition: Cloner.h:250
S & getClonedSrc() const
Returns a object of class S, initialized with the source.
Definition: Cloner.h:186
virtual const S & getSourceOrig() const
Returns a const reference to a default instance, in actual class.
Definition: Cloner.h:228
virtual B & getSource()
Returns a reference to a default instance.
Definition: Cloner.h:219
virtual S & getSourceOrig()
Returns a reference to a default instance, in actual class.
Definition: Cloner.h:237
virtual B & getCloned(index_t i) const
Returns.
Definition: Cloner.h:174