mirror of
https://github.com/EQEmu/Server.git
synced 2026-04-02 04:02:39 +00:00
170 lines
4.0 KiB
C++
170 lines
4.0 KiB
C++
// Copyright Daniel Wallin 2009. Use, modification and distribution is
|
|
// subject to the Boost Software License, Version 1.0. (See accompanying
|
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
#ifndef LUABIND_INHERITANCE_090217_HPP
|
|
# define LUABIND_INHERITANCE_090217_HPP
|
|
|
|
# include <luabind/config.hpp>
|
|
# include <cassert>
|
|
# include <limits>
|
|
# include <map>
|
|
# include <memory>
|
|
# include <vector>
|
|
# include <luabind/typeid.hpp>
|
|
|
|
namespace luabind {
|
|
|
|
namespace detail {
|
|
|
|
using cast_function = void*(*)(void*);
|
|
using class_id = std::size_t;
|
|
|
|
constexpr class_id unknown_class = std::numeric_limits<class_id>::max();
|
|
|
|
class class_rep;
|
|
|
|
class LUABIND_API cast_graph
|
|
{
|
|
public:
|
|
cast_graph();
|
|
~cast_graph();
|
|
|
|
// `src` and `p` here describe the *most derived* object. This means that
|
|
// for a polymorphic type, the pointer must be cast with
|
|
// dynamic_cast<void*> before being passed in here, and `src` has to
|
|
// match typeid(*p).
|
|
std::pair<void*, int> cast(void* p, class_id src, class_id target, class_id dynamic_id, void const* dynamic_ptr) const;
|
|
void insert(class_id src, class_id target, cast_function cast);
|
|
|
|
private:
|
|
class impl;
|
|
std::unique_ptr<impl> m_impl;
|
|
};
|
|
|
|
// Maps a type_id to a class_id. Note that this actually partitions the
|
|
// id-space into two, using one half for "local" ids; ids that are used only as
|
|
// keys into the conversion cache. This is needed because we need a unique key
|
|
// even for types that hasn't been registered explicitly.
|
|
class LUABIND_API class_id_map
|
|
{
|
|
public:
|
|
class_id_map();
|
|
|
|
class_id get(type_id const& type) const;
|
|
class_id get_local(type_id const& type);
|
|
void put(class_id id, type_id const& type);
|
|
|
|
private:
|
|
using map_type = std::map<type_id, class_id>;
|
|
map_type m_classes;
|
|
class_id m_local_id;
|
|
|
|
static class_id const local_id_base;
|
|
};
|
|
|
|
inline class_id_map::class_id_map()
|
|
: m_local_id(local_id_base)
|
|
{}
|
|
|
|
inline class_id class_id_map::get(type_id const& type) const
|
|
{
|
|
map_type::const_iterator i = m_classes.find(type);
|
|
if(i == m_classes.end() || i->second >= local_id_base) {
|
|
return unknown_class;
|
|
}
|
|
else {
|
|
return i->second;
|
|
}
|
|
}
|
|
|
|
inline class_id class_id_map::get_local(type_id const& type)
|
|
{
|
|
std::pair<map_type::iterator, bool> result = m_classes.insert(std::make_pair(type, 0));
|
|
|
|
if(result.second) result.first->second = m_local_id++;
|
|
assert(m_local_id >= local_id_base);
|
|
return result.first->second;
|
|
}
|
|
|
|
inline void class_id_map::put(class_id id, type_id const& type)
|
|
{
|
|
assert(id < local_id_base);
|
|
|
|
std::pair<map_type::iterator, bool> result = m_classes.insert(
|
|
std::make_pair(type, 0));
|
|
|
|
assert(
|
|
result.second
|
|
|| result.first->second == id
|
|
|| result.first->second >= local_id_base
|
|
);
|
|
|
|
result.first->second = id;
|
|
}
|
|
|
|
class class_map
|
|
{
|
|
public:
|
|
class_rep* get(class_id id) const;
|
|
void put(class_id id, class_rep* cls);
|
|
|
|
private:
|
|
std::vector<class_rep*> m_classes;
|
|
};
|
|
|
|
inline class_rep* class_map::get(class_id id) const
|
|
{
|
|
if(id >= m_classes.size())
|
|
return 0;
|
|
return m_classes[id];
|
|
}
|
|
|
|
inline void class_map::put(class_id id, class_rep* cls)
|
|
{
|
|
if(id >= m_classes.size())
|
|
m_classes.resize(id + 1);
|
|
m_classes[id] = cls;
|
|
}
|
|
|
|
template <class S, class T>
|
|
struct static_cast_
|
|
{
|
|
static void* execute(void* p)
|
|
{
|
|
return static_cast<T*>(static_cast<S*>(p));
|
|
}
|
|
};
|
|
|
|
template <class S, class T>
|
|
struct dynamic_cast_
|
|
{
|
|
static void* execute(void* p)
|
|
{
|
|
return dynamic_cast<T*>(static_cast<S*>(p));
|
|
}
|
|
};
|
|
|
|
// Thread safe class_id allocation.
|
|
LUABIND_API class_id allocate_class_id(type_id const& cls);
|
|
|
|
template <class T>
|
|
struct registered_class
|
|
{
|
|
static class_id const id;
|
|
};
|
|
|
|
template <class T>
|
|
class_id const registered_class<T>::id = allocate_class_id(typeid(T));
|
|
|
|
template <class T>
|
|
struct registered_class<T const>
|
|
: registered_class<T>
|
|
{};
|
|
|
|
} // namespace detail
|
|
|
|
} // namespace luabind
|
|
|
|
#endif // LUABIND_INHERITANCE_090217_HPP
|
|
|