]> git.tdb.fi Git - libs/core.git/blob - source/core/variant.h
Add copy constructor and copy assignment to Variant
[libs/core.git] / source / core / variant.h
1 /* $Id$
2
3 This file is part of libmspcore
4 Copyright © 2006-2007 Mikko Rasa, Mikkosoft Productions
5 Distributed under the LGPL
6 */
7
8 #ifndef MSP_CORE_VARIANT_H_
9 #define MSP_CORE_VARIANT_H_
10
11 #include "except.h"
12 #include "meta.h"
13
14 namespace Msp {
15
16 class Variant
17 {
18 private:
19         struct StoreBase
20         {
21                 virtual ~StoreBase() { }
22                 virtual StoreBase *clone() const =0;
23         };
24
25         template<typename T>
26         struct Store: public StoreBase
27         {
28                 T data;
29
30                 Store(T d): data(d) { }
31                 virtual StoreBase *clone() const { return new Store<T>(data); }
32         };
33
34         StoreBase *store;
35
36 public:
37         Variant(): store(0) { }
38         template<typename T>
39         Variant(const T &v): store(new Store<typename RemoveConst<T>::Type>(v)) { }
40         Variant(const Variant &v): store(v.store ? v.store->clone() : 0) { }
41         ~Variant() { delete store; }
42
43         template<typename T>
44         Variant &operator=(const T &v)
45         {
46                 delete store;
47                 store=new Store<typename RemoveConst<T>::Type>(v);
48                 return *this;
49         }
50
51         Variant &operator=(const Variant &v)
52         {
53                 delete store;
54                 store=(v.store ? v.store->clone() : 0);
55                 return *this;
56         }
57
58         template<typename T>
59         T &value() const
60         {
61                 typedef typename RemoveConst<T>::Type NCT;
62                 Store<NCT> *s=dynamic_cast<Store<NCT> *>(store);
63                 if(!s)
64                         throw InvalidState("Type mismatch");
65                 return s->data;
66         }
67
68         template<typename T>
69         bool check_type() const
70         {
71                 return dynamic_cast<Store<typename RemoveConst<T>::Type> *>(store)!=0;
72         }
73
74         template<typename T>
75         operator T() const
76         { return value<T>(); }
77 };
78
79 } // namespace Msp
80
81 #endif