1 /* Any.hpp 2 * Copyright (C) 2019 Sven Jähnichen 3 * 4 * This program is free software: you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation, either version 3 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program. If not, see <https://www.gnu.org/licenses/>. 16 */ 17 18 #ifndef BUTILITIES_ANY_HPP_ 19 #define BUTILITIES_ANY_HPP_ 20 21 #include <typeinfo> 22 #include <iostream> 23 24 namespace BUtilities 25 { 26 27 class Any 28 { 29 protected: 30 struct Envelope 31 { ~EnvelopeBUtilities::Any::Envelope32 virtual ~Envelope () {} cloneBUtilities::Any::Envelope33 virtual Envelope* clone () {return new Envelope (*this);} 34 }; 35 36 template <class T> struct Data : Envelope 37 { DataBUtilities::Any::Data38 Data (const T& t) : data (t) {} ~DataBUtilities::Any::Data39 virtual ~Data () {} cloneBUtilities::Any::Data40 virtual Envelope* clone () override {return new Data<T> (*this);} 41 T data; 42 }; 43 44 Envelope* dataptr = nullptr; 45 size_t dataTypeHash = typeid (void).hash_code (); 46 clone() const47 Envelope* clone () const 48 { 49 if (dataptr == nullptr) return nullptr; 50 return dataptr->clone (); 51 } 52 53 public: Any()54 Any () {} Any(const Any & that)55 Any (const Any& that) : dataTypeHash (that.dataTypeHash) 56 {dataptr = that.clone ();} 57 ~Any()58 ~Any () {if (dataptr) delete dataptr;} 59 operator =(const Any & that)60 Any& operator= (const Any& that) 61 { 62 if (dataptr) delete dataptr; 63 dataptr = that.clone (); 64 dataTypeHash = that.dataTypeHash; 65 return *this; 66 } 67 set(const T & t)68 template <class T> void set (const T& t) 69 { 70 if (dataptr) delete dataptr; 71 dataptr = new Data<T> (t); 72 dataTypeHash = typeid (T).hash_code (); 73 } 74 get() const75 template <class T> T get () const 76 { 77 if ((!dataptr) || (typeid (T).hash_code () != dataTypeHash)) return T (); // Return () better throw exception 78 return ((Data<T>*)dataptr)->data; 79 } 80 81 }; 82 makeAny(const T & t)83template <class T> Any makeAny (const T& t) 84 { 85 Any a; 86 a.set<T> (t); 87 return a; 88 } 89 90 } 91 92 #endif /* BUTILITIES_ANY_HPP_ */ 93