Merge branch 'release-5.x' into develop
This commit is contained in:
commit
dd6b38cafb
@ -163,6 +163,28 @@ chaiscript::Boxed_Number(chai.eval("5.3 + 2.1")).get_as<int>(); // works with an
|
|||||||
static_cast<int>(chai.eval<double>("5.3+2.1")); // this version only works if we know that it's a double
|
static_cast<int>(chai.eval<double>("5.3+2.1")); // this version only works if we know that it's a double
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Conversion Caveats
|
||||||
|
|
||||||
|
Conversion to `std::shared_ptr<T> &` is supported for function calls, but if you attempt to keep a reference to a `shared_ptr<>` you might invoke undefined behavior
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
// ok this is supported, you can register it with chaiscript engine
|
||||||
|
void nullify_shared_ptr(std::shared_ptr<int> &t) {
|
||||||
|
t == nullptr
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
// do some stuff and create a chaiscript instance
|
||||||
|
std::shared_ptr<int> &ptr = chai.eval<std::shared_ptr<int> &>(somevalue);
|
||||||
|
// DO NOT do this. Taking a non-const reference to a shared_ptr is not
|
||||||
|
// supported and causes undefined behavior in the chaiscript engine
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
## Sharing Values
|
## Sharing Values
|
||||||
|
|
||||||
```
|
```
|
||||||
|
@ -173,6 +173,21 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename Result>
|
||||||
|
struct Cast_Helper_Inner<std::shared_ptr<Result> &>
|
||||||
|
{
|
||||||
|
static_assert(!std::is_const<Result>::value, "Non-const reference to std::shared_ptr<const T> is not supported");
|
||||||
|
|
||||||
|
typedef Boxed_Value::Sentinel<Result> Result_Type;
|
||||||
|
|
||||||
|
static Result_Type cast(const Boxed_Value &ob, const Type_Conversions_State *)
|
||||||
|
{
|
||||||
|
std::shared_ptr<Result> &res = ob.get().cast<std::shared_ptr<Result> >();
|
||||||
|
return ob.pointer_sentinel(res);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/// Cast_Helper_Inner for casting to a const std::shared_ptr<const> & type
|
/// Cast_Helper_Inner for casting to a const std::shared_ptr<const> & type
|
||||||
template<typename Result>
|
template<typename Result>
|
||||||
struct Cast_Helper_Inner<const std::shared_ptr<const Result> > : Cast_Helper_Inner<std::shared_ptr<const Result> >
|
struct Cast_Helper_Inner<const std::shared_ptr<const Result> > : Cast_Helper_Inner<std::shared_ptr<const Result> >
|
||||||
|
@ -226,6 +226,50 @@ namespace chaiscript
|
|||||||
return m_data->m_type_info.bare_equal(ti);
|
return m_data->m_type_info.bare_equal(ti);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct Sentinel {
|
||||||
|
Sentinel(std::shared_ptr<T> &ptr, Data &data)
|
||||||
|
: m_ptr(ptr), m_data(data)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
~Sentinel()
|
||||||
|
{
|
||||||
|
// save new pointer data
|
||||||
|
m_data.get().m_data_ptr = m_ptr.get().get();
|
||||||
|
m_data.get().m_const_data_ptr = m_ptr.get().get();
|
||||||
|
}
|
||||||
|
|
||||||
|
Sentinel& operator=(Sentinel&&s) {
|
||||||
|
m_ptr = std::move(s.m_ptr);
|
||||||
|
m_data = std::move(s.m_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
Sentinel(Sentinel &&s)
|
||||||
|
: m_ptr(std::move(s.m_ptr)),
|
||||||
|
m_data(std::move(s.m_data))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
operator std::shared_ptr<T>&() const
|
||||||
|
{
|
||||||
|
return m_ptr.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
Sentinel &operator=(const Sentinel &) = delete;
|
||||||
|
Sentinel(Sentinel&) = delete;
|
||||||
|
|
||||||
|
std::reference_wrapper<std::shared_ptr<T>> m_ptr;
|
||||||
|
std::reference_wrapper<Data> m_data;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
Sentinel<T> pointer_sentinel(std::shared_ptr<T> &ptr) const
|
||||||
|
{
|
||||||
|
return Sentinel<T>(ptr, *(m_data.get()));
|
||||||
|
}
|
||||||
|
|
||||||
bool is_null() const noexcept
|
bool is_null() const noexcept
|
||||||
{
|
{
|
||||||
return (m_data->m_data_ptr == nullptr && m_data->m_const_data_ptr == nullptr);
|
return (m_data->m_data_ptr == nullptr && m_data->m_const_data_ptr == nullptr);
|
||||||
|
@ -150,6 +150,11 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct Get_Type_Info<std::shared_ptr<T> &> : Get_Type_Info<std::shared_ptr<T>>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct Get_Type_Info<const std::shared_ptr<T> &>
|
struct Get_Type_Info<const std::shared_ptr<T> &>
|
||||||
{
|
{
|
||||||
|
@ -1,6 +1,10 @@
|
|||||||
Notes:
|
Notes:
|
||||||
=======
|
=======
|
||||||
Current Version: 5.8.1
|
Current Version: 5.8.2
|
||||||
|
|
||||||
|
### Changes since 5.8.1
|
||||||
|
* Allow casting to non-const & std::shared_ptr<T>
|
||||||
|
|
||||||
|
|
||||||
### Changes since 5.8.0
|
### Changes since 5.8.0
|
||||||
* Fix parsing of floats to be locale independent #250
|
* Fix parsing of floats to be locale independent #250
|
||||||
|
@ -111,6 +111,16 @@ std::shared_ptr<TestBaseType> null_factory()
|
|||||||
return std::shared_ptr<TestBaseType>();
|
return std::shared_ptr<TestBaseType>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void update_shared_ptr(std::shared_ptr<TestBaseType> &ptr)
|
||||||
|
{
|
||||||
|
ptr = std::make_shared<TestDerivedType>();
|
||||||
|
}
|
||||||
|
|
||||||
|
void nullify_shared_ptr(std::shared_ptr<TestBaseType> &ptr)
|
||||||
|
{
|
||||||
|
ptr = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
std::string hello_world()
|
std::string hello_world()
|
||||||
{
|
{
|
||||||
return "Hello World";
|
return "Hello World";
|
||||||
@ -202,6 +212,10 @@ CHAISCRIPT_MODULE_EXPORT chaiscript::ModulePtr create_chaiscript_module_test_mo
|
|||||||
m->add(chaiscript::type_conversion<const char *, std::string>());
|
m->add(chaiscript::type_conversion<const char *, std::string>());
|
||||||
m->add(chaiscript::constructor<Type2 (const TestBaseType &)>(), "Type2");
|
m->add(chaiscript::constructor<Type2 (const TestBaseType &)>(), "Type2");
|
||||||
|
|
||||||
|
m->add(chaiscript::fun(&update_shared_ptr), "update_shared_ptr");
|
||||||
|
m->add(chaiscript::fun(&nullify_shared_ptr), "nullify_shared_ptr");
|
||||||
|
|
||||||
|
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,12 +54,13 @@ bool test_type_conversion(const Boxed_Value &bv, bool expectedpass)
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename Type>
|
template<typename Type>
|
||||||
bool do_test(const Boxed_Value &bv, bool T, bool ConstT, bool TRef, bool ConstTRef, bool TPtr, bool ConstTPtr, bool TPtrConst,
|
bool do_test(const Boxed_Value &bv,
|
||||||
bool ConstTPtrConst, bool SharedPtrT, bool SharedConstPtrT,
|
bool T, bool ConstT, bool TRef, bool ConstTRef, bool TPtr,
|
||||||
bool ConstSharedPtrT, bool ConstSharedConstPtrT, bool ConstSharedPtrTRef, bool ConstSharedPtrTConstRef,
|
bool ConstTPtr, bool TPtrConst, bool ConstTPtrConst, bool SharedPtrT, bool SharedConstPtrT,
|
||||||
bool WrappedRef, bool WrappedConstRef, bool ConstWrappedRef, bool ConstWrappedConstRef,
|
bool SharedPtrTRef, bool ConstSharedPtrT, bool ConstSharedConstPtrT, bool ConstSharedPtrTRef, bool ConstSharedPtrTConstRef,
|
||||||
bool ConstWrappedRefRef, bool ConstWrappedConstRefRef, bool Number,
|
bool WrappedRef, bool WrappedConstRef, bool ConstWrappedRef, bool ConstWrappedConstRef, bool ConstWrappedRefRef,
|
||||||
bool ConstNumber, bool ConstNumberRef, bool TPtrConstRef, bool ConstTPtrConstRef)
|
bool ConstWrappedConstRefRef, bool Number, bool ConstNumber, bool ConstNumberRef, bool TPtrConstRef,
|
||||||
|
bool ConstTPtrConstRef)
|
||||||
{
|
{
|
||||||
bool passed = true;
|
bool passed = true;
|
||||||
passed &= test_type_conversion<Type>(bv, T);
|
passed &= test_type_conversion<Type>(bv, T);
|
||||||
@ -72,8 +73,8 @@ bool do_test(const Boxed_Value &bv, bool T, bool ConstT, bool TRef, bool ConstTR
|
|||||||
passed &= test_type_conversion<const Type * const>(bv, ConstTPtrConst);
|
passed &= test_type_conversion<const Type * const>(bv, ConstTPtrConst);
|
||||||
passed &= test_type_conversion<std::shared_ptr<Type> >(bv, SharedPtrT);
|
passed &= test_type_conversion<std::shared_ptr<Type> >(bv, SharedPtrT);
|
||||||
passed &= test_type_conversion<std::shared_ptr<const Type> >(bv, SharedConstPtrT);
|
passed &= test_type_conversion<std::shared_ptr<const Type> >(bv, SharedConstPtrT);
|
||||||
passed &= test_type_conversion<std::shared_ptr<Type> &>(bv, false);
|
passed &= test_type_conversion<std::shared_ptr<Type> &>(bv, SharedPtrTRef);
|
||||||
passed &= test_type_conversion<std::shared_ptr<const Type> &>(bv, false);
|
//passed &= test_type_conversion<std::shared_ptr<const Type> &>(bv, false);
|
||||||
passed &= test_type_conversion<const std::shared_ptr<Type> >(bv, ConstSharedPtrT);
|
passed &= test_type_conversion<const std::shared_ptr<Type> >(bv, ConstSharedPtrT);
|
||||||
passed &= test_type_conversion<const std::shared_ptr<const Type> >(bv, ConstSharedConstPtrT);
|
passed &= test_type_conversion<const std::shared_ptr<const Type> >(bv, ConstSharedConstPtrT);
|
||||||
passed &= test_type_conversion<const std::shared_ptr<Type> &>(bv, ConstSharedPtrTRef);
|
passed &= test_type_conversion<const std::shared_ptr<Type> &>(bv, ConstSharedPtrTRef);
|
||||||
@ -115,37 +116,37 @@ bool built_in_type_test(const T &initial, bool ispod)
|
|||||||
T i = T(initial);
|
T i = T(initial);
|
||||||
passed &= do_test<T>(var(i), true, true, true, true, true,
|
passed &= do_test<T>(var(i), true, true, true, true, true,
|
||||||
true, true, true, true, true,
|
true, true, true, true, true,
|
||||||
true, true, true, true, true,
|
true, true, true, true, true, true,
|
||||||
true, true, true, true, true,
|
true, true, true, true, true,
|
||||||
ispod, ispod, ispod, true, true);
|
ispod, ispod, ispod, true, true);
|
||||||
|
|
||||||
passed &= do_test<T>(const_var(i), true, true, false, true, false,
|
passed &= do_test<T>(const_var(i), true, true, false, true, false,
|
||||||
true, false, true, false, true,
|
true, false, true, false, true,
|
||||||
false, true, false, true, false,
|
false, false, true, false, true, false,
|
||||||
true, false, true, false, true,
|
true, false, true, false, true,
|
||||||
ispod, ispod, ispod, false, true);
|
ispod, ispod, ispod, false, true);
|
||||||
|
|
||||||
passed &= do_test<T>(var(&i), true, true, true, true, true,
|
passed &= do_test<T>(var(&i), true, true, true, true, true,
|
||||||
true, true, true, false, false,
|
true, true, true, false, false,
|
||||||
false, false, false, false, true,
|
false, false, false, false, false, true,
|
||||||
true, true, true, true, true,
|
true, true, true, true, true,
|
||||||
ispod, ispod, ispod, true, true);
|
ispod, ispod, ispod, true, true);
|
||||||
|
|
||||||
passed &= do_test<T>(const_var(&i), true, true, false, true, false,
|
passed &= do_test<T>(const_var(&i), true, true, false, true, false,
|
||||||
true, false, true, false, false,
|
true, false, true, false, false,
|
||||||
false, false, false, false, false,
|
false, false, false, false, false, false,
|
||||||
true, false, true, false, true,
|
true, false, true, false, true,
|
||||||
ispod, ispod, ispod, false, true);
|
ispod, ispod, ispod, false, true);
|
||||||
|
|
||||||
passed &= do_test<T>(var(std::ref(i)), true, true, true, true, true,
|
passed &= do_test<T>(var(std::ref(i)), true, true, true, true, true,
|
||||||
true, true, true, false, false,
|
true, true, true, false, false,
|
||||||
false, false, false, false, true,
|
false, false, false, false, false, true,
|
||||||
true, true, true, true, true,
|
true, true, true, true, true,
|
||||||
ispod, ispod, ispod, true, true);
|
ispod, ispod, ispod, true, true);
|
||||||
|
|
||||||
passed &= do_test<T>(var(std::cref(i)), true, true, false, true, false,
|
passed &= do_test<T>(var(std::cref(i)), true, true, false, true, false,
|
||||||
true, false, true, false, false,
|
true, false, true, false, false,
|
||||||
false, false, false, false, false,
|
false, false, false, false, false, false,
|
||||||
true, false, true, false, true,
|
true, false, true, false, true,
|
||||||
ispod, ispod, ispod, false, true);
|
ispod, ispod, ispod, false, true);
|
||||||
|
|
||||||
@ -156,33 +157,33 @@ bool built_in_type_test(const T &initial, bool ispod)
|
|||||||
|
|
||||||
passed &= do_test<T>(var(i), true, true, true, true, true,
|
passed &= do_test<T>(var(i), true, true, true, true, true,
|
||||||
true, true, true, true, true,
|
true, true, true, true, true,
|
||||||
true, true, true, true, true,
|
true, true, true, true, true, true,
|
||||||
true, true, true, true, true,
|
true, true, true, true, true,
|
||||||
ispod, ispod, ispod, true, true);
|
ispod, ispod, ispod, true, true);
|
||||||
|
|
||||||
// But a pointer or reference to it should be necessarily const
|
// But a pointer or reference to it should be necessarily const
|
||||||
passed &= do_test<T>(var(&ir), true, true, false, true, false,
|
passed &= do_test<T>(var(&ir), true, true, false, true, false,
|
||||||
true, false, true, false, false,
|
true, false, true, false, false,
|
||||||
false, false, false, false, false,
|
false, false, false, false, false, false,
|
||||||
true, false, true, false, true,
|
true, false, true, false, true,
|
||||||
ispod, ispod, ispod, false, true);
|
ispod, ispod, ispod, false, true);
|
||||||
|
|
||||||
passed &= do_test<T>(var(std::ref(ir)), true, true, false, true, false,
|
passed &= do_test<T>(var(std::ref(ir)), true, true, false, true, false,
|
||||||
true, false, true, false, false,
|
true, false, true, false, false,
|
||||||
false, false, false, false, false,
|
false, false, false, false, false, false,
|
||||||
true, false, true, false, true,
|
true, false, true, false, true,
|
||||||
ispod, ispod, ispod, false, true);
|
ispod, ispod, ispod, false, true);
|
||||||
|
|
||||||
// Make sure const of const works too
|
// Make sure const of const works too
|
||||||
passed &= do_test<T>(const_var(&ir), true, true, false, true, false,
|
passed &= do_test<T>(const_var(&ir), true, true, false, true, false,
|
||||||
true, false, true, false, false,
|
true, false, true, false, false,
|
||||||
false, false, false, false, false,
|
false, false, false, false, false, false,
|
||||||
true, false, true, false, true,
|
true, false, true, false, true,
|
||||||
ispod, ispod, ispod, false, true);
|
ispod, ispod, ispod, false, true);
|
||||||
|
|
||||||
passed &= do_test<T>(const_var(std::ref(ir)), true, true, false, true, false,
|
passed &= do_test<T>(const_var(std::ref(ir)), true, true, false, true, false,
|
||||||
true, false, true, false, false,
|
true, false, true, false, false,
|
||||||
false, false, false, false, false,
|
false, false, false, false, false, false,
|
||||||
true, false, true, false, true,
|
true, false, true, false, true,
|
||||||
ispod, ispod, ispod, false, true);
|
ispod, ispod, ispod, false, true);
|
||||||
|
|
||||||
@ -192,14 +193,14 @@ bool built_in_type_test(const T &initial, bool ispod)
|
|||||||
const T*cip = &i;
|
const T*cip = &i;
|
||||||
passed &= do_test<T>(var(cip), true, true, false, true, false,
|
passed &= do_test<T>(var(cip), true, true, false, true, false,
|
||||||
true, false, true, false, false,
|
true, false, true, false, false,
|
||||||
false, false, false, false, false,
|
false, false, false, false, false, false,
|
||||||
true, false, true, false, true,
|
true, false, true, false, true,
|
||||||
ispod, ispod, ispod, false, true);
|
ispod, ispod, ispod, false, true);
|
||||||
|
|
||||||
// make sure const of const works
|
// make sure const of const works
|
||||||
passed &= do_test<T>(const_var(cip), true, true, false, true, false,
|
passed &= do_test<T>(const_var(cip), true, true, false, true, false,
|
||||||
true, false, true, false, false,
|
true, false, true, false, false,
|
||||||
false, false, false, false, false,
|
false, false, false, false, false, false,
|
||||||
true, false, true, false, true,
|
true, false, true, false, true,
|
||||||
ispod, ispod, ispod, false, true);
|
ispod, ispod, ispod, false, true);
|
||||||
|
|
||||||
@ -209,13 +210,13 @@ bool built_in_type_test(const T &initial, bool ispod)
|
|||||||
|
|
||||||
passed &= do_test<T>(var(ip), true, true, true, true, true,
|
passed &= do_test<T>(var(ip), true, true, true, true, true,
|
||||||
true, true, true, true, true,
|
true, true, true, true, true,
|
||||||
true, true, true, true, true,
|
true, true, true, true, true, true,
|
||||||
true, true, true, true, true,
|
true, true, true, true, true,
|
||||||
ispod, ispod, ispod, true, true);
|
ispod, ispod, ispod, true, true);
|
||||||
|
|
||||||
passed &= do_test<T>(const_var(ip), true, true, false, true, false,
|
passed &= do_test<T>(const_var(ip), true, true, false, true, false,
|
||||||
true, false, true, false, true,
|
true, false, true, false, true,
|
||||||
false, true, false, true, false,
|
false, false, true, false, true, false,
|
||||||
true, false, true, false, true,
|
true, false, true, false, true,
|
||||||
ispod, ispod, ispod, false, true);
|
ispod, ispod, ispod, false, true);
|
||||||
|
|
||||||
@ -224,14 +225,14 @@ bool built_in_type_test(const T &initial, bool ispod)
|
|||||||
|
|
||||||
passed &= do_test<T>(var(ipc), true, true, false, true, false,
|
passed &= do_test<T>(var(ipc), true, true, false, true, false,
|
||||||
true, false, true, false, true,
|
true, false, true, false, true,
|
||||||
false, true, false, true, false,
|
false, false, true, false, true, false,
|
||||||
true, false, true, false, true,
|
true, false, true, false, true,
|
||||||
ispod, ispod, ispod, false, true);
|
ispod, ispod, ispod, false, true);
|
||||||
|
|
||||||
// const of this should be the same, making sure it compiles
|
// const of this should be the same, making sure it compiles
|
||||||
passed &= do_test<T>(const_var(ipc), true, true, false, true, false,
|
passed &= do_test<T>(const_var(ipc), true, true, false, true, false,
|
||||||
true, false, true, false, true,
|
true, false, true, false, true,
|
||||||
false, true, false, true, false,
|
false, false, true, false, true, false,
|
||||||
true, false, true, false, true,
|
true, false, true, false, true,
|
||||||
ispod, ispod, ispod, false, true);
|
ispod, ispod, ispod, false, true);
|
||||||
|
|
||||||
|
25
unittests/shared_ptr_update.chai
Normal file
25
unittests/shared_ptr_update.chai
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
load_module("test_module")
|
||||||
|
|
||||||
|
auto o := null_factory();
|
||||||
|
|
||||||
|
assert_true(o.is_var_null());
|
||||||
|
|
||||||
|
update_shared_ptr(o);
|
||||||
|
|
||||||
|
assert_false(o.is_var_null());
|
||||||
|
assert_true(o.base_only_func() == -9);
|
||||||
|
|
||||||
|
nullify_shared_ptr(o);
|
||||||
|
o.nullify_shared_ptr();
|
||||||
|
|
||||||
|
assert_true(o.is_var_null());
|
||||||
|
|
||||||
|
try {
|
||||||
|
o.func();
|
||||||
|
} catch (e) {
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_true(false);
|
||||||
|
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user