]> git.tdb.fi Git - libs/core.git/blobdiff - source/core/variant.h
Merge branch 'strings-master'
[libs/core.git] / source / core / variant.h
index b81bb506f300f8df2f215a63a427a7df38af7f7e..8d6db9a3de116e81433ac0e6fb706a3748adba50 100644 (file)
@@ -1,7 +1,7 @@
 /* $Id$
 
 This file is part of libmspcore
-Copyright © 2006-2007 Mikko Rasa, Mikkosoft Productions
+Copyright © 2008 Mikko Rasa, Mikkosoft Productions
 Distributed under the LGPL
 */
 
@@ -9,6 +9,7 @@ Distributed under the LGPL
 #define MSP_CORE_VARIANT_H_
 
 #include "except.h"
+#include "meta.h"
 
 namespace Msp {
 
@@ -18,6 +19,7 @@ private:
        struct StoreBase
        {
                virtual ~StoreBase() { }
+               virtual StoreBase *clone() const =0;
        };
 
        template<typename T>
@@ -26,6 +28,7 @@ private:
                T data;
 
                Store(T d): data(d) { }
+               virtual StoreBase *clone() const { return new Store<T>(data); }
        };
 
        StoreBase *store;
@@ -33,21 +36,30 @@ private:
 public:
        Variant(): store(0) { }
        template<typename T>
-       Variant(T v): store(new Store<T>(v)) { }
+       Variant(const T &v): store(new Store<typename RemoveConst<T>::Type>(v)) { }
+       Variant(const Variant &v): store(v.store ? v.store->clone() : 0) { }
        ~Variant() { delete store; }
 
        template<typename T>
-       Variant &operator=(v)
+       Variant &operator=(const T &v)
        {
                delete store;
-               store=new Store<T>(v);
+               store = new Store<typename RemoveConst<T>::Type>(v);
+               return *this;
+       }
+
+       Variant &operator=(const Variant &v)
+       {
+               delete store;
+               store = (v.store ? v.store->clone() : 0);
                return *this;
        }
 
        template<typename T>
-       T value() const
+       T &value() const
        {
-               Store<T> *s=dynamic_cast<Store<T> *>(store);
+               typedef typename RemoveConst<T>::Type NCT;
+               Store<NCT> *s = dynamic_cast<Store<NCT> *>(store);
                if(!s)
                        throw InvalidState("Type mismatch");
                return s->data;
@@ -56,7 +68,7 @@ public:
        template<typename T>
        bool check_type() const
        {
-               return dynamic_cast<Store<T> *>(store)!=0;
+               return dynamic_cast<Store<typename RemoveConst<T>::Type> *>(store)!=0;
        }
 
        template<typename T>