#pragma once #include #include #include namespace ki { namespace pclass { /** * A wrapper around a void pointer that ensures type safety. */ class Value { public: template Value(T &value) { m_value_ptr = value; m_type_hash = typeid(value).hash_code(); } Value(Value &&o) noexcept : m_value_ptr(std::move(m_value_ptr)) , m_type_hash(std::move(o.m_type_hash)) {} /** * @return Whether or not the value being held is of type T. */ template bool is() const { // Do the type hashes match? return m_type_hash == typeid(T).hash_code(); } /** * @return A reference to the value being held as the specified type. */ template const T &get() const { // Make sure that this is allowed if (!is()) throw std::runtime_error("Type mismatch in Value::get() call."); return *(T *)m_value_ptr; } /** * @return A reference to the value being held as the specified type. */ template T &get() { // Make sure that this is allowed if (!is()) throw std::runtime_error("Type mismatch in Value::get() call."); return *(T *)m_value_ptr; } private: void *m_value_ptr; std::size_t m_type_hash; }; } }