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 "StringTools.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 inline
331 void assign(std::nullptr_t){
332 reset();
333 }
334
336
339 template <class T>
340 void assign(const T &x){
341 // std::cout << "assign " << x << " -> " << Type::getTypeChar(getType()) << ',' << getElementCount() << std::endl;
342 suggestType(typeid(T));
343 if (isString()){
344 //std::cout << __FUNCTION__ << ':' << x << " -> " << Type::getTypeChar(getType()) << ',' << getElementCount() << '\n';
345 assignToString(x);
346 }
347 else if (typeIsSet()){
348 if (fillArray){
349 for (size_t i = 0; i<getElementCount(); ++i){
350 caster.put(getPtr(i), x);
351 }
352 }
353 else {
354 requestSize(1);
355 caster.put(x);
356 }
357 }
358 else {
359 std::cerr << __FILE__ << ':' << __FUNCTION__ << ": arg type:" << typeid(T).name() << '\n';
360 throw std::runtime_error(std::string(__FUNCTION__) + ": type is unset");
361 }
362
363
364 }
365
366
367
369 template<typename T>
370 void assign(std::initializer_list<T> l){
372 }
373
375 template <class T>
376 inline
377 void assign(const std::list<T> & l){
379 }
380
382 template <class T>
383 inline
384 void assign(const std::vector<T> & v){
386 }
387
389 template <class T>
390 inline
391 // Castable &operator=(const std::set<T> & s){
392 void assign(const std::set<T> & s){
394 //return *this;
395 }
396
397
399 Castable & assignCastable(const Castable &c);
400
401
402 template <class T>
403 inline
404 Castable &operator<<(const T &x){
405 append(x);
406 return *this;
407 }
408
409
411 /*
412 * Note: if both source and target are strings, does not split it like with Variable::operator=(const char *).
413 */
414 template <class T>
415 inline
416 void append(const T &x){
417 suggestType(typeid(T)); // must be here, esp. if string suggested
418 if (isString()){
420 }
421 else {
422 // suggestType will be repeated
423 appendToElementArray(x);
424 }
425 }
426
428 inline
429 void append(const char *s){
430 append(std::string(s));
431 }
432
434 template <class T>
435 inline
436 void append(const std::list<T> & l){
437 assignContainer(l, true);
438 }
439
441 template <class T>
442 inline
443 void append(const std::vector<T> & v){
444 assignContainer(v, true);
445 }
446
448 template <class T>
449 inline
450 void append(const std::set<T> & s){
451 assignContainer(s, true);
452 }
453
454 // NEW 2025
455 inline // protected
456 void append(){
457 }
458
459 template <class T, class ...TT>
460 void append(const T &arg, const TT& ...args){
461 append(arg);
462 append(args...);
463 }
464
465
466 template <class T>
467 inline
468 T get(size_t i) const {
469 if (i >= elementCount){
470 std::cerr << __FILE__ << " index=" << i << ", contents: '";
471 this->toStream(std::cerr);
472 std::cerr << "'\n";
473 throw std::runtime_error("Castable::get() index overflow");
474 }
475 return caster.get<T>(getPtr(i));
476 }
477
478
479 template <class T>
480 inline
481 T front() const {
482 if (empty()){
483 throw std::runtime_error("Castable::front() called on empty variable");
484 }
485 return caster.get<T>(getPtr(0));
486 }
487
488 template <class T>
489 inline
490 T back() const {
491 if (empty()){
492 throw std::runtime_error("Castable::back() called on empty variable");
493 }
494 return caster.get<T>(getPtr(elementCount - 1));
495 }
496
498
501 inline
502 void pop_back() { // consider move to Variable (but Flexible needs this anyway.
503 if (empty()){
504 throw std::runtime_error("Castable::front() called on empty variable");
505 }
506 if (!isVariable()){
507 throw std::runtime_error("Castable::pop_back() called on a referencing variable");
508 }
510 }
511
512
513 /*
514 template <class T>
515 inline
516 void setElem(size_t i) const {
517 if (i >= elementCount)
518 throw std::runtime_error("Castable::get() index overflow");
519 return caster.get<T>(getPtr(i));
520 }
521 */
522
523
525
528 inline
529 operator std::string() const {
530 return toStr();
531 }
532
535 // Thanks to Mikael Kilpeläinen.
548 template <class T>
549 operator T() const {
550 if (isCharArrayString()){
551 T x;
552 std::stringstream sstr;
553 sstr << getCharArray();
554 sstr >> x;
555 return x;
556 }
557 else
558 return caster.get<T>(); //caster.get<T>(ptr);
559 }
560
561 template <class T, size_t N>
562 operator UniTuple<T,N>() const {
563 UniTuple<T,N> result;
564 result.assignSequence(*this, true);
565 }
566
567
568 inline
569 bool operator==(const Castable &c) const {
570 // std::cerr << __FILE__ << __LINE__ << __FUNCTION__ << std::endl;
571 //throw std::runtime_error("Castable: operator== not implemented.");
572
573 if (!this->typeIsSet()){
574 return !c.typeIsSet(); // is "same"... (?)
575 }
576
577 if (!c.typeIsSet()){
578 return false; // could return false for both?
579 }
580
581 if (this->isString() || c.isString()){ // NOTE: precision loss in rounding numbers
582 return (this->toStr() == c.toStr());
583 }
584
585 if (this->getElementCount() != c.getElementCount()){
586 return false;
587 }
588
589
590 for (size_t i = 0; i<this->getElementCount(); ++i){
591 if (! caster.compare(getPtr(i), c.caster, c.getPtr(i))){
592 return false;
593 }
594 }
595
596 return true;
597 }
598
600 inline
601 bool operator==(const char * s) const {
602 if (isCharArrayString()) // 2021
603 return (strcmp(getCharArray(), s) == 0);
604 else {
605 // Note: caster.get<std::string>() returns only the first element!
606 // std::cerr << __FILE__ << __LINE__ << __FUNCTION__ << toStr() << " vs " << caster.get<std::string>() << std::endl;
607 return (toStr() == s);
608 }
609 //return (caster.get<std::string>() == s);
610 }
611
613
618 inline
619 bool operator==(const std::nullptr_t ptr) const {
620 return getType() == typeid(void);
621 }
622
623 /*
624 inline // 2024
625 bool operator==(const std::string & s) const {
626 return (caster.get<std::string>() == s);
627 }
628 */
629
631 template <class T>
632 bool operator==(const T &x) const {
633 if (isCharArrayString()){ // 2024/04
634 std::stringstream sstr(getCharArray());
635 T c;
636 sstr >> c;
637 return (c == x);
638 }
639 else {
640 return (caster.get<T>() == x);
641 }
642 }
643
644 template <class T, size_t N>
645 bool operator==(const UniTuple<T,N> & x) const {
646 if (isString()){ // 2024/04
647 // std::cerr << __FILE__ << ':' << __FUNCTION__ << " '" << this->toStr() << "' == '" << x.toStr(',') << "'" << std::endl;
648 return (this->toStr() == x.toStr(',')); // consider separator, but this->outputSeparator is null for char array str...
649 }
650 else if (elementCount == N){
651 for (size_t i=0; i<N; ++i){
652 if (x[i] != this->get<T>(i)){
653 return false;
654 }
655 }
656 return true;
657 }
658 else {
659 return false;
660 }
661
662 }
663
664
665
667
670 template <class T>
671 bool operator!=(const T &x) const {
672 return ! this->operator==(x);
673 }
674
675 bool operator!=(const char *x) const {
676 return ! this->operator==(x);
677 }
678
679
681 // strings?
682 template <class T>
683 bool operator<(const T &x) const {
684 return (caster.get<T>() < x);
685 }
686
688 template <class T>
689 bool operator>(const T &x) const {
690 return (caster.get<T>() > x);
691 }
692
694 // strings?
695 template <class T>
696 bool operator<=(const T &x) const {
697 return (caster.get<T>() <= x);
698 }
699
701 template <class T>
702 bool operator>=(const T &x) const {
703 return (caster.get<T>() >= x);
704 }
705
707
710 inline
711 Castable & setSeparator(char c = ','){
714 return *this;
715 }
716
718
722 inline
723 void setInputSeparator(char c = ','){
724 inputSeparator = c;
725 }
726
728
732 inline
733 void setOutputSeparator(char c = ','){
734 outputSeparator = c;
735 }
736
738
742 inline
743 char getInputSeparator() const {
744 return inputSeparator;
745 }
746
748
752 inline
753 char getOutputSeparator() const {
754 return outputSeparator;
755 }
756
757
758 std::ostream & toStream(std::ostream & ostr = std::cout, char separator='\0') const;
759
760 std::istream & fromStream(std::istream & istr);
761
762
763 std::string toStr() const;
764
766 void typeInfo(std::ostream & ostr) const;
767
769 // 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."
770 virtual
771 void info(std::ostream & ostr = std::cout) const;
772
773 // void debug(std::ostream & ostr = std::cout) const;
774
775
776
778
783 template <class T>
784 void toSequence(T & container, char separator = 0) const { // FIX raise
785
786 container.clear();
787
788 if (isString()){
789 if (!separator)
790 separator = this->outputSeparator;
791 StringTools::split(toStr(), container, separator," \t\n");
792 }
793 else {
794 for (size_t i = 0; i < getElementCount(); ++i) {
796 container.insert(container.end(), caster.get<typename T::value_type>(getPtr(i)) );
797 }
798 }
799
800
801 }
802
803
804
805 template <class T>
806 void toMap(T & map, char separator = 0, char equalSign = '=') const {
807
808 map.clear();
809
810 if (isString()){
811 // This part could be in StringTools?
812 typedef std::list<std::string> entryList;
813 entryList entries;
814 toSequence(entries, separator);
815
816 for (entryList::const_iterator it = entries.begin(); it!=entries.end(); ++it){
817 //typename T::value_type entry;
818 typename T::key_type key;
819 typename T::mapped_type data;
820 drain::StringTools::split2(*it, key, data, std::string(1, equalSign)); // TRIM?
821 map[key] = data;
822 }
823 }
824 else {
825 for (size_t i = 0; i < getElementCount(); ++i){
826 //typename T::value_type entry;
827 typename T::key_type key;
828 typename T::mapped_type data;
829 std::stringstream sstr;
830 sstr << i;
831 sstr >> key; // entry.first;
832 std::stringstream sstr2;
833 //sstr2 << caster.get<typename T::value_type>(getPtr(i)); // weirds
834 sstr2 << caster.get<typename T::mapped_type>(getPtr(i)); // weirds
835 sstr2 >> data;
836 map[key] = data;
837 }
838 }
839
840
841 }
842
843
845
848 inline
849 char * getPtr(size_t i = 0) {
850 return &((char *)caster.ptr)[i*caster.getElementSize()];
851 }
852
853 inline
854 const char * getPtr(size_t i = 0) const {
855 return &((const char *)caster.ptr)[i*caster.getElementSize()];
856 }
857
858
860 void copyFormat(const Castable & c){
861 this->elementCount = c.elementCount;
864 this->fillArray = c.fillArray;
865 }
866
867
868 virtual inline
869 bool requestType(const std::type_info & t){
870 return (getType() == t);
871 }
872
874
877 virtual inline
878 bool suggestType(const std::type_info & t){
879 return (getType() == t);
880 }
881
883 bool fillArray = false;
884
885protected:
886
887 virtual
888 void updateSize(size_t elems){
889 elementCount = elems;
890 }
891
892protected:
893
894 Caster caster;
895
896
897
899 template <class F>
900 inline // FINAL
901 void setType(){
903 setType(typeid(F));
904 }
905
907 virtual inline // virtual? Variable may need
908 void setType(const std::type_info &t){
909 setSeparator(','); // ?
910 caster.setType(t);
911 //elementCount = 1; ?
912 }
913
915
918 virtual inline
920 return (getElementCount() == elementCount);
921 }
922
923
925 template <class F>
926 inline
927 void setPtr(void *p){
928 caster.link(p);
929 elementCount = 1;
930 }
931
932
934 template <class F>
935 void setPtr(F &p){
936 if ((!std::is_arithmetic<F>::value) && (typeid(F)!=typeid(std::string))){
937 throw std::runtime_error(std::string(__FUNCTION__) + ": unsupported type: " + typeid(F).name());
938 }
939 caster.link(p); // could use setPtr(void *p, const std::type_info &t) ?
940 elementCount = 1;
941 }
942
944 /*
945 * Function of this kind must be available for general (8bit) memory allocators.
946 */
947 inline
948 void setPtr(void *p, const std::type_info &t, size_t count=1){
949 //if (t == typeid(void))
950 // throw std::runtime_error(std::string(__FUNCTION__) + ": explicit void type given");
951 caster.link(p, t);
952 elementCount = count;
953 }
954
956
959 /*
960 template <class F>
961 // void setPtr(std::pair<F,F> &p){
962 setPtr(&p, typeid(F), 2);
963 //caster.link((F*)&v);
964 fillArray = true; // if a scalar is assigned, assign to both elements
965 //elementCount = 2;
966 }
967 */
968
970
973 template <class F, size_t N>
974 void setPtr(UniTuple<F,N> & tuple){
975 setPtr(tuple.begin(), typeid(F), N);
976 fillArray = true; // (?) if a scalar is assigned, assign to all elements
977 }
978
979
980
981
983 void relink(Castable & c);
984
986 void relink(const Castable & c);
987
988
989 /*
990 inline
991 void setPtr(const Castable &c){
992 //caster.link0((const Caster &)c);
993
994 caster.ptr = c.caster.ptr;
995 caster.setType(c.getType());
996
997 elementCount = c.elementCount; // TODO
998 outputSeparator = c.outputSeparator; // ?
999 }
1000
1002 inline
1003 void setPtr(Castable &c){
1004 caster.link0((Caster &)c);
1005 // caster.ptr = c.caster.ptr;
1006 // caster.setType(c.getType());
1007 elementCount = c.elementCount; // TODO
1008 outputSeparator = c.outputSeparator; // ?
1009 }
1010 */
1011
1013 // IMPORTANT!
1014 inline
1015 void castElement(size_t i, const Caster &c, void *p) const {
1016 c.translate(caster, getPtr(i), p);
1017 }
1018
1019
1020 // Destination type (current type) specific assign operations
1021
1022
1023
1025
1030 template <class T>
1031 void appendToString(const T & x){
1032
1033 std::stringstream sstr;
1034
1035 // drain::Sprinter::toStream(sstr, *this, drain::Sprinter::plainLayout);
1036 toStream(sstr);
1037
1038 if (inputSeparator && (getElementCount()>1)){
1039 sstr << inputSeparator;
1040 }
1041 sstr << x;
1042
1043 std::string s = sstr.str();
1044
1045 suggestType(typeid(std::string));
1046
1047 if (isStlString()){
1048 caster.put(s);
1049 //caster.put(ptr, s);
1050 }
1051 else if (isCharArrayString()){
1052 assignToCharArray(s);
1053 }
1054 else {
1055 throw std::runtime_error(std::string(__FUNCTION__) + ": type is not a string: " + typeid(T).name());
1056 }
1057 }
1058
1059
1060 template <class T>
1061 void assignToString(const T & x){
1062
1063 /*
1064 if (x == nullptr){
1065 //suggestType(typeid(void));
1066 suggestType(typeid(void));
1067 //experimental
1068 return;
1069 }
1070 */
1071
1072 suggestType(typeid(std::string));
1073
1074 if (isStlString()){
1075 caster.put(x);
1076 //caster.put(ptr, x);
1077 }
1078 else if (isCharArrayString()){
1079 requestSize(0); // works only for Variable, ok
1080 clear(); // works always (but if elementCount)
1081 appendToString(x);
1082 }
1083 else {
1084 throw std::runtime_error(std::string(__FUNCTION__) + ": type is std::string");
1085 }
1086 }
1087
1088 void assignToCharArray(const std::string & s);
1089
1090 inline
1091 void assignToCharArray(const char *s){
1092 assignToCharArray(std::string(s));
1093 }
1094
1096
1099 template <class T>
1100 void assignToCharArray(const T & s){
1101 std::stringstream sstr;
1102 sstr << s;
1103 assignToCharArray(sstr.str());
1104 }
1105
1106
1107 inline
1108 void appendToElementArray(const char *s){
1109 appendToElementArray(std::string(s));
1110 }
1111
1112 template <class T>
1113 void appendToElementArray(const T & s){
1114
1115 suggestType(typeid(T)); // check return code?
1116 if (!typeIsSet()){
1117 throw std::runtime_error(std::string(__FUNCTION__) + ": type is unset");
1118 return;
1119 }
1120
1121 // Check if now type==string...
1122 if (isString()){
1123 throw std::runtime_error(std::string(__FUNCTION__) + ": type is std::string (not implemented yet)");
1124 //return;
1125 }
1126
1127 // Extend array.
1129 if (empty()){
1130 throw std::runtime_error(std::string(__FUNCTION__) + ": still empty after resize request(+1)");
1131 return;
1132 }
1133
1134 // TODO: what if non-empty but fixed?
1135
1136 caster.put(getPtr(getElementCount()-1), s);
1137
1138 }
1139
1140
1141
1142public:
1143 /* public NEW 2021 (experimental)
1144 *
1145 * useful in "stream" definitions:
1146 * drain::Referencer(range.tuple()).setSeparator(':').setFill().assignString(ftor);
1147 *
1148 */
1149
1150
1152
1153 void assignString(const std::string &s);
1154
1155 // NEW 2024
1156 template <class T, size_t N>
1157 inline
1158 void assign(const UniTuple<T,N> & tuple){
1159 assignContainer(tuple);
1160 }
1161
1163 template <class T>
1164 void assignContainer(const T & v, bool append=false) {
1165
1166 if (!append){
1167 if (isStlString())
1168 clear();
1169 else
1170 requestSize(0);
1171 }
1172
1173 suggestType(typeid(typename T::value_type));
1174 // Note: sequence of strings, will request string type...
1175
1176 if (isString()){
1177 std::stringstream sstr;
1178 if (append){
1180 //toStream(sstr); // outputsepp?
1181 if (inputSeparator)
1182 sstr << inputSeparator;
1183 }
1184 StringTools::join(v, sstr, inputSeparator); // implement!
1185 assignToString(sstr.str());
1186 }
1187 else if (caster.typeIsSet()){
1188
1189 if (append){
1190 for (typename T::const_iterator it = v.begin(); it != v.end(); ++it){
1191 appendToElementArray(*it);
1192 }
1193 }
1194 else {
1195 requestSize(v.size());
1196 typename T::const_iterator it = v.begin();
1197 typename T::const_iterator itLast = it;
1198 for (size_t i = 0; i<getElementCount(); ++i){
1199 if (it == v.end()){
1200 if (fillArray)
1201 it = itLast; //v.begin(); WHAT if empty?
1202 else
1203 return;
1204 }
1205 else {
1206 itLast = it;
1207 }
1208 caster.put(getPtr(i), *it);
1209 ++it;
1210 }
1211 }
1212 }
1213 else {
1214 throw std::runtime_error(std::string(__FILE__) + ": type unset, cannot assign");
1215 }
1216
1217 }
1218
1219
1221
1224 /* OLD
1225 inline
1226 const char * getCharArray() const {
1227
1228 if (!isCharArrayString())
1229 throw std::runtime_error("getCharArray: type not char array...");
1230
1231 if (empty()){
1232 static const char * empty = "";
1233 return empty;
1234 // throw std::runtime_error("getCharArray: empty array, no even null char");
1235 }
1236
1237 if (*getPtr(getElementCount()-1) != '\0')
1238 throw std::runtime_error("getCharArray: no terminating null char");
1239
1240 return getPtr();
1241
1242 }
1243 */
1244
1246
1252 // NEW
1253
1254public:
1255
1256 const char * getCharArray() const;
1257
1258protected:
1259
1261 // void *ptr;
1262
1265
1268
1271
1272
1273};
1274
1275
1276
1278template <>
1279std::ostream & Sprinter::toStream(std::ostream & ostr, const drain::Castable & x, const SprinterLayout & layout);
1280
1281
1282
1283inline
1284std::ostream & operator<<(std::ostream &ostr, const Castable &c){
1285 return c.toStream(ostr);
1286 //return Sprinter::toStream(ostr, c, Sprinter::plainLayout);
1287}
1288
1289/* UNDER CONSTR..
1290inline
1291std::istream & operator>>(std::istream & istr, Castable &c){
1292 return c.fromStream(istr);
1293}
1294*/
1295
1297template <class T>
1298inline
1299T & operator+=(T & x, const Castable &c){
1300 x += c.get<T>(0);
1301 return x;
1302}
1303
1305template <class T>
1306inline
1307T & operator-=(T & x, const Castable &c){
1308 x -= c.get<T>(0);
1309 return x;
1310}
1311
1313template <class T>
1314inline
1315T & operator*=(T & x, const Castable &c){
1316 x *= c.get<T>(0);
1317 return x;
1318}
1319
1321template <class T>
1322inline
1323T & operator/=(T & x, const Castable &c){
1324 x /= c.get<T>(0);
1325 return x;
1326}
1327
1328
1329DRAIN_TYPENAME(Castable);
1330// template <>
1331// const std::string TypeName<Castable>::name;
1332
1333/*
1334template <class T, size_t N=2>
1335template <class T2>
1336UniTuple<T,N> & UniTuple<T,N>::set(const Castable & t){
1337 // assignSequence(t, true); // by default LENIENT, or how should it be?
1338 return *this;
1339}
1340*/
1341
1342
1343} // namespace drain
1344
1345
1346#endif
1347
1348// Drain
Definition Castable.h:76
void pop_back()
Tries to remove the last element.
Definition Castable.h:502
void setPtr(UniTuple< F, N > &tuple)
Stores the pair as an array of two elements.
Definition Castable.h:974
void setPtr(void *p, const std::type_info &t, size_t count=1)
Sets the data pointer and its explicit type.
Definition Castable.h:948
void append(const std::set< T > &s)
Appends elements of a set.
Definition Castable.h:450
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:436
size_t size() const
Alias, to comply with STL containers.
Definition Castable.h:223
void copyFormat(const Castable &c)
Copies array layout and formatting: separators, element count, fillArray flag.
Definition Castable.h:860
void assignString(const std::string &s)
Input type specific assign operations.
Definition Castable.cpp:376
bool operator==(const std::nullptr_t ptr) const
Experimental. Notice that if type is set, false is returned also for an empty array.
Definition Castable.h:619
bool operator<(const T &x) const
Compares a value to inner data.
Definition Castable.h:683
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:696
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:231
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:244
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:878
void assign(const std::vector< T > &v)
Copies elements of a vector.
Definition Castable.h:384
void append(const char *s)
Appends the string or appends the array by one element.
Definition Castable.h:429
bool isValid() const
Return true, if the pointer is set.
Definition Castable.h:146
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
char getOutputSeparator() const
Definition Castable.h:753
void assign(const std::list< T > &l)
Copies elements of a list.
Definition Castable.h:377
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:935
char * getPtr(size_t i=0)
Returns pointer to the array of chars without validity check.
Definition Castable.h:849
size_t elementCount
Pointer to the data variable.
Definition Castable.h:1264
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:1100
void assignContainer(const T &v, bool append=false)
Assigns a STL Sequence, element by element.
Definition Castable.h:1164
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:1031
void assign(const T &x)
Copies an arbitrary base type or std::string value.
Definition Castable.h:340
Castable & assignCastable(const Castable &c)
Copy data from Castable. Perhaps copy size and type, too.
Definition Castable.cpp:267
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:392
bool operator==(const char *s) const
Compare as a character string.
Definition Castable.h:601
char getInputSeparator() const
Definition Castable.h:743
bool fillArray
If array, assigning a scalar will fill up the current array.
Definition Castable.h:883
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:784
bool operator>(const T &x) const
Compares a value with inner data.
Definition Castable.h:689
char outputSeparator
Element separator usein in writing and reading character strings (streams).
Definition Castable.h:1270
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:927
const char * getCharArray() const
Returns pointer to the array of chars, checks validity first.
Definition Castable.cpp:104
void append(const std::vector< T > &v)
Appends elements of a vector.
Definition Castable.h:443
virtual void setType(const std::type_info &t)
Sets the storage type. If a target value is available, use setPtr() directly.
Definition Castable.h:908
char inputSeparator
Element separator usein in reading a char sequence to an (numeric) array.
Definition Castable.h:1267
void clear()
Clears strings, or for scalars and arrays, sets all the values to zero. Does not change type.
Definition Castable.cpp:92
bool operator==(const T &x) const
Compares a value to internal data.
Definition Castable.h:632
void setType()
Sets the storage type. If a target value is available, use setPtr() directly.
Definition Castable.h:901
void append(const T &x)
Appends the string or appends the array by one element.
Definition Castable.h:416
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:1015
void setOutputSeparator(char c=',')
Definition Castable.h:733
Castable & setSeparator(char c=',')
The character used between array elements in output stream.
Definition Castable.h:711
void assign(std::nullptr_t)
Assigning nullptr resets the castable (unsets type and clears content).
Definition Castable.h:331
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:702
bool operator!=(const T &x) const
Compares a value to inner data.
Definition Castable.h:671
virtual bool requestSize(size_t elementCount)
Request to change the array size. For Castable (and Reference) does nothing and returns false.
Definition Castable.h:919
void setInputSeparator(char c=',')
Definition Castable.h:723
void assign(std::initializer_list< T > l)
Copies elements of a list.
Definition Castable.h:370
Definition Caster.h:77
T get(const void *p) const
Default implementation throws an error. See specialized implementation below.
Definition Caster.h:207
void unsetType()
calls void setType(void)().
Definition Caster.cpp:153
const std::type_info & getType() const
Returns type_info of the current type.
Definition Caster.h:154
size_t getElementSize() const
Returns the size of the base type (size of an element, not of element array).
Definition Caster.h:161
void setType(const std::type_info &t)
Calls setType<T>() for which typeid(T) = t.
Definition Caster.h:129
void translate(const Caster &c, const void *ptrC, void *ptr) const
Convert from str pointer and Caster.
Definition Caster.h:221
void * ptr
Future member: enables setting Caster type.
Definition Caster.h:260
void put(void *p, const T &x) const
Default conversion (for unconventional types). Uses std::stringstream for conversion.
Definition Caster.h:167
static std::ostream & toStream(std::ostream &ostr, const std::initializer_list< T > &x, const SprinterLayout &layout=defaultLayout)
New (experimental)
Definition Sprinter.h:423
static const SprinterLayout plainLayout
Display plain values, concatenating them with comma (except for strings).
Definition Sprinter.h:212
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 StringTools.h:394
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 StringTools.h:516
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 Data.h:1473
T & operator-=(T &x, const Castable &c)
Arithmetics: subtraction.
Definition Castable.h:1307
T & operator*=(T &x, const Castable &c)
Arithmetics: addition.
Definition Castable.h:1315
T & operator/=(T &x, const Castable &c)
Arithmetics: subtraction.
Definition Castable.h:1323
T & operator+=(T &x, const Castable &c)
Arithmetics: addition.
Definition Castable.h:1299
Definition Sprinter.h:136