pclass: Fix a potential future problem

This commit is contained in:
Joshua Scott 2018-12-13 00:57:56 +00:00
parent 9e5ca2816f
commit 1955e72bb9
3 changed files with 35 additions and 30 deletions

View File

@ -2,7 +2,7 @@
#include <utility> #include <utility>
#include <typeinfo> #include <typeinfo>
#include <sstream> #include <sstream>
#include <map> #include <unordered_map>
#include "ki/util/exception.h" #include "ki/util/exception.h"
namespace ki namespace ki
@ -160,18 +160,18 @@ namespace pclass
* A static lookup used to find appropriate casters at runtime. * A static lookup used to find appropriate casters at runtime.
* Contains SrcT -> Caster elements. * Contains SrcT -> Caster elements.
*/ */
static std::map<std::size_t, ValueCaster *> s_caster_lookup; static std::unordered_map<std::size_t, ValueCaster *> s_caster_lookup;
const std::type_info *m_src_type; const std::type_info *m_src_type;
std::map<std::size_t, detail::value_caster_base *> m_casts; std::unordered_map<std::size_t, detail::value_caster_base *> m_casts;
ValueCaster(); ValueCaster();
explicit ValueCaster(const std::type_info &src_type); explicit ValueCaster(const std::type_info &src_type);
/** /**
* @tparam SrcT The cast source type. * @tparam SrcT The cast source type.
* @returns The ValueCaster instance responsible for casting values of type SrcT. * @returns The ValueCaster instance responsible for casting values of type SrcT.
*/ */
template <typename SrcT> template <typename SrcT>
static ValueCaster &get() static ValueCaster &get()
{ {
@ -394,7 +394,9 @@ namespace pclass
Value cast(const Value &value) const override Value cast(const Value &value) const override
{ {
// By default, just attempt to static_cast from SrcT to DestT. // By default, just attempt to static_cast from SrcT to DestT.
return static_cast<DestT>(value.get<SrcT>()); return Value::make_value<DestT>(
static_cast<DestT>(value.get<SrcT>())
);
} }
}; };
} }

View File

@ -9,20 +9,29 @@
define_primitive<st>("signed " n); \ define_primitive<st>("signed " n); \
define_primitive<ut>("unsigned " n) define_primitive<ut>("unsigned " n)
#define DEFINE_BI_PRIMITIVE(n) \
define_primitive< bi<n> >("bi" #n)
#define DEFINE_BUI_PRIMITIVE(n) \
define_primitive< bui<n> >("bui" #n)
#define DEFINE_BIT_INTEGER_PRIMITIVE(n) \
DEFINE_BI_PRIMITIVE(n); \
DEFINE_BUI_PRIMITIVE(n)
namespace ki namespace ki
{ {
namespace pclass namespace pclass
{ {
template <int N>
void define_bit_integer_primitive(pclass::TypeSystem &type_system)
{
define_bit_integer_primitive<N - 1>(type_system);
// Define the signed bit integer
std::ostringstream oss;
oss << "bi" << N;
type_system.define_primitive<bi<N>>(oss.str());
// Define the unsigned bit integer
oss = std::ostringstream();
oss << "bui" << N;
type_system.define_primitive<bui<N>>(oss.str());
}
template <>
void define_bit_integer_primitive<0>(TypeSystem &type_system) {}
TypeSystem::TypeSystem(HashCalculator *hash_calculator) TypeSystem::TypeSystem(HashCalculator *hash_calculator)
{ {
m_hash_calculator = hash_calculator; m_hash_calculator = hash_calculator;
@ -49,13 +58,7 @@ namespace pclass
define_primitive<uint64_t>("gid"); define_primitive<uint64_t>("gid");
// Define bit-integer types // Define bit-integer types
DEFINE_BIT_INTEGER_PRIMITIVE(1); define_bit_integer_primitive<7>(*this);
DEFINE_BIT_INTEGER_PRIMITIVE(2);
DEFINE_BIT_INTEGER_PRIMITIVE(3);
DEFINE_BIT_INTEGER_PRIMITIVE(4);
DEFINE_BIT_INTEGER_PRIMITIVE(5);
DEFINE_BIT_INTEGER_PRIMITIVE(6);
DEFINE_BIT_INTEGER_PRIMITIVE(7);
define_primitive<bi<24>>("s24"); define_primitive<bi<24>>("s24");
define_primitive<bui<24>>("u24"); define_primitive<bui<24>>("u24");

View File

@ -6,7 +6,7 @@ namespace pclass
{ {
namespace detail namespace detail
{ {
Value value_caster_base::cast(const Value& v) const Value value_caster_base::cast(const Value &v) const
{ {
throw runtime_error("Unimplemented cast."); throw runtime_error("Unimplemented cast.");
} }
@ -39,7 +39,7 @@ namespace pclass
delete m_deallocator; delete m_deallocator;
} }
void ValueDeallocator::deallocate(void* ptr) const void ValueDeallocator::deallocate(void *ptr) const
{ {
m_deallocator->deallocate(ptr); m_deallocator->deallocate(ptr);
} }
@ -59,7 +59,7 @@ namespace pclass
} }
} }
ValueCaster::ValueCaster(const std::type_info& src_type) ValueCaster::ValueCaster(const std::type_info &src_type)
{ {
m_src_type = &src_type; m_src_type = &src_type;
} }
@ -73,7 +73,7 @@ namespace pclass
m_deallocator = detail::ValueDeallocator(); m_deallocator = detail::ValueDeallocator();
} }
Value::Value(Value&& that) noexcept Value::Value(Value &&that) noexcept
{ {
// Move pointer to this Value object, and take ownership if // Move pointer to this Value object, and take ownership if
// the other Value previously owned it. // the other Value previously owned it.
@ -85,7 +85,7 @@ namespace pclass
m_deallocator = std::move(that.m_deallocator); m_deallocator = std::move(that.m_deallocator);
} }
Value &Value::operator=(Value&& that) noexcept Value &Value::operator=(Value &&that) noexcept
{ {
// If the current pointer is owned, deallocate it // If the current pointer is owned, deallocate it
if (m_ptr_is_owned) if (m_ptr_is_owned)
@ -111,6 +111,6 @@ namespace pclass
} }
// Initialize the static lookup map // Initialize the static lookup map
std::map<std::size_t, ValueCaster *> ValueCaster::s_caster_lookup = {}; std::unordered_map<std::size_t, ValueCaster *> ValueCaster::s_caster_lookup = {};
} }
} }