Ariles
types.h
Go to the documentation of this file.
1 /**
2  @file
3  @author Alexander Sherikov
4 
5  @copyright 2019 Alexander Sherikov, Licensed under the Apache License, Version 2.0.
6  (see @ref LICENSE or http://www.apache.org/licenses/LICENSE-2.0)
7 
8  @brief
9 */
10 
11 #pragma once
12 
13 namespace ariles2
14 {
15  template <template <class> class t_Pointer, class t_Base, class t_Instantiator>
16  class Any : public ariles2::DefaultBase
17  {
18 #define ARILES2_ENTRIES(v) \
19  ARILES2_TYPED_ENTRY_(v, id, std::string) \
20  ARILES2_TYPED_ENTRY_(v, value, t_Pointer<t_Base>)
21 #include ARILES2_INITIALIZE
22 
23  protected:
24  bool isConsistent() const
25  {
26  if (("" != id_) && (nullptr != value_.get()))
27  {
28  return (true);
29  }
30 
31  if (("" == id_) && (nullptr == value_.get()))
32  {
33  return (true);
34  }
35 
36  return (false);
37  }
38 
39 
40  public:
41  Any()
42  {
43  ariles2::apply<ariles2::Defaults>(*this);
44  }
45 
46 
47  explicit Any(const std::string &id)
48  {
49  build(id);
50  }
51 
52 
53  void build(const std::string &id)
54  {
55  id_ = id;
56  value_ = t_Instantiator::instantiate(id_);
57  CPPUT_ASSERT(nullptr != value_.get(), "Could not instantiate class.");
58  }
59 
60 
61  bool isInitialized() const
62  {
63  return ("" != id_ && nullptr != value_.get());
64  }
65 
66 
67  /// @{
68  /**
69  * @brief Cast methods are potentially dangerous, no id checks are
70  * performed. If value is not initialized the returned pointer may
71  * be nullptr.
72  */
73  template <class t_Derived>
74  t_Derived *cast()
75  {
76  return (dynamic_cast<t_Derived *>(value_.get()));
77  }
78 
79 
80  template <class t_Derived>
81  const t_Derived *cast() const
82  {
83  return (dynamic_cast<const t_Derived *>(value_.get()));
84  }
85  /// @}
86 
87 
88  /// @{
89  /**
90  * @brief These casts succeed if the Ariles config section id
91  * matches the given string.
92  */
93  template <class t_Derived>
94  t_Derived *cast(const std::string &config_section_id)
95  {
96  if (isInitialized())
97  {
98  if (config_section_id == value_->arilesDefaultID())
99  {
100  return (dynamic_cast<t_Derived *>(value_.get()));
101  }
102  }
103  return (nullptr);
104  }
105 
106 
107  template <class t_Derived>
108  const t_Derived *cast(const std::string &config_section_id) const
109  {
110  if (isInitialized())
111  {
112  if (config_section_id == value_->arilesDefaultID())
113  {
114  return (dynamic_cast<t_Derived *>(value_.get()));
115  }
116  }
117  return (nullptr);
118  }
119  /// @}
120 
121 
122  t_Base *operator->()
123  {
124  CPPUT_ASSERT(isInitialized(), "Not initialized");
125  return (value_.get());
126  }
127 
128 
129  const t_Base *operator->() const
130  {
131  CPPUT_ASSERT(isInitialized(), "Not initialized");
132  return (value_.get());
133  }
134 
135 
136  t_Base &operator*()
137  {
138  CPPUT_ASSERT(isInitialized(), "Not initialized");
139  return (*value_);
140  }
141 
142 
143  const t_Base &operator*() const
144  {
145  CPPUT_ASSERT(isInitialized(), "Not initialized");
146  return (*value_);
147  }
148 
149 
150  // Ariles methods
151 
152  void arilesVisit(ariles2::Write &visitor, const ariles2::Write::Parameters &param) const
153  {
155  CPPUT_ASSERT(
156  isConsistent(),
157  "Could not write config: entry is in an inconsistent (partially initialized) state.");
158 
159  visitor.visitMapEntry(id_, "id", param);
160  if (isInitialized())
161  {
162  visitor.visitMapEntry(*value_, "value", param);
163  }
164  }
165 
166 
167  void arilesVisit(ariles2::Read &visitor, const ariles2::Read::Parameters &parameters)
168  {
170 
171  if (visitor.visitMapEntry(id_, "id", parameters))
172  {
173  if ("" == id_)
174  {
175  CPPUT_ASSERT(parameters.allow_missing_entries_, "Id is empty, value cannot be read.");
176  }
177  else
178  {
179  build(id_);
180  visitor.visitMapEntry(*value_, "value", parameters, true);
181  }
182  }
183  }
184 
185 
187  {
189  if (isInitialized())
190  {
191  value_->arilesVirtualVisit(visitor, param);
192  }
193  }
194 
195 
197  {
199  if (isInitialized())
200  {
201  value_->arilesVirtualVisit(visitor, param);
202  }
203  }
204 
205 
207  {
209  if (isInitialized())
210  {
211  value_->arilesVirtualVisit(visitor, param);
212  }
213  }
214  };
215 } // namespace ariles2
216 
217 
218 namespace ariles2
219 {
220  template <template <class> class t_Pointer, class t_Base, class t_Instantiator>
221  class Any2 : public ariles2::DefaultBase
222  {
223 #define ARILES2_ENTRIES(v) \
224  ARILES2_TYPED_ENTRY_(v, id, std::string) \
225  ARILES2_TYPED_ENTRY_(v, value, t_Pointer<t_Base>)
226 #include ARILES2_INITIALIZE
227 
228  protected:
229  bool isConsistent() const
230  {
231  if (("" != id_) && (nullptr != value_.get()))
232  {
233  return (true);
234  }
235 
236  if (("" == id_) && (nullptr == value_.get()))
237  {
238  return (true);
239  }
240 
241  return (false);
242  }
243 
244 
245  public:
247  {
248  ariles2::apply<ariles2::Defaults>(*this);
249  }
250 
251 
252  explicit Any2(const std::string &id)
253  {
254  build(id);
255  }
256 
257 
258  void build(const std::string &id)
259  {
260  id_ = id;
261  value_ = t_Instantiator::instantiate(id_);
262  CPPUT_ASSERT(nullptr != value_.get(), "Could not instantiate class.");
263  }
264 
265 
266  bool isInitialized() const
267  {
268  return ("" != id_ && nullptr != value_.get());
269  }
270 
271 
272  /// @{
273  /**
274  * @brief Cast methods are potentially dangerous, no id checks are
275  * performed. If value is not initialized the returned pointer may
276  * be nullptr.
277  */
278  template <class t_Derived>
279  t_Derived *cast()
280  {
281  return (dynamic_cast<t_Derived *>(value_.get()));
282  }
283 
284 
285  template <class t_Derived>
286  const t_Derived *cast() const
287  {
288  return (dynamic_cast<const t_Derived *>(value_.get()));
289  }
290  /// @}
291 
292 
293  /// @{
294  /**
295  * @brief These casts succeed if the Ariles config section id
296  * matches the given string.
297  */
298  template <class t_Derived>
299  t_Derived *cast(const std::string &config_section_id)
300  {
301  if (isInitialized())
302  {
303  if (config_section_id == value_->arilesDefaultID())
304  {
305  return (dynamic_cast<t_Derived *>(value_.get()));
306  }
307  }
308  return (nullptr);
309  }
310 
311 
312  template <class t_Derived>
313  const t_Derived *cast(const std::string &config_section_id) const
314  {
315  if (isInitialized())
316  {
317  if (config_section_id == value_->arilesDefaultID())
318  {
319  return (dynamic_cast<t_Derived *>(value_.get()));
320  }
321  }
322  return (nullptr);
323  }
324  /// @}
325 
326 
327  t_Base *operator->()
328  {
329  CPPUT_ASSERT(isInitialized(), "Not initialized");
330  return (value_.get());
331  }
332 
333 
334  const t_Base *operator->() const
335  {
336  CPPUT_ASSERT(isInitialized(), "Not initialized");
337  return (value_.get());
338  }
339 
340 
341  t_Base &operator*()
342  {
343  CPPUT_ASSERT(isInitialized(), "Not initialized");
344  return (*value_);
345  }
346 
347 
348  const t_Base &operator*() const
349  {
350  CPPUT_ASSERT(isInitialized(), "Not initialized");
351  return (*value_);
352  }
353 
354 
355  // Ariles methods
356 
357  void arilesVisit(ariles2::Write &visitor, const ariles2::Write::Parameters &param) const
358  {
360  CPPUT_ASSERT(
361  isConsistent(),
362  "Could not write config: entry is in an inconsistent (partially initialized) state.");
363 
364  visitor.visitMapEntry(id_, "id", param);
365  if (isInitialized())
366  {
367  value_->arilesVirtualVisit(visitor, param);
368  }
369  }
370 
371 
373  {
375 
376  if (visitor.visitMapEntry(id_, "id", param))
377  {
378  if ("" == id_)
379  {
380  CPPUT_ASSERT(param.allow_missing_entries_, "Id is empty, value cannot be read.");
381  }
382  else
383  {
384  build(id_);
385 
386  try
387  {
388  value_->arilesVirtualVisit(visitor, param);
389  }
390  catch (const std::exception &e)
391  {
392  CPPUT_THROW("Failed to parse entry <", id_, "> || ", e.what());
393  }
394  }
395  }
396  }
397 
398 
400  {
402  if (isInitialized())
403  {
404  value_->arilesVirtualVisit(visitor, param);
405  }
406  }
407 
408 
410  {
412  if (isInitialized())
413  {
414  value_->arilesVirtualVisit(visitor, param);
415  }
416  }
417 
418 
420  {
422  if (isInitialized())
423  {
424  value_->arilesVirtualVisit(visitor, param);
425  }
426  }
427 
428 
429  std::size_t arilesVisit(const ariles2::Count &visitor, const ariles2::Count::Parameters &param) const
430  {
431  if (isInitialized())
432  {
433  return (this->value_->arilesVirtualVisit(visitor, param) + 1);
434  }
435 
436  return (1);
437  }
438 
439 
440  std::size_t arilesVisit(const ariles2::CountMissing &visitor, const ariles2::CountMissing::Parameters &param)
441  const
442  {
443  CPPUT_ASSERT(isInitialized(), "Not initialized");
444  return (this->value_->arilesVirtualVisit(visitor, param));
445  }
446  };
447 } // namespace ariles2
448 
449 
450 namespace ariles2
451 {
452  template <class t_Pointer>
454  {
455  public:
456  using BasePointer = t_Pointer;
458 
459 
460  public:
462 
463 
464  protected:
466  {
467  }
468 
469  explicit CustomPointerBase(const t_Pointer &value)
470  {
471  value_ = value;
472  }
473 
474  explicit CustomPointerBase(const typename Handler::Value &value)
475  {
476  Handler::allocate(value_);
477  *value_ = value;
478  }
479 
481  {
482  }
483 
484 
485  public:
486  CustomPointerBase &operator=(const t_Pointer &value)
487  {
488  value_ = value;
489  return (*this);
490  }
491 
492  operator BasePointer &()
493  {
494  return (value_);
495  }
496 
497  operator const BasePointer &() const
498  {
499  return (value_);
500  }
501 
502 
503  typename Handler::Value *operator->() const
504  {
505  CPPUT_ASSERT(not isNull(), "Not initialized");
506  return (value_.get());
507  }
508 
509 
510  typename Handler::Value &operator*() const
511  {
512  CPPUT_ASSERT(not isNull(), "Not initialized");
513  return (*value_);
514  }
515 
516 
517  const typename Handler::Value *get() const
518  {
519  return (value_.get());
520  }
521 
522  typename Handler::Value *get()
523  {
524  return (value_.get());
525  }
526 
527 
529  {
531  if (not isNull())
532  {
533  value_->arilesVirtualVisit(visitor, param);
534  }
535  }
536 
537 
538  bool isNull() const
539  {
540  return (Handler::isNull(value_));
541  }
542 
543 
544 #ifdef ARILES2_METHODS_compare
545  template <class t_Other>
546  void arilesVisit(ariles2::Compare &visitor, const t_Other &other, const ariles2::Compare::Parameters &param)
547  const
548  {
550  if (value_.get() != other.value_.get())
551  {
552  if (nullptr != value_ and nullptr != other.value_)
553  {
554  value_->arilesVisit(visitor, *other.value_, param);
555  }
556  else
557  {
558  visitor.equal_ = false;
559  }
560  }
561  }
562 #endif
563 
564 #ifdef ARILES2_METHODS_copyto
565  template <class t_Other>
566  void arilesVisit(ariles2::CopyTo &visitor, t_Other &other, const ariles2::CopyTo::Parameters &param) const
567  {
569  ariles2::copyto::apply_copyto(visitor, value_, other, param);
570  }
571 #endif
572 
573 #ifdef ARILES2_METHODS_copyfrom
574  template <class t_Other>
575  void arilesVisit(ariles2::CopyFrom &visitor, const t_Other &other, const ariles2::CopyFrom::Parameters &param)
576  {
578  ariles2::copyfrom::apply_copyfrom(visitor, value_, other, param);
579  }
580 #endif
581  };
582 
583 
584 
585  template <class t_Pointer>
586  class NonNullPointer : public CustomPointerBase<t_Pointer>, public ariles2::DefaultBase
587  {
588 #include ARILES2_INITIALIZE
589 
590 
591  public:
593  {
594  ariles2::apply<ariles2::Defaults>(*this);
595  }
599 
600 
601 
602  void arilesVisit(ariles2::Write &writer, const ariles2::Write::Parameters &parameters) const
603  {
605  CPPUT_ASSERT(not this->isNull(), "Could not write config: entry is not initialized");
606  this->value_->arilesVirtualVisit(writer, parameters);
607  }
608 
609 
610  void arilesVisit(ariles2::Read &reader, const ariles2::Read::Parameters &parameters)
611  {
613  CPPUT_ASSERT(not this->isNull(), "Not initialized");
614  this->value_->arilesVirtualVisit(reader, parameters);
615  }
616 
617 
619  {
621  CPPUT_ASSERT(not this->isNull(), "Not initialized");
622  this->value_->arilesVirtualVisit(visitor, param);
623  }
624 
625 
626  std::size_t arilesVisit(const ariles2::Count &visitor, const ariles2::Count::Parameters &param) const
627  {
629  CPPUT_ASSERT(not this->isNull(), "Not initialized");
630  return (this->value_->arilesVirtualVisit(visitor, param));
631  }
632 
633 
634  std::size_t arilesVisit(const ariles2::CountMissing &visitor, const ariles2::CountMissing::Parameters &param)
635  const
636  {
638  CPPUT_ASSERT(not this->isNull(), "Not initialized");
639  return (this->value_->arilesVirtualVisit(visitor, param));
640  }
641 
642 
644  {
647  this->value_->arilesVirtualVisit(visitor, param);
648  }
649 
650 
651 
652 #ifdef ARILES2_METHODS_graphviz
653  void arilesVisit(ariles2::Graphviz &writer, const ariles2::Graphviz::Parameters &parameters) const
654  {
656  CPPUT_ASSERT(not this->isNull(), "Could not write config: entry is not initialized");
657  this->value_->arilesVirtualVisit(writer, parameters);
658  }
659 #endif
660  };
661 
662 
663 
664  template <class t_Pointer>
665  class OptionalPointer : public CustomPointerBase<t_Pointer>, public ariles2::DefaultBase
666  {
667 #include ARILES2_INITIALIZE
668 
669 
670  public:
672  {
673  ariles2::apply<ariles2::Defaults>(*this);
674  }
678 
679 
680 
681  void arilesVisit(ariles2::Write &writer, const ariles2::Write::Parameters &parameters) const
682  {
684  CPPUT_ASSERT(
685  parameters.allow_missing_entries_, "Missing entries must be allowed when using OptionalPointer");
686  // should never happen
687  CPPUT_ASSERT(not this->isNull(), "Could not write config: entry is not initialized");
688  this->value_->arilesVirtualVisit(writer, parameters);
689  }
690 
691 
692  void arilesVisit(ariles2::Read &reader, const ariles2::Read::Parameters &parameters)
693  {
695  if (this->isNull())
696  {
698  ariles2::apply<ariles2::Defaults>(*this->value_);
699  }
700  this->value_->arilesVirtualVisit(reader, parameters);
701  }
702 
703 
705  {
707  if (not this->isNull())
708  {
709  this->value_->arilesVirtualVisit(visitor, param);
710  }
711  }
712 
713 
714  std::size_t arilesVisit(const ariles2::Count &visitor, const ariles2::Count::Parameters &param) const
715  {
717  if (not this->isNull())
718  {
719  return (this->value_->arilesVirtualVisit(visitor, param));
720  }
721  return (0);
722  }
723 
724 
725  std::size_t arilesVisit(const ariles2::CountMissing &visitor, const ariles2::CountMissing::Parameters &param)
726  const
727  {
729  if (not this->isNull())
730  {
731  return (this->value_->arilesVirtualVisit(visitor, param));
732  }
733  return (0);
734  }
735 
736 
738  {
740  if (not this->isNull())
741  {
742  this->value_->arilesVirtualVisit(visitor, param);
743  }
744  }
745 
746 
747 
748 #ifdef ARILES2_METHODS_graphviz
749  void arilesVisit(ariles2::Graphviz &writer, const ariles2::Graphviz::Parameters &parameters) const
750  {
752  if (not this->isNull())
753  {
754  this->value_->arilesVirtualVisit(writer, parameters);
755  }
756  }
757 #endif
758  };
759 
760 
761  template <class t_Entry>
763  {
764  return (entry.isNull());
765  }
766 } // namespace ariles2
t_Base & operator*()
Definition: types.h:341
const t_Derived * cast() const
Definition: types.h:286
t_Derived * cast(const std::string &config_section_id)
These casts succeed if the Ariles config section id matches the given string.
Definition: types.h:299
const t_Base * operator->() const
Definition: types.h:334
std::size_t arilesVisit(const ariles2::Count &visitor, const ariles2::Count::Parameters &param) const
Definition: types.h:429
void arilesVisit(const ariles2::PreWrite &visitor, const ariles2::PreWrite::Parameters &param)
Definition: types.h:409
t_Derived * cast()
Cast methods are potentially dangerous, no id checks are performed. If value is not initialized the r...
Definition: types.h:279
std::size_t arilesVisit(const ariles2::CountMissing &visitor, const ariles2::CountMissing::Parameters &param) const
Definition: types.h:440
void arilesVisit(const ariles2::Finalize &visitor, const ariles2::Finalize::Parameters &param)
Definition: types.h:399
void arilesVisit(ariles2::Read &visitor, const ariles2::Read::Parameters &param)
Definition: types.h:372
void arilesVisit(ariles2::Write &visitor, const ariles2::Write::Parameters &param) const
Definition: types.h:357
const t_Derived * cast(const std::string &config_section_id) const
Definition: types.h:313
void build(const std::string &id)
Definition: types.h:258
Any2(const std::string &id)
Definition: types.h:252
t_Base * operator->()
Definition: types.h:327
const t_Base & operator*() const
Definition: types.h:348
void arilesVisit(const ariles2::Defaults &visitor, const ariles2::Defaults::Parameters &param)
Definition: types.h:419
bool isConsistent() const
Definition: types.h:229
bool isInitialized() const
Definition: types.h:266
const t_Derived * cast() const
Definition: types.h:81
t_Base * operator->()
Definition: types.h:122
void arilesVisit(ariles2::Write &visitor, const ariles2::Write::Parameters &param) const
Definition: types.h:152
t_Derived * cast()
Cast methods are potentially dangerous, no id checks are performed. If value is not initialized the r...
Definition: types.h:74
void arilesVisit(const ariles2::Defaults &visitor, const ariles2::Defaults::Parameters &param)
Definition: types.h:206
bool isConsistent() const
Definition: types.h:24
t_Base & operator*()
Definition: types.h:136
const t_Derived * cast(const std::string &config_section_id) const
Definition: types.h:108
t_Derived * cast(const std::string &config_section_id)
These casts succeed if the Ariles config section id matches the given string.
Definition: types.h:94
void arilesVisit(const ariles2::PreWrite &visitor, const ariles2::PreWrite::Parameters &param)
Definition: types.h:196
bool isInitialized() const
Definition: types.h:61
const t_Base * operator->() const
Definition: types.h:129
const t_Base & operator*() const
Definition: types.h:143
void arilesVisit(const ariles2::Finalize &visitor, const ariles2::Finalize::Parameters &param)
Definition: types.h:186
void arilesVisit(ariles2::Read &visitor, const ariles2::Read::Parameters &parameters)
Definition: types.h:167
Any(const std::string &id)
Definition: types.h:47
void build(const std::string &id)
Definition: types.h:53
Handler::Value * operator->() const
Definition: types.h:503
BasePointer value_
Definition: types.h:461
CustomPointerBase & operator=(const t_Pointer &value)
Definition: types.h:486
CustomPointerBase(const t_Pointer &value)
Definition: types.h:469
CustomPointerBase(const typename Handler::Value &value)
Definition: types.h:474
bool isNull() const
Definition: types.h:538
const Handler::Value * get() const
Definition: types.h:517
Handler::Value * get()
Definition: types.h:522
void arilesVisit(const ariles2::PreWrite &visitor, const ariles2::PreWrite::Parameters &param)
Definition: types.h:528
virtual ~CustomPointerBase()
Definition: types.h:480
Handler::Value & operator*() const
Definition: types.h:510
void arilesVisit(ariles2::Read &reader, const ariles2::Read::Parameters &parameters)
Definition: types.h:610
std::size_t arilesVisit(const ariles2::Count &visitor, const ariles2::Count::Parameters &param) const
Definition: types.h:626
void arilesVisit(const ariles2::Finalize &visitor, const ariles2::Finalize::Parameters &param)
Definition: types.h:618
std::size_t arilesVisit(const ariles2::CountMissing &visitor, const ariles2::CountMissing::Parameters &param) const
Definition: types.h:634
void arilesVisit(ariles2::Write &writer, const ariles2::Write::Parameters &parameters) const
Definition: types.h:602
void arilesVisit(const ariles2::Defaults &visitor, const ariles2::Defaults::Parameters &param)
Definition: types.h:643
std::size_t arilesVisit(const ariles2::Count &visitor, const ariles2::Count::Parameters &param) const
Definition: types.h:714
void arilesVisit(ariles2::Read &reader, const ariles2::Read::Parameters &parameters)
Definition: types.h:692
void arilesVisit(const ariles2::Finalize &visitor, const ariles2::Finalize::Parameters &param)
Definition: types.h:704
void arilesVisit(ariles2::Write &writer, const ariles2::Write::Parameters &parameters) const
Definition: types.h:681
std::size_t arilesVisit(const ariles2::CountMissing &visitor, const ariles2::CountMissing::Parameters &param) const
Definition: types.h:725
void arilesVisit(const ariles2::Defaults &visitor, const ariles2::Defaults::Parameters &param)
Definition: types.h:737
bool visitMapEntry(t_Entry &entry, const std::string &name, const Parameters &param, const bool override_missing_entries_locally=false)
Definition: read.h:420
void visitMapEntry(const t_Entry &entry, const std::string &entry_name, const t_Parameters &param)
Definition: write.h:302
#define CPPUT_THROW(...)
Definition: exception.h:19
#define CPPUT_ASSERT(condition,...)
Definition: exception.h:32
void apply_copyfrom(t_Visitor &visitor, t_Left &left, const t_Right &right, const typename t_Visitor::Parameters &param)
Definition: basic.h:307
void apply_copyto(t_Visitor &visitor, const t_Left &left, t_Right &right, const typename t_Visitor::Parameters &param)
Definition: basic.h:353
Definition: basic.h:17
bool isMissing(const ARILES2_POINTER_TYPE< t_Entry > &entry)
#define CPPUT_TRACE_FUNCTION
Definition: trace.h:126