#include using namespace chaiscript; template void use(T) { } template bool run_test_type_conversion(const Boxed_Value &bv, bool expectedpass) { try { To ret = chaiscript::boxed_cast(bv); use(ret); } catch (const chaiscript::exception::bad_boxed_cast &e) { if (expectedpass) { std::cerr << "Failure in run_test_type_conversion: " << e.what() << '\n'; return false; } return true; } catch (const std::exception &e) { std::cerr << "Unexpected standard exception when attempting cast_conversion: " << e.what() << '\n'; return false; } catch (...) { std::cerr << "Unexpected unknown exception when attempting cast_conversion.\n"; return false; } return expectedpass; } template bool test_type_conversion(const Boxed_Value &bv, bool expectedpass) { bool ret = run_test_type_conversion(bv, expectedpass); if (!ret) { std::cerr << "Error with type conversion test. From: " << (bv.is_const() ? "const " : "") << bv.get_type_info().name() << " To: " << (std::is_const::value ? "const " : "") << typeid(To).name() << " test was expected to " << (expectedpass ? "succeed" : "fail") << " but did not\n"; } return ret; } template bool do_test(const Boxed_Value &bv, bool T, bool ConstT, bool TRef, bool ConstTRef, bool TPtr, bool ConstTPtr, bool TPtrConst, bool ConstTPtrConst, bool SharedPtrT, bool SharedConstPtrT, bool SharedPtrTRef, bool ConstSharedPtrT, bool ConstSharedConstPtrT, bool ConstSharedPtrTRef, bool ConstSharedPtrTConstRef, bool WrappedRef, bool WrappedConstRef, bool ConstWrappedRef, bool ConstWrappedConstRef, bool ConstWrappedRefRef, bool ConstWrappedConstRefRef, bool Number, bool ConstNumber, bool ConstNumberRef, bool TPtrConstRef, bool ConstTPtrConstRef) { bool passed = true; passed &= test_type_conversion(bv, T); passed &= test_type_conversion(bv, ConstT); passed &= test_type_conversion(bv, TRef); passed &= test_type_conversion(bv, ConstTRef); passed &= test_type_conversion(bv, TPtr); passed &= test_type_conversion(bv, ConstTPtr); passed &= test_type_conversion(bv, TPtrConst); passed &= test_type_conversion(bv, ConstTPtrConst); passed &= test_type_conversion>(bv, SharedPtrT); passed &= test_type_conversion>(bv, SharedConstPtrT); passed &= test_type_conversion &>(bv, SharedPtrTRef); // passed &= test_type_conversion &>(bv, false); passed &= test_type_conversion>(bv, ConstSharedPtrT); passed &= test_type_conversion>(bv, ConstSharedConstPtrT); passed &= test_type_conversion &>(bv, ConstSharedPtrTRef); passed &= test_type_conversion &>(bv, ConstSharedPtrTConstRef); passed &= test_type_conversion>(bv, WrappedRef); passed &= test_type_conversion>(bv, WrappedConstRef); passed &= test_type_conversion &>(bv, false); passed &= test_type_conversion &>(bv, false); passed &= test_type_conversion>(bv, ConstWrappedRef); passed &= test_type_conversion>(bv, ConstWrappedConstRef); passed &= test_type_conversion &>(bv, ConstWrappedRefRef); passed &= test_type_conversion &>(bv, ConstWrappedConstRefRef); passed &= test_type_conversion(bv, Number); passed &= test_type_conversion(bv, ConstNumber); passed &= test_type_conversion(bv, false); passed &= test_type_conversion(bv, ConstNumberRef); passed &= test_type_conversion(bv, false); passed &= test_type_conversion(bv, false); passed &= test_type_conversion(bv, false); passed &= test_type_conversion(bv, false); passed &= test_type_conversion(bv, false); passed &= test_type_conversion(bv, false); passed &= test_type_conversion(bv, TPtrConstRef); passed &= test_type_conversion(bv, ConstTPtrConstRef); passed &= test_type_conversion(bv, true); passed &= test_type_conversion(bv, true); passed &= test_type_conversion(bv, true); return passed; } /** Tests intended for built int types **/ template bool built_in_type_test(const T &initial, bool ispod) { bool passed = true; /** value tests **/ T i = T(initial); passed &= do_test(var(i), 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); passed &= do_test(const_var(i), true, true, false, true, false, true, false, true, false, true, false, false, true, false, true, false, true, false, true, false, true, ispod, ispod, ispod, false, true); passed &= do_test(var(&i), true, true, true, true, true, true, true, true, false, false, false, false, false, false, false, true, true, true, true, true, true, ispod, ispod, ispod, true, true); passed &= do_test(const_var(&i), true, true, false, true, false, true, false, true, false, false, false, false, false, false, false, false, true, false, true, false, true, ispod, ispod, ispod, false, true); passed &= do_test(var(std::ref(i)), true, true, true, true, true, true, true, true, false, false, false, false, false, false, false, true, true, true, true, true, true, ispod, ispod, ispod, true, true); passed &= do_test(var(std::cref(i)), true, true, false, true, false, true, false, true, false, false, false, false, false, false, false, false, true, false, true, false, true, ispod, ispod, ispod, false, true); /** Const Reference Variable tests */ // This reference will be copied on input, which is expected const T &ir = i; passed &= do_test(var(i), 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); // But a pointer or reference to it should be necessarily const passed &= do_test(var(&ir), true, true, false, true, false, true, false, true, false, false, false, false, false, false, false, false, true, false, true, false, true, ispod, ispod, ispod, false, true); passed &= do_test(var(std::ref(ir)), true, true, false, true, false, true, false, true, false, false, false, false, false, false, false, false, true, false, true, false, true, ispod, ispod, ispod, false, true); // Make sure const of const works too passed &= do_test(const_var(&ir), true, true, false, true, false, true, false, true, false, false, false, false, false, false, false, false, true, false, true, false, true, ispod, ispod, ispod, false, true); passed &= do_test(const_var(std::ref(ir)), true, true, false, true, false, true, false, true, false, false, false, false, false, false, false, false, true, false, true, false, true, ispod, ispod, ispod, false, true); /** Const Reference Variable tests */ // This will always be seen as a const const T *cip = &i; passed &= do_test(var(cip), true, true, false, true, false, true, false, true, false, false, false, false, false, false, false, false, true, false, true, false, true, ispod, ispod, ispod, false, true); // make sure const of const works passed &= do_test(const_var(cip), true, true, false, true, false, true, false, true, false, false, false, false, false, false, false, false, true, false, true, false, true, ispod, ispod, ispod, false, true); /** shared_ptr tests **/ auto ip = std::make_shared(initial); passed &= do_test(var(ip), 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); passed &= do_test(const_var(ip), true, true, false, true, false, true, false, true, false, true, false, false, true, false, true, false, true, false, true, false, true, ispod, ispod, ispod, false, true); /** const shared_ptr tests **/ auto ipc = std::make_shared(T(initial)); passed &= do_test(var(ipc), true, true, false, true, false, true, false, true, false, true, false, false, true, false, true, false, true, false, true, false, true, ispod, ispod, ispod, false, true); // const of this should be the same, making sure it compiles passed &= do_test(const_var(ipc), true, true, false, true, false, true, false, true, false, true, false, false, true, false, true, false, true, false, true, false, true, ispod, ispod, ispod, false, true); /** Double ptr tests **/ /* T **doublep; passed &= do_test(var(doublep), true, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, ispod, ispod, ispod, false, true); */ return passed; } template bool pointer_test(const T &default_value, const T &new_value) { T *p = new T(default_value); // we store a pointer to a pointer, so we can get a pointer to a pointer try { T **result = boxed_cast(var(&p)); *(*result) = new_value; if (p != (*result)) { std::cerr << "Pointer passed in different than one returned\n"; delete p; return false; } if (*p != *(*result)) { std::cerr << "Somehow dereferenced pointer values are not the same?\n"; delete p; return false; } delete p; return true; } catch (const exception::bad_boxed_cast &) { std::cerr << "Bad boxed cast performing ** to ** test\n"; delete p; return false; } catch (...) { std::cerr << "Unknown exception performing ** to ** test\n"; delete p; return false; } } int main() { bool passed = true; /* bool T, bool ConstT, bool TRef, bool ConstTRef, bool TPtr, bool ConstTPtr, bool TPtrConst, bool ConstTPtrConst, bool SharedPtrT, bool SharedConstPtrT, bool ConstSharedPtrT, bool ConstSharedConstPtrT, bool ConstSharedPtrTRef, bool ConstSharedPtrTConstRef, bool WrappedRef, bool WrappedConstRef, bool ConstWrappedRef, bool ConstWrappedConstRef, bool ConstWrappedRefRef, bool ConstWrappedConstRefRef, bool Number, bool ConstNumber, bool ConstNumberRef */ passed &= built_in_type_test(5, true); passed &= built_in_type_test(1.1, true); passed &= built_in_type_test('a', true); passed &= built_in_type_test('a', true); passed &= built_in_type_test('a', true); passed &= built_in_type_test(false, false); passed &= built_in_type_test("Hello World", false); // storing a pointer passed &= pointer_test(1, 0); if (passed) { return EXIT_SUCCESS; } return EXIT_FAILURE; }