From b7e26b90762a696e81a0fa8e3f572b39fe49c7e8 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Sat, 20 Apr 2019 12:09:24 -0600 Subject: [PATCH 01/14] Attempt to get C++17 work compiling for VS 2019 --- .../dispatchkit/function_signature.hpp | 185 ++++++++++-------- .../dispatchkit/register_function.hpp | 2 +- 2 files changed, 104 insertions(+), 83 deletions(-) diff --git a/include/chaiscript/dispatchkit/function_signature.hpp b/include/chaiscript/dispatchkit/function_signature.hpp index 11c780a4..7c351ec2 100644 --- a/include/chaiscript/dispatchkit/function_signature.hpp +++ b/include/chaiscript/dispatchkit/function_signature.hpp @@ -4,121 +4,142 @@ #include namespace chaiscript::dispatch::detail { - template - struct Function_Params - { - }; - template - struct Function_Signature { - using Param_Types = Params; - using Return_Type = Ret; - constexpr static const bool is_object = IsObject; - constexpr static const bool is_member_object = IsMemberObject; - constexpr static const bool is_noexcept = IsNoExcept; - template - constexpr Function_Signature(T &&) noexcept {} - constexpr Function_Signature() noexcept = default; - }; +template +struct Function_Params +{ +}; - // Free functions +template +struct Function_Signature +{ + using Param_Types = Params; + using Return_Type = Ret; + constexpr static const bool is_object = IsObject; + constexpr static const bool is_member_object = IsMemberObject; + constexpr static const bool is_noexcept = IsNoExcept; + template + constexpr Function_Signature(T &&) noexcept {} + constexpr Function_Signature() noexcept = default; +}; - template - Function_Signature(Ret (*f)(Param...)) -> Function_Signature>; +// Free functions - template - Function_Signature(Ret (*f)(Param...) noexcept) -> Function_Signature, true>; +template +Function_Signature(Ret (*f)(Param...))->Function_Signature>; - // no reference specifier +template +Function_Signature(Ret (*f)(Param...) noexcept)->Function_Signature, true>; - template - Function_Signature(Ret (Class::*f)(Param ...) volatile) -> Function_Signature, false, true>; +// no reference specifier - template - Function_Signature(Ret (Class::*f)(Param ...) volatile noexcept) -> Function_Signature, true, true>; +template +Function_Signature(Ret (Class::*f)(Param...) volatile)->Function_Signature, false, true>; - template - Function_Signature(Ret (Class::*f)(Param ...) volatile const) -> Function_Signature, false, true>; +template +Function_Signature(Ret (Class::*f)(Param...) volatile noexcept)->Function_Signature, true, true>; - template - Function_Signature(Ret (Class::*f)(Param ...) volatile const noexcept) -> Function_Signature, true, true>; +template +Function_Signature(Ret (Class::*f)(Param...) volatile const)->Function_Signature, false, true>; - template - Function_Signature(Ret (Class::*f)(Param ...) ) -> Function_Signature, false, true>; +template +Function_Signature(Ret (Class::*f)(Param...) volatile const noexcept)->Function_Signature, true, true>; - template - Function_Signature(Ret (Class::*f)(Param ...) noexcept) -> Function_Signature, true, true>; +template +Function_Signature(Ret (Class::*f)(Param...))->Function_Signature, false, true>; - template - Function_Signature(Ret (Class::*f)(Param ...) const) -> Function_Signature, false, true>; +template +Function_Signature(Ret (Class::*f)(Param...) noexcept)->Function_Signature, true, true>; - template - Function_Signature(Ret (Class::*f)(Param ...) const noexcept) -> Function_Signature, true, true>; +template +Function_Signature(Ret (Class::*f)(Param...) const)->Function_Signature, false, true>; - // & reference specifier +template +Function_Signature(Ret (Class::*f)(Param...) const noexcept)->Function_Signature, true, true>; - template - Function_Signature(Ret (Class::*f)(Param ...) volatile &) -> Function_Signature, false, true>; +// & reference specifier - template - Function_Signature(Ret (Class::*f)(Param ...) volatile & noexcept) -> Function_Signature, true, true>; +template +Function_Signature(Ret (Class::*f)(Param...) volatile &)->Function_Signature, false, true>; - template - Function_Signature(Ret (Class::*f)(Param ...) volatile const &) -> Function_Signature, false, true>; +template +Function_Signature(Ret (Class::*f)(Param...) volatile &noexcept)->Function_Signature, true, true>; - template - Function_Signature(Ret (Class::*f)(Param ...) volatile const & noexcept) -> Function_Signature, true, true>; +template +Function_Signature(Ret (Class::*f)(Param...) volatile const &)->Function_Signature, false, true>; - template - Function_Signature(Ret (Class::*f)(Param ...) & ) -> Function_Signature, false, true>; +template +Function_Signature(Ret (Class::*f)(Param...) volatile const &noexcept)->Function_Signature, true, true>; - template - Function_Signature(Ret (Class::*f)(Param ...) & noexcept) -> Function_Signature, true, true>; +template +Function_Signature(Ret (Class::*f)(Param...) &)->Function_Signature, false, true>; - template - Function_Signature(Ret (Class::*f)(Param ...) const &) -> Function_Signature, false, true>; +template +Function_Signature(Ret (Class::*f)(Param...) & noexcept)->Function_Signature, true, true>; - template - Function_Signature(Ret (Class::*f)(Param ...) const & noexcept) -> Function_Signature, true, true>; +template +Function_Signature(Ret (Class::*f)(Param...) const &)->Function_Signature, false, true>; - // && reference specifier +template +Function_Signature(Ret (Class::*f)(Param...) const &noexcept)->Function_Signature, true, true>; - template - Function_Signature(Ret (Class::*f)(Param ...) volatile &&) -> Function_Signature, false, true>; +// && reference specifier - template - Function_Signature(Ret (Class::*f)(Param ...) volatile && noexcept) -> Function_Signature, true, true>; +template +Function_Signature(Ret (Class::*f)(Param...) volatile &&)->Function_Signature, false, true>; - template - Function_Signature(Ret (Class::*f)(Param ...) volatile const &&) -> Function_Signature, false, true>; +template +Function_Signature(Ret (Class::*f)(Param...) volatile &&noexcept)->Function_Signature, true, true>; - template - Function_Signature(Ret (Class::*f)(Param ...) volatile const && noexcept) -> Function_Signature, true, true>; +template +Function_Signature(Ret (Class::*f)(Param...) volatile const &&)->Function_Signature, false, true>; - template - Function_Signature(Ret (Class::*f)(Param ...) &&) -> Function_Signature, false, true>; +template +Function_Signature(Ret (Class::*f)(Param...) volatile const &&noexcept)->Function_Signature, true, true>; - template - Function_Signature(Ret (Class::*f)(Param ...) && noexcept) -> Function_Signature, true, true>; +template +Function_Signature(Ret (Class::*f)(Param...) &&)->Function_Signature, false, true>; - template - Function_Signature(Ret (Class::*f)(Param ...) const &&) -> Function_Signature, false, true>; +template +Function_Signature(Ret (Class::*f)(Param...) && noexcept)->Function_Signature, true, true>; - template - Function_Signature(Ret (Class::*f)(Param ...) const && noexcept) -> Function_Signature, true, true>; +template +Function_Signature(Ret (Class::*f)(Param...) const &&)->Function_Signature, false, true>; - template - Function_Signature(Ret (Class::*f)) -> Function_Signature, true, true, true>; +template +Function_Signature(Ret (Class::*f)(Param...) const &&noexcept)->Function_Signature, true, true>; - template - Function_Signature(Func &&) -> Function_Signature< - typename decltype(Function_Signature{&std::decay_t::operator()})::Return_Type, - typename decltype(Function_Signature{&std::decay_t::operator()})::Param_Types, - decltype(Function_Signature{&std::decay_t::operator()})::is_noexcept, - false, - false, - true - >; +template +Function_Signature(Ret(Class::*f))->Function_Signature, true, true, true>; + +// primary template handles types that have no nested ::type member: +template> +struct has_call_operator : std::false_type +{ +}; + +// specialization recognizes types that do have a nested ::type member: +template +struct has_call_operator> : std::true_type +{ +}; + +template +auto function_signature(const Func &f) +{ + if constexpr (has_call_operator::value) { + return Function_Signature< + typename decltype(Function_Signature{ &std::decay_t::operator() })::Return_Type, + typename decltype(Function_Signature{ &std::decay_t::operator() })::Param_Types, + decltype(Function_Signature{ &std::decay_t::operator() })::is_noexcept, + false, + false, + true>{}; + } else { + return Function_Signature{ f }; + } } +}// namespace chaiscript::dispatch::detail + #endif diff --git a/include/chaiscript/dispatchkit/register_function.hpp b/include/chaiscript/dispatchkit/register_function.hpp index 907b0035..9a61bfe9 100644 --- a/include/chaiscript/dispatchkit/register_function.hpp +++ b/include/chaiscript/dispatchkit/register_function.hpp @@ -87,7 +87,7 @@ namespace chaiscript template Proxy_Function fun(T &&t) { - return dispatch::detail::make_callable(std::forward(t), dispatch::detail::Function_Signature{t}); + return dispatch::detail::make_callable(std::forward(t), dispatch::detail::function_signature(t)); } From 27072a77e6e2eb13a04840813f55033bda24dbca Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Sat, 20 Apr 2019 12:26:12 -0600 Subject: [PATCH 02/14] Get VS compiling --- include/chaiscript/chaiscript_defines.hpp | 2 +- include/chaiscript/dispatchkit/dispatchkit.hpp | 4 ++-- include/chaiscript/dispatchkit/function_params.hpp | 2 +- include/chaiscript/dispatchkit/proxy_functions.hpp | 12 ++++++------ include/chaiscript/dispatchkit/register_function.hpp | 3 ++- include/chaiscript/dispatchkit/type_conversions.hpp | 2 +- 6 files changed, 13 insertions(+), 12 deletions(-) diff --git a/include/chaiscript/chaiscript_defines.hpp b/include/chaiscript/chaiscript_defines.hpp index d5eb774a..30b8ce18 100644 --- a/include/chaiscript/chaiscript_defines.hpp +++ b/include/chaiscript/chaiscript_defines.hpp @@ -271,7 +271,7 @@ namespace chaiscript { template - [[nodiscard]] auto make_vector(T && ... t) + [[nodiscard]] auto make_vector(T &&... t) -> std::vector...>> { using container_type = std::vector...>>; diff --git a/include/chaiscript/dispatchkit/dispatchkit.hpp b/include/chaiscript/dispatchkit/dispatchkit.hpp index 3fcb38cd..c249f317 100644 --- a/include/chaiscript/dispatchkit/dispatchkit.hpp +++ b/include/chaiscript/dispatchkit/dispatchkit.hpp @@ -1303,8 +1303,8 @@ namespace chaiscript const auto lhssize = lhsparamtypes.size(); const auto rhssize = rhsparamtypes.size(); - constexpr const auto boxed_type = user_type(); - constexpr const auto boxed_pod_type = user_type(); + const auto boxed_type = user_type(); + const auto boxed_pod_type = user_type(); for (size_t i = 1; i < lhssize && i < rhssize; ++i) { diff --git a/include/chaiscript/dispatchkit/function_params.hpp b/include/chaiscript/dispatchkit/function_params.hpp index 090f7004..c8afaaf8 100644 --- a/include/chaiscript/dispatchkit/function_params.hpp +++ b/include/chaiscript/dispatchkit/function_params.hpp @@ -36,7 +36,7 @@ namespace chaiscript { template constexpr explicit Function_Params(const std::array &a) - : m_begin(std::begin(a)), m_end(std::end(a)) + : m_begin(&*std::begin(a)), m_end(&*std::end(a)) { } diff --git a/include/chaiscript/dispatchkit/proxy_functions.hpp b/include/chaiscript/dispatchkit/proxy_functions.hpp index d3c751ee..1bca55c9 100644 --- a/include/chaiscript/dispatchkit/proxy_functions.hpp +++ b/include/chaiscript/dispatchkit/proxy_functions.hpp @@ -77,7 +77,7 @@ namespace chaiscript std::vector convert(Function_Params t_params, const Type_Conversions_State &t_conversions) const { auto vals = t_params.to_vector(); - constexpr auto dynamic_object_type_info = user_type(); + const auto dynamic_object_type_info = user_type(); for (size_t i = 0; i < vals.size(); ++i) { const auto &name = m_types[i].first; @@ -117,7 +117,7 @@ namespace chaiscript // second result: needs conversions std::pair match(const Function_Params &vals, const Type_Conversions_State &t_conversions) const noexcept { - constexpr auto dynamic_object_type_info = user_type(); + const auto dynamic_object_type_info = user_type(); bool needs_conversion = false; if (!m_has_types) { return std::make_pair(true, needs_conversion); } @@ -252,9 +252,9 @@ namespace chaiscript static bool compare_type_to_param(const Type_Info &ti, const Boxed_Value &bv, const Type_Conversions_State &t_conversions) noexcept { - constexpr auto boxed_value_ti = user_type(); - constexpr auto boxed_number_ti = user_type(); - constexpr auto function_ti = user_type>(); + const auto boxed_value_ti = user_type(); + const auto boxed_number_ti = user_type(); + const auto function_ti = user_type>(); if (ti.is_undef() || ti.bare_equal(boxed_value_ti) @@ -757,7 +757,7 @@ namespace chaiscript { return false; } - constexpr auto class_type_info = user_type(); + const auto class_type_info = user_type(); return vals[0].get_type_info().bare_equal(class_type_info); } diff --git a/include/chaiscript/dispatchkit/register_function.hpp b/include/chaiscript/dispatchkit/register_function.hpp index 9a61bfe9..1faf59f6 100644 --- a/include/chaiscript/dispatchkit/register_function.hpp +++ b/include/chaiscript/dispatchkit/register_function.hpp @@ -34,7 +34,8 @@ namespace chaiscript // we now that the Param pack will have only one element, so we are safe expanding it here return Proxy_Function(chaiscript::make_shared...>>(std::forward(func))); } else if constexpr (Is_Member) { - auto call = [func = std::forward(func)](auto && obj, auto && ... param) noexcept(Is_Noexcept) -> decltype(auto) { + // TODO some kind of bug is preventing forwarding of this noexcept for the lambda + auto call = [func = std::forward(func)](auto && obj, auto && ... param) /* noexcept(Is_Noexcept) */ -> decltype(auto) { return (( get_first_param(Function_Params{}, obj).*func )(std::forward(param)...)); }; return Proxy_Function( diff --git a/include/chaiscript/dispatchkit/type_conversions.hpp b/include/chaiscript/dispatchkit/type_conversions.hpp index 9d07ddaa..c98cb8cb 100644 --- a/include/chaiscript/dispatchkit/type_conversions.hpp +++ b/include/chaiscript/dispatchkit/type_conversions.hpp @@ -388,7 +388,7 @@ namespace chaiscript template bool convertable_type() const noexcept { - constexpr auto type = user_type().bare_type_info(); + const auto type = user_type().bare_type_info(); return thread_cache().count(type) != 0; } From 0e243b006a0f0794ccd88fc13073bab094498c62 Mon Sep 17 00:00:00 2001 From: SG-Skril Date: Sun, 10 Nov 2019 18:07:47 +0100 Subject: [PATCH 03/14] Potential fix for issue ChaiScript#481 (bool cannot be stored in Boxed_Number) --- include/chaiscript/dispatchkit/function_call_detail.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/chaiscript/dispatchkit/function_call_detail.hpp b/include/chaiscript/dispatchkit/function_call_detail.hpp index 6071898b..250aa42f 100644 --- a/include/chaiscript/dispatchkit/function_call_detail.hpp +++ b/include/chaiscript/dispatchkit/function_call_detail.hpp @@ -41,7 +41,7 @@ namespace chaiscript Ret call(const Function_Params ¶ms, const Type_Conversions_State &t_state) { - if constexpr (std::is_arithmetic_v) { + if constexpr (std::is_arithmetic_v && !std::is_same_v>, bool>) { return Boxed_Number(dispatch::dispatch(m_funcs, params, t_state)).get_as(); } else if constexpr (std::is_same_v) { dispatch::dispatch(m_funcs, params, t_state); From 85e4598986715233cab31360b5efe3edf25c876c Mon Sep 17 00:00:00 2001 From: Jose Rubio Date: Mon, 13 Jan 2020 16:36:32 +0100 Subject: [PATCH 04/14] =?UTF-8?q?Fix=20for=20warnings:=20by-copy=20capture?= =?UTF-8?q?=20of=20=E2=80=98this=E2=80=99=20and=20unused-local-typedefs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There are two warnings when compiling with GCC 7.4.1 or clang 5.0.1. 1. warning: explicit by-copy capture of ‘this’ redundant with by-copy capture default 2. warning: typedef ... locally defined but not used [-Wunused-local-typedefs] This change removes [2] and it compacts the lambda capture clause in [1]. --- include/chaiscript/language/chaiscript_engine.hpp | 4 ++-- include/chaiscript/language/chaiscript_eval.hpp | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/include/chaiscript/language/chaiscript_engine.hpp b/include/chaiscript/language/chaiscript_engine.hpp index d7da1257..702d5cbc 100644 --- a/include/chaiscript/language/chaiscript_engine.hpp +++ b/include/chaiscript/language/chaiscript_engine.hpp @@ -156,7 +156,7 @@ namespace chaiscript m_engine.add(fun( - [=, this](const dispatch::Proxy_Function_Base &t_fun, const std::vector &t_params) -> Boxed_Value { + [this](const dispatch::Proxy_Function_Base &t_fun, const std::vector &t_params) -> Boxed_Value { Type_Conversions_State s(this->m_engine.conversions(), this->m_engine.conversions().conversion_saves()); return t_fun(Function_Params{t_params}, s); }), "call"); @@ -168,7 +168,7 @@ namespace chaiscript m_engine.add(fun([this](const std::string &t_type_name){ return m_engine.get_type(t_type_name, true); }), "type"); m_engine.add(fun( - [=, this](const Type_Info &t_from, const Type_Info &t_to, const std::function &t_func) { + [this](const Type_Info &t_from, const Type_Info &t_to, const std::function &t_func) { m_engine.add(chaiscript::type_conversion(t_from, t_to, t_func)); } ), "add_type_conversion"); diff --git a/include/chaiscript/language/chaiscript_eval.hpp b/include/chaiscript/language/chaiscript_eval.hpp index 52110bde..d38e5aa3 100644 --- a/include/chaiscript/language/chaiscript_eval.hpp +++ b/include/chaiscript/language/chaiscript_eval.hpp @@ -331,7 +331,6 @@ namespace chaiscript Boxed_Value fn(this->children[0]->eval(t_ss)); - using ConstFunctionTypePtr = const dispatch::Proxy_Function_Base *; try { return (*t_ss->boxed_cast(fn))(Function_Params{params}, t_ss.conversions()); } From aa3c4ae797c4e3afd03387bddb3726bf7077a156 Mon Sep 17 00:00:00 2001 From: TankorSmash Date: Fri, 22 May 2020 00:24:43 -0400 Subject: [PATCH 05/14] fix typo in cheatsheet; add cpp highlighting --- cheatsheet.md | 51 ++++++++++++++++++++++++++------------------------- 1 file changed, 26 insertions(+), 25 deletions(-) diff --git a/cheatsheet.md b/cheatsheet.md index 32d1c3b5..27669a23 100644 --- a/cheatsheet.md +++ b/cheatsheet.md @@ -22,7 +22,7 @@ Note that ChaiScript cannot be used as a global / static object unless it is bei ### General -``` +```cpp chai.add(chaiscript::fun(&function_name), "function_name"); chai.add(chaiscript::fun(&Class::method_name), "method_name"); chai.add(chaiscript::fun(&Class::member_name), "member_name"); @@ -30,7 +30,7 @@ chai.add(chaiscript::fun(&Class::member_name), "member_name"); ### Bound Member Functions -``` +```cpp chai.add(chaiscript::fun(&Class::method_name, Class_instance_ptr), "method_name"); chai.add(chaiscript::fun(&Class::member_name, Class_instance_ptr), "member_name"); ``` @@ -39,18 +39,18 @@ chai.add(chaiscript::fun(&Class::member_name, Class_instance_ptr), "member_name" #### Preferred -``` +```cpp chai.add(chaiscript::fun(&function_with_overloads), "function_name"); ``` #### Alternative -``` +```cpp chai.add(chaiscript::fun(std::static_cast(&function_with_overloads)), "function_name"); ``` This overload technique is also used when exposing base member using derived type -``` +```cpp struct Base { int data; @@ -64,7 +64,7 @@ chai.add(chaiscript::fun(static_cast(&Derived::data)), "data"); ### Lambda -``` +```cpp chai.add( chaiscript::fun>( [](bool type) { @@ -75,7 +75,7 @@ chai.add( ### Constructors -``` +```cpp chai.add(chaiscript::constructor(), "MyType"); chai.add(chaiscript::constructor(), "MyType"); ``` @@ -84,7 +84,7 @@ chai.add(chaiscript::constructor(), "MyType"); It's not strictly necessary to add types, but it helps with many things. Cloning, better errors, etc. -``` +```cpp chai.add(chaiscript::user_type(), "MyClass"); ``` @@ -107,27 +107,27 @@ add_type_conversion(type("string"), type("Type_Info"), fun(s) { return type(s); Invoking a C++ type conversion possible with `static_cast` -``` +```cpp chai.add(chaiscript::type_conversion()); ``` Calling a user defined type conversion that takes a lambda -``` +```cpp chai.add(chaiscript::type_conversion([](const TestBaseType &t_bt) { /* return converted thing */ })); ``` ### Class Hierarchies -If you want objects to be convertable between base and derived classes, you must tell ChaiScritp about the relationship. +If you want objects to be convertable between base and derived classes, you must tell ChaiScript about the relationship. -``` +```cpp chai.add(chaiscript::base_class()); ``` If you have multiple classes in your inheritance graph, you will probably want to tell ChaiScript about all relationships. -``` +```cpp chai.add(chaiscript::base_class()); chai.add(chaiscript::base_class()); chai.add(chaiscript::base_class()); @@ -168,7 +168,8 @@ chai.set_global(chaiscript::var(somevar), "somevar"); // global non-const, overw Namespaces will not be populated until `import` is called. This saves memory and computing costs if a namespace is not imported into every ChaiScript instance. -``` + +```cpp chai.register_namespace([](chaiscript::Namespace& math) { math["pi"] = chaiscript::const_var(3.14159); math["sin"] = chaiscript::var(chaiscript::fun([](const double x) { return sin(x); })); }, @@ -184,7 +185,7 @@ print(math.pi) // prints 3.14159 # Using STL ChaiScript recognize many types from STL, but you have to add specific instantiation yourself. -``` +```cpp typedef std::vector> data_list; data_list my_list{ make_pair(0, "Hello"), make_pair(1, "World") }; chai.add(chaiscript::bootstrap::standard_library::vector_type("DataList")); @@ -202,7 +203,7 @@ chai.eval(R"_( ## General -``` +```cpp chai.eval("print(\"Hello World\")"); chai.eval(R"(print("Hello World"))"); ``` @@ -213,13 +214,13 @@ Returns values are of the type `Boxed_Value` which is meant to be opaque to the ### Prefered -``` +```cpp chai.eval("5.3 + 2.1"); // returns 7.4 as a C++ double ``` ### Alternative -``` +```cpp auto v = chai.eval("5.3 + 2.1"); chai.boxed_cast(v); // extracts double value from boxed_value and applies known conversions chaiscript::boxed_cast(v); // free function version, does not know about conversions @@ -227,7 +228,7 @@ chaiscript::boxed_cast(v); // free function version, does not know about ### Converting Between Algebraic Types -``` +```cpp chaiscript::Boxed_Number(chai.eval("5.3 + 2.1")).get_as(); // works with any number type // which is equivalent to, but much more automatic than: static_cast(chai.eval("5.3+2.1")); // this version only works if we know that it's a double @@ -257,7 +258,7 @@ int main() ## Sharing Values -``` +```cpp double &d = chai.eval("var i = 5.2; i"); // d is now a reference to i in the script std::shared_ptr d = chai.eval("var i = 5.2; i"); // same result but reference counted @@ -267,7 +268,7 @@ chai.eval("print(i)"); // prints 3 ## Catching Eval Errors -``` +```cpp try { chai.eval("2.3 + \"String\""); } catch (const chaiscript::exception::eval_error &e) { @@ -277,7 +278,7 @@ try { ## Catching Errors Thrown From Script -``` +```cpp try { chai.eval("throw(runtime_error(\"error\"))", chaiscript::exception_specification()); } catch (const double e) { @@ -292,19 +293,19 @@ try { ## Sharing Functions -``` +```cpp auto p = chai.eval>("to_string"); p(5); // calls chaiscript's 'to_string' function, returning std::string("5") ``` Note: backtick treats operators as normal functions -``` +```cpp auto p = chai.eval>(`+`); p(5, 6); // calls chaiscript's '+' function, returning 11 ``` -``` +```cpp auto p = chai.eval>("fun(x,y) { to_string(x) + to_string(y); }"); p(3,4.2); // evaluates the lambda function, returning the string "34.2" to C++ ``` From dd69230f197ef58541dd7e81bf5d8b82979025d5 Mon Sep 17 00:00:00 2001 From: Glen Fraser Date: Fri, 4 Sep 2020 11:27:52 +0200 Subject: [PATCH 06/14] Fix issues with Function_Params constructors (array and vector args) - code (on MSVC) was asserting due to trying to dereference invalid pointers (dereferencing the end iterator, even if only to get its address!). - when a Function_Params is constructed with an empty vector, you can't return the address of the vec.front() -- instead we use nullptr for the m_begin and m_end pointers. --- include/chaiscript/dispatchkit/function_params.hpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/include/chaiscript/dispatchkit/function_params.hpp b/include/chaiscript/dispatchkit/function_params.hpp index c8afaaf8..249c41a7 100644 --- a/include/chaiscript/dispatchkit/function_params.hpp +++ b/include/chaiscript/dispatchkit/function_params.hpp @@ -30,13 +30,19 @@ namespace chaiscript { } explicit Function_Params(const std::vector &vec) - : m_begin(&vec.front()), m_end(&vec.front() + vec.size()) + : m_begin(vec.empty() ? nullptr : &vec.front()), m_end(vec.empty() ? nullptr : &vec.front() + vec.size()) { } template constexpr explicit Function_Params(const std::array &a) - : m_begin(&*std::begin(a)), m_end(&*std::end(a)) + : m_begin(&a.front()), m_end(&a.front() + Size) + { + } + + template<> + constexpr explicit Function_Params(const std::array &a) + : m_begin(nullptr), m_end(nullptr) { } From cb9a8587b624e1953d568c0b6245696acfb116ff Mon Sep 17 00:00:00 2001 From: Glen Fraser Date: Fri, 4 Sep 2020 11:45:08 +0200 Subject: [PATCH 07/14] Remove MSVC special case in 'Object copy counts' unit test --- unittests/compiled_tests.cpp | 7 ------- 1 file changed, 7 deletions(-) diff --git a/unittests/compiled_tests.cpp b/unittests/compiled_tests.cpp index 76c31bc8..365386ad 100644 --- a/unittests/compiled_tests.cpp +++ b/unittests/compiled_tests.cpp @@ -713,15 +713,8 @@ TEST_CASE("Object copy counts") CHECK(Object_Copy_Count_Test::copycount() == 0); CHECK(Object_Copy_Count_Test::constructcount() == 1); - - -#ifdef CHAISCRIPT_MSVC - CHECK(Object_Copy_Count_Test::destructcount() == 3); - CHECK(Object_Copy_Count_Test::movecount() == 2); -#else CHECK(Object_Copy_Count_Test::destructcount() == 2); CHECK(Object_Copy_Count_Test::movecount() == 1); -#endif } From 350acbf2544882df8b0251a40b6c4e9852588993 Mon Sep 17 00:00:00 2001 From: Glen Fraser Date: Fri, 4 Sep 2020 12:57:49 +0200 Subject: [PATCH 08/14] Fix compile errors on VS2019 (C++17) with Function_Params - needed to disambiguate between chaiscript::Function_Params and chaiscript::dispatch::detail::Function_Params in several places. --- include/chaiscript/dispatchkit/function_call_detail.hpp | 6 +++--- include/chaiscript/dispatchkit/proxy_functions.hpp | 6 +++--- include/chaiscript/dispatchkit/proxy_functions_detail.hpp | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/include/chaiscript/dispatchkit/function_call_detail.hpp b/include/chaiscript/dispatchkit/function_call_detail.hpp index 6071898b..92e51d3b 100644 --- a/include/chaiscript/dispatchkit/function_call_detail.hpp +++ b/include/chaiscript/dispatchkit/function_call_detail.hpp @@ -39,7 +39,7 @@ namespace chaiscript { } - Ret call(const Function_Params ¶ms, const Type_Conversions_State &t_state) + Ret call(const chaiscript::Function_Params ¶ms, const Type_Conversions_State &t_state) { if constexpr (std::is_arithmetic_v) { return Boxed_Number(dispatch::dispatch(m_funcs, params, t_state)).get_as(); @@ -57,11 +57,11 @@ namespace chaiscript if (m_conversions) { Type_Conversions_State state(*m_conversions, m_conversions->conversion_saves()); - return call(Function_Params{params}, state); + return call(chaiscript::Function_Params{params}, state); } else { Type_Conversions conv; Type_Conversions_State state(conv, conv.conversion_saves()); - return call(Function_Params{params}, state); + return call(chaiscript::Function_Params{params}, state); } } diff --git a/include/chaiscript/dispatchkit/proxy_functions.hpp b/include/chaiscript/dispatchkit/proxy_functions.hpp index 1bca55c9..00b81f43 100644 --- a/include/chaiscript/dispatchkit/proxy_functions.hpp +++ b/include/chaiscript/dispatchkit/proxy_functions.hpp @@ -844,7 +844,7 @@ namespace chaiscript namespace detail { template - bool types_match_except_for_arithmetic(const FuncType &t_func, const Function_Params &plist, + bool types_match_except_for_arithmetic(const FuncType &t_func, const chaiscript::Function_Params &plist, const Type_Conversions_State &t_conversions) noexcept { const std::vector &types = t_func->get_param_types(); @@ -863,7 +863,7 @@ namespace chaiscript } template - Boxed_Value dispatch_with_conversions(InItr begin, const InItr &end, const Function_Params &plist, + Boxed_Value dispatch_with_conversions(InItr begin, const InItr &end, const chaiscript::Function_Params &plist, const Type_Conversions_State &t_conversions, const Funcs &t_funcs) { InItr matching_func(end); @@ -919,7 +919,7 @@ namespace chaiscript ); try { - return (*(matching_func->second))(Function_Params{newplist}, t_conversions); + return (*(matching_func->second))(chaiscript::Function_Params{newplist}, t_conversions); } catch (const exception::bad_boxed_cast &) { //parameter failed to cast } catch (const exception::arity_error &) { diff --git a/include/chaiscript/dispatchkit/proxy_functions_detail.hpp b/include/chaiscript/dispatchkit/proxy_functions_detail.hpp index 3b8a99bd..d4f7cb9e 100644 --- a/include/chaiscript/dispatchkit/proxy_functions_detail.hpp +++ b/include/chaiscript/dispatchkit/proxy_functions_detail.hpp @@ -78,7 +78,7 @@ namespace chaiscript */ template bool compare_types_cast(Ret (*)(Params...), - const Function_Params ¶ms, const Type_Conversions_State &t_conversions) noexcept + const chaiscript::Function_Params ¶ms, const Type_Conversions_State &t_conversions) noexcept { try { std::vector::size_type i = 0; @@ -93,7 +93,7 @@ namespace chaiscript template Ret call_func(Ret (*)(Params...), std::index_sequence, const Callable &f, - [[maybe_unused]] const Function_Params ¶ms, + [[maybe_unused]] const chaiscript::Function_Params ¶ms, [[maybe_unused]] const Type_Conversions_State &t_conversions) { return f(boxed_cast(params[I], &t_conversions)...); @@ -106,7 +106,7 @@ namespace chaiscript /// the bad_boxed_cast is passed up to the caller. template Boxed_Value call_func(Ret (*sig)(Params...), const Callable &f, - const Function_Params ¶ms, const Type_Conversions_State &t_conversions) + const chaiscript::Function_Params ¶ms, const Type_Conversions_State &t_conversions) { if constexpr (std::is_same_v) { call_func(sig, std::index_sequence_for{}, f, params, t_conversions); From f355d27aea3a1cd7c4e34a14e0e60835bb757653 Mon Sep 17 00:00:00 2001 From: Glen Fraser Date: Fri, 4 Sep 2020 13:52:25 +0200 Subject: [PATCH 09/14] Fix GCC build error "explicit specialization in non-namespace scope" - other compilers don't complain, but for GCC needed to move the template constructor specialization (array of size 0) outside the class declaration. --- include/chaiscript/dispatchkit/function_params.hpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/include/chaiscript/dispatchkit/function_params.hpp b/include/chaiscript/dispatchkit/function_params.hpp index 249c41a7..70873880 100644 --- a/include/chaiscript/dispatchkit/function_params.hpp +++ b/include/chaiscript/dispatchkit/function_params.hpp @@ -40,12 +40,6 @@ namespace chaiscript { { } - template<> - constexpr explicit Function_Params(const std::array &a) - : m_begin(nullptr), m_end(nullptr) - { - } - [[nodiscard]] constexpr const Boxed_Value &operator[](const std::size_t t_i) const noexcept { return m_begin[t_i]; } @@ -80,6 +74,13 @@ namespace chaiscript { }; + // Constructor specialization for array of size 0 + template<> + constexpr Function_Params::Function_Params(const std::array &a) + : m_begin(nullptr), m_end(nullptr) + { + } + } From 009b2963a8f8d2111e7b3473b980b0edac2baf48 Mon Sep 17 00:00:00 2001 From: Rabia Alhaffar Date: Tue, 8 Sep 2020 05:23:08 +0300 Subject: [PATCH 10/14] Fix typo mistake in one of for loops --- cheatsheet.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cheatsheet.md b/cheatsheet.md index 27669a23..50ee8aa4 100644 --- a/cheatsheet.md +++ b/cheatsheet.md @@ -345,7 +345,7 @@ while (some_condition()) { /* do something */ } ``` // ranged for -for (x : [1,2,3]) { print(i); } +for (i : [1, 2, 3]) { print(i); } ``` Each of the loop styles can be broken using the `break` statement. For example: From 12f034b424d312eb0780fef10324eb88c3459aa1 Mon Sep 17 00:00:00 2001 From: Glen Fraser Date: Fri, 16 Oct 2020 11:32:51 +0200 Subject: [PATCH 11/14] Change AppVeyor to use VS2019 for Windows build/testing --- appveyor.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index a5528862..5a4fe67e 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,9 +1,9 @@ version: 6.1.x.{build} image: - - Visual Studio 2017 + - Visual Studio 2019 environment: matrix: - - VS_VERSION: "Visual Studio 15" + - VS_VERSION: "Visual Studio 16" build_script: - cmd: >- mkdir build From 259f130a6006f173a91fb3fbe9f2f50e305d22c8 Mon Sep 17 00:00:00 2001 From: Glen Fraser Date: Fri, 16 Oct 2020 11:56:07 +0200 Subject: [PATCH 12/14] Fix build warnings from unused enums in switch; unused function arg --- .../chaiscript/dispatchkit/boxed_number.hpp | 28 ++++++++++++++----- .../dispatchkit/function_params.hpp | 2 +- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/include/chaiscript/dispatchkit/boxed_number.hpp b/include/chaiscript/dispatchkit/boxed_number.hpp index d133dbff..deba0bc7 100644 --- a/include/chaiscript/dispatchkit/boxed_number.hpp +++ b/include/chaiscript/dispatchkit/boxed_number.hpp @@ -185,7 +185,9 @@ namespace chaiscript return const_var(c_lhs * c_rhs); case Operators::Opers::difference: return const_var(c_lhs - c_rhs); - } + default: + break; + } if constexpr (!std::is_floating_point::value && !std::is_floating_point::value) { @@ -203,7 +205,9 @@ namespace chaiscript return const_var(c_lhs | c_rhs); case Operators::Opers::bitwise_xor: return const_var(c_lhs ^ c_rhs); - } + default: + break; + } } if (t_lhs) { @@ -224,7 +228,9 @@ namespace chaiscript case Operators::Opers::assign_difference: *t_lhs -= c_rhs; return t_bv; - } + default: + break; + } if constexpr (!std::is_floating_point::value && !std::is_floating_point::value) { switch (t_oper) { @@ -247,7 +253,9 @@ namespace chaiscript case Operators::Opers::assign_bitwise_xor: *t_lhs ^= c_rhs; return t_bv; - } + default: + break; + } } } @@ -299,7 +307,9 @@ namespace chaiscript case Operators::Opers::pre_decrement: --(*lhs); return t_lhs; - } + default: + break; + } } switch (t_oper) { @@ -307,13 +317,17 @@ namespace chaiscript return const_var(-c_lhs); case Operators::Opers::unary_plus: return const_var(+c_lhs); - } + default: + break; + } if constexpr (!std::is_floating_point_v>) { switch (t_oper) { case Operators::Opers::bitwise_complement: return const_var(~c_lhs); - } + default: + break; + } } throw chaiscript::detail::exception::bad_any_cast(); diff --git a/include/chaiscript/dispatchkit/function_params.hpp b/include/chaiscript/dispatchkit/function_params.hpp index 70873880..1430becc 100644 --- a/include/chaiscript/dispatchkit/function_params.hpp +++ b/include/chaiscript/dispatchkit/function_params.hpp @@ -76,7 +76,7 @@ namespace chaiscript { // Constructor specialization for array of size 0 template<> - constexpr Function_Params::Function_Params(const std::array &a) + constexpr Function_Params::Function_Params(const std::array & /* a */) : m_begin(nullptr), m_end(nullptr) { } From c7fcc9f7d9e4ebd11a3d193e490523665c3890b2 Mon Sep 17 00:00:00 2001 From: Rob Loach Date: Thu, 7 Jan 2021 13:15:47 -0500 Subject: [PATCH 13/14] Fix stack_vector.pop_back() pre-decrementing Fixes #547, found by @balint-luko. --- include/chaiscript/utility/stack_vector.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/chaiscript/utility/stack_vector.hpp b/include/chaiscript/utility/stack_vector.hpp index 706d276a..c72bfe6c 100644 --- a/include/chaiscript/utility/stack_vector.hpp +++ b/include/chaiscript/utility/stack_vector.hpp @@ -43,7 +43,7 @@ struct Stack_Vector }; void pop_back() noexcept(std::is_nothrow_destructible_v) { - (*this)[m_size--].~T(); + (*this)[--m_size].~T(); } ~Stack_Vector() noexcept(std::is_nothrow_destructible_v) From ab691f687da3787b44da68e39f91aa8f56ade6e0 Mon Sep 17 00:00:00 2001 From: frysch Date: Fri, 15 Jan 2021 09:14:49 +0100 Subject: [PATCH 14/14] map_conversion: copy forced for loop var `p` (incompatible ref type) The underlying pair that is dereferenced from the iterator has always `const` qualified `first` member (key type). Therefore, an unnecessary temporary was created and bounded to the const ref to the pair. This could be also fixed with `for (const auto &p : from_map)`. --- include/chaiscript/dispatchkit/type_conversions.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/chaiscript/dispatchkit/type_conversions.hpp b/include/chaiscript/dispatchkit/type_conversions.hpp index c98cb8cb..5daee88a 100644 --- a/include/chaiscript/dispatchkit/type_conversions.hpp +++ b/include/chaiscript/dispatchkit/type_conversions.hpp @@ -645,7 +645,7 @@ namespace chaiscript const std::map &from_map = detail::Cast_Helper &>::cast(t_bv, nullptr); To map; - for (const std::pair &p : from_map) { + for (const std::pair &p : from_map) { map.insert(std::make_pair(p.first, detail::Cast_Helper::cast(p.second, nullptr))); }