Compare commits
1 Commits
develop
...
value_type
Author | SHA1 | Date | |
---|---|---|---|
![]() |
5c541c3d8e |
@ -133,7 +133,7 @@ else()
|
||||
endif()
|
||||
|
||||
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
|
||||
option(USE_LIBCXX "Use clang's libcxx" TRUE)
|
||||
option(USE_LIBCXX "Use clang's libcxx" FALSE)
|
||||
|
||||
if(USE_LIBCXX)
|
||||
add_definitions(-stdlib=libc++)
|
||||
|
@ -44,31 +44,20 @@ namespace chaiscript {
|
||||
private:
|
||||
struct Data
|
||||
{
|
||||
Data(const std::type_info &t_type)
|
||||
: m_type(t_type)
|
||||
{
|
||||
}
|
||||
|
||||
Data &operator=(const Data &) = delete;
|
||||
|
||||
virtual ~Data() {}
|
||||
|
||||
virtual void *data() = 0;
|
||||
const std::type_info &type() const
|
||||
{
|
||||
return m_type;
|
||||
}
|
||||
|
||||
virtual std::unique_ptr<Data> clone() const = 0;
|
||||
const std::type_info &m_type;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct Data_Impl : Data
|
||||
{
|
||||
explicit Data_Impl(T t_type)
|
||||
: Data(typeid(T)),
|
||||
m_data(std::move(t_type))
|
||||
: m_data(std::move(t_type))
|
||||
{
|
||||
}
|
||||
|
||||
@ -90,19 +79,21 @@ namespace chaiscript {
|
||||
};
|
||||
|
||||
std::unique_ptr<Data> m_data;
|
||||
mutable std::array<uint8_t, 15> m_smallSize;
|
||||
bool m_isSmall = false;
|
||||
const std::type_info *m_type = &typeid(void);
|
||||
|
||||
public:
|
||||
// construct/copy/destruct
|
||||
Any() = default;
|
||||
|
||||
Any(const Any &t_any)
|
||||
{
|
||||
if (!t_any.empty())
|
||||
{
|
||||
m_data = t_any.m_data->clone();
|
||||
} else {
|
||||
m_data.reset();
|
||||
}
|
||||
: m_data(t_any.m_data?t_any.m_data->clone():nullptr),
|
||||
m_smallSize(t_any.m_smallSize),
|
||||
m_isSmall(t_any.m_isSmall),
|
||||
m_type(t_any.m_type)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
#if _MSC_VER != 1800
|
||||
@ -111,13 +102,31 @@ namespace chaiscript {
|
||||
#endif
|
||||
|
||||
template<typename ValueType,
|
||||
typename = typename std::enable_if<!std::is_same<Any, typename std::decay<ValueType>::type>::value>::type>
|
||||
typename = typename std::enable_if<!std::is_same<Any, typename std::decay<ValueType>::type>::value>::type,
|
||||
typename = typename std::enable_if< std::is_trivial<typename std::decay<ValueType>::type>::value>::type,
|
||||
typename = typename std::enable_if<sizeof(typename std::decay<ValueType>::type) <= sizeof(decltype(m_smallSize)) >::type>
|
||||
explicit Any(ValueType &&t_value)
|
||||
: m_data(std::unique_ptr<Data>(new Data_Impl<typename std::decay<ValueType>::type>(std::forward<ValueType>(t_value))))
|
||||
: m_isSmall(true), m_type(&typeid(typename std::decay<ValueType>::type))
|
||||
{
|
||||
m_smallSize.fill(0);
|
||||
*(static_cast<typename std::decay<ValueType>::type *>(static_cast<void *>(m_smallSize.data()))) = t_value;
|
||||
// std::cout << "Setting type: " << typeid(typename std::decay<ValueType>::type).name() << " " << t_value << " actual val: " << *(static_cast<typename std::decay<ValueType>::type *>(static_cast<void *>(m_smallSize.data()))) << " cast: " << cast<typename std::decay<ValueType>::type>() << "\n";
|
||||
}
|
||||
|
||||
template<typename ValueType,
|
||||
typename = typename std::enable_if<!std::is_same<Any, typename std::decay<ValueType>::type>::value>::type,
|
||||
typename = typename std::enable_if<
|
||||
!std::is_trivial<typename std::decay<ValueType>::type>::value
|
||||
|| !(sizeof(typename std::decay<ValueType>::type) <= sizeof(decltype(m_smallSize))) >::type>
|
||||
explicit Any(ValueType &&t_value)
|
||||
: m_data(std::unique_ptr<Data>(new Data_Impl<typename std::decay<ValueType>::type>(std::forward<ValueType>(t_value)))),
|
||||
m_isSmall(false),
|
||||
m_type(&typeid(typename std::decay<ValueType>::type))
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
Any & operator=(const Any &t_any)
|
||||
{
|
||||
Any copy(t_any);
|
||||
@ -128,14 +137,20 @@ namespace chaiscript {
|
||||
template<typename ToType>
|
||||
ToType &cast() const
|
||||
{
|
||||
if (m_data && typeid(ToType) == m_data->type())
|
||||
if (m_isSmall && typeid(ToType) == *m_type)
|
||||
{
|
||||
return *static_cast<ToType *>(static_cast<void *>(m_smallSize.data()));
|
||||
} else if (!m_isSmall && m_data && typeid(ToType) == *m_type) {
|
||||
return *static_cast<ToType *>(m_data->data());
|
||||
} else {
|
||||
throw chaiscript::detail::exception::bad_any_cast();
|
||||
}
|
||||
}
|
||||
|
||||
const std::type_info &type() const
|
||||
{
|
||||
return *m_type;
|
||||
}
|
||||
|
||||
~Any()
|
||||
{
|
||||
@ -144,25 +159,31 @@ namespace chaiscript {
|
||||
// modifiers
|
||||
Any & swap(Any &t_other)
|
||||
{
|
||||
std::swap(t_other.m_smallSize, m_smallSize);
|
||||
std::swap(t_other.m_isSmall, m_isSmall);
|
||||
std::swap(t_other.m_data, m_data);
|
||||
std::swap(t_other.m_type, m_type);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// queries
|
||||
bool empty() const
|
||||
{
|
||||
return !bool(m_data);
|
||||
return !bool(m_data) && !m_isSmall;
|
||||
}
|
||||
|
||||
const std::type_info & type() const
|
||||
void *data() const
|
||||
{
|
||||
if (m_data)
|
||||
if (m_isSmall)
|
||||
{
|
||||
return m_data->type();
|
||||
return static_cast<void *>(m_smallSize.data());
|
||||
} else if (m_data) {
|
||||
return m_data->data();
|
||||
} else {
|
||||
return typeid(void);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -76,7 +76,7 @@ namespace chaiscript
|
||||
|
||||
struct Object_Data
|
||||
{
|
||||
static std::shared_ptr<Data> get(Boxed_Value::Void_Type)
|
||||
static std::shared_ptr<Data> get(Boxed_Value::Void_Type, bool, bool)
|
||||
{
|
||||
return std::make_shared<Data>(
|
||||
detail::Get_Type_Info<void>::get(),
|
||||
@ -87,13 +87,13 @@ namespace chaiscript
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static std::shared_ptr<Data> get(const std::shared_ptr<T> *obj)
|
||||
static std::shared_ptr<Data> get(const std::shared_ptr<T> *obj, bool, bool)
|
||||
{
|
||||
return get(*obj);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static std::shared_ptr<Data> get(const std::shared_ptr<T> &obj)
|
||||
static std::shared_ptr<Data> get(const std::shared_ptr<T> &obj, bool, bool)
|
||||
{
|
||||
return std::make_shared<Data>(
|
||||
detail::Get_Type_Info<T>::get(),
|
||||
@ -104,7 +104,7 @@ namespace chaiscript
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static std::shared_ptr<Data> get(std::shared_ptr<T> &&obj)
|
||||
static std::shared_ptr<Data> get(std::shared_ptr<T> &&obj, bool, bool)
|
||||
{
|
||||
auto ptr = obj.get();
|
||||
return std::make_shared<Data>(
|
||||
@ -122,7 +122,7 @@ namespace chaiscript
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static std::shared_ptr<Data> get(std::reference_wrapper<T> obj)
|
||||
static std::shared_ptr<Data> get(std::reference_wrapper<T> obj, bool, bool)
|
||||
{
|
||||
auto p = &obj.get();
|
||||
return std::make_shared<Data>(
|
||||
@ -134,22 +134,57 @@ namespace chaiscript
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static std::shared_ptr<Data> get(T t)
|
||||
static std::shared_ptr<Data> get(T t, bool t_value_type, bool t_make_const)
|
||||
{
|
||||
auto p = std::make_shared<T>(std::move(t));
|
||||
auto ptr = p.get();
|
||||
return std::make_shared<Data>(
|
||||
detail::Get_Type_Info<T>::get(),
|
||||
chaiscript::detail::Any(std::move(p)),
|
||||
false,
|
||||
ptr
|
||||
);
|
||||
typedef typename std::add_const<T>::type const_type;
|
||||
if (t_make_const)
|
||||
{
|
||||
if (t_value_type)
|
||||
{
|
||||
chaiscript::detail::Any a(std::move(t));
|
||||
return std::make_shared<Data>(
|
||||
detail::Get_Type_Info<const_type>::get(),
|
||||
std::move(a),
|
||||
false,
|
||||
nullptr
|
||||
);
|
||||
} else {
|
||||
auto p = std::make_shared<const_type>(std::move(t));
|
||||
auto ptr = p.get();
|
||||
return std::make_shared<Data>(
|
||||
detail::Get_Type_Info<const_type>::get(),
|
||||
chaiscript::detail::Any(std::move(p)),
|
||||
false,
|
||||
ptr
|
||||
);
|
||||
}
|
||||
} else {
|
||||
if (t_value_type)
|
||||
{
|
||||
chaiscript::detail::Any a(std::move(t));
|
||||
return std::make_shared<Data>(
|
||||
detail::Get_Type_Info<T>::get(),
|
||||
std::move(a),
|
||||
false,
|
||||
nullptr
|
||||
);
|
||||
} else {
|
||||
auto p = std::make_shared<T>(std::move(t));
|
||||
auto ptr = p.get();
|
||||
return std::make_shared<Data>(
|
||||
detail::Get_Type_Info<T>::get(),
|
||||
chaiscript::detail::Any(std::move(p)),
|
||||
false,
|
||||
ptr
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static std::shared_ptr<Data> get()
|
||||
{
|
||||
return std::make_shared<Data>(
|
||||
Type_Info(),
|
||||
Type_Info(),
|
||||
chaiscript::detail::Any(),
|
||||
false,
|
||||
nullptr
|
||||
@ -162,9 +197,10 @@ namespace chaiscript
|
||||
/// Basic Boxed_Value constructor
|
||||
template<typename T,
|
||||
typename = typename std::enable_if<!std::is_same<Boxed_Value, typename std::decay<T>::type>::value>::type>
|
||||
explicit Boxed_Value(T &&t)
|
||||
: m_data(Object_Data::get(std::forward<T>(t)))
|
||||
explicit Boxed_Value(T &&t, bool t_make_const=false, bool t_value_type = std::is_trivial<typename std::decay<T>::type>::value)
|
||||
: m_data(Object_Data::get(std::forward<T>(t), t_make_const, t_value_type))
|
||||
{
|
||||
//std::cout << "typeid: " << typeid(T).name() << " is trivial " << std::is_trivial<typename std::decay<T>::type>::value << "\n";
|
||||
}
|
||||
|
||||
/// Unknown-type constructor
|
||||
@ -237,12 +273,22 @@ namespace chaiscript
|
||||
|
||||
void *get_ptr() const CHAISCRIPT_NOEXCEPT
|
||||
{
|
||||
return m_data->m_data_ptr;
|
||||
if (m_data->m_data_ptr)
|
||||
{
|
||||
return m_data->m_data_ptr;
|
||||
} else {
|
||||
return m_data->m_obj.data();
|
||||
}
|
||||
}
|
||||
|
||||
const void *get_const_ptr() const CHAISCRIPT_NOEXCEPT
|
||||
{
|
||||
return m_data->m_const_data_ptr;
|
||||
if (m_data->m_const_data_ptr)
|
||||
{
|
||||
return m_data->m_const_data_ptr;
|
||||
} else {
|
||||
return m_data->m_obj.data();
|
||||
}
|
||||
}
|
||||
|
||||
Boxed_Value get_attr(const std::string &t_name)
|
||||
@ -303,7 +349,7 @@ namespace chaiscript
|
||||
template<typename T>
|
||||
Boxed_Value const_var_impl(const T &t)
|
||||
{
|
||||
return Boxed_Value(std::make_shared<typename std::add_const<T>::type >(t));
|
||||
return Boxed_Value(std::make_shared<typename std::add_const<T>::type >(t), true);
|
||||
}
|
||||
|
||||
/// \brief Takes a pointer to a value, adds const to the pointed to type and returns an immutable Boxed_Value.
|
||||
|
@ -157,7 +157,7 @@ namespace chaiscript
|
||||
{
|
||||
if (!t_bv.is_const())
|
||||
{
|
||||
throw chaiscript::exception::global_non_const();
|
||||
// throw chaiscript::exception::global_non_const();
|
||||
}
|
||||
|
||||
m_globals.emplace_back(std::move(t_bv), std::move(t_name));
|
||||
@ -474,7 +474,7 @@ namespace chaiscript
|
||||
validate_object_name(name);
|
||||
if (!obj.is_const())
|
||||
{
|
||||
throw chaiscript::exception::global_non_const();
|
||||
// throw chaiscript::exception::global_non_const();
|
||||
}
|
||||
|
||||
chaiscript::detail::threading::unique_lock<chaiscript::detail::threading::shared_mutex> l(m_global_object_mutex);
|
||||
|
Loading…
x
Reference in New Issue
Block a user