]> git.tdb.fi Git - libs/core.git/commitdiff
Improve error reporting in Variant
authorMikko Rasa <tdb@tdb.fi>
Wed, 25 May 2011 20:32:24 +0000 (23:32 +0300)
committerMikko Rasa <tdb@tdb.fi>
Wed, 25 May 2011 20:32:24 +0000 (23:32 +0300)
source/core/variant.cpp [new file with mode: 0644]
source/core/variant.h

diff --git a/source/core/variant.cpp b/source/core/variant.cpp
new file mode 100644 (file)
index 0000000..1cdc0a5
--- /dev/null
@@ -0,0 +1,13 @@
+#include <msp/debug/demangle.h>
+#include <msp/strings/formatter.h>
+#include "variant.h"
+
+using namespace std;
+
+namespace Msp {
+
+type_mismatch::type_mismatch(const type_info &e, const type_info &a):
+       runtime_error(format("expected: %s\nactual: %s", Debug::demangle(e.name()), Debug::demangle(a.name())))
+{ }
+
+}
index 8d6db9a3de116e81433ac0e6fb706a3748adba50..f2d2ee563f339bb8b64eb020b516c3792b1db08f 100644 (file)
@@ -8,18 +8,29 @@ Distributed under the LGPL
 #ifndef MSP_CORE_VARIANT_H_
 #define MSP_CORE_VARIANT_H_
 
-#include "except.h"
+#include <stdexcept>
+#include <typeinfo>
 #include "meta.h"
 
 namespace Msp {
 
+class type_mismatch: public std::runtime_error
+{
+public:
+       type_mismatch(const std::type_info &, const std::type_info &);
+       ~type_mismatch() throw() { }
+};
+
+
 class Variant
 {
 private:
        struct StoreBase
        {
                virtual ~StoreBase() { }
-               virtual StoreBase *clone() const =0;
+
+               virtual const std::type_info &type_id() const = 0;
+               virtual StoreBase *clone() const = 0;
        };
 
        template<typename T>
@@ -28,6 +39,8 @@ private:
                T data;
 
                Store(T d): data(d) { }
+
+               virtual const std::type_info &type_id() const { return typeid(T); }
                virtual StoreBase *clone() const { return new Store<T>(data); }
        };
 
@@ -61,7 +74,7 @@ public:
                typedef typename RemoveConst<T>::Type NCT;
                Store<NCT> *s = dynamic_cast<Store<NCT> *>(store);
                if(!s)
-                       throw InvalidState("Type mismatch");
+                       throw type_mismatch(typeid(T), (store ? store->type_id() : typeid(void)));
                return s->data;
        }