1 //------------------------------------------------------------------------------ 2 // emAnything.h 3 // 4 // Copyright (C) 2015-2016 Oliver Hamann. 5 // 6 // Homepage: http://eaglemode.sourceforge.net/ 7 // 8 // This program is free software: you can redistribute it and/or modify it under 9 // the terms of the GNU General Public License version 3 as published by the 10 // Free Software Foundation. 11 // 12 // This program is distributed in the hope that it will be useful, but WITHOUT 13 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 14 // FOR A PARTICULAR PURPOSE. See the GNU General Public License version 3 for 15 // more details. 16 // 17 // You should have received a copy of the GNU General Public License version 3 18 // along with this program. If not, see <http://www.gnu.org/licenses/>. 19 //------------------------------------------------------------------------------ 20 21 #ifndef emAnything_h 22 #define emAnything_h 23 24 #ifndef emStd1_h 25 #include <emCore/emStd1.h> 26 #endif 27 28 29 //============================================================================== 30 //================================= emAnything ================================= 31 //============================================================================== 32 33 class emAnything { 34 35 public: 36 37 // Class for holding any type of value. Copies are implicitly shared. 38 // The derived template class emCastAnything is used to cast to and from 39 // emAnything. Examples: 40 // 41 // // Convert an integer to emAnything: 42 // emAnything a = emCastAnything<int>(100); 43 // 44 // // Get back that integer: 45 // const int * pi = emCastAnything<int>(a); 46 // if (pi) { 47 // int i = *pi; 48 // printf("a = %d\n", i); 49 // } 50 // else { 51 // printf("Error: a is not an int.\n"); 52 // } 53 // 54 // // Convert an emString to emAnything: 55 // emAnything a2 = emCastAnything<emString>(emString("Hello")); 56 // 57 // // Get back that string: 58 // const emString * ps = emCastAnything<emString>(a2); 59 // if (ps) { 60 // printf("a2 = %s\n", ps->Get()); 61 // } 62 // else { 63 // printf("Error: a2 is not an emString.\n"); 64 // } 65 66 emAnything(); 67 // Construct invalid. 68 69 emAnything(const emAnything & anything); 70 // Construct a copy. 71 72 ~emAnything(); 73 // Destruct. 74 75 emAnything & operator = (const emAnything & anything); 76 // Copy. 77 78 protected: 79 80 struct AbstractSharedData { 81 AbstractSharedData(); 82 virtual ~AbstractSharedData(); 83 unsigned int RefCount; 84 }; 85 86 emAnything(AbstractSharedData * data); 87 88 AbstractSharedData * Data; 89 }; 90 91 92 //============================================================================== 93 //=============================== emCastAnything =============================== 94 //============================================================================== 95 96 template <class VALUE> class emCastAnything : public emAnything { 97 98 public: 99 100 // Helper class for casting emAnything to and from any type. 101 // Please see the examples in the description of emAnything. 102 103 emCastAnything(const VALUE & value); 104 emCastAnything(const emAnything & anything); 105 106 operator const VALUE * () const; 107 108 private: 109 110 struct SharedData : AbstractSharedData { 111 SharedData(const VALUE & value); 112 virtual ~SharedData(); 113 VALUE Value; 114 }; 115 }; 116 117 118 //============================================================================== 119 //============================== Implementations =============================== 120 //============================================================================== 121 emAnything()122inline emAnything::emAnything() 123 : Data(NULL) 124 { 125 } 126 AbstractSharedData()127inline emAnything::AbstractSharedData::AbstractSharedData() 128 : RefCount(1) 129 { 130 } 131 emAnything(AbstractSharedData * data)132inline emAnything::emAnything(AbstractSharedData * data) 133 : Data(data) 134 { 135 } 136 emCastAnything(const VALUE & value)137template <class VALUE> inline emCastAnything<VALUE>::emCastAnything( 138 const VALUE & value 139 ) : emAnything(new SharedData(value)) 140 { 141 } 142 emCastAnything(const emAnything & anything)143template <class VALUE> inline emCastAnything<VALUE>::emCastAnything( 144 const emAnything & anything 145 ) : emAnything(anything) 146 { 147 } 148 SharedData(const VALUE & value)149template <class VALUE> inline emCastAnything<VALUE>::SharedData::SharedData( 150 const VALUE & value 151 ) : Value(value) 152 { 153 } 154 155 template <class VALUE> emCastAnything<VALUE>::operator const VALUE * () const 156 { 157 if (Data) { 158 const SharedData * d= 159 dynamic_cast<const typename emCastAnything<VALUE>::SharedData*>(Data) 160 ; 161 if (d) return &d->Value; 162 } 163 return NULL; 164 } 165 ~SharedData()166template <class VALUE> emCastAnything<VALUE>::SharedData::~SharedData() 167 { 168 } 169 170 171 #endif 172