Ariles
Loading...
Searching...
No Matches
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
13namespace ariles2
14{
15 template <template <class> class t_Pointer, class t_Base, class t_Instantiator>
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:
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 {
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
218namespace ariles2
219{
220 template <template <class> class t_Pointer, class t_Base, class t_Instantiator>
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 {
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
441 const
442 {
443 CPPUT_ASSERT(isInitialized(), "Not initialized");
444 return (this->value_->arilesVirtualVisit(visitor, param));
445 }
446 };
447} // namespace ariles2
448
449
450namespace 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 }
597 using CustomPointerBase<t_Pointer>::operator=;
598 using CustomPointerBase<t_Pointer>::arilesVisit;
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
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>
666 {
667#include ARILES2_INITIALIZE
668
669
670 public:
672 {
673 ariles2::apply<ariles2::Defaults>(*this);
674 }
676 using CustomPointerBase<t_Pointer>::operator=;
677 using CustomPointerBase<t_Pointer>::arilesVisit;
678
679
680
681 void arilesVisit(ariles2::Write &writer, const ariles2::Write::Parameters &parameters) const
682 {
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
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
const t_Base & operator*() const
Definition types.h:348
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
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
t_Base * operator->()
Definition types.h:327
void build(const std::string &id)
Definition types.h:258
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
Any2(const std::string &id)
Definition types.h:252
const t_Derived * cast(const std::string &config_section_id) const
Definition types.h:313
const t_Derived * cast() const
Definition types.h:286
void arilesVisit(const ariles2::Defaults &visitor, const ariles2::Defaults::Parameters &param)
Definition types.h:419
t_Derived * cast()
Cast methods are potentially dangerous, no id checks are performed. If value is not initialized the r...
Definition types.h:279
bool isConsistent() const
Definition types.h:229
const t_Base * operator->() const
Definition types.h:334
bool isInitialized() const
Definition types.h:266
t_Base & operator*()
Definition types.h:341
const t_Derived * cast(const std::string &config_section_id) const
Definition types.h:108
void arilesVisit(ariles2::Write &visitor, const ariles2::Write::Parameters &param) const
Definition types.h:152
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
const t_Derived * cast() const
Definition types.h:81
const t_Base & operator*() const
Definition types.h:143
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:122
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::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
t_Base & operator*()
Definition types.h:136
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
Handler::Value & operator*() const
Definition types.h:510
CustomPointerBase(const t_Pointer &value)
Definition types.h:469
Handler::Value * get()
Definition types.h:522
CustomPointerBase & operator=(const t_Pointer &value)
Definition types.h:486
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
void arilesVisit(const ariles2::PreWrite &visitor, const ariles2::PreWrite::Parameters &param)
Definition types.h:528
virtual ~CustomPointerBase()
Definition types.h:480
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
bool isMissing(const ARILES2_POINTER_TYPE< t_Entry > &entry)
#define CPPUT_TRACE_FUNCTION
Definition trace.h:126