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)83 template <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