Loading...
Searching...
No Matches
Castable.h
1/*
2
3MIT License
4
5Copyright (c) 2017 FMI Open Development / Markus Peura, first.last@fmi.fi
6
7Permission is hereby granted, free of charge, to any person obtaining a copy
8of this software and associated documentation files (the "Software"), to deal
9in the Software without restriction, including without limitation the rights
10to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11copies of the Software, and to permit persons to whom the Software is
12furnished to do so, subject to the following conditions:
13
14The above copyright notice and this permission notice shall be included in all
15copies or substantial portions of the Software.
16
17THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23SOFTWARE.
24
25*/
26/*
27Part of Rack development has been done in the BALTRAD projects part-financed
28by the European Union (European Regional Development Fund and European
29Neighbourhood Partnership Instrument, Baltic Sea Region Programme 2007-2013)
30*/
31
32#ifndef DRAIN_CASTABLE2
33#define DRAIN_CASTABLE2 "drain::Castable"
34
35#include <string.h> // Old C
36#include <cstddef>
37#include <typeinfo>
38#include <stdexcept>
39#include <iostream>
40#include <vector>
41#include <list>
42#include <set>
43#include <string>
44
45#include "Caster.h"
46#include "Sprinter.h"
47#include "String.h"
48#include "UniTuple.h"
49
50
51namespace drain {
52
53// Forward declaration
54// class Variable;
55
56// Forward declaration
57// class Referencer;
58
60
76class Castable {
77
78// Optionally, constructors of this base class could be protected.
79public:
80
81 inline
82 Castable() : fillArray(false), elementCount(0){
84 caster.unsetType();
85 };
86
88 inline
89 Castable(const Castable &c) : fillArray(false), elementCount(0) {
90 copyFormat(c); // modifies elementCount = misleading; rename?
91 setPtr(c.caster.ptr, c.caster.getType(), c.elementCount);
92 }
93
95 template <class F>
96 Castable(F &p) : fillArray(false), elementCount(0) {
98 setPtr(p);
99 }
100
101 // Obsolete?
105 template <class F>
106 Castable(F *p) : fillArray(false), elementCount(0) {
107 setSeparator();
108 setPtr(p, typeid(F));
109 // std::cerr << "Castable(F *p) type=" << typeid(F).name() << " value=" << *p << " (" << (double)*p << ")" << std::endl;
110 }
111
112
113 inline virtual
114 ~Castable(){};
115
116
117 virtual inline
118 bool typeIsSet() const {
119 return caster.typeIsSet();
120 };
121
123
131 bool empty() const;
132
134 virtual inline
135 const std::type_info & getType() const {
136 return caster.getType();
137 };
138
140
145 inline
146 bool isValid() const {
147 return (caster.typeIsSet()) && (caster.ptr != nullptr);
148 };
149
150
152 virtual inline
153 bool isLinking() const { // rename: external?
154 return isValid(); // return false, if nullptr
155 // return true;
156 }
157
159
164 virtual inline
165 bool isVariable() const { // needed?
166 return false;
167 }
168
170 inline
171 bool isCharArrayString() const {
172 return ((caster.getType() == typeid(char)) && (outputSeparator=='\0')); // "close enough" guess, or a definition?
173 };
174
176 inline
177 bool isStlString() const {
178 return (caster.getType() == typeid(std::string));
179 };
180
182 inline
183 bool isString() const {
184 return (isCharArrayString() || isStlString());
185 };
186
187
189
195 virtual inline
196 size_t getElementCount() const {
197 return elementCount;
198 }
199
201
206 inline
207 size_t getElementSize() const {
208 return caster.getElementSize();
209 };
210
212
216 virtual inline
217 size_t getSize() const final { // final trap
218 return elementCount * caster.getElementSize();
219 }
220
222 inline
223 size_t size() const {
224 return getElementCount();
225 }
226
227
228
230 inline
231 Castable & setFill(bool fill=true){
232 fillArray = fill;
233 return *this;
234 }
235
237 // Has been protected, even private. Why? Essentially setting a value.
238 void clear();
239
243 inline
244 void reset(){
245 caster.unsetType();
246 updateSize(0);
247 setSeparator(',');
248 }
249
251
254 std::string getTypeName() const { // todo: support const string & in Type::call
255 if (isCharArrayString()){
256 static const std::string s("char-array");
257 return s;
258 }
259 else {
260 return Type::call<drain::simpleName>(getType());
261 }
262 }
263
264
265
266 template <class T>
267 Castable &operator=(const T &x){
268 //std::cout << "op= " << x << " -> " << Type::getTypeChar(getType()) << ',' << getElementCount() << std::endl;
269 assign(x);
270 return *this;
271 }
272
276 inline
277 Castable & operator=(const char *c){
278 assignString(c);
279 return *this;
280 }
281
282
283 template <class T>
284 Castable & operator=(const T *x){
285 throw std::runtime_error("Castable & operator=(const T *x): unsupported");
286 return *this;
287 }
288
290
293 inline
295 if (&c != this){
297 }
298 return *this;
299 }
300
301
302 // Special handler for string assignment
303 inline
304 void assign(const std::string &c){
305 assignString(c);
306 }
307
308
309 inline
310 void assign(const char *c){
311 assignString(c);
312 }
313
314 // "NEW"
315 inline
316 void assign(const Castable &c){
318 }
319
320 template <class T>
321 inline
322 void assign(const T *p){
323 if (p == nullptr)
324 reset();
325 else
326 throw std::runtime_error("Castable & assign(const T *p): unsupported");
327 }
328
330
333 template <class T>
334 void assign(const T &x){
335 // std::cout << "assign " << x << " -> " << Type::getTypeChar(getType()) << ',' << getElementCount() << std::endl;
336 suggestType(typeid(T));
337 if (isString()){
338 //std::cout << __FUNCTION__ << ':' << x << " -> " << Type::getTypeChar(getType()) << ',' << getElementCount() << '\n';
339 assignToString(x);
340 }
341 else if (typeIsSet()){
342 if (fillArray){
343 for (size_t i = 0; i<getElementCount(); ++i){
344 caster.put(getPtr(i), x);
345 }
346 }
347 else {
348 requestSize(1);
349 caster.put(x);
350 }
351 }
352 else {
353 std::cerr << __FILE__ << ':' << __FUNCTION__ << ": arg:" << x << '\n';
354 throw std::runtime_error(std::string(__FUNCTION__) + ": type is unset");
355 }
356
357
358 }
359
360
361
363 template<typename T>
364 void assign(std::initializer_list<T> l){
366 }
367
369 template <class T>
370 inline
371 void assign(const std::list<T> & l){
373 }
374
376 template <class T>
377 inline
378 void assign(const std::vector<T> & v){
380 }
381
383 template <class T>
384 inline
385 // Castable &operator=(const std::set<T> & s){
386 void assign(const std::set<T> & s){
388 //return *this;
389 }
390
391
393 Castable & assignCastable(const Castable &c);
394
395
396 template <class T>
397 inline
398 Castable &operator<<(const T &x){
399 append(x);
400 return *this;
401 }
402
403
405 /*
406 * Note: if both source and target are strings, does not split it like with Variable::operator=(const char *).
407 */
408 template <class T>
409 inline
410 void append(const T &x){
411 suggestType(typeid(T)); // must be here, esp. if string suggested
412 if (isString()){
414 }
415 else {
416 // suggestType will be repeated
417 appendToElementArray(x);
418 }
419 }
420
422 inline
423 void append(const char *s){
424 append(std::string(s));
425 }
426
428 template <class T>
429 inline
430 void append(const std::list<T> & l){
431 assignContainer(l, true);
432 }
433
435 template <class T>
436 inline
437 void append(const std::vector<T> & v){
438 assignContainer(v, true);
439 }
440
442 template <class T>
443 inline
444 void append(const std::set<T> & s){
445 assignContainer(s, true);
446 }
447
448 // NEW 2025
449 inline // protected
450 void append(){
451 }
452
453 template <class T, class ...TT>
454 void append(const T &arg, const TT& ...args){
455 append(arg);
456 append(args...);
457 }
458
459
460 template <class T>
461 inline
462 T get(size_t i) const {
463 if (i >= elementCount){
464 std::cerr << __FILE__ << " index=" << i << ", contents: '";
465 this->toStream(std::cerr);
466 std::cerr << "'\n";
467 throw std::runtime_error("Castable::get() index overflow");
468 }
469 return caster.get<T>(getPtr(i));
470 }
471
472
473 template <class T>
474 inline
475 T front() const {
476 if (empty()){
477 throw std::runtime_error("Castable::front() called on empty variable");
478 }
479 return caster.get<T>(getPtr(0));
480 }
481
482 template <class T>
483 inline
484 T back() const {
485 if (empty()){
486 throw std::runtime_error("Castable::back() called on empty variable");
487 }
488 return caster.get<T>(getPtr(elementCount - 1));
489 }
490
492
495 inline
496 void pop_back() { // consider move to Variable (but Flexible needs this anyway.
497 if (empty()){
498 throw std::runtime_error("Castable::front() called on empty variable");
499 }
500 if (!isVariable()){
501 throw std::runtime_error("Castable::pop_back() called on a referencing variable");
502 }
504 }
505
506
507 /*
508 template <class T>
509 inline
510 void setElem(size_t i) const {
511 if (i >= elementCount)
512 throw std::runtime_error("Castable::get() index overflow");
513 return caster.get<T>(getPtr(i));
514 }
515 */
516
517
519
522 inline
523 operator std::string() const {
524 return toStr();
525 }
526
529 // Thanks to Mikael Kilpeläinen.
542 template <class T>
543 operator T() const {
544 if (isCharArrayString()){
545 T x;
546 std::stringstream sstr;
547 sstr << getCharArray();
548 sstr >> x;
549 return x;
550 }
551 else
552 return caster.get<T>(); //caster.get<T>(ptr);
553 }
554
555 template <class T, size_t N>
556 operator UniTuple<T,N>() const {
557 UniTuple<T,N> result;
558 result.assignSequence(*this, true);
559 }
560
561
562 inline
563 bool operator==(const Castable &c) const {
564 // std::cerr << __FILE__ << __LINE__ << __FUNCTION__ << std::endl;
565 //throw std::runtime_error("Castable: operator== not implemented.");
566
567 if (!this->typeIsSet()){
568 return !c.typeIsSet(); // is "same"... (?)
569 }
570
571 if (!c.typeIsSet()){
572 return false; // could return false for both?
573 }
574
575 if (this->isString() || c.isString()){ // NOTE: precision loss in rounding numbers
576 return (this->toStr() == c.toStr());
577 }
578
579 if (this->getElementCount() != c.getElementCount()){
580 return false;
581 }
582
583
584 for (size_t i = 0; i<this->getElementCount(); ++i){
585 if (! caster.compare(getPtr(i), c.caster, c.getPtr(i))){
586 return false;
587 }
588 }
589
590 return true;
591 }
592
594 inline
595 bool operator==(const char * s) const {
596 if (isCharArrayString()) // 2021
597 return (strcmp(getCharArray(), s) == 0);
598 else {
599 // Note: caster.get<std::string>() returns only the first element!
600 // std::cerr << __FILE__ << __LINE__ << __FUNCTION__ << toStr() << " vs " << caster.get<std::string>() << std::endl;
601 return (toStr() == s);
602 }
603 //return (caster.get<std::string>() == s);
604 }
605
607
612 inline
613 bool operator==(const nullptr_t ptr) const {
614 return getType() == typeid(void);
615 }
616
617 /*
618 inline // 2024
619 bool operator==(const std::string & s) const {
620 return (caster.get<std::string>() == s);
621 }
622 */
623
625 template <class T>
626 bool operator==(const T &x) const {
627 if (isCharArrayString()){ // 2024/04
628 std::stringstream sstr(getCharArray());
629 T c;
630 sstr >> c;
631 return (c == x);
632 }
633 else {
634 return (caster.get<T>() == x);
635 }
636 }
637
638 template <class T, size_t N>
639 bool operator==(const UniTuple<T,N> & x) const {
640 if (isString()){ // 2024/04
641 // std::cerr << __FILE__ << ':' << __FUNCTION__ << " '" << this->toStr() << "' == '" << x.toStr(',') << "'" << std::endl;
642 return (this->toStr() == x.toStr(',')); // consider separator, but this->outputSeparator is null for char array str...
643 }
644 else if (elementCount == N){
645 for (size_t i=0; i<N; ++i){
646 if (x[i] != this->get<T>(i)){
647 return false;
648 }
649 }
650 return true;
651 }
652 else {
653 return false;
654 }
655
656 }
657
658
659
661
664 template <class T>
665 bool operator!=(const T &x) const {
666 return ! this->operator==(x);
667 }
668
669 bool operator!=(const char *x) const {
670 return ! this->operator==(x);
671 }
672
673
675 // strings?
676 template <class T>
677 bool operator<(const T &x) const {
678 return (caster.get<T>() < x);
679 }
680
682 template <class T>
683 bool operator>(const T &x) const {
684 return (caster.get<T>() > x);
685 }
686
688 // strings?
689 template <class T>
690 bool operator<=(const T &x) const {
691 return (caster.get<T>() <= x);
692 }
693
695 template <class T>
696 bool operator>=(const T &x) const {
697 return (caster.get<T>() >= x);
698 }
699
701
704 inline
705 Castable & setSeparator(char c = ','){
708 return *this;
709 }
710
712
716 inline
717 void setInputSeparator(char c = ','){
718 inputSeparator = c;
719 }
720
722
726 inline
727 void setOutputSeparator(char c = ','){
728 outputSeparator = c;
729 }
730
732
736 inline
738 return inputSeparator;
739 }
740
742
746 inline
748 return outputSeparator;
749 }
750
751
752 std::ostream & toStream(std::ostream & ostr = std::cout, char separator='\0') const;
753
754 std::istream & fromStream(std::istream & istr);
755
756
757 std::string toStr() const;
758
760 void typeInfo(std::ostream & ostr) const;
761
763 // Writes a bit longer type indentifier and size in bytes, for example "unsigned int(8) for char and "signed int(16) for signed short int."
764 virtual
765 void info(std::ostream & ostr = std::cout) const;
766
767 // void debug(std::ostream & ostr = std::cout) const;
768
769
770
772
777 template <class T>
778 void toSequence(T & container, char separator = 0) const { // FIX raise
779
780 container.clear();
781
782 if (isString()){
783 if (!separator)
784 separator = this->outputSeparator;
785 StringTools::split(toStr(), container, separator," \t\n");
786 }
787 else {
788 for (size_t i = 0; i < getElementCount(); ++i) {
790 container.insert(container.end(), caster.get<typename T::value_type>(getPtr(i)) );
791 }
792 }
793
794
795 }
796
797
798
799 template <class T>
800 void toMap(T & map, char separator = 0, char equalSign = '=') const {
801
802 map.clear();
803
804 if (isString()){
805 // This part could be in StringTools?
806 typedef std::list<std::string> entryList;
807 entryList entries;
808 toSequence(entries, separator);
809
810 for (entryList::const_iterator it = entries.begin(); it!=entries.end(); ++it){
811 //typename T::value_type entry;
812 typename T::key_type key;
813 typename T::mapped_type data;
814 drain::StringTools::split2(*it, key, data, std::string(1, equalSign)); // TRIM?
815 map[key] = data;
816 }
817 }
818 else {
819 for (size_t i = 0; i < getElementCount(); ++i){
820 //typename T::value_type entry;
821 typename T::key_type key;
822 typename T::mapped_type data;
823 std::stringstream sstr;
824 sstr << i;
825 sstr >> key; // entry.first;
826 std::stringstream sstr2;
827 //sstr2 << caster.get<typename T::value_type>(getPtr(i)); // weirds
828 sstr2 << caster.get<typename T::mapped_type>(getPtr(i)); // weirds
829 sstr2 >> data;
830 map[key] = data;
831 }
832 }
833
834
835 }
836
837
839
842 inline
843 char * getPtr(size_t i = 0) {
844 return &((char *)caster.ptr)[i*caster.getElementSize()];
845 }
846
847 inline
848 const char * getPtr(size_t i = 0) const {
849 return &((const char *)caster.ptr)[i*caster.getElementSize()];
850 }
851
852
854 void copyFormat(const Castable & c){
855 this->elementCount = c.elementCount;
858 this->fillArray = c.fillArray;
859 }
860
861
862 virtual inline
863 bool requestType(const std::type_info & t){
864 return (getType() == t);
865 }
866
868
871 virtual inline
872 bool suggestType(const std::type_info & t){
873 return (getType() == t);
874 }
875
877 bool fillArray = false;
878
879protected:
880
881 virtual
882 void updateSize(size_t elems){
883 elementCount = elems;
884 }
885
886protected:
887
888 Caster caster;
889
890
891
893 template <class F>
894 inline // FINAL
895 void setType(){
897 setType(typeid(F));
898 }
899
901 virtual inline // virtual? Variable may need
902 void setType(const std::type_info &t){
903 setSeparator(','); // ?
904 caster.setType(t);
905 //elementCount = 1; ?
906 }
907
909
912 virtual inline
914 return (getElementCount() == elementCount);
915 }
916
917
919 template <class F>
920 inline
921 void setPtr(void *p){
922 caster.link(p);
923 elementCount = 1;
924 }
925
926
928 template <class F>
929 void setPtr(F &p){
930 if ((!std::is_arithmetic<F>::value) && (typeid(F)!=typeid(std::string))){
931 throw std::runtime_error(std::string(__FUNCTION__) + ": unsupported type: " + typeid(F).name());
932 }
933 caster.link(p); // could use setPtr(void *p, const std::type_info &t) ?
934 elementCount = 1;
935 }
936
938 /*
939 * Function of this kind must be available for general (8bit) memory allocators.
940 */
941 inline
942 void setPtr(void *p, const std::type_info &t, size_t count=1){
943 //if (t == typeid(void))
944 // throw std::runtime_error(std::string(__FUNCTION__) + ": explicit void type given");
945 caster.link(p, t);
946 elementCount = count;
947 }
948
950
953 /*
954 template <class F>
955 // void setPtr(std::pair<F,F> &p){
956 setPtr(&p, typeid(F), 2);
957 //caster.link((F*)&v);
958 fillArray = true; // if a scalar is assigned, assign to both elements
959 //elementCount = 2;
960 }
961 */
962
964
967 template <class F, size_t N>
968 void setPtr(UniTuple<F,N> & tuple){
969 setPtr(tuple.begin(), typeid(F), N);
970 fillArray = true; // (?) if a scalar is assigned, assign to all elements
971 }
972
973
974
975
977 void relink(Castable & c);
978
979
980 /*
981 inline
982 void setPtr(const Castable &c){
983 //caster.link0((const Caster &)c);
984
985 caster.ptr = c.caster.ptr;
986 caster.setType(c.getType());
987
988 elementCount = c.elementCount; // TODO
989 outputSeparator = c.outputSeparator; // ?
990 }
991
993 inline
994 void setPtr(Castable &c){
995 caster.link0((Caster &)c);
996 // caster.ptr = c.caster.ptr;
997 // caster.setType(c.getType());
998 elementCount = c.elementCount; // TODO
999 outputSeparator = c.outputSeparator; // ?
1000 }
1001 */
1002
1004 // IMPORTANT!
1005 inline
1006 void castElement(size_t i, const Caster &c, void *p) const {
1007 c.translate(caster, getPtr(i), p);
1008 }
1009
1010
1011 // Destination type (current type) specific assign operations
1012
1013
1014
1016
1021 template <class T>
1022 void appendToString(const T & x){
1023
1024 std::stringstream sstr;
1025
1026 // drain::Sprinter::toStream(sstr, *this, drain::Sprinter::plainLayout);
1027 toStream(sstr);
1028
1029 if (inputSeparator && (getElementCount()>1)){
1030 sstr << inputSeparator;
1031 }
1032 sstr << x;
1033
1034 std::string s = sstr.str();
1035
1036 suggestType(typeid(std::string));
1037
1038 if (isStlString()){
1039 caster.put(s);
1040 //caster.put(ptr, s);
1041 }
1042 else if (isCharArrayString()){
1043 assignToCharArray(s);
1044 }
1045 else {
1046 throw std::runtime_error(std::string(__FUNCTION__) + ": type is not a string: " + typeid(T).name());
1047 }
1048 }
1049
1050
1051 template <class T>
1052 void assignToString(const T & x){
1053
1054 /*
1055 if (x == nullptr){
1056 //suggestType(typeid(void));
1057 suggestType(typeid(void));
1058 //experimental
1059 return;
1060 }
1061 */
1062
1063 suggestType(typeid(std::string));
1064
1065 if (isStlString()){
1066 caster.put(x);
1067 //caster.put(ptr, x);
1068 }
1069 else if (isCharArrayString()){
1070 requestSize(0); // works only for Variable, ok
1071 clear(); // works always (but if elementCount)
1072 appendToString(x);
1073 }
1074 else {
1075 throw std::runtime_error(std::string(__FUNCTION__) + ": type is std::string");
1076 }
1077 }
1078
1079 void assignToCharArray(const std::string & s);
1080
1081 inline
1082 void assignToCharArray(const char *s){
1083 assignToCharArray(std::string(s));
1084 }
1085
1087
1090 template <class T>
1091 void assignToCharArray(const T & s){
1092 std::stringstream sstr;
1093 sstr << s;
1094 assignToCharArray(sstr.str());
1095 }
1096
1097
1098 inline
1099 void appendToElementArray(const char *s){
1100 appendToElementArray(std::string(s));
1101 }
1102
1103 template <class T>
1104 void appendToElementArray(const T & s){
1105
1106 suggestType(typeid(T)); // check return code?
1107 if (!typeIsSet()){
1108 throw std::runtime_error(std::string(__FUNCTION__) + ": type is unset");
1109 return;
1110 }
1111
1112 // Check if now type==string...
1113 if (isString()){
1114 throw std::runtime_error(std::string(__FUNCTION__) + ": type is std::string (not implemented yet)");
1115 //return;
1116 }
1117
1118 // Extend array.
1120 if (empty()){
1121 throw std::runtime_error(std::string(__FUNCTION__) + ": still empty after resize request(+1)");
1122 return;
1123 }
1124
1125 // TODO: what if non-empty but fixed?
1126
1127 caster.put(getPtr(getElementCount()-1), s);
1128
1129 }
1130
1131
1132
1133public:
1134 /* public NEW 2021 (experimental)
1135 *
1136 * useful in "stream" definitions:
1137 * drain::Referencer(range.tuple()).setSeparator(':').setFill().assignString(ftor);
1138 *
1139 */
1140
1141
1143
1144 void assignString(const std::string &s);
1145
1146 // NEW 2024
1147 template <class T, size_t N>
1148 inline
1149 void assign(const UniTuple<T,N> & tuple){
1150 assignContainer(tuple);
1151 }
1152
1154 template <class T>
1155 void assignContainer(const T & v, bool append=false) {
1156
1157 if (!append){
1158 if (isStlString())
1159 clear();
1160 else
1161 requestSize(0);
1162 }
1163
1164 suggestType(typeid(typename T::value_type));
1165 // Note: sequence of strings, will request string type...
1166
1167 if (isString()){
1168 std::stringstream sstr;
1169 if (append){
1171 //toStream(sstr); // outputsepp?
1172 if (inputSeparator)
1173 sstr << inputSeparator;
1174 }
1175 StringTools::join(v, sstr, inputSeparator); // implement!
1176 assignToString(sstr.str());
1177 }
1178 else if (caster.typeIsSet()){
1179
1180 if (append){
1181 for (typename T::const_iterator it = v.begin(); it != v.end(); ++it){
1182 appendToElementArray(*it);
1183 }
1184 }
1185 else {
1186 requestSize(v.size());
1187 typename T::const_iterator it = v.begin();
1188 typename T::const_iterator itLast = it;
1189 for (size_t i = 0; i<getElementCount(); ++i){
1190 if (it == v.end()){
1191 if (fillArray)
1192 it = itLast; //v.begin(); WHAT if empty?
1193 else
1194 return;
1195 }
1196 else {
1197 itLast = it;
1198 }
1199 caster.put(getPtr(i), *it);
1200 ++it;
1201 }
1202 }
1203 }
1204 else {
1205 throw std::runtime_error(std::string(__FILE__) + ": type unset, cannot assign");
1206 }
1207
1208 }
1209
1210
1212
1215 /* OLD
1216 inline
1217 const char * getCharArray() const {
1218
1219 if (!isCharArrayString())
1220 throw std::runtime_error("getCharArray: type not char array...");
1221
1222 if (empty()){
1223 static const char * empty = "";
1224 return empty;
1225 // throw std::runtime_error("getCharArray: empty array, no even null char");
1226 }
1227
1228 if (*getPtr(getElementCount()-1) != '\0')
1229 throw std::runtime_error("getCharArray: no terminating null char");
1230
1231 return getPtr();
1232
1233 }
1234 */
1235
1237
1243 // NEW
1244
1245public:
1246
1247 const char * getCharArray() const;
1248
1249protected:
1250
1252 // void *ptr;
1253
1256
1259
1262
1263
1264};
1265
1266
1267
1269template <>
1270std::ostream & Sprinter::toStream(std::ostream & ostr, const drain::Castable & x, const SprinterLayout & layout);
1271
1272
1273
1274inline
1275std::ostream & operator<<(std::ostream &ostr, const Castable &c){
1276 return c.toStream(ostr);
1277 //return Sprinter::toStream(ostr, c, Sprinter::plainLayout);
1278}
1279
1280/* UNDER CONSTR..
1281inline
1282std::istream & operator>>(std::istream & istr, Castable &c){
1283 return c.fromStream(istr);
1284}
1285*/
1286
1288template <class T>
1289inline
1290T & operator+=(T & x, const Castable &c){
1291 x += c.get<T>(0);
1292 return x;
1293}
1294
1296template <class T>
1297inline
1298T & operator-=(T & x, const Castable &c){
1299 x -= c.get<T>(0);
1300 return x;
1301}
1302
1304template <class T>
1305inline
1306T & operator*=(T & x, const Castable &c){
1307 x *= c.get<T>(0);
1308 return x;
1309}
1310
1312template <class T>
1313inline
1314T & operator/=(T & x, const Castable &c){
1315 x /= c.get<T>(0);
1316 return x;
1317}
1318
1319
1320
1321template <>
1322const std::string TypeName<Castable>::name;
1323
1324/*
1325template <class T, size_t N=2>
1326template <class T2>
1327UniTuple<T,N> & UniTuple<T,N>::set(const Castable & t){
1328 // assignSequence(t, true); // by default LENIENT, or how should it be?
1329 return *this;
1330}
1331*/
1332
1333
1334} // namespace drain
1335
1336
1337#endif
1338
1339// Drain
Definition Castable.h:76
void pop_back()
Tries to remove the last element.
Definition Castable.h:496
void setPtr(UniTuple< F, N > &tuple)
Stores the pair as an array of two elements.
Definition Castable.h:968
void setPtr(void *p, const std::type_info &t, size_t count=1)
Sets the data pointer and its explicit type.
Definition Castable.h:942
void append(const std::set< T > &s)
Appends elements of a set.
Definition Castable.h:444
bool isCharArrayString() const
Returns true, if type is C char array and outputSepator is the null char.
Definition Castable.h:171
virtual bool isLinking() const
Return true, if the referenced variable is external. Inherited classes - like Variable - may have int...
Definition Castable.h:153
Castable & setFill(bool fill=true)
Set or unset filling (padding) an array if input set is smaller.
Definition Castable.h:231
void append(const std::list< T > &l)
Appends elements of std::list.
Definition Castable.h:430
size_t size() const
Alias, to comply with STL containers.
Definition Castable.h:223
bool operator==(const nullptr_t ptr) const
Experimental. Notice that if type is set, false is returned also for an empty array.
Definition Castable.h:613
void copyFormat(const Castable &c)
Copies array layout and formatting: separators, element count, fillArray flag.
Definition Castable.h:854
void assignString(const std::string &s)
Input type specific assign operations.
Definition Castable.cpp:365
bool operator<(const T &x) const
Compares a value to inner data.
Definition Castable.h:677
Castable(const Castable &c)
Copy constructor: copies the layout and the pointer to the target.
Definition Castable.h:89
bool operator<=(const T &x) const
Compares a value to inner data.
Definition Castable.h:690
void typeInfo(std::ostream &ostr) const
Writes a string of type indentifier char and size in bytes, for example [C@8] for unsigned char and [...
Definition Castable.cpp:220
virtual size_t getElementCount() const
Returns the length of the array, the number of elements in this entry.
Definition Castable.h:196
virtual void info(std::ostream &ostr=std::cout) const
Print value, type and element count.
Definition Castable.cpp:233
virtual bool suggestType(const std::type_info &t)
Request to change in type. For Castable, simply returns true if the current type was requested.
Definition Castable.h:872
void assign(const std::vector< T > &v)
Copies elements of a vector.
Definition Castable.h:378
void append(const char *s)
Appends the string or appends the array by one element.
Definition Castable.h:423
bool isValid() const
Return true, if the pointer is set.
Definition Castable.h:146
char getOutputSeparator()
Definition Castable.h:747
virtual size_t getSize() const final
Returns the size in bytes of the target: (elementCount * elementSize)
Definition Castable.h:217
Castable & operator=(const char *c)
Definition Castable.h:277
bool empty() const
Returns true, if string is empty or array size is zero. (In future, semantics may change: 0 for scala...
Definition Castable.cpp:36
void assign(const std::list< T > &l)
Copies elements of a list.
Definition Castable.h:371
virtual bool isVariable() const
Returns true, if the class contains an own data array.
Definition Castable.h:165
void setPtr(F &p)
Stores the pointer and its storage type F.
Definition Castable.h:929
char * getPtr(size_t i=0)
Returns pointer to the array of chars without validity check.
Definition Castable.h:843
size_t elementCount
Pointer to the data variable.
Definition Castable.h:1255
bool isStlString() const
Returns true, if type is std::string .
Definition Castable.h:177
std::string getTypeName() const
Returns the name of the current storage type.
Definition Castable.h:254
void assignToCharArray(const T &s)
Input anything to char array string.
Definition Castable.h:1091
void assignContainer(const T &v, bool append=false)
Assigns a STL Sequence, element by element.
Definition Castable.h:1155
char getInputSeparator()
Definition Castable.h:737
virtual const std::type_info & getType() const
Return the storage type (base type) of the referenced variable.
Definition Castable.h:135
void appendToString(const T &x)
Append to std::string or char array.
Definition Castable.h:1022
void assign(const T &x)
Copies an arbitrary base type or std::string value.
Definition Castable.h:334
Castable & assignCastable(const Castable &c)
Copy data from Castable. Perhaps copy size and type, too.
Definition Castable.cpp:256
size_t getElementSize() const
Return the size of the current storage type, in bytes.
Definition Castable.h:207
void assign(const std::set< T > &s)
Copies elements of a set.
Definition Castable.h:386
bool operator==(const char *s) const
Compare as a character string.
Definition Castable.h:595
bool fillArray
If array, assigning a scalar will fill up the current array.
Definition Castable.h:877
Castable & operator=(const Castable &c)
Copies the value referred to by Castable. Notice that if type is unset (void), no operation is perfor...
Definition Castable.h:294
void toSequence(T &container, char separator=0) const
Converts data to a STL Sequence, for example std::set, std::list or std::vector .
Definition Castable.h:778
bool operator>(const T &x) const
Compares a value with inner data.
Definition Castable.h:683
char outputSeparator
Element separator usein in writing and reading character strings (streams).
Definition Castable.h:1261
bool isString() const
Returns true, if type is C char array or std::string .
Definition Castable.h:183
void setPtr(void *p)
Stores the pointer and its storage type F. Assumes elementCount=1.
Definition Castable.h:921
const char * getCharArray() const
Returns pointer to the array of chars, checks validity first.
Definition Castable.cpp:93
void append(const std::vector< T > &v)
Appends elements of a vector.
Definition Castable.h:437
virtual void setType(const std::type_info &t)
Sets the storage type. If a target value is available, use setPtr() directly.
Definition Castable.h:902
char inputSeparator
Element separator usein in reading a char sequence to an (numeric) array.
Definition Castable.h:1258
void clear()
Clears strings, or for scalars and arrays, sets all the values to zero. Does not change type.
Definition Castable.cpp:81
bool operator==(const T &x) const
Compares a value to internal data.
Definition Castable.h:626
void setType()
Sets the storage type. If a target value is available, use setPtr() directly.
Definition Castable.h:895
void append(const T &x)
Appends the string or appends the array by one element.
Definition Castable.h:410
void reset()
Definition Castable.h:244
void relink(Castable &c)
Copies the link and element count.
Definition Castable.cpp:69
void castElement(size_t i, const Caster &c, void *p) const
Let Caster c convert my element #i to target *p.
Definition Castable.h:1006
void setOutputSeparator(char c=',')
Definition Castable.h:727
Castable & setSeparator(char c=',')
The character used between array elements in output stream.
Definition Castable.h:705
Castable(F &p)
Constructor for an object pointing to a variable.
Definition Castable.h:96
bool operator>=(const T &x) const
Compares a value with inner data.
Definition Castable.h:696
bool operator!=(const T &x) const
Compares a value to inner data.
Definition Castable.h:665
virtual bool requestSize(size_t elementCount)
Request to change the array size. For Castable (and Reference) does nothing and returns false.
Definition Castable.h:913
void setInputSeparator(char c=',')
Definition Castable.h:717
void assign(std::initializer_list< T > l)
Copies elements of a list.
Definition Castable.h:364
Definition Caster.h:67
T get(const void *p) const
Default implementation throws an error. See specialized implementation below.
Definition Caster.h:194
void unsetType()
calls void setType<void>().
Definition Caster.cpp:134
const std::type_info & getType() const
Returns type_info of the current type.
Definition Caster.h:144
size_t getElementSize() const
Returns the size of the base type (size of an element, not of element array).
Definition Caster.h:151
void setType(const std::type_info &t)
Calls setType<T>() for which typeid(T) = t.
Definition Caster.h:119
void translate(const Caster &c, const void *ptrC, void *ptr) const
Convert from str pointer and Caster.
Definition Caster.h:208
void * ptr
Future member: enables setting Caster type.
Definition Caster.h:247
void put(void *p, const T &x) const
Default conversion (for unconventional types). Uses std::stringstream for conversion.
Definition Caster.h:157
static std::ostream & toStream(std::ostream &ostr, const std::initializer_list< T > &x, const SprinterLayout &layout=defaultLayout)
New (experimental)
Definition Sprinter.h:420
static const SprinterLayout plainLayout
Display plain values, concatenating them with comma (except for strings).
Definition Sprinter.h:209
static bool split2(const std::string &s, T1 &first, T2 &second, const C &separators, const std::string &trimChars=" \t\n")
Splits and trims a given std::string to a std Sequence.
static std::ostream & join(const T &container, std::ostream &ostr, char separator=0)
Writes a STL Container (list, vector, set) to a stream, using an optional separator char (e....
Definition String.h:271
static void split(const std::string &s, T &sequence, const C &separators, const std::string &trimChars=" \t\n")
Splits and trims a given std::string to a std Sequence.
Definition String.h:380
tuplebase_t & assignSequence(T &sequence, bool LENIENT=false)
Proposed for tuples only; derived classes should not shadow this.
Definition TupleBase.h:287
Tuple of N elements of type T.
Definition UniTuple.h:65
Definition DataSelector.cpp:1277
T & operator-=(T &x, const Castable &c)
Arithmetics: subtraction.
Definition Castable.h:1298
T & operator*=(T &x, const Castable &c)
Arithmetics: addition.
Definition Castable.h:1306
T & operator/=(T &x, const Castable &c)
Arithmetics: subtraction.
Definition Castable.h:1314
T & operator+=(T &x, const Castable &c)
Arithmetics: addition.
Definition Castable.h:1290
Definition Sprinter.h:137
static const std::string name
Default implementation: name returned by std::type_info::name()
Definition Type.h:558