Compare commits
2 Commits
develop
...
attempt_co
Author | SHA1 | Date | |
---|---|---|---|
![]() |
fc0264272f | ||
![]() |
f431dbffb4 |
@ -86,6 +86,12 @@ namespace chaiscript
|
||||
// either way, we are not responsible if it doesn't work
|
||||
return(detail::Cast_Helper<Type>::cast((*t_conversions)->boxed_type_conversion<Type>(t_conversions->saves(), bv), t_conversions));
|
||||
} catch (...) {
|
||||
try {
|
||||
throw;
|
||||
} catch (const std::exception &e) {
|
||||
std::cout << "EXCEPTION: " << e.what() << std::endl;
|
||||
}
|
||||
|
||||
try {
|
||||
// try going the other way
|
||||
return(detail::Cast_Helper<Type>::cast((*t_conversions)->boxed_type_down_conversion<Type>(t_conversions->saves(), bv), t_conversions));
|
||||
|
@ -238,6 +238,11 @@ namespace chaiscript
|
||||
return m_data->m_type_info.bare_equal(ti);
|
||||
}
|
||||
|
||||
void reset_pointers() const
|
||||
{
|
||||
m_data->m_data_ptr = nullptr;
|
||||
m_data->m_const_data_ptr = nullptr;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
auto pointer_sentinel(std::shared_ptr<T> &ptr) const
|
||||
|
@ -367,6 +367,7 @@ namespace chaiscript
|
||||
chaiscript::detail::threading::unique_lock<chaiscript::detail::threading::shared_mutex> l(m_mutex);
|
||||
/// \todo error if a conversion already exists
|
||||
m_conversions.insert(conversion);
|
||||
std::cout << "Adding Conversion: TO: " << conversion->to().bare_type_info()->name() << " FROM: " << conversion->from().bare_type_info()->name() << std::endl;
|
||||
m_convertableTypes.insert({conversion->to().bare_type_info(), conversion->from().bare_type_info()});
|
||||
m_num_types = m_convertableTypes.size();
|
||||
}
|
||||
@ -410,12 +411,17 @@ namespace chaiscript
|
||||
Boxed_Value boxed_type_conversion(const Type_Info &to, Conversion_Saves &t_saves, const Boxed_Value &from) const
|
||||
{
|
||||
try {
|
||||
Boxed_Value ret = get_conversion(to, from.get_type_info())->convert(from);
|
||||
std::cout << "boxed_type_conversion" << std::endl;
|
||||
auto conversion = get_conversion(to, from.get_type_info());
|
||||
std::cout << "Conversion found!" << std::endl;
|
||||
Boxed_Value ret = conversion->convert(from);
|
||||
std::cout << "Conversion succeeded!" << std::endl;
|
||||
if (t_saves.enabled) { t_saves.saves.push_back(ret); }
|
||||
return ret;
|
||||
} catch (const std::out_of_range &) {
|
||||
throw exception::bad_boxed_dynamic_cast(from.get_type_info(), *to.bare_type_info(), "No known conversion");
|
||||
} catch (const std::bad_cast &) {
|
||||
std::cout << "Bad Cast!?" << std::endl;
|
||||
throw exception::bad_boxed_dynamic_cast(from.get_type_info(), *to.bare_type_info(), "Unable to perform dynamic_cast operation");
|
||||
}
|
||||
}
|
||||
@ -423,6 +429,7 @@ namespace chaiscript
|
||||
Boxed_Value boxed_type_down_conversion(const Type_Info &from, Conversion_Saves &t_saves, const Boxed_Value &to) const
|
||||
{
|
||||
try {
|
||||
std::cout << "boxed_type_down_conversion" << std::endl;
|
||||
Boxed_Value ret = get_conversion(to.get_type_info(), from)->convert_down(to);
|
||||
if (t_saves.enabled) { t_saves.saves.push_back(ret); }
|
||||
return ret;
|
||||
@ -455,10 +462,12 @@ namespace chaiscript
|
||||
{
|
||||
chaiscript::detail::threading::shared_lock<chaiscript::detail::threading::shared_mutex> l(m_mutex);
|
||||
|
||||
std::cout << "Getting conversion TO: " << to.name() << " FROM: " << from.name() << std::endl;
|
||||
const auto itr = find(to, from);
|
||||
|
||||
if (itr != m_conversions.end())
|
||||
{
|
||||
std::cout << "Found" << std::endl;
|
||||
return *itr;
|
||||
} else {
|
||||
throw std::out_of_range("No such conversion exists from " + from.bare_name() + " to " + to.bare_name());
|
||||
@ -476,7 +485,7 @@ namespace chaiscript
|
||||
return std::find_if(m_conversions.begin(), m_conversions.end(),
|
||||
[&to, &from](const std::shared_ptr<detail::Type_Conversion_Base> &conversion) -> bool
|
||||
{
|
||||
return (conversion->to().bare_equal(to) && conversion->from().bare_equal(from))
|
||||
return (conversion->to().type_info == to.type_info conversion->to().bare_equal(to) && conversion->from().bare_equal(from))
|
||||
|| (conversion->bidir() && conversion->from().bare_equal(to) && conversion->to().bare_equal(from));
|
||||
}
|
||||
);
|
||||
@ -485,6 +494,7 @@ namespace chaiscript
|
||||
std::set<std::shared_ptr<detail::Type_Conversion_Base> >::const_iterator find(
|
||||
const Type_Info &to, const Type_Info &from) const
|
||||
{
|
||||
std::cout << "Finding: TO: " << to.bare_type_info()->name() << " FROM: " << from.bare_type_info()->name() << std::endl;
|
||||
return std::find_if(m_conversions.begin(), m_conversions.end(),
|
||||
[&to, &from](const std::shared_ptr<detail::Type_Conversion_Base> &conversion)
|
||||
{
|
||||
@ -588,6 +598,24 @@ namespace chaiscript
|
||||
return chaiscript::make_shared<detail::Type_Conversion_Base, detail::Type_Conversion_Impl<Callable>>(t_from, t_to, t_func);
|
||||
}
|
||||
|
||||
template<typename From, typename To>
|
||||
Type_Conversion unique_ptr_conversion()
|
||||
{
|
||||
static_assert(std::is_convertible<From, To>::value, "Types are not automatically convertible");
|
||||
auto func = [](const Boxed_Value &t_bv) -> Boxed_Value {
|
||||
std::cout << " unique_ptr_conversion " << std::endl;
|
||||
// not even attempting to call boxed_cast so that we don't get caught in some call recursion
|
||||
auto bv = chaiscript::Boxed_Value(std::unique_ptr<To>(detail::Cast_Helper<std::unique_ptr<From> &&>::cast(t_bv, nullptr)));
|
||||
t_bv.reset_pointers();
|
||||
|
||||
return bv;
|
||||
};
|
||||
|
||||
return chaiscript::make_shared<detail::Type_Conversion_Base,
|
||||
detail::Type_Conversion_Impl<decltype(func)>>(user_type<std::unique_ptr<From>>(),
|
||||
user_type<std::unique_ptr<To>>(), func);
|
||||
}
|
||||
|
||||
template<typename From, typename To, typename Callable>
|
||||
Type_Conversion type_conversion(const Callable &t_function)
|
||||
{
|
||||
|
@ -143,11 +143,11 @@ namespace chaiscript
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// shared_ptr
|
||||
template<typename T>
|
||||
struct Get_Type_Info<std::shared_ptr<T> >
|
||||
{
|
||||
// typedef T type;
|
||||
|
||||
static constexpr Type_Info get()
|
||||
{
|
||||
return Type_Info(std::is_const<T>::value, std::is_reference<T>::value, std::is_pointer<T>::value,
|
||||
@ -176,6 +176,45 @@ namespace chaiscript
|
||||
}
|
||||
};
|
||||
|
||||
// unique_ptr
|
||||
template<typename T>
|
||||
struct Get_Type_Info<std::unique_ptr<T> >
|
||||
{
|
||||
static constexpr Type_Info get()
|
||||
{
|
||||
return Type_Info(std::is_const<T>::value, std::is_reference<T>::value, std::is_pointer<T>::value,
|
||||
std::is_void<T>::value,
|
||||
std::is_arithmetic<T>::value && !std::is_same<typename std::remove_const<typename std::remove_reference<T>::type>::type, bool>::value,
|
||||
&typeid(std::unique_ptr<T> ),
|
||||
&typeid(typename Bare_Type<T>::type));
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct Get_Type_Info<std::unique_ptr<T> &> : Get_Type_Info<std::unique_ptr<T>>
|
||||
{
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct Get_Type_Info<std::unique_ptr<T> &&> : Get_Type_Info<std::unique_ptr<T>>
|
||||
{
|
||||
};
|
||||
|
||||
|
||||
template<typename T>
|
||||
struct Get_Type_Info<const std::unique_ptr<T> &>
|
||||
{
|
||||
static constexpr Type_Info get()
|
||||
{
|
||||
return Type_Info(std::is_const<T>::value, std::is_reference<T>::value, std::is_pointer<T>::value,
|
||||
std::is_void<T>::value,
|
||||
std::is_arithmetic<T>::value && !std::is_same<typename std::remove_const<typename std::remove_reference<T>::type>::type, bool>::value,
|
||||
&typeid(const std::unique_ptr<T> &),
|
||||
&typeid(typename Bare_Type<T>::type));
|
||||
}
|
||||
};
|
||||
|
||||
// reference_wrapper
|
||||
template<typename T>
|
||||
struct Get_Type_Info<std::reference_wrapper<T> >
|
||||
{
|
||||
|
1519
unittests/catch.hpp
1519
unittests/catch.hpp
File diff suppressed because it is too large
Load Diff
@ -1154,6 +1154,8 @@ std::unique_ptr<Unique_Ptr_Test_Class> make_Unique_Ptr_Test_Class()
|
||||
return std::make_unique<Unique_Ptr_Test_Class>();
|
||||
}
|
||||
|
||||
|
||||
|
||||
TEST_CASE("Call methods through unique_ptr")
|
||||
{
|
||||
chaiscript::ChaiScript_Basic chai(create_chaiscript_stdlib(),create_chaiscript_parser());
|
||||
@ -1180,6 +1182,10 @@ std::unique_ptr<Unique_Ptr_Test_Derived_Class> make_Unique_Ptr_Test_Derived_Clas
|
||||
return std::make_unique<Unique_Ptr_Test_Derived_Class>();
|
||||
}
|
||||
|
||||
void call_unique_ptr_with_conversion_to_base(std::unique_ptr<Unique_Ptr_Test_Base_Class> &&)
|
||||
{
|
||||
}
|
||||
|
||||
TEST_CASE("Call methods on base class through unique_ptr<derived>")
|
||||
{
|
||||
chaiscript::ChaiScript_Basic chai(create_chaiscript_stdlib(),create_chaiscript_parser());
|
||||
@ -1190,6 +1196,16 @@ TEST_CASE("Call methods on base class through unique_ptr<derived>")
|
||||
chai.add(chaiscript::base_class<Unique_Ptr_Test_Base_Class, Unique_Ptr_Test_Derived_Class>());
|
||||
CHECK(chai.eval<int>("uptr.getI()") == 5);
|
||||
CHECK(chai.eval<int>("var uptr2 = make_Unique_Ptr_Test_Derived_Class(); uptr2.getI()") == 5);
|
||||
|
||||
chai.add(chaiscript::unique_ptr_conversion<Unique_Ptr_Test_Derived_Class, Unique_Ptr_Test_Base_Class>());
|
||||
|
||||
chai.add(chaiscript::fun(call_unique_ptr_with_conversion_to_base), "call_unique_ptr_with_conversion_to_base");
|
||||
CHECK(!chai.eval<bool>("uptr2.is_var_null"));
|
||||
|
||||
std::cout << "Attempting conversion" << std::endl;
|
||||
CHECK_NOTHROW(chai.eval("call_unique_ptr_with_conversion_to_base(uptr2)"));
|
||||
INFO("Conversion succeeded");
|
||||
CHECK(chai.eval<bool>("uptr2.is_var_null"));
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user