--- /dev/null
+#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())))
+{ }
+
+}
#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>
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); }
};
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;
}