Nymph  v1.5.2
Flow-Based Data Processing Framework
KTExtensibleStruct.hh
Go to the documentation of this file.
1 /*
2  * KTExtensibleStruct.hh
3  *
4  * Created on: Feb 14, 2013
5  * Author: nsoblath
6  * Original Author: Sanshiro Enomoto <sanshiro@uw.edu> (KDExternalStruct, from the KATRIN experiment)
7  */
8 
9 #ifndef KTEXTENSIBLESTRUCT_HH_
10 #define KTEXTENSIBLESTRUCT_HH_
11 
12 namespace Nymph
13 {
14 
15  // *) operator= reallocates extended fields: to avoid this, use Pull().
16 
21  template< class XBaseType >
22  struct KTExtensibleStructCore : public XBaseType
23  {
24  public:
29  virtual ~KTExtensibleStructCore();
33  virtual void Clear(void);
35  template< class XStructType > inline XStructType& Of(void);
37  template< class XStructType > inline const XStructType& Of(void) const;
39  template< class XStructType > inline bool Has(void) const;
41  template< class XStructType > inline XStructType* Detatch(void);
43  virtual KTExtensibleStructCore* Clone(void) const = 0;
45  virtual void Pull(const KTExtensibleStructCore< XBaseType >& object) = 0;
54  protected:
55  void SetPrevPtrInNext();
58  };
59 
60 
61 
62  template< class XInstanceType, class XBaseType >
64  {
65  public:
67  KTExtensibleStruct(void);
70  virtual ~KTExtensibleStruct();
74  virtual KTExtensibleStructCore< XBaseType >* Clone(void) const;
76  virtual void Pull(const KTExtensibleStructCore< XBaseType >& object);
77  void SetIsCopyDisabled(bool flag);
78  private:
80  };
81 
82 
83 
84  template<class XBaseType>
86  {
87  fPrev = 0;
88  fNext = 0;
89  }
90 
91  template<class XBaseType>
93  {
94  fPrev = 0;
95  fNext = 0;
96  }
97 
98  template<class XBaseType>
100  {
101  delete fNext;
102  fNext = 0;
103  }
104 
105  template<class XBaseType>
107  {
108  fNext = 0;
109  return *this;
110  }
111 
112  template<class XBaseType>
114  {
115  delete fNext;
116  fNext = 0;
117  }
118 
119  template<class XBaseType>
120  template<class XStructType>
121  inline XStructType& KTExtensibleStructCore<XBaseType>::Of(void)
122  {
123  XStructType* target = dynamic_cast<XStructType*>(this);
124  if (target)
125  {
126  return *target;
127  }
128 
129  if (! fNext)
130  {
131  fNext = new XStructType();
132  fNext->fPrev = this;
133  }
134 
135  return fNext->Of<XStructType>();
136  }
137 
138  template<class XBaseType>
139  template<class XStructType>
140  inline const XStructType& KTExtensibleStructCore<XBaseType>::Of(void) const
141  {
142  const XStructType* target = dynamic_cast<const XStructType*>(this);
143  if (target)
144  {
145  return *target;
146  }
147 
148  if (fNext == 0)
149  {
150  fNext = new XStructType();
151  fNext->fPrev = const_cast< KTExtensibleStructCore< XBaseType >* >(this);
152  }
153 
154  return fNext->Of<XStructType>();
155  }
156 
157 
158 
159  template<class XBaseType>
160  template<class XStructType>
162  {
163  if (dynamic_cast<const XStructType*>(this))
164  {
165  return true;
166  }
167  if (fNext)
168  {
169  return fNext->Has<XStructType>();
170  }
171 
172  return false;
173  }
174 
175 
176 
177  template<class XBaseType>
178  template<class XStructType>
180  {
181  if (! fNext)
182  {
183  return 0;
184  }
185  XStructType* next = dynamic_cast<XStructType*>(fNext);
186  if (next)
187  {
188  if (next->fNext)
189  {
190  fNext = next->fNext;
191  fNext->fPrev = this;
192  next->fNext = 0;
193  }
194  next->fPrev = 0;
195  return next;
196  }
197  return fNext->Detatch<XStructType>();
198  }
199 
200 
201  template<class XBaseType>
203  {
204  return fNext;
205  }
206 
207  template<class XBaseType>
209  {
210  return fPrev;
211  }
212 
213  template<class XBaseType>
215  {
216  if (fNext == 0) return this;
217  return fNext->Last();
218  }
219 
220  template<class XBaseType>
222  {
223  if (fPrev == 0) return this;
224  return fPrev->First();
225  }
226 
227  template<class XBaseType>
229  {
230  fNext->fPrev = this;
231  return;
232  }
233 
234 
235 
236  template<class XInstanceType, class XBaseType>
238  {
239  fIsCopyDisabled = false;
240  }
241 
242  template<class XInstanceType, class XBaseType>
244  {
245  fIsCopyDisabled = false;
246  }
247 
248  template<class XInstanceType, class XBaseType>
251  {
252  // should this check fIsCopyDisabled in object?
253  fIsCopyDisabled = false;
254 
255  if (object.fNext)
256  {
257  this->fNext = object.fNext->Clone();
258  }
259  }
260 
261  template<class XInstanceType, class XBaseType>
263  {
264  // should this check fIsCopyDisabled in object?
265  if ((&object == this) || fIsCopyDisabled)
266  {
267  return *this;
268  }
269 
270  delete this->fNext;
271  this->fNext = 0;
272 
273  if (object.fNext)
274  {
275  this->fNext = object.fNext->Clone();
277  //this->fNext->fPrev = this;
278  }
279 
280  return *this;
281  }
282 
283  template<class XInstanceType, class XBaseType>
285  {
286  // assume CRTP is used properly,
287  // otherwise compiling fails here (intended behavior)
288  XInstanceType* instance = new XInstanceType(dynamic_cast<const XInstanceType&>(*this));
289  if (this->fNext)
290  {
291  instance->fNext = this->fNext->Clone();
292  instance->SetPrevPtrInNext();
293  //instance->fNext->fPrev = instance->fNext;
294  }
295  return instance;
296  }
297 
298  template<class XInstanceType, class XBaseType>
300  {
301  if (&object == this)
302  {
303  return;
304  }
305 
306  fIsCopyDisabled = true;
307  XInstanceType* instance = dynamic_cast<XInstanceType*>(this);
308  if (object.template Has<XInstanceType>())
309  {
310  instance->operator=(object.template Of<XInstanceType>());
311  }
312  else
313  {
314  instance->operator=(XInstanceType());
315  }
316  fIsCopyDisabled = false;
317 
318  if (this->fNext)
319  {
320  this->fNext->Pull(object);
321  }
322  }
323 
324  template<class XInstanceType, class XBaseType>
326  {
327  fIsCopyDisabled = flag;
328  return;
329  }
330 
331 } /* namespace Nymph */
332 #endif /* KTEXTENSIBLESTRUCT_HH_ */
virtual KTExtensibleStructCore< XBaseType > * Clone(void) const
Duplicates the extended object.
bool Has(void) const
Returns true if XStructType is or is below this object.
virtual void Pull(const KTExtensibleStructCore< XBaseType > &object)
Duplicates object only.
KTExtensibleStruct(void)
Default constructor.
virtual void Pull(const KTExtensibleStructCore< XBaseType > &object)=0
Duplicates object only.
KTExtensibleStructCore * Next() const
Returns the pointer to the next field.
XStructType & Of(void)
Returns a reference to the object of type XStructType; creates that object if it doesn&#39;t exist...
virtual void Clear(void)
Removes extended fields.
KTExtensibleStructCore * Prev() const
Returns the pointer to the previous field.
KTExtensibleStruct & operator=(const KTExtensibleStruct &object)
Duplicates the extended object.
virtual KTExtensibleStructCore * Clone(void) const =0
Duplicates the extended object.
KTExtensibleStructCore & operator=(const KTExtensibleStructCore &)
Duplicates the extended object.
KTExtensibleStructCore * fPrev
KTExtensibleStructCore * Last() const
Returns the pointer to the last field.
KTExtensibleStructCore * fNext
KTExtensibleStructCore * First() const
Returns the pointer to the first field.
XStructType * Detatch(void)
Extracts object of type XStructType.
KTExtensibleStructCore(void)
Default constructor.