From bd9af5eff45e7a12e3e2b0f7abd1ba7f1d88ce26 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Fri, 14 Aug 2015 21:58:54 -0600 Subject: [PATCH 001/155] Order typed functions over untyped specifically the chaiscript defined ones --- .../chaiscript/dispatchkit/dispatchkit.hpp | 226 ++++++++++++------ .../dispatchkit/dynamic_object_detail.hpp | 32 ++- .../dispatchkit/proxy_functions.hpp | 49 +++- unittests/clone_object.chai | 38 +++ 4 files changed, 264 insertions(+), 81 deletions(-) create mode 100644 unittests/clone_object.chai diff --git a/include/chaiscript/dispatchkit/dispatchkit.hpp b/include/chaiscript/dispatchkit/dispatchkit.hpp index 43cb7b12..a7b7edac 100644 --- a/include/chaiscript/dispatchkit/dispatchkit.hpp +++ b/include/chaiscript/dispatchkit/dispatchkit.hpp @@ -732,7 +732,6 @@ namespace chaiscript /// \throws std::range_error if it does not Boxed_Value get_function_object(const std::string &t_name) const { -// std::cout << "Getting function object: " << t_name << '\n'; chaiscript::detail::threading::shared_lock l(m_mutex); const auto &funs = get_boxed_functions_int(); @@ -1026,6 +1025,13 @@ namespace chaiscript void dump_function(const std::pair &f) const { std::vector params = f.second->get_param_types(); + std::vector> typed_params; + + auto func(std::dynamic_pointer_cast(f.second)); + if (func) { + typed_params = func->get_dynamic_param_types().types(); + } + std::string annotation = f.second->annotation(); if (annotation.size() > 0) { @@ -1034,19 +1040,20 @@ namespace chaiscript dump_type(params.front()); std::cout << " " << f.first << "("; - for (std::vector::const_iterator itr = params.begin() + 1; - itr != params.end(); - ) + for (size_t i = 1; i < params.size(); ++i) { - dump_type(*itr); - ++itr; + if (!typed_params.empty() && !typed_params[i-1].first.empty()) { + std::cout << typed_params[i-1].first; + } else { + dump_type(params[i]); + } - if (itr != params.end()) - { + if (i != params.size() - 1) { std::cout << ", "; } } + std::cout << ") \n"; } @@ -1253,97 +1260,166 @@ namespace chaiscript return m_state.m_functions; } - static bool function_less_than(const Proxy_Function &lhs, const Proxy_Function &rhs) + + static std::vector param_types(const Proxy_Function &t_f) { + assert(t_f); + return t_f->get_param_types(); + } - auto dynamic_lhs(std::dynamic_pointer_cast(lhs)); - auto dynamic_rhs(std::dynamic_pointer_cast(rhs)); + static std::vector> param_types(const std::shared_ptr &t_f) + { + assert(t_f); + const auto types = t_f->get_dynamic_param_types().types(); + std::vector> ret(1); + ret.insert(ret.end(), types.begin(), types.end()); + return ret; + } - if (dynamic_lhs && dynamic_rhs) + static Type_Info type_info(const std::pair &t_ti) + { + return t_ti.second; + } + + static Type_Info type_info(const Type_Info &t_ti) + { + return t_ti; + } + + static std::string dynamic_type_name(const std::pair &t_ti) + { + return t_ti.first.empty()?t_ti.second.name():t_ti.first; + } + + static std::string dynamic_type_name(const Type_Info &ti) + { + return ti.name(); + } + + + template + static bool params_less_than(const LHS &t_lhs, const RHS &t_rhs) { - if (dynamic_lhs->get_guard()) - { - return dynamic_rhs->get_guard() ? false : true; - } else { - return false; - } - } + assert(t_lhs); + assert(t_rhs); + const auto lhsparamtypes = param_types(t_lhs); + const auto rhsparamtypes = param_types(t_rhs); - if (dynamic_lhs && !dynamic_rhs) - { - return false; - } - - if (!dynamic_lhs && dynamic_rhs) - { - return true; - } - - const auto &lhsparamtypes = lhs->get_param_types(); - const auto &rhsparamtypes = rhs->get_param_types(); - - const auto lhssize = lhsparamtypes.size(); - const auto rhssize = rhsparamtypes.size(); + const auto lhssize = lhsparamtypes.size(); + const auto rhssize = rhsparamtypes.size(); #ifdef CHAISCRIPT_HAS_MAGIC_STATICS - static auto boxed_type = user_type(); - static auto boxed_pod_type = user_type(); + static auto boxed_type = user_type(); + static auto boxed_pod_type = user_type(); + static auto dynamic_type = user_type(); #else - auto boxed_type = user_type(); - auto boxed_pod_type = user_type(); + auto boxed_type = user_type(); + auto boxed_pod_type = user_type(); + auto dynamic_type = user_type(); #endif - for (size_t i = 1; i < lhssize && i < rhssize; ++i) - { - const Type_Info < = lhsparamtypes[i]; - const Type_Info &rt = rhsparamtypes[i]; - - if (lt.bare_equal(rt) && lt.is_const() == rt.is_const()) + for (size_t i = 1; i < lhssize && i < rhssize; ++i) { - continue; // The first two types are essentially the same, next iteration - } + const Type_Info lt = type_info(lhsparamtypes[i]); + const Type_Info rt = type_info(rhsparamtypes[i]); + const std::string ln = dynamic_type_name(lhsparamtypes[i]); + const std::string rn = dynamic_type_name(rhsparamtypes[i]); - // const is after non-const for the same type - if (lt.bare_equal(rt) && lt.is_const() && !rt.is_const()) - { - return false; - } + if ( (lt.bare_equal(dynamic_type) || lt.is_undef()) + && (rt.bare_equal(dynamic_type) || rt.is_undef())) + { - if (lt.bare_equal(rt) && !lt.is_const()) - { - return true; - } + if (!ln.empty() && rn.empty()) { + return true; + } else if (ln.empty() && !rn.empty()) { + return false; + } else if (!ln.empty() && !rn.empty()) { + if (ln < rn) { + return true; + } else if (rn < ln) { + return false; + } - // boxed_values are sorted last - if (lt.bare_equal(boxed_type)) - { - return false; - } + // the remaining cases are handled by the is_const rules below + } + } - if (rt.bare_equal(boxed_type)) - { - if (lt.bare_equal(boxed_pod_type)) + if (lt.bare_equal(rt) && lt.is_const() == rt.is_const()) + { + continue; // The first two types are essentially the same, next iteration + } + + // const is after non-const for the same type + if (lt.bare_equal(rt) && lt.is_const() && !rt.is_const()) + { + return false; + } + + if (lt.bare_equal(rt) && !lt.is_const()) { return true; } - return true; + + // boxed_values are sorted last + if (lt.bare_equal(boxed_type)) + { + return false; + } + + if (rt.bare_equal(boxed_type)) + { + if (lt.bare_equal(boxed_pod_type)) + { + return true; + } + return true; + } + + if (lt.bare_equal(boxed_pod_type)) + { + return false; + } + + if (rt.bare_equal(boxed_pod_type)) + { + return true; + } + + // otherwise, we want to sort by typeid + return lt < rt; } - if (lt.bare_equal(boxed_pod_type)) - { - return false; + // if everything else checks out, sort on guard + // + auto dynamic_lhs(std::dynamic_pointer_cast(t_lhs)); + auto dynamic_rhs(std::dynamic_pointer_cast(t_rhs)); + + if (dynamic_lhs && dynamic_rhs) { + if (dynamic_lhs->get_guard() && !dynamic_rhs->get_guard()) { + return true; + } else if (dynamic_rhs->get_guard()) { + return false; + } } - if (rt.bare_equal(boxed_pod_type)) - { - return true; - } - - // otherwise, we want to sort by typeid - return lt < rt; + return false; } - return false; + static bool function_less_than(const Proxy_Function &lhs, const Proxy_Function &rhs) + { + auto dynamic_lhs(std::dynamic_pointer_cast(lhs)); + auto dynamic_rhs(std::dynamic_pointer_cast(rhs)); + + if (dynamic_lhs && dynamic_rhs) + { + return params_less_than(dynamic_lhs, dynamic_rhs); + } else if (dynamic_lhs) { + return params_less_than(dynamic_lhs, rhs); + } else if (dynamic_rhs) { + return params_less_than(lhs, dynamic_rhs); + } else { + return params_less_than(lhs, rhs); + } } diff --git a/include/chaiscript/dispatchkit/dynamic_object_detail.hpp b/include/chaiscript/dispatchkit/dynamic_object_detail.hpp index 9d501aed..710c927f 100644 --- a/include/chaiscript/dispatchkit/dynamic_object_detail.hpp +++ b/include/chaiscript/dispatchkit/dynamic_object_detail.hpp @@ -39,7 +39,8 @@ namespace chaiscript /// A Proxy_Function implementation designed for calling a function /// that is automatically guarded based on the first param based on the /// param's type name - class Dynamic_Object_Function : public Proxy_Function_Base + class Dynamic_Object_Function : public Proxy_Function_Base, public Dynamic_Function_Interface + { public: Dynamic_Object_Function( @@ -72,6 +73,17 @@ namespace chaiscript Dynamic_Object_Function &operator=(const Dynamic_Object_Function) = delete; Dynamic_Object_Function(Dynamic_Object_Function &) = delete; + virtual Param_Types get_dynamic_param_types() const { + auto dynamic(std::dynamic_pointer_cast(m_func)); + + if (dynamic) { + return dynamic->get_dynamic_param_types(); + } else { + return Param_Types(get_param_types()); + } + } + + virtual bool operator==(const Proxy_Function_Base &f) const CHAISCRIPT_OVERRIDE { if (const auto *df = dynamic_cast(&f)) @@ -182,7 +194,7 @@ namespace chaiscript * that is automatically guarded based on the first param based on the * param's type name */ - class Dynamic_Object_Constructor : public Proxy_Function_Base + class Dynamic_Object_Constructor : public Proxy_Function_Base, public Dynamic_Function_Interface { public: Dynamic_Object_Constructor( @@ -191,6 +203,7 @@ namespace chaiscript : Proxy_Function_Base(build_type_list(t_func->get_param_types()), t_func->get_arity() - 1), m_type_name(std::move(t_type_name)), m_func(t_func) { + assert( t_func ); assert( (t_func->get_arity() > 0 || t_func->get_arity() < 0) && "Programming error, Dynamic_Object_Function must have at least one parameter (this)"); } @@ -210,6 +223,17 @@ namespace chaiscript virtual ~Dynamic_Object_Constructor() {} + virtual Param_Types get_dynamic_param_types() const { + auto dynamic(std::dynamic_pointer_cast(m_func)); + + if (dynamic) { + return dynamic->get_dynamic_param_types(); + } else { + return Param_Types(get_param_types()); + } + } + + virtual bool operator==(const Proxy_Function_Base &f) const CHAISCRIPT_OVERRIDE { const Dynamic_Object_Constructor *dc = dynamic_cast(&f); @@ -222,7 +246,7 @@ namespace chaiscript new_vals.insert(new_vals.end(), vals.begin(), vals.end()); return m_func->call_match(new_vals, t_conversions); - } + } virtual std::string annotation() const CHAISCRIPT_OVERRIDE { @@ -232,7 +256,7 @@ namespace chaiscript protected: virtual Boxed_Value do_call(const std::vector ¶ms, const Type_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE { - auto bv = var(Dynamic_Object(m_type_name)); + auto bv = Boxed_Value(Dynamic_Object(m_type_name), true); std::vector new_params{bv}; new_params.insert(new_params.end(), params.begin(), params.end()); diff --git a/include/chaiscript/dispatchkit/proxy_functions.hpp b/include/chaiscript/dispatchkit/proxy_functions.hpp index 156831f7..940468e4 100644 --- a/include/chaiscript/dispatchkit/proxy_functions.hpp +++ b/include/chaiscript/dispatchkit/proxy_functions.hpp @@ -53,6 +53,13 @@ namespace chaiscript m_doti(user_type()) {} + Param_Types(const std::vector &t_types) + : m_types(build_param_types(t_types)), + m_has_types(false), + m_doti(user_type()) + { + } + Param_Types(std::vector> t_types) : m_types(std::move(t_types)), m_has_types(false), @@ -61,6 +68,18 @@ namespace chaiscript update_has_types(); } + static std::vector> build_param_types(const std::vector &t_types) + { + std::vector> retval; + std::transform(t_types.begin(), t_types.end(), std::back_inserter(retval), + [](const Type_Info &ti){ + return std::make_pair(std::string(), ti); + } + ); + + return retval; + } + void push_front(std::string t_name, Type_Info t_ti) { m_types.emplace(m_types.begin(), std::move(t_name), std::move(t_ti)); @@ -295,11 +314,18 @@ namespace chaiscript namespace dispatch { + class Dynamic_Function_Interface + { + public: + virtual ~Dynamic_Function_Interface() {} + virtual Param_Types get_dynamic_param_types() const = 0; + }; + /** * A Proxy_Function implementation that is not type safe, the called function * is expecting a vector that it works with how it chooses. */ - class Dynamic_Proxy_Function : public Proxy_Function_Base + class Dynamic_Proxy_Function : public Proxy_Function_Base, public Dynamic_Function_Interface { public: Dynamic_Proxy_Function( @@ -349,6 +375,9 @@ namespace chaiscript return m_description; } + virtual Param_Types get_dynamic_param_types() const { + return m_param_types; + } protected: bool test_guard(const std::vector ¶ms, const Type_Conversions &t_conversions) const @@ -367,6 +396,8 @@ namespace chaiscript } } + + private: static std::vector build_param_type_list(const Param_Types &t_types) { @@ -678,6 +709,8 @@ namespace chaiscript std::reference_wrapper> m_f; std::shared_ptr> m_shared_ptr_holder; }; + + /// Attribute getter Proxy_Function implementation template class Attribute_Access : public Proxy_Function_Base @@ -875,6 +908,15 @@ namespace chaiscript std::vector> ordered_funcs; ordered_funcs.reserve(funcs.size()); +#ifdef CHAISCRIPT_HAS_MAGIC_STATICS + static auto boxed_type = user_type(); + static auto dynamic_type = user_type(); +#else + auto boxed_type = user_type(); + auto dynamic_type = user_type(); +#endif + + for (const auto &func : funcs) { const auto arity = func->get_arity(); @@ -886,7 +928,10 @@ namespace chaiscript size_t numdiffs = 0; for (size_t i = 0; i < plist.size(); ++i) { - if (!func->get_param_types()[i+1].bare_equal(plist[i].get_type_info())) + const auto &p_type = plist[i].get_type_info(); + const auto &f_type = func->get_param_types()[i+1]; + + if (!(f_type.bare_equal(boxed_type) && p_type.bare_equal(dynamic_type)) && !f_type.bare_equal(p_type)) { ++numdiffs; } diff --git a/unittests/clone_object.chai b/unittests/clone_object.chai new file mode 100644 index 00000000..78c38a29 --- /dev/null +++ b/unittests/clone_object.chai @@ -0,0 +1,38 @@ +GLOBAL clone_count = 0; + +class Cloneable +{ + def Cloneable() { + } + +} + + +def clone(Cloneable c) +{ + print("Clone called"); + ++clone_count; + return c; +} + + +class MyObject +{ + def MyObject() { + this.data = Cloneable(); + } + + var data; +} + + +assert_equal(0, clone_count); + +var o = MyObject(); + +assert_equal(0, clone_count); + +var p = o; + +assert_equal(1, clone_count); + From 818fd0b8234b2b492182f182cb2af77352029498 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Wed, 26 Aug 2015 18:47:32 -0600 Subject: [PATCH 002/155] Add function ordering test --- unittests/compiled_tests.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/unittests/compiled_tests.cpp b/unittests/compiled_tests.cpp index 9e344ccd..1a859745 100644 --- a/unittests/compiled_tests.cpp +++ b/unittests/compiled_tests.cpp @@ -317,7 +317,8 @@ TEST_CASE("Function ordering") chaiscript::ChaiScript chai; chai.eval("def test_fun(x) { return 3; }"); chai.eval("def test_fun(x) : x == \"hi\" { return 4; }"); -// chai.eval("def test_fun(x) { return 5; }"); + chai.eval("def test_fun(double d) { return 5; }"); + chai.add(chaiscript::fun(&function_ordering_test_one), "test_fun"); chai.add(chaiscript::fun(&function_ordering_test_two), "test_fun"); @@ -325,6 +326,7 @@ TEST_CASE("Function ordering") CHECK(chai.eval("auto i = 1; test_fun(i)") == 2); CHECK(chai.eval("test_fun(\"bob\")") == 3); CHECK(chai.eval("test_fun(\"hi\")") == 4); + CHECK(chai.eval("test_fun(5.0)") == 5); } From ef333e491ad5f74b4a10e0208793d1bf9c7c5f35 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Thu, 20 Jul 2017 21:16:54 -0600 Subject: [PATCH 003/155] remove existing `constexpr` --- .../chaiscript/dispatchkit/boxed_number.hpp | 2 +- include/chaiscript/dispatchkit/type_info.hpp | 46 +++++++++---------- .../chaiscript/language/chaiscript_parser.hpp | 2 +- include/chaiscript/utility/static_string.hpp | 6 +-- 4 files changed, 28 insertions(+), 28 deletions(-) diff --git a/include/chaiscript/dispatchkit/boxed_number.hpp b/include/chaiscript/dispatchkit/boxed_number.hpp index 8f1e871f..8b46f43c 100644 --- a/include/chaiscript/dispatchkit/boxed_number.hpp +++ b/include/chaiscript/dispatchkit/boxed_number.hpp @@ -94,7 +94,7 @@ namespace chaiscript { } - static constexpr Common_Types get_common_type(size_t t_size, bool t_signed) + static Common_Types get_common_type(size_t t_size, bool t_signed) { return (t_size == 1 && t_signed)?(Common_Types::t_int8) :(t_size == 1)?(Common_Types::t_uint8) diff --git a/include/chaiscript/dispatchkit/type_info.hpp b/include/chaiscript/dispatchkit/type_info.hpp index 4e508474..4480f3c7 100644 --- a/include/chaiscript/dispatchkit/type_info.hpp +++ b/include/chaiscript/dispatchkit/type_info.hpp @@ -33,7 +33,7 @@ namespace chaiscript class Type_Info { public: - constexpr Type_Info(const bool t_is_const, const bool t_is_reference, const bool t_is_pointer, const bool t_is_void, + Type_Info(const bool t_is_const, const bool t_is_reference, const bool t_is_pointer, const bool t_is_void, const bool t_is_arithmetic, const std::type_info *t_ti, const std::type_info *t_bare_ti) : m_type_info(t_ti), m_bare_type_info(t_bare_ti), m_flags((static_cast(t_is_const) << is_const_flag) @@ -44,51 +44,51 @@ namespace chaiscript { } - constexpr Type_Info() = default; + Type_Info() = default; - constexpr bool operator<(const Type_Info &ti) const noexcept + bool operator<(const Type_Info &ti) const noexcept { return m_type_info < ti.m_type_info; } - constexpr bool operator!=(const Type_Info &ti) const noexcept + bool operator!=(const Type_Info &ti) const noexcept { return !(operator==(ti)); } - constexpr bool operator!=(const std::type_info &ti) const noexcept + bool operator!=(const std::type_info &ti) const noexcept { return !(operator==(ti)); } - constexpr bool operator==(const Type_Info &ti) const noexcept + bool operator==(const Type_Info &ti) const noexcept { return ti.m_type_info == m_type_info || *ti.m_type_info == *m_type_info; } - constexpr bool operator==(const std::type_info &ti) const noexcept + bool operator==(const std::type_info &ti) const noexcept { return !is_undef() && (*m_type_info) == ti; } - constexpr bool bare_equal(const Type_Info &ti) const noexcept + bool bare_equal(const Type_Info &ti) const noexcept { return ti.m_bare_type_info == m_bare_type_info || *ti.m_bare_type_info == *m_bare_type_info; } - constexpr bool bare_equal_type_info(const std::type_info &ti) const noexcept + bool bare_equal_type_info(const std::type_info &ti) const noexcept { return !is_undef() && (*m_bare_type_info) == ti; } - constexpr bool is_const() const noexcept { return (m_flags & (1 << is_const_flag)) != 0; } - constexpr bool is_reference() const noexcept { return (m_flags & (1 << is_reference_flag)) != 0; } - constexpr bool is_void() const noexcept { return (m_flags & (1 << is_void_flag)) != 0; } - constexpr bool is_arithmetic() const noexcept { return (m_flags & (1 << is_arithmetic_flag)) != 0; } - constexpr bool is_undef() const noexcept { return (m_flags & (1 << is_undef_flag)) != 0; } - constexpr bool is_pointer() const noexcept { return (m_flags & (1 << is_pointer_flag)) != 0; } + bool is_const() const noexcept { return (m_flags & (1 << is_const_flag)) != 0; } + bool is_reference() const noexcept { return (m_flags & (1 << is_reference_flag)) != 0; } + bool is_void() const noexcept { return (m_flags & (1 << is_void_flag)) != 0; } + bool is_arithmetic() const noexcept { return (m_flags & (1 << is_arithmetic_flag)) != 0; } + bool is_undef() const noexcept { return (m_flags & (1 << is_undef_flag)) != 0; } + bool is_pointer() const noexcept { return (m_flags & (1 << is_pointer_flag)) != 0; } std::string name() const { @@ -110,7 +110,7 @@ namespace chaiscript } } - constexpr const std::type_info *bare_type_info() const + const std::type_info *bare_type_info() const { return m_bare_type_info; } @@ -135,7 +135,7 @@ namespace chaiscript template struct Get_Type_Info { - static constexpr Type_Info get() + static Type_Info get() { return Type_Info(std::is_const::type>::type>::value, std::is_reference::value, std::is_pointer::value, @@ -152,7 +152,7 @@ namespace chaiscript { // typedef T type; - static constexpr Type_Info get() + static Type_Info get() { return Type_Info(std::is_const::value, std::is_reference::value, std::is_pointer::value, std::is_void::value, @@ -170,7 +170,7 @@ namespace chaiscript template struct Get_Type_Info &> { - static constexpr Type_Info get() + static Type_Info get() { return Type_Info(std::is_const::value, std::is_reference::value, std::is_pointer::value, std::is_void::value, @@ -183,7 +183,7 @@ namespace chaiscript template struct Get_Type_Info > { - static constexpr Type_Info get() + static Type_Info get() { return Type_Info(std::is_const::value, std::is_reference::value, std::is_pointer::value, std::is_void::value, @@ -196,7 +196,7 @@ namespace chaiscript template struct Get_Type_Info &> { - static constexpr Type_Info get() + static Type_Info get() { return Type_Info(std::is_const::value, std::is_reference::value, std::is_pointer::value, std::is_void::value, @@ -218,7 +218,7 @@ namespace chaiscript /// chaiscript::Type_Info ti = chaiscript::user_type(i); /// \endcode template - constexpr Type_Info user_type(const T &/*t*/) + Type_Info user_type(const T &/*t*/) { return detail::Get_Type_Info::get(); } @@ -233,7 +233,7 @@ namespace chaiscript /// chaiscript::Type_Info ti = chaiscript::user_type(); /// \endcode template - constexpr Type_Info user_type() + Type_Info user_type() { return detail::Get_Type_Info::get(); } diff --git a/include/chaiscript/language/chaiscript_parser.hpp b/include/chaiscript/language/chaiscript_parser.hpp index 06a51dfa..8db33d02 100644 --- a/include/chaiscript/language/chaiscript_parser.hpp +++ b/include/chaiscript/language/chaiscript_parser.hpp @@ -2286,7 +2286,7 @@ namespace chaiscript bool Prefix() { const auto prev_stack_top = m_match_stack.size(); using SS = utility::Static_String; - constexpr const std::array prefix_opers{{ + const std::array prefix_opers{{ SS{"++"}, SS{"--"}, SS{"-"}, diff --git a/include/chaiscript/utility/static_string.hpp b/include/chaiscript/utility/static_string.hpp index 49edfbd8..b1be2211 100644 --- a/include/chaiscript/utility/static_string.hpp +++ b/include/chaiscript/utility/static_string.hpp @@ -15,16 +15,16 @@ namespace chaiscript struct Static_String { template - constexpr Static_String(const char (&str)[N]) + Static_String(const char (&str)[N]) : m_size(N-1), data(&str[0]) { } - constexpr size_t size() const { + size_t size() const { return m_size; } - constexpr const char *c_str() const { + const char *c_str() const { return data; } From 755f650a8d5d2e2ab23223f976d1e4765243b24f Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Fri, 21 Jul 2017 05:44:20 -0600 Subject: [PATCH 004/155] strip `noexcept` --- .../chaiscript/dispatchkit/boxed_value.hpp | 26 +++++++++---------- include/chaiscript/dispatchkit/type_info.hpp | 26 +++++++++---------- 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/include/chaiscript/dispatchkit/boxed_value.hpp b/include/chaiscript/dispatchkit/boxed_value.hpp index ce943eb9..8938424e 100644 --- a/include/chaiscript/dispatchkit/boxed_value.hpp +++ b/include/chaiscript/dispatchkit/boxed_value.hpp @@ -221,23 +221,23 @@ namespace chaiscript return *this; } - const Type_Info &get_type_info() const noexcept + const Type_Info &get_type_info() const { return m_data->m_type_info; } /// return true if the object is uninitialized - bool is_undef() const noexcept + bool is_undef() const { return m_data->m_type_info.is_undef(); } - bool is_const() const noexcept + bool is_const() const { return m_data->m_type_info.is_const(); } - bool is_type(const Type_Info &ti) const noexcept + bool is_type(const Type_Info &ti) const { return m_data->m_type_info.bare_equal(ti); } @@ -278,42 +278,42 @@ namespace chaiscript return Sentinel(ptr, *(m_data.get())); } - bool is_null() const noexcept + bool is_null() const { return (m_data->m_data_ptr == nullptr && m_data->m_const_data_ptr == nullptr); } - const chaiscript::detail::Any & get() const noexcept + const chaiscript::detail::Any & get() const { return m_data->m_obj; } - bool is_ref() const noexcept + bool is_ref() const { return m_data->m_is_ref; } - bool is_return_value() const noexcept + bool is_return_value() const { return m_data->m_return_value; } - void reset_return_value() const noexcept + void reset_return_value() const { m_data->m_return_value = false; } - bool is_pointer() const noexcept + bool is_pointer() const { return !is_ref(); } - void *get_ptr() const noexcept + void *get_ptr() const { return m_data->m_data_ptr; } - const void *get_const_ptr() const noexcept + const void *get_const_ptr() const { return m_data->m_const_data_ptr; } @@ -353,7 +353,7 @@ namespace chaiscript /// \returns true if the two Boxed_Values share the same internal type - static bool type_match(const Boxed_Value &l, const Boxed_Value &r) noexcept + static bool type_match(const Boxed_Value &l, const Boxed_Value &r) { return l.get_type_info() == r.get_type_info(); } diff --git a/include/chaiscript/dispatchkit/type_info.hpp b/include/chaiscript/dispatchkit/type_info.hpp index 4480f3c7..ba377d21 100644 --- a/include/chaiscript/dispatchkit/type_info.hpp +++ b/include/chaiscript/dispatchkit/type_info.hpp @@ -46,49 +46,49 @@ namespace chaiscript Type_Info() = default; - bool operator<(const Type_Info &ti) const noexcept + bool operator<(const Type_Info &ti) const { return m_type_info < ti.m_type_info; } - bool operator!=(const Type_Info &ti) const noexcept + bool operator!=(const Type_Info &ti) const { return !(operator==(ti)); } - bool operator!=(const std::type_info &ti) const noexcept + bool operator!=(const std::type_info &ti) const { return !(operator==(ti)); } - bool operator==(const Type_Info &ti) const noexcept + bool operator==(const Type_Info &ti) const { return ti.m_type_info == m_type_info || *ti.m_type_info == *m_type_info; } - bool operator==(const std::type_info &ti) const noexcept + bool operator==(const std::type_info &ti) const { return !is_undef() && (*m_type_info) == ti; } - bool bare_equal(const Type_Info &ti) const noexcept + bool bare_equal(const Type_Info &ti) const { return ti.m_bare_type_info == m_bare_type_info || *ti.m_bare_type_info == *m_bare_type_info; } - bool bare_equal_type_info(const std::type_info &ti) const noexcept + bool bare_equal_type_info(const std::type_info &ti) const { return !is_undef() && (*m_bare_type_info) == ti; } - bool is_const() const noexcept { return (m_flags & (1 << is_const_flag)) != 0; } - bool is_reference() const noexcept { return (m_flags & (1 << is_reference_flag)) != 0; } - bool is_void() const noexcept { return (m_flags & (1 << is_void_flag)) != 0; } - bool is_arithmetic() const noexcept { return (m_flags & (1 << is_arithmetic_flag)) != 0; } - bool is_undef() const noexcept { return (m_flags & (1 << is_undef_flag)) != 0; } - bool is_pointer() const noexcept { return (m_flags & (1 << is_pointer_flag)) != 0; } + bool is_const() const { return (m_flags & (1 << is_const_flag)) != 0; } + bool is_reference() const { return (m_flags & (1 << is_reference_flag)) != 0; } + bool is_void() const { return (m_flags & (1 << is_void_flag)) != 0; } + bool is_arithmetic() const { return (m_flags & (1 << is_arithmetic_flag)) != 0; } + bool is_undef() const { return (m_flags & (1 << is_undef_flag)) != 0; } + bool is_pointer() const { return (m_flags & (1 << is_pointer_flag)) != 0; } std::string name() const { From f20cdc7c8f14956844238499f12186fee23b02f3 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Fri, 21 Jul 2017 05:59:45 -0600 Subject: [PATCH 005/155] fix compilation of performance tests --- performance_tests/profile_cpp_calls_2.cpp | 2 +- performance_tests/profile_fun_wrappers.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/performance_tests/profile_cpp_calls_2.cpp b/performance_tests/profile_cpp_calls_2.cpp index 0424654b..aa87fc03 100644 --- a/performance_tests/profile_cpp_calls_2.cpp +++ b/performance_tests/profile_cpp_calls_2.cpp @@ -7,7 +7,7 @@ double f(const std::string &, double, bool) noexcept { int main() { - chaiscript::ChaiScript chai(chaiscript::Std_Lib::library()); + chaiscript::ChaiScript chai; chai.add(chaiscript::fun(&f), "f"); diff --git a/performance_tests/profile_fun_wrappers.cpp b/performance_tests/profile_fun_wrappers.cpp index fb96f483..119f6929 100644 --- a/performance_tests/profile_fun_wrappers.cpp +++ b/performance_tests/profile_fun_wrappers.cpp @@ -7,7 +7,7 @@ double f(const std::string &, double, bool) noexcept { int main() { - chaiscript::ChaiScript chai(chaiscript::Std_Lib::library()); + chaiscript::ChaiScript chai; chai.add(chaiscript::fun(&f), "f"); From e07cd8865919e778079155a64dbfb3f652cf0d03 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Sat, 22 Jul 2017 20:33:30 -0600 Subject: [PATCH 006/155] Add `noexcept` where appropriate This modifies no logic, it simply adds the keyword `noexcept` I believe this is 100% correct. It calls methods that are not guaranteed to be `noexcept`, such as `operator[]` but have no logically way of throwing. --- include/chaiscript/chaiscript_defines.hpp | 14 ++--- include/chaiscript/chaiscript_threading.hpp | 20 +++---- include/chaiscript/dispatchkit/any.hpp | 12 ++-- include/chaiscript/dispatchkit/bind_first.hpp | 4 +- .../chaiscript/dispatchkit/bootstrap_stl.hpp | 2 +- .../chaiscript/dispatchkit/boxed_number.hpp | 4 +- .../chaiscript/dispatchkit/boxed_value.hpp | 30 +++++----- .../chaiscript/dispatchkit/dispatchkit.hpp | 52 ++++++++-------- .../chaiscript/dispatchkit/dynamic_object.hpp | 4 +- .../dispatchkit/dynamic_object_detail.hpp | 12 ++-- .../dispatchkit/proxy_functions.hpp | 50 ++++++++-------- .../dispatchkit/proxy_functions_detail.hpp | 2 +- .../dispatchkit/type_conversions.hpp | 12 ++-- include/chaiscript/dispatchkit/type_info.hpp | 42 ++++++------- .../language/chaiscript_algebraic.hpp | 2 +- .../chaiscript/language/chaiscript_common.hpp | 30 +++++----- .../chaiscript/language/chaiscript_engine.hpp | 4 +- .../chaiscript/language/chaiscript_eval.hpp | 2 +- .../language/chaiscript_optimizer.hpp | 8 +-- .../chaiscript/language/chaiscript_parser.hpp | 60 +++++++++---------- .../chaiscript/language/chaiscript_posix.hpp | 2 +- .../chaiscript/language/chaiscript_tracer.hpp | 2 +- include/chaiscript/utility/fnv1a.hpp | 2 +- include/chaiscript/utility/json.hpp | 44 +++++++------- include/chaiscript/utility/static_string.hpp | 6 +- 25 files changed, 211 insertions(+), 211 deletions(-) diff --git a/include/chaiscript/chaiscript_defines.hpp b/include/chaiscript/chaiscript_defines.hpp index 5b2e84f4..4f8293d1 100644 --- a/include/chaiscript/chaiscript_defines.hpp +++ b/include/chaiscript/chaiscript_defines.hpp @@ -104,17 +104,17 @@ namespace chaiscript { } struct Build_Info { - static int version_major() + static int version_major() noexcept { return chaiscript::version_major; } - static int version_minor() + static int version_minor() noexcept { return chaiscript::version_minor; } - static int version_patch() + static int version_patch() noexcept { return chaiscript::version_patch; } @@ -144,7 +144,7 @@ namespace chaiscript { return chaiscript::compiler_name; } - static bool debug_build() + static bool debug_build() noexcept { return chaiscript::debug_build; } @@ -152,7 +152,7 @@ namespace chaiscript { template - auto parse_num(const char *t_str) -> typename std::enable_if::value, T>::type + auto parse_num(const char *t_str) noexcept -> typename std::enable_if::value, T>::type { T t = 0; for (char c = *t_str; (c = *t_str) != 0; ++t_str) { @@ -167,7 +167,7 @@ namespace chaiscript { template - auto parse_num(const char *t_str) -> typename std::enable_if::value, T>::type + auto parse_num(const char *t_str) noexcept -> typename std::enable_if::value, T>::type { T t = 0; T base = 0; @@ -211,7 +211,7 @@ namespace chaiscript { } template - T parse_num(const std::string &t_str) + T parse_num(const std::string &t_str) noexcept { return parse_num(t_str.c_str()); } diff --git a/include/chaiscript/chaiscript_threading.hpp b/include/chaiscript/chaiscript_threading.hpp index 79feaa1e..47b97288 100644 --- a/include/chaiscript/chaiscript_threading.hpp +++ b/include/chaiscript/chaiscript_threading.hpp @@ -114,25 +114,25 @@ namespace chaiscript class unique_lock { public: - explicit unique_lock(T &) {} - void lock() {} - void unlock() {} + explicit unique_lock(T &) noexcept {} + void lock() noexcept {} + void unlock() noexcept {} }; template class shared_lock { public: - explicit shared_lock(T &) {} - void lock() {} - void unlock() {} + explicit shared_lock(T &) noexcept {} + void lock() noexcept {} + void unlock() noexcept {} }; template class lock_guard { public: - explicit lock_guard(T &) {} + explicit lock_guard(T &) noexcept {} }; class shared_mutex { }; @@ -144,16 +144,16 @@ namespace chaiscript class Thread_Storage { public: - explicit Thread_Storage() + explicit Thread_Storage() noexcept { } - inline T *operator->() const + inline T *operator->() const noexcept { return &obj; } - inline T &operator*() const + inline T &operator*() const noexcept { return obj; } diff --git a/include/chaiscript/dispatchkit/any.hpp b/include/chaiscript/dispatchkit/any.hpp index ae8035c9..47b75a59 100644 --- a/include/chaiscript/dispatchkit/any.hpp +++ b/include/chaiscript/dispatchkit/any.hpp @@ -43,16 +43,16 @@ namespace chaiscript { private: struct Data { - explicit Data(const std::type_info &t_type) + explicit Data(const std::type_info &t_type) noexcept : m_type(t_type) { } Data &operator=(const Data &) = delete; - virtual ~Data() = default; + virtual ~Data() noexcept = default; - virtual void *data() = 0; + virtual void *data() noexcept = 0; const std::type_info &type() const { @@ -72,7 +72,7 @@ namespace chaiscript { { } - void *data() override + void *data() noexcept override { return &m_data; } @@ -141,12 +141,12 @@ namespace chaiscript { } // queries - bool empty() const + bool empty() const noexcept { return !bool(m_data); } - const std::type_info & type() const + const std::type_info & type() const noexcept { if (m_data) { return m_data->type(); diff --git a/include/chaiscript/dispatchkit/bind_first.hpp b/include/chaiscript/dispatchkit/bind_first.hpp index c65c8385..2a377d3d 100644 --- a/include/chaiscript/dispatchkit/bind_first.hpp +++ b/include/chaiscript/dispatchkit/bind_first.hpp @@ -19,13 +19,13 @@ namespace chaiscript { template - T* get_pointer(T *t) + T* get_pointer(T *t) noexcept { return t; } template - T* get_pointer(const std::reference_wrapper &t) + T* get_pointer(const std::reference_wrapper &t) noexcept { return &t.get(); } diff --git a/include/chaiscript/dispatchkit/bootstrap_stl.hpp b/include/chaiscript/dispatchkit/bootstrap_stl.hpp index 7f409a3a..481d20df 100644 --- a/include/chaiscript/dispatchkit/bootstrap_stl.hpp +++ b/include/chaiscript/dispatchkit/bootstrap_stl.hpp @@ -51,7 +51,7 @@ namespace chaiscript { } - bool empty() const + bool empty() const noexcept { return m_begin == m_end; } diff --git a/include/chaiscript/dispatchkit/boxed_number.hpp b/include/chaiscript/dispatchkit/boxed_number.hpp index 8b46f43c..e81a563f 100644 --- a/include/chaiscript/dispatchkit/boxed_number.hpp +++ b/include/chaiscript/dispatchkit/boxed_number.hpp @@ -90,11 +90,11 @@ namespace chaiscript } template - static inline void check_divide_by_zero(T, typename std::enable_if::value>::type* = nullptr) + static inline void check_divide_by_zero(T, typename std::enable_if::value>::type* = nullptr) noexcept { } - static Common_Types get_common_type(size_t t_size, bool t_signed) + static Common_Types get_common_type(size_t t_size, bool t_signed) noexcept { return (t_size == 1 && t_signed)?(Common_Types::t_int8) :(t_size == 1)?(Common_Types::t_uint8) diff --git a/include/chaiscript/dispatchkit/boxed_value.hpp b/include/chaiscript/dispatchkit/boxed_value.hpp index 8938424e..3f6b1bd6 100644 --- a/include/chaiscript/dispatchkit/boxed_value.hpp +++ b/include/chaiscript/dispatchkit/boxed_value.hpp @@ -221,30 +221,30 @@ namespace chaiscript return *this; } - const Type_Info &get_type_info() const + const Type_Info &get_type_info() const noexcept { return m_data->m_type_info; } /// return true if the object is uninitialized - bool is_undef() const + bool is_undef() const noexcept { return m_data->m_type_info.is_undef(); } - bool is_const() const + bool is_const() const noexcept { return m_data->m_type_info.is_const(); } - bool is_type(const Type_Info &ti) const + bool is_type(const Type_Info &ti) const noexcept { return m_data->m_type_info.bare_equal(ti); } template - auto pointer_sentinel(std::shared_ptr &ptr) const + auto pointer_sentinel(std::shared_ptr &ptr) const noexcept { struct Sentinel { Sentinel(std::shared_ptr &t_ptr, Data &data) @@ -263,7 +263,7 @@ namespace chaiscript Sentinel& operator=(Sentinel&&s) = default; Sentinel(Sentinel &&s) = default; - operator std::shared_ptr&() const + operator std::shared_ptr&() const noexcept { return m_ptr.get(); } @@ -278,42 +278,42 @@ namespace chaiscript return Sentinel(ptr, *(m_data.get())); } - bool is_null() const + bool is_null() const noexcept { return (m_data->m_data_ptr == nullptr && m_data->m_const_data_ptr == nullptr); } - const chaiscript::detail::Any & get() const + const chaiscript::detail::Any & get() const noexcept { return m_data->m_obj; } - bool is_ref() const + bool is_ref() const noexcept { return m_data->m_is_ref; } - bool is_return_value() const + bool is_return_value() const noexcept { return m_data->m_return_value; } - void reset_return_value() const + void reset_return_value() const noexcept { m_data->m_return_value = false; } - bool is_pointer() const + bool is_pointer() const noexcept { return !is_ref(); } - void *get_ptr() const + void *get_ptr() const noexcept { return m_data->m_data_ptr; } - const void *get_const_ptr() const + const void *get_const_ptr() const noexcept { return m_data->m_const_data_ptr; } @@ -353,7 +353,7 @@ namespace chaiscript /// \returns true if the two Boxed_Values share the same internal type - static bool type_match(const Boxed_Value &l, const Boxed_Value &r) + static bool type_match(const Boxed_Value &l, const Boxed_Value &r) noexcept { return l.get_type_info() == r.get_type_info(); } diff --git a/include/chaiscript/dispatchkit/dispatchkit.hpp b/include/chaiscript/dispatchkit/dispatchkit.hpp index d8bfb25b..4245f823 100644 --- a/include/chaiscript/dispatchkit/dispatchkit.hpp +++ b/include/chaiscript/dispatchkit/dispatchkit.hpp @@ -292,7 +292,7 @@ namespace chaiscript } - static int calculate_arity(const std::vector &t_funcs) + static int calculate_arity(const std::vector &t_funcs) noexcept { if (t_funcs.empty()) { return -1; @@ -312,7 +312,7 @@ namespace chaiscript return arity; } - bool call_match(const std::vector &vals, const Type_Conversions_State &t_conversions) const override + bool call_match(const std::vector &vals, const Type_Conversions_State &t_conversions) const noexcept override { return std::any_of(std::begin(m_funcs), std::end(m_funcs), [&vals, &t_conversions](const Proxy_Function &f){ return f->call_match(vals, t_conversions); }); @@ -820,7 +820,7 @@ namespace chaiscript /// Return true if a function exists - bool function_exists(const std::string &name) const + bool function_exists(const std::string &name) const noexcept { chaiscript::detail::threading::shared_lock l(m_mutex); @@ -930,13 +930,13 @@ namespace chaiscript } - const Type_Conversions &conversions() const + const Type_Conversions &conversions() const noexcept { return m_conversions; } static bool is_attribute_call(const std::vector &t_funs, const std::vector &t_params, - bool t_has_params, const Type_Conversions_State &t_conversions) + bool t_has_params, const Type_Conversions_State &t_conversions) noexcept { if (!t_has_params || t_params.empty()) { return false; @@ -1166,7 +1166,7 @@ namespace chaiscript } /// return true if the Boxed_Value matches the registered type by name - bool is_type(const Boxed_Value &r, const std::string &user_typename) const + bool is_type(const Boxed_Value &r, const std::string &user_typename) const noexcept { try { if (get_type(user_typename).bare_equal(r.get_type_info())) @@ -1272,66 +1272,66 @@ namespace chaiscript pop_function_call(*m_stack_holder, m_conversions.conversion_saves()); } - Stack_Holder &get_stack_holder() + Stack_Holder &get_stack_holder() noexcept { return *m_stack_holder; } /// Returns the current stack /// make const/non const versions - const StackData &get_stack_data() const + const StackData &get_stack_data() const noexcept { return m_stack_holder->stacks.back(); } - static StackData &get_stack_data(Stack_Holder &t_holder) + static StackData &get_stack_data(Stack_Holder &t_holder) noexcept { return t_holder.stacks.back(); } - StackData &get_stack_data() + StackData &get_stack_data() noexcept { return m_stack_holder->stacks.back(); } - parser::ChaiScript_Parser_Base &get_parser() + parser::ChaiScript_Parser_Base &get_parser() noexcept { return m_parser.get(); } private: - const std::vector> &get_boxed_functions_int() const + const std::vector> &get_boxed_functions_int() const noexcept { return m_state.m_boxed_functions; } - std::vector> &get_boxed_functions_int() + std::vector> &get_boxed_functions_int() noexcept { return m_state.m_boxed_functions; } - const std::vector> &get_function_objects_int() const + const std::vector> &get_function_objects_int() const noexcept { return m_state.m_function_objects; } - std::vector> &get_function_objects_int() + std::vector> &get_function_objects_int() noexcept { return m_state.m_function_objects; } - const std::vector>>> &get_functions_int() const + const std::vector>>> &get_functions_int() const noexcept { return m_state.m_functions; } - std::vector>>> &get_functions_int() + std::vector>>> &get_functions_int() noexcept { return m_state.m_functions; } - static bool function_less_than(const Proxy_Function &lhs, const Proxy_Function &rhs) + static bool function_less_than(const Proxy_Function &lhs, const Proxy_Function &rhs) noexcept { auto dynamic_lhs(std::dynamic_pointer_cast(lhs)); @@ -1432,7 +1432,7 @@ namespace chaiscript } template - static typename Container::iterator find_keyed_value(Container &t_c, const Key &t_key) + static typename Container::iterator find_keyed_value(Container &t_c, const Key &t_key) noexcept { return std::find_if(t_c.begin(), t_c.end(), [&t_key](const typename Container::value_type &o) { @@ -1441,7 +1441,7 @@ namespace chaiscript } template - static typename Container::const_iterator find_keyed_value(const Container &t_c, const Key &t_key) + static typename Container::const_iterator find_keyed_value(const Container &t_c, const Key &t_key) noexcept { return std::find_if(t_c.begin(), t_c.end(), [&t_key](const typename Container::value_type &o) { @@ -1450,7 +1450,7 @@ namespace chaiscript } template - static typename Container::const_iterator find_keyed_value(const Container &t_c, const Key &t_key, const size_t t_hint) + static typename Container::const_iterator find_keyed_value(const Container &t_c, const Key &t_key, const size_t t_hint) noexcept { if (t_c.size() > t_hint && t_c[t_hint].first == t_key) { return std::next(t_c.begin(), static_cast::difference_type>(t_hint)); @@ -1527,23 +1527,23 @@ namespace chaiscript { } - Dispatch_Engine *operator->() const { + Dispatch_Engine *operator->() const noexcept { return &m_engine.get(); } - Dispatch_Engine &operator*() const { + Dispatch_Engine &operator*() const noexcept { return m_engine.get(); } - Stack_Holder &stack_holder() const { + Stack_Holder &stack_holder() const noexcept { return m_stack_holder.get(); } - const Type_Conversions_State &conversions() const { + const Type_Conversions_State &conversions() const noexcept { return m_conversions; } - Type_Conversions::Conversion_Saves &conversion_saves() const { + Type_Conversions::Conversion_Saves &conversion_saves() const noexcept { return m_conversions.saves(); } diff --git a/include/chaiscript/dispatchkit/dynamic_object.hpp b/include/chaiscript/dispatchkit/dynamic_object.hpp index b5afaf15..fc50bed0 100644 --- a/include/chaiscript/dispatchkit/dynamic_object.hpp +++ b/include/chaiscript/dispatchkit/dynamic_object.hpp @@ -50,12 +50,12 @@ namespace chaiscript Dynamic_Object() = default; - bool is_explicit() const + bool is_explicit() const noexcept { return m_option_explicit; } - void set_explicit(const bool t_explicit) + void set_explicit(const bool t_explicit) noexcept { m_option_explicit = t_explicit; } diff --git a/include/chaiscript/dispatchkit/dynamic_object_detail.hpp b/include/chaiscript/dispatchkit/dynamic_object_detail.hpp index df90ab66..c9cd1408 100644 --- a/include/chaiscript/dispatchkit/dynamic_object_detail.hpp +++ b/include/chaiscript/dispatchkit/dynamic_object_detail.hpp @@ -71,7 +71,7 @@ namespace chaiscript Dynamic_Object_Function &operator=(const Dynamic_Object_Function) = delete; Dynamic_Object_Function(Dynamic_Object_Function &) = delete; - bool operator==(const Proxy_Function_Base &f) const override + bool operator==(const Proxy_Function_Base &f) const noexcept override { if (const auto *df = dynamic_cast(&f)) { @@ -81,9 +81,9 @@ namespace chaiscript } } - bool is_attribute_function() const override { return m_is_attribute; } + bool is_attribute_function() const noexcept override { return m_is_attribute; } - bool call_match(const std::vector &vals, const Type_Conversions_State &t_conversions) const override + bool call_match(const std::vector &vals, const Type_Conversions_State &t_conversions) const noexcept override { if (dynamic_object_typename_match(vals, m_type_name, m_ti, t_conversions)) { @@ -127,7 +127,7 @@ namespace chaiscript } bool dynamic_object_typename_match(const Boxed_Value &bv, const std::string &name, - const std::unique_ptr &ti, const Type_Conversions_State &t_conversions) const + const std::unique_ptr &ti, const Type_Conversions_State &t_conversions) const noexcept { if (bv.get_type_info().bare_equal(m_doti)) { @@ -149,7 +149,7 @@ namespace chaiscript } bool dynamic_object_typename_match(const std::vector &bvs, const std::string &name, - const std::unique_ptr &ti, const Type_Conversions_State &t_conversions) const + const std::unique_ptr &ti, const Type_Conversions_State &t_conversions) const noexcept { if (!bvs.empty()) { @@ -199,7 +199,7 @@ namespace chaiscript return std::vector(begin, end); } - bool operator==(const Proxy_Function_Base &f) const override + bool operator==(const Proxy_Function_Base &f) const noexcept override { const Dynamic_Object_Constructor *dc = dynamic_cast(&f); return (dc != nullptr) && dc->m_type_name == m_type_name && (*dc->m_func) == (*m_func); diff --git a/include/chaiscript/dispatchkit/proxy_functions.hpp b/include/chaiscript/dispatchkit/proxy_functions.hpp index 0c60315f..0e809879 100644 --- a/include/chaiscript/dispatchkit/proxy_functions.hpp +++ b/include/chaiscript/dispatchkit/proxy_functions.hpp @@ -70,7 +70,7 @@ namespace chaiscript update_has_types(); } - bool operator==(const Param_Types &t_rhs) const + bool operator==(const Param_Types &t_rhs) const noexcept { return m_types == t_rhs.m_types; } @@ -114,7 +114,7 @@ namespace chaiscript // first result: is a match // second result: needs conversions - std::pair match(const std::vector &vals, const Type_Conversions_State &t_conversions) const + std::pair match(const std::vector &vals, const Type_Conversions_State &t_conversions) const noexcept { bool needs_conversion = false; @@ -158,7 +158,7 @@ namespace chaiscript return std::make_pair(true, needs_conversion); } - const std::vector> &types() const + const std::vector> &types() const noexcept { return m_types; } @@ -210,14 +210,14 @@ namespace chaiscript /// if the function is variadic or takes no arguments (arity of 0 or -1), the returned /// value contains exactly 1 Type_Info object: the return type /// \returns the types of all parameters. - const std::vector &get_param_types() const { return m_types; } + const std::vector &get_param_types() const noexcept { return m_types; } virtual bool operator==(const Proxy_Function_Base &) const = 0; virtual bool call_match(const std::vector &vals, const Type_Conversions_State &t_conversions) const = 0; - virtual bool is_attribute_function() const { return false; } + virtual bool is_attribute_function() const noexcept { return false; } - bool has_arithmetic_param() const + bool has_arithmetic_param() const noexcept { return m_has_arithmetic_param; } @@ -229,7 +229,7 @@ namespace chaiscript //! Return true if the function is a possible match //! to the passed in values - bool filter(const std::vector &vals, const Type_Conversions_State &t_conversions) const + bool filter(const std::vector &vals, const Type_Conversions_State &t_conversions) const noexcept { assert(m_arity == -1 || (m_arity > 0 && static_cast(vals.size()) == m_arity)); @@ -244,12 +244,12 @@ namespace chaiscript } /// \returns the number of arguments the function takes or -1 if it is variadic - int get_arity() const + int get_arity() const noexcept { return m_arity; } - static bool compare_type_to_param(const Type_Info &ti, const Boxed_Value &bv, const Type_Conversions_State &t_conversions) + static bool compare_type_to_param(const Type_Info &ti, const Boxed_Value &bv, const Type_Conversions_State &t_conversions) noexcept { if (ti.is_undef() || ti.bare_equal(user_type()) @@ -292,7 +292,7 @@ namespace chaiscript static bool compare_types(const std::vector &tis, const std::vector &bvs, - const Type_Conversions_State &t_conversions) + const Type_Conversions_State &t_conversions) noexcept { if (tis.size() - 1 != bvs.size()) { @@ -358,7 +358,7 @@ namespace chaiscript } - bool operator==(const Proxy_Function_Base &rhs) const override + bool operator==(const Proxy_Function_Base &rhs) const noexcept override { const Dynamic_Proxy_Function *prhs = dynamic_cast(&rhs); @@ -369,7 +369,7 @@ namespace chaiscript && this->m_param_types == prhs->m_param_types); } - bool call_match(const std::vector &vals, const Type_Conversions_State &t_conversions) const override + bool call_match(const std::vector &vals, const Type_Conversions_State &t_conversions) const noexcept override { return call_match_internal(vals, t_conversions).first; } @@ -380,7 +380,7 @@ namespace chaiscript return m_guard; } - bool has_parse_tree() const { + bool has_parse_tree() const noexcept { return static_cast(m_parsenode); } @@ -413,7 +413,7 @@ namespace chaiscript // first result: is a match // second result: needs conversions - std::pair call_match_internal(const std::vector &vals, const Type_Conversions_State &t_conversions) const + std::pair call_match_internal(const std::vector &vals, const Type_Conversions_State &t_conversions) const noexcept { const auto comparison_result = [&](){ if (m_arity < 0) { @@ -528,7 +528,7 @@ namespace chaiscript assert(m_f->get_arity() < 0 || m_f->get_arity() == static_cast(m_args.size())); } - bool operator==(const Proxy_Function_Base &t_f) const override + bool operator==(const Proxy_Function_Base &t_f) const noexcept override { return &t_f == this; } @@ -620,13 +620,13 @@ namespace chaiscript { } - bool call_match(const std::vector &vals, const Type_Conversions_State &t_conversions) const override + bool call_match(const std::vector &vals, const Type_Conversions_State &t_conversions) const noexcept override { return static_cast(vals.size()) == get_arity() && (compare_types(m_types, vals, t_conversions) && compare_types_with_cast(vals, t_conversions)); } - virtual bool compare_types_with_cast(const std::vector &vals, const Type_Conversions_State &t_conversions) const = 0; + virtual bool compare_types_with_cast(const std::vector &vals, const Type_Conversions_State &t_conversions) const noexcept = 0; }; @@ -642,12 +642,12 @@ namespace chaiscript { } - bool compare_types_with_cast(const std::vector &vals, const Type_Conversions_State &t_conversions) const override + bool compare_types_with_cast(const std::vector &vals, const Type_Conversions_State &t_conversions) const noexcept override { return detail::compare_types_cast(static_cast(nullptr), vals, t_conversions); } - bool operator==(const Proxy_Function_Base &t_func) const override + bool operator==(const Proxy_Function_Base &t_func) const noexcept override { return dynamic_cast *>(&t_func) != nullptr; } @@ -686,12 +686,12 @@ namespace chaiscript assert(!m_shared_ptr_holder || m_shared_ptr_holder.get() == &m_f.get()); } - bool compare_types_with_cast(const std::vector &vals, const Type_Conversions_State &t_conversions) const override + bool compare_types_with_cast(const std::vector &vals, const Type_Conversions_State &t_conversions) const noexcept override { return detail::compare_types_cast(static_cast(nullptr), vals, t_conversions); } - bool operator==(const Proxy_Function_Base &t_func) const override + bool operator==(const Proxy_Function_Base &t_func) const noexcept override { return dynamic_cast *>(&t_func) != nullptr; } @@ -729,9 +729,9 @@ namespace chaiscript { } - bool is_attribute_function() const override { return true; } + bool is_attribute_function() const noexcept override { return true; } - bool operator==(const Proxy_Function_Base &t_func) const override + bool operator==(const Proxy_Function_Base &t_func) const noexcept override { const Attribute_Access * aa = dynamic_cast *>(&t_func); @@ -743,7 +743,7 @@ namespace chaiscript } } - bool call_match(const std::vector &vals, const Type_Conversions_State &) const override + bool call_match(const std::vector &vals, const Type_Conversions_State &) const noexcept override { if (vals.size() != 1) { @@ -841,7 +841,7 @@ namespace chaiscript { template bool types_match_except_for_arithmetic(const FuncType &t_func, const std::vector &plist, - const Type_Conversions_State &t_conversions) + const Type_Conversions_State &t_conversions) noexcept { const std::vector &types = t_func->get_param_types(); diff --git a/include/chaiscript/dispatchkit/proxy_functions_detail.hpp b/include/chaiscript/dispatchkit/proxy_functions_detail.hpp index 9ce58468..70d77b9a 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 std::vector ¶ms, const Type_Conversions_State &t_conversions) + const std::vector ¶ms, const Type_Conversions_State &t_conversions) noexcept { try { std::vector::size_type i = 0; diff --git a/include/chaiscript/dispatchkit/type_conversions.hpp b/include/chaiscript/dispatchkit/type_conversions.hpp index d9d2f374..728494ce 100644 --- a/include/chaiscript/dispatchkit/type_conversions.hpp +++ b/include/chaiscript/dispatchkit/type_conversions.hpp @@ -87,16 +87,16 @@ namespace chaiscript virtual Boxed_Value convert(const Boxed_Value &from) const = 0; virtual Boxed_Value convert_down(const Boxed_Value &to) const = 0; - const Type_Info &to() const + const Type_Info &to() const noexcept { return m_to; } - const Type_Info &from() const + const Type_Info &from() const noexcept { return m_from; } - virtual bool bidir() const + virtual bool bidir() const noexcept { return true; } @@ -272,7 +272,7 @@ namespace chaiscript "Unable to cast down inheritance hierarchy with non-polymorphic types"); } - bool bidir() const override + bool bidir() const noexcept override { return false; } @@ -306,7 +306,7 @@ namespace chaiscript return m_func(t_from); } - bool bidir() const override + bool bidir() const noexcept override { return false; } @@ -328,7 +328,7 @@ namespace chaiscript struct Less_Than { - bool operator()(const std::type_info *t_lhs, const std::type_info *t_rhs) const + bool operator()(const std::type_info *t_lhs, const std::type_info *t_rhs) const noexcept { return *t_lhs != *t_rhs && t_lhs->before(*t_rhs); } diff --git a/include/chaiscript/dispatchkit/type_info.hpp b/include/chaiscript/dispatchkit/type_info.hpp index ba377d21..09344ae6 100644 --- a/include/chaiscript/dispatchkit/type_info.hpp +++ b/include/chaiscript/dispatchkit/type_info.hpp @@ -46,49 +46,49 @@ namespace chaiscript Type_Info() = default; - bool operator<(const Type_Info &ti) const + bool operator<(const Type_Info &ti) const noexcept { return m_type_info < ti.m_type_info; } - bool operator!=(const Type_Info &ti) const + bool operator!=(const Type_Info &ti) const noexcept { return !(operator==(ti)); } - bool operator!=(const std::type_info &ti) const + bool operator!=(const std::type_info &ti) const noexcept { return !(operator==(ti)); } - bool operator==(const Type_Info &ti) const + bool operator==(const Type_Info &ti) const noexcept { return ti.m_type_info == m_type_info || *ti.m_type_info == *m_type_info; } - bool operator==(const std::type_info &ti) const + bool operator==(const std::type_info &ti) const noexcept { return !is_undef() && (*m_type_info) == ti; } - bool bare_equal(const Type_Info &ti) const + bool bare_equal(const Type_Info &ti) const noexcept { return ti.m_bare_type_info == m_bare_type_info || *ti.m_bare_type_info == *m_bare_type_info; } - bool bare_equal_type_info(const std::type_info &ti) const + bool bare_equal_type_info(const std::type_info &ti) const noexcept { return !is_undef() && (*m_bare_type_info) == ti; } - bool is_const() const { return (m_flags & (1 << is_const_flag)) != 0; } - bool is_reference() const { return (m_flags & (1 << is_reference_flag)) != 0; } - bool is_void() const { return (m_flags & (1 << is_void_flag)) != 0; } - bool is_arithmetic() const { return (m_flags & (1 << is_arithmetic_flag)) != 0; } - bool is_undef() const { return (m_flags & (1 << is_undef_flag)) != 0; } - bool is_pointer() const { return (m_flags & (1 << is_pointer_flag)) != 0; } + bool is_const() const noexcept { return (m_flags & (1 << is_const_flag)) != 0; } + bool is_reference() const noexcept { return (m_flags & (1 << is_reference_flag)) != 0; } + bool is_void() const noexcept { return (m_flags & (1 << is_void_flag)) != 0; } + bool is_arithmetic() const noexcept { return (m_flags & (1 << is_arithmetic_flag)) != 0; } + bool is_undef() const noexcept { return (m_flags & (1 << is_undef_flag)) != 0; } + bool is_pointer() const noexcept { return (m_flags & (1 << is_pointer_flag)) != 0; } std::string name() const { @@ -110,7 +110,7 @@ namespace chaiscript } } - const std::type_info *bare_type_info() const + const std::type_info *bare_type_info() const noexcept { return m_bare_type_info; } @@ -135,7 +135,7 @@ namespace chaiscript template struct Get_Type_Info { - static Type_Info get() + static Type_Info get() noexcept { return Type_Info(std::is_const::type>::type>::value, std::is_reference::value, std::is_pointer::value, @@ -152,7 +152,7 @@ namespace chaiscript { // typedef T type; - static Type_Info get() + static Type_Info get() noexcept { return Type_Info(std::is_const::value, std::is_reference::value, std::is_pointer::value, std::is_void::value, @@ -170,7 +170,7 @@ namespace chaiscript template struct Get_Type_Info &> { - static Type_Info get() + static Type_Info get() noexcept { return Type_Info(std::is_const::value, std::is_reference::value, std::is_pointer::value, std::is_void::value, @@ -183,7 +183,7 @@ namespace chaiscript template struct Get_Type_Info > { - static Type_Info get() + static Type_Info get() noexcept { return Type_Info(std::is_const::value, std::is_reference::value, std::is_pointer::value, std::is_void::value, @@ -196,7 +196,7 @@ namespace chaiscript template struct Get_Type_Info &> { - static Type_Info get() + static Type_Info get() noexcept { return Type_Info(std::is_const::value, std::is_reference::value, std::is_pointer::value, std::is_void::value, @@ -218,7 +218,7 @@ namespace chaiscript /// chaiscript::Type_Info ti = chaiscript::user_type(i); /// \endcode template - Type_Info user_type(const T &/*t*/) + Type_Info user_type(const T &/*t*/) noexcept { return detail::Get_Type_Info::get(); } @@ -233,7 +233,7 @@ namespace chaiscript /// chaiscript::Type_Info ti = chaiscript::user_type(); /// \endcode template - Type_Info user_type() + Type_Info user_type() noexcept { return detail::Get_Type_Info::get(); } diff --git a/include/chaiscript/language/chaiscript_algebraic.hpp b/include/chaiscript/language/chaiscript_algebraic.hpp index 8a49d2ee..b52debbe 100644 --- a/include/chaiscript/language/chaiscript_algebraic.hpp +++ b/include/chaiscript/language/chaiscript_algebraic.hpp @@ -55,7 +55,7 @@ namespace chaiscript return opers[static_cast(t_oper)]; } - static Opers to_operator(const std::string &t_str, bool t_is_unary = false) + static Opers to_operator(const std::string &t_str, bool t_is_unary = false) noexcept { #ifdef CHAISCRIPT_MSVC #pragma warning(push) diff --git a/include/chaiscript/language/chaiscript_common.hpp b/include/chaiscript/language/chaiscript_common.hpp index b157cac2..2085d52e 100644 --- a/include/chaiscript/language/chaiscript_common.hpp +++ b/include/chaiscript/language/chaiscript_common.hpp @@ -76,7 +76,7 @@ namespace chaiscript namespace { /// Helper lookup to get the name of each node type - inline const char *ast_node_type_to_string(AST_Node_Type ast_node_type) { + inline const char *ast_node_type_to_string(AST_Node_Type ast_node_type) noexcept { static const char * const ast_node_types[] = { "Id", "Fun_Call", "Unused_Return_Fun_Call", "Arg_List", "Equation", "Var_Decl", "Array_Call", "Dot_Access", "Lambda", "Block", "Scopeless_Block", "Def", "While", "If", "For", "Ranged_For", "Inline_Array", "Inline_Map", "Return", "File", "Prefix", "Break", "Continue", "Map_Pair", "Value_Range", @@ -89,13 +89,13 @@ namespace chaiscript /// \brief Convenience type for file positions struct File_Position { - int line; - int column; + int line = 0; + int column = 0; - File_Position(int t_file_line, int t_file_column) + File_Position(int t_file_line, int t_file_column) noexcept : line(t_file_line), column(t_file_column) { } - File_Position() : line(0), column(0) { } + File_Position() noexcept = default; }; struct Parse_Location { @@ -228,7 +228,7 @@ namespace chaiscript private: template - static AST_Node_Type id(const T& t) + static AST_Node_Type id(const T& t) noexcept { return t.identifier; } @@ -240,7 +240,7 @@ namespace chaiscript } template - static const std::string &fname(const T& t) + static const std::string &fname(const T& t) noexcept { return t.filename(); } @@ -497,15 +497,15 @@ namespace chaiscript const std::string text; Parse_Location location; - const std::string &filename() const { + const std::string &filename() const noexcept { return *location.filename; } - const File_Position &start() const { + const File_Position &start() const noexcept { return location.start; } - const File_Position &end() const { + const File_Position &end() const noexcept { return location.end; } @@ -550,7 +550,7 @@ namespace chaiscript } - virtual ~AST_Node() = default; + virtual ~AST_Node() noexcept = default; AST_Node(AST_Node &&) = default; AST_Node &operator=(AST_Node &&) = default; AST_Node(const AST_Node &) = delete; @@ -573,15 +573,15 @@ namespace chaiscript const std::string text; Parse_Location location; - const std::string &filename() const { + const std::string &filename() const noexcept { return *location.filename; } - const File_Position &start() const { + const File_Position &start() const noexcept { return location.start; } - const File_Position &end() const { + const File_Position &end() const noexcept { return location.end; } @@ -629,7 +629,7 @@ namespace chaiscript ChaiScript_Parser_Base &operator=(const ChaiScript_Parser_Base &&) = delete; template - T &get_tracer() + T &get_tracer() noexcept { // to do type check this somehow? return *static_cast(get_tracer_ptr()); diff --git a/include/chaiscript/language/chaiscript_engine.hpp b/include/chaiscript/language/chaiscript_engine.hpp index 0e07f4ce..11506f58 100644 --- a/include/chaiscript/language/chaiscript_engine.hpp +++ b/include/chaiscript/language/chaiscript_engine.hpp @@ -124,7 +124,7 @@ namespace chaiscript } /// Returns the current evaluation m_engine - chaiscript::detail::Dispatch_Engine &get_eval_engine() { + chaiscript::detail::Dispatch_Engine &get_eval_engine() noexcept { return m_engine; } @@ -316,7 +316,7 @@ explicit ChaiScript_Basic(std::unique_ptr &&pars const std::vector &t_opts = chaiscript::default_options()) = delete; #endif - parser::ChaiScript_Parser_Base &get_parser() + parser::ChaiScript_Parser_Base &get_parser() noexcept { return *m_parser; } diff --git a/include/chaiscript/language/chaiscript_eval.hpp b/include/chaiscript/language/chaiscript_eval.hpp index a9819440..efd54203 100644 --- a/include/chaiscript/language/chaiscript_eval.hpp +++ b/include/chaiscript/language/chaiscript_eval.hpp @@ -667,7 +667,7 @@ namespace chaiscript ); } - static bool has_this_capture(const std::vector> &children) { + static bool has_this_capture(const std::vector> &children) noexcept { return std::any_of(std::begin(children), std::end(children), [](const auto &child){ return child->children[0]->text == "this"; diff --git a/include/chaiscript/language/chaiscript_optimizer.hpp b/include/chaiscript/language/chaiscript_optimizer.hpp index 675d092c..ae32f130 100644 --- a/include/chaiscript/language/chaiscript_optimizer.hpp +++ b/include/chaiscript/language/chaiscript_optimizer.hpp @@ -30,7 +30,7 @@ namespace chaiscript { }; template - eval::AST_Node_Impl &child_at(eval::AST_Node_Impl &node, const size_t offset) { + eval::AST_Node_Impl &child_at(eval::AST_Node_Impl &node, const size_t offset) noexcept { if (node.children[offset]->identifier == AST_Node_Type::Compiled) { return *(dynamic_cast &>(*node.children[offset]).m_original_node); } else { @@ -39,7 +39,7 @@ namespace chaiscript { } template - const eval::AST_Node_Impl &child_at(const eval::AST_Node_Impl &node, const size_t offset) { + const eval::AST_Node_Impl &child_at(const eval::AST_Node_Impl &node, const size_t offset) noexcept { if (node.children[offset]->identifier == AST_Node_Type::Compiled) { return *(dynamic_cast &>(*node.children[offset]).m_original_node); } else { @@ -57,7 +57,7 @@ namespace chaiscript { } template - auto child_count(const eval::AST_Node_Impl &node) { + auto child_count(const eval::AST_Node_Impl &node) noexcept { if (node.identifier == AST_Node_Type::Compiled) { return dynamic_cast&>(node).m_original_node->children.size(); } else { @@ -95,7 +95,7 @@ namespace chaiscript { }; template - bool contains_var_decl_in_scope(const eval::AST_Node_Impl &node) + bool contains_var_decl_in_scope(const eval::AST_Node_Impl &node) noexcept { if (node.identifier == AST_Node_Type::Var_Decl) { return true; diff --git a/include/chaiscript/language/chaiscript_parser.hpp b/include/chaiscript/language/chaiscript_parser.hpp index 8db33d02..3e084a56 100644 --- a/include/chaiscript/language/chaiscript_parser.hpp +++ b/include/chaiscript/language/chaiscript_parser.hpp @@ -120,11 +120,11 @@ namespace chaiscript template class ChaiScript_Parser final : public ChaiScript_Parser_Base { - void *get_tracer_ptr() override { + void *get_tracer_ptr() noexcept override { return &m_tracer; } - static std::array, detail::max_alphabet> build_alphabet() + static std::array, detail::max_alphabet> build_alphabet() noexcept { std::array, detail::max_alphabet> alphabet; @@ -185,7 +185,7 @@ namespace chaiscript return alphabet; } - static const std::array, detail::max_alphabet> &create_alphabet() + static const std::array, detail::max_alphabet> &create_alphabet() noexcept { static const auto alpha = build_alphabet(); return alpha; @@ -213,7 +213,7 @@ namespace chaiscript } - static const std::array &create_operators() { + static const std::array &create_operators() noexcept { static const std::array operators = { { Operator_Precidence::Ternary_Cond, Operator_Precidence::Logical_Or, @@ -231,31 +231,31 @@ namespace chaiscript return operators; } - static const utility::Static_String &multiline_comment_end() + static const utility::Static_String &multiline_comment_end() noexcept { static const utility::Static_String s("*/"); return s; } - static const utility::Static_String &multiline_comment_begin() + static const utility::Static_String &multiline_comment_begin() noexcept { static const utility::Static_String s("/*"); return s; } - static const utility::Static_String &singleline_comment() + static const utility::Static_String &singleline_comment() noexcept { static const utility::Static_String s("//"); return s; } - static const utility::Static_String &annotation() + static const utility::Static_String &annotation() noexcept { static const utility::Static_String s("#"); return s; } - static const utility::Static_String &cr_lf() + static const utility::Static_String &cr_lf() noexcept { static const utility::Static_String s("\r\n"); return s; @@ -271,18 +271,18 @@ namespace chaiscript struct Position { - Position() = default; + Position() noexcept = default; - Position(std::string::const_iterator t_pos, std::string::const_iterator t_end) + Position(std::string::const_iterator t_pos, std::string::const_iterator t_end) noexcept : line(1), col(1), m_pos(t_pos), m_end(t_end), m_last_col(1) { } - static std::string str(const Position &t_begin, const Position &t_end) { + static std::string str(const Position &t_begin, const Position &t_end) noexcept { return std::string(t_begin.m_pos, t_end.m_pos); } - Position &operator++() { + Position &operator++() noexcept { if (m_pos != m_end) { if (*m_pos == '\n') { ++line; @@ -296,7 +296,7 @@ namespace chaiscript return *this; } - Position &operator--() { + Position &operator--() noexcept { --m_pos; if (*m_pos == '\n') { --line; @@ -307,12 +307,12 @@ namespace chaiscript return *this; } - Position &operator+=(size_t t_distance) { + Position &operator+=(size_t t_distance) noexcept { *this = (*this) + t_distance; return *this; } - Position operator+(size_t t_distance) const { + Position operator+(size_t t_distance) const noexcept { Position ret(*this); for (size_t i = 0; i < t_distance; ++i) { ++ret; @@ -320,12 +320,12 @@ namespace chaiscript return ret; } - Position &operator-=(size_t t_distance) { + Position &operator-=(size_t t_distance) noexcept { *this = (*this) - t_distance; return *this; } - Position operator-(size_t t_distance) const { + Position operator-(size_t t_distance) const noexcept { Position ret(*this); for (size_t i = 0; i < t_distance; ++i) { --ret; @@ -333,23 +333,23 @@ namespace chaiscript return ret; } - bool operator==(const Position &t_rhs) const { + bool operator==(const Position &t_rhs) const noexcept { return m_pos == t_rhs.m_pos; } - bool operator!=(const Position &t_rhs) const { + bool operator!=(const Position &t_rhs) const noexcept { return m_pos != t_rhs.m_pos; } - bool has_more() const { + bool has_more() const noexcept { return m_pos != m_end; } - size_t remaining() const { + size_t remaining() const noexcept { return static_cast(std::distance(m_pos, m_end)); } - const char& operator*() const { + const char& operator*() const noexcept { if (m_pos == m_end) { static const char ktmp ='\0'; return ktmp; @@ -387,12 +387,12 @@ namespace chaiscript m_match_stack.reserve(2); } - Tracer &get_tracer() + Tracer &get_tracer() noexcept { return m_tracer; } - Optimizer &get_optimizer() + Optimizer &get_optimizer() noexcept { return m_optimizer; } @@ -403,7 +403,7 @@ namespace chaiscript ChaiScript_Parser &operator=(ChaiScript_Parser &&) = delete; /// test a char in an m_alphabet - bool char_in_alphabet(char c, detail::Alphabet a) const { return m_alphabet[a][static_cast(c)]; } + bool char_in_alphabet(char c, detail::Alphabet a) const noexcept { return m_alphabet[a][static_cast(c)]; } /// Prints the parsed ast_nodes as a tree void debug_print(const AST_Node &t, std::string prepend = "") const override { @@ -461,7 +461,7 @@ namespace chaiscript /// Reads a symbol group from input if it matches the parameter, without skipping initial whitespace - inline auto Symbol_(const utility::Static_String &sym) + inline auto Symbol_(const utility::Static_String &sym) noexcept { const auto len = sym.size(); if (m_position.remaining() >= len) { @@ -549,7 +549,7 @@ namespace chaiscript } /// Reads the optional exponent (scientific notation) and suffix for a Float - bool read_exponent_and_suffix() { + bool read_exponent_and_suffix() noexcept { // Support a form of scientific notation: 1e-5, 35.5E+8, 0.01e19 if (m_position.has_more() && (std::tolower(*m_position) == 'e')) { ++m_position; @@ -577,7 +577,7 @@ namespace chaiscript /// Reads a floating point value from input, without skipping initial whitespace - bool Float_() { + bool Float_() noexcept { if (m_position.has_more() && char_in_alphabet(*m_position,detail::float_alphabet) ) { while (m_position.has_more() && char_in_alphabet(*m_position,detail::int_alphabet) ) { ++m_position; @@ -605,7 +605,7 @@ namespace chaiscript } /// Reads a hex value from input, without skipping initial whitespace - bool Hex_() { + bool Hex_() noexcept { if (m_position.has_more() && (*m_position == '0')) { ++m_position; diff --git a/include/chaiscript/language/chaiscript_posix.hpp b/include/chaiscript/language/chaiscript_posix.hpp index 62f1c117..eb2ea250 100644 --- a/include/chaiscript/language/chaiscript_posix.hpp +++ b/include/chaiscript/language/chaiscript_posix.hpp @@ -49,7 +49,7 @@ namespace chaiscript } } - static T cast_symbol(void *p) + static T cast_symbol(void *p) noexcept { union cast_union { diff --git a/include/chaiscript/language/chaiscript_tracer.hpp b/include/chaiscript/language/chaiscript_tracer.hpp index 9d111815..2cd82dcc 100644 --- a/include/chaiscript/language/chaiscript_tracer.hpp +++ b/include/chaiscript/language/chaiscript_tracer.hpp @@ -14,7 +14,7 @@ namespace chaiscript { struct Noop_Tracer_Detail { template - void trace(const chaiscript::detail::Dispatch_State &, const AST_Node_Impl *) + void trace(const chaiscript::detail::Dispatch_State &, const AST_Node_Impl *) noexcept { } }; diff --git a/include/chaiscript/utility/fnv1a.hpp b/include/chaiscript/utility/fnv1a.hpp index 9e549928..2c55f43d 100644 --- a/include/chaiscript/utility/fnv1a.hpp +++ b/include/chaiscript/utility/fnv1a.hpp @@ -20,7 +20,7 @@ namespace chaiscript { - static constexpr std::uint32_t fnv1a_32(const char *s, std::uint32_t h = 0x811c9dc5) { + static constexpr std::uint32_t fnv1a_32(const char *s, std::uint32_t h = 0x811c9dc5) noexcept { #ifdef __GNUC__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wsign-conversion" diff --git a/include/chaiscript/utility/json.hpp b/include/chaiscript/utility/json.hpp index 693f19da..679f1064 100644 --- a/include/chaiscript/utility/json.hpp +++ b/include/chaiscript/utility/json.hpp @@ -50,32 +50,32 @@ class JSON struct QuickFlatMap { - auto find(const std::string &s) { + auto find(const std::string &s) noexcept { return std::find_if(std::begin(data), std::end(data), [&s](const auto &d) { return d.first == s; }); } - auto find(const std::string &s) const { + auto find(const std::string &s) const noexcept { return std::find_if(std::begin(data), std::end(data), [&s](const auto &d) { return d.first == s; }); } - auto size() const { + auto size() const noexcept { return data.size(); } - auto begin() const { + auto begin() const noexcept { return data.begin(); } - auto end() const { + auto end() const noexcept { return data.end(); } - auto begin() { + auto begin() noexcept { return data.begin(); } - auto end() { + auto end() noexcept { return data.end(); } @@ -108,7 +108,7 @@ class JSON } } - size_t count(const std::string &s) const { + size_t count(const std::string &s) const noexcept { return (find(s) != data.end())?1:0; } @@ -224,8 +224,8 @@ class JSON JSONConstWrapper( const Container *val ) : object( val ) {} JSONConstWrapper( std::nullptr_t ) {} - typename Container::const_iterator begin() const { return object ? object->begin() : typename Container::const_iterator(); } - typename Container::const_iterator end() const { return object ? object->end() : typename Container::const_iterator(); } + typename Container::const_iterator begin() const noexcept { return object ? object->begin() : typename Container::const_iterator(); } + typename Container::const_iterator end() const noexcept { return object ? object->end() : typename Container::const_iterator(); } }; JSON() = default; @@ -245,13 +245,13 @@ class JSON } template - explicit JSON( T b, typename enable_if::value>::type* = nullptr ) : internal( static_cast(b) ) {} + explicit JSON( T b, typename enable_if::value>::type* = nullptr ) noexcept : internal( static_cast(b) ) {} template - explicit JSON( T i, typename enable_if::value && !is_same::value>::type* = nullptr ) : internal( static_cast(i) ) {} + explicit JSON( T i, typename enable_if::value && !is_same::value>::type* = nullptr ) noexcept : internal( static_cast(i) ) {} template - explicit JSON( T f, typename enable_if::value>::type* = nullptr ) : internal( static_cast(f) ) {} + explicit JSON( T f, typename enable_if::value>::type* = nullptr ) noexcept : internal( static_cast(f) ) {} template explicit JSON( T s, typename enable_if::value>::type* = nullptr ) : internal( static_cast(s) ) {} @@ -292,7 +292,7 @@ class JSON } - long length() const { + long length() const noexcept { if( internal.Type == Class::Array ) { return static_cast(internal.List->size()); } else { @@ -308,7 +308,7 @@ class JSON return false; } - int size() const { + int size() const noexcept { if( internal.Type == Class::Object ) { return static_cast(internal.Map->size()); } else if( internal.Type == Class::Array ) { @@ -329,20 +329,20 @@ class JSON return ok ? *internal.String : std::string(""); } - double to_float() const { bool b; return to_float( b ); } - double to_float( bool &ok ) const { + double to_float() const noexcept { bool b; return to_float( b ); } + double to_float( bool &ok ) const noexcept { ok = (internal.Type == Class::Floating); return ok ? internal.Float : 0.0; } - long to_int() const { bool b; return to_int( b ); } - long to_int( bool &ok ) const { + long to_int() const noexcept { bool b; return to_int( b ); } + long to_int( bool &ok ) const noexcept { ok = (internal.Type == Class::Integral); return ok ? internal.Int : 0; } - bool to_bool() const { bool b; return to_bool( b ); } - bool to_bool( bool &ok ) const { + bool to_bool() const noexcept { bool b; return to_bool( b ); } + bool to_bool( bool &ok ) const noexcept { ok = (internal.Type == Class::Boolean); return ok ? internal.Bool : false; } @@ -447,7 +447,7 @@ class JSON struct JSONParser { - static bool isspace(const char c) + static bool isspace(const char c) noexcept { #ifdef CHAISCRIPT_MSVC // MSVC warns on these line in some circumstances diff --git a/include/chaiscript/utility/static_string.hpp b/include/chaiscript/utility/static_string.hpp index b1be2211..0f425032 100644 --- a/include/chaiscript/utility/static_string.hpp +++ b/include/chaiscript/utility/static_string.hpp @@ -15,16 +15,16 @@ namespace chaiscript struct Static_String { template - Static_String(const char (&str)[N]) + Static_String(const char (&str)[N]) noexcept : m_size(N-1), data(&str[0]) { } - size_t size() const { + size_t size() const noexcept { return m_size; } - const char *c_str() const { + const char *c_str() const noexcept { return data; } From 3f8b697e9e4a12bf366e5b0749ddf49372c2d21c Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Sun, 23 Jul 2017 07:38:20 -0600 Subject: [PATCH 007/155] Fix windows noexcept build --- include/chaiscript/language/chaiscript_parser.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/chaiscript/language/chaiscript_parser.hpp b/include/chaiscript/language/chaiscript_parser.hpp index 3e084a56..f744ee3f 100644 --- a/include/chaiscript/language/chaiscript_parser.hpp +++ b/include/chaiscript/language/chaiscript_parser.hpp @@ -271,7 +271,7 @@ namespace chaiscript struct Position { - Position() noexcept = default; + Position() = default; Position(std::string::const_iterator t_pos, std::string::const_iterator t_end) noexcept : line(1), col(1), m_pos(t_pos), m_end(t_end), m_last_col(1) From 7f6f1d8a59eb7ff6837931eb034a560efce6a9e9 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Mon, 31 Jul 2017 16:12:16 -0600 Subject: [PATCH 008/155] Fix clang warnings, fix misplaced noexcept --- CMakeLists.txt | 2 +- include/chaiscript/dispatchkit/bootstrap.hpp | 6 +++--- include/chaiscript/dispatchkit/proxy_functions.hpp | 4 ++-- src/test_module.cpp | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index effc7aed..0131de15 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -191,7 +191,7 @@ else() add_definitions(-Wall -Wextra -Wconversion -Wshadow -Wnon-virtual-dtor -Wold-style-cast -Wcast-align -Wcast-qual -Wunused -Woverloaded-virtual -pedantic ${CPP14_FLAG}) if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") - add_definitions(-Weverything -Wno-c++98-compat-pedantic -Wno-c++98-compat -Wno-documentation -Wno-switch-enum -Wno-weak-vtables -Wno-missing-prototypes -Wno-padded -Wno-missing-noreturn -Wno-exit-time-destructors -Wno-documentation-unknown-command) + add_definitions(-Weverything -Wno-c++98-compat-pedantic -Wno-c++98-compat -Wno-documentation -Wno-switch-enum -Wno-weak-vtables -Wno-missing-prototypes -Wno-padded -Wno-missing-noreturn -Wno-exit-time-destructors -Wno-documentation-unknown-command -Wno-unused-template -Wno-undef ) else() add_definitions(-Wnoexcept) endif() diff --git a/include/chaiscript/dispatchkit/bootstrap.hpp b/include/chaiscript/dispatchkit/bootstrap.hpp index 8aedb353..c819024c 100644 --- a/include/chaiscript/dispatchkit/bootstrap.hpp +++ b/include/chaiscript/dispatchkit/bootstrap.hpp @@ -26,7 +26,7 @@ namespace chaiscript const auto extent = std::extent::value; m.add(user_type(), type); m.add(fun( - [extent](T& t, size_t index)->ReturnType &{ + [](T& t, size_t index)->ReturnType &{ if (extent > 0 && index >= extent) { throw std::range_error("Array index out of range. Received: " + std::to_string(index) + " expected < " + std::to_string(extent)); } else { @@ -37,7 +37,7 @@ namespace chaiscript ); m.add(fun( - [extent](const T &t, size_t index)->const ReturnType &{ + [](const T &t, size_t index)->const ReturnType &{ if (extent > 0 && index >= extent) { throw std::range_error("Array index out of range. Received: " + std::to_string(index) + " expected < " + std::to_string(extent)); } else { @@ -48,7 +48,7 @@ namespace chaiscript ); m.add(fun( - [extent](const T &) { + [](const T &) { return extent; }), "size"); } diff --git a/include/chaiscript/dispatchkit/proxy_functions.hpp b/include/chaiscript/dispatchkit/proxy_functions.hpp index 0e809879..b80e66a8 100644 --- a/include/chaiscript/dispatchkit/proxy_functions.hpp +++ b/include/chaiscript/dispatchkit/proxy_functions.hpp @@ -369,7 +369,7 @@ namespace chaiscript && this->m_param_types == prhs->m_param_types); } - bool call_match(const std::vector &vals, const Type_Conversions_State &t_conversions) const noexcept override + bool call_match(const std::vector &vals, const Type_Conversions_State &t_conversions) const override { return call_match_internal(vals, t_conversions).first; } @@ -413,7 +413,7 @@ namespace chaiscript // first result: is a match // second result: needs conversions - std::pair call_match_internal(const std::vector &vals, const Type_Conversions_State &t_conversions) const noexcept + std::pair call_match_internal(const std::vector &vals, const Type_Conversions_State &t_conversions) const { const auto comparison_result = [&](){ if (m_arity < 0) { diff --git a/src/test_module.cpp b/src/test_module.cpp index fcb255e5..90a1154a 100644 --- a/src/test_module.cpp +++ b/src/test_module.cpp @@ -78,7 +78,7 @@ int to_int(TestEnum t) class TestDerivedType : public TestBaseType { public: - virtual ~TestDerivedType() {} + ~TestDerivedType() override {} TestDerivedType(const TestDerivedType &) = default; TestDerivedType() = default; virtual int func() override { return 1; } From 171765cfdbdeec8de18fa0a4ea0712b1448b57a8 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Sun, 6 Aug 2017 18:19:43 -0600 Subject: [PATCH 009/155] Add back in extent capture --- include/chaiscript/dispatchkit/bootstrap.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/chaiscript/dispatchkit/bootstrap.hpp b/include/chaiscript/dispatchkit/bootstrap.hpp index c819024c..8aedb353 100644 --- a/include/chaiscript/dispatchkit/bootstrap.hpp +++ b/include/chaiscript/dispatchkit/bootstrap.hpp @@ -26,7 +26,7 @@ namespace chaiscript const auto extent = std::extent::value; m.add(user_type(), type); m.add(fun( - [](T& t, size_t index)->ReturnType &{ + [extent](T& t, size_t index)->ReturnType &{ if (extent > 0 && index >= extent) { throw std::range_error("Array index out of range. Received: " + std::to_string(index) + " expected < " + std::to_string(extent)); } else { @@ -37,7 +37,7 @@ namespace chaiscript ); m.add(fun( - [](const T &t, size_t index)->const ReturnType &{ + [extent](const T &t, size_t index)->const ReturnType &{ if (extent > 0 && index >= extent) { throw std::range_error("Array index out of range. Received: " + std::to_string(index) + " expected < " + std::to_string(extent)); } else { @@ -48,7 +48,7 @@ namespace chaiscript ); m.add(fun( - [](const T &) { + [extent](const T &) { return extent; }), "size"); } From 34534c1386143bcac31e5c8ee790b5266cef426f Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Tue, 8 Aug 2017 17:06:36 -0600 Subject: [PATCH 010/155] Changes that noexcept want to happen --- include/chaiscript/chaiscript_threading.hpp | 8 +- include/chaiscript/dispatchkit/any.hpp | 15 +- .../chaiscript/dispatchkit/bad_boxed_cast.hpp | 13 +- include/chaiscript/dispatchkit/bootstrap.hpp | 10 +- .../chaiscript/dispatchkit/boxed_number.hpp | 240 ++++++++++++------ .../dispatchkit/proxy_functions.hpp | 4 + .../dispatchkit/type_conversions.hpp | 9 +- 7 files changed, 192 insertions(+), 107 deletions(-) diff --git a/include/chaiscript/chaiscript_threading.hpp b/include/chaiscript/chaiscript_threading.hpp index 47b97288..cd2c1bd3 100644 --- a/include/chaiscript/chaiscript_threading.hpp +++ b/include/chaiscript/chaiscript_threading.hpp @@ -78,22 +78,22 @@ namespace chaiscript t().erase(this); } - inline const T *operator->() const + inline const T *operator->() const noexcept { return &(t()[this]); } - inline const T &operator*() const + inline const T &operator*() const noexcept { return t()[this]; } - inline T *operator->() + inline T *operator->() noexcept { return &(t()[this]); } - inline T &operator*() + inline T &operator*() noexcept { return t()[this]; } diff --git a/include/chaiscript/dispatchkit/any.hpp b/include/chaiscript/dispatchkit/any.hpp index 47b75a59..1f010ea4 100644 --- a/include/chaiscript/dispatchkit/any.hpp +++ b/include/chaiscript/dispatchkit/any.hpp @@ -21,20 +21,11 @@ namespace chaiscript { class bad_any_cast : public std::bad_cast { public: - bad_any_cast() = default; - - bad_any_cast(const bad_any_cast &) = default; - - ~bad_any_cast() noexcept override = default; - /// \brief Description of what error occurred const char * what() const noexcept override { - return m_what.c_str(); + return "bad any cast"; } - - private: - std::string m_what = "bad any cast"; }; } @@ -54,7 +45,7 @@ namespace chaiscript { virtual void *data() noexcept = 0; - const std::type_info &type() const + const std::type_info &type() const noexcept { return m_type; } @@ -91,7 +82,7 @@ namespace chaiscript { public: // construct/copy/destruct - Any() = default; + Any() noexcept = default; Any(Any &&) = default; Any &operator=(Any &&t_any) = default; diff --git a/include/chaiscript/dispatchkit/bad_boxed_cast.hpp b/include/chaiscript/dispatchkit/bad_boxed_cast.hpp index 1c1d729e..637b284c 100644 --- a/include/chaiscript/dispatchkit/bad_boxed_cast.hpp +++ b/include/chaiscript/dispatchkit/bad_boxed_cast.hpp @@ -15,6 +15,7 @@ #include #include "../chaiscript_defines.hpp" +#include "../utility/static_string.hpp" #include "type_info.hpp" namespace chaiscript { @@ -34,22 +35,22 @@ namespace chaiscript { public: bad_boxed_cast(Type_Info t_from, const std::type_info &t_to, - std::string t_what) noexcept + utility::Static_String t_what) noexcept : from(t_from), to(&t_to), m_what(std::move(t_what)) { } - bad_boxed_cast(Type_Info t_from, const std::type_info &t_to) - : from(t_from), to(&t_to), m_what("Cannot perform boxed_cast: " + t_from.name() + " to: " + t_to.name()) + bad_boxed_cast(Type_Info t_from, const std::type_info &t_to) noexcept + : from(t_from), to(&t_to), m_what("Cannot perform boxed_cast") { } - explicit bad_boxed_cast(std::string t_what) noexcept + explicit bad_boxed_cast(utility::Static_String t_what) noexcept : m_what(std::move(t_what)) { } - bad_boxed_cast(const bad_boxed_cast &) = default; + bad_boxed_cast(const bad_boxed_cast &) noexcept = default; ~bad_boxed_cast() noexcept override = default; /// \brief Description of what error occurred @@ -62,7 +63,7 @@ namespace chaiscript const std::type_info *to = nullptr; ///< std::type_info of the desired (but failed) result type private: - std::string m_what; + utility::Static_String m_what; }; } } diff --git a/include/chaiscript/dispatchkit/bootstrap.hpp b/include/chaiscript/dispatchkit/bootstrap.hpp index 8aedb353..201c3af7 100644 --- a/include/chaiscript/dispatchkit/bootstrap.hpp +++ b/include/chaiscript/dispatchkit/bootstrap.hpp @@ -199,12 +199,12 @@ namespace chaiscript } } - static void print(const std::string &s) + static void print(const std::string &s) noexcept { fwrite(s.c_str(), 1, s.size(), stdout); } - static void println(const std::string &s) + static void println(const std::string &s) noexcept { puts(s.c_str()); } @@ -268,10 +268,10 @@ namespace chaiscript } - static bool has_guard(const Const_Proxy_Function &t_pf) + static bool has_guard(const Const_Proxy_Function &t_pf) noexcept { auto pf = std::dynamic_pointer_cast(t_pf); - return pf && pf->get_guard(); + return pf && pf->has_guard(); } static Const_Proxy_Function get_guard(const Const_Proxy_Function &t_pf) @@ -302,7 +302,7 @@ namespace chaiscript } - static bool has_parse_tree(const chaiscript::Const_Proxy_Function &t_pf) + static bool has_parse_tree(const chaiscript::Const_Proxy_Function &t_pf) noexcept { const auto pf = std::dynamic_pointer_cast(t_pf); return bool(pf); diff --git a/include/chaiscript/dispatchkit/boxed_number.hpp b/include/chaiscript/dispatchkit/boxed_number.hpp index e81a563f..0606cd69 100644 --- a/include/chaiscript/dispatchkit/boxed_number.hpp +++ b/include/chaiscript/dispatchkit/boxed_number.hpp @@ -161,29 +161,29 @@ namespace chaiscript } template - static Boxed_Value boolean_go(Operators::Opers t_oper, const T &t, const T &u) + static bool boolean_go(Operators::Opers t_oper, const T &t, const T &u) noexcept { switch (t_oper) { case Operators::Opers::equals: - return const_var(t == u); + return t == u; case Operators::Opers::less_than: - return const_var(t < u); + return t < u; case Operators::Opers::greater_than: - return const_var(t > u); + return t > u; case Operators::Opers::less_than_equal: - return const_var(t <= u); + return t <= u; case Operators::Opers::greater_than_equal: - return const_var(t >= u); + return t >= u; case Operators::Opers::not_equal: - return const_var(t != u); + return t != u; default: - throw chaiscript::detail::exception::bad_any_cast(); + assert(false); } } template - static Boxed_Value unary_go(Operators::Opers t_oper, T &t, const Boxed_Value &t_lhs) + static void unary_go(Operators::Opers t_oper, T &t) noexcept { switch (t_oper) { @@ -194,14 +194,13 @@ namespace chaiscript --t; break; default: - throw chaiscript::detail::exception::bad_any_cast(); + assert(false); } - - return t_lhs; } template - static Boxed_Value binary_go(Operators::Opers t_oper, T &t, const U &u, const Boxed_Value &t_lhs) + static void binary_go(Operators::Opers t_oper, T &t, const U &u) + noexcept(noexcept(check_divide_by_zero(u))) { switch (t_oper) { @@ -222,14 +221,12 @@ namespace chaiscript t -= u; break; default: - throw chaiscript::detail::exception::bad_any_cast(); + assert(false); } - - return t_lhs; } template - static Boxed_Value binary_int_go(Operators::Opers t_oper, T &t, const U &u, const Boxed_Value &t_lhs) + static void binary_int_go(Operators::Opers t_oper, T &t, const U &u) noexcept { switch (t_oper) { @@ -253,76 +250,77 @@ namespace chaiscript t ^= u; break; default: - throw chaiscript::detail::exception::bad_any_cast(); + assert(false); } - return t_lhs; } template - static Boxed_Value const_unary_int_go(Operators::Opers t_oper, const T &t) + static auto const_unary_int_go(Operators::Opers t_oper, const T &t) noexcept { switch (t_oper) { case Operators::Opers::bitwise_complement: - return const_var(~t); + return ~t; default: - throw chaiscript::detail::exception::bad_any_cast(); + assert(false); } } template - static Boxed_Value const_binary_int_go(Operators::Opers t_oper, const T &t, const T &u) + static auto const_binary_int_go(Operators::Opers t_oper, const T &t, const T &u) + noexcept(noexcept(check_divide_by_zero(u))) { switch (t_oper) { case Operators::Opers::shift_left: - return const_var(t << u); + return t << u; case Operators::Opers::shift_right: - return const_var(t >> u); + return t >> u; case Operators::Opers::remainder: check_divide_by_zero(u); - return const_var(t % u); + return t % u; case Operators::Opers::bitwise_and: - return const_var(t & u); + return t & u; case Operators::Opers::bitwise_or: - return const_var(t | u); + return t | u; case Operators::Opers::bitwise_xor: - return const_var(t ^ u); + return t ^ u; default: - throw chaiscript::detail::exception::bad_any_cast(); + assert(false); } } template - static Boxed_Value const_unary_go(Operators::Opers t_oper, const T &t) + static auto const_unary_go(Operators::Opers t_oper, const T &t) noexcept { switch (t_oper) { case Operators::Opers::unary_minus: - return const_var(-t); + return -t; case Operators::Opers::unary_plus: - return const_var(+t); + return +t; default: - throw chaiscript::detail::exception::bad_any_cast(); + assert(false); } } template - static Boxed_Value const_binary_go(Operators::Opers t_oper, const T &t, const T &u) + static auto const_binary_go(Operators::Opers t_oper, const T &t, const T &u) + noexcept(noexcept(check_divide_by_zero(u))) { switch (t_oper) { case Operators::Opers::sum: - return const_var(t + u); + return t + u; case Operators::Opers::quotient: check_divide_by_zero(u); - return const_var(t / u); + return t / u; case Operators::Opers::product: - return const_var(t * u); + return t * u; case Operators::Opers::difference: - return const_var(t - u); + return t - u; default: - throw chaiscript::detail::exception::bad_any_cast(); + assert(false); } } @@ -331,19 +329,60 @@ namespace chaiscript -> typename std::enable_if::value && !std::is_floating_point::value, Boxed_Value>::type { typedef typename std::common_type::type common_type; - if (t_oper > Operators::Opers::boolean_flag && t_oper < Operators::Opers::non_const_flag) - { - return boolean_go(t_oper, get_as_aux(t_lhs), get_as_aux(t_rhs)); - } else if (t_oper > Operators::Opers::non_const_flag && t_oper < Operators::Opers::non_const_int_flag && !t_lhs.is_const() && !t_lhs.is_return_value()) { - return binary_go(t_oper, *static_cast(t_lhs.get_ptr()), get_as_aux(t_rhs), t_lhs); - } else if (t_oper > Operators::Opers::non_const_int_flag && t_oper < Operators::Opers::const_int_flag && !t_lhs.is_const() && !t_lhs.is_return_value()) { - return binary_int_go(t_oper, *static_cast(t_lhs.get_ptr()), get_as_aux(t_rhs), t_lhs); - } else if (t_oper > Operators::Opers::const_int_flag && t_oper < Operators::Opers::const_flag) { - return const_binary_int_go(t_oper, get_as_aux(t_lhs), get_as_aux(t_rhs)); - } else if (t_oper > Operators::Opers::const_flag) { - return const_binary_go(t_oper, get_as_aux(t_lhs), get_as_aux(t_rhs)); - } else { - throw chaiscript::detail::exception::bad_any_cast(); + + switch (t_oper) { + case Operators::Opers::equals: + case Operators::Opers::less_than: + case Operators::Opers::greater_than: + case Operators::Opers::less_than_equal: + case Operators::Opers::greater_than_equal: + case Operators::Opers::not_equal: + return const_var(boolean_go(t_oper, get_as_aux(t_lhs), get_as_aux(t_rhs))); + case Operators::Opers::assign: + case Operators::Opers::assign_product: + case Operators::Opers::assign_sum: + case Operators::Opers::assign_quotient: + case Operators::Opers::assign_difference: + if (!t_lhs.is_const() && !t_lhs.is_return_value()) { + binary_go(t_oper, *static_cast(t_lhs.get_ptr()), get_as_aux(t_rhs)); + return t_lhs; + } else { + throw chaiscript::detail::exception::bad_any_cast(); + } + case Operators::Opers::assign_bitwise_and: + case Operators::Opers::assign_bitwise_or: + case Operators::Opers::assign_shift_left: + case Operators::Opers::assign_shift_right: + case Operators::Opers::assign_remainder: + case Operators::Opers::assign_bitwise_xor: + if (!t_lhs.is_const() && !t_lhs.is_return_value()) { + binary_int_go(t_oper, *static_cast(t_lhs.get_ptr()), get_as_aux(t_rhs)); + return t_lhs; + } else { + throw chaiscript::detail::exception::bad_any_cast(); + } + case Operators::Opers::shift_left: + case Operators::Opers::shift_right: + case Operators::Opers::remainder: + case Operators::Opers::bitwise_and: + case Operators::Opers::bitwise_or: + case Operators::Opers::bitwise_xor: + { + const auto result + = const_binary_int_go(t_oper, get_as_aux(t_lhs), get_as_aux(t_rhs)); + return const_var(result); + } + case Operators::Opers::sum: + case Operators::Opers::quotient: + case Operators::Opers::product: + case Operators::Opers::difference: + { + const auto result + = const_binary_go(t_oper, get_as_aux(t_lhs), get_as_aux(t_rhs)); + return const_var(result); + } + default: + throw chaiscript::detail::exception::bad_any_cast(); } } @@ -352,16 +391,39 @@ namespace chaiscript -> typename std::enable_if::value || std::is_floating_point::value, Boxed_Value>::type { typedef typename std::common_type::type common_type; - if (t_oper > Operators::Opers::boolean_flag && t_oper < Operators::Opers::non_const_flag) - { - return boolean_go(t_oper, get_as_aux(t_lhs), get_as_aux(t_rhs)); - } else if (t_oper > Operators::Opers::non_const_flag && t_oper < Operators::Opers::non_const_int_flag && !t_lhs.is_const() && !t_lhs.is_return_value()) { - return binary_go(t_oper, *static_cast(t_lhs.get_ptr()), get_as_aux(t_rhs), t_lhs); - } else if (t_oper > Operators::Opers::const_flag) { - return const_binary_go(t_oper, get_as_aux(t_lhs), get_as_aux(t_rhs)); - } else { - throw chaiscript::detail::exception::bad_any_cast(); + + switch (t_oper) { + case Operators::Opers::equals: + case Operators::Opers::less_than: + case Operators::Opers::greater_than: + case Operators::Opers::less_than_equal: + case Operators::Opers::greater_than_equal: + case Operators::Opers::not_equal: + return const_var(boolean_go(t_oper, get_as_aux(t_lhs), get_as_aux(t_rhs))); + case Operators::Opers::assign: + case Operators::Opers::assign_product: + case Operators::Opers::assign_sum: + case Operators::Opers::assign_quotient: + case Operators::Opers::assign_difference: + if (!t_lhs.is_const() && !t_lhs.is_return_value()) { + binary_go(t_oper, *static_cast(t_lhs.get_ptr()), get_as_aux(t_rhs)); + return t_lhs; + } else { + throw chaiscript::detail::exception::bad_any_cast(); + } + case Operators::Opers::sum: + case Operators::Opers::quotient: + case Operators::Opers::product: + case Operators::Opers::difference: + { + const auto result + = const_binary_go(t_oper, get_as_aux(t_lhs), get_as_aux(t_rhs)); + return const_var(result); + } + default: + throw chaiscript::detail::exception::bad_any_cast(); } + } // Unary @@ -369,27 +431,53 @@ namespace chaiscript static auto go(Operators::Opers t_oper, const Boxed_Value &t_lhs) -> typename std::enable_if::value, Boxed_Value>::type { - if (t_oper > Operators::Opers::non_const_flag && t_oper < Operators::Opers::non_const_int_flag && !t_lhs.is_const() && !t_lhs.is_return_value()) { - return unary_go(t_oper, *static_cast(t_lhs.get_ptr()), t_lhs); - } else if (t_oper > Operators::Opers::const_int_flag && t_oper < Operators::Opers::const_flag) { - return const_unary_int_go(t_oper, *static_cast(t_lhs.get_const_ptr())); - } else if (t_oper > Operators::Opers::const_flag) { - return const_unary_go(t_oper, *static_cast(t_lhs.get_const_ptr())); - } else { - throw chaiscript::detail::exception::bad_any_cast(); + switch (t_oper) { + case Operators::Opers::pre_increment: + case Operators::Opers::pre_decrement: + if (!t_lhs.is_const() && !t_lhs.is_return_value()) { + unary_go(t_oper, *static_cast(t_lhs.get_ptr())); + return t_lhs; + } else { + throw chaiscript::detail::exception::bad_any_cast(); + } + case Operators::Opers::bitwise_complement: + { + const auto val = const_unary_int_go(t_oper, *static_cast(t_lhs.get_const_ptr())); + return const_var(val); + } + case Operators::Opers::unary_minus: + case Operators::Opers::unary_plus: + { + const auto val = const_unary_go(t_oper, *static_cast(t_lhs.get_const_ptr())); + return const_var(val); + } + default: + throw chaiscript::detail::exception::bad_any_cast(); } + } template static auto go(Operators::Opers t_oper, const Boxed_Value &t_lhs) -> typename std::enable_if::value, Boxed_Value>::type { - if (t_oper > Operators::Opers::non_const_flag && t_oper < Operators::Opers::non_const_int_flag && !t_lhs.is_const() && !t_lhs.is_return_value()) { - return unary_go(t_oper, *static_cast(t_lhs.get_ptr()), t_lhs); - } else if (t_oper > Operators::Opers::const_flag) { - return const_unary_go(t_oper, *static_cast(t_lhs.get_const_ptr())); - } else { - throw chaiscript::detail::exception::bad_any_cast(); + switch (t_oper) { + case Operators::Opers::pre_increment: + case Operators::Opers::pre_decrement: + if (!t_lhs.is_const() && !t_lhs.is_return_value()) { + unary_go(t_oper, *static_cast(t_lhs.get_ptr())); + return t_lhs; + } else { + throw chaiscript::detail::exception::bad_any_cast(); + } + case Operators::Opers::unary_minus: + case Operators::Opers::unary_plus: + { + const auto val = const_unary_go(t_oper, *static_cast(t_lhs.get_const_ptr())); + return const_var(val); + } + default: + throw chaiscript::detail::exception::bad_any_cast(); } } diff --git a/include/chaiscript/dispatchkit/proxy_functions.hpp b/include/chaiscript/dispatchkit/proxy_functions.hpp index b80e66a8..566792b5 100644 --- a/include/chaiscript/dispatchkit/proxy_functions.hpp +++ b/include/chaiscript/dispatchkit/proxy_functions.hpp @@ -374,6 +374,10 @@ namespace chaiscript return call_match_internal(vals, t_conversions).first; } + bool has_guard() const noexcept + { + return bool(m_guard); + } Proxy_Function get_guard() const { diff --git a/include/chaiscript/dispatchkit/type_conversions.hpp b/include/chaiscript/dispatchkit/type_conversions.hpp index 728494ce..fbab2f81 100644 --- a/include/chaiscript/dispatchkit/type_conversions.hpp +++ b/include/chaiscript/dispatchkit/type_conversions.hpp @@ -20,6 +20,7 @@ #include #include "../chaiscript_threading.hpp" +#include "../utility/static_string.hpp" #include "bad_boxed_cast.hpp" #include "boxed_cast_helper.hpp" #include "boxed_value.hpp" @@ -33,7 +34,7 @@ namespace chaiscript { public: bad_boxed_dynamic_cast(const Type_Info &t_from, const std::type_info &t_to, - const std::string &t_what) noexcept + const utility::Static_String &t_what) noexcept : bad_boxed_cast(t_from, t_to, t_what) { } @@ -43,7 +44,7 @@ namespace chaiscript { } - explicit bad_boxed_dynamic_cast(const std::string &w) noexcept + explicit bad_boxed_dynamic_cast(const utility::Static_String &w) noexcept : bad_boxed_cast(w) { } @@ -57,7 +58,7 @@ namespace chaiscript { public: bad_boxed_type_cast(const Type_Info &t_from, const std::type_info &t_to, - const std::string &t_what) noexcept + const utility::Static_String &t_what) noexcept : bad_boxed_cast(t_from, t_to, t_what) { } @@ -67,7 +68,7 @@ namespace chaiscript { } - explicit bad_boxed_type_cast(const std::string &w) noexcept + explicit bad_boxed_type_cast(const utility::Static_String &w) noexcept : bad_boxed_cast(w) { } From 7986ea08b6d56f291326fd546f8cbad594bd4d75 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Wed, 9 Aug 2017 14:36:45 -0600 Subject: [PATCH 011/155] More work towards all noexcept, warning cleanups --- CMakeLists.txt | 2 +- .../chaiscript/dispatchkit/boxed_number.hpp | 24 +++++++------------ .../chaiscript/dispatchkit/boxed_value.hpp | 4 ++-- .../chaiscript/dispatchkit/dispatchkit.hpp | 6 ++--- .../chaiscript/dispatchkit/dynamic_object.hpp | 2 +- .../dispatchkit/dynamic_object_detail.hpp | 2 +- .../dispatchkit/function_call_detail.hpp | 2 +- .../chaiscript/dispatchkit/handle_return.hpp | 4 ++-- .../dispatchkit/type_conversions.hpp | 2 +- include/chaiscript/dispatchkit/type_info.hpp | 4 ++-- 10 files changed, 22 insertions(+), 30 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0131de15..25a5f1c5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -188,7 +188,7 @@ if(MSVC) # how to workaround or fix the error. So I'm disabling it globally. add_definitions(/wd4503) else() - add_definitions(-Wall -Wextra -Wconversion -Wshadow -Wnon-virtual-dtor -Wold-style-cast -Wcast-align -Wcast-qual -Wunused -Woverloaded-virtual -pedantic ${CPP14_FLAG}) + add_definitions(-Wall -Wextra -Wconversion -Wshadow -Wnon-virtual-dtor -Wold-style-cast -Wcast-align -Wcast-qual -Wunused -Woverloaded-virtual -Wno-noexcept-type -Wpedantic ${CPP14_FLAG}) if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") add_definitions(-Weverything -Wno-c++98-compat-pedantic -Wno-c++98-compat -Wno-documentation -Wno-switch-enum -Wno-weak-vtables -Wno-missing-prototypes -Wno-padded -Wno-missing-noreturn -Wno-exit-time-destructors -Wno-documentation-unknown-command -Wno-unused-template -Wno-undef ) diff --git a/include/chaiscript/dispatchkit/boxed_number.hpp b/include/chaiscript/dispatchkit/boxed_number.hpp index 0606cd69..084e91ad 100644 --- a/include/chaiscript/dispatchkit/boxed_number.hpp +++ b/include/chaiscript/dispatchkit/boxed_number.hpp @@ -179,6 +179,7 @@ namespace chaiscript return t != u; default: assert(false); + return false; } } @@ -254,20 +255,9 @@ namespace chaiscript } } - template - static auto const_unary_int_go(Operators::Opers t_oper, const T &t) noexcept - { - switch (t_oper) - { - case Operators::Opers::bitwise_complement: - return ~t; - default: - assert(false); - } - } template - static auto const_binary_int_go(Operators::Opers t_oper, const T &t, const T &u) + static auto const_binary_int_go(Operators::Opers t_oper, T t, T u) noexcept(noexcept(check_divide_by_zero(u))) { switch (t_oper) @@ -287,11 +277,12 @@ namespace chaiscript return t ^ u; default: assert(false); + return static_cast(t); } } template - static auto const_unary_go(Operators::Opers t_oper, const T &t) noexcept + static auto const_unary_go(Operators::Opers t_oper, T t) noexcept { switch (t_oper) { @@ -301,11 +292,12 @@ namespace chaiscript return +t; default: assert(false); + return static_cast(t); } } template - static auto const_binary_go(Operators::Opers t_oper, const T &t, const T &u) + static auto const_binary_go(Operators::Opers t_oper, T t, T u) noexcept(noexcept(check_divide_by_zero(u))) { switch (t_oper) @@ -321,6 +313,7 @@ namespace chaiscript return t - u; default: assert(false); + return static_cast(t); } } @@ -442,8 +435,7 @@ namespace chaiscript } case Operators::Opers::bitwise_complement: { - const auto val = const_unary_int_go(t_oper, *static_cast(t_lhs.get_const_ptr())); - return const_var(val); + return const_var(~(*static_cast(t_lhs.get_const_ptr()))); } case Operators::Opers::unary_minus: case Operators::Opers::unary_plus: diff --git a/include/chaiscript/dispatchkit/boxed_value.hpp b/include/chaiscript/dispatchkit/boxed_value.hpp index 3f6b1bd6..3bef5851 100644 --- a/include/chaiscript/dispatchkit/boxed_value.hpp +++ b/include/chaiscript/dispatchkit/boxed_value.hpp @@ -208,14 +208,14 @@ namespace chaiscript Boxed_Value(const Boxed_Value&) = default; Boxed_Value& operator=(const Boxed_Value&) = default; - void swap(Boxed_Value &rhs) + void swap(Boxed_Value &rhs) noexcept { std::swap(m_data, rhs.m_data); } /// Copy the values stored in rhs.m_data to m_data. /// m_data pointers are not shared in this case - Boxed_Value assign(const Boxed_Value &rhs) + Boxed_Value assign(const Boxed_Value &rhs) noexcept { (*m_data) = (*rhs.m_data); return *this; diff --git a/include/chaiscript/dispatchkit/dispatchkit.hpp b/include/chaiscript/dispatchkit/dispatchkit.hpp index 4245f823..1d8dc85c 100644 --- a/include/chaiscript/dispatchkit/dispatchkit.hpp +++ b/include/chaiscript/dispatchkit/dispatchkit.hpp @@ -196,7 +196,7 @@ namespace chaiscript apply_globals(m_globals.begin(), m_globals.end(), t_engine); } - bool has_function(const Proxy_Function &new_f, const std::string &name) + bool has_function(const Proxy_Function &new_f, const std::string &name) noexcept { return std::any_of(m_funcs.begin(), m_funcs.end(), [&](const std::pair &existing_f) { @@ -276,7 +276,7 @@ namespace chaiscript { } - bool operator==(const dispatch::Proxy_Function_Base &rhs) const override + bool operator==(const dispatch::Proxy_Function_Base &rhs) const noexcept override { try { const auto &dispatch_fun = dynamic_cast(rhs); @@ -820,7 +820,7 @@ namespace chaiscript /// Return true if a function exists - bool function_exists(const std::string &name) const noexcept + bool function_exists(const std::string &name) const { chaiscript::detail::threading::shared_lock l(m_mutex); diff --git a/include/chaiscript/dispatchkit/dynamic_object.hpp b/include/chaiscript/dispatchkit/dynamic_object.hpp index fc50bed0..f87de455 100644 --- a/include/chaiscript/dispatchkit/dynamic_object.hpp +++ b/include/chaiscript/dispatchkit/dynamic_object.hpp @@ -60,7 +60,7 @@ namespace chaiscript m_option_explicit = t_explicit; } - std::string get_type_name() const + const std::string &get_type_name() const noexcept { return m_type_name; } diff --git a/include/chaiscript/dispatchkit/dynamic_object_detail.hpp b/include/chaiscript/dispatchkit/dynamic_object_detail.hpp index c9cd1408..0a443ff8 100644 --- a/include/chaiscript/dispatchkit/dynamic_object_detail.hpp +++ b/include/chaiscript/dispatchkit/dynamic_object_detail.hpp @@ -109,7 +109,7 @@ namespace chaiscript } } - bool compare_first_type(const Boxed_Value &bv, const Type_Conversions_State &t_conversions) const override + bool compare_first_type(const Boxed_Value &bv, const Type_Conversions_State &t_conversions) const noexcept override { return dynamic_object_typename_match(bv, m_type_name, m_ti, t_conversions); } diff --git a/include/chaiscript/dispatchkit/function_call_detail.hpp b/include/chaiscript/dispatchkit/function_call_detail.hpp index d6cb241f..7d8b3d5e 100644 --- a/include/chaiscript/dispatchkit/function_call_detail.hpp +++ b/include/chaiscript/dispatchkit/function_call_detail.hpp @@ -129,7 +129,7 @@ namespace chaiscript } template - static Boxed_Value box(Boxed_Value bv) + static Boxed_Value box(Boxed_Value bv) noexcept { return bv; } diff --git a/include/chaiscript/dispatchkit/handle_return.hpp b/include/chaiscript/dispatchkit/handle_return.hpp index 8570c8d0..4dc381d4 100644 --- a/include/chaiscript/dispatchkit/handle_return.hpp +++ b/include/chaiscript/dispatchkit/handle_return.hpp @@ -199,7 +199,7 @@ namespace chaiscript template<> struct Handle_Return { - static Boxed_Value handle(const Boxed_Value &r) + static Boxed_Value handle(const Boxed_Value &r) noexcept { return r; } @@ -226,7 +226,7 @@ namespace chaiscript template<> struct Handle_Return { - static Boxed_Value handle(const Boxed_Number &r) + static Boxed_Value handle(const Boxed_Number &r) noexcept { return r.bv; } diff --git a/include/chaiscript/dispatchkit/type_conversions.hpp b/include/chaiscript/dispatchkit/type_conversions.hpp index fbab2f81..353afddc 100644 --- a/include/chaiscript/dispatchkit/type_conversions.hpp +++ b/include/chaiscript/dispatchkit/type_conversions.hpp @@ -460,7 +460,7 @@ namespace chaiscript { return *itr; } else { - throw std::out_of_range("No such conversion exists from " + from.bare_name() + " to " + to.bare_name()); + throw std::out_of_range(std::string("No such conversion exists from ") + from.bare_name() + " to " + to.bare_name()); } } diff --git a/include/chaiscript/dispatchkit/type_info.hpp b/include/chaiscript/dispatchkit/type_info.hpp index 09344ae6..8199f872 100644 --- a/include/chaiscript/dispatchkit/type_info.hpp +++ b/include/chaiscript/dispatchkit/type_info.hpp @@ -90,7 +90,7 @@ namespace chaiscript bool is_undef() const noexcept { return (m_flags & (1 << is_undef_flag)) != 0; } bool is_pointer() const noexcept { return (m_flags & (1 << is_pointer_flag)) != 0; } - std::string name() const + const char * name() const noexcept { if (!is_undef()) { @@ -100,7 +100,7 @@ namespace chaiscript } } - std::string bare_name() const + const char * bare_name() const noexcept { if (!is_undef()) { From e1cf8b9eb1d59d49149454424ec49bd0d8a3b28f Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Thu, 10 Aug 2017 10:27:26 -0600 Subject: [PATCH 012/155] Remove exception specification shared_ptr use --- .../dispatchkit/exception_specification.hpp | 37 ++++++++++++------- .../chaiscript/language/chaiscript_engine.hpp | 24 ++++++------ 2 files changed, 34 insertions(+), 27 deletions(-) diff --git a/include/chaiscript/dispatchkit/exception_specification.hpp b/include/chaiscript/dispatchkit/exception_specification.hpp index 79607fe2..0947b9ac 100644 --- a/include/chaiscript/dispatchkit/exception_specification.hpp +++ b/include/chaiscript/dispatchkit/exception_specification.hpp @@ -25,26 +25,36 @@ class bad_boxed_cast; namespace chaiscript { + namespace detail { - struct Exception_Handler_Base + struct Exception_Handler { - virtual void handle(const Boxed_Value &bv, const Dispatch_Engine &t_engine) = 0; + virtual void operator()(const Boxed_Value &, const detail::Dispatch_Engine &) const + { + } - virtual ~Exception_Handler_Base() = default; + Exception_Handler() = default; + Exception_Handler(Exception_Handler &&) = default; + Exception_Handler &operator=(Exception_Handler &&) = default; + virtual ~Exception_Handler() noexcept = default; protected: - template - static void throw_type(const Boxed_Value &bv, const Dispatch_Engine &t_engine) - { - try { T t = t_engine.boxed_cast(bv); throw t; } catch (const chaiscript::exception::bad_boxed_cast &) {} - } + Exception_Handler(const Exception_Handler &) = default; + Exception_Handler &operator=(const Exception_Handler &) = default; + }; - template - struct Exception_Handler_Impl : Exception_Handler_Base + template + struct Exception_Handler_Impl final : Exception_Handler { - void handle(const Boxed_Value &bv, const Dispatch_Engine &t_engine) override + template + static void throw_type(const Boxed_Value &bv, const Dispatch_Engine &t_engine) + { + try { throw t_engine.boxed_cast(bv); } catch (const chaiscript::exception::bad_boxed_cast &) {} + } + + void operator()(const Boxed_Value &bv, const Dispatch_Engine &t_engine) const final { (void)std::initializer_list{(throw_type(bv, t_engine), 0)...}; } @@ -101,14 +111,13 @@ namespace chaiscript /// /// \sa chaiscript::exception_specification for creation of chaiscript::Exception_Handler objects /// \sa \ref exceptions - typedef std::shared_ptr Exception_Handler; /// \brief creates a chaiscript::Exception_Handler which handles one type of exception unboxing /// \sa \ref exceptions template - Exception_Handler exception_specification() + auto exception_specification() noexcept { - return std::make_shared>(); + return detail::Exception_Handler_Impl(); } } diff --git a/include/chaiscript/language/chaiscript_engine.hpp b/include/chaiscript/language/chaiscript_engine.hpp index 11506f58..c88fe10e 100644 --- a/include/chaiscript/language/chaiscript_engine.hpp +++ b/include/chaiscript/language/chaiscript_engine.hpp @@ -623,12 +623,12 @@ explicit ChaiScript_Basic(std::unique_ptr &&pars /// \brief Evaluates a string. Equivalent to ChaiScript::eval. /// /// \param[in] t_script Script to execute - /// \param[in] t_handler Optional Exception_Handler used for automatic unboxing of script thrown exceptions + /// \param[in] t_handler Optional detail::Exception_Handler used for automatic unboxing of script thrown exceptions /// /// \return result of the script execution /// /// \throw chaiscript::exception::eval_error In the case that evaluation fails. - Boxed_Value operator()(const std::string &t_script, const Exception_Handler &t_handler = Exception_Handler()) + Boxed_Value operator()(const std::string &t_script, const detail::Exception_Handler &t_handler = detail::Exception_Handler()) { return eval(t_script, t_handler); } @@ -637,7 +637,7 @@ explicit ChaiScript_Basic(std::unique_ptr &&pars /// /// \tparam T Type to extract from the result value of the script execution /// \param[in] t_input Script to execute - /// \param[in] t_handler Optional Exception_Handler used for automatic unboxing of script thrown exceptions + /// \param[in] t_handler Optional detail::Exception_Handler used for automatic unboxing of script thrown exceptions /// \param[in] t_filename Optional filename to report to the user for where the error occured. Useful /// in special cases where you are loading a file internally instead of using eval_file /// @@ -647,7 +647,7 @@ explicit ChaiScript_Basic(std::unique_ptr &&pars /// \throw chaiscript::exception::bad_boxed_cast In the case that evaluation succeeds but the result value cannot be converted /// to the requested type. template - T eval(const std::string &t_input, const Exception_Handler &t_handler = Exception_Handler(), const std::string &t_filename="__EVAL__") + T eval(const std::string &t_input, const detail::Exception_Handler &t_handler = detail::Exception_Handler(), const std::string &t_filename="__EVAL__") { return m_engine.boxed_cast(eval(t_input, t_handler, t_filename)); } @@ -663,44 +663,42 @@ explicit ChaiScript_Basic(std::unique_ptr &&pars /// \brief Evaluates a string. /// /// \param[in] t_input Script to execute - /// \param[in] t_handler Optional Exception_Handler used for automatic unboxing of script thrown exceptions + /// \param[in] t_handler Optional detail::Exception_Handler used for automatic unboxing of script thrown exceptions /// \param[in] t_filename Optional filename to report to the user for where the error occurred. Useful /// in special cases where you are loading a file internally instead of using eval_file /// /// \return result of the script execution /// /// \throw exception::eval_error In the case that evaluation fails. - Boxed_Value eval(const std::string &t_input, const Exception_Handler &t_handler = Exception_Handler(), const std::string &t_filename="__EVAL__") + Boxed_Value eval(const std::string &t_input, const detail::Exception_Handler &t_handler = detail::Exception_Handler(), const std::string &t_filename="__EVAL__") { try { return do_eval(t_input, t_filename); } catch (Boxed_Value &bv) { - if (t_handler) { - t_handler->handle(bv, m_engine); - } + t_handler(bv, m_engine); throw; } } /// \brief Loads the file specified by filename, evaluates it, and returns the result. /// \param[in] t_filename File to load and parse. - /// \param[in] t_handler Optional Exception_Handler used for automatic unboxing of script thrown exceptions + /// \param[in] t_handler Optional detail::Exception_Handler used for automatic unboxing of script thrown exceptions /// \return result of the script execution /// \throw chaiscript::exception::eval_error In the case that evaluation fails. - Boxed_Value eval_file(const std::string &t_filename, const Exception_Handler &t_handler = Exception_Handler()) { + Boxed_Value eval_file(const std::string &t_filename, const detail::Exception_Handler &t_handler = detail::Exception_Handler()) { return eval(load_file(t_filename), t_handler, t_filename); } /// \brief Loads the file specified by filename, evaluates it, and returns the type safe result. /// \tparam T Type to extract from the result value of the script execution /// \param[in] t_filename File to load and parse. - /// \param[in] t_handler Optional Exception_Handler used for automatic unboxing of script thrown exceptions + /// \param[in] t_handler Optional detail::Exception_Handler used for automatic unboxing of script thrown exceptions /// \return result of the script execution /// \throw chaiscript::exception::eval_error In the case that evaluation fails. /// \throw chaiscript::exception::bad_boxed_cast In the case that evaluation succeeds but the result value cannot be converted /// to the requested type. template - T eval_file(const std::string &t_filename, const Exception_Handler &t_handler = Exception_Handler()) { + T eval_file(const std::string &t_filename, const detail::Exception_Handler &t_handler = detail::Exception_Handler()) { return m_engine.boxed_cast(eval_file(t_filename, t_handler)); } }; From 5d56051532188778b8b23af6ba806007afbc5a0c Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Thu, 10 Aug 2017 19:47:03 -0600 Subject: [PATCH 013/155] Various noexcept additions --- include/chaiscript/chaiscript_threading.hpp | 4 +++- include/chaiscript/dispatchkit/proxy_functions.hpp | 7 ++++--- .../chaiscript/dispatchkit/type_conversions.hpp | 14 +++++++------- .../chaiscript/language/chaiscript_algebraic.hpp | 2 +- include/chaiscript/language/chaiscript_common.hpp | 14 ++++++++------ include/chaiscript/language/chaiscript_eval.hpp | 2 +- .../chaiscript/language/chaiscript_optimizer.hpp | 1 + 7 files changed, 25 insertions(+), 19 deletions(-) diff --git a/include/chaiscript/chaiscript_threading.hpp b/include/chaiscript/chaiscript_threading.hpp index cd2c1bd3..ab455983 100644 --- a/include/chaiscript/chaiscript_threading.hpp +++ b/include/chaiscript/chaiscript_threading.hpp @@ -102,7 +102,9 @@ namespace chaiscript void *m_key; private: - static std::unordered_map &t() + /// todo: is it valid to make this noexcept? The allocation could fail, but if it + /// does there is no possible way to recover + static std::unordered_map &t() noexcept { thread_local std::unordered_map my_t; return my_t; diff --git a/include/chaiscript/dispatchkit/proxy_functions.hpp b/include/chaiscript/dispatchkit/proxy_functions.hpp index 566792b5..75a67a64 100644 --- a/include/chaiscript/dispatchkit/proxy_functions.hpp +++ b/include/chaiscript/dispatchkit/proxy_functions.hpp @@ -212,7 +212,7 @@ namespace chaiscript /// \returns the types of all parameters. const std::vector &get_param_types() const noexcept { return m_types; } - virtual bool operator==(const Proxy_Function_Base &) const = 0; + virtual bool operator==(const Proxy_Function_Base &) const noexcept = 0; virtual bool call_match(const std::vector &vals, const Type_Conversions_State &t_conversions) const = 0; virtual bool is_attribute_function() const noexcept { return false; } @@ -268,8 +268,9 @@ namespace chaiscript } } - virtual bool compare_first_type(const Boxed_Value &bv, const Type_Conversions_State &t_conversions) const + virtual bool compare_first_type(const Boxed_Value &bv, const Type_Conversions_State &t_conversions) const noexcept { + /// TODO is m_types guaranteed to be at least 2?? return compare_type_to_param(m_types[1], bv, t_conversions); } @@ -379,7 +380,7 @@ namespace chaiscript return bool(m_guard); } - Proxy_Function get_guard() const + Proxy_Function get_guard() const noexcept { return m_guard; } diff --git a/include/chaiscript/dispatchkit/type_conversions.hpp b/include/chaiscript/dispatchkit/type_conversions.hpp index 353afddc..dd327bf7 100644 --- a/include/chaiscript/dispatchkit/type_conversions.hpp +++ b/include/chaiscript/dispatchkit/type_conversions.hpp @@ -371,18 +371,18 @@ namespace chaiscript } template - bool convertable_type() const + bool convertable_type() const noexcept { return thread_cache().count(user_type().bare_type_info()) != 0; } template - bool converts() const + bool converts() const noexcept { return converts(user_type(), user_type()); } - bool converts(const Type_Info &to, const Type_Info &from) const + bool converts(const Type_Info &to, const Type_Info &from) const noexcept { const auto &types = thread_cache(); if (types.count(to.bare_type_info()) != 0 && types.count(from.bare_type_info()) != 0) @@ -464,7 +464,7 @@ namespace chaiscript } } - Conversion_Saves &conversion_saves() const { + Conversion_Saves &conversion_saves() const noexcept { return *m_conversion_saves; } @@ -519,15 +519,15 @@ namespace chaiscript { } - const Type_Conversions *operator->() const { + const Type_Conversions *operator->() const noexcept { return &m_conversions.get(); } - const Type_Conversions *get() const { + const Type_Conversions *get() const noexcept { return &m_conversions.get(); } - Type_Conversions::Conversion_Saves &saves() const { + Type_Conversions::Conversion_Saves &saves() const noexcept { return m_saves; } diff --git a/include/chaiscript/language/chaiscript_algebraic.hpp b/include/chaiscript/language/chaiscript_algebraic.hpp index b52debbe..2030d061 100644 --- a/include/chaiscript/language/chaiscript_algebraic.hpp +++ b/include/chaiscript/language/chaiscript_algebraic.hpp @@ -36,7 +36,7 @@ namespace chaiscript invalid }; - static const char *to_string(Opers t_oper) { + static const char *to_string(Opers t_oper) noexcept { static const char *opers[] = { "", "==", "<", ">", "<=", ">=", "!=", diff --git a/include/chaiscript/language/chaiscript_common.hpp b/include/chaiscript/language/chaiscript_common.hpp index 2085d52e..c8adbb6c 100644 --- a/include/chaiscript/language/chaiscript_common.hpp +++ b/include/chaiscript/language/chaiscript_common.hpp @@ -31,16 +31,18 @@ struct AST_Node; namespace chaiscript { struct Name_Validator { - static bool is_reserved_word(const std::string &name) + static bool is_reserved_word(const std::string &name) noexcept { - static const std::set m_reserved_words + static const char *m_reserved_words[] = {"def", "fun", "while", "for", "if", "else", "&&", "||", ",", "auto", "return", "break", "true", "false", "class", "attr", "var", "global", "GLOBAL", "_", "__LINE__", "__FILE__", "__FUNC__", "__CLASS__"}; - return m_reserved_words.count(name) > 0; + + return std::any_of(std::begin(m_reserved_words), std::end(m_reserved_words), + [&name](const char *str){ return str == name; }); } - static bool valid_object_name(const std::string &name) + static bool valid_object_name(const std::string &name) noexcept { return name.find("::") == std::string::npos && !is_reserved_word(name); } @@ -136,7 +138,7 @@ namespace chaiscript /// \brief Thrown if an error occurs while attempting to load a binary module struct load_module_error : std::runtime_error { - explicit load_module_error(const std::string &t_reason) noexcept + explicit load_module_error(const std::string &t_reason) : std::runtime_error(t_reason) { } @@ -479,7 +481,7 @@ namespace chaiscript /// Errors generated when loading a file struct file_not_found_error : std::runtime_error { - explicit file_not_found_error(const std::string &t_filename) noexcept + explicit file_not_found_error(const std::string &t_filename) : std::runtime_error("File Not Found: " + t_filename) { } diff --git a/include/chaiscript/language/chaiscript_eval.hpp b/include/chaiscript/language/chaiscript_eval.hpp index efd54203..23557ca1 100644 --- a/include/chaiscript/language/chaiscript_eval.hpp +++ b/include/chaiscript/language/chaiscript_eval.hpp @@ -741,7 +741,7 @@ namespace chaiscript return std::move(vec.back()); } - static bool has_guard(const std::vector> &t_children, const std::size_t offset) + static bool has_guard(const std::vector> &t_children, const std::size_t offset) noexcept { if ((t_children.size() > 2 + offset) && (t_children[1+offset]->identifier == AST_Node_Type::Arg_List)) { if (t_children.size() > 3 + offset) { diff --git a/include/chaiscript/language/chaiscript_optimizer.hpp b/include/chaiscript/language/chaiscript_optimizer.hpp index ae32f130..3df867f1 100644 --- a/include/chaiscript/language/chaiscript_optimizer.hpp +++ b/include/chaiscript/language/chaiscript_optimizer.hpp @@ -447,3 +447,4 @@ namespace chaiscript { #endif + From 5ba155e0587f9ea91155a3ddfb5bd1a86f483907 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Thu, 10 Aug 2017 19:52:32 -0600 Subject: [PATCH 014/155] Make operators noexcept (removing std::vector usage) --- .../chaiscript/language/chaiscript_parser.hpp | 78 +++++++++++++++---- 1 file changed, 61 insertions(+), 17 deletions(-) diff --git a/include/chaiscript/language/chaiscript_parser.hpp b/include/chaiscript/language/chaiscript_parser.hpp index f744ee3f..a23a4f2f 100644 --- a/include/chaiscript/language/chaiscript_parser.hpp +++ b/include/chaiscript/language/chaiscript_parser.hpp @@ -192,23 +192,67 @@ namespace chaiscript } - static const std::vector> &create_operator_matches() { - static const std::vector> operator_matches { - {"?"}, - {"||"}, - {"&&"}, - {"|"}, - {"^"}, - {"&"}, - {"==", "!="}, - {"<", "<=", ">", ">="}, - {"<<", ">>"}, - //We share precedence here but then separate them later - {"+", "-"}, - {"*", "/", "%"}, - {"++", "--", "-", "+", "!", "~"} + struct Operator_Matches + { + struct Array_View + { + template + Array_View(const std::array &data) noexcept + : m_begin(&(*std::begin(data))), + m_end(&(*std::end(data))) + { + } + + auto begin() const noexcept + { + return m_begin; + } + + auto end() const noexcept + { + return m_end; + } + + const utility::Static_String *m_begin; + const utility::Static_String *m_end; }; + const std::array m_0 {{"?"}}; + const std::array m_1 {{"||"}}; + const std::array m_2 {{"&&"}}; + const std::array m_3 {{"|"}}; + const std::array m_4 {{"^"}}; + const std::array m_5 {{"&"}}; + const std::array m_6 {{"==", "!="}}; + const std::array m_7 {{"<", "<=", ">", ">="}}; + const std::array m_8 {{"<<", ">>"}}; + //We share precedence here but then separate them later + const std::array m_9 {{"+", "-"}}; + const std::array m_10 {{"*", "/", "%"}}; + const std::array m_11 {{"++", "--", "-", "+", "!", "~"}}; + + const std::array all_data {{ + m_0, m_1, m_2, m_3, m_4, m_5, m_6, m_7, m_8, m_9, m_10, m_11 + }}; + + auto begin() const noexcept + { + return all_data.begin(); + } + + auto end() const noexcept + { + return all_data.end(); + } + + decltype(auto) operator[](const std::size_t pos) const noexcept { + return (all_data[pos]); + } + + }; + + static const auto &create_operator_matches() noexcept { + const static Operator_Matches operator_matches; return operator_matches; } @@ -262,7 +306,7 @@ namespace chaiscript } const std::array, detail::max_alphabet> &m_alphabet = create_alphabet(); - const std::vector> &m_operator_matches = create_operator_matches(); + const Operator_Matches &m_operator_matches = create_operator_matches(); const std::array &m_operators = create_operators(); std::shared_ptr m_filename; @@ -1392,7 +1436,7 @@ namespace chaiscript bool is_operator(const std::string &t_s) const { return std::any_of(m_operator_matches.begin(), m_operator_matches.end(), - [t_s](const std::vector &opers) { + [t_s](const auto &opers) { return std::any_of(opers.begin(), opers.end(), [t_s](const utility::Static_String &s) { return t_s == s.c_str(); From 73d543eef0b107efe6529e9e8909ba95a36f2a2a Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Thu, 10 Aug 2017 20:26:30 -0600 Subject: [PATCH 015/155] Make operator lookup noexcept --- include/chaiscript/language/chaiscript_parser.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/chaiscript/language/chaiscript_parser.hpp b/include/chaiscript/language/chaiscript_parser.hpp index a23a4f2f..b5eff1bb 100644 --- a/include/chaiscript/language/chaiscript_parser.hpp +++ b/include/chaiscript/language/chaiscript_parser.hpp @@ -1434,11 +1434,11 @@ namespace chaiscript return retval; } - bool is_operator(const std::string &t_s) const { + bool is_operator(const std::string &t_s) const noexcept { return std::any_of(m_operator_matches.begin(), m_operator_matches.end(), - [t_s](const auto &opers) { + [&t_s](const auto &opers) { return std::any_of(opers.begin(), opers.end(), - [t_s](const utility::Static_String &s) { + [&t_s](const utility::Static_String &s) { return t_s == s.c_str(); }); }); From ca8f78ff89696d0d0b4eb000d317a45dbc5eddf6 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Thu, 10 Aug 2017 22:22:13 -0600 Subject: [PATCH 016/155] JSON noexcept updates --- include/chaiscript/utility/json.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/chaiscript/utility/json.hpp b/include/chaiscript/utility/json.hpp index 679f1064..0b96dcae 100644 --- a/include/chaiscript/utility/json.hpp +++ b/include/chaiscript/utility/json.hpp @@ -300,7 +300,7 @@ class JSON } } - bool has_key( const std::string &key ) const { + bool has_key( const std::string &key ) const noexcept { if( internal.Type == Class::Object ) { return internal.Map->count(key) != 0; } @@ -318,10 +318,10 @@ class JSON } } - Class JSONType() const { return internal.Type; } + Class JSONType() const noexcept { return internal.Type; } /// Functions for getting primitives from the JSON object. - bool is_null() const { return internal.Type == Class::Null; } + bool is_null() const noexcept { return internal.Type == Class::Null; } std::string to_string() const { bool b; return to_string( b ); } std::string to_string( bool &ok ) const { From 710b3c4003b197dcf07696e6e9fc9e309e30cdb3 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Fri, 11 Aug 2017 08:57:44 -0600 Subject: [PATCH 017/155] Fix instantiation of Static_String for older compilers --- .../chaiscript/language/chaiscript_parser.hpp | 26 ++++++++++--------- 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/include/chaiscript/language/chaiscript_parser.hpp b/include/chaiscript/language/chaiscript_parser.hpp index b5eff1bb..3c71dba0 100644 --- a/include/chaiscript/language/chaiscript_parser.hpp +++ b/include/chaiscript/language/chaiscript_parser.hpp @@ -217,19 +217,21 @@ namespace chaiscript const utility::Static_String *m_end; }; - const std::array m_0 {{"?"}}; - const std::array m_1 {{"||"}}; - const std::array m_2 {{"&&"}}; - const std::array m_3 {{"|"}}; - const std::array m_4 {{"^"}}; - const std::array m_5 {{"&"}}; - const std::array m_6 {{"==", "!="}}; - const std::array m_7 {{"<", "<=", ">", ">="}}; - const std::array m_8 {{"<<", ">>"}}; + using SS = utility::Static_String; + + const std::array m_0 {{SS("?")}}; + const std::array m_1 {{SS("||")}}; + const std::array m_2 {{SS("&&")}}; + const std::array m_3 {{SS("|")}}; + const std::array m_4 {{SS("^")}}; + const std::array m_5 {{SS("&")}}; + const std::array m_6 {{SS("=="), SS("!=")}}; + const std::array m_7 {{SS("<"), SS("<="), SS(">"), SS(">=")}}; + const std::array m_8 {{SS("<<"), SS(">>")}}; //We share precedence here but then separate them later - const std::array m_9 {{"+", "-"}}; - const std::array m_10 {{"*", "/", "%"}}; - const std::array m_11 {{"++", "--", "-", "+", "!", "~"}}; + const std::array m_9 {{SS("+"), SS("-")}}; + const std::array m_10 {{SS("*"), SS("/"), SS("%")}}; + const std::array m_11 {{SS("++"), SS("--"), SS("-"), SS("+"), SS("!"), SS("~")}}; const std::array all_data {{ m_0, m_1, m_2, m_3, m_4, m_5, m_6, m_7, m_8, m_9, m_10, m_11 From 1ca857b890519ccea8bc8e29ab52aa1def3f0524 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Fri, 11 Aug 2017 14:20:17 -0600 Subject: [PATCH 018/155] Satisfy older clangs by adding default ctor --- include/chaiscript/language/chaiscript_parser.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/chaiscript/language/chaiscript_parser.hpp b/include/chaiscript/language/chaiscript_parser.hpp index 3c71dba0..64066718 100644 --- a/include/chaiscript/language/chaiscript_parser.hpp +++ b/include/chaiscript/language/chaiscript_parser.hpp @@ -237,6 +237,8 @@ namespace chaiscript m_0, m_1, m_2, m_3, m_4, m_5, m_6, m_7, m_8, m_9, m_10, m_11 }}; + Operator_Matches() {} + auto begin() const noexcept { return all_data.begin(); From 0fc420f69da1eb61241943b47c1d8d1c620a165f Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Tue, 15 Aug 2017 10:13:20 -0600 Subject: [PATCH 019/155] Revert "Remove exception specification shared_ptr use" This reverts commit e1cf8b9eb1d59d49149454424ec49bd0d8a3b28f. --- .../dispatchkit/exception_specification.hpp | 35 +++++++------------ .../chaiscript/language/chaiscript_engine.hpp | 24 +++++++------ 2 files changed, 26 insertions(+), 33 deletions(-) diff --git a/include/chaiscript/dispatchkit/exception_specification.hpp b/include/chaiscript/dispatchkit/exception_specification.hpp index 0947b9ac..79607fe2 100644 --- a/include/chaiscript/dispatchkit/exception_specification.hpp +++ b/include/chaiscript/dispatchkit/exception_specification.hpp @@ -25,36 +25,26 @@ class bad_boxed_cast; namespace chaiscript { - namespace detail { - struct Exception_Handler + struct Exception_Handler_Base { - virtual void operator()(const Boxed_Value &, const detail::Dispatch_Engine &) const - { - } + virtual void handle(const Boxed_Value &bv, const Dispatch_Engine &t_engine) = 0; - Exception_Handler() = default; - Exception_Handler(Exception_Handler &&) = default; - Exception_Handler &operator=(Exception_Handler &&) = default; - virtual ~Exception_Handler() noexcept = default; + virtual ~Exception_Handler_Base() = default; protected: - Exception_Handler(const Exception_Handler &) = default; - Exception_Handler &operator=(const Exception_Handler &) = default; - - }; - - template - struct Exception_Handler_Impl final : Exception_Handler - { - template + template static void throw_type(const Boxed_Value &bv, const Dispatch_Engine &t_engine) { - try { throw t_engine.boxed_cast(bv); } catch (const chaiscript::exception::bad_boxed_cast &) {} + try { T t = t_engine.boxed_cast(bv); throw t; } catch (const chaiscript::exception::bad_boxed_cast &) {} } + }; - void operator()(const Boxed_Value &bv, const Dispatch_Engine &t_engine) const final + template + struct Exception_Handler_Impl : Exception_Handler_Base + { + void handle(const Boxed_Value &bv, const Dispatch_Engine &t_engine) override { (void)std::initializer_list{(throw_type(bv, t_engine), 0)...}; } @@ -111,13 +101,14 @@ namespace chaiscript /// /// \sa chaiscript::exception_specification for creation of chaiscript::Exception_Handler objects /// \sa \ref exceptions + typedef std::shared_ptr Exception_Handler; /// \brief creates a chaiscript::Exception_Handler which handles one type of exception unboxing /// \sa \ref exceptions template - auto exception_specification() noexcept + Exception_Handler exception_specification() { - return detail::Exception_Handler_Impl(); + return std::make_shared>(); } } diff --git a/include/chaiscript/language/chaiscript_engine.hpp b/include/chaiscript/language/chaiscript_engine.hpp index c88fe10e..11506f58 100644 --- a/include/chaiscript/language/chaiscript_engine.hpp +++ b/include/chaiscript/language/chaiscript_engine.hpp @@ -623,12 +623,12 @@ explicit ChaiScript_Basic(std::unique_ptr &&pars /// \brief Evaluates a string. Equivalent to ChaiScript::eval. /// /// \param[in] t_script Script to execute - /// \param[in] t_handler Optional detail::Exception_Handler used for automatic unboxing of script thrown exceptions + /// \param[in] t_handler Optional Exception_Handler used for automatic unboxing of script thrown exceptions /// /// \return result of the script execution /// /// \throw chaiscript::exception::eval_error In the case that evaluation fails. - Boxed_Value operator()(const std::string &t_script, const detail::Exception_Handler &t_handler = detail::Exception_Handler()) + Boxed_Value operator()(const std::string &t_script, const Exception_Handler &t_handler = Exception_Handler()) { return eval(t_script, t_handler); } @@ -637,7 +637,7 @@ explicit ChaiScript_Basic(std::unique_ptr &&pars /// /// \tparam T Type to extract from the result value of the script execution /// \param[in] t_input Script to execute - /// \param[in] t_handler Optional detail::Exception_Handler used for automatic unboxing of script thrown exceptions + /// \param[in] t_handler Optional Exception_Handler used for automatic unboxing of script thrown exceptions /// \param[in] t_filename Optional filename to report to the user for where the error occured. Useful /// in special cases where you are loading a file internally instead of using eval_file /// @@ -647,7 +647,7 @@ explicit ChaiScript_Basic(std::unique_ptr &&pars /// \throw chaiscript::exception::bad_boxed_cast In the case that evaluation succeeds but the result value cannot be converted /// to the requested type. template - T eval(const std::string &t_input, const detail::Exception_Handler &t_handler = detail::Exception_Handler(), const std::string &t_filename="__EVAL__") + T eval(const std::string &t_input, const Exception_Handler &t_handler = Exception_Handler(), const std::string &t_filename="__EVAL__") { return m_engine.boxed_cast(eval(t_input, t_handler, t_filename)); } @@ -663,42 +663,44 @@ explicit ChaiScript_Basic(std::unique_ptr &&pars /// \brief Evaluates a string. /// /// \param[in] t_input Script to execute - /// \param[in] t_handler Optional detail::Exception_Handler used for automatic unboxing of script thrown exceptions + /// \param[in] t_handler Optional Exception_Handler used for automatic unboxing of script thrown exceptions /// \param[in] t_filename Optional filename to report to the user for where the error occurred. Useful /// in special cases where you are loading a file internally instead of using eval_file /// /// \return result of the script execution /// /// \throw exception::eval_error In the case that evaluation fails. - Boxed_Value eval(const std::string &t_input, const detail::Exception_Handler &t_handler = detail::Exception_Handler(), const std::string &t_filename="__EVAL__") + Boxed_Value eval(const std::string &t_input, const Exception_Handler &t_handler = Exception_Handler(), const std::string &t_filename="__EVAL__") { try { return do_eval(t_input, t_filename); } catch (Boxed_Value &bv) { - t_handler(bv, m_engine); + if (t_handler) { + t_handler->handle(bv, m_engine); + } throw; } } /// \brief Loads the file specified by filename, evaluates it, and returns the result. /// \param[in] t_filename File to load and parse. - /// \param[in] t_handler Optional detail::Exception_Handler used for automatic unboxing of script thrown exceptions + /// \param[in] t_handler Optional Exception_Handler used for automatic unboxing of script thrown exceptions /// \return result of the script execution /// \throw chaiscript::exception::eval_error In the case that evaluation fails. - Boxed_Value eval_file(const std::string &t_filename, const detail::Exception_Handler &t_handler = detail::Exception_Handler()) { + Boxed_Value eval_file(const std::string &t_filename, const Exception_Handler &t_handler = Exception_Handler()) { return eval(load_file(t_filename), t_handler, t_filename); } /// \brief Loads the file specified by filename, evaluates it, and returns the type safe result. /// \tparam T Type to extract from the result value of the script execution /// \param[in] t_filename File to load and parse. - /// \param[in] t_handler Optional detail::Exception_Handler used for automatic unboxing of script thrown exceptions + /// \param[in] t_handler Optional Exception_Handler used for automatic unboxing of script thrown exceptions /// \return result of the script execution /// \throw chaiscript::exception::eval_error In the case that evaluation fails. /// \throw chaiscript::exception::bad_boxed_cast In the case that evaluation succeeds but the result value cannot be converted /// to the requested type. template - T eval_file(const std::string &t_filename, const detail::Exception_Handler &t_handler = detail::Exception_Handler()) { + T eval_file(const std::string &t_filename, const Exception_Handler &t_handler = Exception_Handler()) { return m_engine.boxed_cast(eval_file(t_filename, t_handler)); } }; From 58f740844d8986dfa0a515c889086b155226ce05 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Tue, 15 Aug 2017 13:17:23 -0600 Subject: [PATCH 020/155] Undo perf hit to keyword lookups --- include/chaiscript/language/chaiscript_common.hpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/include/chaiscript/language/chaiscript_common.hpp b/include/chaiscript/language/chaiscript_common.hpp index c8adbb6c..08d026aa 100644 --- a/include/chaiscript/language/chaiscript_common.hpp +++ b/include/chaiscript/language/chaiscript_common.hpp @@ -23,6 +23,7 @@ #include "../dispatchkit/dispatchkit.hpp" #include "../dispatchkit/proxy_functions.hpp" #include "../dispatchkit/type_info.hpp" +#include namespace chaiscript { struct AST_Node; @@ -33,13 +34,15 @@ namespace chaiscript struct Name_Validator { static bool is_reserved_word(const std::string &name) noexcept { - static const char *m_reserved_words[] - = {"def", "fun", "while", "for", "if", "else", "&&", "||", ",", "auto", - "return", "break", "true", "false", "class", "attr", "var", "global", "GLOBAL", "_", - "__LINE__", "__FILE__", "__FUNC__", "__CLASS__"}; + static const std::unordered_set words { + "def", "fun", "while", "for", "if", "else", + "&&", "||", ",", "auto", "return", "break", + "true", "false", "class", "attr", "var", "global", + "GLOBAL", "_", + "__LINE__", "__FILE__", "__FUNC__", "__CLASS__" + }; - return std::any_of(std::begin(m_reserved_words), std::end(m_reserved_words), - [&name](const char *str){ return str == name; }); + return words.count(name) == 1; } static bool valid_object_name(const std::string &name) noexcept From ddb2f352cd7f7a5e18e1bff009e71aa9c02cee80 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Thu, 17 Aug 2017 11:27:14 -0600 Subject: [PATCH 021/155] Initial simple application of constexpr to API --- include/chaiscript/chaiscript_defines.hpp | 22 ++++----- include/chaiscript/chaiscript_threading.hpp | 20 ++++---- include/chaiscript/dispatchkit/any.hpp | 2 +- include/chaiscript/dispatchkit/bind_first.hpp | 2 +- .../chaiscript/dispatchkit/bootstrap_stl.hpp | 12 ++--- .../dispatchkit/boxed_cast_helper.hpp | 2 +- .../chaiscript/dispatchkit/boxed_number.hpp | 20 ++++---- include/chaiscript/dispatchkit/type_info.hpp | 46 +++++++++--------- .../language/chaiscript_algebraic.hpp | 4 +- .../chaiscript/language/chaiscript_common.hpp | 8 ++-- .../chaiscript/language/chaiscript_parser.hpp | 47 +++++++++---------- .../chaiscript/language/chaiscript_tracer.hpp | 4 +- include/chaiscript/utility/static_string.hpp | 6 +-- 13 files changed, 97 insertions(+), 98 deletions(-) diff --git a/include/chaiscript/chaiscript_defines.hpp b/include/chaiscript/chaiscript_defines.hpp index 4f8293d1..3754fc6a 100644 --- a/include/chaiscript/chaiscript_defines.hpp +++ b/include/chaiscript/chaiscript_defines.hpp @@ -75,13 +75,13 @@ static_assert(_MSC_FULL_VER >= 190024210, "Visual C++ 2015 Update 3 or later req #include namespace chaiscript { - static const int version_major = 6; - static const int version_minor = 0; - static const int version_patch = 0; + constexpr static const int version_major = 6; + constexpr static const int version_minor = 0; + constexpr static const int version_patch = 0; - static const char *compiler_version = CHAISCRIPT_COMPILER_VERSION; - static const char *compiler_name = CHAISCRIPT_COMPILER_NAME; - static const bool debug_build = CHAISCRIPT_DEBUG; + constexpr static const char *compiler_version = CHAISCRIPT_COMPILER_VERSION; + constexpr static const char *compiler_name = CHAISCRIPT_COMPILER_NAME; + constexpr static const bool debug_build = CHAISCRIPT_DEBUG; template inline std::shared_ptr make_shared(Arg && ... arg) @@ -104,17 +104,17 @@ namespace chaiscript { } struct Build_Info { - static int version_major() noexcept + constexpr static int version_major() noexcept { return chaiscript::version_major; } - static int version_minor() noexcept + constexpr static int version_minor() noexcept { return chaiscript::version_minor; } - static int version_patch() noexcept + constexpr static int version_patch() noexcept { return chaiscript::version_patch; } @@ -144,7 +144,7 @@ namespace chaiscript { return chaiscript::compiler_name; } - static bool debug_build() noexcept + constexpr static bool debug_build() noexcept { return chaiscript::debug_build; } @@ -152,7 +152,7 @@ namespace chaiscript { template - auto parse_num(const char *t_str) noexcept -> typename std::enable_if::value, T>::type + constexpr auto parse_num(const char *t_str) noexcept -> typename std::enable_if::value, T>::type { T t = 0; for (char c = *t_str; (c = *t_str) != 0; ++t_str) { diff --git a/include/chaiscript/chaiscript_threading.hpp b/include/chaiscript/chaiscript_threading.hpp index ab455983..ce63df63 100644 --- a/include/chaiscript/chaiscript_threading.hpp +++ b/include/chaiscript/chaiscript_threading.hpp @@ -116,25 +116,25 @@ namespace chaiscript class unique_lock { public: - explicit unique_lock(T &) noexcept {} - void lock() noexcept {} - void unlock() noexcept {} + constexpr explicit unique_lock(T &) noexcept {} + constexpr void lock() noexcept {} + constexpr void unlock() noexcept {} }; template class shared_lock { public: - explicit shared_lock(T &) noexcept {} - void lock() noexcept {} - void unlock() noexcept {} + constexpr explicit shared_lock(T &) noexcept {} + constexpr void lock() noexcept {} + constexpr void unlock() noexcept {} }; template class lock_guard { public: - explicit lock_guard(T &) noexcept {} + constexpr explicit lock_guard(T &) noexcept {} }; class shared_mutex { }; @@ -146,16 +146,16 @@ namespace chaiscript class Thread_Storage { public: - explicit Thread_Storage() noexcept + constexpr explicit Thread_Storage() noexcept { } - inline T *operator->() const noexcept + constexpr inline T *operator->() const noexcept { return &obj; } - inline T &operator*() const noexcept + constexpr inline T &operator*() const noexcept { return obj; } diff --git a/include/chaiscript/dispatchkit/any.hpp b/include/chaiscript/dispatchkit/any.hpp index 1f010ea4..e9af7c36 100644 --- a/include/chaiscript/dispatchkit/any.hpp +++ b/include/chaiscript/dispatchkit/any.hpp @@ -34,7 +34,7 @@ namespace chaiscript { private: struct Data { - explicit Data(const std::type_info &t_type) noexcept + constexpr explicit Data(const std::type_info &t_type) noexcept : m_type(t_type) { } diff --git a/include/chaiscript/dispatchkit/bind_first.hpp b/include/chaiscript/dispatchkit/bind_first.hpp index 2a377d3d..8495e3c3 100644 --- a/include/chaiscript/dispatchkit/bind_first.hpp +++ b/include/chaiscript/dispatchkit/bind_first.hpp @@ -19,7 +19,7 @@ namespace chaiscript { template - T* get_pointer(T *t) noexcept + constexpr T* get_pointer(T *t) noexcept { return t; } diff --git a/include/chaiscript/dispatchkit/bootstrap_stl.hpp b/include/chaiscript/dispatchkit/bootstrap_stl.hpp index 481d20df..df25c9ec 100644 --- a/include/chaiscript/dispatchkit/bootstrap_stl.hpp +++ b/include/chaiscript/dispatchkit/bootstrap_stl.hpp @@ -46,17 +46,17 @@ namespace chaiscript { typedef Container container_type; - Bidir_Range(Container &c) + constexpr Bidir_Range(Container &c) : m_begin(c.begin()), m_end(c.end()) { } - bool empty() const noexcept + constexpr bool empty() const noexcept { return m_begin == m_end; } - void pop_front() + constexpr void pop_front() { if (empty()) { @@ -65,7 +65,7 @@ namespace chaiscript ++m_begin; } - void pop_back() + constexpr void pop_back() { if (empty()) { @@ -74,7 +74,7 @@ namespace chaiscript --m_end; } - decltype(auto) front() const + constexpr decltype(auto) front() const { if (empty()) { @@ -83,7 +83,7 @@ namespace chaiscript return (*m_begin); } - decltype(auto) back() const + constexpr decltype(auto) back() const { if (empty()) { diff --git a/include/chaiscript/dispatchkit/boxed_cast_helper.hpp b/include/chaiscript/dispatchkit/boxed_cast_helper.hpp index b00dd045..834e4609 100644 --- a/include/chaiscript/dispatchkit/boxed_cast_helper.hpp +++ b/include/chaiscript/dispatchkit/boxed_cast_helper.hpp @@ -27,7 +27,7 @@ namespace chaiscript // Cast_Helper_Inner helper classes template - T* throw_if_null(T *t) + constexpr T* throw_if_null(T *t) { if (t) { return t; } throw std::runtime_error("Attempted to dereference null Boxed_Value"); diff --git a/include/chaiscript/dispatchkit/boxed_number.hpp b/include/chaiscript/dispatchkit/boxed_number.hpp index 084e91ad..7d22dddc 100644 --- a/include/chaiscript/dispatchkit/boxed_number.hpp +++ b/include/chaiscript/dispatchkit/boxed_number.hpp @@ -80,7 +80,7 @@ namespace chaiscript }; template - static inline void check_divide_by_zero(T t, typename std::enable_if::value>::type* = nullptr) + constexpr static inline void check_divide_by_zero(T t, typename std::enable_if::value>::type* = nullptr) { #ifndef CHAISCRIPT_NO_PROTECT_DIVIDEBYZERO if (t == 0) { @@ -90,11 +90,11 @@ namespace chaiscript } template - static inline void check_divide_by_zero(T, typename std::enable_if::value>::type* = nullptr) noexcept + constexpr static inline void check_divide_by_zero(T, typename std::enable_if::value>::type* = nullptr) noexcept { } - static Common_Types get_common_type(size_t t_size, bool t_signed) noexcept + constexpr static Common_Types get_common_type(size_t t_size, bool t_signed) noexcept { return (t_size == 1 && t_signed)?(Common_Types::t_int8) :(t_size == 1)?(Common_Types::t_uint8) @@ -161,7 +161,7 @@ namespace chaiscript } template - static bool boolean_go(Operators::Opers t_oper, const T &t, const T &u) noexcept + constexpr static bool boolean_go(Operators::Opers t_oper, const T &t, const T &u) noexcept { switch (t_oper) { @@ -184,7 +184,7 @@ namespace chaiscript } template - static void unary_go(Operators::Opers t_oper, T &t) noexcept + constexpr static void unary_go(Operators::Opers t_oper, T &t) noexcept { switch (t_oper) { @@ -200,7 +200,7 @@ namespace chaiscript } template - static void binary_go(Operators::Opers t_oper, T &t, const U &u) + constexpr static void binary_go(Operators::Opers t_oper, T &t, const U &u) noexcept(noexcept(check_divide_by_zero(u))) { switch (t_oper) @@ -227,7 +227,7 @@ namespace chaiscript } template - static void binary_int_go(Operators::Opers t_oper, T &t, const U &u) noexcept + constexpr static void binary_int_go(Operators::Opers t_oper, T &t, const U &u) noexcept { switch (t_oper) { @@ -257,7 +257,7 @@ namespace chaiscript template - static auto const_binary_int_go(Operators::Opers t_oper, T t, T u) + constexpr static auto const_binary_int_go(Operators::Opers t_oper, T t, T u) noexcept(noexcept(check_divide_by_zero(u))) { switch (t_oper) @@ -282,7 +282,7 @@ namespace chaiscript } template - static auto const_unary_go(Operators::Opers t_oper, T t) noexcept + constexpr static auto const_unary_go(Operators::Opers t_oper, T t) noexcept { switch (t_oper) { @@ -297,7 +297,7 @@ namespace chaiscript } template - static auto const_binary_go(Operators::Opers t_oper, T t, T u) + constexpr static auto const_binary_go(Operators::Opers t_oper, T t, T u) noexcept(noexcept(check_divide_by_zero(u))) { switch (t_oper) diff --git a/include/chaiscript/dispatchkit/type_info.hpp b/include/chaiscript/dispatchkit/type_info.hpp index 8199f872..f8fc868d 100644 --- a/include/chaiscript/dispatchkit/type_info.hpp +++ b/include/chaiscript/dispatchkit/type_info.hpp @@ -33,7 +33,7 @@ namespace chaiscript class Type_Info { public: - Type_Info(const bool t_is_const, const bool t_is_reference, const bool t_is_pointer, const bool t_is_void, + constexpr Type_Info(const bool t_is_const, const bool t_is_reference, const bool t_is_pointer, const bool t_is_void, const bool t_is_arithmetic, const std::type_info *t_ti, const std::type_info *t_bare_ti) : m_type_info(t_ti), m_bare_type_info(t_bare_ti), m_flags((static_cast(t_is_const) << is_const_flag) @@ -44,51 +44,51 @@ namespace chaiscript { } - Type_Info() = default; + constexpr Type_Info() = default; - bool operator<(const Type_Info &ti) const noexcept + constexpr bool operator<(const Type_Info &ti) const noexcept { return m_type_info < ti.m_type_info; } - bool operator!=(const Type_Info &ti) const noexcept + constexpr bool operator!=(const Type_Info &ti) const noexcept { return !(operator==(ti)); } - bool operator!=(const std::type_info &ti) const noexcept + constexpr bool operator!=(const std::type_info &ti) const noexcept { return !(operator==(ti)); } - bool operator==(const Type_Info &ti) const noexcept + constexpr bool operator==(const Type_Info &ti) const noexcept { return ti.m_type_info == m_type_info || *ti.m_type_info == *m_type_info; } - bool operator==(const std::type_info &ti) const noexcept + constexpr bool operator==(const std::type_info &ti) const noexcept { return !is_undef() && (*m_type_info) == ti; } - bool bare_equal(const Type_Info &ti) const noexcept + constexpr bool bare_equal(const Type_Info &ti) const noexcept { return ti.m_bare_type_info == m_bare_type_info || *ti.m_bare_type_info == *m_bare_type_info; } - bool bare_equal_type_info(const std::type_info &ti) const noexcept + constexpr bool bare_equal_type_info(const std::type_info &ti) const noexcept { return !is_undef() && (*m_bare_type_info) == ti; } - bool is_const() const noexcept { return (m_flags & (1 << is_const_flag)) != 0; } - bool is_reference() const noexcept { return (m_flags & (1 << is_reference_flag)) != 0; } - bool is_void() const noexcept { return (m_flags & (1 << is_void_flag)) != 0; } - bool is_arithmetic() const noexcept { return (m_flags & (1 << is_arithmetic_flag)) != 0; } - bool is_undef() const noexcept { return (m_flags & (1 << is_undef_flag)) != 0; } - bool is_pointer() const noexcept { return (m_flags & (1 << is_pointer_flag)) != 0; } + constexpr bool is_const() const noexcept { return (m_flags & (1 << is_const_flag)) != 0; } + constexpr bool is_reference() const noexcept { return (m_flags & (1 << is_reference_flag)) != 0; } + constexpr bool is_void() const noexcept { return (m_flags & (1 << is_void_flag)) != 0; } + constexpr bool is_arithmetic() const noexcept { return (m_flags & (1 << is_arithmetic_flag)) != 0; } + constexpr bool is_undef() const noexcept { return (m_flags & (1 << is_undef_flag)) != 0; } + constexpr bool is_pointer() const noexcept { return (m_flags & (1 << is_pointer_flag)) != 0; } const char * name() const noexcept { @@ -110,7 +110,7 @@ namespace chaiscript } } - const std::type_info *bare_type_info() const noexcept + constexpr const std::type_info *bare_type_info() const noexcept { return m_bare_type_info; } @@ -135,7 +135,7 @@ namespace chaiscript template struct Get_Type_Info { - static Type_Info get() noexcept + constexpr static Type_Info get() noexcept { return Type_Info(std::is_const::type>::type>::value, std::is_reference::value, std::is_pointer::value, @@ -152,7 +152,7 @@ namespace chaiscript { // typedef T type; - static Type_Info get() noexcept + constexpr static Type_Info get() noexcept { return Type_Info(std::is_const::value, std::is_reference::value, std::is_pointer::value, std::is_void::value, @@ -170,7 +170,7 @@ namespace chaiscript template struct Get_Type_Info &> { - static Type_Info get() noexcept + constexpr static Type_Info get() noexcept { return Type_Info(std::is_const::value, std::is_reference::value, std::is_pointer::value, std::is_void::value, @@ -183,7 +183,7 @@ namespace chaiscript template struct Get_Type_Info > { - static Type_Info get() noexcept + constexpr static Type_Info get() noexcept { return Type_Info(std::is_const::value, std::is_reference::value, std::is_pointer::value, std::is_void::value, @@ -196,7 +196,7 @@ namespace chaiscript template struct Get_Type_Info &> { - static Type_Info get() noexcept + constexpr static Type_Info get() noexcept { return Type_Info(std::is_const::value, std::is_reference::value, std::is_pointer::value, std::is_void::value, @@ -218,7 +218,7 @@ namespace chaiscript /// chaiscript::Type_Info ti = chaiscript::user_type(i); /// \endcode template - Type_Info user_type(const T &/*t*/) noexcept + constexpr Type_Info user_type(const T &/*t*/) noexcept { return detail::Get_Type_Info::get(); } @@ -233,7 +233,7 @@ namespace chaiscript /// chaiscript::Type_Info ti = chaiscript::user_type(); /// \endcode template - Type_Info user_type() noexcept + constexpr Type_Info user_type() noexcept { return detail::Get_Type_Info::get(); } diff --git a/include/chaiscript/language/chaiscript_algebraic.hpp b/include/chaiscript/language/chaiscript_algebraic.hpp index 2030d061..5cf132dd 100644 --- a/include/chaiscript/language/chaiscript_algebraic.hpp +++ b/include/chaiscript/language/chaiscript_algebraic.hpp @@ -36,8 +36,8 @@ namespace chaiscript invalid }; - static const char *to_string(Opers t_oper) noexcept { - static const char *opers[] = { + constexpr static const char *to_string(Opers t_oper) noexcept { + constexpr const char *opers[] = { "", "==", "<", ">", "<=", ">=", "!=", "", diff --git a/include/chaiscript/language/chaiscript_common.hpp b/include/chaiscript/language/chaiscript_common.hpp index 08d026aa..da25af22 100644 --- a/include/chaiscript/language/chaiscript_common.hpp +++ b/include/chaiscript/language/chaiscript_common.hpp @@ -81,8 +81,8 @@ namespace chaiscript namespace { /// Helper lookup to get the name of each node type - inline const char *ast_node_type_to_string(AST_Node_Type ast_node_type) noexcept { - static const char * const ast_node_types[] = { "Id", "Fun_Call", "Unused_Return_Fun_Call", "Arg_List", "Equation", "Var_Decl", + constexpr const char *ast_node_type_to_string(AST_Node_Type ast_node_type) noexcept { + constexpr const char * const ast_node_types[] = { "Id", "Fun_Call", "Unused_Return_Fun_Call", "Arg_List", "Equation", "Var_Decl", "Array_Call", "Dot_Access", "Lambda", "Block", "Scopeless_Block", "Def", "While", "If", "For", "Ranged_For", "Inline_Array", "Inline_Map", "Return", "File", "Prefix", "Break", "Continue", "Map_Pair", "Value_Range", "Inline_Range", "Try", "Catch", "Finally", "Method", "Attr_Decl", @@ -97,10 +97,10 @@ namespace chaiscript int line = 0; int column = 0; - File_Position(int t_file_line, int t_file_column) noexcept + constexpr File_Position(int t_file_line, int t_file_column) noexcept : line(t_file_line), column(t_file_column) { } - File_Position() noexcept = default; + constexpr File_Position() noexcept = default; }; struct Parse_Location { diff --git a/include/chaiscript/language/chaiscript_parser.hpp b/include/chaiscript/language/chaiscript_parser.hpp index 64066718..7a24acb5 100644 --- a/include/chaiscript/language/chaiscript_parser.hpp +++ b/include/chaiscript/language/chaiscript_parser.hpp @@ -197,18 +197,18 @@ namespace chaiscript struct Array_View { template - Array_View(const std::array &data) noexcept - : m_begin(&(*std::begin(data))), - m_end(&(*std::end(data))) + constexpr Array_View(const std::array &data) noexcept + : m_begin(&data.front()), + m_end(m_begin + Len) { } - auto begin() const noexcept + constexpr auto begin() const noexcept { return m_begin; } - auto end() const noexcept + constexpr auto end() const noexcept { return m_end; } @@ -237,19 +237,19 @@ namespace chaiscript m_0, m_1, m_2, m_3, m_4, m_5, m_6, m_7, m_8, m_9, m_10, m_11 }}; - Operator_Matches() {} + constexpr Operator_Matches() noexcept {} - auto begin() const noexcept + constexpr auto begin() const noexcept { return all_data.begin(); } - auto end() const noexcept + constexpr auto end() const noexcept { return all_data.end(); } - decltype(auto) operator[](const std::size_t pos) const noexcept { + constexpr decltype(auto) operator[](const std::size_t pos) const noexcept { return (all_data[pos]); } @@ -319,9 +319,9 @@ namespace chaiscript struct Position { - Position() = default; + constexpr Position() = default; - Position(std::string::const_iterator t_pos, std::string::const_iterator t_end) noexcept + constexpr Position(std::string::const_iterator t_pos, std::string::const_iterator t_end) noexcept : line(1), col(1), m_pos(t_pos), m_end(t_end), m_last_col(1) { } @@ -344,7 +344,7 @@ namespace chaiscript return *this; } - Position &operator--() noexcept { + constexpr Position &operator--() noexcept { --m_pos; if (*m_pos == '\n') { --line; @@ -355,12 +355,12 @@ namespace chaiscript return *this; } - Position &operator+=(size_t t_distance) noexcept { + constexpr Position &operator+=(size_t t_distance) noexcept { *this = (*this) + t_distance; return *this; } - Position operator+(size_t t_distance) const noexcept { + constexpr Position operator+(size_t t_distance) const noexcept { Position ret(*this); for (size_t i = 0; i < t_distance; ++i) { ++ret; @@ -368,12 +368,12 @@ namespace chaiscript return ret; } - Position &operator-=(size_t t_distance) noexcept { + constexpr Position &operator-=(size_t t_distance) noexcept { *this = (*this) - t_distance; return *this; } - Position operator-(size_t t_distance) const noexcept { + constexpr Position operator-(size_t t_distance) const noexcept { Position ret(*this); for (size_t i = 0; i < t_distance; ++i) { --ret; @@ -381,15 +381,15 @@ namespace chaiscript return ret; } - bool operator==(const Position &t_rhs) const noexcept { + constexpr bool operator==(const Position &t_rhs) const noexcept { return m_pos == t_rhs.m_pos; } - bool operator!=(const Position &t_rhs) const noexcept { + constexpr bool operator!=(const Position &t_rhs) const noexcept { return m_pos != t_rhs.m_pos; } - bool has_more() const noexcept { + constexpr bool has_more() const noexcept { return m_pos != m_end; } @@ -397,10 +397,9 @@ namespace chaiscript return static_cast(std::distance(m_pos, m_end)); } - const char& operator*() const noexcept { + constexpr const char& operator*() const noexcept { if (m_pos == m_end) { - static const char ktmp ='\0'; - return ktmp; + return ""[0]; } else { return *m_pos; } @@ -427,7 +426,7 @@ namespace chaiscript } } - public: + public: explicit ChaiScript_Parser(Tracer tracer = Tracer(), Optimizer optimizer=Optimizer()) : m_tracer(std::move(tracer)), m_optimizer(std::move(optimizer)) @@ -451,7 +450,7 @@ namespace chaiscript ChaiScript_Parser &operator=(ChaiScript_Parser &&) = delete; /// test a char in an m_alphabet - bool char_in_alphabet(char c, detail::Alphabet a) const noexcept { return m_alphabet[a][static_cast(c)]; } + constexpr bool char_in_alphabet(char c, detail::Alphabet a) const noexcept { return m_alphabet[a][static_cast(c)]; } /// Prints the parsed ast_nodes as a tree void debug_print(const AST_Node &t, std::string prepend = "") const override { diff --git a/include/chaiscript/language/chaiscript_tracer.hpp b/include/chaiscript/language/chaiscript_tracer.hpp index 2cd82dcc..3774826b 100644 --- a/include/chaiscript/language/chaiscript_tracer.hpp +++ b/include/chaiscript/language/chaiscript_tracer.hpp @@ -14,7 +14,7 @@ namespace chaiscript { struct Noop_Tracer_Detail { template - void trace(const chaiscript::detail::Dispatch_State &, const AST_Node_Impl *) noexcept + constexpr void trace(const chaiscript::detail::Dispatch_State &, const AST_Node_Impl *) noexcept { } }; @@ -23,7 +23,7 @@ namespace chaiscript { struct Tracer : T... { Tracer() = default; - explicit Tracer(T ... t) + constexpr explicit Tracer(T ... t) : T(std::move(t))... { } diff --git a/include/chaiscript/utility/static_string.hpp b/include/chaiscript/utility/static_string.hpp index 0f425032..fb63f28e 100644 --- a/include/chaiscript/utility/static_string.hpp +++ b/include/chaiscript/utility/static_string.hpp @@ -15,16 +15,16 @@ namespace chaiscript struct Static_String { template - Static_String(const char (&str)[N]) noexcept + constexpr Static_String(const char (&str)[N]) noexcept : m_size(N-1), data(&str[0]) { } - size_t size() const noexcept { + constexpr size_t size() const noexcept { return m_size; } - const char *c_str() const noexcept { + constexpr const char *c_str() const noexcept { return data; } From 535c0344b71ad086590dcb1e614fd5befca8efb2 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Sun, 20 Aug 2017 13:11:57 -0600 Subject: [PATCH 022/155] Make function constexpr --- include/chaiscript/language/chaiscript_algebraic.hpp | 4 ++-- include/chaiscript/language/chaiscript_eval.hpp | 8 ++++---- include/chaiscript/language/chaiscript_optimizer.hpp | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/include/chaiscript/language/chaiscript_algebraic.hpp b/include/chaiscript/language/chaiscript_algebraic.hpp index 5cf132dd..3e5675aa 100644 --- a/include/chaiscript/language/chaiscript_algebraic.hpp +++ b/include/chaiscript/language/chaiscript_algebraic.hpp @@ -55,14 +55,14 @@ namespace chaiscript return opers[static_cast(t_oper)]; } - static Opers to_operator(const std::string &t_str, bool t_is_unary = false) noexcept + constexpr static Opers to_operator(const char * const t_str, bool t_is_unary = false) noexcept { #ifdef CHAISCRIPT_MSVC #pragma warning(push) #pragma warning(disable : 4307) #endif - const auto op_hash = utility::fnv1a_32(t_str.c_str()); + const auto op_hash = utility::fnv1a_32(t_str); switch (op_hash) { case utility::fnv1a_32("=="): { return Opers::equals; } case utility::fnv1a_32("<"): { return Opers::less_than; } diff --git a/include/chaiscript/language/chaiscript_eval.hpp b/include/chaiscript/language/chaiscript_eval.hpp index 23557ca1..6716dd9e 100644 --- a/include/chaiscript/language/chaiscript_eval.hpp +++ b/include/chaiscript/language/chaiscript_eval.hpp @@ -159,7 +159,7 @@ namespace chaiscript struct Fold_Right_Binary_Operator_AST_Node : AST_Node_Impl { Fold_Right_Binary_Operator_AST_Node(const std::string &t_oper, Parse_Location t_loc, std::vector> t_children, Boxed_Value t_rhs) : AST_Node_Impl(t_oper, AST_Node_Type::Binary, std::move(t_loc), std::move(t_children)), - m_oper(Operators::to_operator(t_oper)), + m_oper(Operators::to_operator(t_oper.c_str())), m_rhs(std::move(t_rhs)) { } @@ -204,7 +204,7 @@ namespace chaiscript struct Binary_Operator_AST_Node : AST_Node_Impl { Binary_Operator_AST_Node(const std::string &t_oper, Parse_Location t_loc, std::vector> t_children) : AST_Node_Impl(t_oper, AST_Node_Type::Binary, std::move(t_loc), std::move(t_children)), - m_oper(Operators::to_operator(t_oper)) + m_oper(Operators::to_operator(t_oper.c_str())) { } Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override { @@ -420,7 +420,7 @@ namespace chaiscript struct Equation_AST_Node final : AST_Node_Impl { Equation_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector> t_children) : AST_Node_Impl(std::move(t_ast_node_text), AST_Node_Type::Equation, std::move(t_loc), std::move(t_children)), - m_oper(Operators::to_operator(this->text)) + m_oper(Operators::to_operator(this->text.c_str())) { assert(this->children.size() == 2); } @@ -1162,7 +1162,7 @@ namespace chaiscript struct Prefix_AST_Node final : AST_Node_Impl { Prefix_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector> t_children) : AST_Node_Impl(std::move(t_ast_node_text), AST_Node_Type::Prefix, std::move(t_loc), std::move(t_children)), - m_oper(Operators::to_operator(this->text, true)) + m_oper(Operators::to_operator(this->text.c_str(), true)) { } Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override{ diff --git a/include/chaiscript/language/chaiscript_optimizer.hpp b/include/chaiscript/language/chaiscript_optimizer.hpp index 3df867f1..877cb4a7 100644 --- a/include/chaiscript/language/chaiscript_optimizer.hpp +++ b/include/chaiscript/language/chaiscript_optimizer.hpp @@ -241,7 +241,7 @@ namespace chaiscript { { try { const auto &oper = node->text; - const auto parsed = Operators::to_operator(oper); + const auto parsed = Operators::to_operator(oper.c_str()); if (parsed != Operators::Opers::invalid) { const auto rhs = dynamic_cast *>(node->children[1].get())->m_value; if (rhs.get_type_info().is_arithmetic()) { @@ -268,7 +268,7 @@ namespace chaiscript { { try { const auto &oper = node->text; - const auto parsed = Operators::to_operator(oper, true); + const auto parsed = Operators::to_operator(oper.c_str(), true); const auto lhs = dynamic_cast *>(node->children[0].get())->m_value; const auto match = oper + node->children[0]->text; @@ -308,7 +308,7 @@ namespace chaiscript { { try { const auto &oper = node->text; - const auto parsed = Operators::to_operator(oper); + const auto parsed = Operators::to_operator(oper.c_str()); if (parsed != Operators::Opers::invalid) { const auto lhs = dynamic_cast &>(*node->children[0]).m_value; const auto rhs = dynamic_cast &>(*node->children[1]).m_value; From b51b52dea9b58c12a93f3bb077ec35f5ce280da9 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Tue, 22 Aug 2017 10:03:26 -0600 Subject: [PATCH 023/155] constexpr bind_first --- include/chaiscript/dispatchkit/any.hpp | 2 +- include/chaiscript/dispatchkit/bind_first.hpp | 22 +++++++++---------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/include/chaiscript/dispatchkit/any.hpp b/include/chaiscript/dispatchkit/any.hpp index e9af7c36..32ccdf89 100644 --- a/include/chaiscript/dispatchkit/any.hpp +++ b/include/chaiscript/dispatchkit/any.hpp @@ -82,7 +82,7 @@ namespace chaiscript { public: // construct/copy/destruct - Any() noexcept = default; + constexpr Any() noexcept = default; Any(Any &&) = default; Any &operator=(Any &&t_any) = default; diff --git a/include/chaiscript/dispatchkit/bind_first.hpp b/include/chaiscript/dispatchkit/bind_first.hpp index 8495e3c3..d0a668fb 100644 --- a/include/chaiscript/dispatchkit/bind_first.hpp +++ b/include/chaiscript/dispatchkit/bind_first.hpp @@ -31,25 +31,25 @@ namespace chaiscript } template - auto bind_first(Ret (*f)(P1, Param...), O&& o) + constexpr auto bind_first(Ret (*f)(P1, Param...), O&& o) { - return [f, o](Param...param) -> Ret { - return f(std::forward(o), std::forward(param)...); + return [f, o = std::forward(o)](Param...param) -> Ret { + return f(o, std::forward(param)...); }; } template - auto bind_first(Ret (Class::*f)(Param...), O&& o) + constexpr auto bind_first(Ret (Class::*f)(Param...), O&& o) { - return [f, o](Param...param) -> Ret { + return [f, o = std::forward(o)](Param...param) -> Ret { return (get_pointer(o)->*f)(std::forward(param)...); }; } template - auto bind_first(Ret (Class::*f)(Param...) const, O&& o) + constexpr auto bind_first(Ret (Class::*f)(Param...) const, O&& o) { - return [f, o](Param...param) -> Ret { + return [f, o = std::forward(o)](Param...param) -> Ret { return (get_pointer(o)->*f)(std::forward(param)...); }; @@ -58,22 +58,22 @@ namespace chaiscript template auto bind_first(const std::function &f, O&& o) { - return [f, o](Param...param) -> Ret { + return [f, o = std::forward(o)](Param...param) -> Ret { return f(o, std::forward(param)...); }; } template - auto bind_first(const F &fo, O&& o, Ret (Class::*f)(P1, Param...) const) + constexpr auto bind_first(const F &fo, O&& o, Ret (Class::*f)(P1, Param...) const) { - return [fo, o, f](Param ...param) -> Ret { + return [fo, o = std::forward(o), f](Param ...param) -> Ret { return (fo.*f)(o, std::forward(param)...); }; } template - auto bind_first(const F &f, O&& o) + constexpr auto bind_first(const F &f, O&& o) { return bind_first(f, std::forward(o), &F::operator()); } From ac8f876347af514299878d6c3d248e647e2a7c02 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Tue, 22 Aug 2017 12:02:42 -0600 Subject: [PATCH 024/155] constexpr fixes for Visual Studio --- .../chaiscript/language/chaiscript_parser.hpp | 29 ++++++++++++------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/include/chaiscript/language/chaiscript_parser.hpp b/include/chaiscript/language/chaiscript_parser.hpp index 7a24acb5..80acf8c1 100644 --- a/include/chaiscript/language/chaiscript_parser.hpp +++ b/include/chaiscript/language/chaiscript_parser.hpp @@ -241,12 +241,12 @@ namespace chaiscript constexpr auto begin() const noexcept { - return all_data.begin(); + return &all_data[0]; } constexpr auto end() const noexcept { - return all_data.end(); + return begin() + all_data.size(); } constexpr decltype(auto) operator[](const std::size_t pos) const noexcept { @@ -321,20 +321,25 @@ namespace chaiscript { constexpr Position() = default; - constexpr Position(std::string::const_iterator t_pos, std::string::const_iterator t_end) noexcept + constexpr Position(const char * t_pos, const char * t_end) noexcept : line(1), col(1), m_pos(t_pos), m_end(t_end), m_last_col(1) { } static std::string str(const Position &t_begin, const Position &t_end) noexcept { - return std::string(t_begin.m_pos, t_end.m_pos); + if (t_begin.m_pos != nullptr && t_end.m_pos != nullptr) { + return std::string(t_begin.m_pos, t_end.m_pos); + } else { + return {}; + } } - Position &operator++() noexcept { + constexpr Position &operator++() noexcept { if (m_pos != m_end) { if (*m_pos == '\n') { ++line; - m_last_col = std::exchange(col, 1); + m_last_col = col; + col = 1; } else { ++col; } @@ -393,8 +398,8 @@ namespace chaiscript return m_pos != m_end; } - size_t remaining() const noexcept { - return static_cast(std::distance(m_pos, m_end)); + constexpr size_t remaining() const noexcept { + return static_cast(m_end - m_pos); } constexpr const char& operator*() const noexcept { @@ -409,8 +414,8 @@ namespace chaiscript int col = -1; private: - std::string::const_iterator m_pos; - std::string::const_iterator m_end; + const char *m_pos = nullptr; + const char *m_end = nullptr; int m_last_col = -1; }; @@ -2605,7 +2610,9 @@ namespace chaiscript /// Parses the given input string, tagging parsed ast_nodes with the given m_filename. AST_NodePtr parse_internal(const std::string &t_input, std::string t_fname) { - m_position = Position(t_input.begin(), t_input.end()); + const auto begin = t_input.empty() ? nullptr : &t_input.front(); + const auto end = begin == nullptr ? nullptr : begin + t_input.size(); + m_position = Position(begin, end); m_filename = std::make_shared(std::move(t_fname)); if ((t_input.size() > 1) && (t_input[0] == '#') && (t_input[1] == '!')) { From b810e4f7d9cde7c291aa4e37251cb50c00857c0a Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Tue, 22 Aug 2017 13:29:08 -0600 Subject: [PATCH 025/155] Callable traits constexpr --- include/chaiscript/dispatchkit/callable_traits.hpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/include/chaiscript/dispatchkit/callable_traits.hpp b/include/chaiscript/dispatchkit/callable_traits.hpp index 4b61b088..8d7936d2 100644 --- a/include/chaiscript/dispatchkit/callable_traits.hpp +++ b/include/chaiscript/dispatchkit/callable_traits.hpp @@ -25,10 +25,10 @@ namespace chaiscript { template struct Const_Caller { - explicit Const_Caller(Ret (Class::*t_func)(Param...) const) : m_func(t_func) {} + constexpr explicit Const_Caller(Ret (Class::*t_func)(Param...) const) : m_func(t_func) {} template - Ret operator()(const Class &o, Inner&& ... inner) const { + constexpr Ret operator()(const Class &o, Inner&& ... inner) const { return (o.*m_func)(std::forward(inner)...); } @@ -38,10 +38,10 @@ namespace chaiscript { template struct Fun_Caller { - explicit Fun_Caller(Ret( * t_func)(Param...) ) : m_func(t_func) {} + constexpr explicit Fun_Caller(Ret( * t_func)(Param...) ) : m_func(t_func) {} template - Ret operator()(Inner&& ... inner) const { + constexpr Ret operator()(Inner&& ... inner) const { return (m_func)(std::forward(inner)...); } @@ -51,10 +51,10 @@ namespace chaiscript { template struct Caller { - explicit Caller(Ret (Class::*t_func)(Param...)) : m_func(t_func) {} + constexpr explicit Caller(Ret (Class::*t_func)(Param...)) : m_func(t_func) {} template - Ret operator()(Class &o, Inner&& ... inner) const { + constexpr Ret operator()(Class &o, Inner&& ... inner) const { return (o.*m_func)(std::forward(inner)...); } From ac7af60d76504563a81b3737c58109814aa6924b Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Tue, 22 Aug 2017 15:54:42 -0600 Subject: [PATCH 026/155] Make constructors return values, not shared_ptr --- include/chaiscript/dispatchkit/callable_traits.hpp | 4 ++-- include/chaiscript/dispatchkit/dispatchkit.hpp | 4 ++-- include/chaiscript/dispatchkit/proxy_constructors.hpp | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/include/chaiscript/dispatchkit/callable_traits.hpp b/include/chaiscript/dispatchkit/callable_traits.hpp index 8d7936d2..0dc92416 100644 --- a/include/chaiscript/dispatchkit/callable_traits.hpp +++ b/include/chaiscript/dispatchkit/callable_traits.hpp @@ -17,8 +17,8 @@ namespace chaiscript { struct Constructor { template - std::shared_ptr operator()(Inner&& ... inner) const { - return std::make_shared(std::forward(inner)...); + constexpr Class operator()(Inner&& ... inner) const { + return Class(std::forward(inner)...); } }; diff --git a/include/chaiscript/dispatchkit/dispatchkit.hpp b/include/chaiscript/dispatchkit/dispatchkit.hpp index 1d8dc85c..e469ca29 100644 --- a/include/chaiscript/dispatchkit/dispatchkit.hpp +++ b/include/chaiscript/dispatchkit/dispatchkit.hpp @@ -1363,8 +1363,8 @@ namespace chaiscript const auto lhssize = lhsparamtypes.size(); const auto rhssize = rhsparamtypes.size(); - static const auto boxed_type = user_type(); - static const auto boxed_pod_type = user_type(); + constexpr const auto boxed_type = user_type(); + constexpr const auto boxed_pod_type = user_type(); for (size_t i = 1; i < lhssize && i < rhssize; ++i) { diff --git a/include/chaiscript/dispatchkit/proxy_constructors.hpp b/include/chaiscript/dispatchkit/proxy_constructors.hpp index bbe79d7a..10b72cf5 100644 --- a/include/chaiscript/dispatchkit/proxy_constructors.hpp +++ b/include/chaiscript/dispatchkit/proxy_constructors.hpp @@ -26,7 +26,7 @@ namespace chaiscript auto call = dispatch::detail::Constructor(); return Proxy_Function( - chaiscript::make_shared (Params...), decltype(call)>>(call)); + chaiscript::make_shared>(call)); } } } From 21500a1dcc077394862f6fcb7c19db00ff3c4f77 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Tue, 22 Aug 2017 16:13:17 -0600 Subject: [PATCH 027/155] Add source tracking for uninit memory sanitizer --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 25a5f1c5..78dfc613 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -54,8 +54,8 @@ if(CMAKE_COMPILER_IS_GNUCC OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") option(ENABLE_MEMORY_SANITIZER "Enable memory sanitizer testing in gcc/clang" FALSE) if(ENABLE_MEMORY_SANITIZER) - add_definitions(-fsanitize=memory -g) - set(LINKER_FLAGS "${LINKER_FLAGS} -fsanitize=memory") + add_definitions(-fsanitize=memory -fsanitize-memory-track-origins -g) + set(LINKER_FLAGS "${LINKER_FLAGS} -fsanitize=memory -fsanitize-memory-track-origins ") endif() option(ENABLE_UNDEFINED_SANITIZER "Enable undefined behavior sanitizer testing in gcc/clang" FALSE) From d56c5b489b3394eb3feee9c3334405423e4e07fe Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Tue, 22 Aug 2017 16:15:25 -0600 Subject: [PATCH 028/155] Fix bug exposed while moving to constexpr --- src/test_module.cpp | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/src/test_module.cpp b/src/test_module.cpp index 90a1154a..4216ee5b 100644 --- a/src/test_module.cpp +++ b/src/test_module.cpp @@ -12,8 +12,23 @@ class TestBaseType TestBaseType(int) : val(10), const_val(15), mdarray{} { } TestBaseType(int *) : val(10), const_val(15), mdarray{} { } - TestBaseType(const TestBaseType &) = default; - virtual ~TestBaseType() {} + TestBaseType(const TestBaseType &other) + : val(other.val), const_val(other.const_val), const_val_ptr(&const_val), + func_member(other.func_member) + { + } + + TestBaseType(TestBaseType &&other) + : val(other.val), const_val(other.const_val), const_val_ptr(&const_val), + func_member(std::move(other.func_member)) + { + } + + + TestBaseType &operator=(TestBaseType &&) = delete; + TestBaseType &operator=(const TestBaseType &) = delete; + + virtual ~TestBaseType() = default; virtual int func() { return 0; } int base_only_func() { return -9; } @@ -36,8 +51,6 @@ class TestBaseType t_str = "42"; } - private: - TestBaseType &operator=(const TestBaseType &) = delete; }; class Type2 @@ -78,22 +91,14 @@ int to_int(TestEnum t) class TestDerivedType : public TestBaseType { public: - ~TestDerivedType() override {} - TestDerivedType(const TestDerivedType &) = default; - TestDerivedType() = default; virtual int func() override { return 1; } int derived_only_func() { return 19; } - private: - TestDerivedType &operator=(const TestDerivedType &) = delete; }; class TestMoreDerivedType : public TestDerivedType { public: - TestMoreDerivedType(const TestMoreDerivedType &) = default; - TestMoreDerivedType() = default; - virtual ~TestMoreDerivedType() {} }; std::shared_ptr derived_type_factory() From 3feb08443808b267baa8a9b7d423eeac83bdd231 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Tue, 22 Aug 2017 22:22:47 -0600 Subject: [PATCH 029/155] constexpr user_type objects --- .../dispatchkit/proxy_functions.hpp | 28 +++++++++++-------- .../dispatchkit/type_conversions.hpp | 4 ++- 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/include/chaiscript/dispatchkit/proxy_functions.hpp b/include/chaiscript/dispatchkit/proxy_functions.hpp index 75a67a64..b1a096e6 100644 --- a/include/chaiscript/dispatchkit/proxy_functions.hpp +++ b/include/chaiscript/dispatchkit/proxy_functions.hpp @@ -52,14 +52,12 @@ namespace chaiscript { public: Param_Types() - : m_has_types(false), - m_doti(user_type()) + : m_has_types(false) {} explicit Param_Types(std::vector> t_types) : m_types(std::move(t_types)), - m_has_types(false), - m_doti(user_type()) + m_has_types(false) { update_has_types(); } @@ -77,13 +75,14 @@ namespace chaiscript std::vector convert(std::vector vals, const Type_Conversions_State &t_conversions) const { + constexpr auto dynamic_object_type_info = user_type(); for (size_t i = 0; i < vals.size(); ++i) { const auto &name = m_types[i].first; if (!name.empty()) { const auto &bv = vals[i]; - if (!bv.get_type_info().bare_equal(m_doti)) + if (!bv.get_type_info().bare_equal(dynamic_object_type_info)) { const auto &ti = m_types[i].second; if (!ti.is_undef()) @@ -116,6 +115,7 @@ namespace chaiscript // second result: needs conversions std::pair match(const std::vector &vals, const Type_Conversions_State &t_conversions) const noexcept { + constexpr auto dynamic_object_type_info = user_type(); bool needs_conversion = false; if (!m_has_types) { return std::make_pair(true, needs_conversion); } @@ -127,7 +127,7 @@ namespace chaiscript if (!name.empty()) { const auto &bv = vals[i]; - if (bv.get_type_info().bare_equal(m_doti)) + if (bv.get_type_info().bare_equal(dynamic_object_type_info)) { try { const Dynamic_Object &d = boxed_cast(bv, &t_conversions); @@ -180,7 +180,6 @@ namespace chaiscript std::vector> m_types; bool m_has_types; - Type_Info m_doti; }; @@ -251,12 +250,16 @@ 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>(); + if (ti.is_undef() - || ti.bare_equal(user_type()) + || ti.bare_equal(boxed_value_ti) || (!bv.get_type_info().is_undef() - && ( (ti.bare_equal(user_type()) && bv.get_type_info().is_arithmetic()) + && ( (ti.bare_equal(boxed_number_ti) && bv.get_type_info().is_arithmetic()) || ti.bare_equal(bv.get_type_info()) - || bv.get_type_info().bare_equal(user_type >()) + || bv.get_type_info().bare_equal(function_ti) || t_conversions->converts(ti, bv.get_type_info()) ) ) @@ -754,8 +757,8 @@ namespace chaiscript { return false; } - - return vals[0].get_type_info().bare_equal(user_type()); + constexpr auto class_type_info = user_type(); + return vals[0].get_type_info().bare_equal(class_type_info); } protected: @@ -804,6 +807,7 @@ namespace chaiscript return {user_type(), user_type()}; } + std::vector m_param_types{user_type(), user_type()}; T Class::* m_attr; }; } diff --git a/include/chaiscript/dispatchkit/type_conversions.hpp b/include/chaiscript/dispatchkit/type_conversions.hpp index dd327bf7..85991b4b 100644 --- a/include/chaiscript/dispatchkit/type_conversions.hpp +++ b/include/chaiscript/dispatchkit/type_conversions.hpp @@ -123,6 +123,7 @@ namespace chaiscript public: static Boxed_Value cast(const Boxed_Value &t_from) { + if (t_from.get_type_info().bare_equal(chaiscript::user_type())) { if (t_from.is_pointer()) @@ -373,7 +374,8 @@ namespace chaiscript template bool convertable_type() const noexcept { - return thread_cache().count(user_type().bare_type_info()) != 0; + constexpr auto type = user_type().bare_type_info(); + return thread_cache().count(type) != 0; } template From 0d76241f77b89d81da4c1536bd4dc3e954a67668 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Wed, 23 Aug 2017 16:08:44 -0600 Subject: [PATCH 030/155] Avoid capture of constexpr value --- include/chaiscript/dispatchkit/bootstrap.hpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/include/chaiscript/dispatchkit/bootstrap.hpp b/include/chaiscript/dispatchkit/bootstrap.hpp index 201c3af7..030da21e 100644 --- a/include/chaiscript/dispatchkit/bootstrap.hpp +++ b/include/chaiscript/dispatchkit/bootstrap.hpp @@ -23,10 +23,10 @@ namespace chaiscript void array(const std::string &type, Module& m) { typedef typename std::remove_extent::type ReturnType; - const auto extent = std::extent::value; m.add(user_type(), type); m.add(fun( - [extent](T& t, size_t index)->ReturnType &{ + [](T& t, size_t index)->ReturnType &{ + constexpr const auto extent = std::extent::value; if (extent > 0 && index >= extent) { throw std::range_error("Array index out of range. Received: " + std::to_string(index) + " expected < " + std::to_string(extent)); } else { @@ -37,7 +37,8 @@ namespace chaiscript ); m.add(fun( - [extent](const T &t, size_t index)->const ReturnType &{ + [](const T &t, size_t index)->const ReturnType &{ + constexpr const auto extent = std::extent::value; if (extent > 0 && index >= extent) { throw std::range_error("Array index out of range. Received: " + std::to_string(index) + " expected < " + std::to_string(extent)); } else { @@ -48,8 +49,8 @@ namespace chaiscript ); m.add(fun( - [extent](const T &) { - return extent; + [](const T &) { + return std::extent::value; }), "size"); } From b8b548bab37286074d5bc429203bd0029893c4dd Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Wed, 23 Aug 2017 16:09:54 -0600 Subject: [PATCH 031/155] more constexpr for parser --- include/chaiscript/dispatchkit/bootstrap.hpp | 2 +- .../chaiscript/language/chaiscript_parser.hpp | 301 +++++++++--------- 2 files changed, 154 insertions(+), 149 deletions(-) diff --git a/include/chaiscript/dispatchkit/bootstrap.hpp b/include/chaiscript/dispatchkit/bootstrap.hpp index 201c3af7..fe06b84c 100644 --- a/include/chaiscript/dispatchkit/bootstrap.hpp +++ b/include/chaiscript/dispatchkit/bootstrap.hpp @@ -23,7 +23,7 @@ namespace chaiscript void array(const std::string &type, Module& m) { typedef typename std::remove_extent::type ReturnType; - const auto extent = std::extent::value; + constexpr const auto extent = std::extent::value; m.add(user_type(), type); m.add(fun( [extent](T& t, size_t index)->ReturnType &{ diff --git a/include/chaiscript/language/chaiscript_parser.hpp b/include/chaiscript/language/chaiscript_parser.hpp index 80acf8c1..71112298 100644 --- a/include/chaiscript/language/chaiscript_parser.hpp +++ b/include/chaiscript/language/chaiscript_parser.hpp @@ -124,145 +124,147 @@ namespace chaiscript return &m_tracer; } - static std::array, detail::max_alphabet> build_alphabet() noexcept + template + constexpr static void set_alphabet(Array2D &array, const First first, const Second second) noexcept { - std::array, detail::max_alphabet> alphabet; - - for (auto &alpha : alphabet) { - alpha.fill(false); - } - - alphabet[detail::symbol_alphabet][static_cast('?')]=true; - alphabet[detail::symbol_alphabet][static_cast('+')]=true; - alphabet[detail::symbol_alphabet][static_cast('-')]=true; - alphabet[detail::symbol_alphabet][static_cast('*')]=true; - alphabet[detail::symbol_alphabet][static_cast('/')]=true; - alphabet[detail::symbol_alphabet][static_cast('|')]=true; - alphabet[detail::symbol_alphabet][static_cast('&')]=true; - alphabet[detail::symbol_alphabet][static_cast('^')]=true; - alphabet[detail::symbol_alphabet][static_cast('=')]=true; - alphabet[detail::symbol_alphabet][static_cast('.')]=true; - alphabet[detail::symbol_alphabet][static_cast('<')]=true; - alphabet[detail::symbol_alphabet][static_cast('>')]=true; - - for ( size_t c = 'a' ; c <= 'z' ; ++c ) { alphabet[detail::keyword_alphabet][c]=true; } - for ( size_t c = 'A' ; c <= 'Z' ; ++c ) { alphabet[detail::keyword_alphabet][c]=true; } - for ( size_t c = '0' ; c <= '9' ; ++c ) { alphabet[detail::keyword_alphabet][c]=true; } - alphabet[detail::keyword_alphabet][static_cast('_')]=true; - - for ( size_t c = '0' ; c <= '9' ; ++c ) { alphabet[detail::int_alphabet][c]=true; } - for ( size_t c = '0' ; c <= '9' ; ++c ) { alphabet[detail::float_alphabet][c]=true; } - alphabet[detail::float_alphabet][static_cast('.')]=true; - - for ( size_t c = '0' ; c <= '9' ; ++c ) { alphabet[detail::hex_alphabet][c]=true; } - for ( size_t c = 'a' ; c <= 'f' ; ++c ) { alphabet[detail::hex_alphabet][c]=true; } - for ( size_t c = 'A' ; c <= 'F' ; ++c ) { alphabet[detail::hex_alphabet][c]=true; } - - alphabet[detail::x_alphabet][static_cast('x')]=true; - alphabet[detail::x_alphabet][static_cast('X')]=true; - - for ( size_t c = '0' ; c <= '1' ; ++c ) { alphabet[detail::bin_alphabet][c]=true; } - alphabet[detail::b_alphabet][static_cast('b')]=true; - alphabet[detail::b_alphabet][static_cast('B')]=true; - - for ( size_t c = 'a' ; c <= 'z' ; ++c ) { alphabet[detail::id_alphabet][c]=true; } - for ( size_t c = 'A' ; c <= 'Z' ; ++c ) { alphabet[detail::id_alphabet][c]=true; } - alphabet[detail::id_alphabet][static_cast('_')] = true; - - alphabet[detail::white_alphabet][static_cast(' ')]=true; - alphabet[detail::white_alphabet][static_cast('\t')]=true; - - alphabet[detail::int_suffix_alphabet][static_cast('l')] = true; - alphabet[detail::int_suffix_alphabet][static_cast('L')] = true; - alphabet[detail::int_suffix_alphabet][static_cast('u')] = true; - alphabet[detail::int_suffix_alphabet][static_cast('U')] = true; - - alphabet[detail::float_suffix_alphabet][static_cast('l')] = true; - alphabet[detail::float_suffix_alphabet][static_cast('L')] = true; - alphabet[detail::float_suffix_alphabet][static_cast('f')] = true; - alphabet[detail::float_suffix_alphabet][static_cast('F')] = true; - - return alphabet; + auto *first_ptr = &std::get<0>(array) + static_cast(first); + auto *second_ptr = &std::get<0>(*first_ptr) + static_cast(second); + *second_ptr = true; } - static const std::array, detail::max_alphabet> &create_alphabet() noexcept + constexpr static std::array, detail::max_alphabet> build_alphabet() noexcept { - static const auto alpha = build_alphabet(); - return alpha; + std::array, detail::max_alphabet> alphabet{}; + + set_alphabet(alphabet, detail::symbol_alphabet, '?'); + + set_alphabet(alphabet, detail::symbol_alphabet, '?'); + set_alphabet(alphabet, detail::symbol_alphabet, '+'); + set_alphabet(alphabet, detail::symbol_alphabet, '-'); + set_alphabet(alphabet, detail::symbol_alphabet, '*'); + set_alphabet(alphabet, detail::symbol_alphabet, '/'); + set_alphabet(alphabet, detail::symbol_alphabet, '|'); + set_alphabet(alphabet, detail::symbol_alphabet, '&'); + set_alphabet(alphabet, detail::symbol_alphabet, '^'); + set_alphabet(alphabet, detail::symbol_alphabet, '='); + set_alphabet(alphabet, detail::symbol_alphabet, '.'); + set_alphabet(alphabet, detail::symbol_alphabet, '<'); + set_alphabet(alphabet, detail::symbol_alphabet, '>'); + + for ( size_t c = 'a' ; c <= 'z' ; ++c ) { set_alphabet(alphabet, detail::keyword_alphabet, c); } + for ( size_t c = 'A' ; c <= 'Z' ; ++c ) { set_alphabet(alphabet, detail::keyword_alphabet, c); } + for ( size_t c = '0' ; c <= '9' ; ++c ) { set_alphabet(alphabet, detail::keyword_alphabet, c); } + set_alphabet(alphabet, detail::keyword_alphabet, '_'); + + for ( size_t c = '0' ; c <= '9' ; ++c ) { set_alphabet(alphabet, detail::int_alphabet, c); } + for ( size_t c = '0' ; c <= '9' ; ++c ) { set_alphabet(alphabet, detail::float_alphabet, c); } + set_alphabet(alphabet, detail::float_alphabet, '.'); + + for ( size_t c = '0' ; c <= '9' ; ++c ) { set_alphabet(alphabet, detail::hex_alphabet, c); } + for ( size_t c = 'a' ; c <= 'f' ; ++c ) { set_alphabet(alphabet, detail::hex_alphabet, c); } + for ( size_t c = 'A' ; c <= 'F' ; ++c ) { set_alphabet(alphabet, detail::hex_alphabet, c); } + + set_alphabet(alphabet, detail::x_alphabet, 'x'); + set_alphabet(alphabet, detail::x_alphabet, 'X'); + + for ( size_t c = '0' ; c <= '1' ; ++c ) { set_alphabet(alphabet, detail::bin_alphabet, c); } + set_alphabet(alphabet, detail::b_alphabet, 'b'); + set_alphabet(alphabet, detail::b_alphabet, 'B'); + + for ( size_t c = 'a' ; c <= 'z' ; ++c ) { set_alphabet(alphabet, detail::id_alphabet, c); } + for ( size_t c = 'A' ; c <= 'Z' ; ++c ) { set_alphabet(alphabet, detail::id_alphabet, c); } + set_alphabet(alphabet, detail::id_alphabet, '_'); + + set_alphabet(alphabet, detail::white_alphabet, ' '); + set_alphabet(alphabet, detail::white_alphabet, '\t'); + + set_alphabet(alphabet, detail::int_suffix_alphabet, 'l'); + set_alphabet(alphabet, detail::int_suffix_alphabet, 'L'); + set_alphabet(alphabet, detail::int_suffix_alphabet, 'u'); + set_alphabet(alphabet, detail::int_suffix_alphabet, 'U'); + + set_alphabet(alphabet, detail::float_suffix_alphabet, 'l'); + set_alphabet(alphabet, detail::float_suffix_alphabet, 'L'); + set_alphabet(alphabet, detail::float_suffix_alphabet, 'f'); + set_alphabet(alphabet, detail::float_suffix_alphabet, 'F'); + + return alphabet; } struct Operator_Matches { - struct Array_View - { - template - constexpr Array_View(const std::array &data) noexcept - : m_begin(&data.front()), - m_end(m_begin + Len) - { - } - - constexpr auto begin() const noexcept - { - return m_begin; - } - - constexpr auto end() const noexcept - { - return m_end; - } - - const utility::Static_String *m_begin; - const utility::Static_String *m_end; - }; - using SS = utility::Static_String; - const std::array m_0 {{SS("?")}}; - const std::array m_1 {{SS("||")}}; - const std::array m_2 {{SS("&&")}}; - const std::array m_3 {{SS("|")}}; - const std::array m_4 {{SS("^")}}; - const std::array m_5 {{SS("&")}}; - const std::array m_6 {{SS("=="), SS("!=")}}; - const std::array m_7 {{SS("<"), SS("<="), SS(">"), SS(">=")}}; - const std::array m_8 {{SS("<<"), SS(">>")}}; + std::array m_0 {{SS("?")}}; + std::array m_1 {{SS("||")}}; + std::array m_2 {{SS("&&")}}; + std::array m_3 {{SS("|")}}; + std::array m_4 {{SS("^")}}; + std::array m_5 {{SS("&")}}; + std::array m_6 {{SS("=="), SS("!=")}}; + std::array m_7 {{SS("<"), SS("<="), SS(">"), SS(">=")}}; + std::array m_8 {{SS("<<"), SS(">>")}}; //We share precedence here but then separate them later - const std::array m_9 {{SS("+"), SS("-")}}; - const std::array m_10 {{SS("*"), SS("/"), SS("%")}}; - const std::array m_11 {{SS("++"), SS("--"), SS("-"), SS("+"), SS("!"), SS("~")}}; + std::array m_9 {{SS("+"), SS("-")}}; + std::array m_10 {{SS("*"), SS("/"), SS("%")}}; + std::array m_11 {{SS("++"), SS("--"), SS("-"), SS("+"), SS("!"), SS("~")}}; - const std::array all_data {{ - m_0, m_1, m_2, m_3, m_4, m_5, m_6, m_7, m_8, m_9, m_10, m_11 - }}; - - constexpr Operator_Matches() noexcept {} - - constexpr auto begin() const noexcept - { - return &all_data[0]; + bool is_match(const std::string &t_str) const noexcept { + constexpr std::array groups{{0,1,2,3,4,5,6,7,8,9,10,11}}; + return std::any_of(groups.begin(), groups.end(), [&t_str, this](const std::size_t group){ return is_match(group, t_str); }); } - constexpr auto end() const noexcept + template + bool any_of(const std::size_t t_group, Predicate &&predicate) const { - return begin() + all_data.size(); + auto match = [&predicate](const auto &array) { + return std::any_of(array.begin(), array.end(), predicate); + }; + + switch (t_group) { + case 0: return match(m_0); + case 1: return match(m_1); + case 2: return match(m_2); + case 3: return match(m_3); + case 4: return match(m_4); + case 5: return match(m_5); + case 6: return match(m_6); + case 7: return match(m_7); + case 8: return match(m_8); + case 9: return match(m_9); + case 10: return match(m_10); + case 11: return match(m_11); + default: return false; + } } - constexpr decltype(auto) operator[](const std::size_t pos) const noexcept { - return (all_data[pos]); + bool is_match(const std::size_t t_group, const std::string &t_str) const noexcept { + auto match = [&t_str](const auto &array) { + return std::any_of(array.begin(), array.end(), [&t_str](const auto &v){ return v.c_str() == t_str; }); + }; + + switch (t_group) { + case 0: return match(m_0); + case 1: return match(m_1); + case 2: return match(m_2); + case 3: return match(m_3); + case 4: return match(m_4); + case 5: return match(m_5); + case 6: return match(m_6); + case 7: return match(m_7); + case 8: return match(m_8); + case 9: return match(m_9); + case 10: return match(m_10); + case 11: return match(m_11); + default: return false; + } } }; - static const auto &create_operator_matches() noexcept { - const static Operator_Matches operator_matches; - return operator_matches; - } - - - static const std::array &create_operators() noexcept { - static const std::array operators = { { + constexpr static std::array create_operators() noexcept { + std::array operators = { { Operator_Precidence::Ternary_Cond, Operator_Precidence::Logical_Or, Operator_Precidence::Logical_And, @@ -279,39 +281,36 @@ namespace chaiscript return operators; } - static const utility::Static_String &multiline_comment_end() noexcept + constexpr static utility::Static_String multiline_comment_end() noexcept { - static const utility::Static_String s("*/"); + constexpr utility::Static_String s("*/"); return s; } - static const utility::Static_String &multiline_comment_begin() noexcept + constexpr static utility::Static_String multiline_comment_begin() noexcept { - static const utility::Static_String s("/*"); + constexpr utility::Static_String s("/*"); return s; } - static const utility::Static_String &singleline_comment() noexcept + constexpr static utility::Static_String singleline_comment() noexcept { - static const utility::Static_String s("//"); + constexpr utility::Static_String s("//"); return s; } - static const utility::Static_String &annotation() noexcept + constexpr static utility::Static_String annotation() noexcept { - static const utility::Static_String s("#"); + constexpr utility::Static_String s("#"); return s; } - static const utility::Static_String &cr_lf() noexcept + constexpr static utility::Static_String cr_lf() noexcept { - static const utility::Static_String s("\r\n"); + constexpr utility::Static_String s("\r\n"); return s; } - const std::array, detail::max_alphabet> &m_alphabet = create_alphabet(); - const Operator_Matches &m_operator_matches = create_operator_matches(); - const std::array &m_operators = create_operators(); std::shared_ptr m_filename; std::vector> m_match_stack; @@ -455,7 +454,10 @@ namespace chaiscript ChaiScript_Parser &operator=(ChaiScript_Parser &&) = delete; /// test a char in an m_alphabet - constexpr bool char_in_alphabet(char c, detail::Alphabet a) const noexcept { return m_alphabet[a][static_cast(c)]; } + constexpr bool char_in_alphabet(char c, detail::Alphabet a) const noexcept { + constexpr auto alphabet = build_alphabet(); + return alphabet[a][static_cast(c)]; + } /// Prints the parsed ast_nodes as a tree void debug_print(const AST_Node &t, std::string prepend = "") const override { @@ -1443,13 +1445,8 @@ namespace chaiscript } bool is_operator(const std::string &t_s) const noexcept { - return std::any_of(m_operator_matches.begin(), m_operator_matches.end(), - [&t_s](const auto &opers) { - return std::any_of(opers.begin(), opers.end(), - [&t_s](const utility::Static_String &s) { - return t_s == s.c_str(); - }); - }); + constexpr Operator_Matches operator_matches; + return operator_matches.is_match(t_s); } /// Reads (and potentially captures) a symbol group from input if it matches the parameter @@ -2347,12 +2344,14 @@ namespace chaiscript SS{"~"} }}; + constexpr auto operators = create_operators(); + for (const auto &oper : prefix_opers) { const bool is_char = oper.size() == 1; if ((is_char && Char(oper.c_str()[0])) || (!is_char && Symbol(oper))) { - if (!Operator(m_operators.size()-1)) { + if (!Operator(operators.size()-1)) { throw exception::eval_error("Incomplete prefix '" + std::string(oper.c_str()) + "' expression", File_Position(m_position.line, m_position.col), *m_filename); } @@ -2370,20 +2369,26 @@ namespace chaiscript } bool Operator_Helper(const size_t t_precedence, std::string &oper) { - for (auto & elem : m_operator_matches[t_precedence]) { - if (Symbol(elem)) { - oper = elem.c_str(); - return true; - } - } - return false; + constexpr Operator_Matches operator_matches; + return operator_matches.any_of(t_precedence, + [&oper, this](const auto &elem){ + if (Symbol(elem)) { + oper = elem.c_str(); + return true; + } else { + return false; + } + } + ); } bool Operator(const size_t t_precedence = 0) { bool retval = false; const auto prev_stack_top = m_match_stack.size(); - if (m_operators[t_precedence] != Operator_Precidence::Prefix) { + constexpr auto operators = create_operators(); + + if (operators[t_precedence] != Operator_Precidence::Prefix) { if (Operator(t_precedence+1)) { retval = true; std::string oper; @@ -2394,7 +2399,7 @@ namespace chaiscript File_Position(m_position.line, m_position.col), *m_filename); } - switch (m_operators[t_precedence]) { + switch (operators[t_precedence]) { case(Operator_Precidence::Ternary_Cond) : if (Symbol(":")) { if (!Operator(t_precedence+1)) { From dd918c524d0bc9d081df723f42e18874874e4cf7 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Wed, 23 Aug 2017 20:20:17 -0600 Subject: [PATCH 032/155] Use if constexpr in boxed_number --- .../chaiscript/dispatchkit/boxed_number.hpp | 416 ++++++------------ .../language/chaiscript_algebraic.hpp | 5 - 2 files changed, 126 insertions(+), 295 deletions(-) diff --git a/include/chaiscript/dispatchkit/boxed_number.hpp b/include/chaiscript/dispatchkit/boxed_number.hpp index 7d22dddc..7a8ae645 100644 --- a/include/chaiscript/dispatchkit/boxed_number.hpp +++ b/include/chaiscript/dispatchkit/boxed_number.hpp @@ -80,20 +80,17 @@ namespace chaiscript }; template - constexpr static inline void check_divide_by_zero(T t, typename std::enable_if::value>::type* = nullptr) + constexpr static inline void check_divide_by_zero(T t) { #ifndef CHAISCRIPT_NO_PROTECT_DIVIDEBYZERO - if (t == 0) { - throw chaiscript::exception::arithmetic_error("divide by zero"); + if constexpr (!std::is_floating_point::value) { + if (t == 0) { + throw chaiscript::exception::arithmetic_error("divide by zero"); + } } #endif } - template - constexpr static inline void check_divide_by_zero(T, typename std::enable_if::value>::type* = nullptr) noexcept - { - } - constexpr static Common_Types get_common_type(size_t t_size, bool t_signed) noexcept { return (t_size == 1 && t_signed)?(Common_Types::t_int8) @@ -160,318 +157,157 @@ namespace chaiscript } } - template - constexpr static bool boolean_go(Operators::Opers t_oper, const T &t, const T &u) noexcept + + + template + static auto go(Operators::Opers t_oper, const Boxed_Value &t_bv, LHS *t_lhs, const T &c_lhs, const T &c_rhs) { - switch (t_oper) - { + switch (t_oper) { case Operators::Opers::equals: - return t == u; + return const_var(c_lhs == c_rhs); case Operators::Opers::less_than: - return t < u; + return const_var(c_lhs < c_rhs); case Operators::Opers::greater_than: - return t > u; + return const_var(c_lhs > c_rhs); case Operators::Opers::less_than_equal: - return t <= u; + return const_var(c_lhs <= c_rhs); case Operators::Opers::greater_than_equal: - return t >= u; + return const_var(c_lhs >= c_rhs); case Operators::Opers::not_equal: - return t != u; - default: - assert(false); - return false; - } - } - - template - constexpr static void unary_go(Operators::Opers t_oper, T &t) noexcept - { - switch (t_oper) - { - case Operators::Opers::pre_increment: - ++t; - break; - case Operators::Opers::pre_decrement: - --t; - break; - default: - assert(false); - } - } - - template - constexpr static void binary_go(Operators::Opers t_oper, T &t, const U &u) - noexcept(noexcept(check_divide_by_zero(u))) - { - switch (t_oper) - { - case Operators::Opers::assign: - t = u; - break; - case Operators::Opers::assign_product: - t *= u; - break; - case Operators::Opers::assign_sum: - t += u; - break; - case Operators::Opers::assign_quotient: - check_divide_by_zero(u); - t /= u; - break; - case Operators::Opers::assign_difference: - t -= u; - break; - default: - assert(false); - } - } - - template - constexpr static void binary_int_go(Operators::Opers t_oper, T &t, const U &u) noexcept - { - switch (t_oper) - { - case Operators::Opers::assign_bitwise_and: - t &= u; - break; - case Operators::Opers::assign_bitwise_or: - t |= u; - break; - case Operators::Opers::assign_shift_left: - t <<= u; - break; - case Operators::Opers::assign_shift_right: - t >>= u; - break; - case Operators::Opers::assign_remainder: - check_divide_by_zero(u); - t %= u; - break; - case Operators::Opers::assign_bitwise_xor: - t ^= u; - break; - default: - assert(false); - } - } - - - template - constexpr static auto const_binary_int_go(Operators::Opers t_oper, T t, T u) - noexcept(noexcept(check_divide_by_zero(u))) - { - switch (t_oper) - { - case Operators::Opers::shift_left: - return t << u; - case Operators::Opers::shift_right: - return t >> u; - case Operators::Opers::remainder: - check_divide_by_zero(u); - return t % u; - case Operators::Opers::bitwise_and: - return t & u; - case Operators::Opers::bitwise_or: - return t | u; - case Operators::Opers::bitwise_xor: - return t ^ u; - default: - assert(false); - return static_cast(t); - } - } - - template - constexpr static auto const_unary_go(Operators::Opers t_oper, T t) noexcept - { - switch (t_oper) - { - case Operators::Opers::unary_minus: - return -t; - case Operators::Opers::unary_plus: - return +t; - default: - assert(false); - return static_cast(t); - } - } - - template - constexpr static auto const_binary_go(Operators::Opers t_oper, T t, T u) - noexcept(noexcept(check_divide_by_zero(u))) - { - switch (t_oper) - { + return const_var(c_lhs != c_rhs); case Operators::Opers::sum: - return t + u; + return const_var(c_lhs + c_rhs); case Operators::Opers::quotient: - check_divide_by_zero(u); - return t / u; + check_divide_by_zero(c_rhs); + return const_var(c_lhs / c_rhs); case Operators::Opers::product: - return t * u; + return const_var(c_lhs * c_rhs); case Operators::Opers::difference: - return t - u; - default: - assert(false); - return static_cast(t); + return const_var(c_lhs - c_rhs); } + + + if constexpr (!std::is_floating_point::value) { + switch (t_oper) { + case Operators::Opers::shift_left: + return const_var(c_lhs << c_rhs); + case Operators::Opers::shift_right: + return const_var(c_lhs >> c_rhs); + case Operators::Opers::remainder: + return const_var(c_lhs % c_rhs); + case Operators::Opers::bitwise_and: + return const_var(c_lhs & c_rhs); + case Operators::Opers::bitwise_or: + return const_var(c_lhs | c_rhs); + case Operators::Opers::bitwise_xor: + return const_var(c_lhs ^ c_rhs); + } + } + + if (t_lhs) { + switch (t_oper) { + case Operators::Opers::assign: + *t_lhs = c_rhs; + return t_bv; + case Operators::Opers::assign_product: + *t_lhs *= c_rhs; + return t_bv; + case Operators::Opers::assign_sum: + *t_lhs += c_rhs; + return t_bv; + case Operators::Opers::assign_quotient: + *t_lhs /= c_rhs; + return t_bv; + case Operators::Opers::assign_difference: + *t_lhs -= c_rhs; + return t_bv; + } + + if constexpr (!std::is_floating_point::value) { + switch (t_oper) { + case Operators::Opers::assign_bitwise_and: + *t_lhs &= c_rhs; + return t_bv; + case Operators::Opers::assign_bitwise_or: + *t_lhs |= c_rhs; + return t_bv; + case Operators::Opers::assign_shift_left: + *t_lhs <<= c_rhs; + return t_bv; + case Operators::Opers::assign_shift_right: + *t_lhs >>= c_rhs; + return t_bv; + case Operators::Opers::assign_remainder: + *t_lhs %= c_rhs; + return t_bv; + case Operators::Opers::assign_bitwise_xor: + *t_lhs ^= c_rhs; + return t_bv; + } + } + } + + throw chaiscript::detail::exception::bad_any_cast(); } template static auto go(Operators::Opers t_oper, const Boxed_Value &t_lhs, const Boxed_Value &t_rhs) - -> typename std::enable_if::value && !std::is_floating_point::value, Boxed_Value>::type { - typedef typename std::common_type::type common_type; + using common_type = typename std::common_type::type; - switch (t_oper) { - case Operators::Opers::equals: - case Operators::Opers::less_than: - case Operators::Opers::greater_than: - case Operators::Opers::less_than_equal: - case Operators::Opers::greater_than_equal: - case Operators::Opers::not_equal: - return const_var(boolean_go(t_oper, get_as_aux(t_lhs), get_as_aux(t_rhs))); - case Operators::Opers::assign: - case Operators::Opers::assign_product: - case Operators::Opers::assign_sum: - case Operators::Opers::assign_quotient: - case Operators::Opers::assign_difference: - if (!t_lhs.is_const() && !t_lhs.is_return_value()) { - binary_go(t_oper, *static_cast(t_lhs.get_ptr()), get_as_aux(t_rhs)); - return t_lhs; - } else { - throw chaiscript::detail::exception::bad_any_cast(); - } - case Operators::Opers::assign_bitwise_and: - case Operators::Opers::assign_bitwise_or: - case Operators::Opers::assign_shift_left: - case Operators::Opers::assign_shift_right: - case Operators::Opers::assign_remainder: - case Operators::Opers::assign_bitwise_xor: - if (!t_lhs.is_const() && !t_lhs.is_return_value()) { - binary_int_go(t_oper, *static_cast(t_lhs.get_ptr()), get_as_aux(t_rhs)); - return t_lhs; - } else { - throw chaiscript::detail::exception::bad_any_cast(); - } - case Operators::Opers::shift_left: - case Operators::Opers::shift_right: - case Operators::Opers::remainder: - case Operators::Opers::bitwise_and: - case Operators::Opers::bitwise_or: - case Operators::Opers::bitwise_xor: - { - const auto result - = const_binary_int_go(t_oper, get_as_aux(t_lhs), get_as_aux(t_rhs)); - return const_var(result); - } - case Operators::Opers::sum: - case Operators::Opers::quotient: - case Operators::Opers::product: - case Operators::Opers::difference: - { - const auto result - = const_binary_go(t_oper, get_as_aux(t_lhs), get_as_aux(t_rhs)); - return const_var(result); - } - default: - throw chaiscript::detail::exception::bad_any_cast(); - } - } - - template - static auto go(Operators::Opers t_oper, const Boxed_Value &t_lhs, const Boxed_Value &t_rhs) - -> typename std::enable_if::value || std::is_floating_point::value, Boxed_Value>::type - { - typedef typename std::common_type::type common_type; - - switch (t_oper) { - case Operators::Opers::equals: - case Operators::Opers::less_than: - case Operators::Opers::greater_than: - case Operators::Opers::less_than_equal: - case Operators::Opers::greater_than_equal: - case Operators::Opers::not_equal: - return const_var(boolean_go(t_oper, get_as_aux(t_lhs), get_as_aux(t_rhs))); - case Operators::Opers::assign: - case Operators::Opers::assign_product: - case Operators::Opers::assign_sum: - case Operators::Opers::assign_quotient: - case Operators::Opers::assign_difference: - if (!t_lhs.is_const() && !t_lhs.is_return_value()) { - binary_go(t_oper, *static_cast(t_lhs.get_ptr()), get_as_aux(t_rhs)); - return t_lhs; - } else { - throw chaiscript::detail::exception::bad_any_cast(); - } - case Operators::Opers::sum: - case Operators::Opers::quotient: - case Operators::Opers::product: - case Operators::Opers::difference: - { - const auto result - = const_binary_go(t_oper, get_as_aux(t_lhs), get_as_aux(t_rhs)); - return const_var(result); - } - default: - throw chaiscript::detail::exception::bad_any_cast(); - } + auto *lhs = [&]() -> LHS *{ + if (!t_lhs.is_const() && !t_lhs.is_return_value()) { + return static_cast(t_lhs.get_ptr()); + } else { + return nullptr; + } + }(); + return go(t_oper, t_lhs, lhs, get_as_aux(t_lhs), get_as_aux(t_rhs)); } // Unary template static auto go(Operators::Opers t_oper, const Boxed_Value &t_lhs) - -> typename std::enable_if::value, Boxed_Value>::type { - switch (t_oper) { - case Operators::Opers::pre_increment: - case Operators::Opers::pre_decrement: - if (!t_lhs.is_const() && !t_lhs.is_return_value()) { - unary_go(t_oper, *static_cast(t_lhs.get_ptr())); + auto *lhs = [&]() -> LHS *{ + if (!t_lhs.is_const() && !t_lhs.is_return_value()) { + return static_cast(t_lhs.get_ptr()); + } else { + return nullptr; + } + }(); + + const LHS &c_lhs = (*static_cast(t_lhs.get_const_ptr())); + + if (lhs) { + switch (t_oper) { + case Operators::Opers::pre_increment: + ++(*lhs); return t_lhs; - } else { - throw chaiscript::detail::exception::bad_any_cast(); - } - case Operators::Opers::bitwise_complement: - { - return const_var(~(*static_cast(t_lhs.get_const_ptr()))); - } - case Operators::Opers::unary_minus: - case Operators::Opers::unary_plus: - { - const auto val = const_unary_go(t_oper, *static_cast(t_lhs.get_const_ptr())); - return const_var(val); - } - default: - throw chaiscript::detail::exception::bad_any_cast(); + case Operators::Opers::pre_decrement: + --(*lhs); + return t_lhs; + } } + switch (t_oper) { + case Operators::Opers::unary_minus: + return const_var(-c_lhs); + case Operators::Opers::unary_plus: + return const_var(+c_lhs); + } + + if constexpr (!std::is_floating_point::value) { + switch (t_oper) { + case Operators::Opers::bitwise_complement: + return const_var(~c_lhs); + } + } + + throw chaiscript::detail::exception::bad_any_cast(); } - template - static auto go(Operators::Opers t_oper, const Boxed_Value &t_lhs) - -> typename std::enable_if::value, Boxed_Value>::type - { - switch (t_oper) { - case Operators::Opers::pre_increment: - case Operators::Opers::pre_decrement: - if (!t_lhs.is_const() && !t_lhs.is_return_value()) { - unary_go(t_oper, *static_cast(t_lhs.get_ptr())); - return t_lhs; - } else { - throw chaiscript::detail::exception::bad_any_cast(); - } - case Operators::Opers::unary_minus: - case Operators::Opers::unary_plus: - { - const auto val = const_unary_go(t_oper, *static_cast(t_lhs.get_const_ptr())); - return const_var(val); - } - default: - throw chaiscript::detail::exception::bad_any_cast(); - } - } template inline static Boxed_Value oper_rhs(Operators::Opers t_oper, const Boxed_Value &t_lhs, const Boxed_Value &t_rhs) diff --git a/include/chaiscript/language/chaiscript_algebraic.hpp b/include/chaiscript/language/chaiscript_algebraic.hpp index 3e5675aa..06d242a8 100644 --- a/include/chaiscript/language/chaiscript_algebraic.hpp +++ b/include/chaiscript/language/chaiscript_algebraic.hpp @@ -21,17 +21,12 @@ namespace chaiscript struct Operators { enum class Opers { - boolean_flag, equals, less_than, greater_than, less_than_equal, greater_than_equal, not_equal, - non_const_flag, assign, pre_increment, pre_decrement, assign_product, assign_sum, assign_quotient, assign_difference, - non_const_int_flag, assign_bitwise_and, assign_bitwise_or, assign_shift_left, assign_shift_right, assign_remainder, assign_bitwise_xor, - const_int_flag, shift_left, shift_right, remainder, bitwise_and, bitwise_or, bitwise_xor, bitwise_complement, - const_flag, sum, quotient, product, difference, unary_plus, unary_minus, invalid }; From 77228412944d25fbb3b3a40392ea5c51ed8e2619 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Wed, 23 Aug 2017 21:23:18 -0600 Subject: [PATCH 033/155] More if constexpr work --- include/chaiscript/dispatchkit/bootstrap.hpp | 31 ++++++------------- .../dispatchkit/proxy_functions.hpp | 29 +++++++---------- .../dispatchkit/type_conversions.hpp | 18 ++++------- 3 files changed, 28 insertions(+), 50 deletions(-) diff --git a/include/chaiscript/dispatchkit/bootstrap.hpp b/include/chaiscript/dispatchkit/bootstrap.hpp index 4f4027d2..8ae21bfa 100644 --- a/include/chaiscript/dispatchkit/bootstrap.hpp +++ b/include/chaiscript/dispatchkit/bootstrap.hpp @@ -112,30 +112,19 @@ namespace chaiscript /// uses ostream operator >> to perform the conversion template auto parse_string(const std::string &i) - -> typename std::enable_if< - !std::is_same::value - && !std::is_same::value - && !std::is_same::value, - Input>::type { - std::stringstream ss(i); - Input t; - ss >> t; - return t; + if constexpr (!std::is_same::value + && !std::is_same::value + && !std::is_same::value) { + std::stringstream ss(i); + Input t; + ss >> t; + return t; + } else { + throw std::runtime_error("Parsing of wide characters is not yet supported"); + } } - template - auto parse_string(const std::string &) - -> typename std::enable_if< - std::is_same::value - || std::is_same::value - || std::is_same::value, - Input>::type - { - throw std::runtime_error("Parsing of wide characters is not yet supported"); - } - - /// Add all common functions for a POD type. All operators, and /// common conversions template diff --git a/include/chaiscript/dispatchkit/proxy_functions.hpp b/include/chaiscript/dispatchkit/proxy_functions.hpp index b1a096e6..8fcffb28 100644 --- a/include/chaiscript/dispatchkit/proxy_functions.hpp +++ b/include/chaiscript/dispatchkit/proxy_functions.hpp @@ -777,30 +777,25 @@ namespace chaiscript private: template - auto do_call_impl(Class *o) const -> std::enable_if_t::value, Boxed_Value> + auto do_call_impl(Class *o) const { - return detail::Handle_Return::handle(o->*m_attr); + if constexpr(std::is_pointer::value) { + return detail::Handle_Return::handle(o->*m_attr); + } else { + return detail::Handle_Return::type>::handle(o->*m_attr); + } } template - auto do_call_impl(const Class *o) const -> std::enable_if_t::value, Boxed_Value> + auto do_call_impl(const Class *o) const { - return detail::Handle_Return::handle(o->*m_attr); + if constexpr(std::is_pointer::value) { + return detail::Handle_Return::handle(o->*m_attr); + } else { + return detail::Handle_Return::type>::type>::handle(o->*m_attr); + } } - template - auto do_call_impl(Class *o) const -> std::enable_if_t::value, Boxed_Value> - { - return detail::Handle_Return::type>::handle(o->*m_attr); - } - - template - auto do_call_impl(const Class *o) const -> std::enable_if_t::value, Boxed_Value> - { - return detail::Handle_Return::type>::type>::handle(o->*m_attr); - } - - static std::vector param_types() { diff --git a/include/chaiscript/dispatchkit/type_conversions.hpp b/include/chaiscript/dispatchkit/type_conversions.hpp index 85991b4b..d1f88233 100644 --- a/include/chaiscript/dispatchkit/type_conversions.hpp +++ b/include/chaiscript/dispatchkit/type_conversions.hpp @@ -562,23 +562,17 @@ namespace chaiscript /// \endcode /// template - Type_Conversion base_class(typename std::enable_if::value && std::is_polymorphic::value>::type* = nullptr) + Type_Conversion base_class() { //Can only be used with related polymorphic types //may be expanded some day to support conversions other than child -> parent static_assert(std::is_base_of::value, "Classes are not related by inheritance"); - return chaiscript::make_shared>(); - } - - template - Type_Conversion base_class(typename std::enable_if::value || !std::is_polymorphic::value>::type* = nullptr) - { - //Can only be used with related polymorphic types - //may be expanded some day to support conversions other than child -> parent - static_assert(std::is_base_of::value, "Classes are not related by inheritance"); - - return chaiscript::make_shared>(); + if constexpr(std::is_polymorphic::value && std::is_polymorphic::value) { + return chaiscript::make_shared>(); + } else { + return chaiscript::make_shared>(); + } } From 9bbe7238278f96141b51ab4c6e5313ffc2879bea Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Wed, 23 Aug 2017 21:38:41 -0600 Subject: [PATCH 034/155] Fix unhandled divide by zero --- include/chaiscript/dispatchkit/boxed_number.hpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/chaiscript/dispatchkit/boxed_number.hpp b/include/chaiscript/dispatchkit/boxed_number.hpp index 7a8ae645..10858b9c 100644 --- a/include/chaiscript/dispatchkit/boxed_number.hpp +++ b/include/chaiscript/dispatchkit/boxed_number.hpp @@ -194,6 +194,7 @@ namespace chaiscript case Operators::Opers::shift_right: return const_var(c_lhs >> c_rhs); case Operators::Opers::remainder: + check_divide_by_zero(c_rhs); return const_var(c_lhs % c_rhs); case Operators::Opers::bitwise_and: return const_var(c_lhs & c_rhs); @@ -216,6 +217,7 @@ namespace chaiscript *t_lhs += c_rhs; return t_bv; case Operators::Opers::assign_quotient: + check_divide_by_zero(c_rhs); *t_lhs /= c_rhs; return t_bv; case Operators::Opers::assign_difference: @@ -226,6 +228,7 @@ namespace chaiscript if constexpr (!std::is_floating_point::value) { switch (t_oper) { case Operators::Opers::assign_bitwise_and: + check_divide_by_zero(c_rhs); *t_lhs &= c_rhs; return t_bv; case Operators::Opers::assign_bitwise_or: From 9596e15049efae53784af0afe08677008232fc3d Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Thu, 24 Aug 2017 18:35:03 -0600 Subject: [PATCH 035/155] Warning / build fixes for gcc7 --- include/chaiscript/dispatchkit/bootstrap.hpp | 2 +- include/chaiscript/dispatchkit/boxed_number.hpp | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/include/chaiscript/dispatchkit/bootstrap.hpp b/include/chaiscript/dispatchkit/bootstrap.hpp index 8ae21bfa..67116da6 100644 --- a/include/chaiscript/dispatchkit/bootstrap.hpp +++ b/include/chaiscript/dispatchkit/bootstrap.hpp @@ -111,7 +111,7 @@ namespace chaiscript /// Internal function for converting from a string to a value /// uses ostream operator >> to perform the conversion template - auto parse_string(const std::string &i) + Input parse_string(const std::string &i) { if constexpr (!std::is_same::value && !std::is_same::value diff --git a/include/chaiscript/dispatchkit/boxed_number.hpp b/include/chaiscript/dispatchkit/boxed_number.hpp index 10858b9c..8bb39142 100644 --- a/include/chaiscript/dispatchkit/boxed_number.hpp +++ b/include/chaiscript/dispatchkit/boxed_number.hpp @@ -59,6 +59,7 @@ namespace chaiscript #pragma GCC diagnostic ignored "-Wconversion" #pragma GCC diagnostic ignored "-Wsign-conversion" #pragma GCC diagnostic ignored "-Wfloat-conversion" +#pragma GCC diagnostic ignored "-Wswitch" #endif /// \brief Represents any numeric type, generically. Used internally for generic operations between POD values @@ -80,7 +81,7 @@ namespace chaiscript }; template - constexpr static inline void check_divide_by_zero(T t) + constexpr static inline void check_divide_by_zero([[maybe_unused]] T t) { #ifndef CHAISCRIPT_NO_PROTECT_DIVIDEBYZERO if constexpr (!std::is_floating_point::value) { From d115dbfd795eead5fa3e3d78789993f37cf8680f Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Thu, 24 Aug 2017 20:46:22 -0600 Subject: [PATCH 036/155] move towards string_view --- include/chaiscript/chaiscript_defines.hpp | 15 +++------ .../chaiscript/dispatchkit/dispatchkit.hpp | 31 ++++++++++--------- 2 files changed, 21 insertions(+), 25 deletions(-) diff --git a/include/chaiscript/chaiscript_defines.hpp b/include/chaiscript/chaiscript_defines.hpp index 3754fc6a..44fa86e4 100644 --- a/include/chaiscript/chaiscript_defines.hpp +++ b/include/chaiscript/chaiscript_defines.hpp @@ -21,6 +21,7 @@ static_assert(_MSC_FULL_VER >= 190024210, "Visual C++ 2015 Update 3 or later req #endif #include +#include #if defined( _LIBCPP_VERSION ) #define CHAISCRIPT_LIBCPP @@ -152,10 +153,10 @@ namespace chaiscript { template - constexpr auto parse_num(const char *t_str) noexcept -> typename std::enable_if::value, T>::type + constexpr auto parse_num(const std::string_view &t_str) noexcept -> typename std::enable_if::value, T>::type { T t = 0; - for (char c = *t_str; (c = *t_str) != 0; ++t_str) { + for (const auto c : t_str) { if (c < '0' || c > '9') { return t; } @@ -167,7 +168,7 @@ namespace chaiscript { template - auto parse_num(const char *t_str) noexcept -> typename std::enable_if::value, T>::type + auto parse_num(const std::string_view &t_str) noexcept -> typename std::enable_if::value, T>::type { T t = 0; T base = 0; @@ -183,8 +184,7 @@ namespace chaiscript { } }; - for(; *t_str != '\0'; ++t_str) { - char c = *t_str; + for (const auto c : t_str) { if (c == '.') { decimal_place = 10; } else if (c == 'e' || c == 'E') { @@ -210,11 +210,6 @@ namespace chaiscript { return final_value(t, base, exponent, neg_exponent); } - template - T parse_num(const std::string &t_str) noexcept - { - return parse_num(t_str.c_str()); - } enum class Options { diff --git a/include/chaiscript/dispatchkit/dispatchkit.hpp b/include/chaiscript/dispatchkit/dispatchkit.hpp index e469ca29..3d6eba2a 100644 --- a/include/chaiscript/dispatchkit/dispatchkit.hpp +++ b/include/chaiscript/dispatchkit/dispatchkit.hpp @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -180,9 +181,9 @@ namespace chaiscript //Add a bit of ChaiScript to eval during module implementation - Module &eval(const std::string &str) + Module &eval(std::string str) { - m_evals.push_back(str); + m_evals.push_back(std::move(str)); return *this; } @@ -196,7 +197,7 @@ namespace chaiscript apply_globals(m_globals.begin(), m_globals.end(), t_engine); } - bool has_function(const Proxy_Function &new_f, const std::string &name) noexcept + bool has_function(const Proxy_Function &new_f, const std::string_view &name) noexcept { return std::any_of(m_funcs.begin(), m_funcs.end(), [&](const std::pair &existing_f) { @@ -438,7 +439,7 @@ namespace chaiscript { public: - typedef std::map Type_Name_Map; + typedef std::map> Type_Name_Map; typedef std::vector> Scope; typedef Stack_Holder::StackData StackData; @@ -447,7 +448,7 @@ namespace chaiscript std::vector>>> m_functions; std::vector> m_function_objects; std::vector> m_boxed_functions; - std::map m_global_objects; + std::map> m_global_objects; Type_Name_Map m_types; }; @@ -654,7 +655,7 @@ namespace chaiscript /// Searches the current stack for an object of the given name /// includes a special overload for the _ place holder object to /// ensure that it is always in scope. - Boxed_Value get_object(const std::string &name, std::atomic_uint_fast32_t &t_loc, Stack_Holder &t_holder) const + Boxed_Value get_object(const std::string_view &name, std::atomic_uint_fast32_t &t_loc, Stack_Holder &t_holder) const { enum class Loc : uint_fast32_t { located = 0x80000000, @@ -719,7 +720,7 @@ namespace chaiscript } /// Returns the type info for a named type - Type_Info get_type(const std::string &name, bool t_throw = true) const + Type_Info get_type(const std::string_view &name, bool t_throw = true) const { chaiscript::detail::threading::shared_lock l(m_mutex); @@ -776,7 +777,7 @@ namespace chaiscript /// Return a function by name - std::pair>> get_function(const std::string &t_name, const size_t t_hint) const + std::pair>> get_function(const std::string_view &t_name, const size_t t_hint) const { chaiscript::detail::threading::shared_lock l(m_mutex); @@ -804,7 +805,7 @@ namespace chaiscript /// \returns a function object (Boxed_Value wrapper) if it exists /// \throws std::range_error if it does not /// \warn does not obtain a mutex lock. \sa get_function_object for public version - std::pair get_function_object_int(const std::string &t_name, const size_t t_hint) const + std::pair get_function_object_int(const std::string_view &t_name, const size_t t_hint) const { const auto &funs = get_boxed_functions_int(); @@ -814,13 +815,13 @@ namespace chaiscript { return std::make_pair(std::distance(funs.begin(), itr), itr->second); } else { - throw std::range_error("Object not found: " + t_name); + throw std::range_error("Object not found: " + std::string(t_name)); } } /// Return true if a function exists - bool function_exists(const std::string &name) const + bool function_exists(const std::string_view &name) const { chaiscript::detail::threading::shared_lock l(m_mutex); @@ -1076,7 +1077,7 @@ namespace chaiscript - Boxed_Value call_function(const std::string &t_name, std::atomic_uint_fast32_t &t_loc, const std::vector ¶ms, + Boxed_Value call_function(const std::string_view &t_name, std::atomic_uint_fast32_t &t_loc, const std::vector ¶ms, const Type_Conversions_State &t_conversions) const { uint_fast32_t loc = t_loc; @@ -1166,7 +1167,7 @@ namespace chaiscript } /// return true if the Boxed_Value matches the registered type by name - bool is_type(const Boxed_Value &r, const std::string &user_typename) const noexcept + bool is_type(const Boxed_Value &r, const std::string_view &user_typename) const noexcept { try { if (get_type(user_typename).bare_equal(r.get_type_info())) @@ -1445,7 +1446,7 @@ namespace chaiscript { return std::find_if(t_c.begin(), t_c.end(), [&t_key](const typename Container::value_type &o) { - return o.first == t_key; + return std::equal(o.first.begin(), o.first.end(), t_key.begin(), t_key.end()); }); } @@ -1555,7 +1556,7 @@ namespace chaiscript return m_engine.get().add_object(t_name, std::move(obj), m_stack_holder.get()); } - Boxed_Value get_object(const std::string &t_name, std::atomic_uint_fast32_t &t_loc) const { + Boxed_Value get_object(const std::string_view &t_name, std::atomic_uint_fast32_t &t_loc) const { return m_engine.get().get_object(t_name, t_loc, m_stack_holder.get()); } From ff70341af243adfa3b300f7eccef09537721dc1d Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Thu, 24 Aug 2017 21:14:05 -0600 Subject: [PATCH 037/155] Avoid conversions to string_view, 2% perf savings --- include/chaiscript/dispatchkit/dispatchkit.hpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/include/chaiscript/dispatchkit/dispatchkit.hpp b/include/chaiscript/dispatchkit/dispatchkit.hpp index 3d6eba2a..ccaa03c0 100644 --- a/include/chaiscript/dispatchkit/dispatchkit.hpp +++ b/include/chaiscript/dispatchkit/dispatchkit.hpp @@ -437,9 +437,19 @@ namespace chaiscript /// of the object stack, functions and registered types. class Dispatch_Engine { + struct str_less { + bool operator()(const std::string &t_lhs, const std::string &t_rhs) const noexcept { + return t_lhs < t_rhs; + } + template + bool operator()(const LHS &t_lhs, const RHS &t_rhs) const noexcept { + return std::lexicographical_compare(t_lhs.begin(), t_lhs.end(), t_rhs.begin(), t_rhs.end()); + } + struct is_transparent{}; + }; public: - typedef std::map> Type_Name_Map; + typedef std::map Type_Name_Map; typedef std::vector> Scope; typedef Stack_Holder::StackData StackData; @@ -448,7 +458,7 @@ namespace chaiscript std::vector>>> m_functions; std::vector> m_function_objects; std::vector> m_boxed_functions; - std::map> m_global_objects; + std::map m_global_objects; Type_Name_Map m_types; }; From e49df4c54df5f93e9eaec985b6e61835cb277f86 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Fri, 25 Aug 2017 11:17:47 -0600 Subject: [PATCH 038/155] Move the parser to string_view --- include/chaiscript/chaiscript_defines.hpp | 10 +++ .../chaiscript/dispatchkit/dispatchkit.hpp | 10 --- .../chaiscript/language/chaiscript_common.hpp | 29 +++++++++ .../chaiscript/language/chaiscript_parser.hpp | 61 ++++++++++--------- include/chaiscript/utility/fnv1a.hpp | 24 ++++++-- include/chaiscript/utility/static_string.hpp | 24 ++++++++ 6 files changed, 114 insertions(+), 44 deletions(-) diff --git a/include/chaiscript/chaiscript_defines.hpp b/include/chaiscript/chaiscript_defines.hpp index 44fa86e4..ef937620 100644 --- a/include/chaiscript/chaiscript_defines.hpp +++ b/include/chaiscript/chaiscript_defines.hpp @@ -210,6 +210,16 @@ namespace chaiscript { return final_value(t, base, exponent, neg_exponent); } + struct str_less { + bool operator()(const std::string &t_lhs, const std::string &t_rhs) const noexcept { + return t_lhs < t_rhs; + } + template + bool operator()(const LHS &t_lhs, const RHS &t_rhs) const noexcept { + return std::lexicographical_compare(t_lhs.begin(), t_lhs.end(), t_rhs.begin(), t_rhs.end()); + } + struct is_transparent{}; + }; enum class Options { diff --git a/include/chaiscript/dispatchkit/dispatchkit.hpp b/include/chaiscript/dispatchkit/dispatchkit.hpp index ccaa03c0..f51aa0cf 100644 --- a/include/chaiscript/dispatchkit/dispatchkit.hpp +++ b/include/chaiscript/dispatchkit/dispatchkit.hpp @@ -437,16 +437,6 @@ namespace chaiscript /// of the object stack, functions and registered types. class Dispatch_Engine { - struct str_less { - bool operator()(const std::string &t_lhs, const std::string &t_rhs) const noexcept { - return t_lhs < t_rhs; - } - template - bool operator()(const LHS &t_lhs, const RHS &t_rhs) const noexcept { - return std::lexicographical_compare(t_lhs.begin(), t_lhs.end(), t_rhs.begin(), t_rhs.end()); - } - struct is_transparent{}; - }; public: typedef std::map Type_Name_Map; diff --git a/include/chaiscript/language/chaiscript_common.hpp b/include/chaiscript/language/chaiscript_common.hpp index da25af22..82aa478b 100644 --- a/include/chaiscript/language/chaiscript_common.hpp +++ b/include/chaiscript/language/chaiscript_common.hpp @@ -45,6 +45,19 @@ namespace chaiscript return words.count(name) == 1; } + static bool is_reserved_word(const std::string_view &name) noexcept + { + static const std::unordered_set words { + "def", "fun", "while", "for", "if", "else", + "&&", "||", ",", "auto", "return", "break", + "true", "false", "class", "attr", "var", "global", + "GLOBAL", "_", + "__LINE__", "__FILE__", "__FUNC__", "__CLASS__" + }; + + return words.count(name) == 1; + } + static bool valid_object_name(const std::string &name) noexcept { return name.find("::") == std::string::npos && !is_reserved_word(name); @@ -60,6 +73,22 @@ namespace chaiscript throw exception::illegal_name_error(name); } } + + static bool valid_object_name(const std::string_view &name) noexcept + { + return name.find("::") == std::string::npos && !is_reserved_word(name); + } + + static void validate_object_name(const std::string_view &name) + { + if (is_reserved_word(name)) { + throw exception::reserved_word_error(std::string(name)); + } + + if (name.find("::") != std::string::npos) { + throw exception::illegal_name_error(std::string(name)); + } + } }; /// Signature of module entry point that all binary loadable modules must implement. diff --git a/include/chaiscript/language/chaiscript_parser.hpp b/include/chaiscript/language/chaiscript_parser.hpp index 71112298..3c679639 100644 --- a/include/chaiscript/language/chaiscript_parser.hpp +++ b/include/chaiscript/language/chaiscript_parser.hpp @@ -210,7 +210,7 @@ namespace chaiscript std::array m_10 {{SS("*"), SS("/"), SS("%")}}; std::array m_11 {{SS("++"), SS("--"), SS("-"), SS("+"), SS("!"), SS("~")}}; - bool is_match(const std::string &t_str) const noexcept { + bool is_match(const std::string_view &t_str) const noexcept { constexpr std::array groups{{0,1,2,3,4,5,6,7,8,9,10,11}}; return std::any_of(groups.begin(), groups.end(), [&t_str, this](const std::size_t group){ return is_match(group, t_str); }); } @@ -239,9 +239,9 @@ namespace chaiscript } } - bool is_match(const std::size_t t_group, const std::string &t_str) const noexcept { + constexpr bool is_match(const std::size_t t_group, const std::string_view &t_str) const noexcept { auto match = [&t_str](const auto &array) { - return std::any_of(array.begin(), array.end(), [&t_str](const auto &v){ return v.c_str() == t_str; }); + return std::any_of(array.begin(), array.end(), [&t_str](const auto &v){ return v == t_str; }); }; switch (t_group) { @@ -325,9 +325,9 @@ namespace chaiscript { } - static std::string str(const Position &t_begin, const Position &t_end) noexcept { + static std::string_view str(const Position &t_begin, const Position &t_end) noexcept { if (t_begin.m_pos != nullptr && t_end.m_pos != nullptr) { - return std::string(t_begin.m_pos, t_end.m_pos); + return std::string_view(t_begin.m_pos, std::distance(t_begin.m_pos, t_end.m_pos)); } else { return {}; } @@ -423,10 +423,10 @@ namespace chaiscript Tracer m_tracer; Optimizer m_optimizer; - void validate_object_name(const std::string &name) const + void validate_object_name(const std::string_view &name) const { if (!Name_Validator::valid_object_name(name)) { - throw exception::eval_error("Invalid Object Name: " + name, File_Position(m_position.line, m_position.col), *m_filename); + throw exception::eval_error("Invalid Object Name: " + std::string(name), File_Position(m_position.line, m_position.col), *m_filename); } } @@ -720,7 +720,7 @@ namespace chaiscript } /// Parses a floating point value and returns a Boxed_Value representation of it - static Boxed_Value buildFloat(const std::string &t_val) + static Boxed_Value buildFloat(const std::string_view &t_val) { bool float_ = false; bool long_ = false; @@ -753,7 +753,7 @@ namespace chaiscript - static Boxed_Value buildInt(const int base, const std::string &t_val, const bool prefixed) + static Boxed_Value buildInt(const int base, std::string_view t_val, const bool prefixed) { bool unsigned_ = false; bool long_ = false; @@ -780,7 +780,7 @@ namespace chaiscript } } - const auto val = prefixed?std::string(t_val.begin()+2,t_val.end()):t_val; + if (prefixed) { t_val.remove_prefix(2); }; #ifdef __GNUC__ #pragma GCC diagnostic push @@ -793,7 +793,8 @@ namespace chaiscript #endif try { - auto u = std::stoll(val,nullptr,base); + /// TODO fix this to use from_chars + auto u = std::stoll(std::string(t_val),nullptr,base); if (!unsigned_ && !long_ && u >= std::numeric_limits::min() && u <= std::numeric_limits::max()) { @@ -813,7 +814,8 @@ namespace chaiscript } catch (const std::out_of_range &) { // too big to be signed try { - auto u = std::stoull(val,nullptr,base); + /// TODO fix this to use from_chars + auto u = std::stoull(std::string(t_val),nullptr,base); if (!longlong_ && u >= std::numeric_limits::min() && u <= std::numeric_limits::max()) { return const_var(static_cast(u)); @@ -833,9 +835,9 @@ namespace chaiscript } template - std::unique_ptr> make_node(std::string t_match, const int t_prev_line, const int t_prev_col, Param && ...param) + std::unique_ptr> make_node(std::string_view t_match, const int t_prev_line, const int t_prev_col, Param && ...param) { - return chaiscript::make_unique, T>(std::move(t_match), Parse_Location(m_filename, t_prev_line, t_prev_col, m_position.line, m_position.col), std::forward(param)...); + return chaiscript::make_unique, T>(std::string(t_match), Parse_Location(m_filename, t_prev_line, t_prev_col, m_position.line, m_position.col), std::forward(param)...); } /// Reads a number from the input, detecting if it's an integer or floating point @@ -848,20 +850,20 @@ namespace chaiscript if (Hex_()) { auto match = Position::str(start, m_position); auto bv = buildInt(16, match, true); - m_match_stack.emplace_back(make_node>(std::move(match), start.line, start.col, std::move(bv))); + m_match_stack.emplace_back(make_node>(match, start.line, start.col, std::move(bv))); return true; } if (Binary_()) { auto match = Position::str(start, m_position); auto bv = buildInt(2, match, true); - m_match_stack.push_back(make_node>(std::move(match), start.line, start.col, std::move(bv))); + m_match_stack.push_back(make_node>(match, start.line, start.col, std::move(bv))); return true; } if (Float_()) { auto match = Position::str(start, m_position); auto bv = buildFloat(match); - m_match_stack.push_back(make_node>(std::move(match), start.line, start.col, std::move(bv))); + m_match_stack.push_back(make_node>(match, start.line, start.col, std::move(bv))); return true; } else { @@ -869,11 +871,11 @@ namespace chaiscript auto match = Position::str(start, m_position); if (!match.empty() && (match[0] == '0')) { auto bv = buildInt(8, match, false); - m_match_stack.push_back(make_node>(std::move(match), start.line, start.col, std::move(bv))); + m_match_stack.push_back(make_node>(match, start.line, start.col, std::move(bv))); } else if (!match.empty()) { auto bv = buildInt(10, match, false); - m_match_stack.push_back(make_node>(std::move(match), start.line, start.col, std::move(bv))); + m_match_stack.push_back(make_node>(match, start.line, start.col, std::move(bv))); } else { return false; } @@ -932,7 +934,7 @@ namespace chaiscript if (Id_()) { auto text = Position::str(start, m_position); - const auto text_hash = utility::fnv1a_32(text.c_str()); + const auto text_hash = utility::fnv1a_32(text); if (validate) { validate_object_name(text); @@ -945,25 +947,25 @@ namespace chaiscript switch (text_hash) { case utility::fnv1a_32("true"): { - m_match_stack.push_back(make_node>(std::move(text), start.line, start.col, const_var(true))); + m_match_stack.push_back(make_node>(text, start.line, start.col, const_var(true))); } break; case utility::fnv1a_32("false"): { - m_match_stack.push_back(make_node>(std::move(text), start.line, start.col, const_var(false))); + m_match_stack.push_back(make_node>(text, start.line, start.col, const_var(false))); } break; case utility::fnv1a_32("Infinity"): { - m_match_stack.push_back(make_node>(std::move(text), start.line, start.col, + m_match_stack.push_back(make_node>(text, start.line, start.col, const_var(std::numeric_limits::infinity()))); } break; case utility::fnv1a_32("NaN"): { - m_match_stack.push_back(make_node>(std::move(text), start.line, start.col, + m_match_stack.push_back(make_node>(text, start.line, start.col, const_var(std::numeric_limits::quiet_NaN()))); } break; case utility::fnv1a_32("__LINE__"): { - m_match_stack.push_back(make_node>(std::move(text), start.line, start.col, + m_match_stack.push_back(make_node>(text, start.line, start.col, const_var(start.line))); } break; case utility::fnv1a_32("__FILE__"): { - m_match_stack.push_back(make_node>(std::move(text), start.line, start.col, + m_match_stack.push_back(make_node>(text, start.line, start.col, const_var(m_filename))); } break; case utility::fnv1a_32("__FUNC__"): { @@ -976,7 +978,7 @@ namespace chaiscript } } - m_match_stack.push_back(make_node>(std::move(text), start.line, start.col, + m_match_stack.push_back(make_node>(text, start.line, start.col, const_var(fun_name))); } break; case utility::fnv1a_32("__CLASS__"): { @@ -998,10 +1000,11 @@ namespace chaiscript Boxed_Value(std::make_shared()))); } break; default: { - std::string val = std::move(text); + auto val = text; if (*start == '`') { // 'escaped' literal, like an operator name val = Position::str(start+1, m_position-1); + // val.remove_prefix(1); val.remove_suffix(1); } m_match_stack.push_back(make_node>(val, start.line, start.col)); } break; @@ -1444,7 +1447,7 @@ namespace chaiscript return retval; } - bool is_operator(const std::string &t_s) const noexcept { + bool is_operator(const std::string_view &t_s) const noexcept { constexpr Operator_Matches operator_matches; return operator_matches.is_match(t_s); } diff --git a/include/chaiscript/utility/fnv1a.hpp b/include/chaiscript/utility/fnv1a.hpp index 2c55f43d..8442764a 100644 --- a/include/chaiscript/utility/fnv1a.hpp +++ b/include/chaiscript/utility/fnv1a.hpp @@ -18,9 +18,8 @@ namespace chaiscript namespace utility { - - - static constexpr std::uint32_t fnv1a_32(const char *s, std::uint32_t h = 0x811c9dc5) noexcept { + template + static constexpr std::uint32_t fnv1a_32(Itr begin, Itr end) noexcept { #ifdef __GNUC__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wsign-conversion" @@ -30,7 +29,14 @@ namespace chaiscript #pragma warning(push) #pragma warning(disable : 4307) #endif - return (*s == 0) ? h : fnv1a_32(s+1, ((h ^ (*s)) * 0x01000193)); + std::uint32_t h = 0x811c9dc5; + + while (begin != end) { + h = (h ^ (*begin)) * 0x01000193; + ++begin; + } + return h; + #ifdef CHAISCRIPT_MSVC #pragma warning(pop) #endif @@ -42,8 +48,16 @@ namespace chaiscript } - } + template + static constexpr std::uint32_t fnv1a_32(const char (&str)[N]) noexcept { + return fnv1a_32(std::begin(str), std::end(str)-1); + } + static constexpr std::uint32_t fnv1a_32(const std::string_view &sv) noexcept { + return fnv1a_32(sv.begin(), sv.end()); + } + + } } diff --git a/include/chaiscript/utility/static_string.hpp b/include/chaiscript/utility/static_string.hpp index fb63f28e..f6e4df1f 100644 --- a/include/chaiscript/utility/static_string.hpp +++ b/include/chaiscript/utility/static_string.hpp @@ -27,6 +27,30 @@ namespace chaiscript constexpr const char *c_str() const noexcept { return data; } + + constexpr auto begin() const noexcept { + return data; + } + + constexpr auto end() const noexcept { + return data + m_size; + } + + constexpr bool operator==(const std::string_view &other) const noexcept { + //return std::string_view(data, m_size) == other; + auto b1 = begin(); + const auto e1 = end(); + auto b2 = other.begin(); + const auto e2 = other.end(); + + if (e1 - b1 != e2 - b2) { return false; } + + while (b1 != e1) { + if (*b1 != *b2) { return false; } + ++b1; ++b2; + } + return true; + } const size_t m_size; const char *data = nullptr; From 04902f8209f53ce644a97c27570b545219749b41 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Fri, 25 Aug 2017 12:48:34 -0600 Subject: [PATCH 039/155] Use C++17's emplace_back return reference --- include/chaiscript/dispatchkit/dispatchkit.hpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/include/chaiscript/dispatchkit/dispatchkit.hpp b/include/chaiscript/dispatchkit/dispatchkit.hpp index f51aa0cf..6ff2accb 100644 --- a/include/chaiscript/dispatchkit/dispatchkit.hpp +++ b/include/chaiscript/dispatchkit/dispatchkit.hpp @@ -516,8 +516,7 @@ namespace chaiscript throw chaiscript::exception::name_conflict_error(t_name); } - stack_elem.emplace_back(t_name, std::move(obj)); - return stack_elem.back().second; + return stack_elem.emplace_back(t_name, std::move(obj)).second; } From dce9e17c34940904bc005a044e60441324abfae7 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Fri, 25 Aug 2017 14:49:44 -0600 Subject: [PATCH 040/155] More string_view tweaks --- .../language/chaiscript_algebraic.hpp | 2 +- .../chaiscript/language/chaiscript_common.hpp | 72 +++++++++---------- .../chaiscript/language/chaiscript_eval.hpp | 8 +-- .../language/chaiscript_optimizer.hpp | 6 +- include/chaiscript/utility/fnv1a.hpp | 4 ++ 5 files changed, 44 insertions(+), 48 deletions(-) diff --git a/include/chaiscript/language/chaiscript_algebraic.hpp b/include/chaiscript/language/chaiscript_algebraic.hpp index 06d242a8..d13607a9 100644 --- a/include/chaiscript/language/chaiscript_algebraic.hpp +++ b/include/chaiscript/language/chaiscript_algebraic.hpp @@ -50,7 +50,7 @@ namespace chaiscript return opers[static_cast(t_oper)]; } - constexpr static Opers to_operator(const char * const t_str, bool t_is_unary = false) noexcept + constexpr static Opers to_operator(const std::string_view &t_str, bool t_is_unary = false) noexcept { #ifdef CHAISCRIPT_MSVC #pragma warning(push) diff --git a/include/chaiscript/language/chaiscript_common.hpp b/include/chaiscript/language/chaiscript_common.hpp index 82aa478b..2c96efe3 100644 --- a/include/chaiscript/language/chaiscript_common.hpp +++ b/include/chaiscript/language/chaiscript_common.hpp @@ -32,54 +32,46 @@ struct AST_Node; namespace chaiscript { struct Name_Validator { - static bool is_reserved_word(const std::string &name) noexcept + template + static bool is_reserved_word(const T &s) noexcept { - static const std::unordered_set words { - "def", "fun", "while", "for", "if", "else", - "&&", "||", ",", "auto", "return", "break", - "true", "false", "class", "attr", "var", "global", - "GLOBAL", "_", - "__LINE__", "__FILE__", "__FUNC__", "__CLASS__" - }; + const static std::unordered_set words{ + utility::fnv1a_32("def"), + utility::fnv1a_32("fun"), + utility::fnv1a_32("while"), + utility::fnv1a_32("for"), + utility::fnv1a_32("if"), + utility::fnv1a_32("else"), + utility::fnv1a_32("&&"), + utility::fnv1a_32("||"), + utility::fnv1a_32(","), + utility::fnv1a_32("auto"), + utility::fnv1a_32("return"), + utility::fnv1a_32("break"), + utility::fnv1a_32("true"), + utility::fnv1a_32("false"), + utility::fnv1a_32("class"), + utility::fnv1a_32("attr"), + utility::fnv1a_32("var"), + utility::fnv1a_32("global"), + utility::fnv1a_32("GLOBAL"), + utility::fnv1a_32("_"), + utility::fnv1a_32("__LINE__"), + utility::fnv1a_32("__FILE__"), + utility::fnv1a_32("__FUNC__"), + utility::fnv1a_32("__CLASS__")}; - return words.count(name) == 1; + return words.count(utility::fnv1a_32(s)) == 1; } - static bool is_reserved_word(const std::string_view &name) noexcept - { - static const std::unordered_set words { - "def", "fun", "while", "for", "if", "else", - "&&", "||", ",", "auto", "return", "break", - "true", "false", "class", "attr", "var", "global", - "GLOBAL", "_", - "__LINE__", "__FILE__", "__FUNC__", "__CLASS__" - }; - - return words.count(name) == 1; - } - - static bool valid_object_name(const std::string &name) noexcept + template + static bool valid_object_name(const T &name) noexcept { return name.find("::") == std::string::npos && !is_reserved_word(name); } - static void validate_object_name(const std::string &name) - { - if (is_reserved_word(name)) { - throw exception::reserved_word_error(name); - } - - if (name.find("::") != std::string::npos) { - throw exception::illegal_name_error(name); - } - } - - static bool valid_object_name(const std::string_view &name) noexcept - { - return name.find("::") == std::string::npos && !is_reserved_word(name); - } - - static void validate_object_name(const std::string_view &name) + template + static void validate_object_name(const T &name) { if (is_reserved_word(name)) { throw exception::reserved_word_error(std::string(name)); diff --git a/include/chaiscript/language/chaiscript_eval.hpp b/include/chaiscript/language/chaiscript_eval.hpp index 6716dd9e..23557ca1 100644 --- a/include/chaiscript/language/chaiscript_eval.hpp +++ b/include/chaiscript/language/chaiscript_eval.hpp @@ -159,7 +159,7 @@ namespace chaiscript struct Fold_Right_Binary_Operator_AST_Node : AST_Node_Impl { Fold_Right_Binary_Operator_AST_Node(const std::string &t_oper, Parse_Location t_loc, std::vector> t_children, Boxed_Value t_rhs) : AST_Node_Impl(t_oper, AST_Node_Type::Binary, std::move(t_loc), std::move(t_children)), - m_oper(Operators::to_operator(t_oper.c_str())), + m_oper(Operators::to_operator(t_oper)), m_rhs(std::move(t_rhs)) { } @@ -204,7 +204,7 @@ namespace chaiscript struct Binary_Operator_AST_Node : AST_Node_Impl { Binary_Operator_AST_Node(const std::string &t_oper, Parse_Location t_loc, std::vector> t_children) : AST_Node_Impl(t_oper, AST_Node_Type::Binary, std::move(t_loc), std::move(t_children)), - m_oper(Operators::to_operator(t_oper.c_str())) + m_oper(Operators::to_operator(t_oper)) { } Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override { @@ -420,7 +420,7 @@ namespace chaiscript struct Equation_AST_Node final : AST_Node_Impl { Equation_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector> t_children) : AST_Node_Impl(std::move(t_ast_node_text), AST_Node_Type::Equation, std::move(t_loc), std::move(t_children)), - m_oper(Operators::to_operator(this->text.c_str())) + m_oper(Operators::to_operator(this->text)) { assert(this->children.size() == 2); } @@ -1162,7 +1162,7 @@ namespace chaiscript struct Prefix_AST_Node final : AST_Node_Impl { Prefix_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector> t_children) : AST_Node_Impl(std::move(t_ast_node_text), AST_Node_Type::Prefix, std::move(t_loc), std::move(t_children)), - m_oper(Operators::to_operator(this->text.c_str(), true)) + m_oper(Operators::to_operator(this->text, true)) { } Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override{ diff --git a/include/chaiscript/language/chaiscript_optimizer.hpp b/include/chaiscript/language/chaiscript_optimizer.hpp index 877cb4a7..3df867f1 100644 --- a/include/chaiscript/language/chaiscript_optimizer.hpp +++ b/include/chaiscript/language/chaiscript_optimizer.hpp @@ -241,7 +241,7 @@ namespace chaiscript { { try { const auto &oper = node->text; - const auto parsed = Operators::to_operator(oper.c_str()); + const auto parsed = Operators::to_operator(oper); if (parsed != Operators::Opers::invalid) { const auto rhs = dynamic_cast *>(node->children[1].get())->m_value; if (rhs.get_type_info().is_arithmetic()) { @@ -268,7 +268,7 @@ namespace chaiscript { { try { const auto &oper = node->text; - const auto parsed = Operators::to_operator(oper.c_str(), true); + const auto parsed = Operators::to_operator(oper, true); const auto lhs = dynamic_cast *>(node->children[0].get())->m_value; const auto match = oper + node->children[0]->text; @@ -308,7 +308,7 @@ namespace chaiscript { { try { const auto &oper = node->text; - const auto parsed = Operators::to_operator(oper.c_str()); + const auto parsed = Operators::to_operator(oper); if (parsed != Operators::Opers::invalid) { const auto lhs = dynamic_cast &>(*node->children[0]).m_value; const auto rhs = dynamic_cast &>(*node->children[1]).m_value; diff --git a/include/chaiscript/utility/fnv1a.hpp b/include/chaiscript/utility/fnv1a.hpp index 8442764a..07f9955f 100644 --- a/include/chaiscript/utility/fnv1a.hpp +++ b/include/chaiscript/utility/fnv1a.hpp @@ -57,6 +57,10 @@ namespace chaiscript return fnv1a_32(sv.begin(), sv.end()); } + static std::uint32_t fnv1a_32(const std::string &s) noexcept { + return fnv1a_32(s.begin(), s.end()); + } + } } From 4275ec6878080ef10d01a1e026cb4f75bd0a5386 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Fri, 25 Aug 2017 15:31:24 -0600 Subject: [PATCH 041/155] Make it easier to swap around some hashing algorithms --- .../language/chaiscript_algebraic.hpp | 62 +++++------ .../chaiscript/language/chaiscript_common.hpp | 50 ++++----- .../chaiscript/language/chaiscript_parser.hpp | 22 ++-- include/chaiscript/utility/fnv1a.hpp | 68 ------------ include/chaiscript/utility/hash.hpp | 101 ++++++++++++++++++ 5 files changed, 168 insertions(+), 135 deletions(-) delete mode 100644 include/chaiscript/utility/fnv1a.hpp create mode 100644 include/chaiscript/utility/hash.hpp diff --git a/include/chaiscript/language/chaiscript_algebraic.hpp b/include/chaiscript/language/chaiscript_algebraic.hpp index d13607a9..cfaa5346 100644 --- a/include/chaiscript/language/chaiscript_algebraic.hpp +++ b/include/chaiscript/language/chaiscript_algebraic.hpp @@ -11,7 +11,7 @@ #ifndef CHAISCRIPT_ALGEBRAIC_HPP_ #define CHAISCRIPT_ALGEBRAIC_HPP_ -#include "../utility/fnv1a.hpp" +#include "../utility/hash.hpp" #include @@ -57,37 +57,37 @@ namespace chaiscript #pragma warning(disable : 4307) #endif - const auto op_hash = utility::fnv1a_32(t_str); + const auto op_hash = utility::hash(t_str); switch (op_hash) { - case utility::fnv1a_32("=="): { return Opers::equals; } - case utility::fnv1a_32("<"): { return Opers::less_than; } - case utility::fnv1a_32(">"): { return Opers::greater_than; } - case utility::fnv1a_32("<="): { return Opers::less_than_equal; } - case utility::fnv1a_32(">="): { return Opers::greater_than_equal; } - case utility::fnv1a_32("!="): { return Opers::not_equal; } - case utility::fnv1a_32("="): { return Opers::assign; } - case utility::fnv1a_32("++"): { return Opers::pre_increment; } - case utility::fnv1a_32("--"): { return Opers::pre_decrement; } - case utility::fnv1a_32("*="): { return Opers::assign_product; } - case utility::fnv1a_32("+="): { return Opers::assign_sum; } - case utility::fnv1a_32("-="): { return Opers::assign_difference; } - case utility::fnv1a_32("&="): { return Opers::assign_bitwise_and; } - case utility::fnv1a_32("|="): { return Opers::assign_bitwise_or; } - case utility::fnv1a_32("<<="): { return Opers::assign_shift_left; } - case utility::fnv1a_32(">>="): { return Opers::assign_shift_right; } - case utility::fnv1a_32("%="): { return Opers::assign_remainder; } - case utility::fnv1a_32("^="): { return Opers::assign_bitwise_xor; } - case utility::fnv1a_32("<<"): { return Opers::shift_left; } - case utility::fnv1a_32(">>"): { return Opers::shift_right; } - case utility::fnv1a_32("%"): { return Opers::remainder; } - case utility::fnv1a_32("&"): { return Opers::bitwise_and; } - case utility::fnv1a_32("|"): { return Opers::bitwise_or; } - case utility::fnv1a_32("^"): { return Opers::bitwise_xor; } - case utility::fnv1a_32("~"): { return Opers::bitwise_complement; } - case utility::fnv1a_32("+"): { return t_is_unary ? Opers::unary_plus : Opers::sum; } - case utility::fnv1a_32("-"): { return t_is_unary ? Opers::unary_minus : Opers::difference; } - case utility::fnv1a_32("/"): { return Opers::quotient; } - case utility::fnv1a_32("*"): { return Opers::product; } + case utility::hash("=="): { return Opers::equals; } + case utility::hash("<"): { return Opers::less_than; } + case utility::hash(">"): { return Opers::greater_than; } + case utility::hash("<="): { return Opers::less_than_equal; } + case utility::hash(">="): { return Opers::greater_than_equal; } + case utility::hash("!="): { return Opers::not_equal; } + case utility::hash("="): { return Opers::assign; } + case utility::hash("++"): { return Opers::pre_increment; } + case utility::hash("--"): { return Opers::pre_decrement; } + case utility::hash("*="): { return Opers::assign_product; } + case utility::hash("+="): { return Opers::assign_sum; } + case utility::hash("-="): { return Opers::assign_difference; } + case utility::hash("&="): { return Opers::assign_bitwise_and; } + case utility::hash("|="): { return Opers::assign_bitwise_or; } + case utility::hash("<<="): { return Opers::assign_shift_left; } + case utility::hash(">>="): { return Opers::assign_shift_right; } + case utility::hash("%="): { return Opers::assign_remainder; } + case utility::hash("^="): { return Opers::assign_bitwise_xor; } + case utility::hash("<<"): { return Opers::shift_left; } + case utility::hash(">>"): { return Opers::shift_right; } + case utility::hash("%"): { return Opers::remainder; } + case utility::hash("&"): { return Opers::bitwise_and; } + case utility::hash("|"): { return Opers::bitwise_or; } + case utility::hash("^"): { return Opers::bitwise_xor; } + case utility::hash("~"): { return Opers::bitwise_complement; } + case utility::hash("+"): { return t_is_unary ? Opers::unary_plus : Opers::sum; } + case utility::hash("-"): { return t_is_unary ? Opers::unary_minus : Opers::difference; } + case utility::hash("/"): { return Opers::quotient; } + case utility::hash("*"): { return Opers::product; } default: { return Opers::invalid; } } #ifdef CHAISCRIPT_MSVC diff --git a/include/chaiscript/language/chaiscript_common.hpp b/include/chaiscript/language/chaiscript_common.hpp index 2c96efe3..837ebeea 100644 --- a/include/chaiscript/language/chaiscript_common.hpp +++ b/include/chaiscript/language/chaiscript_common.hpp @@ -36,32 +36,32 @@ namespace chaiscript static bool is_reserved_word(const T &s) noexcept { const static std::unordered_set words{ - utility::fnv1a_32("def"), - utility::fnv1a_32("fun"), - utility::fnv1a_32("while"), - utility::fnv1a_32("for"), - utility::fnv1a_32("if"), - utility::fnv1a_32("else"), - utility::fnv1a_32("&&"), - utility::fnv1a_32("||"), - utility::fnv1a_32(","), - utility::fnv1a_32("auto"), - utility::fnv1a_32("return"), - utility::fnv1a_32("break"), - utility::fnv1a_32("true"), - utility::fnv1a_32("false"), - utility::fnv1a_32("class"), - utility::fnv1a_32("attr"), - utility::fnv1a_32("var"), - utility::fnv1a_32("global"), - utility::fnv1a_32("GLOBAL"), - utility::fnv1a_32("_"), - utility::fnv1a_32("__LINE__"), - utility::fnv1a_32("__FILE__"), - utility::fnv1a_32("__FUNC__"), - utility::fnv1a_32("__CLASS__")}; + utility::hash("def"), + utility::hash("fun"), + utility::hash("while"), + utility::hash("for"), + utility::hash("if"), + utility::hash("else"), + utility::hash("&&"), + utility::hash("||"), + utility::hash(","), + utility::hash("auto"), + utility::hash("return"), + utility::hash("break"), + utility::hash("true"), + utility::hash("false"), + utility::hash("class"), + utility::hash("attr"), + utility::hash("var"), + utility::hash("global"), + utility::hash("GLOBAL"), + utility::hash("_"), + utility::hash("__LINE__"), + utility::hash("__FILE__"), + utility::hash("__FUNC__"), + utility::hash("__CLASS__")}; - return words.count(utility::fnv1a_32(s)) == 1; + return words.count(utility::hash(s)) == 1; } template diff --git a/include/chaiscript/language/chaiscript_parser.hpp b/include/chaiscript/language/chaiscript_parser.hpp index 3c679639..535aca81 100644 --- a/include/chaiscript/language/chaiscript_parser.hpp +++ b/include/chaiscript/language/chaiscript_parser.hpp @@ -27,7 +27,7 @@ #include "chaiscript_common.hpp" #include "chaiscript_optimizer.hpp" #include "chaiscript_tracer.hpp" -#include "../utility/fnv1a.hpp" +#include "../utility/hash.hpp" #include "../utility/static_string.hpp" #if defined(CHAISCRIPT_UTF16_UTF32) @@ -934,7 +934,7 @@ namespace chaiscript if (Id_()) { auto text = Position::str(start, m_position); - const auto text_hash = utility::fnv1a_32(text); + const auto text_hash = utility::hash(text); if (validate) { validate_object_name(text); @@ -946,29 +946,29 @@ namespace chaiscript #endif switch (text_hash) { - case utility::fnv1a_32("true"): { + case utility::hash("true"): { m_match_stack.push_back(make_node>(text, start.line, start.col, const_var(true))); } break; - case utility::fnv1a_32("false"): { + case utility::hash("false"): { m_match_stack.push_back(make_node>(text, start.line, start.col, const_var(false))); } break; - case utility::fnv1a_32("Infinity"): { + case utility::hash("Infinity"): { m_match_stack.push_back(make_node>(text, start.line, start.col, const_var(std::numeric_limits::infinity()))); } break; - case utility::fnv1a_32("NaN"): { + case utility::hash("NaN"): { m_match_stack.push_back(make_node>(text, start.line, start.col, const_var(std::numeric_limits::quiet_NaN()))); } break; - case utility::fnv1a_32("__LINE__"): { + case utility::hash("__LINE__"): { m_match_stack.push_back(make_node>(text, start.line, start.col, const_var(start.line))); } break; - case utility::fnv1a_32("__FILE__"): { + case utility::hash("__FILE__"): { m_match_stack.push_back(make_node>(text, start.line, start.col, const_var(m_filename))); } break; - case utility::fnv1a_32("__FUNC__"): { + case utility::hash("__FUNC__"): { std::string fun_name = "NOT_IN_FUNCTION"; for (size_t idx = m_match_stack.size() - 1; idx > 0; --idx) { @@ -981,7 +981,7 @@ namespace chaiscript m_match_stack.push_back(make_node>(text, start.line, start.col, const_var(fun_name))); } break; - case utility::fnv1a_32("__CLASS__"): { + case utility::hash("__CLASS__"): { std::string fun_name = "NOT_IN_CLASS"; for (size_t idx = m_match_stack.size() - 1; idx > 1; --idx) { @@ -995,7 +995,7 @@ namespace chaiscript m_match_stack.push_back(make_node>(std::move(text), start.line, start.col, const_var(fun_name))); } break; - case utility::fnv1a_32("_"): { + case utility::hash("_"): { m_match_stack.push_back(make_node>(std::move(text), start.line, start.col, Boxed_Value(std::make_shared()))); } break; diff --git a/include/chaiscript/utility/fnv1a.hpp b/include/chaiscript/utility/fnv1a.hpp deleted file mode 100644 index 07f9955f..00000000 --- a/include/chaiscript/utility/fnv1a.hpp +++ /dev/null @@ -1,68 +0,0 @@ -// This file is distributed under the BSD License. -// See "license.txt" for details. -// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) -// Copyright 2009-2017, Jason Turner (jason@emptycrate.com) -// http://www.chaiscript.com - -#ifndef CHAISCRIPT_UTILITY_FNV1A_HPP_ -#define CHAISCRIPT_UTILITY_FNV1A_HPP_ - - -#include -#include "../chaiscript_defines.hpp" - - -namespace chaiscript -{ - - - namespace utility - { - template - static constexpr std::uint32_t fnv1a_32(Itr begin, Itr end) noexcept { -#ifdef __GNUC__ -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wsign-conversion" -#endif - -#ifdef CHAISCRIPT_MSVC -#pragma warning(push) -#pragma warning(disable : 4307) -#endif - std::uint32_t h = 0x811c9dc5; - - while (begin != end) { - h = (h ^ (*begin)) * 0x01000193; - ++begin; - } - return h; - -#ifdef CHAISCRIPT_MSVC -#pragma warning(pop) -#endif - -#ifdef __GNUC__ -#pragma GCC diagnostic pop -#endif - - } - - - template - static constexpr std::uint32_t fnv1a_32(const char (&str)[N]) noexcept { - return fnv1a_32(std::begin(str), std::end(str)-1); - } - - static constexpr std::uint32_t fnv1a_32(const std::string_view &sv) noexcept { - return fnv1a_32(sv.begin(), sv.end()); - } - - static std::uint32_t fnv1a_32(const std::string &s) noexcept { - return fnv1a_32(s.begin(), s.end()); - } - - } - -} - -#endif diff --git a/include/chaiscript/utility/hash.hpp b/include/chaiscript/utility/hash.hpp new file mode 100644 index 00000000..cffd2142 --- /dev/null +++ b/include/chaiscript/utility/hash.hpp @@ -0,0 +1,101 @@ +// This file is distributed under the BSD License. +// See "license.txt" for details. +// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) +// Copyright 2009-2017, Jason Turner (jason@emptycrate.com) +// http://www.chaiscript.com + +#ifndef CHAISCRIPT_UTILITY_FNV1A_HPP_ +#define CHAISCRIPT_UTILITY_FNV1A_HPP_ + + +#include +#include "../chaiscript_defines.hpp" + + +namespace chaiscript +{ + namespace utility + { + namespace fnv1a { + template + static constexpr std::uint32_t hash(Itr begin, Itr end) noexcept { +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wsign-conversion" +#endif + +#ifdef CHAISCRIPT_MSVC +#pragma warning(push) +#pragma warning(disable : 4307) +#endif + std::uint32_t h = 0x811c9dc5; + + while (begin != end) { + h = (h ^ (*begin)) * 0x01000193; + ++begin; + } + return h; + +#ifdef CHAISCRIPT_MSVC +#pragma warning(pop) +#endif + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif + + } + + + template + static constexpr std::uint32_t hash(const char (&str)[N]) noexcept { + return hash(std::begin(str), std::end(str)-1); + } + + static constexpr std::uint32_t hash(const std::string_view &sv) noexcept { + return hash(sv.begin(), sv.end()); + } + + static inline std::uint32_t hash(const std::string &s) noexcept { + return hash(s.begin(), s.end()); + } + } + + namespace jenkins_one_at_a_time { + template + static constexpr std::uint32_t hash(Itr begin, Itr end) noexcept { + std::uint32_t hash = 0; + + while (begin != end) { + hash += *begin; + hash += hash << 10; + hash ^= hash >> 6; + ++begin; + } + + hash += hash << 3; + hash ^= hash >> 11; + hash += hash << 15; + return hash; + } + + template + static constexpr std::uint32_t hash(const char (&str)[N]) noexcept { + return hash(std::begin(str), std::end(str)-1); + } + + static constexpr std::uint32_t hash(const std::string_view &sv) noexcept { + return hash(sv.begin(), sv.end()); + } + + static inline std::uint32_t hash(const std::string &s) noexcept { + return hash(s.begin(), s.end()); + } + } + + using fnv1a::hash; + } + +} + +#endif From f9a1784b9b11ee0adaec489586f68c0c42c7bd11 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Fri, 25 Aug 2017 19:48:13 -0600 Subject: [PATCH 042/155] Move json.hpp to variant --- include/chaiscript/utility/json.hpp | 354 +++++++----------- include/chaiscript/utility/quick_flat_map.hpp | 81 ++++ 2 files changed, 223 insertions(+), 212 deletions(-) create mode 100644 include/chaiscript/utility/quick_flat_map.hpp diff --git a/include/chaiscript/utility/json.hpp b/include/chaiscript/utility/json.hpp index 0b96dcae..bf88f0ff 100644 --- a/include/chaiscript/utility/json.hpp +++ b/include/chaiscript/utility/json.hpp @@ -3,7 +3,6 @@ // -#pragma once #ifndef SIMPLEJSON_HPP #define SIMPLEJSON_HPP @@ -19,7 +18,9 @@ #include #include #include +#include #include "../chaiscript_defines.hpp" +#include "quick_flat_map.hpp" namespace json { @@ -37,7 +38,7 @@ class JSON { public: enum class Class { - Null, + Null = 0, Object, Array, String, @@ -48,155 +49,98 @@ class JSON private: - struct QuickFlatMap + + using Data = std::variant, std::vector, std::string, double, int, bool>; + + struct Internal { - auto find(const std::string &s) noexcept { - return std::find_if(std::begin(data), std::end(data), [&s](const auto &d) { return d.first == s; }); + Internal(nullptr_t) : d(nullptr) { } + Internal() : d(nullptr) { } + Internal(Class c) : d(make_type(c)) { } + template Internal(T t) : d(std::move(t)) { } + + static Data make_type(Class c) { + switch (c) { + case Class::Null: return nullptr; + case Class::Object: return chaiscript::utility::QuickFlatMap{}; + case Class::Array: return std::vector{}; + case Class::String: return std::string{}; + case Class::Floating: return double{}; + case Class::Integral: return int{}; + case Class::Boolean: return bool{}; + } + throw std::runtime_error("unknown type"); } - auto find(const std::string &s) const noexcept { - return std::find_if(std::begin(data), std::end(data), [&s](const auto &d) { return d.first == s; }); - } - - auto size() const noexcept { - return data.size(); - } - - auto begin() const noexcept { - return data.begin(); - } - - auto end() const noexcept { - return data.end(); - } - - - auto begin() noexcept { - return data.begin(); - } - - auto end() noexcept { - return data.end(); - } - - - JSON &operator[](const std::string &s) { - const auto itr = find(s); - if (itr != data.end()) { - return itr->second; - } else { - data.emplace_back(s, JSON()); - return data.back().second; + void set_type(Class c) { + if (type() != c) { + d = make_type(c); } } - JSON &at(const std::string &s) { - const auto itr = find(s); - if (itr != data.end()) { - return itr->second; + Class type() const noexcept { + return Class(d.index()); + } + + + template + decltype(auto) visit_or(Visitor &&visitor, Or &&other) const + { + if (type() == Class(ClassValue)) { + return visitor(std::get(ClassValue)>(d)); } else { - throw std::out_of_range("Unknown key: " + s); + return other(); } } - const JSON &at(const std::string &s) const { - const auto itr = find(s); - if (itr != data.end()) { - return itr->second; - } else { - throw std::out_of_range("Unknown key: " + s); - } + template + auto &get_set_type() { + set_type(ClassValue); + return std::get(ClassValue)>(d); } - size_t count(const std::string &s) const noexcept { - return (find(s) != data.end())?1:0; + auto &Map() { + return get_set_type(); + } + auto &Vector() { + return get_set_type(); + } + auto &String() { + return get_set_type(); + } + auto &Int() { + return get_set_type(); + } + auto &Float() { + return get_set_type(); + } + auto &Bool() { + return get_set_type(); } - std::vector> data; - - using iterator = decltype(data)::iterator; - using const_iterator = decltype(data)::const_iterator; + auto Map() const noexcept { + return std::get_if(Class::Object)>(&d); + } + auto Vector() const noexcept { + return std::get_if(Class::Array)>(&d); + } + auto String() const noexcept { + return std::get_if(Class::String)>(&d); + } + auto Int() const noexcept { + return std::get_if(Class::Integral)>(&d); + } + auto Float() const noexcept { + return std::get_if(Class::Floating)>(&d); + } + auto Bool() const noexcept { + return std::get_if(Class::Boolean)>(&d); + } + Data d; }; - struct Internal { - template - auto clone(const std::unique_ptr &ptr) { - if (ptr != nullptr) { - return std::make_unique(*ptr); - } else { - return std::unique_ptr(nullptr); - } - } - - Internal( double d ) : Float( d ), Type(Class::Floating) {} - Internal( long l ) : Int( l ), Type(Class::Integral) {} - Internal( bool b ) : Bool( b ), Type(Class::Boolean) {} - Internal( std::string s ) : String(std::make_unique(std::move(s))), Type(Class::String) {} - Internal() : Type(Class::Null) {} - - Internal(Class t_type) { - set_type(t_type); - } - - Internal(const Internal &other) - : List(clone(other.List)), - Map(clone(other.Map)), - String(clone(other.String)), - Float(other.Float), - Int(other.Int), - Bool(other.Bool), - Type(other.Type) - { - } - - Internal &operator=(const Internal &other) - { - List = clone(other.List); - Map = clone(other.Map); - String = clone(other.String); - Float = other.Float; - Int = other.Int; - Bool = other.Bool; - Type = other.Type; - return *this; - } - - void set_type( Class type ) { - if( type == Type ) { - return; - } - - Map.reset(); - List.reset(); - String.reset(); - - switch( type ) { - case Class::Object: Map = std::make_unique(); break; - case Class::Array: List = std::make_unique>(); break; - case Class::String: String = std::make_unique(); break; - case Class::Floating: Float = 0.0; break; - case Class::Integral: Int = 0; break; - case Class::Boolean: Bool = false; break; - case Class::Null: break; - } - - Type = type; - } - - Internal(Internal &&) = default; - Internal &operator=(Internal &&) = default; - - std::unique_ptr> List; - std::unique_ptr Map; - std::unique_ptr String; - double Float = 0; - long Int = 0; - bool Bool = false; - - Class Type = Class::Null; - }; Internal internal; @@ -248,7 +192,7 @@ class JSON explicit JSON( T b, typename enable_if::value>::type* = nullptr ) noexcept : internal( static_cast(b) ) {} template - explicit JSON( T i, typename enable_if::value && !is_same::value>::type* = nullptr ) noexcept : internal( static_cast(i) ) {} + explicit JSON( T i, typename enable_if::value && !is_same::value>::type* = nullptr ) noexcept : internal( static_cast(i) ) {} template explicit JSON( T f, typename enable_if::value>::type* = nullptr ) noexcept : internal( static_cast(f) ) {} @@ -261,17 +205,16 @@ class JSON static JSON Load( const std::string & ); JSON& operator[]( const std::string &key ) { - internal.set_type( Class::Object ); - return internal.Map->operator[]( key ); + return internal.Map().operator[]( key ); } JSON& operator[]( const size_t index ) { - internal.set_type( Class::Array ); - if( index >= internal.List->size() ) { - internal.List->resize( index + 1 ); + auto &vec = internal.Vector(); + if( index >= vec.size() ) { + vec.resize( index + 1 ); } - return internal.List->operator[]( index ); + return vec.operator[]( index ); } @@ -280,7 +223,10 @@ class JSON } const JSON &at( const std::string &key ) const { - return internal.Map->at( key ); + return internal.visit_or( + [&](const auto &m)->const JSON &{ return m.at(key); }, + []()->const JSON &{ throw std::range_error("Not an object, no keys"); } + ); } JSON &at( size_t index ) { @@ -288,100 +234,84 @@ class JSON } const JSON &at( size_t index ) const { - return internal.List->at( index ); + return internal.visit_or( + [&](const auto &m)->const JSON&{ return m.at(index); }, + []()->const JSON &{ throw std::range_error("Not an array, no indexes"); } + ); } - - long length() const noexcept { - if( internal.Type == Class::Array ) { - return static_cast(internal.List->size()); - } else { - return -1; - } + auto length() const noexcept { + return internal.visit_or( + [&](const auto &m){ return static_cast(m.size()); }, + [](){ return -1; } + ); } bool has_key( const std::string &key ) const noexcept { - if( internal.Type == Class::Object ) { - return internal.Map->count(key) != 0; - } - - return false; + return internal.visit_or( + [&](const auto &m){ return m.count(key) != 0; }, + [](){ return false; } + ); } int size() const noexcept { - if( internal.Type == Class::Object ) { - return static_cast(internal.Map->size()); - } else if( internal.Type == Class::Array ) { - return static_cast(internal.List->size()); + if (auto m = internal.Map(); m != nullptr) { + return static_cast(m->size()); + } if (auto v = internal.Vector(); v != nullptr) { + return static_cast(v->size()); } else { return -1; } } - Class JSONType() const noexcept { return internal.Type; } + Class JSONType() const noexcept { return internal.type(); } /// Functions for getting primitives from the JSON object. - bool is_null() const noexcept { return internal.Type == Class::Null; } + bool is_null() const noexcept { return internal.type() == Class::Null; } - std::string to_string() const { bool b; return to_string( b ); } - std::string to_string( bool &ok ) const { - ok = (internal.Type == Class::String); - return ok ? *internal.String : std::string(""); + std::string to_string() const noexcept { + return internal.visit_or( + [](const auto &o){ return o; }, + [](){ return std::string{}; } + ); + } + double to_float() const noexcept { + return internal.visit_or( + [](const auto &o){ return o; }, + [](){ return double{}; } + ); + } + int to_int() const noexcept { + return internal.visit_or( + [](const auto &o){ return o; }, + [](){ return int{}; } + ); + } + bool to_bool() const noexcept { + return internal.visit_or( + [](const auto &o){ return o; }, + [](){ return false; } + ); } - double to_float() const noexcept { bool b; return to_float( b ); } - double to_float( bool &ok ) const noexcept { - ok = (internal.Type == Class::Floating); - return ok ? internal.Float : 0.0; - } - - long to_int() const noexcept { bool b; return to_int( b ); } - long to_int( bool &ok ) const noexcept { - ok = (internal.Type == Class::Integral); - return ok ? internal.Int : 0; - } - - bool to_bool() const noexcept { bool b; return to_bool( b ); } - bool to_bool( bool &ok ) const noexcept { - ok = (internal.Type == Class::Boolean); - return ok ? internal.Bool : false; - } - - JSONWrapper object_range() { - if( internal.Type == Class::Object ) { - return JSONWrapper( internal.Map.get() ); - } else { - return JSONWrapper( nullptr ); - } + JSONWrapper> object_range() { + return std::get_if(Class::Object)>(&internal.d); } JSONWrapper> array_range() { - if( internal.Type == Class::Array ) { - return JSONWrapper>( internal.List.get() ); - } else { - return JSONWrapper>( nullptr ); - } + return std::get_if(Class::Array)>(&internal.d); } - JSONConstWrapper object_range() const { - if( internal.Type == Class::Object ) { - return JSONConstWrapper( internal.Map.get() ); - } else { - return JSONConstWrapper( nullptr ); - } + JSONConstWrapper> object_range() const { + return std::get_if(Class::Object)>(&internal.d); } - JSONConstWrapper> array_range() const { - if( internal.Type == Class::Array ) { - return JSONConstWrapper>( internal.List.get() ); - } else { - return JSONConstWrapper>( nullptr ); - } + return std::get_if(Class::Array)>(&internal.d); } std::string dump( long depth = 1, std::string tab = " ") const { - switch( internal.Type ) { + switch( internal.type() ) { case Class::Null: return "null"; case Class::Object: { @@ -390,7 +320,7 @@ class JSON std::string s = "{\n"; bool skip = true; - for( auto &p : *internal.Map ) { + for( auto &p : *internal.Map() ) { if( !skip ) { s += ",\n"; } s += ( pad + "\"" + p.first + "\" : " + p.second.dump( depth + 1, tab ) ); skip = false; @@ -401,7 +331,7 @@ class JSON case Class::Array: { std::string s = "["; bool skip = true; - for( auto &p : *internal.List ) { + for( auto &p : *internal.Vector() ) { if( !skip ) { s += ", "; } s += p.dump( depth + 1, tab ); skip = false; @@ -410,13 +340,13 @@ class JSON return s; } case Class::String: - return "\"" + json_escape( *internal.String ) + "\""; + return "\"" + json_escape( *internal.String() ) + "\""; case Class::Floating: - return std::to_string( internal.Float ); + return std::to_string( *internal.Float() ); case Class::Integral: - return std::to_string( internal.Int ); + return std::to_string( *internal.Int() ); case Class::Boolean: - return internal.Bool ? "true" : "false"; + return *internal.Bool() ? "true" : "false"; } throw std::runtime_error("Unhandled JSON type"); diff --git a/include/chaiscript/utility/quick_flat_map.hpp b/include/chaiscript/utility/quick_flat_map.hpp new file mode 100644 index 00000000..1d3be2bb --- /dev/null +++ b/include/chaiscript/utility/quick_flat_map.hpp @@ -0,0 +1,81 @@ +#ifndef CHAISCRIPT_UTILITY_QUICK_FLAT_MAP_HPP +#define CHAISCRIPT_UTILITY_QUICK_FLAT_MAP_HPP + +namespace chaiscript::utility { + + template + struct QuickFlatMap + { + auto find(const Key &s) noexcept { + return std::find_if(std::begin(data), std::end(data), [&s](const auto &d) { return d.first == s; }); + } + + auto find(const Key &s) const noexcept { + return std::find_if(std::begin(data), std::end(data), [&s](const auto &d) { return d.first == s; }); + } + + auto size() const noexcept { + return data.size(); + } + + auto begin() const noexcept { + return data.begin(); + } + + auto end() const noexcept { + return data.end(); + } + + + auto begin() noexcept { + return data.begin(); + } + + auto end() noexcept { + return data.end(); + } + + + Value &operator[](const Key &s) { + const auto itr = find(s); + if (itr != data.end()) { + return itr->second; + } else { + return data.emplace_back(s, Value()).second; + } + } + + Value &at(const Key &s) { + const auto itr = find(s); + if (itr != data.end()) { + return itr->second; + } else { + throw std::out_of_range("Unknown key: " + s); + } + } + + const Value &at(const Key &s) const { + const auto itr = find(s); + if (itr != data.end()) { + return itr->second; + } else { + throw std::out_of_range("Unknown key: " + s); + } + } + + size_t count(const Key &s) const noexcept { + return (find(s) != data.end())?1:0; + } + + std::vector> data; + + using iterator = typename decltype(data)::iterator; + using const_iterator = typename decltype(data)::const_iterator; + + + }; + +} + +#endif + From e6a6a20eb657240c0bea05729eb9979b2edf7053 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Sat, 26 Aug 2017 08:24:55 -0600 Subject: [PATCH 043/155] Handful for C++17 things --- .../dispatchkit/proxy_functions_detail.hpp | 28 +++++-------------- .../chaiscript/language/chaiscript_eval.hpp | 21 +++++++------- 2 files changed, 18 insertions(+), 31 deletions(-) diff --git a/include/chaiscript/dispatchkit/proxy_functions_detail.hpp b/include/chaiscript/dispatchkit/proxy_functions_detail.hpp index 70d77b9a..8db9b509 100644 --- a/include/chaiscript/dispatchkit/proxy_functions_detail.hpp +++ b/include/chaiscript/dispatchkit/proxy_functions_detail.hpp @@ -82,10 +82,7 @@ namespace chaiscript { try { std::vector::size_type i = 0; - (void)i; - (void)params; (void)t_conversions; - // this is ok because the order of evaluation of initializer lists is well defined - (void)std::initializer_list{(boxed_cast(params[i++], &t_conversions), 0)...}; + ( boxed_cast(params[i++], &t_conversions), ... ); return true; } catch (const exception::bad_boxed_cast &) { return false; @@ -111,23 +108,12 @@ namespace chaiscript Boxed_Value call_func(const chaiscript::dispatch::detail::Function_Signature &sig, const Callable &f, const std::vector ¶ms, const Type_Conversions_State &t_conversions) { - return Handle_Return::handle(call_func(sig, std::index_sequence_for{}, f, params, t_conversions)); - } - - template - Boxed_Value call_func(const chaiscript::dispatch::detail::Function_Signature &sig, const Callable &f, - const std::vector ¶ms, const Type_Conversions_State &t_conversions) - { - call_func(sig, std::index_sequence_for{}, f, params, t_conversions); -#ifdef CHAISCRIPT_MSVC -#pragma warning(push) -#pragma warning(disable : 4702) -#endif - // MSVC is reporting that this is unreachable code - and it's wrong. - return Handle_Return::handle(); -#ifdef CHAISCRIPT_MSVC -#pragma warning(pop) -#endif + if constexpr (std::is_same_v) { + call_func(sig, std::index_sequence_for{}, f, params, t_conversions); + return Handle_Return::handle(); + } else { + return Handle_Return::handle(call_func(sig, std::index_sequence_for{}, f, params, t_conversions)); + } } } diff --git a/include/chaiscript/language/chaiscript_eval.hpp b/include/chaiscript/language/chaiscript_eval.hpp index 23557ca1..1b05cac7 100644 --- a/include/chaiscript/language/chaiscript_eval.hpp +++ b/include/chaiscript/language/chaiscript_eval.hpp @@ -57,8 +57,9 @@ namespace chaiscript chaiscript::detail::Dispatch_State state(t_ss); const Boxed_Value *thisobj = [&]() -> const Boxed_Value *{ - auto &stack = t_ss.get_stack_data(state.stack_holder()).back(); - if (!stack.empty() && stack.back().first == "__this") { + if (auto &stack = t_ss.get_stack_data(state.stack_holder()).back(); + !stack.empty() && stack.back().first == "__this") + { return &stack.back().second; } else if (!t_vals.empty()) { return &t_vals[0]; @@ -71,8 +72,8 @@ namespace chaiscript if (thisobj && !has_this_capture) { state.add_object("this", *thisobj); } if (t_locals) { - for (const auto &local : *t_locals) { - state.add_object(local.first, local.second); + for (const auto &[name, value] : *t_locals) { + state.add_object(name, value); } } @@ -109,7 +110,7 @@ namespace chaiscript std::vector> get_children() const final { std::vector> retval; retval.reserve(children.size()); - for (auto &&child : children) { + for (auto &child : children) { retval.emplace_back(*child); } @@ -868,9 +869,9 @@ namespace chaiscript Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override{ const auto get_function = [&t_ss](const std::string &t_name, auto &t_hint){ uint_fast32_t hint = t_hint; - auto funs = t_ss->get_function(t_name, hint); - if (funs.first != hint) { t_hint = uint_fast32_t(funs.first); } - return std::move(funs.second); + auto [funs_loc, funs] = t_ss->get_function(t_name, hint); + if (funs_loc != hint) { t_hint = uint_fast32_t(funs_loc); } + return std::move(funs); }; const auto call_function = [&t_ss](const auto &t_funcs, const Boxed_Value &t_param) { @@ -1056,8 +1057,8 @@ namespace chaiscript if (!this->children.empty()) { vec.reserve(this->children[0]->children.size()); for (const auto &child : this->children[0]->children) { - auto obj = child->eval(t_ss); - if (!obj.is_return_value()) { + if (auto obj = child->eval(t_ss); + !obj.is_return_value()) { vec.push_back(t_ss->call_function("clone", m_loc, {obj}, t_ss.conversions())); } else { vec.push_back(std::move(obj)); From ac78e978fe0b4e7591080a189bf9664d8d6d91bc Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Sat, 26 Aug 2017 14:19:38 -0600 Subject: [PATCH 044/155] Move to template type deduction for function signature --- .../dispatchkit/callable_traits.hpp | 107 --------------- .../chaiscript/dispatchkit/function_call.hpp | 12 +- .../dispatchkit/function_signature.hpp | 124 ++++++++++++++++++ .../dispatchkit/proxy_constructors.hpp | 5 +- .../dispatchkit/proxy_functions.hpp | 4 +- .../dispatchkit/proxy_functions_detail.hpp | 5 +- .../dispatchkit/register_function.hpp | 123 +++++++---------- 7 files changed, 189 insertions(+), 191 deletions(-) delete mode 100644 include/chaiscript/dispatchkit/callable_traits.hpp create mode 100644 include/chaiscript/dispatchkit/function_signature.hpp diff --git a/include/chaiscript/dispatchkit/callable_traits.hpp b/include/chaiscript/dispatchkit/callable_traits.hpp deleted file mode 100644 index 0dc92416..00000000 --- a/include/chaiscript/dispatchkit/callable_traits.hpp +++ /dev/null @@ -1,107 +0,0 @@ -// This file is distributed under the BSD License. -// See "license.txt" for details. -// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) -// Copyright 2009-2017, Jason Turner (jason@emptycrate.com) -// http://www.chaiscript.com - -#ifndef CHAISCRIPT_CALLABLE_TRAITS_HPP_ -#define CHAISCRIPT_CALLABLE_TRAITS_HPP_ - -#include - -namespace chaiscript { - namespace dispatch { - namespace detail { - - template - struct Constructor - { - template - constexpr Class operator()(Inner&& ... inner) const { - return Class(std::forward(inner)...); - } - }; - - template - struct Const_Caller - { - constexpr explicit Const_Caller(Ret (Class::*t_func)(Param...) const) : m_func(t_func) {} - - template - constexpr Ret operator()(const Class &o, Inner&& ... inner) const { - return (o.*m_func)(std::forward(inner)...); - } - - Ret (Class::*m_func)(Param...) const; - }; - - template - struct Fun_Caller - { - constexpr explicit Fun_Caller(Ret( * t_func)(Param...) ) : m_func(t_func) {} - - template - constexpr Ret operator()(Inner&& ... inner) const { - return (m_func)(std::forward(inner)...); - } - - Ret(*m_func)(Param...); - }; - - template - struct Caller - { - constexpr explicit Caller(Ret (Class::*t_func)(Param...)) : m_func(t_func) {} - - template - constexpr Ret operator()(Class &o, Inner&& ... inner) const { - return (o.*m_func)(std::forward(inner)...); - } - - Ret (Class::*m_func)(Param...); - }; - - template - struct Arity - { - }; - - template - struct Arity - { - static const size_t arity = sizeof...(Params); - }; - - - template - struct Function_Signature - { - }; - - template - struct Function_Signature - { - typedef Ret Return_Type; - typedef Ret (Signature)(Params...); - }; - - template - struct Function_Signature - { - typedef Ret Return_Type; - typedef Ret (Signature)(Params...); - }; - - - template - struct Callable_Traits - { - typedef typename Function_Signature::Signature Signature; - typedef typename Function_Signature::Return_Type Return_Type; - }; - } - } -} - -#endif - diff --git a/include/chaiscript/dispatchkit/function_call.hpp b/include/chaiscript/dispatchkit/function_call.hpp index 1980f35c..796003bf 100644 --- a/include/chaiscript/dispatchkit/function_call.hpp +++ b/include/chaiscript/dispatchkit/function_call.hpp @@ -18,7 +18,6 @@ #include "boxed_cast.hpp" #include "function_call_detail.hpp" #include "proxy_functions.hpp" -#include "callable_traits.hpp" namespace chaiscript { class Boxed_Value; @@ -32,6 +31,15 @@ namespace chaiscript { namespace dispatch { + namespace detail + { + template + constexpr auto arity(Ret (*)(Param...)) noexcept + { + return sizeof...(Param); + } + } + /// Build a function caller that knows how to dispatch on a set of functions /// example: /// std::function f = @@ -43,7 +51,7 @@ namespace chaiscript { const bool has_arity_match = std::any_of(funcs.begin(), funcs.end(), [](const Const_Proxy_Function &f) { - return f->get_arity() == -1 || size_t(f->get_arity()) == chaiscript::dispatch::detail::Arity::arity; + return f->get_arity() == -1 || size_t(f->get_arity()) == detail::arity(static_cast(nullptr)); }); if (!has_arity_match) { diff --git a/include/chaiscript/dispatchkit/function_signature.hpp b/include/chaiscript/dispatchkit/function_signature.hpp new file mode 100644 index 00000000..11c780a4 --- /dev/null +++ b/include/chaiscript/dispatchkit/function_signature.hpp @@ -0,0 +1,124 @@ +#ifndef CHAISCRIPT_FUNCTION_SIGNATURE_HPP +#define CHAISCRIPT_FUNCTION_SIGNATURE_HPP + +#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; + }; + + // Free functions + + template + Function_Signature(Ret (*f)(Param...)) -> Function_Signature>; + + template + Function_Signature(Ret (*f)(Param...) noexcept) -> Function_Signature, true>; + + // no reference specifier + + template + Function_Signature(Ret (Class::*f)(Param ...) volatile) -> 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) -> 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 ...) ) -> Function_Signature, false, true>; + + template + Function_Signature(Ret (Class::*f)(Param ...) noexcept) -> Function_Signature, true, true>; + + template + Function_Signature(Ret (Class::*f)(Param ...) const) -> Function_Signature, false, true>; + + template + Function_Signature(Ret (Class::*f)(Param ...) const noexcept) -> Function_Signature, true, true>; + + // & reference specifier + + template + Function_Signature(Ret (Class::*f)(Param ...) volatile &) -> 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 &) -> 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 ...) & ) -> Function_Signature, false, true>; + + template + Function_Signature(Ret (Class::*f)(Param ...) & noexcept) -> Function_Signature, true, true>; + + template + Function_Signature(Ret (Class::*f)(Param ...) const &) -> Function_Signature, false, true>; + + template + Function_Signature(Ret (Class::*f)(Param ...) const & noexcept) -> Function_Signature, true, true>; + + // && reference specifier + + template + Function_Signature(Ret (Class::*f)(Param ...) volatile &&) -> 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 &&) -> 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 ...) &&) -> Function_Signature, false, true>; + + template + Function_Signature(Ret (Class::*f)(Param ...) && noexcept) -> Function_Signature, true, true>; + + template + Function_Signature(Ret (Class::*f)(Param ...) const &&) -> Function_Signature, false, true>; + + template + Function_Signature(Ret (Class::*f)(Param ...) const && noexcept) -> Function_Signature, true, true>; + + template + Function_Signature(Ret (Class::*f)) -> Function_Signature, true, 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 + >; +} + +#endif diff --git a/include/chaiscript/dispatchkit/proxy_constructors.hpp b/include/chaiscript/dispatchkit/proxy_constructors.hpp index 10b72cf5..3ccdcdf7 100644 --- a/include/chaiscript/dispatchkit/proxy_constructors.hpp +++ b/include/chaiscript/dispatchkit/proxy_constructors.hpp @@ -19,11 +19,12 @@ namespace chaiscript { namespace detail { - template Proxy_Function build_constructor_(Class (*)(Params...)) { - auto call = dispatch::detail::Constructor(); + auto call = [](auto && ... param){ + return Class(std::forward(param)...); + }; return Proxy_Function( chaiscript::make_shared>(call)); diff --git a/include/chaiscript/dispatchkit/proxy_functions.hpp b/include/chaiscript/dispatchkit/proxy_functions.hpp index 8fcffb28..b2383ce1 100644 --- a/include/chaiscript/dispatchkit/proxy_functions.hpp +++ b/include/chaiscript/dispatchkit/proxy_functions.hpp @@ -664,7 +664,7 @@ namespace chaiscript protected: Boxed_Value do_call(const std::vector ¶ms, const Type_Conversions_State &t_conversions) const override { - return detail::call_func(detail::Function_Signature(), m_f, params, t_conversions); + return detail::call_func(static_cast(nullptr), m_f, params, t_conversions); } private: @@ -716,7 +716,7 @@ namespace chaiscript protected: Boxed_Value do_call(const std::vector ¶ms, const Type_Conversions_State &t_conversions) const override { - return detail::call_func(detail::Function_Signature(), m_f.get(), params, t_conversions); + return detail::call_func(static_cast(nullptr), m_f.get(), params, t_conversions); } diff --git a/include/chaiscript/dispatchkit/proxy_functions_detail.hpp b/include/chaiscript/dispatchkit/proxy_functions_detail.hpp index 8db9b509..e24ebc92 100644 --- a/include/chaiscript/dispatchkit/proxy_functions_detail.hpp +++ b/include/chaiscript/dispatchkit/proxy_functions_detail.hpp @@ -21,7 +21,6 @@ #include "boxed_value.hpp" #include "handle_return.hpp" #include "type_info.hpp" -#include "callable_traits.hpp" namespace chaiscript { class Type_Conversions_State; @@ -91,7 +90,7 @@ namespace chaiscript template - Ret call_func(const chaiscript::dispatch::detail::Function_Signature &, + Ret call_func(Ret (*)(Params...), std::index_sequence, const Callable &f, const std::vector ¶ms, const Type_Conversions_State &t_conversions) { @@ -105,7 +104,7 @@ namespace chaiscript /// if any unboxing fails the execution of the function fails and /// the bad_boxed_cast is passed up to the caller. template - Boxed_Value call_func(const chaiscript::dispatch::detail::Function_Signature &sig, const Callable &f, + Boxed_Value call_func(Ret (*sig)(Params...), const Callable &f, const std::vector ¶ms, const Type_Conversions_State &t_conversions) { if constexpr (std::is_same_v) { diff --git a/include/chaiscript/dispatchkit/register_function.hpp b/include/chaiscript/dispatchkit/register_function.hpp index e660790d..07445375 100644 --- a/include/chaiscript/dispatchkit/register_function.hpp +++ b/include/chaiscript/dispatchkit/register_function.hpp @@ -15,9 +15,54 @@ #include "bind_first.hpp" #include "proxy_functions.hpp" +#include "function_signature.hpp" namespace chaiscript { + namespace dispatch::detail + { + template + Param1 get_first_param(Function_Params, Obj &&obj) + { + return static_cast(std::forward(obj)); + } + + template + auto make_callable_impl(Func &&func, Function_Signature, Is_Noexcept, Is_Member, Is_MemberObject, Is_Object>) + { + if constexpr (Is_MemberObject) { + // 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) { + return (( get_first_param(Function_Params{}, obj).*func )(std::forward(param)...)); + }; + return Proxy_Function( + chaiscript::make_shared>(std::move(call)) + ); + } else { + return Proxy_Function( + chaiscript::make_shared>>(std::forward(func)) + ); + } + } + + // this version peels off the function object itself from the function signature, when used + // on a callable object + template + auto make_callable(Func &&func, Function_Signature, Is_Noexcept, false, false, true>) + { + return make_callable_impl(std::forward(func), Function_Signature, Is_Noexcept, false, false, true>{}); + } + + template + auto make_callable(Func &&func, Function_Signature, Is_Noexcept, Is_Member, Is_MemberObject, false> fs) + { + return make_callable_impl(std::forward(func), fs); + } + } /// \brief Creates a new Proxy_Function object from a free function, member function or data member /// \param[in] t Function / member to expose @@ -40,85 +85,12 @@ namespace chaiscript /// /// \sa \ref adding_functions template - Proxy_Function fun(const T &t) + Proxy_Function fun(T &&t) { - typedef typename dispatch::detail::Callable_Traits::Signature Signature; - - return Proxy_Function( - chaiscript::make_shared>(t)); + return dispatch::detail::make_callable(std::forward(t), dispatch::detail::Function_Signature{t}); } - template - Proxy_Function fun(Ret (*func)(Param...)) - { - auto fun_call = dispatch::detail::Fun_Caller(func); - - return Proxy_Function( - chaiscript::make_shared>(fun_call)); - - } - - template - Proxy_Function fun(Ret (Class::*t_func)(Param...) const) - { - auto call = dispatch::detail::Const_Caller(t_func); - - return Proxy_Function( - chaiscript::make_shared>(call)); - } - - template - Proxy_Function fun(Ret (Class::*t_func)(Param...)) - { - auto call = dispatch::detail::Caller(t_func); - - return Proxy_Function( - chaiscript::make_shared>(call)); - - } - - template::value>::type*/> - Proxy_Function fun(T Class::* m /*, typename std::enable_if::value>::type* = 0*/ ) - { - return Proxy_Function(chaiscript::make_shared>(m)); - } - -// only compile this bit if noexcept is part of the type system -// -#if __cpp_noexcept_function_type >= 201510 - template - Proxy_Function fun(Ret (*func)(Param...) noexcept) - { - auto fun_call = dispatch::detail::Fun_Caller(func); - - return Proxy_Function( - chaiscript::make_shared>(fun_call)); - - } - - template - Proxy_Function fun(Ret (Class::*t_func)(Param...) const noexcept) - { - auto call = dispatch::detail::Const_Caller(t_func); - - return Proxy_Function( - chaiscript::make_shared>(call)); - } - - template - Proxy_Function fun(Ret (Class::*t_func)(Param...) noexcept) - { - auto call = dispatch::detail::Caller(t_func); - - return Proxy_Function( - chaiscript::make_shared>(call)); - - } -#endif - - - /// \brief Creates a new Proxy_Function object from a free function, member function or data member and binds the first parameter of it /// \param[in] t Function / member to expose @@ -145,6 +117,7 @@ namespace chaiscript } + } From 4213f24761dc4788bd17cc1aabad53224eed94e2 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Tue, 29 Aug 2017 16:14:44 -0600 Subject: [PATCH 045/155] Various C++17 considerations --- include/chaiscript/chaiscript_threading.hpp | 5 +-- include/chaiscript/dispatchkit/any.hpp | 16 +++------- .../chaiscript/dispatchkit/dispatchkit.hpp | 31 +++++++------------ .../dispatchkit/exception_specification.hpp | 2 +- .../dispatchkit/proxy_functions_detail.hpp | 4 +-- .../chaiscript/language/chaiscript_engine.hpp | 1 - .../language/chaiscript_optimizer.hpp | 2 +- .../chaiscript/language/chaiscript_tracer.hpp | 2 +- 8 files changed, 24 insertions(+), 39 deletions(-) diff --git a/include/chaiscript/chaiscript_threading.hpp b/include/chaiscript/chaiscript_threading.hpp index ce63df63..00db825e 100644 --- a/include/chaiscript/chaiscript_threading.hpp +++ b/include/chaiscript/chaiscript_threading.hpp @@ -17,6 +17,7 @@ #ifndef CHAISCRIPT_NO_THREADS #include #include +#include #else #ifndef CHAISCRIPT_NO_THREADS_WARNING #pragma message ("ChaiScript is compiling without thread safety.") @@ -49,13 +50,13 @@ namespace chaiscript using unique_lock = std::unique_lock; template - using shared_lock = std::unique_lock; + using shared_lock = std::shared_lock; template using lock_guard = std::lock_guard; - using shared_mutex = std::mutex; + using std::shared_mutex; using std::mutex; diff --git a/include/chaiscript/dispatchkit/any.hpp b/include/chaiscript/dispatchkit/any.hpp index 32ccdf89..823679eb 100644 --- a/include/chaiscript/dispatchkit/any.hpp +++ b/include/chaiscript/dispatchkit/any.hpp @@ -86,21 +86,15 @@ namespace chaiscript { Any(Any &&) = default; Any &operator=(Any &&t_any) = default; - Any(const Any &t_any) - { - if (!t_any.empty()) - { - m_data = t_any.m_data->clone(); - } else { - m_data.reset(); - } + Any(const Any &t_any) + : m_data(t_any.empty() ? nullptr : t_any.m_data->clone()) + { } - template::type>::value>::type> + typename = std::enable_if_t>>> explicit Any(ValueType &&t_value) - : m_data(std::unique_ptr(new Data_Impl::type>(std::forward(t_value)))) + : m_data(std::unique_ptr(new Data_Impl>(std::forward(t_value)))) { } diff --git a/include/chaiscript/dispatchkit/dispatchkit.hpp b/include/chaiscript/dispatchkit/dispatchkit.hpp index 6ff2accb..5b25127b 100644 --- a/include/chaiscript/dispatchkit/dispatchkit.hpp +++ b/include/chaiscript/dispatchkit/dispatchkit.hpp @@ -1049,7 +1049,7 @@ namespace chaiscript if (!functions.empty()) { try { if (is_no_param) { - std::vector tmp_params(params); + auto tmp_params(params); tmp_params.insert(tmp_params.begin() + 1, var(t_name)); return do_attribute_call(2, tmp_params, functions, t_conversions); } else { @@ -1080,10 +1080,9 @@ namespace chaiscript const Type_Conversions_State &t_conversions) const { uint_fast32_t loc = t_loc; - const auto funs = get_function(t_name, loc); - if (funs.first != loc) { t_loc = uint_fast32_t(funs.first); -} - return dispatch::dispatch(*funs.second, params, t_conversions); + const auto [func_loc, func] = get_function(t_name, loc); + if (func_loc != loc) { t_loc = uint_fast32_t(func_loc); } + return dispatch::dispatch(*func, params, t_conversions); } @@ -1102,12 +1101,12 @@ namespace chaiscript /// Dump function to stdout void dump_function(const std::pair &f) const { - std::vector params = f.second->get_param_types(); + const auto params = f.second->get_param_types(); dump_type(params.front()); std::cout << " " << f.first << "("; - for (std::vector::const_iterator itr = params.begin() + 1; + for (auto itr = params.begin() + 1; itr != params.end(); ) { @@ -1132,7 +1131,7 @@ namespace chaiscript throw chaiscript::exception::arity_error(static_cast(params.size()), 1); } - const Const_Proxy_Function &f = this->boxed_cast(params[0]); + const auto &f = this->boxed_cast(params[0]); const Type_Conversions_State convs(m_conversions, m_conversions.conversion_saves()); return const_var(f->call_match(std::vector(params.begin() + 1, params.end()), convs)); @@ -1142,25 +1141,17 @@ namespace chaiscript void dump_system() const { std::cout << "Registered Types: \n"; - std::vector > types = get_types(); - for (std::vector >::const_iterator itr = types.begin(); - itr != types.end(); - ++itr) + for (const auto &[type_name, type] : get_types() ) { - std::cout << itr->first << ": "; - std::cout << itr->second.bare_name(); - std::cout << '\n'; + std::cout << type_name << ": " << type.bare_name() << '\n'; } std::cout << '\n'; - std::vector > funcs = get_functions(); std::cout << "Functions: \n"; - for (std::vector >::const_iterator itr = funcs.begin(); - itr != funcs.end(); - ++itr) + for (const auto &func : get_functions()) { - dump_function(*itr); + dump_function(func); } std::cout << '\n'; } diff --git a/include/chaiscript/dispatchkit/exception_specification.hpp b/include/chaiscript/dispatchkit/exception_specification.hpp index 79607fe2..0eeecdc4 100644 --- a/include/chaiscript/dispatchkit/exception_specification.hpp +++ b/include/chaiscript/dispatchkit/exception_specification.hpp @@ -46,7 +46,7 @@ namespace chaiscript { void handle(const Boxed_Value &bv, const Dispatch_Engine &t_engine) override { - (void)std::initializer_list{(throw_type(bv, t_engine), 0)...}; + (throw_type(bv, t_engine), ...); } }; } diff --git a/include/chaiscript/dispatchkit/proxy_functions_detail.hpp b/include/chaiscript/dispatchkit/proxy_functions_detail.hpp index e24ebc92..ed71663f 100644 --- a/include/chaiscript/dispatchkit/proxy_functions_detail.hpp +++ b/include/chaiscript/dispatchkit/proxy_functions_detail.hpp @@ -92,9 +92,9 @@ namespace chaiscript template Ret call_func(Ret (*)(Params...), std::index_sequence, const Callable &f, - const std::vector ¶ms, const Type_Conversions_State &t_conversions) + [[maybe_unused]] const std::vector ¶ms, + [[maybe_unused]] const Type_Conversions_State &t_conversions) { - (void)params; (void)t_conversions; return f(boxed_cast(params[I], &t_conversions)...); } diff --git a/include/chaiscript/language/chaiscript_engine.hpp b/include/chaiscript/language/chaiscript_engine.hpp index 11506f58..cfdffc0e 100644 --- a/include/chaiscript/language/chaiscript_engine.hpp +++ b/include/chaiscript/language/chaiscript_engine.hpp @@ -557,7 +557,6 @@ explicit ChaiScript_Basic(std::unique_ptr &&pars std::string load_module(const std::string &t_module_name) { #ifdef CHAISCRIPT_NO_DYNLOAD - (void)t_module_name; // -Wunused-parameter throw chaiscript::exception::load_module_error("Loadable module support was disabled (CHAISCRIPT_NO_DYNLOAD)"); #else std::vector errors; diff --git a/include/chaiscript/language/chaiscript_optimizer.hpp b/include/chaiscript/language/chaiscript_optimizer.hpp index 3df867f1..74fa3803 100644 --- a/include/chaiscript/language/chaiscript_optimizer.hpp +++ b/include/chaiscript/language/chaiscript_optimizer.hpp @@ -24,7 +24,7 @@ namespace chaiscript { template auto optimize(eval::AST_Node_Impl_Ptr p) { - (void)std::initializer_list{ (p = static_cast(*this).optimize(std::move(p)), 0)... }; + ( (p = static_cast(*this).optimize(std::move(p))), ... ); return p; } }; diff --git a/include/chaiscript/language/chaiscript_tracer.hpp b/include/chaiscript/language/chaiscript_tracer.hpp index 3774826b..a60db66d 100644 --- a/include/chaiscript/language/chaiscript_tracer.hpp +++ b/include/chaiscript/language/chaiscript_tracer.hpp @@ -29,7 +29,7 @@ namespace chaiscript { } void do_trace(const chaiscript::detail::Dispatch_State &ds, const AST_Node_Impl> *node) { - (void)std::initializer_list{ (static_cast(*this).trace(ds, node), 0)... }; + (static_cast(*this).trace(ds, node), ... ); } static void trace(const chaiscript::detail::Dispatch_State &ds, const AST_Node_Impl> *node) { From 17384763216a067dcc979c221bee8f9e0b0ecfa4 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Wed, 30 Aug 2017 08:41:08 -0600 Subject: [PATCH 046/155] Make comparison constexpr --- include/chaiscript/chaiscript_defines.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/chaiscript/chaiscript_defines.hpp b/include/chaiscript/chaiscript_defines.hpp index ef937620..9754913f 100644 --- a/include/chaiscript/chaiscript_defines.hpp +++ b/include/chaiscript/chaiscript_defines.hpp @@ -215,7 +215,7 @@ namespace chaiscript { return t_lhs < t_rhs; } template - bool operator()(const LHS &t_lhs, const RHS &t_rhs) const noexcept { + constexpr bool operator()(const LHS &t_lhs, const RHS &t_rhs) const noexcept { return std::lexicographical_compare(t_lhs.begin(), t_lhs.end(), t_rhs.begin(), t_rhs.end()); } struct is_transparent{}; From bfe7799d13b177809bb0e0eb02243d59b7bfe4ca Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Sat, 2 Sep 2017 13:12:52 -0600 Subject: [PATCH 047/155] Come C++17 updates, namespaces, etc --- include/chaiscript/dispatchkit/any.hpp | 4 ++-- include/chaiscript/language/chaiscript_common.hpp | 5 ++--- include/chaiscript/language/chaiscript_engine.hpp | 12 ++++++------ include/chaiscript/language/chaiscript_eval.hpp | 6 ++---- 4 files changed, 12 insertions(+), 15 deletions(-) diff --git a/include/chaiscript/dispatchkit/any.hpp b/include/chaiscript/dispatchkit/any.hpp index 823679eb..d13b653f 100644 --- a/include/chaiscript/dispatchkit/any.hpp +++ b/include/chaiscript/dispatchkit/any.hpp @@ -70,7 +70,7 @@ namespace chaiscript { std::unique_ptr clone() const override { - return std::unique_ptr(new Data_Impl(m_data)); + return std::make_unique>(m_data); } Data_Impl &operator=(const Data_Impl&) = delete; @@ -94,7 +94,7 @@ namespace chaiscript { template>>> explicit Any(ValueType &&t_value) - : m_data(std::unique_ptr(new Data_Impl>(std::forward(t_value)))) + : m_data(std::make_unique>>(std::forward(t_value))) { } diff --git a/include/chaiscript/language/chaiscript_common.hpp b/include/chaiscript/language/chaiscript_common.hpp index 837ebeea..dbbfc744 100644 --- a/include/chaiscript/language/chaiscript_common.hpp +++ b/include/chaiscript/language/chaiscript_common.hpp @@ -674,19 +674,18 @@ namespace chaiscript struct Return_Value { Boxed_Value retval; - explicit Return_Value(Boxed_Value t_return_value) : retval(std::move(t_return_value)) { } + + explicit Return_Value(Boxed_Value &&t_return_value) : retval(std::move(t_return_value)) { } }; /// Special type indicating a call to 'break' struct Break_Loop { - Break_Loop() = default; }; /// Special type indicating a call to 'continue' struct Continue_Loop { - Continue_Loop() = default; }; diff --git a/include/chaiscript/language/chaiscript_engine.hpp b/include/chaiscript/language/chaiscript_engine.hpp index cfdffc0e..47cf43a3 100644 --- a/include/chaiscript/language/chaiscript_engine.hpp +++ b/include/chaiscript/language/chaiscript_engine.hpp @@ -94,7 +94,7 @@ namespace chaiscript /// Evaluates the given file and looks in the 'use' paths - const Boxed_Value internal_eval_file(const std::string &t_filename) { + Boxed_Value internal_eval_file(const std::string &t_filename) { for (const auto &path : m_use_paths) { try { @@ -115,7 +115,7 @@ namespace chaiscript /// Evaluates the given string, used during eval() inside of a script - const Boxed_Value internal_eval(const std::string &t_e) { + Boxed_Value internal_eval(const std::string &t_e) { try { return do_eval(t_e, "__EVAL__", true); } catch (const exception::eval_error &t_ee) { @@ -310,10 +310,10 @@ namespace chaiscript } } #else // CHAISCRIPT_NO_DYNLOAD -explicit ChaiScript_Basic(std::unique_ptr &&parser, - std::vector t_module_paths = {}, - std::vector t_use_paths = {}, - const std::vector &t_opts = chaiscript::default_options()) = delete; + explicit ChaiScript_Basic(std::unique_ptr &&parser, + std::vector t_module_paths = {}, + std::vector t_use_paths = {}, + const std::vector &t_opts = chaiscript::default_options()) = delete; #endif parser::ChaiScript_Parser_Base &get_parser() noexcept diff --git a/include/chaiscript/language/chaiscript_eval.hpp b/include/chaiscript/language/chaiscript_eval.hpp index 1b05cac7..42c18790 100644 --- a/include/chaiscript/language/chaiscript_eval.hpp +++ b/include/chaiscript/language/chaiscript_eval.hpp @@ -34,11 +34,9 @@ #include "chaiscript_algebraic.hpp" #include "chaiscript_common.hpp" -namespace chaiscript { -namespace exception { +namespace chaiscript::exception { class bad_boxed_cast; -} // namespace exception -} // namespace chaiscript +} // namespace chaiscript::exception namespace chaiscript { From f338586d3719cef44b02d1a0780e41ff30f2dc60 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Sat, 2 Sep 2017 19:06:46 -0600 Subject: [PATCH 048/155] Performance improvements and LOC reduction in BoxedNumber --- .../chaiscript/dispatchkit/boxed_number.hpp | 288 +++++++----------- 1 file changed, 111 insertions(+), 177 deletions(-) diff --git a/include/chaiscript/dispatchkit/boxed_number.hpp b/include/chaiscript/dispatchkit/boxed_number.hpp index 8bb39142..2817ff1a 100644 --- a/include/chaiscript/dispatchkit/boxed_number.hpp +++ b/include/chaiscript/dispatchkit/boxed_number.hpp @@ -109,49 +109,49 @@ namespace chaiscript { const Type_Info &inp_ = t_bv.get_type_info(); - if (inp_ == typeid(int)) { + if (inp_ == user_type()) { return get_common_type(sizeof(int), true); - } else if (inp_ == typeid(double)) { + } else if (inp_ == user_type()) { return Common_Types::t_double; - } else if (inp_ == typeid(long double)) { + } else if (inp_ == user_type()) { return Common_Types::t_long_double; - } else if (inp_ == typeid(float)) { + } else if (inp_ == user_type()) { return Common_Types::t_float; - } else if (inp_ == typeid(char)) { + } else if (inp_ == user_type()) { return get_common_type(sizeof(char), std::is_signed::value); - } else if (inp_ == typeid(unsigned char)) { + } else if (inp_ == user_type()) { return get_common_type(sizeof(unsigned char), false); - } else if (inp_ == typeid(unsigned int)) { + } else if (inp_ == user_type()) { return get_common_type(sizeof(unsigned int), false); - } else if (inp_ == typeid(long)) { + } else if (inp_ == user_type()) { return get_common_type(sizeof(long), true); - } else if (inp_ == typeid(long long)) { + } else if (inp_ == user_type()) { return get_common_type(sizeof(long long), true); - } else if (inp_ == typeid(unsigned long)) { + } else if (inp_ == user_type()) { return get_common_type(sizeof(unsigned long), false); - } else if (inp_ == typeid(unsigned long long)) { + } else if (inp_ == user_type()) { return get_common_type(sizeof(unsigned long long), false); - } else if (inp_ == typeid(std::int8_t)) { + } else if (inp_ == user_type()) { return Common_Types::t_int8; - } else if (inp_ == typeid(std::int16_t)) { + } else if (inp_ == user_type()) { return Common_Types::t_int16; - } else if (inp_ == typeid(std::int32_t)) { + } else if (inp_ == user_type()) { return Common_Types::t_int32; - } else if (inp_ == typeid(std::int64_t)) { + } else if (inp_ == user_type()) { return Common_Types::t_int64; - } else if (inp_ == typeid(std::uint8_t)) { + } else if (inp_ == user_type()) { return Common_Types::t_uint8; - } else if (inp_ == typeid(std::uint16_t)) { + } else if (inp_ == user_type()) { return Common_Types::t_uint16; - } else if (inp_ == typeid(std::uint32_t)) { + } else if (inp_ == user_type()) { return Common_Types::t_uint32; - } else if (inp_ == typeid(std::uint64_t)) { + } else if (inp_ == user_type()) { return Common_Types::t_uint64; - } else if (inp_ == typeid(wchar_t)) { + } else if (inp_ == user_type()) { return get_common_type(sizeof(wchar_t), std::is_signed::value); - } else if (inp_ == typeid(char16_t)) { + } else if (inp_ == user_type()) { return get_common_type(sizeof(char16_t), std::is_signed::value); - } else if (inp_ == typeid(char32_t)) { + } else if (inp_ == user_type()) { return get_common_type(sizeof(char32_t), std::is_signed::value); } else { throw chaiscript::detail::exception::bad_any_cast(); @@ -160,8 +160,8 @@ namespace chaiscript - template - static auto go(Operators::Opers t_oper, const Boxed_Value &t_bv, LHS *t_lhs, const T &c_lhs, const T &c_rhs) + template + static auto go(Operators::Opers t_oper, const Boxed_Value &t_bv, LHS *t_lhs, const LHS &c_lhs, const RHS &c_rhs) { switch (t_oper) { case Operators::Opers::equals: @@ -188,7 +188,7 @@ namespace chaiscript } - if constexpr (!std::is_floating_point::value) { + if constexpr (!std::is_floating_point::value && !std::is_floating_point::value) { switch (t_oper) { case Operators::Opers::shift_left: return const_var(c_lhs << c_rhs); @@ -226,7 +226,7 @@ namespace chaiscript return t_bv; } - if constexpr (!std::is_floating_point::value) { + if constexpr (!std::is_floating_point::value && !std::is_floating_point::value) { switch (t_oper) { case Operators::Opers::assign_bitwise_and: check_divide_by_zero(c_rhs); @@ -254,155 +254,89 @@ namespace chaiscript throw chaiscript::detail::exception::bad_any_cast(); } - template - static auto go(Operators::Opers t_oper, const Boxed_Value &t_lhs, const Boxed_Value &t_rhs) - { - using common_type = typename std::common_type::type; - - auto *lhs = [&]() -> LHS *{ - if (!t_lhs.is_const() && !t_lhs.is_return_value()) { - return static_cast(t_lhs.get_ptr()); - } else { - return nullptr; - } - }(); - - return go(t_oper, t_lhs, lhs, get_as_aux(t_lhs), get_as_aux(t_rhs)); - } - - // Unary - template - static auto go(Operators::Opers t_oper, const Boxed_Value &t_lhs) - { - auto *lhs = [&]() -> LHS *{ - if (!t_lhs.is_const() && !t_lhs.is_return_value()) { - return static_cast(t_lhs.get_ptr()); - } else { - return nullptr; - } - }(); - - const LHS &c_lhs = (*static_cast(t_lhs.get_const_ptr())); - - if (lhs) { - switch (t_oper) { - case Operators::Opers::pre_increment: - ++(*lhs); - return t_lhs; - case Operators::Opers::pre_decrement: - --(*lhs); - return t_lhs; - } - } - - switch (t_oper) { - case Operators::Opers::unary_minus: - return const_var(-c_lhs); - case Operators::Opers::unary_plus: - return const_var(+c_lhs); - } - - if constexpr (!std::is_floating_point::value) { - switch (t_oper) { - case Operators::Opers::bitwise_complement: - return const_var(~c_lhs); - } - } - - throw chaiscript::detail::exception::bad_any_cast(); - } - - - template - inline static Boxed_Value oper_rhs(Operators::Opers t_oper, const Boxed_Value &t_lhs, const Boxed_Value &t_rhs) + template + inline static auto visit(const Boxed_Value &bv, Callable &&callable) { - switch (get_common_type(t_rhs)) { + switch (get_common_type(bv)) { case Common_Types::t_int32: - return go(t_oper, t_lhs, t_rhs); + return callable(*static_cast(bv.get_const_ptr())); case Common_Types::t_uint8: - return go(t_oper, t_lhs, t_rhs); + return callable(*static_cast(bv.get_const_ptr())); case Common_Types::t_int8: - return go(t_oper, t_lhs, t_rhs); + return callable(*static_cast(bv.get_const_ptr())); case Common_Types::t_uint16: - return go(t_oper, t_lhs, t_rhs); + return callable(*static_cast(bv.get_const_ptr())); case Common_Types::t_int16: - return go(t_oper, t_lhs, t_rhs); + return callable(*static_cast(bv.get_const_ptr())); case Common_Types::t_uint32: - return go(t_oper, t_lhs, t_rhs); + return callable(*static_cast(bv.get_const_ptr())); case Common_Types::t_uint64: - return go(t_oper, t_lhs, t_rhs); + return callable(*static_cast(bv.get_const_ptr())); case Common_Types::t_int64: - return go(t_oper, t_lhs, t_rhs); + return callable(*static_cast(bv.get_const_ptr())); case Common_Types::t_double: - return go(t_oper, t_lhs, t_rhs); + return callable(*static_cast(bv.get_const_ptr())); case Common_Types::t_float: - return go(t_oper, t_lhs, t_rhs); + return callable(*static_cast(bv.get_const_ptr())); case Common_Types::t_long_double: - return go(t_oper, t_lhs, t_rhs); - } + return callable(*static_cast(bv.get_const_ptr())); + default: + throw chaiscript::detail::exception::bad_any_cast(); - throw chaiscript::detail::exception::bad_any_cast(); + } } inline static Boxed_Value oper(Operators::Opers t_oper, const Boxed_Value &t_lhs) { - switch (get_common_type(t_lhs)) { - case Common_Types::t_int32: - return go(t_oper, t_lhs); - case Common_Types::t_uint8: - return go(t_oper, t_lhs); - case Common_Types::t_int8: - return go(t_oper, t_lhs); - case Common_Types::t_uint16: - return go(t_oper, t_lhs); - case Common_Types::t_int16: - return go(t_oper, t_lhs); - case Common_Types::t_uint32: - return go(t_oper, t_lhs); - case Common_Types::t_uint64: - return go(t_oper, t_lhs); - case Common_Types::t_int64: - return go(t_oper, t_lhs); - case Common_Types::t_double: - return go(t_oper, t_lhs); - case Common_Types::t_float: - return go(t_oper, t_lhs); - case Common_Types::t_long_double: - return go(t_oper, t_lhs); - } + auto unary_operator = [t_oper, &t_lhs](const auto &c_lhs){ + auto *lhs = static_cast *>(t_lhs.get_ptr()); - throw chaiscript::detail::exception::bad_any_cast(); + if (lhs) { + switch (t_oper) { + case Operators::Opers::pre_increment: + ++(*lhs); + return t_lhs; + case Operators::Opers::pre_decrement: + --(*lhs); + return t_lhs; + } + } + + switch (t_oper) { + case Operators::Opers::unary_minus: + return const_var(-c_lhs); + case Operators::Opers::unary_plus: + return const_var(+c_lhs); + } + + if constexpr (!std::is_floating_point_v>) { + switch (t_oper) { + case Operators::Opers::bitwise_complement: + return const_var(~c_lhs); + } + } + + throw chaiscript::detail::exception::bad_any_cast(); + }; + + return visit(t_lhs, unary_operator); } inline static Boxed_Value oper(Operators::Opers t_oper, const Boxed_Value &t_lhs, const Boxed_Value &t_rhs) { - switch (get_common_type(t_lhs)) { - case Common_Types::t_int32: - return oper_rhs(t_oper, t_lhs, t_rhs); - case Common_Types::t_uint8: - return oper_rhs(t_oper, t_lhs, t_rhs); - case Common_Types::t_int8: - return oper_rhs(t_oper, t_lhs, t_rhs); - case Common_Types::t_uint16: - return oper_rhs(t_oper, t_lhs, t_rhs); - case Common_Types::t_int16: - return oper_rhs(t_oper, t_lhs, t_rhs); - case Common_Types::t_uint32: - return oper_rhs(t_oper, t_lhs, t_rhs); - case Common_Types::t_uint64: - return oper_rhs(t_oper, t_lhs, t_rhs); - case Common_Types::t_int64: - return oper_rhs(t_oper, t_lhs, t_rhs); - case Common_Types::t_double: - return oper_rhs(t_oper, t_lhs, t_rhs); - case Common_Types::t_float: - return oper_rhs(t_oper, t_lhs, t_rhs); - case Common_Types::t_long_double: - return oper_rhs(t_oper, t_lhs, t_rhs); - } - throw chaiscript::detail::exception::bad_any_cast(); + auto lhs_visit = [t_oper, &t_lhs, &t_rhs](const auto &c_lhs){ + auto *lhs = static_cast *>(t_lhs.get_ptr()); + + auto rhs_visit = [t_oper, &t_lhs, lhs, &c_lhs](const auto &c_rhs) { + return go(t_oper, t_lhs, lhs, c_lhs, c_rhs); + }; + + return visit(t_rhs, rhs_visit); + }; + + return visit(t_lhs, lhs_visit); } template @@ -445,11 +379,11 @@ namespace chaiscript { const Type_Info &inp_ = t_bv.get_type_info(); - if (inp_ == typeid(double)) { + if (inp_ == user_type()) { return true; - } else if (inp_ == typeid(long double)) { + } else if (inp_ == user_type()) { return true; - } else if (inp_ == typeid(float)) { + } else if (inp_ == user_type()) { return true; } else { return false; @@ -458,49 +392,49 @@ namespace chaiscript Boxed_Number get_as(const Type_Info &inp_) const { - if (inp_.bare_equal_type_info(typeid(int))) { + if (inp_.bare_equal(user_type())) { return Boxed_Number(get_as()); - } else if (inp_.bare_equal_type_info(typeid(double))) { + } else if (inp_.bare_equal(user_type())) { return Boxed_Number(get_as()); - } else if (inp_.bare_equal_type_info(typeid(float))) { + } else if (inp_.bare_equal(user_type())) { return Boxed_Number(get_as()); - } else if (inp_.bare_equal_type_info(typeid(long double))) { + } else if (inp_.bare_equal(user_type())) { return Boxed_Number(get_as()); - } else if (inp_.bare_equal_type_info(typeid(char))) { + } else if (inp_.bare_equal(user_type())) { return Boxed_Number(get_as()); - } else if (inp_.bare_equal_type_info(typeid(unsigned char))) { + } else if (inp_.bare_equal(user_type())) { return Boxed_Number(get_as()); - } else if (inp_.bare_equal_type_info(typeid(wchar_t))) { + } else if (inp_.bare_equal(user_type())) { return Boxed_Number(get_as()); - } else if (inp_.bare_equal_type_info(typeid(char16_t))) { + } else if (inp_.bare_equal(user_type())) { return Boxed_Number(get_as()); - } else if (inp_.bare_equal_type_info(typeid(char32_t))) { + } else if (inp_.bare_equal(user_type())) { return Boxed_Number(get_as()); - } else if (inp_.bare_equal_type_info(typeid(unsigned int))) { + } else if (inp_.bare_equal(user_type())) { return Boxed_Number(get_as()); - } else if (inp_.bare_equal_type_info(typeid(long))) { + } else if (inp_.bare_equal(user_type())) { return Boxed_Number(get_as()); - } else if (inp_.bare_equal_type_info(typeid(long long))) { + } else if (inp_.bare_equal(user_type())) { return Boxed_Number(get_as()); - } else if (inp_.bare_equal_type_info(typeid(unsigned long))) { + } else if (inp_.bare_equal(user_type())) { return Boxed_Number(get_as()); - } else if (inp_.bare_equal_type_info(typeid(unsigned long long))) { + } else if (inp_.bare_equal(user_type())) { return Boxed_Number(get_as()); - } else if (inp_.bare_equal_type_info(typeid(int8_t))) { + } else if (inp_.bare_equal(user_type())) { return Boxed_Number(get_as()); - } else if (inp_.bare_equal_type_info(typeid(int16_t))) { + } else if (inp_.bare_equal(user_type())) { return Boxed_Number(get_as()); - } else if (inp_.bare_equal_type_info(typeid(int32_t))) { + } else if (inp_.bare_equal(user_type())) { return Boxed_Number(get_as()); - } else if (inp_.bare_equal_type_info(typeid(int64_t))) { + } else if (inp_.bare_equal(user_type())) { return Boxed_Number(get_as()); - } else if (inp_.bare_equal_type_info(typeid(uint8_t))) { + } else if (inp_.bare_equal(user_type())) { return Boxed_Number(get_as()); - } else if (inp_.bare_equal_type_info(typeid(uint16_t))) { + } else if (inp_.bare_equal(user_type())) { return Boxed_Number(get_as()); - } else if (inp_.bare_equal_type_info(typeid(uint32_t))) { + } else if (inp_.bare_equal(user_type())) { return Boxed_Number(get_as()); - } else if (inp_.bare_equal_type_info(typeid(uint64_t))) { + } else if (inp_.bare_equal(user_type())) { return Boxed_Number(get_as()); } else { throw chaiscript::detail::exception::bad_any_cast(); @@ -632,7 +566,7 @@ namespace chaiscript static void validate_boxed_number(const Boxed_Value &v) { const Type_Info &inp_ = v.get_type_info(); - if (inp_ == typeid(bool)) + if (inp_ == user_type()) { throw chaiscript::detail::exception::bad_any_cast(); } From e38b05ff9ac969dcd96214fd7b662f88a853f17b Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Sun, 10 Sep 2017 07:12:33 -0600 Subject: [PATCH 049/155] Better constexpr for comment types --- .../chaiscript/language/chaiscript_parser.hpp | 48 +++++-------------- 1 file changed, 12 insertions(+), 36 deletions(-) diff --git a/include/chaiscript/language/chaiscript_parser.hpp b/include/chaiscript/language/chaiscript_parser.hpp index 71112298..0cfe4223 100644 --- a/include/chaiscript/language/chaiscript_parser.hpp +++ b/include/chaiscript/language/chaiscript_parser.hpp @@ -281,35 +281,11 @@ namespace chaiscript return operators; } - constexpr static utility::Static_String multiline_comment_end() noexcept - { - constexpr utility::Static_String s("*/"); - return s; - } - - constexpr static utility::Static_String multiline_comment_begin() noexcept - { - constexpr utility::Static_String s("/*"); - return s; - } - - constexpr static utility::Static_String singleline_comment() noexcept - { - constexpr utility::Static_String s("//"); - return s; - } - - constexpr static utility::Static_String annotation() noexcept - { - constexpr utility::Static_String s("#"); - return s; - } - - constexpr static utility::Static_String cr_lf() noexcept - { - constexpr utility::Static_String s("\r\n"); - return s; - } + constexpr static utility::Static_String m_multiline_comment_end{"*/"}; + constexpr static utility::Static_String m_multiline_comment_begin{"/*"}; + constexpr static utility::Static_String m_singleline_comment{"//"}; + constexpr static utility::Static_String m_annotation{"#"}; + constexpr static utility::Static_String m_cr_lf{"\r\n"}; std::shared_ptr m_filename; @@ -532,18 +508,18 @@ namespace chaiscript /// Skips any multi-line or single-line comment bool SkipComment() { - if (Symbol_(multiline_comment_begin())) { + if (Symbol_(m_multiline_comment_begin)) { while (m_position.has_more()) { - if (Symbol_(multiline_comment_end())) { + if (Symbol_(m_multiline_comment_end)) { break; } else if (!Eol_()) { ++m_position; } } return true; - } else if (Symbol_(singleline_comment())) { + } else if (Symbol_(m_singleline_comment)) { while (m_position.has_more()) { - if (Symbol_(cr_lf())) { + if (Symbol_(m_cr_lf)) { m_position -= 2; break; } else if (Char_('\n')) { @@ -554,9 +530,9 @@ namespace chaiscript } } return true; - } else if (Symbol_(annotation())) { + } else if (Symbol_(m_annotation)) { while (m_position.has_more()) { - if (Symbol_(cr_lf())) { + if (Symbol_(m_cr_lf)) { m_position -= 2; break; } else if (Char_('\n')) { @@ -1472,7 +1448,7 @@ namespace chaiscript bool Eol_(const bool t_eos = false) { bool retval = false; - if (m_position.has_more() && (Symbol_(cr_lf()) || Char_('\n'))) { + if (m_position.has_more() && (Symbol_(m_cr_lf) || Char_('\n'))) { retval = true; //++m_position.line; m_position.col = 1; From c5a9cab3dd601daef96ea40a7d12cc5f7adb3f0b Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Wed, 20 Sep 2017 15:34:19 -0600 Subject: [PATCH 050/155] Simple cleanup for string comparisons --- include/chaiscript/language/chaiscript_parser.hpp | 2 +- include/chaiscript/utility/static_string.hpp | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/include/chaiscript/language/chaiscript_parser.hpp b/include/chaiscript/language/chaiscript_parser.hpp index 0cfe4223..2b7e7930 100644 --- a/include/chaiscript/language/chaiscript_parser.hpp +++ b/include/chaiscript/language/chaiscript_parser.hpp @@ -241,7 +241,7 @@ namespace chaiscript bool is_match(const std::size_t t_group, const std::string &t_str) const noexcept { auto match = [&t_str](const auto &array) { - return std::any_of(array.begin(), array.end(), [&t_str](const auto &v){ return v.c_str() == t_str; }); + return std::any_of(array.begin(), array.end(), [&t_str](const auto &v){ return v == t_str; }); }; switch (t_group) { diff --git a/include/chaiscript/utility/static_string.hpp b/include/chaiscript/utility/static_string.hpp index fb63f28e..09935fe6 100644 --- a/include/chaiscript/utility/static_string.hpp +++ b/include/chaiscript/utility/static_string.hpp @@ -28,6 +28,18 @@ namespace chaiscript return data; } + constexpr const char *begin() const noexcept { + return data; + } + + constexpr const char *end() const noexcept { + return data + m_size; + } + + bool operator==(const std::string &t_str) const noexcept { + return std::equal(begin(), end(), std::cbegin(t_str), std::cend(t_str)); + } + const size_t m_size; const char *data = nullptr; }; From 6cae70c20846dc73e570c293c1333202fafd8687 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Wed, 20 Sep 2017 16:44:32 -0600 Subject: [PATCH 051/155] Move to module level statics from function level --- .../chaiscript/language/chaiscript_parser.hpp | 24 ++++++++----------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/include/chaiscript/language/chaiscript_parser.hpp b/include/chaiscript/language/chaiscript_parser.hpp index 2b7e7930..413e12b0 100644 --- a/include/chaiscript/language/chaiscript_parser.hpp +++ b/include/chaiscript/language/chaiscript_parser.hpp @@ -286,7 +286,7 @@ namespace chaiscript constexpr static utility::Static_String m_singleline_comment{"//"}; constexpr static utility::Static_String m_annotation{"#"}; constexpr static utility::Static_String m_cr_lf{"\r\n"}; - + constexpr static auto m_operators = create_operators(); std::shared_ptr m_filename; std::vector> m_match_stack; @@ -429,10 +429,12 @@ namespace chaiscript ChaiScript_Parser(ChaiScript_Parser &&) = default; ChaiScript_Parser &operator=(ChaiScript_Parser &&) = delete; + constexpr static auto m_alphabet = build_alphabet(); + constexpr static Operator_Matches m_operator_matches{}; + /// test a char in an m_alphabet constexpr bool char_in_alphabet(char c, detail::Alphabet a) const noexcept { - constexpr auto alphabet = build_alphabet(); - return alphabet[a][static_cast(c)]; + return m_alphabet[a][static_cast(c)]; } /// Prints the parsed ast_nodes as a tree @@ -1421,8 +1423,7 @@ namespace chaiscript } bool is_operator(const std::string &t_s) const noexcept { - constexpr Operator_Matches operator_matches; - return operator_matches.is_match(t_s); + return m_operator_matches.is_match(t_s); } /// Reads (and potentially captures) a symbol group from input if it matches the parameter @@ -2320,14 +2321,12 @@ namespace chaiscript SS{"~"} }}; - constexpr auto operators = create_operators(); - for (const auto &oper : prefix_opers) { const bool is_char = oper.size() == 1; if ((is_char && Char(oper.c_str()[0])) || (!is_char && Symbol(oper))) { - if (!Operator(operators.size()-1)) { + if (!Operator(m_operators.size()-1)) { throw exception::eval_error("Incomplete prefix '" + std::string(oper.c_str()) + "' expression", File_Position(m_position.line, m_position.col), *m_filename); } @@ -2345,8 +2344,7 @@ namespace chaiscript } bool Operator_Helper(const size_t t_precedence, std::string &oper) { - constexpr Operator_Matches operator_matches; - return operator_matches.any_of(t_precedence, + return m_operator_matches.any_of(t_precedence, [&oper, this](const auto &elem){ if (Symbol(elem)) { oper = elem.c_str(); @@ -2362,9 +2360,7 @@ namespace chaiscript bool retval = false; const auto prev_stack_top = m_match_stack.size(); - constexpr auto operators = create_operators(); - - if (operators[t_precedence] != Operator_Precidence::Prefix) { + if (m_operators[t_precedence] != Operator_Precidence::Prefix) { if (Operator(t_precedence+1)) { retval = true; std::string oper; @@ -2375,7 +2371,7 @@ namespace chaiscript File_Position(m_position.line, m_position.col), *m_filename); } - switch (operators[t_precedence]) { + switch (m_operators[t_precedence]) { case(Operator_Precidence::Ternary_Cond) : if (Symbol(":")) { if (!Operator(t_precedence+1)) { From f54aa907365929bd10e7b2d17ca210896efd8485 Mon Sep 17 00:00:00 2001 From: Mario Lang Date: Mon, 25 Sep 2017 16:55:18 +0200 Subject: [PATCH 052/155] Use using --- include/chaiscript/dispatchkit/bootstrap.hpp | 2 +- .../chaiscript/dispatchkit/bootstrap_stl.hpp | 14 ++++++------- .../chaiscript/dispatchkit/dispatchkit.hpp | 20 +++++++++---------- .../dispatchkit/exception_specification.hpp | 2 +- .../dispatchkit/proxy_functions.hpp | 6 +++--- .../dispatchkit/type_conversions.hpp | 2 +- include/chaiscript/dispatchkit/type_info.hpp | 2 +- .../chaiscript/language/chaiscript_common.hpp | 6 +++--- .../chaiscript/language/chaiscript_parser.hpp | 6 +++--- 9 files changed, 30 insertions(+), 30 deletions(-) diff --git a/include/chaiscript/dispatchkit/bootstrap.hpp b/include/chaiscript/dispatchkit/bootstrap.hpp index 67116da6..79e157c4 100644 --- a/include/chaiscript/dispatchkit/bootstrap.hpp +++ b/include/chaiscript/dispatchkit/bootstrap.hpp @@ -22,7 +22,7 @@ namespace chaiscript template::value>::type > void array(const std::string &type, Module& m) { - typedef typename std::remove_extent::type ReturnType; + using ReturnType = typename std::remove_extent::type; m.add(user_type(), type); m.add(fun( diff --git a/include/chaiscript/dispatchkit/bootstrap_stl.hpp b/include/chaiscript/dispatchkit/bootstrap_stl.hpp index df25c9ec..78a85fca 100644 --- a/include/chaiscript/dispatchkit/bootstrap_stl.hpp +++ b/include/chaiscript/dispatchkit/bootstrap_stl.hpp @@ -44,7 +44,7 @@ namespace chaiscript template struct Bidir_Range { - typedef Container container_type; + using container_type = Container; constexpr Bidir_Range(Container &c) : m_begin(c.begin()), m_end(c.end()) @@ -355,7 +355,7 @@ namespace chaiscript , "back"); - typedef void (ContainerType::*push_back)(const typename ContainerType::value_type &); + using push_back = void (ContainerType::*)(const typename ContainerType::value_type &); m.add(fun(static_cast(&ContainerType::push_back)), [&]()->std::string{ if (typeid(typename ContainerType::value_type) == typeid(Boxed_Value)) { @@ -395,8 +395,8 @@ namespace chaiscript template void front_insertion_sequence_type(const std::string &type, Module& m) { - typedef void (ContainerType::*push_ptr)(typename ContainerType::const_reference); - typedef void (ContainerType::*pop_ptr)(); + using push_ptr = void (ContainerType::*)(typename ContainerType::const_reference); + using pop_ptr = void (ContainerType::*)(); m.add(fun([](ContainerType &container)->decltype(auto){ if (container.empty()) { @@ -498,7 +498,7 @@ namespace chaiscript { m.add(fun(detail::count), "count"); - typedef size_t (ContainerType::*erase_ptr)(const typename ContainerType::key_type &); + using erase_ptr = size_t (ContainerType::*)(const typename ContainerType::key_type &); m.add(fun(static_cast(&ContainerType::erase)), "erase"); @@ -529,8 +529,8 @@ namespace chaiscript { m.add(user_type(), type); - typedef typename MapType::mapped_type &(MapType::*elem_access)(const typename MapType::key_type &); - typedef const typename MapType::mapped_type &(MapType::*const_elem_access)(const typename MapType::key_type &) const; + using elem_access = typename MapType::mapped_type &(MapType::*)(const typename MapType::key_type &); + using const_elem_access = const typename MapType::mapped_type &(MapType::*)(const typename MapType::key_type &) const; m.add(fun(static_cast(&MapType::operator[])), "[]"); diff --git a/include/chaiscript/dispatchkit/dispatchkit.hpp b/include/chaiscript/dispatchkit/dispatchkit.hpp index 5b25127b..8c8748d1 100644 --- a/include/chaiscript/dispatchkit/dispatchkit.hpp +++ b/include/chaiscript/dispatchkit/dispatchkit.hpp @@ -261,7 +261,7 @@ namespace chaiscript }; /// Convenience typedef for Module objects to be added to the ChaiScript runtime - typedef std::shared_ptr ModulePtr; + using ModulePtr = std::shared_ptr; namespace detail { @@ -388,11 +388,11 @@ namespace chaiscript using SmallVector = std::vector; - typedef SmallVector> Scope; - typedef SmallVector StackData; - typedef SmallVector Stacks; - typedef SmallVector Call_Param_List; - typedef SmallVector Call_Params; + using Scope = SmallVector>; + using StackData = SmallVector; + using Stacks = SmallVector; + using Call_Param_List = SmallVector; + using Call_Params = SmallVector; Stack_Holder() { @@ -439,9 +439,9 @@ namespace chaiscript { public: - typedef std::map Type_Name_Map; - typedef std::vector> Scope; - typedef Stack_Holder::StackData StackData; + using Type_Name_Map = std::map; + using Scope = std::vector>; + using StackData = Stack_Holder::StackData; struct State { @@ -1417,7 +1417,7 @@ namespace chaiscript t_c.reserve(t_c.size() + 1); // tightly control growth of memory usage here t_c.emplace_back(t_key, std::forward(t_value)); } else { - typedef typename Container::value_type value_type; + using value_type = typename Container::value_type; *itr = value_type(t_key, std::forward(t_value)); } } diff --git a/include/chaiscript/dispatchkit/exception_specification.hpp b/include/chaiscript/dispatchkit/exception_specification.hpp index 0eeecdc4..608a1d44 100644 --- a/include/chaiscript/dispatchkit/exception_specification.hpp +++ b/include/chaiscript/dispatchkit/exception_specification.hpp @@ -101,7 +101,7 @@ namespace chaiscript /// /// \sa chaiscript::exception_specification for creation of chaiscript::Exception_Handler objects /// \sa \ref exceptions - typedef std::shared_ptr Exception_Handler; + using Exception_Handler = std::shared_ptr; /// \brief creates a chaiscript::Exception_Handler which handles one type of exception unboxing /// \sa \ref exceptions diff --git a/include/chaiscript/dispatchkit/proxy_functions.hpp b/include/chaiscript/dispatchkit/proxy_functions.hpp index b2383ce1..1f413069 100644 --- a/include/chaiscript/dispatchkit/proxy_functions.hpp +++ b/include/chaiscript/dispatchkit/proxy_functions.hpp @@ -41,7 +41,7 @@ namespace chaiscript class Boxed_Number; struct AST_Node; - typedef std::unique_ptr AST_NodePtr; + using AST_NodePtr = std::unique_ptr; namespace dispatch { @@ -318,11 +318,11 @@ namespace chaiscript } /// \brief Common typedef used for passing of any registered function in ChaiScript - typedef std::shared_ptr Proxy_Function; + using Proxy_Function = std::shared_ptr; /// \brief Const version of Proxy_Function. Points to a const Proxy_Function. This is how most registered functions /// are handled internally. - typedef std::shared_ptr Const_Proxy_Function; + using Const_Proxy_Function = std::shared_ptr; namespace exception { diff --git a/include/chaiscript/dispatchkit/type_conversions.hpp b/include/chaiscript/dispatchkit/type_conversions.hpp index d1f88233..6dc2138c 100644 --- a/include/chaiscript/dispatchkit/type_conversions.hpp +++ b/include/chaiscript/dispatchkit/type_conversions.hpp @@ -538,7 +538,7 @@ namespace chaiscript std::reference_wrapper m_saves; }; - typedef std::shared_ptr Type_Conversion; + using Type_Conversion = std::shared_ptr; /// \brief Used to register a to / parent class relationship with ChaiScript. Necessary if you /// want automatic conversions up your inheritance hierarchy. diff --git a/include/chaiscript/dispatchkit/type_info.hpp b/include/chaiscript/dispatchkit/type_info.hpp index f8fc868d..ebf1b2cd 100644 --- a/include/chaiscript/dispatchkit/type_info.hpp +++ b/include/chaiscript/dispatchkit/type_info.hpp @@ -24,7 +24,7 @@ namespace chaiscript template struct Bare_Type { - typedef typename std::remove_cv::type>::type>::type type; + using type = typename std::remove_cv::type>::type>::type; }; } diff --git a/include/chaiscript/language/chaiscript_common.hpp b/include/chaiscript/language/chaiscript_common.hpp index dbbfc744..cfc60ab2 100644 --- a/include/chaiscript/language/chaiscript_common.hpp +++ b/include/chaiscript/language/chaiscript_common.hpp @@ -84,7 +84,7 @@ namespace chaiscript }; /// Signature of module entry point that all binary loadable modules must implement. - typedef ModulePtr (*Create_Module_Func)(); + using Create_Module_Func = ModulePtr (*)(); /// Types of AST nodes available to the parser and eval @@ -150,8 +150,8 @@ namespace chaiscript /// \brief Typedef for pointers to AST_Node objects. Used in building of the AST_Node tree - typedef std::unique_ptr AST_NodePtr; - typedef std::unique_ptr AST_NodePtr_Const; + using AST_NodePtr = std::unique_ptr; + using AST_NodePtr_Const = std::unique_ptr; struct AST_Node_Trace; diff --git a/include/chaiscript/language/chaiscript_parser.hpp b/include/chaiscript/language/chaiscript_parser.hpp index ebcef83f..09bcc370 100644 --- a/include/chaiscript/language/chaiscript_parser.hpp +++ b/include/chaiscript/language/chaiscript_parser.hpp @@ -76,7 +76,7 @@ namespace chaiscript // common for all implementations static std::string u8str_from_ll(long long val) { - typedef std::string::value_type char_type; + using char_type = std::string::value_type; char_type c[2]; c[1] = char_type(val); @@ -92,7 +92,7 @@ namespace chaiscript static string_type str_from_ll(long long val) { - typedef typename string_type::value_type target_char_type; + using target_char_type = typename string_type::value_type; #if defined (CHAISCRIPT_UTF16_UTF32) // prepare converter std::wstring_convert, target_char_type> converter; @@ -1065,7 +1065,7 @@ namespace chaiscript struct Char_Parser { string_type &match; - typedef typename string_type::value_type char_type; + using char_type = typename string_type::value_type; bool is_escaped = false; bool is_interpolated = false; bool saw_interpolation_marker = false; From 91bcf1187ed0cb8aa6cf4ca0a4e6ebbf1a0c1895 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Sun, 12 Nov 2017 04:09:37 -0700 Subject: [PATCH 053/155] minor noexcept adjustments --- include/chaiscript/dispatchkit/dispatchkit.hpp | 14 +++++++------- include/chaiscript/dispatchkit/type_info.hpp | 4 ++-- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/include/chaiscript/dispatchkit/dispatchkit.hpp b/include/chaiscript/dispatchkit/dispatchkit.hpp index 5b25127b..4773834f 100644 --- a/include/chaiscript/dispatchkit/dispatchkit.hpp +++ b/include/chaiscript/dispatchkit/dispatchkit.hpp @@ -199,13 +199,13 @@ namespace chaiscript bool has_function(const Proxy_Function &new_f, const std::string_view &name) noexcept { - return std::any_of(m_funcs.begin(), m_funcs.end(), + return std::any_of(m_funcs.begin(), m_funcs.end(), [&](const std::pair &existing_f) { return existing_f.second == name && *(existing_f.first) == *(new_f); } ); } - + private: std::vector> m_typeinfos; @@ -215,14 +215,14 @@ namespace chaiscript std::vector m_conversions; template - static void apply(InItr begin, const InItr end, T &t) + static void apply(InItr begin, const InItr end, T &t) { - for_each(begin, end, + for_each(begin, end, [&t](const auto &obj) { try { t.add(obj.first, obj.second); } catch (const chaiscript::exception::name_conflict_error &) { - /// \todo Should we throw an error if there's a name conflict + /// \todo Should we throw an error if there's a name conflict /// while applying a module? } } @@ -266,7 +266,7 @@ namespace chaiscript namespace detail { /// A Proxy_Function implementation that is able to take - /// a vector of Proxy_Functions and perform a dispatch on them. It is + /// a vector of Proxy_Functions and perform a dispatch on them. It is /// used specifically in the case of dealing with Function object variables class Dispatch_Function final : public dispatch::Proxy_Function_Base { @@ -386,7 +386,7 @@ namespace chaiscript template using SmallVector = std::vector; - + typedef SmallVector> Scope; typedef SmallVector StackData; diff --git a/include/chaiscript/dispatchkit/type_info.hpp b/include/chaiscript/dispatchkit/type_info.hpp index f8fc868d..7683bd1e 100644 --- a/include/chaiscript/dispatchkit/type_info.hpp +++ b/include/chaiscript/dispatchkit/type_info.hpp @@ -34,7 +34,7 @@ namespace chaiscript { public: constexpr Type_Info(const bool t_is_const, const bool t_is_reference, const bool t_is_pointer, const bool t_is_void, - const bool t_is_arithmetic, const std::type_info *t_ti, const std::type_info *t_bare_ti) + const bool t_is_arithmetic, const std::type_info *t_ti, const std::type_info *t_bare_ti) noexcept : m_type_info(t_ti), m_bare_type_info(t_bare_ti), m_flags((static_cast(t_is_const) << is_const_flag) + (static_cast(t_is_reference) << is_reference_flag) @@ -44,7 +44,7 @@ namespace chaiscript { } - constexpr Type_Info() = default; + constexpr Type_Info() noexcept = default; constexpr bool operator<(const Type_Info &ti) const noexcept { From 8895ee8fc58ff13e7ee17007aeab6f78bf9f81f1 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Mon, 13 Nov 2017 00:02:22 -0700 Subject: [PATCH 054/155] Fix assignment / modification of return values --- include/chaiscript/dispatchkit/boxed_number.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/chaiscript/dispatchkit/boxed_number.hpp b/include/chaiscript/dispatchkit/boxed_number.hpp index 2817ff1a..3e96a03e 100644 --- a/include/chaiscript/dispatchkit/boxed_number.hpp +++ b/include/chaiscript/dispatchkit/boxed_number.hpp @@ -327,7 +327,7 @@ namespace chaiscript { auto lhs_visit = [t_oper, &t_lhs, &t_rhs](const auto &c_lhs){ - auto *lhs = static_cast *>(t_lhs.get_ptr()); + auto *lhs = t_lhs.is_return_value()?nullptr:static_cast *>(t_lhs.get_ptr()); auto rhs_visit = [t_oper, &t_lhs, lhs, &c_lhs](const auto &c_rhs) { return go(t_oper, t_lhs, lhs, c_lhs, c_rhs); From 425c679c6c8e3f72df778b987e74fb353cf34923 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Mon, 13 Nov 2017 09:03:55 -0700 Subject: [PATCH 055/155] Fix GLOBAL in clone_object tests --- unittests/clone_object.chai | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/unittests/clone_object.chai b/unittests/clone_object.chai index 78c38a29..04ad0be8 100644 --- a/unittests/clone_object.chai +++ b/unittests/clone_object.chai @@ -1,4 +1,4 @@ -GLOBAL clone_count = 0; +global clone_count = 0; class Cloneable { From 28a59d2a6e3192f59564142a02dcf45229df9fb6 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Thu, 16 Nov 2017 09:10:29 -0700 Subject: [PATCH 056/155] Avoid creating vectors when possible --- include/chaiscript/chaiscript_defines.hpp | 59 +++++++-- include/chaiscript/chaiscript_stdlib.hpp | 2 +- include/chaiscript/dispatchkit/any.hpp | 8 +- include/chaiscript/dispatchkit/bootstrap.hpp | 2 +- .../chaiscript/dispatchkit/dispatchkit.hpp | 41 +++---- .../dispatchkit/dynamic_object_detail.hpp | 14 +-- .../dispatchkit/function_call_detail.hpp | 16 ++- .../dispatchkit/function_params.hpp | 81 +++++++++++++ .../dispatchkit/proxy_functions.hpp | 114 +++++++++--------- .../dispatchkit/proxy_functions_detail.hpp | 7 +- .../chaiscript/language/chaiscript_common.hpp | 9 +- .../chaiscript/language/chaiscript_engine.hpp | 4 +- .../chaiscript/language/chaiscript_eval.hpp | 107 ++++++++-------- .../chaiscript/language/chaiscript_parser.hpp | 54 ++++----- include/chaiscript/utility/stack_vector.hpp | 63 ++++++++++ 15 files changed, 375 insertions(+), 206 deletions(-) create mode 100644 include/chaiscript/dispatchkit/function_params.hpp create mode 100644 include/chaiscript/utility/stack_vector.hpp diff --git a/include/chaiscript/chaiscript_defines.hpp b/include/chaiscript/chaiscript_defines.hpp index 9754913f..6c8ee78d 100644 --- a/include/chaiscript/chaiscript_defines.hpp +++ b/include/chaiscript/chaiscript_defines.hpp @@ -105,47 +105,47 @@ namespace chaiscript { } struct Build_Info { - constexpr static int version_major() noexcept + [[nodiscard]] constexpr static int version_major() noexcept { return chaiscript::version_major; } - constexpr static int version_minor() noexcept + [[nodiscard]] constexpr static int version_minor() noexcept { return chaiscript::version_minor; } - constexpr static int version_patch() noexcept + [[nodiscard]] constexpr static int version_patch() noexcept { return chaiscript::version_patch; } - static std::string version() + [[nodiscard]] static std::string version() { return std::to_string(version_major()) + '.' + std::to_string(version_minor()) + '.' + std::to_string(version_patch()); } - static std::string compiler_id() + [[nodiscard]] static std::string compiler_id() { return compiler_name() + '-' + compiler_version(); } - static std::string build_id() + [[nodiscard]] static std::string build_id() { return compiler_id() + (debug_build()?"-Debug":"-Release"); } - static std::string compiler_version() + [[nodiscard]] static std::string compiler_version() { return chaiscript::compiler_version; } - static std::string compiler_name() + [[nodiscard]] static std::string compiler_name() { return chaiscript::compiler_name; } - constexpr static bool debug_build() noexcept + [[nodiscard]] constexpr static bool debug_build() noexcept { return chaiscript::debug_build; } @@ -153,7 +153,8 @@ namespace chaiscript { template - constexpr auto parse_num(const std::string_view &t_str) noexcept -> typename std::enable_if::value, T>::type + [[nodiscard]] constexpr auto parse_num(const std::string_view &t_str) noexcept + -> typename std::enable_if::value, T>::type { T t = 0; for (const auto c : t_str) { @@ -168,7 +169,8 @@ namespace chaiscript { template - auto parse_num(const std::string_view &t_str) noexcept -> typename std::enable_if::value, T>::type + [[nodiscard]] auto parse_num(const std::string_view &t_str) noexcept + -> typename std::enable_if::value, T>::type { T t = 0; T base = 0; @@ -211,11 +213,11 @@ namespace chaiscript { } struct str_less { - bool operator()(const std::string &t_lhs, const std::string &t_rhs) const noexcept { + [[nodiscard]] bool operator()(const std::string &t_lhs, const std::string &t_rhs) const noexcept { return t_lhs < t_rhs; } template - constexpr bool operator()(const LHS &t_lhs, const RHS &t_rhs) const noexcept { + [[nodiscard]] constexpr bool operator()(const LHS &t_lhs, const RHS &t_rhs) const noexcept { return std::lexicographical_compare(t_lhs.begin(), t_lhs.end(), t_rhs.begin(), t_rhs.end()); } struct is_transparent{}; @@ -229,6 +231,37 @@ namespace chaiscript { External_Scripts }; + template + struct is_nothrow_forward_constructible + : std::bool_constant()})> + { + }; + + template< class From, class To > + inline constexpr bool is_nothrow_forward_constructible_v + = is_nothrow_forward_constructible::value; + + template + [[nodiscard]] constexpr auto make_container(T && ... t) + { + Container c; + c.reserve(sizeof...(t)); + (c.push_back(std::forward(t)), ...); + return c; + } + + + template + [[nodiscard]] auto make_vector(T && ... t) + { + using container_type = + std::vector...>>; + + return make_container(std::forward(t)...); + } + + + static inline std::vector default_options() { #ifdef CHAISCRIPT_NO_DYNLOAD diff --git a/include/chaiscript/chaiscript_stdlib.hpp b/include/chaiscript/chaiscript_stdlib.hpp index ed56b234..2407fcf0 100644 --- a/include/chaiscript/chaiscript_stdlib.hpp +++ b/include/chaiscript/chaiscript_stdlib.hpp @@ -42,7 +42,7 @@ namespace chaiscript { public: - static ModulePtr library() + [[nodiscard]] static ModulePtr library() { auto lib = std::make_shared(); bootstrap::Bootstrap::bootstrap(*lib); diff --git a/include/chaiscript/dispatchkit/any.hpp b/include/chaiscript/dispatchkit/any.hpp index d13b653f..a9e31594 100644 --- a/include/chaiscript/dispatchkit/any.hpp +++ b/include/chaiscript/dispatchkit/any.hpp @@ -83,8 +83,8 @@ namespace chaiscript { public: // construct/copy/destruct constexpr Any() noexcept = default; - Any(Any &&) = default; - Any &operator=(Any &&t_any) = default; + Any(Any &&) noexcept = default; + Any &operator=(Any &&t_any) noexcept = default; Any(const Any &t_any) : m_data(t_any.empty() ? nullptr : t_any.m_data->clone()) @@ -93,7 +93,7 @@ namespace chaiscript { template>>> - explicit Any(ValueType &&t_value) + explicit Any(ValueType &&t_value) noexcept(is_nothrow_forward_constructible_v>) : m_data(std::make_unique>>(std::forward(t_value))) { } @@ -128,7 +128,7 @@ namespace chaiscript { // queries bool empty() const noexcept { - return !bool(m_data); + return !static_cast(m_data); } const std::type_info & type() const noexcept diff --git a/include/chaiscript/dispatchkit/bootstrap.hpp b/include/chaiscript/dispatchkit/bootstrap.hpp index 67116da6..9a94d104 100644 --- a/include/chaiscript/dispatchkit/bootstrap.hpp +++ b/include/chaiscript/dispatchkit/bootstrap.hpp @@ -241,7 +241,7 @@ namespace chaiscript /// Create a bound function object. The first param is the function to bind /// the remaining parameters are the args to bind into the result - static Boxed_Value bind_function(const std::vector ¶ms) + static Boxed_Value bind_function(const Function_Params ¶ms) { if (params.empty()) { throw exception::arity_error(0, 1); diff --git a/include/chaiscript/dispatchkit/dispatchkit.hpp b/include/chaiscript/dispatchkit/dispatchkit.hpp index f8217ea4..4f338cee 100644 --- a/include/chaiscript/dispatchkit/dispatchkit.hpp +++ b/include/chaiscript/dispatchkit/dispatchkit.hpp @@ -313,14 +313,14 @@ namespace chaiscript return arity; } - bool call_match(const std::vector &vals, const Type_Conversions_State &t_conversions) const noexcept override + bool call_match(const Function_Params &vals, const Type_Conversions_State &t_conversions) const noexcept override { return std::any_of(std::begin(m_funcs), std::end(m_funcs), [&vals, &t_conversions](const Proxy_Function &f){ return f->call_match(vals, t_conversions); }); } protected: - Boxed_Value do_call(const std::vector ¶ms, const Type_Conversions_State &t_conversions) const override + Boxed_Value do_call(const Function_Params ¶ms, const Type_Conversions_State &t_conversions) const override { return dispatch::dispatch(m_funcs, params, t_conversions); } @@ -935,7 +935,7 @@ namespace chaiscript return m_conversions; } - static bool is_attribute_call(const std::vector &t_funs, const std::vector &t_params, + static bool is_attribute_call(const std::vector &t_funs, const Function_Params &t_params, bool t_has_params, const Type_Conversions_State &t_conversions) noexcept { if (!t_has_params || t_params.empty()) { @@ -956,7 +956,7 @@ namespace chaiscript #pragma warning(push) #pragma warning(disable : 4715) #endif - Boxed_Value call_member(const std::string &t_name, std::atomic_uint_fast32_t &t_loc, const std::vector ¶ms, bool t_has_params, + Boxed_Value call_member(const std::string &t_name, std::atomic_uint_fast32_t &t_loc, const Function_Params ¶ms, bool t_has_params, const Type_Conversions_State &t_conversions) { uint_fast32_t loc = t_loc; @@ -964,9 +964,9 @@ namespace chaiscript if (funs.first != loc) { t_loc = uint_fast32_t(funs.first); } const auto do_attribute_call = - [this](int l_num_params, const std::vector &l_params, const std::vector &l_funs, const Type_Conversions_State &l_conversions)->Boxed_Value + [this](int l_num_params, Function_Params l_params, const std::vector &l_funs, const Type_Conversions_State &l_conversions)->Boxed_Value { - std::vector attr_params{l_params.begin(), l_params.begin() + l_num_params}; + Function_Params attr_params(l_params.begin(), l_params.begin() + l_num_params); Boxed_Value bv = dispatch::dispatch(l_funs, attr_params, l_conversions); if (l_num_params < int(l_params.size()) || bv.get_type_info().bare_equal(user_type())) { struct This_Foist { @@ -1049,14 +1049,15 @@ namespace chaiscript if (!functions.empty()) { try { if (is_no_param) { - auto tmp_params(params); + auto tmp_params = params.to_vector(); tmp_params.insert(tmp_params.begin() + 1, var(t_name)); - return do_attribute_call(2, tmp_params, functions, t_conversions); + return do_attribute_call(2, Function_Params(tmp_params), functions, t_conversions); } else { - return dispatch::dispatch(functions, {params[0], var(t_name), var(std::vector(params.begin()+1, params.end()))}, t_conversions); + std::array p{params[0], var(t_name), var(std::vector(params.begin()+1, params.end()))}; + return dispatch::dispatch(functions, Function_Params{p}, t_conversions); } } catch (const dispatch::option_explicit_set &e) { - throw chaiscript::exception::dispatch_error(params, std::vector(funs.second->begin(), funs.second->end()), + throw chaiscript::exception::dispatch_error(params, std::vector(funs.second->begin(), funs.second->end()), e.what()); } } @@ -1076,7 +1077,7 @@ namespace chaiscript - Boxed_Value call_function(const std::string_view &t_name, std::atomic_uint_fast32_t &t_loc, const std::vector ¶ms, + Boxed_Value call_function(const std::string_view &t_name, std::atomic_uint_fast32_t &t_loc, Function_Params params, const Type_Conversions_State &t_conversions) const { uint_fast32_t loc = t_loc; @@ -1132,7 +1133,7 @@ namespace chaiscript /// Returns true if a call can be made that consists of the first parameter /// (the function) with the remaining parameters as its arguments. - Boxed_Value call_exists(const std::vector ¶ms) const + Boxed_Value call_exists(const Function_Params ¶ms) const { if (params.empty()) { @@ -1142,7 +1143,7 @@ namespace chaiscript const auto &f = this->boxed_cast(params[0]); const Type_Conversions_State convs(m_conversions, m_conversions.conversion_saves()); - return const_var(f->call_match(std::vector(params.begin() + 1, params.end()), convs)); + return const_var(f->call_match(Function_Params(params.begin() + 1, params.end()), convs)); } /// Dump all system info to stdout @@ -1203,11 +1204,6 @@ namespace chaiscript m_state = t_state; } - static void save_function_params(Stack_Holder &t_s, std::initializer_list t_params) - { - t_s.call_params.back().insert(t_s.call_params.back().begin(), t_params); - } - static void save_function_params(Stack_Holder &t_s, std::vector &&t_params) { for (auto &¶m : t_params) @@ -1216,22 +1212,17 @@ namespace chaiscript } } - static void save_function_params(Stack_Holder &t_s, const std::vector &t_params) + static void save_function_params(Stack_Holder &t_s, const Function_Params &t_params) { t_s.call_params.back().insert(t_s.call_params.back().begin(), t_params.begin(), t_params.end()); } - void save_function_params(std::initializer_list t_params) - { - save_function_params(*m_stack_holder, t_params); - } - void save_function_params(std::vector &&t_params) { save_function_params(*m_stack_holder, std::move(t_params)); } - void save_function_params(const std::vector &t_params) + void save_function_params(const Function_Params &t_params) { save_function_params(*m_stack_holder, t_params); } diff --git a/include/chaiscript/dispatchkit/dynamic_object_detail.hpp b/include/chaiscript/dispatchkit/dynamic_object_detail.hpp index eacfb51a..7c0364d8 100644 --- a/include/chaiscript/dispatchkit/dynamic_object_detail.hpp +++ b/include/chaiscript/dispatchkit/dynamic_object_detail.hpp @@ -94,7 +94,7 @@ namespace chaiscript bool is_attribute_function() const noexcept override { return m_is_attribute; } - bool call_match(const std::vector &vals, const Type_Conversions_State &t_conversions) const noexcept override + bool call_match(const Function_Params &vals, const Type_Conversions_State &t_conversions) const noexcept override { if (dynamic_object_typename_match(vals, m_type_name, m_ti, t_conversions)) { @@ -110,7 +110,7 @@ namespace chaiscript } protected: - Boxed_Value do_call(const std::vector ¶ms, const Type_Conversions_State &t_conversions) const override + Boxed_Value do_call(const Function_Params ¶ms, const Type_Conversions_State &t_conversions) const override { if (dynamic_object_typename_match(params, m_type_name, m_ti, t_conversions)) { @@ -159,7 +159,7 @@ namespace chaiscript } - bool dynamic_object_typename_match(const std::vector &bvs, const std::string &name, + bool dynamic_object_typename_match(const Function_Params &bvs, const std::string &name, const std::unique_ptr &ti, const Type_Conversions_State &t_conversions) const noexcept { if (!bvs.empty()) @@ -228,22 +228,22 @@ namespace chaiscript return (dc != nullptr) && dc->m_type_name == m_type_name && (*dc->m_func) == (*m_func); } - bool call_match(const std::vector &vals, const Type_Conversions_State &t_conversions) const override + bool call_match(const Function_Params &vals, const Type_Conversions_State &t_conversions) const override { std::vector new_vals{Boxed_Value(Dynamic_Object(m_type_name))}; new_vals.insert(new_vals.end(), vals.begin(), vals.end()); - return m_func->call_match(new_vals, t_conversions); + return m_func->call_match(Function_Params{new_vals}, t_conversions); } protected: - Boxed_Value do_call(const std::vector ¶ms, const Type_Conversions_State &t_conversions) const override + Boxed_Value do_call(const Function_Params ¶ms, const Type_Conversions_State &t_conversions) const override { auto bv = Boxed_Value(Dynamic_Object(m_type_name), true); std::vector new_params{bv}; new_params.insert(new_params.end(), params.begin(), params.end()); - (*m_func)(new_params, t_conversions); + (*m_func)(Function_Params{new_params}, t_conversions); return bv; } diff --git a/include/chaiscript/dispatchkit/function_call_detail.hpp b/include/chaiscript/dispatchkit/function_call_detail.hpp index 7d8b3d5e..5cd1932e 100644 --- a/include/chaiscript/dispatchkit/function_call_detail.hpp +++ b/include/chaiscript/dispatchkit/function_call_detail.hpp @@ -35,7 +35,7 @@ namespace chaiscript struct Function_Caller_Ret { static Ret call(const std::vector &t_funcs, - const std::vector ¶ms, const Type_Conversions_State *t_conversions) + const Function_Params ¶ms, const Type_Conversions_State *t_conversions) { if (t_conversions != nullptr) { return boxed_cast(dispatch::dispatch(t_funcs, params, *t_conversions), t_conversions); @@ -54,7 +54,7 @@ namespace chaiscript struct Function_Caller_Ret { static Ret call(const std::vector &t_funcs, - const std::vector ¶ms, const Type_Conversions_State *t_conversions) + const Function_Params ¶ms, const Type_Conversions_State *t_conversions) { if (t_conversions != nullptr) { return Boxed_Number(dispatch::dispatch(t_funcs, params, *t_conversions)).get_as(); @@ -74,7 +74,7 @@ namespace chaiscript struct Function_Caller_Ret { static void call(const std::vector &t_funcs, - const std::vector ¶ms, const Type_Conversions_State *t_conversions) + const Function_Params ¶ms, const Type_Conversions_State *t_conversions) { if (t_conversions != nullptr) { dispatch::dispatch(t_funcs, params, *t_conversions); @@ -101,16 +101,14 @@ namespace chaiscript template Ret operator()(P&& ... param) { + std::array params{box

(std::forward

(param))...}; + if (m_conversions) { Type_Conversions_State state(*m_conversions, m_conversions->conversion_saves()); - return Function_Caller_Ret::value && !std::is_same::value>::call(m_funcs, { - box

(std::forward

(param))... - }, &state + return Function_Caller_Ret::value && !std::is_same::value>::call(m_funcs, Function_Params{params}, &state ); } else { - return Function_Caller_Ret::value && !std::is_same::value>::call(m_funcs, { - box

(std::forward

(param))... - }, nullptr + return Function_Caller_Ret::value && !std::is_same::value>::call(m_funcs, Function_Params{params}, nullptr ); } diff --git a/include/chaiscript/dispatchkit/function_params.hpp b/include/chaiscript/dispatchkit/function_params.hpp new file mode 100644 index 00000000..090f7004 --- /dev/null +++ b/include/chaiscript/dispatchkit/function_params.hpp @@ -0,0 +1,81 @@ +// This file is distributed under the BSD License. +// See "license.txt" for details. +// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) +// Copyright 2009-2017, Jason Turner (jason@emptycrate.com) +// http://www.chaiscript.com + +// This is an open source non-commercial project. Dear PVS-Studio, please check it. +// PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com + + +#ifndef CHAISCRIPT_FUNCTION_PARAMS_HPP +#define CHAISCRIPT_FUNCTION_PARAMS_HPP + + +#include "boxed_value.hpp" + +namespace chaiscript { + + class Function_Params + { + public: + constexpr Function_Params(const Boxed_Value * const t_begin, const Boxed_Value * const t_end) + : m_begin(t_begin), m_end(t_end) + { + } + + explicit Function_Params(const Boxed_Value &bv) + : m_begin(&bv), m_end(m_begin + 1) + { + } + + explicit Function_Params(const std::vector &vec) + : m_begin(&vec.front()), m_end(&vec.front() + vec.size()) + { + } + + template + constexpr explicit Function_Params(const std::array &a) + : m_begin(std::begin(a)), m_end(std::end(a)) + { + } + + [[nodiscard]] constexpr const Boxed_Value &operator[](const std::size_t t_i) const noexcept { + return m_begin[t_i]; + } + + [[nodiscard]] constexpr const Boxed_Value *begin() const noexcept { + return m_begin; + } + + [[nodiscard]] constexpr const Boxed_Value &front() const noexcept { + return *m_begin; + } + + [[nodiscard]] constexpr const Boxed_Value *end() const noexcept { + return m_end; + } + + [[nodiscard]] constexpr std::size_t size() const noexcept { + return m_end - m_begin; + } + + std::vector to_vector() const { + return std::vector{m_begin, m_end}; + } + + [[nodiscard]] constexpr bool empty() const noexcept { + return m_begin == m_end; + } + + private: + const Boxed_Value *m_begin = nullptr; + const Boxed_Value *m_end = nullptr; + + }; + +} + + +#endif + diff --git a/include/chaiscript/dispatchkit/proxy_functions.hpp b/include/chaiscript/dispatchkit/proxy_functions.hpp index f1797417..0f97edbf 100644 --- a/include/chaiscript/dispatchkit/proxy_functions.hpp +++ b/include/chaiscript/dispatchkit/proxy_functions.hpp @@ -27,6 +27,7 @@ #include "proxy_functions_detail.hpp" #include "type_info.hpp" #include "dynamic_object.hpp" +#include "function_params.hpp" namespace chaiscript { class Type_Conversions; @@ -91,8 +92,9 @@ namespace chaiscript return m_types == t_rhs.m_types; } - std::vector convert(std::vector vals, const Type_Conversions_State &t_conversions) const + 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(); for (size_t i = 0; i < vals.size(); ++i) { @@ -131,7 +133,7 @@ namespace chaiscript // first result: is a match // second result: needs conversions - std::pair match(const std::vector &vals, const Type_Conversions_State &t_conversions) const noexcept + std::pair match(const Function_Params &vals, const Type_Conversions_State &t_conversions) const noexcept { constexpr auto dynamic_object_type_info = user_type(); bool needs_conversion = false; @@ -154,7 +156,7 @@ namespace chaiscript } } catch (const std::bad_cast &) { return std::make_pair(false, false); - } + } } else { const auto &ti = m_types[i].second; if (!ti.is_undef()) @@ -214,7 +216,7 @@ namespace chaiscript public: virtual ~Proxy_Function_Base() = default; - Boxed_Value operator()(const std::vector ¶ms, const chaiscript::Type_Conversions_State &t_conversions) const + Boxed_Value operator()(const Function_Params ¶ms, const chaiscript::Type_Conversions_State &t_conversions) const { if (m_arity < 0 || size_t(m_arity) == params.size()) { return do_call(params, t_conversions); @@ -226,11 +228,11 @@ namespace chaiscript /// Returns a vector containing all of the types of the parameters the function returns/takes /// if the function is variadic or takes no arguments (arity of 0 or -1), the returned /// value contains exactly 1 Type_Info object: the return type - /// \returns the types of all parameters. + /// \returns the types of all parameters. const std::vector &get_param_types() const noexcept { return m_types; } virtual bool operator==(const Proxy_Function_Base &) const noexcept = 0; - virtual bool call_match(const std::vector &vals, const Type_Conversions_State &t_conversions) const = 0; + virtual bool call_match(const Function_Params &vals, const Type_Conversions_State &t_conversions) const = 0; virtual bool is_attribute_function() const noexcept { return false; } @@ -246,7 +248,7 @@ namespace chaiscript //! Return true if the function is a possible match //! to the passed in values - bool filter(const std::vector &vals, const Type_Conversions_State &t_conversions) const noexcept + bool filter(const Function_Params &vals, const Type_Conversions_State &t_conversions) const noexcept { assert(m_arity == -1 || (m_arity > 0 && static_cast(vals.size()) == m_arity)); @@ -272,13 +274,13 @@ namespace chaiscript constexpr auto boxed_number_ti = user_type(); constexpr auto function_ti = user_type>(); - if (ti.is_undef() + if (ti.is_undef() || ti.bare_equal(boxed_value_ti) || (!bv.get_type_info().is_undef() && ( (ti.bare_equal(boxed_number_ti) && bv.get_type_info().is_arithmetic()) || ti.bare_equal(bv.get_type_info()) || bv.get_type_info().bare_equal(function_ti) - || t_conversions->converts(ti, bv.get_type_info()) + || t_conversions->converts(ti, bv.get_type_info()) ) ) ) @@ -296,7 +298,7 @@ namespace chaiscript } protected: - virtual Boxed_Value do_call(const std::vector ¶ms, const Type_Conversions_State &t_conversions) const = 0; + virtual Boxed_Value do_call(const Function_Params ¶ms, const Type_Conversions_State &t_conversions) const = 0; Proxy_Function_Base(std::vector t_types, int t_arity) : m_types(std::move(t_types)), m_arity(t_arity), m_has_arithmetic_param(false) @@ -313,7 +315,7 @@ namespace chaiscript } - static bool compare_types(const std::vector &tis, const std::vector &bvs, + static bool compare_types(const std::vector &tis, const Function_Params &bvs, const Type_Conversions_State &t_conversions) noexcept { if (tis.size() - 1 != bvs.size()) @@ -367,10 +369,8 @@ namespace chaiscript virtual Param_Types get_dynamic_param_types() const = 0; }; - /** - * A Proxy_Function implementation that is not type safe, the called function - * is expecting a vector that it works with how it chooses. - */ + /// A Proxy_Function implementation that is not type safe, the called function + /// is expecting a vector that it works with how it chooses. class Dynamic_Proxy_Function : public Proxy_Function_Base, public Dynamic_Function_Interface { public: @@ -398,7 +398,7 @@ namespace chaiscript && this->m_param_types == prhs->m_param_types); } - bool call_match(const std::vector &vals, const Type_Conversions_State &t_conversions) const override + bool call_match(const Function_Params &vals, const Type_Conversions_State &t_conversions) const override { return call_match_internal(vals, t_conversions).first; } @@ -431,7 +431,7 @@ namespace chaiscript } protected: - bool test_guard(const std::vector ¶ms, const Type_Conversions_State &t_conversions) const + bool test_guard(const Function_Params ¶ms, const Type_Conversions_State &t_conversions) const { if (m_guard) { @@ -449,7 +449,7 @@ namespace chaiscript // first result: is a match // second result: needs conversions - std::pair call_match_internal(const std::vector &vals, const Type_Conversions_State &t_conversions) const + std::pair call_match_internal(const Function_Params &vals, const Type_Conversions_State &t_conversions) const { const auto comparison_result = [&](){ if (m_arity < 0) { @@ -462,7 +462,7 @@ namespace chaiscript }(); return std::make_pair( - comparison_result.first && test_guard(vals, t_conversions), + comparison_result.first && test_guard(vals, t_conversions), comparison_result.second ); } @@ -500,7 +500,7 @@ namespace chaiscript { public: Dynamic_Proxy_Function_Impl( - Callable t_f, + Callable t_f, int t_arity=-1, std::shared_ptr t_parsenode = AST_NodePtr(), Param_Types t_param_types = Param_Types(), @@ -517,13 +517,13 @@ namespace chaiscript protected: - Boxed_Value do_call(const std::vector ¶ms, const Type_Conversions_State &t_conversions) const override + Boxed_Value do_call(const Function_Params ¶ms, const Type_Conversions_State &t_conversions) const override { - const auto match_results = call_match_internal(params, t_conversions); - if (match_results.first) + const auto [is_a_match, needs_conversions] = call_match_internal(params, t_conversions); + if (is_a_match) { - if (match_results.second) { - return m_f(m_param_types.convert(params, t_conversions)); + if (needs_conversions) { + return m_f(Function_Params{m_param_types.convert(params, t_conversions)}); } else { return m_f(params); } @@ -556,7 +556,7 @@ namespace chaiscript class Bound_Function final : public Proxy_Function_Base { public: - Bound_Function(const Const_Proxy_Function &t_f, + Bound_Function(const Const_Proxy_Function &t_f, const std::vector &t_args) : Proxy_Function_Base(build_param_type_info(t_f, t_args), (t_f->get_arity()<0?-1:static_cast(build_param_type_info(t_f, t_args).size())-1)), m_f(t_f), m_args(t_args) @@ -570,9 +570,9 @@ namespace chaiscript } - bool call_match(const std::vector &vals, const Type_Conversions_State &t_conversions) const override + bool call_match(const Function_Params &vals, const Type_Conversions_State &t_conversions) const override { - return m_f->call_match(build_param_list(vals), t_conversions); + return m_f->call_match(Function_Params(build_param_list(vals)), t_conversions); } std::vector get_contained_functions() const override @@ -581,7 +581,7 @@ namespace chaiscript } - std::vector build_param_list(const std::vector ¶ms) const + std::vector build_param_list(const Function_Params ¶ms) const { auto parg = params.begin(); auto barg = m_args.begin(); @@ -590,7 +590,7 @@ namespace chaiscript while (!(parg == params.end() && barg == m_args.end())) { - while (barg != m_args.end() + while (barg != m_args.end() && !(barg->get_type_info() == chaiscript::detail::Get_Type_Info::get())) { args.push_back(*barg); @@ -603,18 +603,18 @@ namespace chaiscript ++parg; } - if (barg != m_args.end() + if (barg != m_args.end() && barg->get_type_info() == chaiscript::detail::Get_Type_Info::get()) { ++barg; - } + } } return args; } protected: - static std::vector build_param_type_info(const Const_Proxy_Function &t_f, + static std::vector build_param_type_info(const Const_Proxy_Function &t_f, const std::vector &t_args) { assert(t_f->get_arity() < 0 || t_f->get_arity() == static_cast(t_args.size())); @@ -638,9 +638,9 @@ namespace chaiscript return retval; } - Boxed_Value do_call(const std::vector ¶ms, const Type_Conversions_State &t_conversions) const override + Boxed_Value do_call(const Function_Params ¶ms, const Type_Conversions_State &t_conversions) const override { - return (*m_f)(build_param_list(params), t_conversions); + return (*m_f)(Function_Params{build_param_list(params)}, t_conversions); } private: @@ -656,13 +656,13 @@ namespace chaiscript { } - bool call_match(const std::vector &vals, const Type_Conversions_State &t_conversions) const noexcept override + bool call_match(const Function_Params &vals, const Type_Conversions_State &t_conversions) const noexcept override { - return static_cast(vals.size()) == get_arity() + return static_cast(vals.size()) == get_arity() && (compare_types(m_types, vals, t_conversions) && compare_types_with_cast(vals, t_conversions)); } - virtual bool compare_types_with_cast(const std::vector &vals, const Type_Conversions_State &t_conversions) const noexcept = 0; + virtual bool compare_types_with_cast(const Function_Params &vals, const Type_Conversions_State &t_conversions) const noexcept = 0; }; @@ -678,7 +678,7 @@ namespace chaiscript { } - bool compare_types_with_cast(const std::vector &vals, const Type_Conversions_State &t_conversions) const noexcept override + bool compare_types_with_cast(const Function_Params &vals, const Type_Conversions_State &t_conversions) const noexcept override { return detail::compare_types_cast(static_cast(nullptr), vals, t_conversions); } @@ -690,7 +690,7 @@ namespace chaiscript protected: - Boxed_Value do_call(const std::vector ¶ms, const Type_Conversions_State &t_conversions) const override + Boxed_Value do_call(const Function_Params ¶ms, const Type_Conversions_State &t_conversions) const override { return detail::call_func(static_cast(nullptr), m_f, params, t_conversions); } @@ -722,7 +722,7 @@ namespace chaiscript assert(!m_shared_ptr_holder || m_shared_ptr_holder.get() == &m_f.get()); } - bool compare_types_with_cast(const std::vector &vals, const Type_Conversions_State &t_conversions) const noexcept override + bool compare_types_with_cast(const Function_Params &vals, const Type_Conversions_State &t_conversions) const noexcept override { return detail::compare_types_cast(static_cast(nullptr), vals, t_conversions); } @@ -742,7 +742,7 @@ namespace chaiscript } protected: - Boxed_Value do_call(const std::vector ¶ms, const Type_Conversions_State &t_conversions) const override + Boxed_Value do_call(const Function_Params ¶ms, const Type_Conversions_State &t_conversions) const override { return detail::call_func(static_cast(nullptr), m_f.get(), params, t_conversions); } @@ -765,11 +765,11 @@ namespace chaiscript { } - bool is_attribute_function() const noexcept override { return true; } + bool is_attribute_function() const noexcept override { return true; } bool operator==(const Proxy_Function_Base &t_func) const noexcept override { - const Attribute_Access * aa + const Attribute_Access * aa = dynamic_cast *>(&t_func); if (aa) { @@ -779,7 +779,7 @@ namespace chaiscript } } - bool call_match(const std::vector &vals, const Type_Conversions_State &) const noexcept override + bool call_match(const Function_Params &vals, const Type_Conversions_State &) const noexcept override { if (vals.size() != 1) { @@ -790,7 +790,7 @@ namespace chaiscript } protected: - Boxed_Value do_call(const std::vector ¶ms, const Type_Conversions_State &t_conversions) const override + Boxed_Value do_call(const Function_Params ¶ms, const Type_Conversions_State &t_conversions) const override { const Boxed_Value &bv = params[0]; if (bv.is_const()) @@ -839,22 +839,22 @@ namespace chaiscript { /// \brief Exception thrown in the case that a method dispatch fails /// because no matching function was found - /// + /// /// May be thrown due to an arity_error, a guard_error or a bad_boxed_cast /// exception class dispatch_error : public std::runtime_error { public: - dispatch_error(std::vector t_parameters, + dispatch_error(const Function_Params &t_parameters, std::vector t_functions) - : std::runtime_error("Error with function dispatch"), parameters(std::move(t_parameters)), functions(std::move(t_functions)) + : std::runtime_error("Error with function dispatch"), parameters(t_parameters.to_vector()), functions(std::move(t_functions)) { } - dispatch_error(std::vector t_parameters, + dispatch_error(const Function_Params &t_parameters, std::vector t_functions, const std::string &t_desc) - : std::runtime_error(t_desc), parameters(std::move(t_parameters)), functions(std::move(t_functions)) + : std::runtime_error(t_desc), parameters(t_parameters.to_vector()), functions(std::move(t_functions)) { } @@ -865,14 +865,14 @@ namespace chaiscript std::vector parameters; std::vector functions; }; - } + } namespace dispatch { - namespace detail + namespace detail { template - bool types_match_except_for_arithmetic(const FuncType &t_func, const std::vector &plist, + bool types_match_except_for_arithmetic(const FuncType &t_func, const Function_Params &plist, const Type_Conversions_State &t_conversions) noexcept { const std::vector &types = t_func->get_param_types(); @@ -891,7 +891,7 @@ namespace chaiscript } template - Boxed_Value dispatch_with_conversions(InItr begin, const InItr &end, const std::vector &plist, + Boxed_Value dispatch_with_conversions(InItr begin, const InItr &end, const Function_Params &plist, const Type_Conversions_State &t_conversions, const Funcs &t_funcs) { InItr matching_func(end); @@ -947,7 +947,7 @@ namespace chaiscript ); try { - return (*(matching_func->second))(newplist, t_conversions); + return (*(matching_func->second))(Function_Params{newplist}, t_conversions); } catch (const exception::bad_boxed_cast &) { //parameter failed to cast } catch (const exception::arity_error &) { @@ -966,7 +966,7 @@ namespace chaiscript /// function is found or throw dispatch_error if no matching function is found template Boxed_Value dispatch(const Funcs &funcs, - const std::vector &plist, const Type_Conversions_State &t_conversions) + const Function_Params &plist, const Type_Conversions_State &t_conversions) { std::vector> ordered_funcs; ordered_funcs.reserve(funcs.size()); diff --git a/include/chaiscript/dispatchkit/proxy_functions_detail.hpp b/include/chaiscript/dispatchkit/proxy_functions_detail.hpp index ed71663f..3799363f 100644 --- a/include/chaiscript/dispatchkit/proxy_functions_detail.hpp +++ b/include/chaiscript/dispatchkit/proxy_functions_detail.hpp @@ -21,6 +21,7 @@ #include "boxed_value.hpp" #include "handle_return.hpp" #include "type_info.hpp" +#include "function_params.hpp" namespace chaiscript { class Type_Conversions_State; @@ -77,7 +78,7 @@ namespace chaiscript */ template bool compare_types_cast(Ret (*)(Params...), - const std::vector ¶ms, const Type_Conversions_State &t_conversions) noexcept + const Function_Params ¶ms, const Type_Conversions_State &t_conversions) noexcept { try { std::vector::size_type i = 0; @@ -92,7 +93,7 @@ namespace chaiscript template Ret call_func(Ret (*)(Params...), std::index_sequence, const Callable &f, - [[maybe_unused]] const std::vector ¶ms, + [[maybe_unused]] const Function_Params ¶ms, [[maybe_unused]] const Type_Conversions_State &t_conversions) { return f(boxed_cast(params[I], &t_conversions)...); @@ -105,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 std::vector ¶ms, const Type_Conversions_State &t_conversions) + const 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); diff --git a/include/chaiscript/language/chaiscript_common.hpp b/include/chaiscript/language/chaiscript_common.hpp index dbbfc744..0527bb0c 100644 --- a/include/chaiscript/language/chaiscript_common.hpp +++ b/include/chaiscript/language/chaiscript_common.hpp @@ -95,7 +95,7 @@ namespace chaiscript Logical_And, Logical_Or, Reference, Switch, Case, Default, Noop, Class, Binary, Arg, Global_Decl, Constant, Compiled }; - enum class Operator_Precidence { Ternary_Cond, Logical_Or, + enum class Operator_Precedence { Ternary_Cond, Logical_Or, Logical_And, Bitwise_Or, Bitwise_Xor, Bitwise_And, Equality, Comparison, Shift, Addition, Multiplication, Prefix }; @@ -732,12 +732,7 @@ namespace chaiscript m_ds->pop_function_call(m_ds.stack_holder(), m_ds.conversion_saves()); } - void save_params(const std::vector &t_params) - { - m_ds->save_function_params(t_params); - } - - void save_params(std::initializer_list t_params) + void save_params(const Function_Params &t_params) { m_ds->save_function_params(t_params); } diff --git a/include/chaiscript/language/chaiscript_engine.hpp b/include/chaiscript/language/chaiscript_engine.hpp index 47cf43a3..6cf22a1d 100644 --- a/include/chaiscript/language/chaiscript_engine.hpp +++ b/include/chaiscript/language/chaiscript_engine.hpp @@ -145,7 +145,7 @@ namespace chaiscript m_engine.add( dispatch::make_dynamic_proxy_function( - [this](const std::vector &t_params) { + [this](const Function_Params &t_params) { return m_engine.call_exists(t_params); }) , "call_exists"); @@ -154,7 +154,7 @@ namespace chaiscript m_engine.add(fun( [=](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(t_params, s); + return t_fun(Function_Params{t_params}, s); }), "call"); diff --git a/include/chaiscript/language/chaiscript_eval.hpp b/include/chaiscript/language/chaiscript_eval.hpp index 42c18790..dcdf073e 100644 --- a/include/chaiscript/language/chaiscript_eval.hpp +++ b/include/chaiscript/language/chaiscript_eval.hpp @@ -51,7 +51,7 @@ namespace chaiscript { /// Helper function that will set up the scope around a function call, including handling the named function parameters template - static Boxed_Value eval_function(chaiscript::detail::Dispatch_Engine &t_ss, const AST_Node_Impl &t_node, const std::vector &t_param_names, const std::vector &t_vals, const std::map *t_locals=nullptr, bool has_this_capture = false) { + static Boxed_Value eval_function(chaiscript::detail::Dispatch_Engine &t_ss, const AST_Node_Impl &t_node, const std::vector &t_param_names, const Function_Params &t_vals, const std::map *t_locals=nullptr, bool has_this_capture = false) { chaiscript::detail::Dispatch_State state(t_ss); const Boxed_Value *thisobj = [&]() -> const Boxed_Value *{ @@ -183,8 +183,9 @@ namespace chaiscript } } else { chaiscript::eval::detail::Function_Push_Pop fpp(t_ss); - fpp.save_params({t_lhs, m_rhs}); - return t_ss->call_function(t_oper_string, m_loc, {t_lhs, m_rhs}, t_ss.conversions()); + std::array params{t_lhs, m_rhs}; + fpp.save_params(Function_Params{params}); + return t_ss->call_function(t_oper_string, m_loc, Function_Params{params}, t_ss.conversions()); } } catch(const exception::dispatch_error &e){ @@ -229,8 +230,9 @@ namespace chaiscript } } else { chaiscript::eval::detail::Function_Push_Pop fpp(t_ss); - fpp.save_params({t_lhs, t_rhs}); - return t_ss->call_function(t_oper_string, m_loc, {t_lhs, t_rhs}, t_ss.conversions()); + std::array params{t_lhs, t_rhs}; + fpp.save_params(Function_Params(params)); + return t_ss->call_function(t_oper_string, m_loc, Function_Params(params), t_ss.conversions()); } } catch(const exception::dispatch_error &e){ @@ -304,13 +306,13 @@ namespace chaiscript } if (Save_Params) { - fpp.save_params(params); + fpp.save_params(Function_Params{params}); } Boxed_Value fn(this->children[0]->eval(t_ss)); try { - return (*t_ss->boxed_cast(fn))(params, t_ss.conversions()); + return (*t_ss->boxed_cast(fn))(Function_Params{params}, t_ss.conversions()); } catch(const exception::dispatch_error &e){ throw exception::eval_error(std::string(e.what()) + " with function '" + this->children[0]->text + "'", e.parameters, e.functions, false, *t_ss); @@ -319,7 +321,7 @@ namespace chaiscript try { Const_Proxy_Function f = t_ss->boxed_cast(fn); // handle the case where there is only 1 function to try to call and dispatch fails on it - throw exception::eval_error("Error calling function '" + this->children[0]->text + "'", params, {f}, false, *t_ss); + throw exception::eval_error("Error calling function '" + this->children[0]->text + "'", params, make_vector(f), false, *t_ss); } catch (const exception::bad_boxed_cast &) { throw exception::eval_error("'" + this->children[0]->pretty_print() + "' does not evaluate to a function."); } @@ -425,25 +427,25 @@ namespace chaiscript Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override { chaiscript::eval::detail::Function_Push_Pop fpp(t_ss); - Boxed_Value rhs = this->children[1]->eval(t_ss); - Boxed_Value lhs = this->children[0]->eval(t_ss); - if (m_oper != Operators::Opers::invalid && lhs.get_type_info().is_arithmetic() && - rhs.get_type_info().is_arithmetic()) + std::array params{this->children[0]->eval(t_ss), this->children[1]->eval(t_ss)}; + + if (m_oper != Operators::Opers::invalid && params[0].get_type_info().is_arithmetic() && + params[0].get_type_info().is_arithmetic()) { try { - return Boxed_Number::do_oper(m_oper, lhs, rhs); + return Boxed_Number::do_oper(m_oper, params[0], params[1]); } catch (const std::exception &) { throw exception::eval_error("Error with unsupported arithmetic assignment operation"); } } else if (m_oper == Operators::Opers::assign) { - if (lhs.is_return_value()) { + if (params[0].is_return_value()) { throw exception::eval_error("Error, cannot assign to temporary value."); } try { - if (lhs.is_undef()) { + if (params[0].is_undef()) { if (!this->children.empty() && ((this->children[0]->identifier == AST_Node_Type::Reference) || (!this->children[0]->children.empty() @@ -454,20 +456,20 @@ namespace chaiscript { /// \todo This does not handle the case of an unassigned reference variable /// being assigned outside of its declaration - lhs.assign(rhs); - lhs.reset_return_value(); - return rhs; + params[0].assign(params[1]); + params[0].reset_return_value(); + return params[1]; } else { - if (!rhs.is_return_value()) + if (!params[1].is_return_value()) { - rhs = t_ss->call_function("clone", m_clone_loc, {rhs}, t_ss.conversions()); + params[1] = t_ss->call_function("clone", m_clone_loc, Function_Params{¶ms[0], std::end(params)}, t_ss.conversions()); } - rhs.reset_return_value(); + params[1].reset_return_value(); } } try { - return t_ss->call_function(this->text, m_loc, {std::move(lhs), rhs}, t_ss.conversions()); + return t_ss->call_function(this->text, m_loc, Function_Params{params}, t_ss.conversions()); } catch(const exception::dispatch_error &e){ throw exception::eval_error("Unable to find appropriate'" + this->text + "' operator.", e.parameters, e.functions, false, *t_ss); @@ -478,22 +480,22 @@ namespace chaiscript } } else if (this->text == ":=") { - if (lhs.is_undef() || Boxed_Value::type_match(lhs, rhs)) { - lhs.assign(rhs); - lhs.reset_return_value(); + if (params[0].is_undef() || Boxed_Value::type_match(params[0], params[1])) { + params[0].assign(params[1]); + params[0].reset_return_value(); } else { throw exception::eval_error("Mismatched types in equation"); } } else { try { - return t_ss->call_function(this->text, m_loc, {std::move(lhs), rhs}, t_ss.conversions()); + return t_ss->call_function(this->text, m_loc, Function_Params{params}, t_ss.conversions()); } catch(const exception::dispatch_error &e){ throw exception::eval_error("Unable to find appropriate'" + this->text + "' operator.", e.parameters, e.functions, false, *t_ss); } } - return rhs; + return params[1]; } private: @@ -550,11 +552,11 @@ namespace chaiscript Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override { chaiscript::eval::detail::Function_Push_Pop fpp(t_ss); - const std::vector params{this->children[0]->eval(t_ss), this->children[1]->eval(t_ss)}; + std::array params{this->children[0]->eval(t_ss), this->children[1]->eval(t_ss)}; try { - fpp.save_params(params); - return t_ss->call_function("[]", m_loc, params, t_ss.conversions()); + fpp.save_params(Function_Params{params}); + return t_ss->call_function("[]", m_loc, Function_Params{params}, t_ss.conversions()); } catch(const exception::dispatch_error &e){ throw exception::eval_error("Can not find appropriate array lookup operator '[]'.", e.parameters, e.functions, false, *t_ss ); @@ -579,7 +581,7 @@ namespace chaiscript Boxed_Value retval = this->children[0]->eval(t_ss); - std::vector params{retval}; + auto params = make_vector(retval); bool has_function_params = false; if (this->children[1]->children.size() > 1) { @@ -589,10 +591,10 @@ namespace chaiscript } } - fpp.save_params(params); + fpp.save_params(Function_Params{params}); try { - retval = t_ss->call_member(m_fun_name, m_loc, std::move(params), has_function_params, t_ss.conversions()); + retval = t_ss->call_member(m_fun_name, m_loc, Function_Params{params}, has_function_params, t_ss.conversions()); } catch(const exception::dispatch_error &e){ if (e.functions.empty()) @@ -608,7 +610,8 @@ namespace chaiscript if (this->children[1]->identifier == AST_Node_Type::Array_Call) { try { - retval = t_ss->call_function("[]", m_array_loc, {retval, this->children[1]->children[1]->eval(t_ss)}, t_ss.conversions()); + std::array p{retval, this->children[1]->children[1]->eval(t_ss)}; + retval = t_ss->call_function("[]", m_array_loc, Function_Params{p}, t_ss.conversions()); } catch(const exception::dispatch_error &e){ throw exception::eval_error("Can not find appropriate array lookup operator '[]'.", e.parameters, e.functions, true, *t_ss); @@ -657,7 +660,7 @@ namespace chaiscript return Boxed_Value( dispatch::make_dynamic_proxy_function( [engine, lambda_node = this->m_lambda_node, param_names = this->m_param_names, captures, - this_capture = this->m_this_capture] (const std::vector &t_params) + this_capture = this->m_this_capture] (const Function_Params &t_params) { return detail::eval_function(engine, *lambda_node, param_names, t_params, &captures, this_capture); }, @@ -771,7 +774,7 @@ namespace chaiscript std::shared_ptr guard; if (m_guard_node) { guard = dispatch::make_dynamic_proxy_function( - [engine, guardnode = m_guard_node, t_param_names](const std::vector &t_params) + [engine, guardnode = m_guard_node, t_param_names](const Function_Params &t_params) { return detail::eval_function(engine, *guardnode, t_param_names, t_params); }, @@ -782,7 +785,7 @@ namespace chaiscript const std::string & l_function_name = this->children[0]->text; t_ss->add( dispatch::make_dynamic_proxy_function( - [engine, func_node = m_body_node, t_param_names](const std::vector &t_params) + [engine, func_node = m_body_node, t_param_names](const Function_Params &t_params) { return detail::eval_function(engine, *func_node, t_param_names, t_params); }, @@ -873,7 +876,7 @@ namespace chaiscript }; const auto call_function = [&t_ss](const auto &t_funcs, const Boxed_Value &t_param) { - return dispatch::dispatch(*t_funcs, {t_param}, t_ss.conversions()); + return dispatch::dispatch(*t_funcs, Function_Params{t_param}, t_ss.conversions()); }; @@ -988,7 +991,8 @@ namespace chaiscript if (this->children[currentCase]->identifier == AST_Node_Type::Case) { //This is a little odd, but because want to see both the switch and the case simultaneously, I do a downcast here. try { - if (hasMatched || boxed_cast(t_ss->call_function("==", m_loc, {match_value, this->children[currentCase]->children[0]->eval(t_ss)}, t_ss.conversions()))) { + std::array p{match_value, this->children[currentCase]->children[0]->eval(t_ss)}; + if (hasMatched || boxed_cast(t_ss->call_function("==", m_loc, Function_Params{p}, t_ss.conversions()))) { this->children[currentCase]->eval(t_ss); hasMatched = true; } @@ -1057,7 +1061,7 @@ namespace chaiscript for (const auto &child : this->children[0]->children) { if (auto obj = child->eval(t_ss); !obj.is_return_value()) { - vec.push_back(t_ss->call_function("clone", m_loc, {obj}, t_ss.conversions())); + vec.push_back(t_ss->call_function("clone", m_loc, Function_Params{obj}, t_ss.conversions())); } else { vec.push_back(std::move(obj)); } @@ -1087,7 +1091,7 @@ namespace chaiscript for (const auto &child : this->children[0]->children) { auto obj = child->children[1]->eval(t_ss); if (!obj.is_return_value()) { - obj = t_ss->call_function("clone", m_loc, {obj}, t_ss.conversions()); + obj = t_ss->call_function("clone", m_loc, Function_Params{obj}, t_ss.conversions()); } retval[t_ss->boxed_cast(child->children[0]->eval(t_ss))] = std::move(obj); @@ -1174,8 +1178,8 @@ namespace chaiscript return Boxed_Number::do_oper(m_oper, bv); } else { chaiscript::eval::detail::Function_Push_Pop fpp(t_ss); - fpp.save_params({bv}); - return t_ss->call_function(this->text, m_loc, {std::move(bv)}, t_ss.conversions()); + fpp.save_params(Function_Params{bv}); + return t_ss->call_function(this->text, m_loc, Function_Params{bv}, t_ss.conversions()); } } catch (const exception::dispatch_error &e) { throw exception::eval_error("Error with prefix operator evaluation: '" + this->text + "'", e.parameters, e.functions, false, *t_ss); @@ -1240,9 +1244,12 @@ namespace chaiscript Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override{ try { - auto oper1 = this->children[0]->children[0]->children[0]->eval(t_ss); - auto oper2 = this->children[0]->children[0]->children[1]->eval(t_ss); - return t_ss->call_function("generate_range", m_loc, {oper1, oper2}, t_ss.conversions()); + std::array params{ + this->children[0]->children[0]->children[0]->eval(t_ss), + this->children[0]->children[0]->children[1]->eval(t_ss) + }; + + return t_ss->call_function("generate_range", m_loc, Function_Params{params}, t_ss.conversions()); } catch (const exception::dispatch_error &e) { throw exception::eval_error("Unable to generate range vector, while calling 'generate_range'", e.parameters, e.functions, false, *t_ss); @@ -1280,7 +1287,7 @@ namespace chaiscript if (dispatch::Param_Types( std::vector>{Arg_List_AST_Node::get_arg_type(*catch_block.children[0], t_ss)} - ).match(std::vector{t_except}, t_ss.conversions()).first) + ).match(Function_Params{t_except}, t_ss.conversions()).first) { t_ss.add_object(name, t_except); @@ -1410,7 +1417,7 @@ namespace chaiscript std::reference_wrapper engine(*t_ss); if (m_guard_node) { guard = dispatch::make_dynamic_proxy_function( - [engine, t_param_names, guardnode = m_guard_node](const std::vector &t_params) { + [engine, t_param_names, guardnode = m_guard_node](const Function_Params &t_params) { return chaiscript::eval::detail::eval_function(engine, *guardnode, t_param_names, t_params); }, static_cast(numparams), m_guard_node); @@ -1425,7 +1432,7 @@ namespace chaiscript t_ss->add( std::make_shared(class_name, dispatch::make_dynamic_proxy_function( - [engine, t_param_names, node = m_body_node](const std::vector &t_params) { + [engine, t_param_names, node = m_body_node](const Function_Params &t_params) { return chaiscript::eval::detail::eval_function(engine, *node, t_param_names, t_params); }, static_cast(numparams), m_body_node, param_types, guard @@ -1442,7 +1449,7 @@ namespace chaiscript t_ss->add( std::make_shared(class_name, dispatch::make_dynamic_proxy_function( - [engine, t_param_names, node = m_body_node](const std::vector &t_params) { + [engine, t_param_names, node = m_body_node](const Function_Params &t_params) { return chaiscript::eval::detail::eval_function(engine, *node, t_param_names, t_params); }, static_cast(numparams), m_body_node, param_types, guard), type), diff --git a/include/chaiscript/language/chaiscript_parser.hpp b/include/chaiscript/language/chaiscript_parser.hpp index ebcef83f..749ac9d3 100644 --- a/include/chaiscript/language/chaiscript_parser.hpp +++ b/include/chaiscript/language/chaiscript_parser.hpp @@ -263,20 +263,20 @@ namespace chaiscript }; - constexpr static std::array create_operators() noexcept { - std::array operators = { { - Operator_Precidence::Ternary_Cond, - Operator_Precidence::Logical_Or, - Operator_Precidence::Logical_And, - Operator_Precidence::Bitwise_Or, - Operator_Precidence::Bitwise_Xor, - Operator_Precidence::Bitwise_And, - Operator_Precidence::Equality, - Operator_Precidence::Comparison, - Operator_Precidence::Shift, - Operator_Precidence::Addition, - Operator_Precidence::Multiplication, - Operator_Precidence::Prefix + constexpr static std::array create_operators() noexcept { + std::array operators = { { + Operator_Precedence::Ternary_Cond, + Operator_Precedence::Logical_Or, + Operator_Precedence::Logical_And, + Operator_Precedence::Bitwise_Or, + Operator_Precedence::Bitwise_Xor, + Operator_Precedence::Bitwise_And, + Operator_Precedence::Equality, + Operator_Precedence::Comparison, + Operator_Precedence::Shift, + Operator_Precedence::Addition, + Operator_Precedence::Multiplication, + Operator_Precedence::Prefix } }; return operators; } @@ -2363,7 +2363,7 @@ namespace chaiscript bool retval = false; const auto prev_stack_top = m_match_stack.size(); - if (m_operators[t_precedence] != Operator_Precidence::Prefix) { + if (m_operators[t_precedence] != Operator_Precedence::Prefix) { if (Operator(t_precedence+1)) { retval = true; std::string oper; @@ -2375,7 +2375,7 @@ namespace chaiscript } switch (m_operators[t_precedence]) { - case(Operator_Precidence::Ternary_Cond) : + case(Operator_Precedence::Ternary_Cond) : if (Symbol(":")) { if (!Operator(t_precedence+1)) { throw exception::eval_error("Incomplete '" + oper + "' expression", @@ -2389,24 +2389,24 @@ namespace chaiscript } break; - case(Operator_Precidence::Addition) : - case(Operator_Precidence::Multiplication) : - case(Operator_Precidence::Shift) : - case(Operator_Precidence::Equality) : - case(Operator_Precidence::Bitwise_And) : - case(Operator_Precidence::Bitwise_Xor) : - case(Operator_Precidence::Bitwise_Or) : - case(Operator_Precidence::Comparison) : + case(Operator_Precedence::Addition) : + case(Operator_Precedence::Multiplication) : + case(Operator_Precedence::Shift) : + case(Operator_Precedence::Equality) : + case(Operator_Precedence::Bitwise_And) : + case(Operator_Precedence::Bitwise_Xor) : + case(Operator_Precedence::Bitwise_Or) : + case(Operator_Precedence::Comparison) : build_match>(prev_stack_top, oper); break; - case(Operator_Precidence::Logical_And) : + case(Operator_Precedence::Logical_And) : build_match>(prev_stack_top, oper); break; - case(Operator_Precidence::Logical_Or) : + case(Operator_Precedence::Logical_Or) : build_match>(prev_stack_top, oper); break; - case(Operator_Precidence::Prefix) : + case(Operator_Precedence::Prefix) : assert(false); // cannot reach here because of if() statement at the top break; diff --git a/include/chaiscript/utility/stack_vector.hpp b/include/chaiscript/utility/stack_vector.hpp new file mode 100644 index 00000000..706d276a --- /dev/null +++ b/include/chaiscript/utility/stack_vector.hpp @@ -0,0 +1,63 @@ +// This file is distributed under the BSD License. +// See "license.txt" for details. +// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) +// Copyright 2009-2017, Jason Turner (jason@emptycrate.com) +// http://www.chaiscript.com + +// This is an open source non-commercial project. Dear PVS-Studio, please check it. +// PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com + + +#ifndef CHAISCRIPT_STACK_VECTOR_HPP_ +#define CHAISCRIPT_STACK_VECTOR_HPP_ + +#include +#include +#include + + + +template +struct Stack_Vector +{ + constexpr static auto aligned_size = sizeof(T) + (sizeof(T) & std::alignment_of_v) > 0 ? std::alignment_of_v : 0; + + alignas(std::alignment_of_v) char data[aligned_size * MaxSize]; + + [[nodiscard]] T & operator[](const std::size_t idx) noexcept { + return *reinterpret_cast(&data + aligned_size * idx); + } + + [[nodiscard]] const T & operator[](const std::size_t idx) const noexcept { + return *reinterpret_cast(&data + aligned_size * idx); + } + + template + T& emplace_back(Param && ... param) { + auto *p = new(&(*this)[m_size++]) T(std::forward(param)...); + return *p; + }; + + auto size() const noexcept { + return m_size; + }; + + void pop_back() noexcept(std::is_nothrow_destructible_v) { + (*this)[m_size--].~T(); + } + + ~Stack_Vector() noexcept(std::is_nothrow_destructible_v) + { + auto loc = m_size - 1; + for (std::size_t pos = 0; pos < m_size; ++pos) { + (*this)[loc--].~T(); + } + } + + std::size_t m_size{0}; + +}; + +#endif CHAISCRIPT_STACK_VECTOR_HPP_ + + From b03b90dee602bde9316498fe98b1f4ea0ff760fc Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Fri, 17 Nov 2017 05:26:24 -0700 Subject: [PATCH 057/155] Fix bug introduced with Function_Params refactor --- include/chaiscript/language/chaiscript_eval.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/chaiscript/language/chaiscript_eval.hpp b/include/chaiscript/language/chaiscript_eval.hpp index dcdf073e..cac5d293 100644 --- a/include/chaiscript/language/chaiscript_eval.hpp +++ b/include/chaiscript/language/chaiscript_eval.hpp @@ -462,7 +462,7 @@ namespace chaiscript } else { if (!params[1].is_return_value()) { - params[1] = t_ss->call_function("clone", m_clone_loc, Function_Params{¶ms[0], std::end(params)}, t_ss.conversions()); + params[1] = t_ss->call_function("clone", m_clone_loc, Function_Params{¶ms[1], std::end(params)}, t_ss.conversions()); } params[1].reset_return_value(); } From a6d30baa27c6fbacb85d8f675baef9f809a6bf2d Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Fri, 17 Nov 2017 06:12:50 -0700 Subject: [PATCH 058/155] Apply some if constexpr action --- .../dispatchkit/function_call_detail.hpp | 104 +++++------------- .../chaiscript/dispatchkit/handle_return.hpp | 4 +- .../chaiscript/language/chaiscript_eval.hpp | 2 +- 3 files changed, 28 insertions(+), 82 deletions(-) diff --git a/include/chaiscript/dispatchkit/function_call_detail.hpp b/include/chaiscript/dispatchkit/function_call_detail.hpp index 5cd1932e..023947cc 100644 --- a/include/chaiscript/dispatchkit/function_call_detail.hpp +++ b/include/chaiscript/dispatchkit/function_call_detail.hpp @@ -29,66 +29,7 @@ namespace chaiscript { namespace detail { - /// Internal helper class for handling the return - /// value of a build_function_caller - template - struct Function_Caller_Ret - { - static Ret call(const std::vector &t_funcs, - const Function_Params ¶ms, const Type_Conversions_State *t_conversions) - { - if (t_conversions != nullptr) { - return boxed_cast(dispatch::dispatch(t_funcs, params, *t_conversions), t_conversions); - } else { - Type_Conversions conv; - Type_Conversions_State state(conv, conv.conversion_saves()); - return boxed_cast(dispatch::dispatch(t_funcs, params, state), t_conversions); - } - } - }; - - /** - * Specialization for arithmetic return types - */ - template - struct Function_Caller_Ret - { - static Ret call(const std::vector &t_funcs, - const Function_Params ¶ms, const Type_Conversions_State *t_conversions) - { - if (t_conversions != nullptr) { - return Boxed_Number(dispatch::dispatch(t_funcs, params, *t_conversions)).get_as(); - } else { - Type_Conversions conv; - Type_Conversions_State state(conv, conv.conversion_saves()); - return Boxed_Number(dispatch::dispatch(t_funcs, params, state)).get_as(); - } - } - }; - - - /** - * Specialization for void return types - */ - template<> - struct Function_Caller_Ret - { - static void call(const std::vector &t_funcs, - const Function_Params ¶ms, const Type_Conversions_State *t_conversions) - { - if (t_conversions != nullptr) { - dispatch::dispatch(t_funcs, params, *t_conversions); - } else { - Type_Conversions conv; - Type_Conversions_State state(conv, conv.conversion_saves()); - dispatch::dispatch(t_funcs, params, state); - } - } - }; - - /** - * used internally for unwrapping a function call's types - */ + /// used internally for unwrapping a function call's types template struct Build_Function_Caller_Helper { @@ -98,6 +39,17 @@ namespace chaiscript { } + Ret call(const 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(); + } else if constexpr (std::is_same_v) { + dispatch::dispatch(m_funcs, params, t_state); + } else { + return boxed_cast(dispatch::dispatch(m_funcs, params, t_state), &t_state); + } + } + template Ret operator()(P&& ... param) { @@ -105,32 +57,26 @@ namespace chaiscript if (m_conversions) { Type_Conversions_State state(*m_conversions, m_conversions->conversion_saves()); - return Function_Caller_Ret::value && !std::is_same::value>::call(m_funcs, Function_Params{params}, &state - ); + return call(Function_Params{params}, state); } else { - return Function_Caller_Ret::value && !std::is_same::value>::call(m_funcs, Function_Params{params}, nullptr - ); + Type_Conversions conv; + Type_Conversions_State state(conv, conv.conversion_saves()); + return call(Function_Params{params}, state); } } - template - static auto box(Q&& q) -> typename std::enable_if::value&&!std::is_same::type>::type>::value, Boxed_Value>::type - { - return Boxed_Value(std::ref(std::forward(q))); - } template - static auto box(Q&& q) -> typename std::enable_if::value&&!std::is_same::type>::type>::value, Boxed_Value>::type - { - return Boxed_Value(std::forward(q)); - } - - template - static Boxed_Value box(Boxed_Value bv) noexcept - { - return bv; - } + static Boxed_Value box(Q &&q) { + if constexpr (std::is_same_v>) { + return std::forward(q); + } else if constexpr (std::is_reference_v

) { + return Boxed_Value(std::ref(std::forward(q))); + } else { + return Boxed_Value(std::forward(q)); + } + } std::vector m_funcs; diff --git a/include/chaiscript/dispatchkit/handle_return.hpp b/include/chaiscript/dispatchkit/handle_return.hpp index 4dc381d4..e06b44df 100644 --- a/include/chaiscript/dispatchkit/handle_return.hpp +++ b/include/chaiscript/dispatchkit/handle_return.hpp @@ -36,14 +36,14 @@ namespace chaiscript struct Handle_Return { template::type>::value>::type> + typename = std::enable_if_t>>> static Boxed_Value handle(T r) { return Boxed_Value(std::move(r), true); } template::type>::value>::type> + typename = std::enable_if_t>>> static Boxed_Value handle(T &&r) { return Boxed_Value(std::make_shared(std::forward(r)), true); diff --git a/include/chaiscript/language/chaiscript_eval.hpp b/include/chaiscript/language/chaiscript_eval.hpp index cac5d293..f368d62f 100644 --- a/include/chaiscript/language/chaiscript_eval.hpp +++ b/include/chaiscript/language/chaiscript_eval.hpp @@ -920,6 +920,7 @@ namespace chaiscript try { this->children[2]->eval(t_ss); } catch (detail::Continue_Loop &) { + // continue statement hit } call_function(pop_front_funcs, range_obj); } @@ -1456,7 +1457,6 @@ namespace chaiscript function_name); } } catch (const exception::name_conflict_error &e) { - std::cout << "Method!!" << std::endl; throw exception::eval_error("Method redefined '" + e.name() + "'"); } return void_var(); From d59350d356df3e9b5d9a83b61beaac4c0c629122 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Sat, 18 Nov 2017 18:42:45 -0700 Subject: [PATCH 059/155] Various cleanups --- include/chaiscript/dispatchkit/bootstrap.hpp | 4 ++-- include/chaiscript/dispatchkit/boxed_value.hpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/chaiscript/dispatchkit/bootstrap.hpp b/include/chaiscript/dispatchkit/bootstrap.hpp index 9a94d104..983ae64c 100644 --- a/include/chaiscript/dispatchkit/bootstrap.hpp +++ b/include/chaiscript/dispatchkit/bootstrap.hpp @@ -151,7 +151,7 @@ namespace chaiscript /// Specific version of shared_ptr_clone just for Proxy_Functions template - std::shared_ptr::type> shared_ptr_unconst_clone(const std::shared_ptr::type> &p) + std::shared_ptr> shared_ptr_unconst_clone(const std::shared_ptr> &p) { return std::const_pointer_cast::type>(p); } @@ -483,7 +483,7 @@ namespace chaiscript opers_arithmetic_pod(m); - + m.add(fun(&Build_Info::version_major), "version_major"); m.add(fun(&Build_Info::version_minor), "version_minor"); m.add(fun(&Build_Info::version_patch), "version_patch"); diff --git a/include/chaiscript/dispatchkit/boxed_value.hpp b/include/chaiscript/dispatchkit/boxed_value.hpp index 3bef5851..1fb72722 100644 --- a/include/chaiscript/dispatchkit/boxed_value.hpp +++ b/include/chaiscript/dispatchkit/boxed_value.hpp @@ -194,7 +194,7 @@ namespace chaiscript public: /// Basic Boxed_Value constructor template::type>::value>::type> + typename = std::enable_if_t>>> explicit Boxed_Value(T &&t, bool t_return_value = false) : m_data(Object_Data::get(std::forward(t), t_return_value)) { From 92ae85c3e822cfc530a7c865e660e81d2da9a4a2 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Sat, 18 Nov 2017 19:08:14 -0700 Subject: [PATCH 060/155] Remove guards from catch blocks --- .../chaiscript/language/chaiscript_eval.hpp | 21 ++---------- .../chaiscript/language/chaiscript_parser.hpp | 5 --- unittests/3.x/exception_guards.chai | 34 ------------------- unittests/exception_guards.chai | 34 ------------------- unittests/exception_typed_2.chai | 34 ------------------- 5 files changed, 2 insertions(+), 126 deletions(-) delete mode 100644 unittests/3.x/exception_guards.chai delete mode 100644 unittests/exception_guards.chai delete mode 100644 unittests/exception_typed_2.chai diff --git a/include/chaiscript/language/chaiscript_eval.hpp b/include/chaiscript/language/chaiscript_eval.hpp index f368d62f..a99c4ebb 100644 --- a/include/chaiscript/language/chaiscript_eval.hpp +++ b/include/chaiscript/language/chaiscript_eval.hpp @@ -1280,7 +1280,7 @@ namespace chaiscript auto &catch_block = *this->children[i]; if (catch_block.children.size() == 1) { - //No variable capture, no guards + //No variable capture retval = catch_block.children[0]->eval(t_ss); break; } else if (catch_block.children.size() == 2 || catch_block.children.size() == 3) { @@ -1293,27 +1293,10 @@ namespace chaiscript t_ss.add_object(name, t_except); if (catch_block.children.size() == 2) { - //Variable capture, no guards + //Variable capture retval = catch_block.children[1]->eval(t_ss); break; } - else if (catch_block.children.size() == 3) { - //Variable capture, guards - - bool guard = false; - try { - guard = boxed_cast(catch_block.children[1]->eval(t_ss)); - } catch (const exception::bad_boxed_cast &) { - if (this->children.back()->identifier == AST_Node_Type::Finally) { - this->children.back()->children[0]->eval(t_ss); - } - throw exception::eval_error("Guard condition not boolean"); - } - if (guard) { - retval = catch_block.children[2]->eval(t_ss); - break; - } - } } } else { diff --git a/include/chaiscript/language/chaiscript_parser.hpp b/include/chaiscript/language/chaiscript_parser.hpp index 749ac9d3..77386c3e 100644 --- a/include/chaiscript/language/chaiscript_parser.hpp +++ b/include/chaiscript/language/chaiscript_parser.hpp @@ -1715,11 +1715,6 @@ namespace chaiscript if (!(Arg() && Char(')'))) { throw exception::eval_error("Incomplete 'catch' expression", File_Position(m_position.line, m_position.col), *m_filename); } - if (Char(':')) { - if (!Operator()) { - throw exception::eval_error("Missing guard expression for catch", File_Position(m_position.line, m_position.col), *m_filename); - } - } } while (Eol()) {} diff --git a/unittests/3.x/exception_guards.chai b/unittests/3.x/exception_guards.chai deleted file mode 100644 index 99cd9018..00000000 --- a/unittests/3.x/exception_guards.chai +++ /dev/null @@ -1,34 +0,0 @@ -var results = []; - -for (var i = 2; i < 6; ++i) { - try { - throw(i) - } - catch(e) : e < 2 { - results.push_back("c1: " + e.to_string()); - } - catch(e) : e < 4 { - results.push_back("c2: " + e.to_string()); - } - catch(e) { - results.push_back("c3: " + e.to_string()); - } - catch { - // Should never get called - assert_equal(false, true) - } -} - -try { - throw(3) -} -catch(e) : e < 3 -{ - // Should never get called - assert_equal(false, true); -} -catch { - results.push_back("defaultcatch"); -} - -assert_equal(["c2: 2", "c2: 3", "c3: 4", "c3: 5", "defaultcatch"], results); diff --git a/unittests/exception_guards.chai b/unittests/exception_guards.chai deleted file mode 100644 index 12792985..00000000 --- a/unittests/exception_guards.chai +++ /dev/null @@ -1,34 +0,0 @@ -auto results = []; - -for (auto i = 2; i < 6; ++i) { - try { - throw(i) - } - catch(e) : e < 2 { - results.push_back("c1: " + e.to_string()); - } - catch(e) : e < 4 { - results.push_back("c2: " + e.to_string()); - } - catch(e) { - results.push_back("c3: " + e.to_string()); - } - catch { - // Should never get called - assert_equal(false, true) - } -} - -try { - throw(3) -} -catch(e) : e < 3 -{ - // Should never get called - assert_equal(false, true); -} -catch { - results.push_back("defaultcatch"); -} - -assert_equal(["c2: 2", "c2: 3", "c3: 4", "c3: 5", "defaultcatch"], results); diff --git a/unittests/exception_typed_2.chai b/unittests/exception_typed_2.chai deleted file mode 100644 index cb294c78..00000000 --- a/unittests/exception_typed_2.chai +++ /dev/null @@ -1,34 +0,0 @@ -auto results = []; - -for (auto i = 2; i < 6; ++i) { - try { - throw(i) - } - catch(int e) : e < 2 { - results.push_back("c1: " + e.to_string()); - } - catch(int e) : e < 4 { - results.push_back("c2: " + e.to_string()); - } - catch(e) { - results.push_back("c3: " + e.to_string()); - } - catch { - // Should never get called - assert_equal(false, true) - } -} - -try { - throw(3) -} -catch(int e) : e < 3 -{ - // Should never get called - assert_equal(false, true); -} -catch { - results.push_back("defaultcatch"); -} - -assert_equal(["c2: 2", "c2: 3", "c3: 4", "c3: 5", "defaultcatch"], results); From c6021f3e6183aad8ccad8cd0ad702e5b1b1eb611 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Sun, 19 Nov 2017 06:20:27 -0700 Subject: [PATCH 061/155] Bug fix from Function_Params refactor --- include/chaiscript/dispatchkit/any.hpp | 4 ++-- include/chaiscript/dispatchkit/dispatchkit.hpp | 4 ++-- include/chaiscript/language/chaiscript_eval.hpp | 16 +++++++++++++--- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/include/chaiscript/dispatchkit/any.hpp b/include/chaiscript/dispatchkit/any.hpp index a9e31594..f8f94f26 100644 --- a/include/chaiscript/dispatchkit/any.hpp +++ b/include/chaiscript/dispatchkit/any.hpp @@ -84,7 +84,7 @@ namespace chaiscript { // construct/copy/destruct constexpr Any() noexcept = default; Any(Any &&) noexcept = default; - Any &operator=(Any &&t_any) noexcept = default; + Any &operator=(Any &&t_any) = default; Any(const Any &t_any) : m_data(t_any.empty() ? nullptr : t_any.m_data->clone()) @@ -93,7 +93,7 @@ namespace chaiscript { template>>> - explicit Any(ValueType &&t_value) noexcept(is_nothrow_forward_constructible_v>) + explicit Any(ValueType &&t_value) : m_data(std::make_unique>>(std::forward(t_value))) { } diff --git a/include/chaiscript/dispatchkit/dispatchkit.hpp b/include/chaiscript/dispatchkit/dispatchkit.hpp index 4f338cee..6e39aff4 100644 --- a/include/chaiscript/dispatchkit/dispatchkit.hpp +++ b/include/chaiscript/dispatchkit/dispatchkit.hpp @@ -1053,7 +1053,7 @@ namespace chaiscript tmp_params.insert(tmp_params.begin() + 1, var(t_name)); return do_attribute_call(2, Function_Params(tmp_params), functions, t_conversions); } else { - std::array p{params[0], var(t_name), var(std::vector(params.begin()+1, params.end()))}; + std::array p{params[0], var(t_name), var(std::vector(params.begin()+1, params.end()))}; return dispatch::dispatch(functions, Function_Params{p}, t_conversions); } } catch (const dispatch::option_explicit_set &e) { @@ -1077,7 +1077,7 @@ namespace chaiscript - Boxed_Value call_function(const std::string_view &t_name, std::atomic_uint_fast32_t &t_loc, Function_Params params, + Boxed_Value call_function(const std::string_view &t_name, std::atomic_uint_fast32_t &t_loc, const Function_Params ¶ms, const Type_Conversions_State &t_conversions) const { uint_fast32_t loc = t_loc; diff --git a/include/chaiscript/language/chaiscript_eval.hpp b/include/chaiscript/language/chaiscript_eval.hpp index a99c4ebb..781615c9 100644 --- a/include/chaiscript/language/chaiscript_eval.hpp +++ b/include/chaiscript/language/chaiscript_eval.hpp @@ -428,10 +428,20 @@ namespace chaiscript Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override { chaiscript::eval::detail::Function_Push_Pop fpp(t_ss); - std::array params{this->children[0]->eval(t_ss), this->children[1]->eval(t_ss)}; + auto params = [&](){ + // The RHS *must* be evaluated before the LHS + // consider `var range = range(x)` + // if we declare the variable in scope first, then the name lookup fails + // for the RHS + auto rhs = this->children[1]->eval(t_ss); + auto lhs = this->children[0]->eval(t_ss); + std::array p{std::move(lhs), std::move(rhs)}; + return p; + }(); + if (m_oper != Operators::Opers::invalid && params[0].get_type_info().is_arithmetic() && - params[0].get_type_info().is_arithmetic()) + params[1].get_type_info().is_arithmetic()) { try { return Boxed_Number::do_oper(m_oper, params[0], params[1]); @@ -452,7 +462,7 @@ namespace chaiscript && this->children[0]->children[0]->identifier == AST_Node_Type::Reference) ) ) - + { /// \todo This does not handle the case of an unassigned reference variable /// being assigned outside of its declaration From a1772a055b6995752cb6c8118187ebf156ce82e2 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Sun, 19 Nov 2017 06:25:30 -0700 Subject: [PATCH 062/155] Remove some `std::endl` usage --- samples/fun_call_performance.cpp | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/samples/fun_call_performance.cpp b/samples/fun_call_performance.cpp index 31fa606c..5b8478b9 100644 --- a/samples/fun_call_performance.cpp +++ b/samples/fun_call_performance.cpp @@ -145,20 +145,20 @@ std::vector default_search_paths() void help(int n) { if (n >= 0) { - std::cout << "ChaiScript evaluator. To evaluate an expression, type it and press ." << std::endl; - std::cout << "Additionally, you can inspect the runtime system using:" << std::endl; - std::cout << " dump_system() - outputs all functions registered to the system" << std::endl; - std::cout << " dump_object(x) - dumps information about the given symbol" << std::endl; + std::cout << "ChaiScript evaluator. To evaluate an expression, type it and press .\n"; + std::cout << "Additionally, you can inspect the runtime system using:\n"; + std::cout << " dump_system() - outputs all functions registered to the system\n"; + std::cout << " dump_object(x) - dumps information about the given symbol\n"; } else { - std::cout << "usage : chai [option]+" << std::endl; - std::cout << "option:" << std::endl; - std::cout << " -h | --help" << std::endl; - std::cout << " -i | --interactive" << std::endl; - std::cout << " -c | --command cmd" << std::endl; - std::cout << " -v | --version" << std::endl; - std::cout << " - --stdin" << std::endl; - std::cout << " filepath" << std::endl; + std::cout << "usage : chai [option]+\n"; + std::cout << "option:\n"; + std::cout << " -h | --help\n"; + std::cout << " -i | --interactive\n"; + std::cout << " -c | --command cmd\n"; + std::cout << " -v | --version\n"; + std::cout << " - --stdin\n"; + std::cout << " filepath\n"; } } @@ -244,7 +244,7 @@ void interactive(chaiscript::ChaiScript& chai) //Then, we try to print the result of the evaluation to the user if (!val.get_type_info().bare_equal(chaiscript::user_type())) { try { - std::cout << chai.eval >("to_string")(val) << std::endl; + std::cout << chai.eval >("to_string")(val) << '\n'; } catch (...) {} //If we can't, do nothing } @@ -254,7 +254,7 @@ void interactive(chaiscript::ChaiScript& chai) if (ee.call_stack.size() > 0) { std::cout << "during evaluation at (" << ee.call_stack[0].start().line << ", " << ee.call_stack[0].start().column << ")"; } - std::cout << std::endl; + std::cout << '\n'; } catch (const std::exception &e) { std::cout << e.what(); From 61bce309018a04d7c05d37bb0de22f9afac6307d Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Tue, 21 Nov 2017 06:30:19 -0700 Subject: [PATCH 063/155] Unused code removal --- .../chaiscript/dispatchkit/bootstrap_stl.hpp | 145 +----------------- 1 file changed, 2 insertions(+), 143 deletions(-) diff --git a/include/chaiscript/dispatchkit/bootstrap_stl.hpp b/include/chaiscript/dispatchkit/bootstrap_stl.hpp index df25c9ec..684096d4 100644 --- a/include/chaiscript/dispatchkit/bootstrap_stl.hpp +++ b/include/chaiscript/dispatchkit/bootstrap_stl.hpp @@ -178,13 +178,6 @@ namespace chaiscript detail::input_range_type_impl >(type,m); detail::input_range_type_impl >("Const_" + type,m); } - template - ModulePtr input_range_type(const std::string &type) - { - auto m = std::make_shared(); - input_range_type(type, *m); - return m; - } /// Add random_access_container concept to the given ContainerType @@ -197,7 +190,7 @@ namespace chaiscript m.add( fun( [](ContainerType &c, int index) -> typename ContainerType::reference { - /// \todo we are prefering to keep the key as 'int' to avoid runtime conversions + /// \todo we are preferring to keep the key as 'int' to avoid runtime conversions /// during dispatch. reevaluate return c.at(static_cast(index)); }), "[]"); @@ -205,19 +198,11 @@ namespace chaiscript m.add( fun( [](const ContainerType &c, int index) -> typename ContainerType::const_reference { - /// \todo we are prefering to keep the key as 'int' to avoid runtime conversions + /// \todo we are preferring to keep the key as 'int' to avoid runtime conversions /// during dispatch. reevaluate return c.at(static_cast(index)); }), "[]"); } - template - ModulePtr random_access_container_type(const std::string &type) - { - auto m = std::make_shared(); - random_access_container_type(type, *m); - return m; - } - /// Add assignable concept to the given ContainerType @@ -228,14 +213,6 @@ namespace chaiscript copy_constructor(type, m); operators::assign(m); } - template - ModulePtr assignable_type(const std::string &type) - { - auto m = std::make_shared(); - assignable_type(type, *m); - return m; - } - /// Add container resize concept to the given ContainerType /// http://www.cplusplus.com/reference/stl/ @@ -245,14 +222,6 @@ namespace chaiscript m.add(fun([](ContainerType *a, typename ContainerType::size_type n, const typename ContainerType::value_type& val) { return a->resize(n, val); } ), "resize"); m.add(fun([](ContainerType *a, typename ContainerType::size_type n) { return a->resize(n); } ), "resize"); } - template - ModulePtr resizable_type(const std::string &type) - { - auto m = std::make_shared(); - resizable_type(type, *m); - return m; - } - /// Add container reserve concept to the given ContainerType /// http://www.cplusplus.com/reference/stl/ @@ -262,14 +231,6 @@ namespace chaiscript m.add(fun([](ContainerType *a, typename ContainerType::size_type n) { return a->reserve(n); } ), "reserve"); m.add(fun([](const ContainerType *a) { return a->capacity(); } ), "capacity"); } - template - ModulePtr reservable_type(const std::string &type) - { - auto m = std::make_shared(); - reservable_type(type, *m); - return m; - } - /// Add container concept to the given ContainerType /// http://www.sgi.com/tech/stl/Container.html @@ -280,14 +241,6 @@ namespace chaiscript m.add(fun([](const ContainerType *a) { return a->empty(); } ), "empty"); m.add(fun([](ContainerType *a) { a->clear(); } ), "clear"); } - template - ModulePtr container_type(const std::string& type) - { - auto m = std::make_shared(); - container_type(type, *m); - return m; - } - /// Add default constructable concept to the given Type /// http://www.sgi.com/tech/stl/DefaultConstructible.html @@ -296,15 +249,6 @@ namespace chaiscript { m.add(constructor(), type); } - template - ModulePtr default_constructible_type(const std::string& type) - { - auto m = std::make_shared(); - default_constructible_type(type, *m); - return m; - } - - /// Add sequence concept to the given ContainerType /// http://www.sgi.com/tech/stl/Sequence.html @@ -322,13 +266,6 @@ namespace chaiscript m.add(fun(&detail::erase_at), "erase_at"); } - template - ModulePtr sequence_type(const std::string &type) - { - auto m = std::make_shared(); - sequence_type(type, *m); - return m; - } /// Add back insertion sequence concept to the given ContainerType /// http://www.sgi.com/tech/stl/BackInsertionSequence.html @@ -380,14 +317,6 @@ namespace chaiscript m.add(fun(&ContainerType::pop_back), "pop_back"); } - template - ModulePtr back_insertion_sequence_type(const std::string &type) - { - auto m = std::make_shared(); - back_insertion_sequence_type(type, *m); - return m; - } - /// Front insertion sequence @@ -442,14 +371,6 @@ namespace chaiscript m.add(fun(static_cast(&ContainerType::pop_front)), "pop_front"); } - template - ModulePtr front_insertion_sequence_type(const std::string &type) - { - auto m = std::make_shared(); - front_insertion_sequence_type(type, *m); - return m; - } - /// bootstrap a given PairType /// http://www.sgi.com/tech/stl/pair.html @@ -464,14 +385,6 @@ namespace chaiscript basic_constructors(type, m); m.add(constructor(), type); } - template - ModulePtr pair_type(const std::string &type) - { - auto m = std::make_shared(); - pair_type(type, *m); - return m; - } - /// Add pair associative container concept to the given ContainerType @@ -482,14 +395,6 @@ namespace chaiscript { pair_type(type + "_Pair", m); } - template - ModulePtr pair_associative_container_type(const std::string &type) - { - auto m = std::make_shared(); - pair_associative_container_type(type, *m); - return m; - } - /// Add unique associative container concept to the given ContainerType /// http://www.sgi.com/tech/stl/UniqueAssociativeContainer.html @@ -513,14 +418,6 @@ namespace chaiscript } }()); } - template - ModulePtr unique_associative_container_type(const std::string &type) - { - auto m = std::make_shared(); - unique_associative_container_type(type, *m); - return m; - } - /// Add a MapType container /// http://www.sgi.com/tech/stl/Map.html @@ -568,14 +465,6 @@ namespace chaiscript pair_associative_container_type(type, m); input_range_type(type, m); } - template - ModulePtr map_type(const std::string &type) - { - auto m = std::make_shared(); - map_type(type, *m); - return m; - } - /// http://www.sgi.com/tech/stl/List.html template @@ -592,14 +481,6 @@ namespace chaiscript assignable_type(type, m); input_range_type(type, m); } - template - ModulePtr list_type(const std::string &type) - { - auto m = std::make_shared(); - list_type(type, m); - return m; - } - /// Create a vector type with associated concepts /// http://www.sgi.com/tech/stl/Vector.html @@ -665,13 +546,6 @@ namespace chaiscript ); } } - template - ModulePtr vector_type(const std::string &type) - { - auto m = std::make_shared(); - vector_type(type, *m); - return m; - } /// Add a String container /// http://www.sgi.com/tech/stl/basic_string.html @@ -715,14 +589,6 @@ namespace chaiscript m.add(fun([](const String *s) { return s->data(); } ), "data"); m.add(fun([](const String *s, size_t pos, size_t len) { return s->substr(pos, len); } ), "substr"); } - template - ModulePtr string_type(const std::string &type) - { - auto m = std::make_shared(); - string_type(type, *m); - return m; - } - /// Add a MapType container @@ -736,13 +602,6 @@ namespace chaiscript m.add(fun(&FutureType::get), "get"); m.add(fun(&FutureType::wait), "wait"); } - template - ModulePtr future_type(const std::string &type) - { - auto m = std::make_shared(); - future_type(type, *m); - return m; - } } } } From fe405a781c6c6b38d7dbf57efdf6d2d643094256 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Tue, 21 Nov 2017 16:10:13 -0700 Subject: [PATCH 064/155] Revert "Merge branch 'typed_function_ordering' into c++17" This reverts commit 5d5a126bb15b8490ebdb92a8f0a8b2b990d8a067, reversing changes made to dd912822a7979aad101042c62478c2441ae21d1a. --- .../chaiscript/dispatchkit/dispatchkit.hpp | 231 ++++++------------ .../dispatchkit/dynamic_object_detail.hpp | 27 +- .../dispatchkit/proxy_functions.hpp | 38 +-- unittests/compiled_tests.cpp | 4 +- 4 files changed, 82 insertions(+), 218 deletions(-) diff --git a/include/chaiscript/dispatchkit/dispatchkit.hpp b/include/chaiscript/dispatchkit/dispatchkit.hpp index 930bff61..f8bbf45f 100644 --- a/include/chaiscript/dispatchkit/dispatchkit.hpp +++ b/include/chaiscript/dispatchkit/dispatchkit.hpp @@ -1104,30 +1104,22 @@ namespace chaiscript { const auto params = f.second->get_param_types(); - std::vector> typed_params; - - auto func(std::dynamic_pointer_cast(f.second)); - if (func) { - typed_params = func->get_dynamic_param_types().types(); - } - dump_type(params.front()); std::cout << " " << f.first << "("; - for (size_t i = 1; i < params.size(); ++i) + for (auto itr = params.begin() + 1; + itr != params.end(); + ) { - if (!typed_params.empty() && !typed_params[i-1].first.empty()) { - std::cout << typed_params[i-1].first; - } else { - dump_type(params[i]); - } + dump_type(*itr); + ++itr; - if (i != params.size() - 1) { + if (itr != params.end()) + { std::cout << ", "; } } - std::cout << ") \n"; } @@ -1321,157 +1313,88 @@ namespace chaiscript return m_state.m_functions; } - - static std::vector param_types(const Proxy_Function &t_f) + static bool function_less_than(const Proxy_Function &lhs, const Proxy_Function &rhs) noexcept { - assert(t_f); - return t_f->get_param_types(); - } - static std::vector> param_types(const std::shared_ptr &t_f) - { - assert(t_f); - const auto types = t_f->get_dynamic_param_types().types(); - std::vector> ret(1); - ret.insert(ret.end(), types.begin(), types.end()); - return ret; - } + auto dynamic_lhs(std::dynamic_pointer_cast(lhs)); + auto dynamic_rhs(std::dynamic_pointer_cast(rhs)); - static Type_Info type_info(const std::pair &t_ti) - { - return t_ti.second; - } - - static Type_Info type_info(const Type_Info &t_ti) - { - return t_ti; - } - - static std::string dynamic_type_name(const std::pair &t_ti) - { - return t_ti.first.empty()?t_ti.second.name():t_ti.first; - } - - static std::string dynamic_type_name(const Type_Info &ti) - { - return ti.name(); - } - - - template - static bool params_less_than(const LHS &t_lhs, const RHS &t_rhs) + if (dynamic_lhs && dynamic_rhs) { - assert(t_lhs); - assert(t_rhs); - const auto lhsparamtypes = param_types(t_lhs); - const auto rhsparamtypes = param_types(t_rhs); - - const auto lhssize = lhsparamtypes.size(); - const auto rhssize = rhsparamtypes.size(); - - constexpr auto boxed_type = user_type(); - constexpr auto boxed_pod_type = user_type(); - constexpr auto dynamic_type = user_type(); - - for (size_t i = 1; i < lhssize && i < rhssize; ++i) + if (dynamic_lhs->get_guard()) { - const Type_Info lt = type_info(lhsparamtypes[i]); - const Type_Info rt = type_info(rhsparamtypes[i]); - const std::string ln = dynamic_type_name(lhsparamtypes[i]); - const std::string rn = dynamic_type_name(rhsparamtypes[i]); - - if ( (lt.bare_equal(dynamic_type) || lt.is_undef()) - && (rt.bare_equal(dynamic_type) || rt.is_undef())) - { - - if (!ln.empty() && rn.empty()) { - return true; - } else if (ln.empty() && !rn.empty()) { - return false; - } else if (!ln.empty() && !rn.empty()) { - if (ln < rn) { - return true; - } else if (rn < ln) { - return false; - } - - // the remaining cases are handled by the is_const rules below - } - } - - if (lt.bare_equal(rt) && lt.is_const() == rt.is_const()) - { - continue; // The first two types are essentially the same, next iteration - } - - - // const is after non-const for the same type - if (lt.bare_equal(rt) && lt.is_const() && !rt.is_const()) - { - return false; - } - - if (lt.bare_equal(rt) && !lt.is_const()) - { - return true; - } - - // boxed_values are sorted last - if (lt.bare_equal(boxed_type)) - { - return false; - } - - if (rt.bare_equal(boxed_type)) - { - return true; - } - - if (lt.bare_equal(boxed_pod_type)) - { - return false; - } - - if (rt.bare_equal(boxed_pod_type)) - { - return true; - } - - // otherwise, we want to sort by typeid - return lt < rt; - } - - // if everything else checks out, sort on guard - // - auto dynamic_lhs(std::dynamic_pointer_cast(t_lhs)); - auto dynamic_rhs(std::dynamic_pointer_cast(t_rhs)); - - if (dynamic_lhs && dynamic_rhs) { - if (dynamic_lhs->get_guard() && !dynamic_rhs->get_guard()) { - return true; - } else if (dynamic_rhs->get_guard()) { - return false; - } + return dynamic_rhs->get_guard() ? false : true; + } else { + return false; } + } + if (dynamic_lhs && !dynamic_rhs) + { return false; } - static bool function_less_than(const Proxy_Function &lhs, const Proxy_Function &rhs) noexcept - { - auto dynamic_lhs(std::dynamic_pointer_cast(lhs)); - auto dynamic_rhs(std::dynamic_pointer_cast(rhs)); - - if (dynamic_lhs && dynamic_rhs) + if (!dynamic_lhs && dynamic_rhs) { - return params_less_than(dynamic_lhs, dynamic_rhs); - } else if (dynamic_lhs) { - return params_less_than(dynamic_lhs, rhs); - } else if (dynamic_rhs) { - return params_less_than(lhs, dynamic_rhs); - } else { - return params_less_than(lhs, rhs); + return true; } + + const auto &lhsparamtypes = lhs->get_param_types(); + const auto &rhsparamtypes = rhs->get_param_types(); + + 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(); + + for (size_t i = 1; i < lhssize && i < rhssize; ++i) + { + const Type_Info < = lhsparamtypes[i]; + const Type_Info &rt = rhsparamtypes[i]; + + if (lt.bare_equal(rt) && lt.is_const() == rt.is_const()) + { + continue; // The first two types are essentially the same, next iteration + } + + // const is after non-const for the same type + if (lt.bare_equal(rt) && lt.is_const() && !rt.is_const()) + { + return false; + } + + if (lt.bare_equal(rt) && !lt.is_const()) + { + return true; + } + + // boxed_values are sorted last + if (lt.bare_equal(boxed_type)) + { + return false; + } + + if (rt.bare_equal(boxed_type)) + { + return true; + } + + if (lt.bare_equal(boxed_pod_type)) + { + return false; + } + + if (rt.bare_equal(boxed_pod_type)) + { + return true; + } + + // otherwise, we want to sort by typeid + return lt < rt; + } + + return false; } diff --git a/include/chaiscript/dispatchkit/dynamic_object_detail.hpp b/include/chaiscript/dispatchkit/dynamic_object_detail.hpp index 7c0364d8..d9e3a15a 100644 --- a/include/chaiscript/dispatchkit/dynamic_object_detail.hpp +++ b/include/chaiscript/dispatchkit/dynamic_object_detail.hpp @@ -39,7 +39,7 @@ namespace chaiscript /// A Proxy_Function implementation designed for calling a function /// that is automatically guarded based on the first param based on the /// param's type name - class Dynamic_Object_Function : public Proxy_Function_Base, public Dynamic_Function_Interface + class Dynamic_Object_Function final : public Proxy_Function_Base { public: Dynamic_Object_Function( @@ -71,17 +71,6 @@ namespace chaiscript Dynamic_Object_Function &operator=(const Dynamic_Object_Function) = delete; Dynamic_Object_Function(Dynamic_Object_Function &) = delete; - Param_Types get_dynamic_param_types() const noexcept override { - auto dynamic(std::dynamic_pointer_cast(m_func)); - - if (dynamic) { - return dynamic->get_dynamic_param_types(); - } else { - return Param_Types(get_param_types()); - } - } - - bool operator==(const Proxy_Function_Base &f) const noexcept override { if (const auto *df = dynamic_cast(&f)) @@ -184,7 +173,7 @@ namespace chaiscript * that is automatically guarded based on the first param based on the * param's type name */ - class Dynamic_Object_Constructor final : public Proxy_Function_Base, public Dynamic_Function_Interface + class Dynamic_Object_Constructor final : public Proxy_Function_Base { public: Dynamic_Object_Constructor( @@ -193,7 +182,6 @@ namespace chaiscript : Proxy_Function_Base(build_type_list(t_func->get_param_types()), t_func->get_arity() - 1), m_type_name(std::move(t_type_name)), m_func(t_func) { - assert( t_func ); assert( (t_func->get_arity() > 0 || t_func->get_arity() < 0) && "Programming error, Dynamic_Object_Function must have at least one parameter (this)"); } @@ -211,17 +199,6 @@ namespace chaiscript return std::vector(begin, end); } - Param_Types get_dynamic_param_types() const noexcept override { - auto dynamic(std::dynamic_pointer_cast(m_func)); - - if (dynamic) { - return dynamic->get_dynamic_param_types(); - } else { - return Param_Types(get_param_types()); - } - } - - bool operator==(const Proxy_Function_Base &f) const noexcept override { const Dynamic_Object_Constructor *dc = dynamic_cast(&f); diff --git a/include/chaiscript/dispatchkit/proxy_functions.hpp b/include/chaiscript/dispatchkit/proxy_functions.hpp index 3fee032f..7f00f235 100644 --- a/include/chaiscript/dispatchkit/proxy_functions.hpp +++ b/include/chaiscript/dispatchkit/proxy_functions.hpp @@ -56,12 +56,6 @@ namespace chaiscript : m_has_types(false) {} - explicit Param_Types(const std::vector &t_types) - : m_types(build_param_types(t_types)), - m_has_types(false) - { - } - explicit Param_Types(std::vector> t_types) : m_types(std::move(t_types)), m_has_types(false) @@ -69,18 +63,6 @@ namespace chaiscript update_has_types(); } - static std::vector> build_param_types(const std::vector &t_types) - { - std::vector> retval; - std::transform(t_types.begin(), t_types.end(), std::back_inserter(retval), - [](const Type_Info &ti){ - return std::make_pair(std::string(), ti); - } - ); - - return retval; - } - void push_front(std::string t_name, Type_Info t_ti) { m_types.emplace(m_types.begin(), std::move(t_name), t_ti); @@ -362,16 +344,9 @@ namespace chaiscript namespace dispatch { - class Dynamic_Function_Interface - { - public: - virtual ~Dynamic_Function_Interface() {} - virtual Param_Types get_dynamic_param_types() const = 0; - }; - /// A Proxy_Function implementation that is not type safe, the called function /// is expecting a vector that it works with how it chooses. - class Dynamic_Proxy_Function : public Proxy_Function_Base, public Dynamic_Function_Interface + class Dynamic_Proxy_Function : public Proxy_Function_Base { public: Dynamic_Proxy_Function( @@ -426,9 +401,6 @@ namespace chaiscript } } - Param_Types get_dynamic_param_types() const override { - return m_param_types; - } protected: bool test_guard(const Function_Params ¶ms, const Type_Conversions_State &t_conversions) const @@ -971,9 +943,6 @@ namespace chaiscript std::vector> ordered_funcs; ordered_funcs.reserve(funcs.size()); - const constexpr auto boxed_type = user_type(); - const constexpr auto dynamic_type = user_type(); - for (const auto &func : funcs) { const auto arity = func->get_arity(); @@ -985,10 +954,7 @@ namespace chaiscript size_t numdiffs = 0; for (size_t i = 0; i < plist.size(); ++i) { - const auto &p_type = plist[i].get_type_info(); - const auto &f_type = func->get_param_types()[i+1]; - - if (!(f_type.bare_equal(boxed_type) && p_type.bare_equal(dynamic_type)) && !f_type.bare_equal(p_type)) + if (!func->get_param_types()[i+1].bare_equal(plist[i].get_type_info())) { ++numdiffs; } diff --git a/unittests/compiled_tests.cpp b/unittests/compiled_tests.cpp index 48e5b378..6e241572 100644 --- a/unittests/compiled_tests.cpp +++ b/unittests/compiled_tests.cpp @@ -321,8 +321,7 @@ TEST_CASE("Function ordering") chaiscript::ChaiScript_Basic chai(create_chaiscript_stdlib(),create_chaiscript_parser()); chai.eval("def test_fun(x) { return 3; }"); chai.eval("def test_fun(x) : x == \"hi\" { return 4; }"); - chai.eval("def test_fun(double d) { return 5; }"); - +// chai.eval("def test_fun(x) { return 5; }"); chai.add(chaiscript::fun(&function_ordering_test_one), "test_fun"); chai.add(chaiscript::fun(&function_ordering_test_two), "test_fun"); @@ -330,7 +329,6 @@ TEST_CASE("Function ordering") CHECK(chai.eval("auto i = 1; test_fun(i)") == 2); CHECK(chai.eval("test_fun(\"bob\")") == 3); CHECK(chai.eval("test_fun(\"hi\")") == 4); - CHECK(chai.eval("test_fun(5.0)") == 5); } From f462796ee5e0053f85feee7830b9bd924bd56301 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Tue, 21 Nov 2017 16:17:53 -0700 Subject: [PATCH 065/155] Add clone shortcircuit for strings --- include/chaiscript/language/chaiscript_eval.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/chaiscript/language/chaiscript_eval.hpp b/include/chaiscript/language/chaiscript_eval.hpp index 2c72dbe8..eae007b1 100644 --- a/include/chaiscript/language/chaiscript_eval.hpp +++ b/include/chaiscript/language/chaiscript_eval.hpp @@ -96,6 +96,8 @@ namespace chaiscript return Boxed_Number::clone(incoming); } else if (incoming.get_type_info().bare_equal_type_info(typeid(bool))) { return Boxed_Value(*static_cast(incoming.get_const_ptr())); + } else if (incoming.get_type_info().bare_equal_type_info(typeid(std::string))) { + return Boxed_Value(*static_cast(incoming.get_const_ptr())); } else { std::array params{std::move(incoming)}; return t_ss->call_function("clone", t_loc, Function_Params{params}, t_ss.conversions()); From b47fec2f7178d30f9c47060a195f972744a0f1ce Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Tue, 21 Nov 2017 16:37:18 -0700 Subject: [PATCH 066/155] Comment out clone_object tests from typed_function_ordering --- unittests/clone_object.chai | 3 +++ 1 file changed, 3 insertions(+) diff --git a/unittests/clone_object.chai b/unittests/clone_object.chai index 04ad0be8..8864d0ce 100644 --- a/unittests/clone_object.chai +++ b/unittests/clone_object.chai @@ -1,3 +1,5 @@ + +/* global clone_count = 0; class Cloneable @@ -35,4 +37,5 @@ assert_equal(0, clone_count); var p = o; assert_equal(1, clone_count); +*/ From 48e5a46cbd5b2f4a8aa5fb604cb3bd3d027338f6 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Thu, 23 Nov 2017 22:38:15 -0700 Subject: [PATCH 067/155] Move to QuickFlatMap from manual vector map thing --- .../chaiscript/dispatchkit/dispatchkit.hpp | 83 +++++-------------- include/chaiscript/utility/quick_flat_map.hpp | 62 ++++++++++++++ 2 files changed, 85 insertions(+), 60 deletions(-) diff --git a/include/chaiscript/dispatchkit/dispatchkit.hpp b/include/chaiscript/dispatchkit/dispatchkit.hpp index f8bbf45f..7fac1721 100644 --- a/include/chaiscript/dispatchkit/dispatchkit.hpp +++ b/include/chaiscript/dispatchkit/dispatchkit.hpp @@ -36,6 +36,7 @@ #include "proxy_functions.hpp" #include "type_info.hpp" #include "short_alloc.hpp" +#include "../utility/quick_flat_map.hpp" namespace chaiscript { class Boxed_Number; @@ -388,7 +389,7 @@ namespace chaiscript using SmallVector = std::vector; - using Scope = SmallVector>; + using Scope = utility::QuickFlatMap; using StackData = SmallVector; using Stacks = SmallVector; using Call_Param_List = SmallVector; @@ -409,24 +410,13 @@ namespace chaiscript void push_stack() { stacks.emplace_back(1); -// stacks.emplace_back(StackData(1, Scope(scope_allocator), stack_data_allocator)); } void push_call_params() { call_params.emplace_back(); -// call_params.emplace_back(Call_Param_List(call_param_list_allocator)); } - //Scope::allocator_type::arena_type scope_allocator; - //StackData::allocator_type::arena_type stack_data_allocator; - //Stacks::allocator_type::arena_type stacks_allocator; - //Call_Param_List::allocator_type::arena_type call_param_list_allocator; - //Call_Params::allocator_type::arena_type call_params_allocator; - -// Stacks stacks = Stacks(stacks_allocator); -// Call_Params call_params = Call_Params(call_params_allocator); - Stacks stacks; Call_Params call_params; @@ -440,7 +430,7 @@ namespace chaiscript public: using Type_Name_Map = std::map; - using Scope = std::vector>; + using Scope = utility::QuickFlatMap; using StackData = Stack_Holder::StackData; struct State @@ -486,12 +476,7 @@ namespace chaiscript for (auto stack_elem = stack.rbegin(); stack_elem != stack.rend(); ++stack_elem) { - auto itr = std::find_if(stack_elem->begin(), stack_elem->end(), - [&](const std::pair &o) { - return o.first == name; - }); - - if (itr != stack_elem->end()) + if (auto itr = stack_elem->find(name); itr != stack_elem->end()) { itr->second = std::move(obj); return; @@ -504,38 +489,32 @@ namespace chaiscript /// Adds a named object to the current scope /// \warning This version does not check the validity of the name /// it is meant for internal use only - Boxed_Value &add_get_object(const std::string &t_name, Boxed_Value obj, Stack_Holder &t_holder) + Boxed_Value &add_get_object(std::string t_name, Boxed_Value obj, Stack_Holder &t_holder) { auto &stack_elem = get_stack_data(t_holder).back(); - if (std::any_of(stack_elem.begin(), stack_elem.end(), - [&](const std::pair &o) { - return o.first == t_name; - })) + if (auto result = stack_elem.insert(std::pair{std::move(t_name), std::move(obj)}); result.second) { - throw chaiscript::exception::name_conflict_error(t_name); + return result.first->second; + } else { + //insert failed + throw chaiscript::exception::name_conflict_error(result.first->first); } - - return stack_elem.emplace_back(t_name, std::move(obj)).second; } /// Adds a named object to the current scope /// \warning This version does not check the validity of the name /// it is meant for internal use only - void add_object(const std::string &t_name, Boxed_Value obj, Stack_Holder &t_holder) + void add_object(std::string t_name, Boxed_Value obj, Stack_Holder &t_holder) { auto &stack_elem = get_stack_data(t_holder).back(); - if (std::any_of(stack_elem.begin(), stack_elem.end(), - [&](const std::pair &o) { - return o.first == t_name; - })) + if (auto result = stack_elem.insert(std::pair{std::move(t_name), std::move(obj)}); !result.second) { - throw chaiscript::exception::name_conflict_error(t_name); + //insert failed + throw chaiscript::exception::name_conflict_error(result.first->first); } - - stack_elem.emplace_back(t_name, std::move(obj)); } @@ -566,46 +545,30 @@ namespace chaiscript } /// Adds a new global (non-const) shared object, between all the threads - Boxed_Value add_global_no_throw(const Boxed_Value &obj, const std::string &name) + Boxed_Value add_global_no_throw(Boxed_Value obj, std::string name) { chaiscript::detail::threading::unique_lock l(m_mutex); - const auto itr = m_state.m_global_objects.find(name); - if (itr == m_state.m_global_objects.end()) - { - m_state.m_global_objects.insert(std::make_pair(name, obj)); - return obj; - } else { - return itr->second; - } + return m_state.m_global_objects.insert(std::pair{std::move(name), std::move(obj)}).first->second; } /// Adds a new global (non-const) shared object, between all the threads - void add_global(const Boxed_Value &obj, const std::string &name) + void add_global(Boxed_Value obj, std::string name) { chaiscript::detail::threading::unique_lock l(m_mutex); - if (m_state.m_global_objects.find(name) != m_state.m_global_objects.end()) - { - throw chaiscript::exception::name_conflict_error(name); - } else { - m_state.m_global_objects.insert(std::make_pair(name, obj)); + if (auto result = m_state.m_global_objects.insert(std::pair{std::move(name), std::move(obj)}); !result.second) { + // insert failed + throw chaiscript::exception::name_conflict_error(result.first->first); } } /// Updates an existing global shared object or adds a new global shared object if not found - void set_global(const Boxed_Value &obj, const std::string &name) + void set_global(Boxed_Value obj, std::string name) { chaiscript::detail::threading::unique_lock l(m_mutex); - - const auto itr = m_state.m_global_objects.find(name); - if (itr != m_state.m_global_objects.end()) - { - itr->second.assign(obj); - } else { - m_state.m_global_objects.insert(std::make_pair(name, obj)); - } + m_state.m_global_objects.insert_or_assign(std::move(name), std::move(obj)); } /// Adds a new scope to the stack @@ -688,7 +651,7 @@ namespace chaiscript } else if ((loc & static_cast(Loc::is_local)) != 0u) { auto &stack = get_stack_data(t_holder); - return stack[stack.size() - 1 - ((loc & static_cast(Loc::stack_mask)) >> 16)][loc & static_cast(Loc::loc_mask)].second; + return stack[stack.size() - 1 - ((loc & static_cast(Loc::stack_mask)) >> 16)].at_index(loc & static_cast(Loc::loc_mask)); } // Is the value we are looking for a global or function? diff --git a/include/chaiscript/utility/quick_flat_map.hpp b/include/chaiscript/utility/quick_flat_map.hpp index 1d3be2bb..d19a2d19 100644 --- a/include/chaiscript/utility/quick_flat_map.hpp +++ b/include/chaiscript/utility/quick_flat_map.hpp @@ -35,6 +35,14 @@ namespace chaiscript::utility { return data.end(); } + auto &back() noexcept { + return data.back(); + } + + const auto &back() const noexcept { + return data.back(); + } + Value &operator[](const Key &s) { const auto itr = find(s); @@ -45,6 +53,27 @@ namespace chaiscript::utility { } } + Value &at_index(const std::size_t idx) noexcept + { + return data[idx].second; + } + + const Value &at_index(const std::size_t idx) const noexcept + { + return data[idx].second; + } + + bool empty() const noexcept + { + return data.empty(); + } + + template + void assign(Itr begin, Itr end) + { + data.assign(begin, end); + } + Value &at(const Key &s) { const auto itr = find(s); if (itr != data.end()) { @@ -54,6 +83,30 @@ namespace chaiscript::utility { } } + + template + auto insert_or_assign(Key &&key, M &&m) + { + if (auto itr = find(key); itr != data.end()) { + *itr = std::forward(m); + return std::pair{itr, false}; + } else { + return std::pair{data.emplace(itr, std::move(key), std::forward(m)), true}; + } + } + + + template + auto insert_or_assign(const Key &key, M &&m) + { + if (auto itr = find(key); itr != data.end()) { + *itr = std::forward(m); + return std::pair{itr, false}; + } else { + return std::pair{data.emplace(itr, key, std::forward(m)), true}; + } + } + const Value &at(const Key &s) const { const auto itr = find(s); if (itr != data.end()) { @@ -69,9 +122,18 @@ namespace chaiscript::utility { std::vector> data; + using value_type = std::pair; using iterator = typename decltype(data)::iterator; using const_iterator = typename decltype(data)::const_iterator; + std::pair insert( value_type&& value ) + { + if (const auto itr = find(value.first); itr != data.end()) { + return std::pair{itr, false}; + } else { + return std::pair{data.insert(itr, std::move(value)), true}; + } + } }; From db72ab626fa7945b248cde25b5ef3617300e9086 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Fri, 24 Nov 2017 22:20:52 -0700 Subject: [PATCH 068/155] Consolidate hand-rolled flat maps --- include/chaiscript/chaiscript_defines.hpp | 12 +++ .../chaiscript/dispatchkit/dispatchkit.hpp | 99 +++++-------------- include/chaiscript/utility/quick_flat_map.hpp | 46 +++++++-- 3 files changed, 74 insertions(+), 83 deletions(-) diff --git a/include/chaiscript/chaiscript_defines.hpp b/include/chaiscript/chaiscript_defines.hpp index 6c8ee78d..f0599e23 100644 --- a/include/chaiscript/chaiscript_defines.hpp +++ b/include/chaiscript/chaiscript_defines.hpp @@ -212,6 +212,18 @@ namespace chaiscript { return final_value(t, base, exponent, neg_exponent); } + struct str_equal { + [[nodiscard]] bool operator()(const std::string &t_lhs, const std::string &t_rhs) const noexcept { + return t_lhs == t_rhs; + } + template + [[nodiscard]] constexpr bool operator()(const LHS &t_lhs, const RHS &t_rhs) const noexcept { + return std::equal(t_lhs.begin(), t_lhs.end(), t_rhs.begin(), t_rhs.end()); + } + struct is_transparent{}; + }; + + struct str_less { [[nodiscard]] bool operator()(const std::string &t_lhs, const std::string &t_rhs) const noexcept { return t_lhs < t_rhs; diff --git a/include/chaiscript/dispatchkit/dispatchkit.hpp b/include/chaiscript/dispatchkit/dispatchkit.hpp index 7fac1721..34607a1d 100644 --- a/include/chaiscript/dispatchkit/dispatchkit.hpp +++ b/include/chaiscript/dispatchkit/dispatchkit.hpp @@ -389,7 +389,7 @@ namespace chaiscript using SmallVector = std::vector; - using Scope = utility::QuickFlatMap; + using Scope = utility::QuickFlatMap; using StackData = SmallVector; using Stacks = SmallVector; using Call_Param_List = SmallVector; @@ -430,14 +430,14 @@ namespace chaiscript public: using Type_Name_Map = std::map; - using Scope = utility::QuickFlatMap; + using Scope = utility::QuickFlatMap; using StackData = Stack_Holder::StackData; struct State { - std::vector>>> m_functions; - std::vector> m_function_objects; - std::vector> m_boxed_functions; + utility::QuickFlatMap>, str_equal> m_functions; + utility::QuickFlatMap m_function_objects; + utility::QuickFlatMap m_boxed_functions; std::map m_global_objects; Type_Name_Map m_types; }; @@ -745,9 +745,7 @@ namespace chaiscript const auto &funs = get_functions_int(); - auto itr = find_keyed_value(funs, t_name, t_hint); - - if (itr != funs.end()) + if (const auto itr = funs.find(t_name, t_hint); itr != funs.end()) { return std::make_pair(std::distance(funs.begin(), itr), itr->second); } else { @@ -771,9 +769,7 @@ namespace chaiscript { const auto &funs = get_boxed_functions_int(); - auto itr = find_keyed_value(funs, t_name, t_hint); - - if (itr != funs.end()) + if (const auto itr = funs.find(t_name, t_hint); itr != funs.end()) { return std::make_pair(std::distance(funs.begin(), itr), itr->second); } else { @@ -787,8 +783,7 @@ namespace chaiscript { chaiscript::detail::threading::shared_lock l(m_mutex); - const auto &functions = get_functions_int(); - return find_keyed_value(functions, name) != functions.end(); + return get_functions_int().count(name) > 0; } /// \returns All values in the local thread state in the parent scope, or if it doesn't exist, @@ -1246,32 +1241,32 @@ namespace chaiscript private: - const std::vector> &get_boxed_functions_int() const noexcept + const decltype(State::m_boxed_functions) &get_boxed_functions_int() const noexcept { return m_state.m_boxed_functions; } - std::vector> &get_boxed_functions_int() noexcept + decltype(State::m_boxed_functions) &get_boxed_functions_int() noexcept { return m_state.m_boxed_functions; } - const std::vector> &get_function_objects_int() const noexcept + const decltype(State::m_function_objects) &get_function_objects_int() const noexcept { return m_state.m_function_objects; } - std::vector> &get_function_objects_int() noexcept + decltype(State::m_function_objects) &get_function_objects_int() noexcept { return m_state.m_function_objects; } - const std::vector>>> &get_functions_int() const noexcept + const decltype(State::m_functions) &get_functions_int() const noexcept { return m_state.m_functions; } - std::vector>>> &get_functions_int() noexcept + decltype(State::m_functions) &get_functions_int() noexcept { return m_state.m_functions; } @@ -1360,63 +1355,17 @@ namespace chaiscript return false; } - - - template - static void add_keyed_value(Container &t_c, const Key &t_key, Value &&t_value) - { - auto itr = find_keyed_value(t_c, t_key); - - if (itr == t_c.end()) { - t_c.reserve(t_c.size() + 1); // tightly control growth of memory usage here - t_c.emplace_back(t_key, std::forward(t_value)); - } else { - using value_type = typename Container::value_type; - *itr = value_type(t_key, std::forward(t_value)); - } - } - - template - static typename Container::iterator find_keyed_value(Container &t_c, const Key &t_key) noexcept - { - return std::find_if(t_c.begin(), t_c.end(), - [&t_key](const typename Container::value_type &o) { - return o.first == t_key; - }); - } - - template - static typename Container::const_iterator find_keyed_value(const Container &t_c, const Key &t_key) noexcept - { - return std::find_if(t_c.begin(), t_c.end(), - [&t_key](const typename Container::value_type &o) { - return std::equal(o.first.begin(), o.first.end(), t_key.begin(), t_key.end()); - }); - } - - template - static typename Container::const_iterator find_keyed_value(const Container &t_c, const Key &t_key, const size_t t_hint) noexcept - { - if (t_c.size() > t_hint && t_c[t_hint].first == t_key) { - return std::next(t_c.begin(), static_cast::difference_type>(t_hint)); - } else { - return find_keyed_value(t_c, t_key); - } - } - - /// Implementation detail for adding a function. /// \throws exception::name_conflict_error if there's a function matching the given one being added void add_function(const Proxy_Function &t_f, const std::string &t_name) { chaiscript::detail::threading::unique_lock l(m_mutex); - auto &funcs = get_functions_int(); - - auto itr = find_keyed_value(funcs, t_name); - Proxy_Function new_func = [&]() -> Proxy_Function { + auto &funcs = get_functions_int(); + auto itr = funcs.find(t_name); + if (itr != funcs.end()) { auto vec = *itr->second; @@ -1437,17 +1386,21 @@ namespace chaiscript // if the function is the only function but it also contains // arithmetic operators, we must wrap it in a dispatch function // to allow for automatic arithmetic type conversions - std::vector vec({t_f}); - funcs.emplace_back(t_name, std::make_shared>(vec)); + std::vector vec; + vec.push_back(t_f); + funcs.insert(std::pair{t_name, std::make_shared>(vec)}); return std::make_shared(std::move(vec)); } else { - funcs.emplace_back(t_name, std::make_shared>(std::initializer_list({t_f}))); + auto vec = std::make_shared>(); + vec->push_back(t_f); + funcs.insert(std::pair{t_name, vec}); return t_f; } }(); - add_keyed_value(get_boxed_functions_int(), t_name, const_var(new_func)); - add_keyed_value(get_function_objects_int(), t_name, std::move(new_func)); + + get_boxed_functions_int().insert_or_assign(t_name, const_var(new_func)); + get_function_objects_int().insert_or_assign(t_name, std::move(new_func)); } mutable chaiscript::detail::threading::shared_mutex m_mutex; diff --git a/include/chaiscript/utility/quick_flat_map.hpp b/include/chaiscript/utility/quick_flat_map.hpp index d19a2d19..35bc089d 100644 --- a/include/chaiscript/utility/quick_flat_map.hpp +++ b/include/chaiscript/utility/quick_flat_map.hpp @@ -3,15 +3,29 @@ namespace chaiscript::utility { - template + template> struct QuickFlatMap { - auto find(const Key &s) noexcept { - return std::find_if(std::begin(data), std::end(data), [&s](const auto &d) { return d.first == s; }); + Comparator comparator; + + template + auto find(const Lookup &s) noexcept { + return std::find_if(std::begin(data), std::end(data), [&s, this](const auto &d) { return comparator(d.first, s); }); } - auto find(const Key &s) const noexcept { - return std::find_if(std::begin(data), std::end(data), [&s](const auto &d) { return d.first == s; }); + template + auto find(const Lookup &s) const noexcept { + return std::find_if(std::cbegin(data), std::cend(data), [&s, this](const auto &d) { return comparator(d.first, s); }); + } + + template + auto find(const Lookup &s, const std::size_t t_hint) const noexcept { + if (data.size() > t_hint && comparator(data[t_hint].first, s)) { + const auto begin = std::cbegin(data); + return std::next(begin, static_cast>::difference_type>(t_hint)); + } else { + return find(s); + } } auto size() const noexcept { @@ -49,6 +63,7 @@ namespace chaiscript::utility { if (itr != data.end()) { return itr->second; } else { + grow(); return data.emplace_back(s, Value()).second; } } @@ -91,7 +106,8 @@ namespace chaiscript::utility { *itr = std::forward(m); return std::pair{itr, false}; } else { - return std::pair{data.emplace(itr, std::move(key), std::forward(m)), true}; + grow(); + return std::pair{data.emplace(data.end(), std::move(key), std::forward(m)), true}; } } @@ -100,10 +116,11 @@ namespace chaiscript::utility { auto insert_or_assign(const Key &key, M &&m) { if (auto itr = find(key); itr != data.end()) { - *itr = std::forward(m); + itr->second = std::forward(m); return std::pair{itr, false}; } else { - return std::pair{data.emplace(itr, key, std::forward(m)), true}; + grow(); + return std::pair{data.emplace(data.end(), key, std::forward(m)), true}; } } @@ -116,7 +133,8 @@ namespace chaiscript::utility { } } - size_t count(const Key &s) const noexcept { + template + size_t count(const Lookup &s) const noexcept { return (find(s) != data.end())?1:0; } @@ -131,10 +149,18 @@ namespace chaiscript::utility { if (const auto itr = find(value.first); itr != data.end()) { return std::pair{itr, false}; } else { - return std::pair{data.insert(itr, std::move(value)), true}; + grow(); + return std::pair{data.insert(data.end(), std::move(value)), true}; } } + void grow() { + if ((data.capacity() - data.size()) == 0) { + data.reserve(data.size() + 2); + } + } + + }; } From 4a61d1e5116c0a8fdf3f8c9858c38f391435bf99 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Thu, 14 Dec 2017 08:13:19 -0700 Subject: [PATCH 069/155] Enable C++latest for C++17 Visual Studio builds --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 78dfc613..268ee81b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -168,7 +168,7 @@ else() endif() if(MSVC) - add_definitions(/W4 /w14545 /w34242 /w34254 /w34287 /w44263 /w44265 /w44296 /w44311 /w44826 /we4289 /w14546 /w14547 /w14549 /w14555 /w14619 /w14905 /w14906 /w14928) + add_definitions(/std:c++latest /W4 /w14545 /w34242 /w34254 /w34287 /w44263 /w44265 /w44296 /w44311 /w44826 /we4289 /w14546 /w14547 /w14549 /w14555 /w14619 /w14905 /w14906 /w14928) if (MSVC_VERSION STREQUAL "1800") # VS2013 doesn't have magic statics From 6bfc130b737f8c6008f51ac55bc4bfb30b4803b2 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Sat, 16 Dec 2017 11:50:32 -0700 Subject: [PATCH 070/155] Fix pull from develop, fix gcc warnings --- CMakeLists.txt | 25 +++-------- include/chaiscript/chaiscript_defines.hpp | 43 +++++++++++++++++++ .../chaiscript/language/chaiscript_engine.hpp | 3 +- include/chaiscript/utility/json.hpp | 6 +-- 4 files changed, 53 insertions(+), 24 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 78dfc613..c7911466 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -22,7 +22,6 @@ option(BUILD_SAMPLES "Build Samples Folder" FALSE) option(RUN_FUZZY_TESTS "Run tests generated by AFL" FALSE) option(USE_STD_MAKE_SHARED "Use std::make_shared instead of chaiscript::make_shared" FALSE) option(RUN_PERFORMANCE_TESTS "Run Performance Tests" FALSE) -option(BUILD_IN_CPP17_MODE "Build with C++17 flags" FALSE) mark_as_advanced(USE_STD_MAKE_SHARED) @@ -150,21 +149,7 @@ endif() if(CMAKE_COMPILER_IS_GNUCC) execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion OUTPUT_VARIABLE GCC_VERSION) - if(GCC_VERSION VERSION_LESS 4.9) - set(CPP14_FLAG "-std=c++1y") - else() - if (BUILD_IN_CPP17_MODE) - set(CPP14_FLAG "-std=c++1z") - else() - set(CPP14_FLAG "-std=c++14") - endif() - endif() -else() - if (BUILD_IN_CPP17_MODE) - set(CPP14_FLAG "-std=c++1z") - else() - set(CPP14_FLAG "-std=c++14") - endif() + set(CPP17_FLAG "-std=c++1z") endif() if(MSVC) @@ -188,7 +173,7 @@ if(MSVC) # how to workaround or fix the error. So I'm disabling it globally. add_definitions(/wd4503) else() - add_definitions(-Wall -Wextra -Wconversion -Wshadow -Wnon-virtual-dtor -Wold-style-cast -Wcast-align -Wcast-qual -Wunused -Woverloaded-virtual -Wno-noexcept-type -Wpedantic ${CPP14_FLAG}) + add_definitions(-Wall -Wextra -Wconversion -Wshadow -Wnon-virtual-dtor -Wold-style-cast -Wcast-align -Wcast-qual -Wunused -Woverloaded-virtual -Wno-noexcept-type -Wpedantic ${CPP17_FLAG}) if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") add_definitions(-Weverything -Wno-c++98-compat-pedantic -Wno-c++98-compat -Wno-documentation -Wno-switch-enum -Wno-weak-vtables -Wno-missing-prototypes -Wno-padded -Wno-missing-noreturn -Wno-exit-time-destructors -Wno-documentation-unknown-command -Wno-unused-template -Wno-undef ) @@ -206,12 +191,12 @@ if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") if(USE_LIBCXX) add_definitions(-stdlib=libc++) - set(LINKER_FLAGS "${LINKER_FLAGS} ${CPP14_FLAG} -stdlib=libc++") + set(LINKER_FLAGS "${LINKER_FLAGS} ${CPP17_FLAG} -stdlib=libc++") else() - set(LINKER_FLAGS "${LINKER_FLAGS} ${CPP14_FLAG}") + set(LINKER_FLAGS "${LINKER_FLAGS} ${CPP17_FLAG}") endif() elseif(CMAKE_COMPILER_IS_GNUCC) - set(LINKER_FLAGS "${LINKER_FLAGS} ${CPP14_FLAG}") + set(LINKER_FLAGS "${LINKER_FLAGS} ${CPP17_FLAG}") endif() # limitations in MinGW require us to make an optimized build diff --git a/include/chaiscript/chaiscript_defines.hpp b/include/chaiscript/chaiscript_defines.hpp index 1fe3a512..7bac2681 100644 --- a/include/chaiscript/chaiscript_defines.hpp +++ b/include/chaiscript/chaiscript_defines.hpp @@ -168,6 +168,49 @@ namespace chaiscript { } + template + [[nodiscard]] auto parse_num(const std::string_view &t_str) noexcept + -> typename std::enable_if::value, T>::type + { + T t = 0; + T base = 0; + T decimal_place = 0; + bool exponent = false; + bool neg_exponent = false; + + const auto final_value = [](const T val, const T baseval, const bool hasexp, const bool negexp) -> T { + if (!hasexp) { + return val; + } else { + return baseval * std::pow(T(10), val*T(negexp?-1:1)); + } + }; + + for (const auto c : t_str) { + if (c == '.') { + decimal_place = 10; + } else if (c == 'e' || c == 'E') { + exponent = true; + decimal_place = 0; + base = t; + t = 0; + } else if (c == '-' && exponent) { + neg_exponent = true; + } else if (c == '+' && exponent) { + neg_exponent = false; + } else if (c < '0' || c > '9') { + return final_value(t, base, exponent, neg_exponent); + } else if (decimal_place < T(10)) { + t *= T(10); + t += T(c - '0'); + } else { + t += (T(c - '0') / (T(decimal_place))); + decimal_place *= 10; + } + } + + return final_value(t, base, exponent, neg_exponent); + } template auto parse_num(const char *t_str) -> typename std::enable_if::value, T>::type diff --git a/include/chaiscript/language/chaiscript_engine.hpp b/include/chaiscript/language/chaiscript_engine.hpp index 3dce4a76..aa34e505 100644 --- a/include/chaiscript/language/chaiscript_engine.hpp +++ b/include/chaiscript/language/chaiscript_engine.hpp @@ -200,7 +200,8 @@ namespace chaiscript m_engine.add(fun([this](const Boxed_Value &t_bv, const std::string &t_name){ add_global(t_bv, t_name); }), "add_global"); m_engine.add(fun([this](const Boxed_Value &t_bv, const std::string &t_name){ set_global(t_bv, t_name); }), "set_global"); - m_engine.add(fun([this](const std::string& t_namespace_name) { register_namespace([](Namespace& space) {}, t_namespace_name); import(t_namespace_name); }), "namespace"); + // why this unused parameter to Namesapce? + m_engine.add(fun([this](const std::string& t_namespace_name) { register_namespace([](Namespace& ) {}, t_namespace_name); import(t_namespace_name); }), "namespace"); m_engine.add(fun([this](const std::string& t_namespace_name) { import(t_namespace_name); }), "import"); } diff --git a/include/chaiscript/utility/json.hpp b/include/chaiscript/utility/json.hpp index d227d85e..f5583033 100644 --- a/include/chaiscript/utility/json.hpp +++ b/include/chaiscript/utility/json.hpp @@ -50,11 +50,11 @@ class JSON private: - using Data = std::variant, std::vector, std::string, double, int64_t, bool>; + using Data = std::variant, std::vector, std::string, double, int64_t, bool>; struct Internal { - Internal(nullptr_t) : d(nullptr) { } + Internal(std::nullptr_t) : d(nullptr) { } Internal() : d(nullptr) { } Internal(Class c) : d(make_type(c)) { } template Internal(T t) : d(std::move(t)) { } @@ -96,7 +96,7 @@ class JSON template auto &get_set_type() { set_type(ClassValue); - return std::get(ClassValue)>(d); + return (std::get(ClassValue)>(d)); } auto &Map() { From c902771f161ca5d80828803635eb8f9e35ef7665 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Mon, 19 Feb 2018 16:36:08 -0700 Subject: [PATCH 071/155] Use catch's test parser --- CMakeLists.txt | 34 ++-------------------------------- cmake/CatchAddTests.cmake | 10 ++++------ 2 files changed, 6 insertions(+), 38 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 74f7e614..af4fd810 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -117,6 +117,7 @@ configure_file(Doxyfile.in ${CMAKE_BINARY_DIR}/Doxyfile) include(CTest) include(CPack) +include(cmake/Catch.cmake) if(NOT MINGW) find_library(READLINE_LIBRARY NAMES readline PATH /usr/lib /usr/local/lib /opt/local/lib) @@ -337,37 +338,6 @@ endif() if(BUILD_TESTING) - # Add catch tests macro - macro(ADD_CATCH_TESTS executable) - if (MSVC) - file(TO_NATIVE_PATH "${QT_LIBRARY_DIR}" QT_LIB_PATH) - set(NEWPATH "${QT_LIB_PATH};$ENV{PATH}") - else() - set(NEWPATH $ENV{PATH}) - endif() - - get_target_property(target_files ${executable} SOURCES) - - foreach(source ${target_files}) - if(NOT "${source}" MATCHES "/moc_.*cxx") - string(REGEX MATCH .*cpp source "${source}") - if(source) - file(READ "${source}" contents) - string(REGEX MATCHALL "TEST_CASE\\([ ]*\"[^\"]+\"" found_tests ${contents}) - foreach(hit ${found_tests}) - string(REGEX REPLACE "TEST_CASE\\([ ]*(\"[^\"]+\").*" "\\1" test_name ${hit}) - add_test(compiled.${test_name} "${executable}" ${test_name}) - set_tests_properties(compiled.${test_name} PROPERTIES TIMEOUT 660 ENVIRONMENT "PATH=${NEWPATH}") - endforeach() - endif() - endif() - endforeach() - endmacro() - - - - - option(UNIT_TEST_LIGHT "Unit tests light (expect module loading failures)" FALSE) add_test(version_check chai -c "if(\"\\\${ version() };\\\${version_major()};\\\${version_minor()};\\\${version_patch()}\" != \"${CHAI_VERSION};${CPACK_PACKAGE_VERSION_MAJOR};${CPACK_PACKAGE_VERSION_MINOR};${CPACK_PACKAGE_VERSION_PATCH}\") { exit(-1) }") @@ -425,7 +395,7 @@ if(BUILD_TESTING) if(NOT UNIT_TEST_LIGHT) add_executable(compiled_tests unittests/compiled_tests.cpp) target_link_libraries(compiled_tests ${LIBS} ${CHAISCRIPT_LIBS}) - ADD_CATCH_TESTS(compiled_tests) + catch_discover_tests(compiled_tests) add_executable(static_chaiscript_test unittests/static_chaiscript.cpp) target_link_libraries(static_chaiscript_test ${LIBS}) diff --git a/cmake/CatchAddTests.cmake b/cmake/CatchAddTests.cmake index c68921e4..205e2b87 100644 --- a/cmake/CatchAddTests.cmake +++ b/cmake/CatchAddTests.cmake @@ -50,23 +50,21 @@ string(REPLACE "\n" ";" output "${output}") # Parse output foreach(line ${output}) - # Test name; strip spaces to get just the name... - string(REGEX REPLACE " +" "" test "${line}") # ...and add to script add_command(add_test - "${prefix}${test}${suffix}" + "${prefix}${line}${suffix}" ${TEST_EXECUTOR} "${TEST_EXECUTABLE}" - "${test}" + "${line}" ${extra_args} ) add_command(set_tests_properties - "${prefix}${test}${suffix}" + "${prefix}${line}${suffix}" PROPERTIES WORKING_DIRECTORY "${TEST_WORKING_DIR}" ${properties} ) - list(APPEND tests "${prefix}${test}${suffix}") + list(APPEND tests "${prefix}${line}${suffix}") endforeach() # Create a list of all discovered tests, which users may use to e.g. set From be5709ab5c83da9ad58ca1f986a2e2f460cb0765 Mon Sep 17 00:00:00 2001 From: Stan <> Date: Sun, 4 Mar 2018 22:49:36 +0100 Subject: [PATCH 072/155] Add support for chained dot calls. --- .../chaiscript/language/chaiscript_parser.hpp | 10 +++++++ unittests/multiline.chai | 29 +++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/include/chaiscript/language/chaiscript_parser.hpp b/include/chaiscript/language/chaiscript_parser.hpp index 09bcc370..0d1885fb 100644 --- a/include/chaiscript/language/chaiscript_parser.hpp +++ b/include/chaiscript/language/chaiscript_parser.hpp @@ -2188,6 +2188,16 @@ namespace chaiscript } build_match>(prev_stack_top); } + else if (Eol()) { + auto start = --m_position; + while (Eol()) {} + if (Symbol(".")) { + has_more = true; + --m_position; + } else { + m_position = start; + } + } } } diff --git a/unittests/multiline.chai b/unittests/multiline.chai index dfa213c3..f4cd9d9c 100644 --- a/unittests/multiline.chai +++ b/unittests/multiline.chai @@ -1,3 +1,14 @@ +class MyClass { + var value; + def MyClass(v) { this.value = v; } + def getWrappedIncrement() { return MyClass(this.value + 1); } + def getValue { return this.value; } +}; + +def foo(x) { + return MyClass(x+1); +} + auto x = [1, 2, 3, 4] @@ -7,3 +18,21 @@ auto y = map(x, fun(x) { x + 1 }) assert_equal(2, y[0]) + +auto z = foo(1) +.value + +assert_equal(2, z) + +auto v = foo(2) +.getValue() + +assert_equal(3, v) + +auto u = MyClass(3) +.getWrappedIncrement() + +.getWrappedIncrement() +.getValue() + +assert_equal(5, u) \ No newline at end of file From 2d762c8be30c8ae10c76fc9876eb75cf20e7251a Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Tue, 29 May 2018 11:51:15 -0600 Subject: [PATCH 073/155] Update copyrights to 2018 --- LICENSE | 2 +- include/chaiscript/chaiscript.hpp | 2 +- include/chaiscript/chaiscript_basic.hpp | 2 +- include/chaiscript/chaiscript_defines.hpp | 2 +- include/chaiscript/chaiscript_threading.hpp | 2 +- include/chaiscript/dispatchkit/bad_boxed_cast.hpp | 2 +- include/chaiscript/dispatchkit/bind_first.hpp | 2 +- include/chaiscript/dispatchkit/bootstrap.hpp | 2 +- include/chaiscript/dispatchkit/bootstrap_stl.hpp | 2 +- include/chaiscript/dispatchkit/boxed_cast.hpp | 2 +- include/chaiscript/dispatchkit/boxed_cast_helper.hpp | 2 +- include/chaiscript/dispatchkit/boxed_number.hpp | 2 +- include/chaiscript/dispatchkit/boxed_value.hpp | 2 +- include/chaiscript/dispatchkit/callable_traits.hpp | 2 +- include/chaiscript/dispatchkit/dispatchkit.hpp | 2 +- include/chaiscript/dispatchkit/dynamic_object.hpp | 2 +- include/chaiscript/dispatchkit/dynamic_object_detail.hpp | 2 +- include/chaiscript/dispatchkit/exception_specification.hpp | 2 +- include/chaiscript/dispatchkit/function_call.hpp | 2 +- include/chaiscript/dispatchkit/function_call_detail.hpp | 2 +- include/chaiscript/dispatchkit/handle_return.hpp | 2 +- include/chaiscript/dispatchkit/operators.hpp | 2 +- include/chaiscript/dispatchkit/proxy_constructors.hpp | 2 +- include/chaiscript/dispatchkit/proxy_functions.hpp | 2 +- include/chaiscript/dispatchkit/proxy_functions_detail.hpp | 2 +- include/chaiscript/dispatchkit/register_function.hpp | 2 +- include/chaiscript/dispatchkit/type_conversions.hpp | 2 +- include/chaiscript/dispatchkit/type_info.hpp | 2 +- include/chaiscript/language/chaiscript_algebraic.hpp | 2 +- include/chaiscript/language/chaiscript_common.hpp | 2 +- include/chaiscript/language/chaiscript_engine.hpp | 2 +- include/chaiscript/language/chaiscript_eval.hpp | 2 +- include/chaiscript/language/chaiscript_optimizer.hpp | 2 +- include/chaiscript/language/chaiscript_parser.hpp | 2 +- include/chaiscript/language/chaiscript_posix.hpp | 2 +- include/chaiscript/language/chaiscript_prelude.hpp | 2 +- include/chaiscript/language/chaiscript_tracer.hpp | 2 +- include/chaiscript/language/chaiscript_unknown.hpp | 2 +- include/chaiscript/language/chaiscript_windows.hpp | 2 +- include/chaiscript/utility/fnv1a.hpp | 2 +- include/chaiscript/utility/static_string.hpp | 2 +- include/chaiscript/utility/utility.hpp | 2 +- license.txt | 2 +- samples/fun_call_performance.cpp | 2 +- src/libfuzzer_client.cpp | 2 +- src/main.cpp | 2 +- src/stl_extra.cpp | 2 +- 47 files changed, 47 insertions(+), 47 deletions(-) diff --git a/LICENSE b/LICENSE index 8e6a6b98..4874fcdf 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ BSD-3-Clause License -Copyright 2009-2016 Jason Turner +Copyright 2009-2018 Jason Turner Copyright 2009-2012 Jonathan Turner. All Rights Reserved. diff --git a/include/chaiscript/chaiscript.hpp b/include/chaiscript/chaiscript.hpp index dbf6d73b..04e19898 100644 --- a/include/chaiscript/chaiscript.hpp +++ b/include/chaiscript/chaiscript.hpp @@ -1,7 +1,7 @@ // This file is distributed under the BSD License. // See "license.txt" for details. // Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) -// Copyright 2009-2017, Jason Turner (jason@emptycrate.com) +// Copyright 2009-2018, Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com // This is an open source non-commercial project. Dear PVS-Studio, please check it. diff --git a/include/chaiscript/chaiscript_basic.hpp b/include/chaiscript/chaiscript_basic.hpp index b770b1b7..0e638450 100644 --- a/include/chaiscript/chaiscript_basic.hpp +++ b/include/chaiscript/chaiscript_basic.hpp @@ -1,7 +1,7 @@ // This file is distributed under the BSD License. // See "license.txt" for details. // Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) -// Copyright 2009-2017, Jason Turner (jason@emptycrate.com) +// Copyright 2009-2018, Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com #ifndef CHAISCRIPT_BASIC_HPP_ diff --git a/include/chaiscript/chaiscript_defines.hpp b/include/chaiscript/chaiscript_defines.hpp index 4508d603..add4774a 100644 --- a/include/chaiscript/chaiscript_defines.hpp +++ b/include/chaiscript/chaiscript_defines.hpp @@ -1,7 +1,7 @@ // This file is distributed under the BSD License. // See "license.txt" for details. // Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) -// Copyright 2009-2017, Jason Turner (jason@emptycrate.com) +// Copyright 2009-2018, Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com #ifndef CHAISCRIPT_DEFINES_HPP_ diff --git a/include/chaiscript/chaiscript_threading.hpp b/include/chaiscript/chaiscript_threading.hpp index 79feaa1e..41306ea4 100644 --- a/include/chaiscript/chaiscript_threading.hpp +++ b/include/chaiscript/chaiscript_threading.hpp @@ -1,7 +1,7 @@ // This file is distributed under the BSD License. // See "license.txt" for details. // Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) -// Copyright 2009-2017, Jason Turner (jason@emptycrate.com) +// Copyright 2009-2018, Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com // This is an open source non-commercial project. Dear PVS-Studio, please check it. diff --git a/include/chaiscript/dispatchkit/bad_boxed_cast.hpp b/include/chaiscript/dispatchkit/bad_boxed_cast.hpp index 1c1d729e..d880feab 100644 --- a/include/chaiscript/dispatchkit/bad_boxed_cast.hpp +++ b/include/chaiscript/dispatchkit/bad_boxed_cast.hpp @@ -1,7 +1,7 @@ // This file is distributed under the BSD License. // See "license.txt" for details. // Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) -// Copyright 2009-2017, Jason Turner (jason@emptycrate.com) +// Copyright 2009-2018, Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com // This is an open source non-commercial project. Dear PVS-Studio, please check it. diff --git a/include/chaiscript/dispatchkit/bind_first.hpp b/include/chaiscript/dispatchkit/bind_first.hpp index c65c8385..3dbcc4d2 100644 --- a/include/chaiscript/dispatchkit/bind_first.hpp +++ b/include/chaiscript/dispatchkit/bind_first.hpp @@ -1,7 +1,7 @@ // This file is distributed under the BSD License. // See "license.txt" for details. // Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) -// Copyright 2009-2017, Jason Turner (jason@emptycrate.com) +// Copyright 2009-2018, Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com // This is an open source non-commercial project. Dear PVS-Studio, please check it. diff --git a/include/chaiscript/dispatchkit/bootstrap.hpp b/include/chaiscript/dispatchkit/bootstrap.hpp index c74b86b9..c0ad7ce3 100644 --- a/include/chaiscript/dispatchkit/bootstrap.hpp +++ b/include/chaiscript/dispatchkit/bootstrap.hpp @@ -1,7 +1,7 @@ // This file is distributed under the BSD License. // See "license.txt" for details. // Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) -// Copyright 2009-2017, Jason Turner (jason@emptycrate.com) +// Copyright 2009-2018, Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com // This is an open source non-commercial project. Dear PVS-Studio, please check it. diff --git a/include/chaiscript/dispatchkit/bootstrap_stl.hpp b/include/chaiscript/dispatchkit/bootstrap_stl.hpp index bc3c0869..31c6deea 100644 --- a/include/chaiscript/dispatchkit/bootstrap_stl.hpp +++ b/include/chaiscript/dispatchkit/bootstrap_stl.hpp @@ -1,7 +1,7 @@ // This file is distributed under the BSD License. // See "license.txt" for details. // Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) -// Copyright 2009-2017, Jason Turner (jason@emptycrate.com) +// Copyright 2009-2018, Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com // This is an open source non-commercial project. Dear PVS-Studio, please check it. diff --git a/include/chaiscript/dispatchkit/boxed_cast.hpp b/include/chaiscript/dispatchkit/boxed_cast.hpp index b79d735b..4b6e4d79 100644 --- a/include/chaiscript/dispatchkit/boxed_cast.hpp +++ b/include/chaiscript/dispatchkit/boxed_cast.hpp @@ -1,7 +1,7 @@ // This file is distributed under the BSD License. // See "license.txt" for details. // Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) -// Copyright 2009-2017, Jason Turner (jason@emptycrate.com) +// Copyright 2009-2018, Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com // This is an open source non-commercial project. Dear PVS-Studio, please check it. diff --git a/include/chaiscript/dispatchkit/boxed_cast_helper.hpp b/include/chaiscript/dispatchkit/boxed_cast_helper.hpp index b00dd045..b7919bd2 100644 --- a/include/chaiscript/dispatchkit/boxed_cast_helper.hpp +++ b/include/chaiscript/dispatchkit/boxed_cast_helper.hpp @@ -1,7 +1,7 @@ // This file is distributed under the BSD License. // See "license.txt" for details. // Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) -// Copyright 2009-2017, Jason Turner (jason@emptycrate.com) +// Copyright 2009-2018, Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com // This is an open source non-commercial project. Dear PVS-Studio, please check it. diff --git a/include/chaiscript/dispatchkit/boxed_number.hpp b/include/chaiscript/dispatchkit/boxed_number.hpp index dafc1234..290a73ab 100644 --- a/include/chaiscript/dispatchkit/boxed_number.hpp +++ b/include/chaiscript/dispatchkit/boxed_number.hpp @@ -1,7 +1,7 @@ // This file is distributed under the BSD License. // See "license.txt" for details. // Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) -// Copyright 2009-2017, Jason Turner (jason@emptycrate.com) +// Copyright 2009-2018, Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com // This is an open source non-commercial project. Dear PVS-Studio, please check it. diff --git a/include/chaiscript/dispatchkit/boxed_value.hpp b/include/chaiscript/dispatchkit/boxed_value.hpp index ce943eb9..5b9e600d 100644 --- a/include/chaiscript/dispatchkit/boxed_value.hpp +++ b/include/chaiscript/dispatchkit/boxed_value.hpp @@ -1,7 +1,7 @@ // This file is distributed under the BSD License. // See "license.txt" for details. // Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) -// Copyright 2009-2017, Jason Turner (jason@emptycrate.com) +// Copyright 2009-2018, Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com // This is an open source non-commercial project. Dear PVS-Studio, please check it. diff --git a/include/chaiscript/dispatchkit/callable_traits.hpp b/include/chaiscript/dispatchkit/callable_traits.hpp index 4b61b088..30d0f532 100644 --- a/include/chaiscript/dispatchkit/callable_traits.hpp +++ b/include/chaiscript/dispatchkit/callable_traits.hpp @@ -1,7 +1,7 @@ // This file is distributed under the BSD License. // See "license.txt" for details. // Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) -// Copyright 2009-2017, Jason Turner (jason@emptycrate.com) +// Copyright 2009-2018, Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com #ifndef CHAISCRIPT_CALLABLE_TRAITS_HPP_ diff --git a/include/chaiscript/dispatchkit/dispatchkit.hpp b/include/chaiscript/dispatchkit/dispatchkit.hpp index 05f02535..39630742 100644 --- a/include/chaiscript/dispatchkit/dispatchkit.hpp +++ b/include/chaiscript/dispatchkit/dispatchkit.hpp @@ -1,7 +1,7 @@ // This file is distributed under the BSD License. // See "license.txt" for details. // Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) -// Copyright 2009-2017, Jason Turner (jason@emptycrate.com) +// Copyright 2009-2018, Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com // This is an open source non-commercial project. Dear PVS-Studio, please check it. diff --git a/include/chaiscript/dispatchkit/dynamic_object.hpp b/include/chaiscript/dispatchkit/dynamic_object.hpp index b5afaf15..91514724 100644 --- a/include/chaiscript/dispatchkit/dynamic_object.hpp +++ b/include/chaiscript/dispatchkit/dynamic_object.hpp @@ -1,7 +1,7 @@ // This file is distributed under the BSD License. // See "license.txt" for details. // Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) -// Copyright 2009-2017, Jason Turner (jason@emptycrate.com) +// Copyright 2009-2018, Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com // This is an open source non-commercial project. Dear PVS-Studio, please check it. diff --git a/include/chaiscript/dispatchkit/dynamic_object_detail.hpp b/include/chaiscript/dispatchkit/dynamic_object_detail.hpp index df90ab66..4a983746 100644 --- a/include/chaiscript/dispatchkit/dynamic_object_detail.hpp +++ b/include/chaiscript/dispatchkit/dynamic_object_detail.hpp @@ -1,7 +1,7 @@ // This file is distributed under the BSD License. // See "license.txt" for details. // Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) -// Copyright 2009-2017, Jason Turner (jason@emptycrate.com) +// Copyright 2009-2018, Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com #ifndef CHAISCRIPT_DYNAMIC_OBJECT_DETAIL_HPP_ diff --git a/include/chaiscript/dispatchkit/exception_specification.hpp b/include/chaiscript/dispatchkit/exception_specification.hpp index 79607fe2..53ef3920 100644 --- a/include/chaiscript/dispatchkit/exception_specification.hpp +++ b/include/chaiscript/dispatchkit/exception_specification.hpp @@ -1,7 +1,7 @@ // This file is distributed under the BSD License. // See "license.txt" for details. // Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) -// Copyright 2009-2017, Jason Turner (jason@emptycrate.com) +// Copyright 2009-2018, Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com // This is an open source non-commercial project. Dear PVS-Studio, please check it. diff --git a/include/chaiscript/dispatchkit/function_call.hpp b/include/chaiscript/dispatchkit/function_call.hpp index 1980f35c..33f08e5a 100644 --- a/include/chaiscript/dispatchkit/function_call.hpp +++ b/include/chaiscript/dispatchkit/function_call.hpp @@ -1,7 +1,7 @@ // This file is distributed under the BSD License. // See "license.txt" for details. // Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) -// Copyright 2009-2017, Jason Turner (jason@emptycrate.com) +// Copyright 2009-2018, Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com // This is an open source non-commercial project. Dear PVS-Studio, please check it. diff --git a/include/chaiscript/dispatchkit/function_call_detail.hpp b/include/chaiscript/dispatchkit/function_call_detail.hpp index d6cb241f..028ccbbc 100644 --- a/include/chaiscript/dispatchkit/function_call_detail.hpp +++ b/include/chaiscript/dispatchkit/function_call_detail.hpp @@ -1,7 +1,7 @@ // This file is distributed under the BSD License. // See "license.txt" for details. // Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) -// Copyright 2009-2017, Jason Turner (jason@emptycrate.com) +// Copyright 2009-2018, Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com // This is an open source non-commercial project. Dear PVS-Studio, please check it. diff --git a/include/chaiscript/dispatchkit/handle_return.hpp b/include/chaiscript/dispatchkit/handle_return.hpp index 8570c8d0..ea6b4dff 100644 --- a/include/chaiscript/dispatchkit/handle_return.hpp +++ b/include/chaiscript/dispatchkit/handle_return.hpp @@ -1,7 +1,7 @@ // This file is distributed under the BSD License. // See "license.txt" for details. // Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) -// Copyright 2009-2017, Jason Turner (jason@emptycrate.com) +// Copyright 2009-2018, Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com // This is an open source non-commercial project. Dear PVS-Studio, please check it. diff --git a/include/chaiscript/dispatchkit/operators.hpp b/include/chaiscript/dispatchkit/operators.hpp index 54c73b94..ceb177ad 100644 --- a/include/chaiscript/dispatchkit/operators.hpp +++ b/include/chaiscript/dispatchkit/operators.hpp @@ -1,7 +1,7 @@ // This file is distributed under the BSD License. // See "license.txt" for details. // Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) -// Copyright 2009-2017, Jason Turner (jason@emptycrate.com) +// Copyright 2009-2018, Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com // This is an open source non-commercial project. Dear PVS-Studio, please check it. diff --git a/include/chaiscript/dispatchkit/proxy_constructors.hpp b/include/chaiscript/dispatchkit/proxy_constructors.hpp index bbe79d7a..cfa5c775 100644 --- a/include/chaiscript/dispatchkit/proxy_constructors.hpp +++ b/include/chaiscript/dispatchkit/proxy_constructors.hpp @@ -1,7 +1,7 @@ // This file is distributed under the BSD License. // See "license.txt" for details. // Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) -// Copyright 2009-2017, Jason Turner (jason@emptycrate.com) +// Copyright 2009-2018, Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com // This is an open source non-commercial project. Dear PVS-Studio, please check it. diff --git a/include/chaiscript/dispatchkit/proxy_functions.hpp b/include/chaiscript/dispatchkit/proxy_functions.hpp index 0c60315f..fb9bc2d1 100644 --- a/include/chaiscript/dispatchkit/proxy_functions.hpp +++ b/include/chaiscript/dispatchkit/proxy_functions.hpp @@ -1,7 +1,7 @@ // This file is distributed under the BSD License. // See "license.txt" for details. // Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) -// Copyright 2009-2017, Jason Turner (jason@emptycrate.com) +// Copyright 2009-2018, Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com // This is an open source non-commercial project. Dear PVS-Studio, please check it. diff --git a/include/chaiscript/dispatchkit/proxy_functions_detail.hpp b/include/chaiscript/dispatchkit/proxy_functions_detail.hpp index 9ce58468..f2c89bad 100644 --- a/include/chaiscript/dispatchkit/proxy_functions_detail.hpp +++ b/include/chaiscript/dispatchkit/proxy_functions_detail.hpp @@ -1,7 +1,7 @@ // This file is distributed under the BSD License. // See "license.txt" for details. // Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) -// Copyright 2009-2017, Jason Turner (jason@emptycrate.com) +// Copyright 2009-2018, Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com // This is an open source non-commercial project. Dear PVS-Studio, please check it. diff --git a/include/chaiscript/dispatchkit/register_function.hpp b/include/chaiscript/dispatchkit/register_function.hpp index 2e56fe0e..1fc44469 100644 --- a/include/chaiscript/dispatchkit/register_function.hpp +++ b/include/chaiscript/dispatchkit/register_function.hpp @@ -1,7 +1,7 @@ // This file is distributed under the BSD License. // See "license.txt" for details. // Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) -// Copyright 2009-2017, Jason Turner (jason@emptycrate.com) +// Copyright 2009-2018, Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com // This is an open source non-commercial project. Dear PVS-Studio, please check it. diff --git a/include/chaiscript/dispatchkit/type_conversions.hpp b/include/chaiscript/dispatchkit/type_conversions.hpp index d9d2f374..a333943c 100644 --- a/include/chaiscript/dispatchkit/type_conversions.hpp +++ b/include/chaiscript/dispatchkit/type_conversions.hpp @@ -1,7 +1,7 @@ // This file is distributed under the BSD License. // See "license.txt" for details. // Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) -// Copyright 2009-2017, Jason Turner (jason@emptycrate.com) +// Copyright 2009-2018, Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com // This is an open source non-commercial project. Dear PVS-Studio, please check it. diff --git a/include/chaiscript/dispatchkit/type_info.hpp b/include/chaiscript/dispatchkit/type_info.hpp index 53f007b0..b76b5493 100644 --- a/include/chaiscript/dispatchkit/type_info.hpp +++ b/include/chaiscript/dispatchkit/type_info.hpp @@ -1,7 +1,7 @@ // This file is distributed under the BSD License. // See "license.txt" for details. // Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) -// Copyright 2009-2017, Jason Turner (jason@emptycrate.com) +// Copyright 2009-2018, Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com // This is an open source non-commercial project. Dear PVS-Studio, please check it. diff --git a/include/chaiscript/language/chaiscript_algebraic.hpp b/include/chaiscript/language/chaiscript_algebraic.hpp index 8a49d2ee..8f4a1b27 100644 --- a/include/chaiscript/language/chaiscript_algebraic.hpp +++ b/include/chaiscript/language/chaiscript_algebraic.hpp @@ -1,7 +1,7 @@ // This file is distributed under the BSD License. // See "license.txt" for details. // Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) -// Copyright 2009-2017, Jason Turner (jason@emptycrate.com) +// Copyright 2009-2018, Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com // This is an open source non-commercial project. Dear PVS-Studio, please check it. diff --git a/include/chaiscript/language/chaiscript_common.hpp b/include/chaiscript/language/chaiscript_common.hpp index 73e5f027..4e107efb 100644 --- a/include/chaiscript/language/chaiscript_common.hpp +++ b/include/chaiscript/language/chaiscript_common.hpp @@ -1,7 +1,7 @@ // This file is distributed under the BSD License. // See "license.txt" for details. // Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) -// Copyright 2009-2017, Jason Turner (jason@emptycrate.com) +// Copyright 2009-2018, Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com // This is an open source non-commercial project. Dear PVS-Studio, please check it. diff --git a/include/chaiscript/language/chaiscript_engine.hpp b/include/chaiscript/language/chaiscript_engine.hpp index 3e6d0d84..404b836c 100644 --- a/include/chaiscript/language/chaiscript_engine.hpp +++ b/include/chaiscript/language/chaiscript_engine.hpp @@ -1,7 +1,7 @@ // This file is distributed under the BSD License. // See "license.txt" for details. // Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) -// Copyright 2009-2017, Jason Turner (jason@emptycrate.com) +// Copyright 2009-2018, Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com // This is an open source non-commercial project. Dear PVS-Studio, please check it. diff --git a/include/chaiscript/language/chaiscript_eval.hpp b/include/chaiscript/language/chaiscript_eval.hpp index b6cdfe67..83d00403 100644 --- a/include/chaiscript/language/chaiscript_eval.hpp +++ b/include/chaiscript/language/chaiscript_eval.hpp @@ -1,7 +1,7 @@ // This file is distributed under the BSD License. // See "license.txt" for details. // Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) -// Copyright 2009-2017, Jason Turner (jason@emptycrate.com) +// Copyright 2009-2018, Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com // This is an open source non-commercial project. Dear PVS-Studio, please check it. diff --git a/include/chaiscript/language/chaiscript_optimizer.hpp b/include/chaiscript/language/chaiscript_optimizer.hpp index 4bcae1a4..53fdc833 100644 --- a/include/chaiscript/language/chaiscript_optimizer.hpp +++ b/include/chaiscript/language/chaiscript_optimizer.hpp @@ -1,7 +1,7 @@ // This file is distributed under the BSD License. // See "license.txt" for details. // Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) -// Copyright 2009-2017, Jason Turner (jason@emptycrate.com) +// Copyright 2009-2018, Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com #ifndef CHAISCRIPT_OPTIMIZER_HPP_ diff --git a/include/chaiscript/language/chaiscript_parser.hpp b/include/chaiscript/language/chaiscript_parser.hpp index 848296c9..1a401316 100644 --- a/include/chaiscript/language/chaiscript_parser.hpp +++ b/include/chaiscript/language/chaiscript_parser.hpp @@ -1,7 +1,7 @@ // This file is distributed under the BSD License. // See "license.txt" for details. // Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) -// Copyright 2009-2017, Jason Turner (jason@emptycrate.com) +// Copyright 2009-2018, Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com // This is an open source non-commercial project. Dear PVS-Studio, please check it. diff --git a/include/chaiscript/language/chaiscript_posix.hpp b/include/chaiscript/language/chaiscript_posix.hpp index 87b66881..b909347a 100644 --- a/include/chaiscript/language/chaiscript_posix.hpp +++ b/include/chaiscript/language/chaiscript_posix.hpp @@ -1,7 +1,7 @@ // This file is distributed under the BSD License. // See "license.txt" for details. // Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) -// Copyright 2009-2017, Jason Turner (jason@emptycrate.com) +// Copyright 2009-2018, Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com #ifndef CHAISCRIPT_POSIX_HPP_ diff --git a/include/chaiscript/language/chaiscript_prelude.hpp b/include/chaiscript/language/chaiscript_prelude.hpp index a4deb874..5e470993 100644 --- a/include/chaiscript/language/chaiscript_prelude.hpp +++ b/include/chaiscript/language/chaiscript_prelude.hpp @@ -1,7 +1,7 @@ // This file is distributed under the BSD License. // See "license.txt" for details. // Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) -// and 2009-2017, Jason Turner (jason@emptycrate.com) +// and 2009-2018, Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com #ifndef CHAISCRIPT_PRELUDE_HPP_ diff --git a/include/chaiscript/language/chaiscript_tracer.hpp b/include/chaiscript/language/chaiscript_tracer.hpp index 9d111815..a19b0bc8 100644 --- a/include/chaiscript/language/chaiscript_tracer.hpp +++ b/include/chaiscript/language/chaiscript_tracer.hpp @@ -1,7 +1,7 @@ // This file is distributed under the BSD License. // See "license.txt" for details. // Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) -// Copyright 2009-2017, Jason Turner (jason@emptycrate.com) +// Copyright 2009-2018, Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com #ifndef CHAISCRIPT_TRACER_HPP_ diff --git a/include/chaiscript/language/chaiscript_unknown.hpp b/include/chaiscript/language/chaiscript_unknown.hpp index 8fc1d494..be63ddef 100644 --- a/include/chaiscript/language/chaiscript_unknown.hpp +++ b/include/chaiscript/language/chaiscript_unknown.hpp @@ -1,7 +1,7 @@ // This file is distributed under the BSD License. // See "license.txt" for details. // Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) -// Copyright 2009-2017, Jason Turner (jason@emptycrate.com) +// Copyright 2009-2018, Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com #ifndef CHAISCRIPT_UNKNOWN_HPP_ diff --git a/include/chaiscript/language/chaiscript_windows.hpp b/include/chaiscript/language/chaiscript_windows.hpp index 493572c2..46443232 100644 --- a/include/chaiscript/language/chaiscript_windows.hpp +++ b/include/chaiscript/language/chaiscript_windows.hpp @@ -1,7 +1,7 @@ // This file is distributed under the BSD License. // See "license.txt" for details. // Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) -// Copyright 2009-2017, Jason Turner (jason@emptycrate.com) +// Copyright 2009-2018, Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com #ifndef CHAISCRIPT_WINDOWS_HPP_ diff --git a/include/chaiscript/utility/fnv1a.hpp b/include/chaiscript/utility/fnv1a.hpp index 9e549928..1d7f378d 100644 --- a/include/chaiscript/utility/fnv1a.hpp +++ b/include/chaiscript/utility/fnv1a.hpp @@ -1,7 +1,7 @@ // This file is distributed under the BSD License. // See "license.txt" for details. // Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) -// Copyright 2009-2017, Jason Turner (jason@emptycrate.com) +// Copyright 2009-2018, Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com #ifndef CHAISCRIPT_UTILITY_FNV1A_HPP_ diff --git a/include/chaiscript/utility/static_string.hpp b/include/chaiscript/utility/static_string.hpp index 49edfbd8..0d63fd9f 100644 --- a/include/chaiscript/utility/static_string.hpp +++ b/include/chaiscript/utility/static_string.hpp @@ -1,7 +1,7 @@ // This file is distributed under the BSD License. // See "license.txt" for details. // Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) -// Copyright 2009-2017, Jason Turner (jason@emptycrate.com) +// Copyright 2009-2018, Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com #ifndef CHAISCRIPT_UTILITY_STATIC_STRING_HPP_ diff --git a/include/chaiscript/utility/utility.hpp b/include/chaiscript/utility/utility.hpp index b743c451..b57d4d01 100644 --- a/include/chaiscript/utility/utility.hpp +++ b/include/chaiscript/utility/utility.hpp @@ -1,7 +1,7 @@ // This file is distributed under the BSD License. // See "license.txt" for details. // Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) -// Copyright 2009-2017, Jason Turner (jason@emptycrate.com) +// Copyright 2009-2018, Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com // This is an open source non-commercial project. Dear PVS-Studio, please check it. diff --git a/license.txt b/license.txt index 8e6a6b98..4874fcdf 100644 --- a/license.txt +++ b/license.txt @@ -1,6 +1,6 @@ BSD-3-Clause License -Copyright 2009-2016 Jason Turner +Copyright 2009-2018 Jason Turner Copyright 2009-2012 Jonathan Turner. All Rights Reserved. diff --git a/samples/fun_call_performance.cpp b/samples/fun_call_performance.cpp index 31fa606c..e2476cb5 100644 --- a/samples/fun_call_performance.cpp +++ b/samples/fun_call_performance.cpp @@ -1,7 +1,7 @@ // This file is distributed under the BSD License. // See "license.txt" for details. // Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) -// Copyright 2009-2017, Jason Turner (jason@emptycrate.com) +// Copyright 2009-2018, Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com // This is an open source non-commercial project. Dear PVS-Studio, please check it. diff --git a/src/libfuzzer_client.cpp b/src/libfuzzer_client.cpp index 28927ee1..4dec4560 100644 --- a/src/libfuzzer_client.cpp +++ b/src/libfuzzer_client.cpp @@ -1,7 +1,7 @@ // This file is distributed under the BSD License. // See "license.txt" for details. // Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) -// Copyright 2009-2017, Jason Turner (jason@emptycrate.com) +// Copyright 2009-2018, Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com // This is an open source non-commercial project. Dear PVS-Studio, please check it. diff --git a/src/main.cpp b/src/main.cpp index b5d55520..7fbc1cb1 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,7 +1,7 @@ // This file is distributed under the BSD License. // See "license.txt" for details. // Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) -// Copyright 2009-2017, Jason Turner (jason@emptycrate.com) +// Copyright 2009-2018, Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com // This is an open source non-commercial project. Dear PVS-Studio, please check it. diff --git a/src/stl_extra.cpp b/src/stl_extra.cpp index cd0ec663..90657580 100644 --- a/src/stl_extra.cpp +++ b/src/stl_extra.cpp @@ -1,7 +1,7 @@ // This file is distributed under the BSD License. // See "license.txt" for details. // Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) -// Copyright 2009-2017, Jason Turner (jason@emptycrate.com) +// Copyright 2009-2018, Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com // This is an open source non-commercial project. Dear PVS-Studio, please check it. From 07fdb3bf6e98063b3e111b71ec5cbe4805197a26 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Sun, 3 Jun 2018 16:48:03 -0600 Subject: [PATCH 074/155] Remove backward compatibility tests --- unittests/3.x/assign_const.chai | 2 - unittests/3.x/bind.chai | 2 - unittests/3.x/bind2.chai | 34 --------- unittests/3.x/block_start.chai | 1 - unittests/3.x/bool_not.chai | 1 - unittests/3.x/break_while.chai | 7 -- unittests/3.x/char_init.chai | 1 - unittests/3.x/classification.chai | 7 -- unittests/3.x/collate.chai | 3 - unittests/3.x/compare_gt.chai | 1 - unittests/3.x/compare_lt.chai | 1 - unittests/3.x/concat.chai | 5 -- unittests/3.x/const_range_test.chai | 4 - unittests/3.x/convert_double_string.chai | 1 - unittests/3.x/convert_int_string.chai | 1 - unittests/3.x/convert_string_double.chai | 1 - unittests/3.x/convert_string_int.chai | 1 - unittests/3.x/deep_array_lookup.chai | 11 --- unittests/3.x/dispatch_functions.chai | 10 --- unittests/3.x/drop.chai | 1 - unittests/3.x/drop_while.chai | 1 - unittests/3.x/empty.chai | 0 unittests/3.x/equ_shortform.chai | 4 - unittests/3.x/eval.chai | 1 - unittests/3.x/eval_error.chai | 38 ---------- unittests/3.x/even.chai | 1 - unittests/3.x/exception.chai | 9 --- unittests/3.x/exception_finally.chai | 32 -------- unittests/3.x/filter.chai | 1 - unittests/3.x/float.chai | 7 -- unittests/3.x/foldl.chai | 1 - unittests/3.x/for.chai | 7 -- unittests/3.x/for_each.chai | 1 - unittests/3.x/for_each_range.chai | 3 - unittests/3.x/for_each_retro.chai | 4 - unittests/3.x/function_array_adjacent.chai | 1 - unittests/3.x/function_introspection.chai | 75 ------------------- unittests/3.x/function_reassignment.chai | 3 - unittests/3.x/generate_range.chai | 1 - unittests/3.x/global_const_in_module.chai | 7 -- unittests/3.x/if.chai | 7 -- unittests/3.x/if_else.chai | 13 ---- unittests/3.x/if_elseif.chai | 18 ----- unittests/3.x/if_elseif_else.chai | 14 ---- unittests/3.x/index_operator.chai | 10 --- unittests/3.x/inheritance.chai | 8 -- unittests/3.x/instring_eval.chai | 3 - unittests/3.x/instring_eval_more.chai | 4 - .../3.x/invalid_function_assignment.chai | 1 - .../3.x/invalid_function_reassignment.chai | 2 - unittests/3.x/is_undef.chai | 4 - unittests/3.x/join.chai | 1 - unittests/3.x/lambda.chai | 2 - unittests/3.x/list_push_back.chai | 8 -- unittests/3.x/list_push_front.chai | 8 -- unittests/3.x/load_module.chai | 2 - unittests/3.x/loop_inner_outer.chai | 9 --- unittests/3.x/malformed_inline_map.chai | 8 -- unittests/3.x/map.chai | 1 - unittests/3.x/map_access.chai | 2 - unittests/3.x/map_inplace_init.chai | 3 - unittests/3.x/math_add.chai | 1 - unittests/3.x/math_add_mixed.chai | 1 - unittests/3.x/math_dec.chai | 3 - unittests/3.x/math_div.chai | 1 - unittests/3.x/math_inc.chai | 3 - unittests/3.x/math_mod.chai | 1 - unittests/3.x/math_mult.chai | 1 - unittests/3.x/math_negate.chai | 1 - unittests/3.x/math_paren.chai | 1 - unittests/3.x/math_sub.chai | 1 - unittests/3.x/max.chai | 1 - unittests/3.x/memberscope.chai | 12 --- unittests/3.x/method_sugar.chai | 1 - unittests/3.x/min.chai | 1 - unittests/3.x/mmd1.chai | 20 ----- unittests/3.x/mmd2.chai | 9 --- unittests/3.x/multiline.chai | 9 --- unittests/3.x/number_formats.chai | 3 - unittests/3.x/object_attr.chai | 6 -- unittests/3.x/object_attr_same_name.chai | 9 --- unittests/3.x/object_clone.chai | 11 --- unittests/3.x/object_constructor_guards.chai | 10 --- unittests/3.x/object_method_guards.chai | 7 -- unittests/3.x/odd.chai | 1 - unittests/3.x/operator_overload.chai | 9 --- unittests/3.x/operator_overload2.chai | 9 --- unittests/3.x/operators_float.chai | 16 ---- unittests/3.x/operators_int.chai | 31 -------- unittests/3.x/pair.chai | 5 -- .../3.x/pointer_passed_to_constructor.chai | 8 -- unittests/3.x/precedence_1.chai | 1 - unittests/3.x/precedence_2.chai | 1 - unittests/3.x/precedence_3.chai | 1 - unittests/3.x/precedence_eq.chai | 3 - unittests/3.x/product.chai | 1 - unittests/3.x/range.chai | 4 - unittests/3.x/range_back.chai | 4 - unittests/3.x/range_contains.chai | 5 -- unittests/3.x/range_find.chai | 6 -- unittests/3.x/range_inplace.chai | 1 - unittests/3.x/reduce.chai | 1 - unittests/3.x/ref_equal.chai | 5 -- unittests/3.x/retro.chai | 4 - unittests/3.x/retroretro.chai | 7 -- unittests/3.x/return.chai | 5 -- unittests/3.x/runtime_error.chai | 11 --- unittests/3.x/shift.chai | 1 - unittests/3.x/string_charptr.chai | 6 -- unittests/3.x/string_concat.chai | 1 - unittests/3.x/string_find.chai | 1 - unittests/3.x/string_find_first_not_of.chai | 1 - unittests/3.x/string_find_first_of.chai | 1 - unittests/3.x/string_find_last_not_of.chai | 1 - unittests/3.x/string_find_last_of.chai | 1 - unittests/3.x/string_init.chai | 1 - unittests/3.x/string_literal_access.chai | 1 - unittests/3.x/string_rfind.chai | 1 - unittests/3.x/sum.chai | 1 - unittests/3.x/switch_break.chai | 22 ------ unittests/3.x/switch_default.chai | 18 ----- unittests/3.x/switch_empty.chai | 4 - unittests/3.x/switch_fallthru.chai | 18 ----- unittests/3.x/switch_fallthru_and_break.chai | 19 ----- unittests/3.x/take.chai | 1 - unittests/3.x/take_while.chai | 1 - unittests/3.x/type_info.chai | 11 --- unittests/3.x/unit_test.inc | 53 ------------- unittests/3.x/use.chai | 9 --- unittests/3.x/use.inc | 4 - unittests/3.x/vector_access.chai | 2 - unittests/3.x/vector_erase_at.chai | 3 - unittests/3.x/vector_inplace_init.chai | 2 - unittests/3.x/vector_insert_at.chai | 3 - unittests/3.x/vector_literal_acccess.chai | 1 - unittests/3.x/vector_of_one.chai | 2 - .../3.x/vector_paren_literal_access.chai | 1 - unittests/3.x/vector_push_back.chai | 5 -- unittests/3.x/vector_push_empty.chai | 4 - unittests/3.x/zip.chai | 5 -- unittests/3.x/zip_with.chai | 3 - 141 files changed, 880 deletions(-) delete mode 100644 unittests/3.x/assign_const.chai delete mode 100644 unittests/3.x/bind.chai delete mode 100644 unittests/3.x/bind2.chai delete mode 100644 unittests/3.x/block_start.chai delete mode 100644 unittests/3.x/bool_not.chai delete mode 100644 unittests/3.x/break_while.chai delete mode 100644 unittests/3.x/char_init.chai delete mode 100644 unittests/3.x/classification.chai delete mode 100644 unittests/3.x/collate.chai delete mode 100644 unittests/3.x/compare_gt.chai delete mode 100644 unittests/3.x/compare_lt.chai delete mode 100644 unittests/3.x/concat.chai delete mode 100644 unittests/3.x/const_range_test.chai delete mode 100644 unittests/3.x/convert_double_string.chai delete mode 100644 unittests/3.x/convert_int_string.chai delete mode 100644 unittests/3.x/convert_string_double.chai delete mode 100644 unittests/3.x/convert_string_int.chai delete mode 100644 unittests/3.x/deep_array_lookup.chai delete mode 100644 unittests/3.x/dispatch_functions.chai delete mode 100644 unittests/3.x/drop.chai delete mode 100644 unittests/3.x/drop_while.chai delete mode 100644 unittests/3.x/empty.chai delete mode 100644 unittests/3.x/equ_shortform.chai delete mode 100644 unittests/3.x/eval.chai delete mode 100644 unittests/3.x/eval_error.chai delete mode 100644 unittests/3.x/even.chai delete mode 100644 unittests/3.x/exception.chai delete mode 100644 unittests/3.x/exception_finally.chai delete mode 100644 unittests/3.x/filter.chai delete mode 100644 unittests/3.x/float.chai delete mode 100644 unittests/3.x/foldl.chai delete mode 100644 unittests/3.x/for.chai delete mode 100644 unittests/3.x/for_each.chai delete mode 100644 unittests/3.x/for_each_range.chai delete mode 100644 unittests/3.x/for_each_retro.chai delete mode 100644 unittests/3.x/function_array_adjacent.chai delete mode 100644 unittests/3.x/function_introspection.chai delete mode 100644 unittests/3.x/function_reassignment.chai delete mode 100644 unittests/3.x/generate_range.chai delete mode 100644 unittests/3.x/global_const_in_module.chai delete mode 100644 unittests/3.x/if.chai delete mode 100644 unittests/3.x/if_else.chai delete mode 100644 unittests/3.x/if_elseif.chai delete mode 100644 unittests/3.x/if_elseif_else.chai delete mode 100644 unittests/3.x/index_operator.chai delete mode 100644 unittests/3.x/inheritance.chai delete mode 100644 unittests/3.x/instring_eval.chai delete mode 100644 unittests/3.x/instring_eval_more.chai delete mode 100644 unittests/3.x/invalid_function_assignment.chai delete mode 100644 unittests/3.x/invalid_function_reassignment.chai delete mode 100644 unittests/3.x/is_undef.chai delete mode 100644 unittests/3.x/join.chai delete mode 100644 unittests/3.x/lambda.chai delete mode 100644 unittests/3.x/list_push_back.chai delete mode 100644 unittests/3.x/list_push_front.chai delete mode 100644 unittests/3.x/load_module.chai delete mode 100644 unittests/3.x/loop_inner_outer.chai delete mode 100644 unittests/3.x/malformed_inline_map.chai delete mode 100644 unittests/3.x/map.chai delete mode 100644 unittests/3.x/map_access.chai delete mode 100644 unittests/3.x/map_inplace_init.chai delete mode 100644 unittests/3.x/math_add.chai delete mode 100644 unittests/3.x/math_add_mixed.chai delete mode 100644 unittests/3.x/math_dec.chai delete mode 100644 unittests/3.x/math_div.chai delete mode 100644 unittests/3.x/math_inc.chai delete mode 100644 unittests/3.x/math_mod.chai delete mode 100644 unittests/3.x/math_mult.chai delete mode 100644 unittests/3.x/math_negate.chai delete mode 100644 unittests/3.x/math_paren.chai delete mode 100644 unittests/3.x/math_sub.chai delete mode 100644 unittests/3.x/max.chai delete mode 100644 unittests/3.x/memberscope.chai delete mode 100644 unittests/3.x/method_sugar.chai delete mode 100644 unittests/3.x/min.chai delete mode 100644 unittests/3.x/mmd1.chai delete mode 100644 unittests/3.x/mmd2.chai delete mode 100644 unittests/3.x/multiline.chai delete mode 100644 unittests/3.x/number_formats.chai delete mode 100644 unittests/3.x/object_attr.chai delete mode 100644 unittests/3.x/object_attr_same_name.chai delete mode 100644 unittests/3.x/object_clone.chai delete mode 100644 unittests/3.x/object_constructor_guards.chai delete mode 100644 unittests/3.x/object_method_guards.chai delete mode 100644 unittests/3.x/odd.chai delete mode 100644 unittests/3.x/operator_overload.chai delete mode 100644 unittests/3.x/operator_overload2.chai delete mode 100644 unittests/3.x/operators_float.chai delete mode 100644 unittests/3.x/operators_int.chai delete mode 100644 unittests/3.x/pair.chai delete mode 100644 unittests/3.x/pointer_passed_to_constructor.chai delete mode 100644 unittests/3.x/precedence_1.chai delete mode 100644 unittests/3.x/precedence_2.chai delete mode 100644 unittests/3.x/precedence_3.chai delete mode 100644 unittests/3.x/precedence_eq.chai delete mode 100644 unittests/3.x/product.chai delete mode 100644 unittests/3.x/range.chai delete mode 100644 unittests/3.x/range_back.chai delete mode 100644 unittests/3.x/range_contains.chai delete mode 100644 unittests/3.x/range_find.chai delete mode 100644 unittests/3.x/range_inplace.chai delete mode 100644 unittests/3.x/reduce.chai delete mode 100644 unittests/3.x/ref_equal.chai delete mode 100644 unittests/3.x/retro.chai delete mode 100644 unittests/3.x/retroretro.chai delete mode 100644 unittests/3.x/return.chai delete mode 100644 unittests/3.x/runtime_error.chai delete mode 100644 unittests/3.x/shift.chai delete mode 100644 unittests/3.x/string_charptr.chai delete mode 100644 unittests/3.x/string_concat.chai delete mode 100644 unittests/3.x/string_find.chai delete mode 100644 unittests/3.x/string_find_first_not_of.chai delete mode 100644 unittests/3.x/string_find_first_of.chai delete mode 100644 unittests/3.x/string_find_last_not_of.chai delete mode 100644 unittests/3.x/string_find_last_of.chai delete mode 100644 unittests/3.x/string_init.chai delete mode 100644 unittests/3.x/string_literal_access.chai delete mode 100644 unittests/3.x/string_rfind.chai delete mode 100644 unittests/3.x/sum.chai delete mode 100644 unittests/3.x/switch_break.chai delete mode 100644 unittests/3.x/switch_default.chai delete mode 100644 unittests/3.x/switch_empty.chai delete mode 100644 unittests/3.x/switch_fallthru.chai delete mode 100644 unittests/3.x/switch_fallthru_and_break.chai delete mode 100644 unittests/3.x/take.chai delete mode 100644 unittests/3.x/take_while.chai delete mode 100644 unittests/3.x/type_info.chai delete mode 100644 unittests/3.x/unit_test.inc delete mode 100644 unittests/3.x/use.chai delete mode 100644 unittests/3.x/use.inc delete mode 100644 unittests/3.x/vector_access.chai delete mode 100644 unittests/3.x/vector_erase_at.chai delete mode 100644 unittests/3.x/vector_inplace_init.chai delete mode 100644 unittests/3.x/vector_insert_at.chai delete mode 100644 unittests/3.x/vector_literal_acccess.chai delete mode 100644 unittests/3.x/vector_of_one.chai delete mode 100644 unittests/3.x/vector_paren_literal_access.chai delete mode 100644 unittests/3.x/vector_push_back.chai delete mode 100644 unittests/3.x/vector_push_empty.chai delete mode 100644 unittests/3.x/zip.chai delete mode 100644 unittests/3.x/zip_with.chai diff --git a/unittests/3.x/assign_const.chai b/unittests/3.x/assign_const.chai deleted file mode 100644 index 9726ed50..00000000 --- a/unittests/3.x/assign_const.chai +++ /dev/null @@ -1,2 +0,0 @@ -assert_throws("Error: \"Error, cannot assign to constant value.\"", fun() { 1 = 2 } ); -assert_throws("Error: \"Error, cannot assign to constant value.\"", fun() { 1 + 2 = 2 } ); diff --git a/unittests/3.x/bind.chai b/unittests/3.x/bind.chai deleted file mode 100644 index 3c72673f..00000000 --- a/unittests/3.x/bind.chai +++ /dev/null @@ -1,2 +0,0 @@ -var prod = bind(foldl, _, `*`, 1.0) -assert_equal(60, prod([3, 4, 5])) diff --git a/unittests/3.x/bind2.chai b/unittests/3.x/bind2.chai deleted file mode 100644 index 0b8ddde3..00000000 --- a/unittests/3.x/bind2.chai +++ /dev/null @@ -1,34 +0,0 @@ - -def add(x, y) -{ - return x + y; -} - -assert_equal(2, add.get_arity()); - -var b = bind(add, 2, _); - -assert_equal(1, b.get_arity()); - -var c = bind(b, 3); - -assert_equal(0, c.get_arity()); - -assert_equal(6, b(4)); -assert_equal(5, c()); - -def concat2(a,b,c,d) -{ - return to_string(a) + to_string(b) + to_string(c) + to_string(d); -} - -var d = bind(concat2, _, " Hello ", _, " World"); -assert_equal(2, d.get_arity()); - -assert_equal("1 Hello 3 World", d(1,3)); - -var e = bind(`<`, _, 5); -var types = e.get_param_types(); -assert_equal(2, types.size()); -assert_equal(true, types[0].bare_equal(bool_type)); - diff --git a/unittests/3.x/block_start.chai b/unittests/3.x/block_start.chai deleted file mode 100644 index 4830af1f..00000000 --- a/unittests/3.x/block_start.chai +++ /dev/null @@ -1 +0,0 @@ -{print("hello")} diff --git a/unittests/3.x/bool_not.chai b/unittests/3.x/bool_not.chai deleted file mode 100644 index fe4d0f77..00000000 --- a/unittests/3.x/bool_not.chai +++ /dev/null @@ -1 +0,0 @@ -assert_equal(false, !true) diff --git a/unittests/3.x/break_while.chai b/unittests/3.x/break_while.chai deleted file mode 100644 index 5ff897c8..00000000 --- a/unittests/3.x/break_while.chai +++ /dev/null @@ -1,7 +0,0 @@ -var i = 0 -while (i < 10) { - if (++i == 5) { - break - } -} -assert_equal(5, i); diff --git a/unittests/3.x/char_init.chai b/unittests/3.x/char_init.chai deleted file mode 100644 index ce764774..00000000 --- a/unittests/3.x/char_init.chai +++ /dev/null @@ -1 +0,0 @@ -assert_equal("b", to_string('b')) diff --git a/unittests/3.x/classification.chai b/unittests/3.x/classification.chai deleted file mode 100644 index 8c2cca94..00000000 --- a/unittests/3.x/classification.chai +++ /dev/null @@ -1,7 +0,0 @@ -assert_equal(true, 1.is_var_const()); -assert_equal(false, 1.is_var_reference()); -assert_equal(true, 1.is_var_pointer()); -assert_equal(false, 1.is_var_null()); -assert_equal(false, 1.is_var_undef()); -var i; -assert_equal(true, i.is_var_undef()); diff --git a/unittests/3.x/collate.chai b/unittests/3.x/collate.chai deleted file mode 100644 index 12632e59..00000000 --- a/unittests/3.x/collate.chai +++ /dev/null @@ -1,3 +0,0 @@ -var v = collate(1, 2) -assert_equal(1, v[0]) -assert_equal(2, v[1]) diff --git a/unittests/3.x/compare_gt.chai b/unittests/3.x/compare_gt.chai deleted file mode 100644 index 9a6ea456..00000000 --- a/unittests/3.x/compare_gt.chai +++ /dev/null @@ -1 +0,0 @@ -assert_equal(false, 1 > 2); diff --git a/unittests/3.x/compare_lt.chai b/unittests/3.x/compare_lt.chai deleted file mode 100644 index 60641103..00000000 --- a/unittests/3.x/compare_lt.chai +++ /dev/null @@ -1 +0,0 @@ -assert_equal(true, 1 < 2) diff --git a/unittests/3.x/concat.chai b/unittests/3.x/concat.chai deleted file mode 100644 index 3d285a5b..00000000 --- a/unittests/3.x/concat.chai +++ /dev/null @@ -1,5 +0,0 @@ -var v = concat([1, 2], [3, 4]); - -assert_equal(4, v.size()); -assert_equal(1, v[0]); -assert_equal(4, v[3]); diff --git a/unittests/3.x/const_range_test.chai b/unittests/3.x/const_range_test.chai deleted file mode 100644 index 5ebb5808..00000000 --- a/unittests/3.x/const_range_test.chai +++ /dev/null @@ -1,4 +0,0 @@ -//If the following succeeds, the test passes - - -"Hello World".for_each(fun(x) { print(x) } ) diff --git a/unittests/3.x/convert_double_string.chai b/unittests/3.x/convert_double_string.chai deleted file mode 100644 index e12b90f2..00000000 --- a/unittests/3.x/convert_double_string.chai +++ /dev/null @@ -1 +0,0 @@ -assert_equal("3.5bob", 3.5.to_string() + "bob"); diff --git a/unittests/3.x/convert_int_string.chai b/unittests/3.x/convert_int_string.chai deleted file mode 100644 index 0fcda326..00000000 --- a/unittests/3.x/convert_int_string.chai +++ /dev/null @@ -1 +0,0 @@ -assert_equal("3bob", 3.to_string + "bob") diff --git a/unittests/3.x/convert_string_double.chai b/unittests/3.x/convert_string_double.chai deleted file mode 100644 index b7b0b6ef..00000000 --- a/unittests/3.x/convert_string_double.chai +++ /dev/null @@ -1 +0,0 @@ -assert_equal(6.8, "3.5".to_double() + 3.3) diff --git a/unittests/3.x/convert_string_int.chai b/unittests/3.x/convert_string_int.chai deleted file mode 100644 index e62eec95..00000000 --- a/unittests/3.x/convert_string_int.chai +++ /dev/null @@ -1 +0,0 @@ -assert_equal(8, "4".to_int() + 4) diff --git a/unittests/3.x/deep_array_lookup.chai b/unittests/3.x/deep_array_lookup.chai deleted file mode 100644 index c405302d..00000000 --- a/unittests/3.x/deep_array_lookup.chai +++ /dev/null @@ -1,11 +0,0 @@ -var a = [1,2,3, [4,5,6] ] - -assert_equal(a[3][0], 4) - - -def Test::Test() { this.a = [1,2,3]; } -attr Test::a; - -var t = Test(); - -assert_equal(t.a[0], 1) diff --git a/unittests/3.x/dispatch_functions.chai b/unittests/3.x/dispatch_functions.chai deleted file mode 100644 index f25ae017..00000000 --- a/unittests/3.x/dispatch_functions.chai +++ /dev/null @@ -1,10 +0,0 @@ -assert_equal(`==`, `==`); -assert_not_equal(`==`, `<`); -assert_equal(`<`.get_arity(), 2); -assert_equal(get_arity.get_contained_functions().size(), 0); -assert_equal(get_arity.get_arity(), 1); -assert_equal(get_arity.get_param_types().size(), 2); - -var paramtypes = get_arity.get_param_types(); - -assert_equal(true, paramtypes[1].bare_equal(Function_type)); diff --git a/unittests/3.x/drop.chai b/unittests/3.x/drop.chai deleted file mode 100644 index c64b431e..00000000 --- a/unittests/3.x/drop.chai +++ /dev/null @@ -1 +0,0 @@ -assert_equal([3,4], drop([1, 2, 3, 4], 2)) diff --git a/unittests/3.x/drop_while.chai b/unittests/3.x/drop_while.chai deleted file mode 100644 index 08e19f2f..00000000 --- a/unittests/3.x/drop_while.chai +++ /dev/null @@ -1 +0,0 @@ -assert_equal([2, 3], drop_while([1, 2, 3], odd)) diff --git a/unittests/3.x/empty.chai b/unittests/3.x/empty.chai deleted file mode 100644 index e69de29b..00000000 diff --git a/unittests/3.x/equ_shortform.chai b/unittests/3.x/equ_shortform.chai deleted file mode 100644 index 41c8e1de..00000000 --- a/unittests/3.x/equ_shortform.chai +++ /dev/null @@ -1,4 +0,0 @@ -var x=.5 -assert_equal(.5, x) -var y=-.5 -assert_equal(-.5, y) diff --git a/unittests/3.x/eval.chai b/unittests/3.x/eval.chai deleted file mode 100644 index 2f18aa41..00000000 --- a/unittests/3.x/eval.chai +++ /dev/null @@ -1 +0,0 @@ -assert_equal(7, eval("3 + 4")) diff --git a/unittests/3.x/eval_error.chai b/unittests/3.x/eval_error.chai deleted file mode 100644 index b5814450..00000000 --- a/unittests/3.x/eval_error.chai +++ /dev/null @@ -1,38 +0,0 @@ - -def deep() -{ - try { - } catch { - - } finally { - if (2) - { - } - - } -} - -def func() -{ - deep(); -} - -def doing() -{ - for (var i = 0; i < 10; ++i) - { - func(); - } -} - -def while_doing() -{ - while (true) - { - doing(); - } -} - -var f = fun() { while_doing(); } - -assert_true(get_eval_error(f).call_stack.size() <= 16) diff --git a/unittests/3.x/even.chai b/unittests/3.x/even.chai deleted file mode 100644 index 5a9a9aea..00000000 --- a/unittests/3.x/even.chai +++ /dev/null @@ -1 +0,0 @@ -assert_equal(true, even(4)) diff --git a/unittests/3.x/exception.chai b/unittests/3.x/exception.chai deleted file mode 100644 index 50df6a80..00000000 --- a/unittests/3.x/exception.chai +++ /dev/null @@ -1,9 +0,0 @@ -var x = 1 -try { - throw(x) - x = 2 -} -catch(e) { - x = e + 3 -} -assert_equal(4, x); diff --git a/unittests/3.x/exception_finally.chai b/unittests/3.x/exception_finally.chai deleted file mode 100644 index d6fd834a..00000000 --- a/unittests/3.x/exception_finally.chai +++ /dev/null @@ -1,32 +0,0 @@ -var finallyone = false; - -try { - throw(3) -} -catch(x) { - assert_equal(3, x) -} -finally { - finallyone = true; -} - -assert_equal(true, finallyone); - -var try2 = false; -var catch2 = false; -var finally2 = false; - - -try { - try2 = true; -} -catch { - catch2 = true; -} -finally { - finally2 = true; -} - -assert_equal(true, try2); -assert_equal(false, catch2); -assert_equal(true, finally2); diff --git a/unittests/3.x/filter.chai b/unittests/3.x/filter.chai deleted file mode 100644 index 6d805fee..00000000 --- a/unittests/3.x/filter.chai +++ /dev/null @@ -1 +0,0 @@ -assert_equal([1,3], filter([1, 2, 3, 4], odd)) diff --git a/unittests/3.x/float.chai b/unittests/3.x/float.chai deleted file mode 100644 index b1bdf299..00000000 --- a/unittests/3.x/float.chai +++ /dev/null @@ -1,7 +0,0 @@ -assert_equal(true, 1.2 < 2) -assert_equal(true, 1.2 > 1) -assert_equal(1.2, 1.2) - -assert_equal(true, .5 > 0) -assert_equal(true, .5 < 1) -assert_equal(0.5, .5) diff --git a/unittests/3.x/foldl.chai b/unittests/3.x/foldl.chai deleted file mode 100644 index 7e9db51f..00000000 --- a/unittests/3.x/foldl.chai +++ /dev/null @@ -1 +0,0 @@ -assert_equal(10, foldl([1, 2, 3, 4], `+`, 0)) diff --git a/unittests/3.x/for.chai b/unittests/3.x/for.chai deleted file mode 100644 index 9799be24..00000000 --- a/unittests/3.x/for.chai +++ /dev/null @@ -1,7 +0,0 @@ -var ret = [] - -for (var i = 0; i < 5; ++i) { - ret.push_back(i); -} - -assert_equal([0,1,2,3,4], ret); diff --git a/unittests/3.x/for_each.chai b/unittests/3.x/for_each.chai deleted file mode 100644 index 242a1baf..00000000 --- a/unittests/3.x/for_each.chai +++ /dev/null @@ -1 +0,0 @@ -for_each([1, 2, 3], print) diff --git a/unittests/3.x/for_each_range.chai b/unittests/3.x/for_each_range.chai deleted file mode 100644 index 43191bfb..00000000 --- a/unittests/3.x/for_each_range.chai +++ /dev/null @@ -1,3 +0,0 @@ -var v = [1,2,3]; -var r = range(v); -for_each(r, fun(x) { assert_equal(true, x>0); } ) diff --git a/unittests/3.x/for_each_retro.chai b/unittests/3.x/for_each_retro.chai deleted file mode 100644 index cc27a580..00000000 --- a/unittests/3.x/for_each_retro.chai +++ /dev/null @@ -1,4 +0,0 @@ -// Don't bother checking the output from this one, just makes sure it executes -var v = [1,2,3]; -var r = retro(range(v)); -for_each(r, print) diff --git a/unittests/3.x/function_array_adjacent.chai b/unittests/3.x/function_array_adjacent.chai deleted file mode 100644 index c34e2be9..00000000 --- a/unittests/3.x/function_array_adjacent.chai +++ /dev/null @@ -1 +0,0 @@ -assert_equal(2, `+`.get_contained_functions()[0].get_arity()) diff --git a/unittests/3.x/function_introspection.chai b/unittests/3.x/function_introspection.chai deleted file mode 100644 index 014cf45d..00000000 --- a/unittests/3.x/function_introspection.chai +++ /dev/null @@ -1,75 +0,0 @@ - -#Test Function Description -def test_function(a) -{ - return a; -} - - - - -// test_function tests -assert_equal(test_function.get_arity(), 1); -assert_equal(test_function.get_contained_functions().size(), 0); -assert_equal(test_function.get_param_types().size(), 2); - -assert_equal(test_function, test_function); - -assert_not_equal(test_function, `+`); - -assert_equal(test_function.call([1]), 1); - -// dynamic object function tests - -def int::test_fun() -{ - return this; -} - -assert_equal(test_fun.get_arity(), 1); -assert_equal(test_fun.get_contained_functions.size(), 1); -assert_equal(test_fun.get_param_types().size(), 2); -assert_equal(test_fun, test_fun); -var test_fun_types = test_fun.get_param_types(); -assert_equal(true, test_fun_types[0].bare_equal(Object_type)); -assert_equal(true, test_fun_types[1].bare_equal(int_type)); - - -// built-ins tests - -assert_equal(2, `==`.get_arity()); - -// < should be the merging of two functions bool <(PODObject, PODObject) and bool <(string, string) -// we want to peel it apart and make sure that's true -var types = `<`.get_param_types(); -assert_equal(3, types.size()); -assert_equal(true, types[0].bare_equal(bool_type)); -assert_equal(true, types[1].bare_equal(Object_type)); -assert_equal(true, types[2].bare_equal(Object_type)); -assert_equal(2, `<`.get_contained_functions().size()); - - -// guard existence tests - -def with_guard(x) : x > 3 {} -def without_guard(x) {} - -def group_guard(x) {} -def group_guard(x) : x > 3 {} - -assert_equal(true, with_guard.has_guard()); -assert_equal(false, without_guard.has_guard()); - -assert_equal(2, group_guard.get_contained_functions().size()); -var group = group_guard.get_contained_functions(); - -assert_equal(true, group[0].has_guard()) -assert_equal(false, group[1].has_guard()) - -assert_throws("Function does not have a guard", fun[group]() { group[1].get_guard(); } ); -assert_throws("Function does not have a guard", fun[without_guard]() { without_guard.get_guard(); } ); - -var guard = with_guard.get_guard(); - -assert_equal(false, guard.has_guard()); -assert_throws("Function does not have a guard", fun[guard]() { guard.get_guard(); } ); diff --git a/unittests/3.x/function_reassignment.chai b/unittests/3.x/function_reassignment.chai deleted file mode 100644 index 2a885fdc..00000000 --- a/unittests/3.x/function_reassignment.chai +++ /dev/null @@ -1,3 +0,0 @@ -var x = `+` -x = `-` -assert_equal(1, x(5,4)) diff --git a/unittests/3.x/generate_range.chai b/unittests/3.x/generate_range.chai deleted file mode 100644 index 9e25970a..00000000 --- a/unittests/3.x/generate_range.chai +++ /dev/null @@ -1 +0,0 @@ -assert_equal([1,2,3,4,5,6,7,8,9,10], generate_range(1, 10)) diff --git a/unittests/3.x/global_const_in_module.chai b/unittests/3.x/global_const_in_module.chai deleted file mode 100644 index c9ca65a6..00000000 --- a/unittests/3.x/global_const_in_module.chai +++ /dev/null @@ -1,7 +0,0 @@ -load_module("test_module") - - -assert_equal(to_int(TestValue1), 1) - -assert_equal(TestValue1.type_name(), "TestEnum") - diff --git a/unittests/3.x/if.chai b/unittests/3.x/if.chai deleted file mode 100644 index 3ec7321b..00000000 --- a/unittests/3.x/if.chai +++ /dev/null @@ -1,7 +0,0 @@ -var t = false; - -if (true) { - t = true; -} - -assert_equal(true, t); diff --git a/unittests/3.x/if_else.chai b/unittests/3.x/if_else.chai deleted file mode 100644 index 8cb42db9..00000000 --- a/unittests/3.x/if_else.chai +++ /dev/null @@ -1,13 +0,0 @@ -var i = 3 -var b1 = false; -var b2 = false; - -if (i == 2) { - b1 = true; -} -else { - b2 = true; -} - -assert_equal(false, b1); -assert_equal(true, b2); diff --git a/unittests/3.x/if_elseif.chai b/unittests/3.x/if_elseif.chai deleted file mode 100644 index 75b85b5f..00000000 --- a/unittests/3.x/if_elseif.chai +++ /dev/null @@ -1,18 +0,0 @@ -var b1 = false; -var b2 = false; -var b3 = false; - -var i = 3 -if (i == 2) { - b1 = true; -} -else if (i == 4) { - b2 = true; -} -else if (i == 3) { - b3 = true; -} - -assert_equal(false, b1); -assert_equal(false, b2); -assert_equal(true, b3); diff --git a/unittests/3.x/if_elseif_else.chai b/unittests/3.x/if_elseif_else.chai deleted file mode 100644 index 26ed0d26..00000000 --- a/unittests/3.x/if_elseif_else.chai +++ /dev/null @@ -1,14 +0,0 @@ -var i = 3 -var b = false -if (i == 2) { - assert_equal(false, true) -} -else if (i == 4) { - assert_equal(false, true) -} -else { - assert_equal(true, true) - b = true -} - -assert_equal(true, b) diff --git a/unittests/3.x/index_operator.chai b/unittests/3.x/index_operator.chai deleted file mode 100644 index e8af5cf6..00000000 --- a/unittests/3.x/index_operator.chai +++ /dev/null @@ -1,10 +0,0 @@ - -// tests more complex parses of the index operator - -def Bob::bob3() { return [1,2,3]; } -def Bob::Bob() {} -var b = Bob(); - - -assert_equal(b.bob3()[0], 1); -assert_equal((b.bob3())[1], 2); diff --git a/unittests/3.x/inheritance.chai b/unittests/3.x/inheritance.chai deleted file mode 100644 index 1fcd346b..00000000 --- a/unittests/3.x/inheritance.chai +++ /dev/null @@ -1,8 +0,0 @@ -load_module("test_module") - -var t0 = TestBaseType() -var t = TestDerivedType(); - -assert_equal(t0.func(), 0); -assert_equal(t.func(), 1); - diff --git a/unittests/3.x/instring_eval.chai b/unittests/3.x/instring_eval.chai deleted file mode 100644 index a72b2fc4..00000000 --- a/unittests/3.x/instring_eval.chai +++ /dev/null @@ -1,3 +0,0 @@ -var bob = 5.5 -assert_equal("5.5", "${bob}") -assert_equal("val: 8 and 8", "val: ${5.5 + 2.5} and ${bob + 2.5}") diff --git a/unittests/3.x/instring_eval_more.chai b/unittests/3.x/instring_eval_more.chai deleted file mode 100644 index 17768f82..00000000 --- a/unittests/3.x/instring_eval_more.chai +++ /dev/null @@ -1,4 +0,0 @@ -assert_equal("\$ {4 + 5}", "$ {4 + 5}") -assert_equal("\$9", "$${4+5}") -assert_equal("Value: \${4 + 5}", "Value: \${4 + 5}") -assert_equal("Value: \$9", "Value: \$${4 + 5}") diff --git a/unittests/3.x/invalid_function_assignment.chai b/unittests/3.x/invalid_function_assignment.chai deleted file mode 100644 index 3aa1bc2f..00000000 --- a/unittests/3.x/invalid_function_assignment.chai +++ /dev/null @@ -1 +0,0 @@ -assert_throws("Error: \"Error, cannot assign to constant value.\"", fun() { clone = `-` } ); diff --git a/unittests/3.x/invalid_function_reassignment.chai b/unittests/3.x/invalid_function_reassignment.chai deleted file mode 100644 index 77307b6f..00000000 --- a/unittests/3.x/invalid_function_reassignment.chai +++ /dev/null @@ -1,2 +0,0 @@ -assert_throws("Error: \"Unable to find appropriate'=' operator.\" With parameters: (int, const Function)", fun() { auto x = 5; x = `-`; } ); - diff --git a/unittests/3.x/is_undef.chai b/unittests/3.x/is_undef.chai deleted file mode 100644 index 38572f0f..00000000 --- a/unittests/3.x/is_undef.chai +++ /dev/null @@ -1,4 +0,0 @@ -var i; -assert_equal(true, i.is_var_undef()); -i = 5; -assert_equal(false, i.is_var_undef()); diff --git a/unittests/3.x/join.chai b/unittests/3.x/join.chai deleted file mode 100644 index 1891c468..00000000 --- a/unittests/3.x/join.chai +++ /dev/null @@ -1 +0,0 @@ -assert_equal("1*2*3", join([1, 2, 3], "*")) diff --git a/unittests/3.x/lambda.chai b/unittests/3.x/lambda.chai deleted file mode 100644 index 6b65a1ba..00000000 --- a/unittests/3.x/lambda.chai +++ /dev/null @@ -1,2 +0,0 @@ -var bob = fun(x) { x + 1 } -assert_equal(4, bob(3)); diff --git a/unittests/3.x/list_push_back.chai b/unittests/3.x/list_push_back.chai deleted file mode 100644 index 4d88deb8..00000000 --- a/unittests/3.x/list_push_back.chai +++ /dev/null @@ -1,8 +0,0 @@ -load_module("stl_extra") - -var x = List() -x.push_back(3) -x.push_back("A") - -assert_equal(3, x.front()); -assert_equal("A", x.back()); diff --git a/unittests/3.x/list_push_front.chai b/unittests/3.x/list_push_front.chai deleted file mode 100644 index 86e28329..00000000 --- a/unittests/3.x/list_push_front.chai +++ /dev/null @@ -1,8 +0,0 @@ -load_module("stl_extra") - -var x = List() -x.push_front(3) -x.push_front("A") - -assert_equal("A", x.front()); -assert_equal(3, x.back()); diff --git a/unittests/3.x/load_module.chai b/unittests/3.x/load_module.chai deleted file mode 100644 index a231a200..00000000 --- a/unittests/3.x/load_module.chai +++ /dev/null @@ -1,2 +0,0 @@ -load_module("test_module") -assert_equal("Hello World", hello_world()); diff --git a/unittests/3.x/loop_inner_outer.chai b/unittests/3.x/loop_inner_outer.chai deleted file mode 100644 index 64a25e6e..00000000 --- a/unittests/3.x/loop_inner_outer.chai +++ /dev/null @@ -1,9 +0,0 @@ -var total = 0 - -for (var i = 0; i < 10; ++i) { - for (var j = 0; j < 10; ++j) { - total += 1 - } -} - -assert_equal(100, total); diff --git a/unittests/3.x/malformed_inline_map.chai b/unittests/3.x/malformed_inline_map.chai deleted file mode 100644 index 1488ded4..00000000 --- a/unittests/3.x/malformed_inline_map.chai +++ /dev/null @@ -1,8 +0,0 @@ - -try { - eval("[\"hello\":5,\"j\",\"k\"]"); - assert_true(false); -} catch (eval_error ee) { -} - - diff --git a/unittests/3.x/map.chai b/unittests/3.x/map.chai deleted file mode 100644 index a0a31ee1..00000000 --- a/unittests/3.x/map.chai +++ /dev/null @@ -1 +0,0 @@ -assert_equal([true, false, true], map([1,2,3], odd)) diff --git a/unittests/3.x/map_access.chai b/unittests/3.x/map_access.chai deleted file mode 100644 index 19ebc1ad..00000000 --- a/unittests/3.x/map_access.chai +++ /dev/null @@ -1,2 +0,0 @@ -var x = ["bob":2, "fred":3] -assert_equal(3, x["fred"]) diff --git a/unittests/3.x/map_inplace_init.chai b/unittests/3.x/map_inplace_init.chai deleted file mode 100644 index b1d8221b..00000000 --- a/unittests/3.x/map_inplace_init.chai +++ /dev/null @@ -1,3 +0,0 @@ -var x = ["bob":1, "fred":2] - -assert_equal(2, x.size()); diff --git a/unittests/3.x/math_add.chai b/unittests/3.x/math_add.chai deleted file mode 100644 index bcb90369..00000000 --- a/unittests/3.x/math_add.chai +++ /dev/null @@ -1 +0,0 @@ -assert_equal(3, (1 + 2)) diff --git a/unittests/3.x/math_add_mixed.chai b/unittests/3.x/math_add_mixed.chai deleted file mode 100644 index b000cafe..00000000 --- a/unittests/3.x/math_add_mixed.chai +++ /dev/null @@ -1 +0,0 @@ -assert_equal(3.5, 1.5 + 2) diff --git a/unittests/3.x/math_dec.chai b/unittests/3.x/math_dec.chai deleted file mode 100644 index e746f298..00000000 --- a/unittests/3.x/math_dec.chai +++ /dev/null @@ -1,3 +0,0 @@ -var i = 3 -assert_equal(2, --i) -assert_equal(2, i) diff --git a/unittests/3.x/math_div.chai b/unittests/3.x/math_div.chai deleted file mode 100644 index 971f2170..00000000 --- a/unittests/3.x/math_div.chai +++ /dev/null @@ -1 +0,0 @@ -assert_equal(2, 10/5) diff --git a/unittests/3.x/math_inc.chai b/unittests/3.x/math_inc.chai deleted file mode 100644 index ec317c03..00000000 --- a/unittests/3.x/math_inc.chai +++ /dev/null @@ -1,3 +0,0 @@ -var i = 3 -assert_equal(4, ++i) -assert_equal(4, i) diff --git a/unittests/3.x/math_mod.chai b/unittests/3.x/math_mod.chai deleted file mode 100644 index 326c35a9..00000000 --- a/unittests/3.x/math_mod.chai +++ /dev/null @@ -1 +0,0 @@ -assert_equal(2, 11 % 3) diff --git a/unittests/3.x/math_mult.chai b/unittests/3.x/math_mult.chai deleted file mode 100644 index 94c355d6..00000000 --- a/unittests/3.x/math_mult.chai +++ /dev/null @@ -1 +0,0 @@ -assert_equal(12, 3 * 4) diff --git a/unittests/3.x/math_negate.chai b/unittests/3.x/math_negate.chai deleted file mode 100644 index 36bae880..00000000 --- a/unittests/3.x/math_negate.chai +++ /dev/null @@ -1 +0,0 @@ -assert_equal(-7, -(3 + 4)) diff --git a/unittests/3.x/math_paren.chai b/unittests/3.x/math_paren.chai deleted file mode 100644 index 01b7f205..00000000 --- a/unittests/3.x/math_paren.chai +++ /dev/null @@ -1 +0,0 @@ -assert_equal(27, 3*(4+5)) diff --git a/unittests/3.x/math_sub.chai b/unittests/3.x/math_sub.chai deleted file mode 100644 index 7e8342c1..00000000 --- a/unittests/3.x/math_sub.chai +++ /dev/null @@ -1 +0,0 @@ -assert_equal(2, 5 - 3) diff --git a/unittests/3.x/max.chai b/unittests/3.x/max.chai deleted file mode 100644 index 533e7e84..00000000 --- a/unittests/3.x/max.chai +++ /dev/null @@ -1 +0,0 @@ -assert_equal(5, max(3, 5)) diff --git a/unittests/3.x/memberscope.chai b/unittests/3.x/memberscope.chai deleted file mode 100644 index fe46810a..00000000 --- a/unittests/3.x/memberscope.chai +++ /dev/null @@ -1,12 +0,0 @@ -attr Vector3::x -attr Vector3::y -attr Vector3::z - -def Vector3::Vector3(x, y, z) { - this.x = x - this.y = y - this.z = z -} - -var v = Vector3(1,2,3); -assert_equal(1, v.x); diff --git a/unittests/3.x/method_sugar.chai b/unittests/3.x/method_sugar.chai deleted file mode 100644 index 521400bc..00000000 --- a/unittests/3.x/method_sugar.chai +++ /dev/null @@ -1 +0,0 @@ -assert_equal(6, [1, 2, 3].sum()) diff --git a/unittests/3.x/min.chai b/unittests/3.x/min.chai deleted file mode 100644 index 0ef1ba79..00000000 --- a/unittests/3.x/min.chai +++ /dev/null @@ -1 +0,0 @@ -assert_equal(3, min(3, 5)) diff --git a/unittests/3.x/mmd1.chai b/unittests/3.x/mmd1.chai deleted file mode 100644 index 36121a90..00000000 --- a/unittests/3.x/mmd1.chai +++ /dev/null @@ -1,20 +0,0 @@ -def bob(x, y, z) { - x + y + z -} - -def bob(x, y) { - x - y -} - -def bob(x) { - -x -} - -def bob() { - 10 -} - -assert_equal(10, bob()) -assert_equal(-5, bob(5)) -assert_equal(-1, bob(5,6)) -assert_equal(18, bob(5,6,7)) diff --git a/unittests/3.x/mmd2.chai b/unittests/3.x/mmd2.chai deleted file mode 100644 index 1c5f1771..00000000 --- a/unittests/3.x/mmd2.chai +++ /dev/null @@ -1,9 +0,0 @@ -def bob(x, y) : x > 10 { x - y } - -def bob(x, y) : x > 5 { x - y + 10 } - -def bob(x, y) { x + y } - -assert_equal(7, bob(3,4)) -assert_equal(9, bob(6,7)) -assert_equal(-1, bob(11,12)) diff --git a/unittests/3.x/multiline.chai b/unittests/3.x/multiline.chai deleted file mode 100644 index f13be4e6..00000000 --- a/unittests/3.x/multiline.chai +++ /dev/null @@ -1,9 +0,0 @@ -var x = [1, 2, - 3, 4] - -assert_equal(1, x[0]) - -var y = map(x, - fun(x) { x + 1 }) - -assert_equal(2, y[0]) diff --git a/unittests/3.x/number_formats.chai b/unittests/3.x/number_formats.chai deleted file mode 100644 index c80ece04..00000000 --- a/unittests/3.x/number_formats.chai +++ /dev/null @@ -1,3 +0,0 @@ -assert_equal(10, 012) -assert_equal(31, 0x1f) -assert_equal(3, 0b11) diff --git a/unittests/3.x/object_attr.chai b/unittests/3.x/object_attr.chai deleted file mode 100644 index c2da08ea..00000000 --- a/unittests/3.x/object_attr.chai +++ /dev/null @@ -1,6 +0,0 @@ -attr bob::z -def bob::bob() { this.z = 10 } -var x = bob() -def bob::fred(x) { this.z - x } - -assert_equal(7, x.fred(3)) diff --git a/unittests/3.x/object_attr_same_name.chai b/unittests/3.x/object_attr_same_name.chai deleted file mode 100644 index fa20bac4..00000000 --- a/unittests/3.x/object_attr_same_name.chai +++ /dev/null @@ -1,9 +0,0 @@ -attr bob::z -def bob::bob() { this.z = 10 } - -attr bob2::z -def bob2::bob2() { this.z = 12 } - -var b = bob(); -var b2 = bob2(); - diff --git a/unittests/3.x/object_clone.chai b/unittests/3.x/object_clone.chai deleted file mode 100644 index 4659f41a..00000000 --- a/unittests/3.x/object_clone.chai +++ /dev/null @@ -1,11 +0,0 @@ -attr bob::z -def bob::bob() { } - -var x = bob(); -x.z = 10; - -var y = clone(x); -y.z = 20; - -assert_equal(10, x.z) -assert_equal(20, y.z) diff --git a/unittests/3.x/object_constructor_guards.chai b/unittests/3.x/object_constructor_guards.chai deleted file mode 100644 index f48c00a1..00000000 --- a/unittests/3.x/object_constructor_guards.chai +++ /dev/null @@ -1,10 +0,0 @@ -attr bob::val - -def bob::bob(x) : x < 10 { this.val = "Less Than Ten: " + x.to_string(); } -def bob::bob(x) { this.val = "Any Other Value: " + x.to_string(); } - -var b = bob(12) -var c = bob(3) - -assert_equal("Any Other Value: 12", b.val ) -assert_equal("Less Than Ten: 3", c.val ) diff --git a/unittests/3.x/object_method_guards.chai b/unittests/3.x/object_method_guards.chai deleted file mode 100644 index addc8508..00000000 --- a/unittests/3.x/object_method_guards.chai +++ /dev/null @@ -1,7 +0,0 @@ -def bob::bob() { } -def bob::fred(e) : e < 10 { assert_equal(true, e<10) } -def bob::fred(e) { assert_equal(true, e >= 10) } - -var b = bob() -b.fred(3) -b.fred(12) diff --git a/unittests/3.x/odd.chai b/unittests/3.x/odd.chai deleted file mode 100644 index dbaf2a01..00000000 --- a/unittests/3.x/odd.chai +++ /dev/null @@ -1 +0,0 @@ -assert_equal(false, odd(4)) diff --git a/unittests/3.x/operator_overload.chai b/unittests/3.x/operator_overload.chai deleted file mode 100644 index 9bd2eb79..00000000 --- a/unittests/3.x/operator_overload.chai +++ /dev/null @@ -1,9 +0,0 @@ -def Bob::`+`(y) { this.x + y.x } -def Bob::Bob() { } -attr Bob::x -var b = Bob() -var c = Bob() -b.x = 4 -c.x = 5 - -assert_equal(9, b+c) diff --git a/unittests/3.x/operator_overload2.chai b/unittests/3.x/operator_overload2.chai deleted file mode 100644 index b4afbe7b..00000000 --- a/unittests/3.x/operator_overload2.chai +++ /dev/null @@ -1,9 +0,0 @@ -def Bob::Bob() { } -attr Bob::x -def `-`(a, b) : is_type(a, "Bob") && is_type(b, "Bob") { a.x - b.x } -var b = Bob() -var c = Bob() -b.x = 4 -c.x = 5 - -assert_equal(-1, b-c) diff --git a/unittests/3.x/operators_float.chai b/unittests/3.x/operators_float.chai deleted file mode 100644 index 847f5e58..00000000 --- a/unittests/3.x/operators_float.chai +++ /dev/null @@ -1,16 +0,0 @@ -var i = 1.0; -var j = 2.0; -var k = 3.0; - -assert_equal(3, i + j) -assert_equal(1.0, +i) -assert_equal(-1, i-j) -assert_equal(-1, -i) -assert_equal(1.5, k/j) -assert_equal(6, j*k) - -assert_equal(0, i -= i) -assert_equal(3, j *= 1.5) -assert_equal(1.5, j /= 2) -assert_equal(2.5, j += 1) -assert_throws("Error: \"Error with numeric operator calling: %\"", fun[k]() { k % 2 } ); diff --git a/unittests/3.x/operators_int.chai b/unittests/3.x/operators_int.chai deleted file mode 100644 index 4627b552..00000000 --- a/unittests/3.x/operators_int.chai +++ /dev/null @@ -1,31 +0,0 @@ -var i = 1; -var j = 2; -var k = 3; - -assert_equal(3, i + j); -assert_equal(1, +i); -assert_equal(-1, i - j); -assert_equal(-1, -i); -assert_equal(2, j & k); -assert_equal(-3, ~j); -assert_equal(1, j ^ k); -assert_equal(3, i | j); -assert_equal(2, j / i); -assert_equal(4, i << j); -assert_equal(6, j * k); -assert_equal(1, k % j); -assert_equal(1, j >> i); - -assert_equal(0, i &= 2); -assert_equal(1, j ^= 3); -assert_equal(3, j |= 2); -assert_equal(-1, i -= 1); -assert_equal(6, j <<= 1); -assert_equal(12, j *= 2); -assert_equal(6, j /= 2); -assert_equal(2, j %= 4); -assert_equal(1, j >>= 1); -assert_equal(2, j += 1); -assert_equal(1, --j); -assert_equal(2, ++j); - diff --git a/unittests/3.x/pair.chai b/unittests/3.x/pair.chai deleted file mode 100644 index 9b3c8049..00000000 --- a/unittests/3.x/pair.chai +++ /dev/null @@ -1,5 +0,0 @@ -var p = Pair("Hello", "World") - -assert_equal(p.first, "Hello") -assert_equal(p.second, "World") - diff --git a/unittests/3.x/pointer_passed_to_constructor.chai b/unittests/3.x/pointer_passed_to_constructor.chai deleted file mode 100644 index 6495ee38..00000000 --- a/unittests/3.x/pointer_passed_to_constructor.chai +++ /dev/null @@ -1,8 +0,0 @@ -load_module("test_module") - -var i = 1; -var t0 = TestBaseType(i); - -var t1 = TestBaseType(get_new_int()) - - diff --git a/unittests/3.x/precedence_1.chai b/unittests/3.x/precedence_1.chai deleted file mode 100644 index a5388625..00000000 --- a/unittests/3.x/precedence_1.chai +++ /dev/null @@ -1 +0,0 @@ -assert_equal(14, 2 + 3 * 4) diff --git a/unittests/3.x/precedence_2.chai b/unittests/3.x/precedence_2.chai deleted file mode 100644 index 27a19d4a..00000000 --- a/unittests/3.x/precedence_2.chai +++ /dev/null @@ -1 +0,0 @@ -assert_equal(-2, 5 - 4 - 3) diff --git a/unittests/3.x/precedence_3.chai b/unittests/3.x/precedence_3.chai deleted file mode 100644 index 6eecbf64..00000000 --- a/unittests/3.x/precedence_3.chai +++ /dev/null @@ -1 +0,0 @@ -assert_equal(0, 10 / 5 % 2) diff --git a/unittests/3.x/precedence_eq.chai b/unittests/3.x/precedence_eq.chai deleted file mode 100644 index 325d667e..00000000 --- a/unittests/3.x/precedence_eq.chai +++ /dev/null @@ -1,3 +0,0 @@ -var x = var y = 4 -assert_equal(4, x); -assert_equal(4, y); diff --git a/unittests/3.x/product.chai b/unittests/3.x/product.chai deleted file mode 100644 index 03ba3cfa..00000000 --- a/unittests/3.x/product.chai +++ /dev/null @@ -1 +0,0 @@ -assert_equal(24, product([1, 2, 3, 4])) diff --git a/unittests/3.x/range.chai b/unittests/3.x/range.chai deleted file mode 100644 index ddef4f2a..00000000 --- a/unittests/3.x/range.chai +++ /dev/null @@ -1,4 +0,0 @@ -var x = [1, 2, 3, 4] -var r = range(x) -r.pop_front() -assert_equal(2, r.front()); diff --git a/unittests/3.x/range_back.chai b/unittests/3.x/range_back.chai deleted file mode 100644 index 6bf56721..00000000 --- a/unittests/3.x/range_back.chai +++ /dev/null @@ -1,4 +0,0 @@ -var x = [1, 2, 3, 4] -var r = range(x) -r.pop_back() -assert_equal(3, r.back()) diff --git a/unittests/3.x/range_contains.chai b/unittests/3.x/range_contains.chai deleted file mode 100644 index 28a99b12..00000000 --- a/unittests/3.x/range_contains.chai +++ /dev/null @@ -1,5 +0,0 @@ -var v = [1,2,"hi", "world", 5.5] -assert_equal(true, v.contains(5.5)) -assert_equal(false, v.contains(0)) -assert_equal(false, v.contains(1, lt)) -assert_equal(true, v.contains(2, `==`)) diff --git a/unittests/3.x/range_find.chai b/unittests/3.x/range_find.chai deleted file mode 100644 index 08045e5a..00000000 --- a/unittests/3.x/range_find.chai +++ /dev/null @@ -1,6 +0,0 @@ -var v = [2, 1, "Hi", 5.5] -var r = v.find("Hi"); - -assert_equal("Hi", r.front()) -var r2 = v.find(2, `<`); -assert_equal(1, r2.front()); diff --git a/unittests/3.x/range_inplace.chai b/unittests/3.x/range_inplace.chai deleted file mode 100644 index d661f5de..00000000 --- a/unittests/3.x/range_inplace.chai +++ /dev/null @@ -1 +0,0 @@ -assert_equal([3,4,5,6], [3..6]) diff --git a/unittests/3.x/reduce.chai b/unittests/3.x/reduce.chai deleted file mode 100644 index 3b255b31..00000000 --- a/unittests/3.x/reduce.chai +++ /dev/null @@ -1 +0,0 @@ -assert_equal(10, reduce([1, 2, 3, 4], `+`)) diff --git a/unittests/3.x/ref_equal.chai b/unittests/3.x/ref_equal.chai deleted file mode 100644 index 1dbb90e1..00000000 --- a/unittests/3.x/ref_equal.chai +++ /dev/null @@ -1,5 +0,0 @@ -var i = 3 -var j := i -j = 4 - -assert_equal(4, i) diff --git a/unittests/3.x/retro.chai b/unittests/3.x/retro.chai deleted file mode 100644 index d7f6818d..00000000 --- a/unittests/3.x/retro.chai +++ /dev/null @@ -1,4 +0,0 @@ -var x = [1, 2, 3, 4] -var r = retro(range(x)) -r.pop_front() -assert_equal(3, r.front()) diff --git a/unittests/3.x/retroretro.chai b/unittests/3.x/retroretro.chai deleted file mode 100644 index 09af3ca7..00000000 --- a/unittests/3.x/retroretro.chai +++ /dev/null @@ -1,7 +0,0 @@ -var x = [1, 2, 3, 4] -var r = retro(range(x)) -r.pop_back() -var r2 = retro(r) -r2.pop_front() -assert_equal(2, r.back()) -assert_equal(3, r2.front()) diff --git a/unittests/3.x/return.chai b/unittests/3.x/return.chai deleted file mode 100644 index 1747de90..00000000 --- a/unittests/3.x/return.chai +++ /dev/null @@ -1,5 +0,0 @@ -def sam() { - return 5 -} - -assert_equal(5, sam()) diff --git a/unittests/3.x/runtime_error.chai b/unittests/3.x/runtime_error.chai deleted file mode 100644 index e1e2fc10..00000000 --- a/unittests/3.x/runtime_error.chai +++ /dev/null @@ -1,11 +0,0 @@ -var caught = false - -try { - throw(runtime_error("error")) -} -catch(e) { - caught = true - assert_equal("error", e.what()) -} - -assert_equal(true, caught) diff --git a/unittests/3.x/shift.chai b/unittests/3.x/shift.chai deleted file mode 100644 index 03f7ea3a..00000000 --- a/unittests/3.x/shift.chai +++ /dev/null @@ -1 +0,0 @@ -assert_equal(8, 2 << 2) diff --git a/unittests/3.x/string_charptr.chai b/unittests/3.x/string_charptr.chai deleted file mode 100644 index a3065ce4..00000000 --- a/unittests/3.x/string_charptr.chai +++ /dev/null @@ -1,6 +0,0 @@ -assert_equal(true, "hello".c_str().is_var_const()) -assert_equal("char", "hello".c_str().type_name()) - -assert_equal(true, "hello".data().is_var_const()) -assert_equal("char", "hello".data().type_name()) - diff --git a/unittests/3.x/string_concat.chai b/unittests/3.x/string_concat.chai deleted file mode 100644 index 40bf4aaf..00000000 --- a/unittests/3.x/string_concat.chai +++ /dev/null @@ -1 +0,0 @@ -assert_equal("hello, there", "hello, " + "there") diff --git a/unittests/3.x/string_find.chai b/unittests/3.x/string_find.chai deleted file mode 100644 index f2cc1f82..00000000 --- a/unittests/3.x/string_find.chai +++ /dev/null @@ -1 +0,0 @@ -assert_equal(3, find("123abab", "ab")) diff --git a/unittests/3.x/string_find_first_not_of.chai b/unittests/3.x/string_find_first_not_of.chai deleted file mode 100644 index 4d5fd8d4..00000000 --- a/unittests/3.x/string_find_first_not_of.chai +++ /dev/null @@ -1 +0,0 @@ -assert_equal(2, find_first_not_of("abcd", "abd")) diff --git a/unittests/3.x/string_find_first_of.chai b/unittests/3.x/string_find_first_of.chai deleted file mode 100644 index 0200bb2c..00000000 --- a/unittests/3.x/string_find_first_of.chai +++ /dev/null @@ -1 +0,0 @@ -assert_equal(1, find_first_of("abab", "bec")) diff --git a/unittests/3.x/string_find_last_not_of.chai b/unittests/3.x/string_find_last_not_of.chai deleted file mode 100644 index 0090f9f9..00000000 --- a/unittests/3.x/string_find_last_not_of.chai +++ /dev/null @@ -1 +0,0 @@ -assert_equal(3, find_last_not_of("abab", "ac")) diff --git a/unittests/3.x/string_find_last_of.chai b/unittests/3.x/string_find_last_of.chai deleted file mode 100644 index 72f0f6a0..00000000 --- a/unittests/3.x/string_find_last_of.chai +++ /dev/null @@ -1 +0,0 @@ -assert_equal(3, find_last_of("abab", "bec")) diff --git a/unittests/3.x/string_init.chai b/unittests/3.x/string_init.chai deleted file mode 100644 index a3d11632..00000000 --- a/unittests/3.x/string_init.chai +++ /dev/null @@ -1 +0,0 @@ -print("bob") diff --git a/unittests/3.x/string_literal_access.chai b/unittests/3.x/string_literal_access.chai deleted file mode 100644 index e8943a1b..00000000 --- a/unittests/3.x/string_literal_access.chai +++ /dev/null @@ -1 +0,0 @@ -assert_equal('b', "abc"[1]) diff --git a/unittests/3.x/string_rfind.chai b/unittests/3.x/string_rfind.chai deleted file mode 100644 index 01675f34..00000000 --- a/unittests/3.x/string_rfind.chai +++ /dev/null @@ -1 +0,0 @@ -assert_equal(5, rfind("123abab", "ab")) diff --git a/unittests/3.x/sum.chai b/unittests/3.x/sum.chai deleted file mode 100644 index 7502ae7e..00000000 --- a/unittests/3.x/sum.chai +++ /dev/null @@ -1 +0,0 @@ -assert_equal(10, sum([1, 2, 3, 4])) diff --git a/unittests/3.x/switch_break.chai b/unittests/3.x/switch_break.chai deleted file mode 100644 index 8d362759..00000000 --- a/unittests/3.x/switch_break.chai +++ /dev/null @@ -1,22 +0,0 @@ -var total = 0; - -switch(2) { - case (1) { - total += 1; - break; - } - case (2) { - total += 2; - break; - } - case (3) { - total += 4; - break; - } - case (4) { - total += 8; - break; - } -} - -assert_equal(total, 2) diff --git a/unittests/3.x/switch_default.chai b/unittests/3.x/switch_default.chai deleted file mode 100644 index 8c48aa50..00000000 --- a/unittests/3.x/switch_default.chai +++ /dev/null @@ -1,18 +0,0 @@ -var total = 0; - -switch(2) { - case (1) { - total += 1; - } - case (3) { - total += 4; - } - case (4) { - total += 8; - } - default { - total += 16; - } -} - -assert_equal(total, 16) diff --git a/unittests/3.x/switch_empty.chai b/unittests/3.x/switch_empty.chai deleted file mode 100644 index 8d3a1669..00000000 --- a/unittests/3.x/switch_empty.chai +++ /dev/null @@ -1,4 +0,0 @@ -switch(true) { } - -// We just have to get here without error for success -assert_equal(true, true); diff --git a/unittests/3.x/switch_fallthru.chai b/unittests/3.x/switch_fallthru.chai deleted file mode 100644 index 627b6493..00000000 --- a/unittests/3.x/switch_fallthru.chai +++ /dev/null @@ -1,18 +0,0 @@ -var total = 0; - -switch(2) { - case (1) { - total += 1; - } - case (2) { - total += 2; - } - case (3) { - total += 4; - } - case (4) { - total += 8; - } -} - -assert_equal(total, 14); diff --git a/unittests/3.x/switch_fallthru_and_break.chai b/unittests/3.x/switch_fallthru_and_break.chai deleted file mode 100644 index 3c93071b..00000000 --- a/unittests/3.x/switch_fallthru_and_break.chai +++ /dev/null @@ -1,19 +0,0 @@ -var total = 0; - -switch(2) { - case (1) { - total += 1; - } - case (2) { - total += 2; - } - case (3) { - total += 4; - break; - } - case (4) { - total += 8; - } -} - -assert_equal(total, 6) diff --git a/unittests/3.x/take.chai b/unittests/3.x/take.chai deleted file mode 100644 index 5110392e..00000000 --- a/unittests/3.x/take.chai +++ /dev/null @@ -1 +0,0 @@ -assert_equal(2, take([1, 2, 3, 4], 2).back()) diff --git a/unittests/3.x/take_while.chai b/unittests/3.x/take_while.chai deleted file mode 100644 index 56a4ba22..00000000 --- a/unittests/3.x/take_while.chai +++ /dev/null @@ -1 +0,0 @@ -assert_equal([1], take_while([1, 2, 3, 4], odd)) diff --git a/unittests/3.x/type_info.chai b/unittests/3.x/type_info.chai deleted file mode 100644 index fc2dd3e7..00000000 --- a/unittests/3.x/type_info.chai +++ /dev/null @@ -1,11 +0,0 @@ -assert_equal("string", string_type.name()); -assert_equal(false, string_type.is_type_const()); -assert_equal(false, string_type.is_type_reference()); -assert_equal(false, string_type.is_type_void()); -assert_equal(false, string_type.is_type_undef()); -assert_equal(false, string_type.is_type_pointer()); -assert_equal("string", "string".get_type_info().name()); -assert_equal(true, string_type.bare_equal("string".get_type_info())); - -assert_equal(true, "bob".is_type(string_type)); - diff --git a/unittests/3.x/unit_test.inc b/unittests/3.x/unit_test.inc deleted file mode 100644 index d746e7bf..00000000 --- a/unittests/3.x/unit_test.inc +++ /dev/null @@ -1,53 +0,0 @@ -def assert_equal(x, y) -{ - if (x == y) - { - // Passes - } else { - // Fails - print("assert_equal failure: got " + to_string(y) + " expected " + to_string(x)); - exit(-1); - } -} - -def assert_false(f) -{ - if (f) - { - print("assert_false failure"); - exit(-1); - } -} - -def assert_true(f) -{ - if (!f) - { - print("assert_false failure"); - exit(-1); - } -} - -def assert_not_equal(x, y) -{ - if (!(x == y)) - { - // Passes - } else { - // Fails - print("assert_not_equal failure: got " + to_string(y) + " which was not expected."); - exit(-1); - } -} - -def assert_throws(desc, x) -{ - if (throws_exception(x)) - { - // Passes - } else { - // Fails - print("assert_throws failure, function did not throw exception: " + to_string(desc)); - exit(-1); - } -} diff --git a/unittests/3.x/use.chai b/unittests/3.x/use.chai deleted file mode 100644 index efd587da..00000000 --- a/unittests/3.x/use.chai +++ /dev/null @@ -1,9 +0,0 @@ -use("use.inc") - -assert_equal("hello", greet()) - -// Include it a second time and see if there are any errors -use("use.inc") - -assert_equal("hello", greet()) - diff --git a/unittests/3.x/use.inc b/unittests/3.x/use.inc deleted file mode 100644 index 28970935..00000000 --- a/unittests/3.x/use.inc +++ /dev/null @@ -1,4 +0,0 @@ -def greet { - return("hello") -} - diff --git a/unittests/3.x/vector_access.chai b/unittests/3.x/vector_access.chai deleted file mode 100644 index 34d483cd..00000000 --- a/unittests/3.x/vector_access.chai +++ /dev/null @@ -1,2 +0,0 @@ -var x = [1, 2, 3] -assert_equal(3, x[2]) diff --git a/unittests/3.x/vector_erase_at.chai b/unittests/3.x/vector_erase_at.chai deleted file mode 100644 index 9a96218f..00000000 --- a/unittests/3.x/vector_erase_at.chai +++ /dev/null @@ -1,3 +0,0 @@ -var x = [1, 2, 3] -x.erase_at(1) -assert_equal([1,3], x); diff --git a/unittests/3.x/vector_inplace_init.chai b/unittests/3.x/vector_inplace_init.chai deleted file mode 100644 index f16c15b3..00000000 --- a/unittests/3.x/vector_inplace_init.chai +++ /dev/null @@ -1,2 +0,0 @@ -var x = [1, 2, 3] -assert_equal(3, x.size()) diff --git a/unittests/3.x/vector_insert_at.chai b/unittests/3.x/vector_insert_at.chai deleted file mode 100644 index 4f6ec45b..00000000 --- a/unittests/3.x/vector_insert_at.chai +++ /dev/null @@ -1,3 +0,0 @@ -var x = [1, 2, 3] -x.insert_at(1, 6) -assert_equal([1,6,2,3], x); diff --git a/unittests/3.x/vector_literal_acccess.chai b/unittests/3.x/vector_literal_acccess.chai deleted file mode 100644 index 29a7c05f..00000000 --- a/unittests/3.x/vector_literal_acccess.chai +++ /dev/null @@ -1 +0,0 @@ -assert_equal(1, [1,2,3][0]) diff --git a/unittests/3.x/vector_of_one.chai b/unittests/3.x/vector_of_one.chai deleted file mode 100644 index f4bb01bf..00000000 --- a/unittests/3.x/vector_of_one.chai +++ /dev/null @@ -1,2 +0,0 @@ -var x = [1] -assert_equal(1, x[0]) diff --git a/unittests/3.x/vector_paren_literal_access.chai b/unittests/3.x/vector_paren_literal_access.chai deleted file mode 100644 index a0c6b966..00000000 --- a/unittests/3.x/vector_paren_literal_access.chai +++ /dev/null @@ -1 +0,0 @@ -assert_equal(1, ([1,2,3])[0]) diff --git a/unittests/3.x/vector_push_back.chai b/unittests/3.x/vector_push_back.chai deleted file mode 100644 index 715082bd..00000000 --- a/unittests/3.x/vector_push_back.chai +++ /dev/null @@ -1,5 +0,0 @@ -var x = [1, 2] -x.push_back(3) -assert_equal(3, x.size()) -assert_equal(3, x.back()) -assert_equal(1, x.front()) diff --git a/unittests/3.x/vector_push_empty.chai b/unittests/3.x/vector_push_empty.chai deleted file mode 100644 index 29c568d1..00000000 --- a/unittests/3.x/vector_push_empty.chai +++ /dev/null @@ -1,4 +0,0 @@ -var bob = [] -bob.push_back(3) -assert_equal(1, bob.size()) -assert_equal(3, bob.front()) diff --git a/unittests/3.x/zip.chai b/unittests/3.x/zip.chai deleted file mode 100644 index d39583f2..00000000 --- a/unittests/3.x/zip.chai +++ /dev/null @@ -1,5 +0,0 @@ -var z = zip([1, 2, 3], [4, 5, 6]) - -assert_equal([1,4], z[0]) -assert_equal([2,5], z[1]) -assert_equal([3,6], z[2]) diff --git a/unittests/3.x/zip_with.chai b/unittests/3.x/zip_with.chai deleted file mode 100644 index 1fe3dd90..00000000 --- a/unittests/3.x/zip_with.chai +++ /dev/null @@ -1,3 +0,0 @@ -var z = zip_with(`+`, [1, 2, 3], [4, 5, 6]) - -assert_equal([5,7,9], z) From 2dfd4441782f8c6f1aa89a895a31b604db27c8a4 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Mon, 11 Jun 2018 05:27:48 -0600 Subject: [PATCH 075/155] Formatting cleanup --- .../language/chaiscript_prelude.hpp | 650 +++++++++--------- 1 file changed, 325 insertions(+), 325 deletions(-) diff --git a/include/chaiscript/language/chaiscript_prelude.hpp b/include/chaiscript/language/chaiscript_prelude.hpp index 5e470993..46e3f5d4 100644 --- a/include/chaiscript/language/chaiscript_prelude.hpp +++ b/include/chaiscript/language/chaiscript_prelude.hpp @@ -8,36 +8,36 @@ #define CHAISCRIPT_PRELUDE_HPP_ namespace chaiscript { -struct ChaiScript_Prelude { +struct ChaiScript_Prelude { static std::string chaiscript_prelude() { return R"chaiscript( -def lt(l, r) { - if (call_exists(`<`, l, r)) { - l < r - } else { - type_name(l) < type_name(r) - } +def lt(l, r) { + if (call_exists(`<`, l, r)) { + l < r + } else { + type_name(l) < type_name(r) + } } -def gt(l, r) { - if (call_exists(`>`, l, r)) { - l > r - } else { - type_name(l) > type_name(r) - } +def gt(l, r) { + if (call_exists(`>`, l, r)) { + l > r + } else { + type_name(l) > type_name(r) + } } -def eq(l, r) { - if (call_exists(`==`, l, r)) { - l == r - } else { - false - } +def eq(l, r) { + if (call_exists(`==`, l, r)) { + l == r + } else { + false + } } -def new(x) { - eval(type_name(x))(); +def new(x) { + eval(type_name(x))(); } def clone(double x) { @@ -64,85 +64,85 @@ def clone(x) : function_exists(type_name(x)) && call_exists(eval(type_name(x)), # to_string for Pair() -def to_string(x) : call_exists(first, x) && call_exists(second, x) { - "<" + x.first.to_string() + ", " + x.second.to_string() + ">"; +def to_string(x) : call_exists(first, x) && call_exists(second, x) { + "<" + x.first.to_string() + ", " + x.second.to_string() + ">"; } # to_string for containers -def to_string(x) : call_exists(range, x) && !x.is_type("string"){ - "[" + x.join(", ") + "]"; +def to_string(x) : call_exists(range, x) && !x.is_type("string"){ + "[" + x.join(", ") + "]"; } # Prints to console with no carriage return -def puts(x) { - print_string(x.to_string()); +def puts(x) { + print_string(x.to_string()); } # Prints to console with carriage return -def print(x) { - println_string(x.to_string()); +def print(x) { + println_string(x.to_string()); } # Returns the maximum value of two numbers def max(a, b) { - if (a>b) { - a - } else { - b - } -} + if (a>b) { + a + } else { + b + } +} # Returns the minimum value of two numbers -def min(a, b) -{ - if (a 0) && (!r.empty())) { - inserter(r.front()); - r.pop_front(); - --i; - } +def take(container, num, inserter) : call_exists(range, container) { + auto r := range(container); + auto i = num; + while ((i > 0) && (!r.empty())) { + inserter(r.front()); + r.pop_front(); + --i; + } } # Returns a new container with the given number of elements taken from the container def take(container, num) { - auto retval := new(container); - take(container, num, back_inserter(retval)); - retval; -} - - -def take_while(container, f, inserter) : call_exists(range, container) { - auto r := range(container); - while ((!r.empty()) && f(r.front())) { - inserter(r.front()); - r.pop_front(); - } -} - - -# Returns a new container with the given elements match the second value function -def take_while(container, f) { - auto retval := new(container); - take_while(container, f, back_inserter(retval)); + auto retval := new(container); + take(container, num, back_inserter(retval)); retval; } -def drop(container, num, inserter) : call_exists(range, container) { - auto r := range(container); - auto i = num; - while ((i > 0) && (!r.empty())) { - r.pop_front(); - --i; - } - while (!r.empty()) { - inserter(r.front()); - r.pop_front(); - } +def take_while(container, f, inserter) : call_exists(range, container) { + auto r := range(container); + while ((!r.empty()) && f(r.front())) { + inserter(r.front()); + r.pop_front(); + } } -# Returns a new container with the given number of elements dropped from the given container +# Returns a new container with the given elements match the second value function +def take_while(container, f) { + auto retval := new(container); + take_while(container, f, back_inserter(retval)); + retval; +} + + +def drop(container, num, inserter) : call_exists(range, container) { + auto r := range(container); + auto i = num; + while ((i > 0) && (!r.empty())) { + r.pop_front(); + --i; + } + while (!r.empty()) { + inserter(r.front()); + r.pop_front(); + } +} + + +# Returns a new container with the given number of elements dropped from the given container def drop(container, num) { - auto retval := new(container); - drop(container, num, back_inserter(retval)); - retval; + auto retval := new(container); + drop(container, num, back_inserter(retval)); + retval; } -def drop_while(container, f, inserter) : call_exists(range, container) { - auto r := range(container); - while ((!r.empty())&& f(r.front())) { - r.pop_front(); - } - while (!r.empty()) { - inserter(r.front()); - r.pop_front(); - } +def drop_while(container, f, inserter) : call_exists(range, container) { + auto r := range(container); + while ((!r.empty())&& f(r.front())) { + r.pop_front(); + } + while (!r.empty()) { + inserter(r.front()); + r.pop_front(); + } } # Returns a new container with the given elements dropped that match the second value function def drop_while(container, f) { - auto retval := new(container); - drop_while(container, f, back_inserter(retval)); - retval; + auto retval := new(container); + drop_while(container, f, back_inserter(retval)); + retval; } # Applies the second value function to the container. Starts with the first two elements. Expects at least 2 elements. -def reduce(container, func) : container.size() >= 2 && call_exists(range, container) { - auto r := range(container); - auto retval = r.front(); - r.pop_front(); - retval = func(retval, r.front()); - r.pop_front(); - while (!r.empty()) { - retval = func(retval, r.front()); - r.pop_front(); - } - retval; +def reduce(container, func) : container.size() >= 2 && call_exists(range, container) { + auto r := range(container); + auto retval = r.front(); + r.pop_front(); + retval = func(retval, r.front()); + r.pop_front(); + while (!r.empty()) { + retval = func(retval, r.front()); + r.pop_front(); + } + retval; } # Returns a string of the elements in container delimited by the second value string -def join(container, delim) { - auto retval = ""; - auto range := range(container); - if (!range.empty()) { - retval += to_string(range.front()); - range.pop_front(); - while (!range.empty()) { - retval += delim; - retval += to_string(range.front()); - range.pop_front(); - } - } - retval; +def join(container, delim) { + auto retval = ""; + auto range := range(container); + if (!range.empty()) { + retval += to_string(range.front()); + range.pop_front(); + while (!range.empty()) { + retval += delim; + retval += to_string(range.front()); + range.pop_front(); + } + } + retval; } -def filter(container, f, inserter) : call_exists(range, container) { - auto r := range(container); - while (!r.empty()) { - if (f(r.front())) { - inserter(r.front()); - } - r.pop_front(); - } -} +def filter(container, f, inserter) : call_exists(range, container) { + auto r := range(container); + while (!r.empty()) { + if (f(r.front())) { + inserter(r.front()); + } + r.pop_front(); + } +} # Returns a new Vector which match the second value function -def filter(container, f) { - auto retval := new(container); +def filter(container, f) { + auto retval := new(container); filter(container, f, back_inserter(retval)); retval; } -def generate_range(x, y, inserter) { - auto i = x; - while (i <= y) { - inserter(i); - ++i; - } +def generate_range(x, y, inserter) { + auto i = x; + while (i <= y) { + inserter(i); + ++i; + } } # Returns a new Vector which represents the range from the first value to the second value -def generate_range(x, y) { - auto retval := Vector(); - generate_range(x,y,back_inserter(retval)); - retval; +def generate_range(x, y) { + auto retval := Vector(); + generate_range(x,y,back_inserter(retval)); + retval; } # Returns a new Vector with the first value to the second value as its elements -def collate(x, y) { - return [x, y]; +def collate(x, y) { + return [x, y]; } -def zip_with(f, x, y, inserter) : call_exists(range, x) && call_exists(range, y) { - auto r_x := range(x); - auto r_y := range(y); - while (!r_x.empty() && !r_y.empty()) { - inserter(f(r_x.front(), r_y.front())); - r_x.pop_front(); - r_y.pop_front(); - } +def zip_with(f, x, y, inserter) : call_exists(range, x) && call_exists(range, y) { + auto r_x := range(x); + auto r_y := range(y); + while (!r_x.empty() && !r_y.empty()) { + inserter(f(r_x.front(), r_y.front())); + r_x.pop_front(); + r_y.pop_front(); + } } # Returns a new Vector which joins matching elements of the second and third value with the first value function -def zip_with(f, x, y) { - auto retval := Vector(); - zip_with(f,x,y,back_inserter(retval)); +def zip_with(f, x, y) { + auto retval := Vector(); + zip_with(f,x,y,back_inserter(retval)); retval; } # Returns a new Vector which joins matching elements of the first and second -def zip(x, y) { - zip_with(collate, x, y); +def zip(x, y) { + zip_with(collate, x, y); } # Returns the position of the second value string in the first value string -def string::find(string substr) { - find(this, substr, size_t(0)); +def string::find(string substr) { + find(this, substr, size_t(0)); } # Returns the position of last match of the second value string in the first value string -def string::rfind(string substr) { - rfind(this, substr, size_t(-1)); +def string::rfind(string substr) { + rfind(this, substr, size_t(-1)); } # Returns the position of the first match of elements in the second value string in the first value string -def string::find_first_of(string list) { - find_first_of(this, list, size_t(0)); -} +def string::find_first_of(string list) { + find_first_of(this, list, size_t(0)); +} # Returns the position of the last match of elements in the second value string in the first value string def string::find_last_of(string list) { - find_last_of(this, list, size_t(-1)); -} - - -# Returns the position of the first non-matching element in the second value string in the first value string -def string::find_first_not_of(string list) { - find_first_not_of(this, list, size_t(0)); -} - - -# Returns the position of the last non-matching element in the second value string in the first value string -def string::find_last_not_of(string list) { - find_last_not_of(this, list, size_t(-1)); -} - - -def string::ltrim() { - drop_while(this, fun(x) { x == ' ' || x == '\t' || x == '\r' || x == '\n'}); -} - - -def string::rtrim() { - reverse(drop_while(reverse(this), fun(x) { x == ' ' || x == '\t' || x == '\r' || x == '\n'})); -} - - -def string::trim() { - ltrim(rtrim(this)); + find_last_of(this, list, size_t(-1)); } -def find(container, value, Function compare_func) : call_exists(range, container) { - auto range := range(container); - while (!range.empty()) { - if (compare_func(range.front(), value)) { - return range; - } else { - range.pop_front(); - } - } - range; -} +# Returns the position of the first non-matching element in the second value string in the first value string +def string::find_first_not_of(string list) { + find_first_not_of(this, list, size_t(0)); +} -def find(container, value) { - find(container, value, eq) -} +# Returns the position of the last non-matching element in the second value string in the first value string +def string::find_last_not_of(string list) { + find_last_not_of(this, list, size_t(-1)); +} + + +def string::ltrim() { + drop_while(this, fun(x) { x == ' ' || x == '\t' || x == '\r' || x == '\n'}); +} + + +def string::rtrim() { + reverse(drop_while(reverse(this), fun(x) { x == ' ' || x == '\t' || x == '\r' || x == '\n'})); +} + + +def string::trim() { + ltrim(rtrim(this)); +} + + +def find(container, value, Function compare_func) : call_exists(range, container) { + auto range := range(container); + while (!range.empty()) { + if (compare_func(range.front(), value)) { + return range; + } else { + range.pop_front(); + } + } + range; +} + + +def find(container, value) { + find(container, value, eq) +} )chaiscript"; From ecd6000d54f9212464f811403f47a9a89e0a8fba Mon Sep 17 00:00:00 2001 From: Alek Mosingiewicz Date: Tue, 7 Aug 2018 18:00:58 +0200 Subject: [PATCH 076/155] Throw conversion error when conversion already exists. --- .../dispatchkit/type_conversions.hpp | 31 ++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/include/chaiscript/dispatchkit/type_conversions.hpp b/include/chaiscript/dispatchkit/type_conversions.hpp index 8b57d79c..8ba6bfc8 100644 --- a/include/chaiscript/dispatchkit/type_conversions.hpp +++ b/include/chaiscript/dispatchkit/type_conversions.hpp @@ -30,6 +30,25 @@ namespace chaiscript { namespace exception { + /// \brief Error thrown when there's a problem with type conversion + class conversion_error + { + public: + conversion_error(const Type_Info& t_to, const Type_Info& t_from, const utility::Static_String what): to(t_to), + from(t_from), m_what(std::move(what)) {}; + + const char * what() const noexcept + { + return m_what.c_str(); + } + + private: + const Type_Info& to; + const Type_Info& from; + utility::Static_String m_what; + + }; + class bad_boxed_dynamic_cast : public bad_boxed_cast { public: @@ -362,10 +381,14 @@ namespace chaiscript return cache; } + void add_conversion(const std::shared_ptr &conversion) { chaiscript::detail::threading::unique_lock l(m_mutex); - /// \todo error if a conversion already exists + if (has_conversion(conversion)) { + throw exception::conversion_error(conversion->to(), conversion->from(), + "Trying to re-insert an existing conversion!"); + } m_conversions.insert(conversion); m_convertableTypes.insert({conversion->to().bare_type_info(), conversion->from().bare_type_info()}); m_num_types = m_convertableTypes.size(); @@ -452,6 +475,12 @@ namespace chaiscript return find_bidir(to, from) != m_conversions.end(); } + /// \brief has_conversion overloaded for Type_Conversion_Base parameter + bool has_conversion(const std::shared_ptr &conversion) + { + return has_conversion(conversion->to(), conversion->from()); + } + std::shared_ptr get_conversion(const Type_Info &to, const Type_Info &from) const { chaiscript::detail::threading::shared_lock l(m_mutex); From 27bee4a266dc8d2469d1eb65b7a91d6338f1ba77 Mon Sep 17 00:00:00 2001 From: Alek Mosingiewicz Date: Fri, 10 Aug 2018 17:29:46 +0200 Subject: [PATCH 077/155] Bypass the mutex problem when looking for conversion, automatic test. --- .../dispatchkit/type_conversions.hpp | 8 +------- unittests/compiled_tests.cpp | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/include/chaiscript/dispatchkit/type_conversions.hpp b/include/chaiscript/dispatchkit/type_conversions.hpp index 8ba6bfc8..05c03fc1 100644 --- a/include/chaiscript/dispatchkit/type_conversions.hpp +++ b/include/chaiscript/dispatchkit/type_conversions.hpp @@ -385,7 +385,7 @@ namespace chaiscript void add_conversion(const std::shared_ptr &conversion) { chaiscript::detail::threading::unique_lock l(m_mutex); - if (has_conversion(conversion)) { + if (find_bidir(conversion->to(), conversion->from()) != m_conversions.end()) { throw exception::conversion_error(conversion->to(), conversion->from(), "Trying to re-insert an existing conversion!"); } @@ -475,12 +475,6 @@ namespace chaiscript return find_bidir(to, from) != m_conversions.end(); } - /// \brief has_conversion overloaded for Type_Conversion_Base parameter - bool has_conversion(const std::shared_ptr &conversion) - { - return has_conversion(conversion->to(), conversion->from()); - } - std::shared_ptr get_conversion(const Type_Info &to, const Type_Info &from) const { chaiscript::detail::threading::shared_lock l(m_mutex); diff --git a/unittests/compiled_tests.cpp b/unittests/compiled_tests.cpp index 8723d23d..f6141b09 100644 --- a/unittests/compiled_tests.cpp +++ b/unittests/compiled_tests.cpp @@ -1354,4 +1354,23 @@ TEST_CASE("Test ability to get 'use' function from default construction") const auto use_function = chai.eval>("use"); } +TEST_CASE("Throw an exception when trying to add one conversion twice") +{ + struct my_int { + int value; + my_int(int val): value(val) {}; + }; + + chaiscript::ChaiScript chai; + chai.add(chaiscript::type_conversion([](int x) { + std::cout << "Foo type conversion 1\n"; + return my_int(x); + })); + CHECK_THROWS_AS(chai.add(chaiscript::type_conversion([](int x) { + std::cout << "Foo type conversion 2\n"; + return my_int(x); + })), chaiscript::exception::conversion_error); + +} + From 80f11de41ef77f33a46339b0ceb5977afad2c1f9 Mon Sep 17 00:00:00 2001 From: Alek Mosingiewicz Date: Fri, 10 Aug 2018 17:57:15 +0200 Subject: [PATCH 078/155] Make information on source and target types in Type Conversion Exception public. --- include/chaiscript/dispatchkit/type_conversions.hpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/include/chaiscript/dispatchkit/type_conversions.hpp b/include/chaiscript/dispatchkit/type_conversions.hpp index 05c03fc1..f0065243 100644 --- a/include/chaiscript/dispatchkit/type_conversions.hpp +++ b/include/chaiscript/dispatchkit/type_conversions.hpp @@ -42,9 +42,10 @@ namespace chaiscript return m_what.c_str(); } - private: - const Type_Info& to; - const Type_Info& from; + const Type_Info& to; + const Type_Info& from; + + private: utility::Static_String m_what; }; From eb3ee28cee2174d489c1a59d1f66cdf08ccb7b0e Mon Sep 17 00:00:00 2001 From: Alek Mosingiewicz Date: Mon, 13 Aug 2018 17:56:49 +0200 Subject: [PATCH 079/155] Some better naming for test. --- include/chaiscript/dispatchkit/type_conversions.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/chaiscript/dispatchkit/type_conversions.hpp b/include/chaiscript/dispatchkit/type_conversions.hpp index f0065243..caec282a 100644 --- a/include/chaiscript/dispatchkit/type_conversions.hpp +++ b/include/chaiscript/dispatchkit/type_conversions.hpp @@ -34,7 +34,7 @@ namespace chaiscript class conversion_error { public: - conversion_error(const Type_Info& t_to, const Type_Info& t_from, const utility::Static_String what): to(t_to), + conversion_error(const Type_Info t_to, const Type_Info t_from, const utility::Static_String what): to(t_to), from(t_from), m_what(std::move(what)) {}; const char * what() const noexcept @@ -42,8 +42,8 @@ namespace chaiscript return m_what.c_str(); } - const Type_Info& to; - const Type_Info& from; + Type_Info to; + Type_Info from; private: utility::Static_String m_what; From a254e112862317af77fa657aa02f3d1343fde38b Mon Sep 17 00:00:00 2001 From: Alek Mosingiewicz Date: Mon, 13 Aug 2018 17:57:38 +0200 Subject: [PATCH 080/155] Make information on source and target types in Type Conversion Exception public. --- unittests/compiled_tests.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/unittests/compiled_tests.cpp b/unittests/compiled_tests.cpp index f6141b09..b05fdb2e 100644 --- a/unittests/compiled_tests.cpp +++ b/unittests/compiled_tests.cpp @@ -1354,7 +1354,7 @@ TEST_CASE("Test ability to get 'use' function from default construction") const auto use_function = chai.eval>("use"); } -TEST_CASE("Throw an exception when trying to add one conversion twice") +TEST_CASE("Throw an exception when trying to add same conversion twice") { struct my_int { int value; @@ -1363,11 +1363,11 @@ TEST_CASE("Throw an exception when trying to add one conversion twice") chaiscript::ChaiScript chai; chai.add(chaiscript::type_conversion([](int x) { - std::cout << "Foo type conversion 1\n"; + std::cout << "My_int type conversion 1\n"; return my_int(x); })); CHECK_THROWS_AS(chai.add(chaiscript::type_conversion([](int x) { - std::cout << "Foo type conversion 2\n"; + std::cout << "My_int type conversion 2\n"; return my_int(x); })), chaiscript::exception::conversion_error); From b9741d94330948ffa535e13422b9a98fdc4039be Mon Sep 17 00:00:00 2001 From: Alek Mosingiewicz Date: Mon, 13 Aug 2018 18:25:43 +0200 Subject: [PATCH 081/155] Make conversion_error inherit from bad_boxed_cast. --- .../chaiscript/dispatchkit/type_conversions.hpp | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/include/chaiscript/dispatchkit/type_conversions.hpp b/include/chaiscript/dispatchkit/type_conversions.hpp index caec282a..20f1295e 100644 --- a/include/chaiscript/dispatchkit/type_conversions.hpp +++ b/include/chaiscript/dispatchkit/type_conversions.hpp @@ -31,22 +31,14 @@ namespace chaiscript namespace exception { /// \brief Error thrown when there's a problem with type conversion - class conversion_error + class conversion_error: public bad_boxed_cast { public: - conversion_error(const Type_Info t_to, const Type_Info t_from, const utility::Static_String what): to(t_to), - from(t_from), m_what(std::move(what)) {}; + conversion_error(const Type_Info t_to, const Type_Info t_from, const utility::Static_String what) noexcept + : bad_boxed_cast(t_from, (*t_to.bare_type_info()), what), type_to(t_to) {}; - const char * what() const noexcept - { - return m_what.c_str(); - } + Type_Info type_to; - Type_Info to; - Type_Info from; - - private: - utility::Static_String m_what; }; From 9f9436e741c50ced4c8d33b0946e5f7e4f2eaa6d Mon Sep 17 00:00:00 2001 From: Alek Mosingiewicz Date: Mon, 13 Aug 2018 21:19:15 +0200 Subject: [PATCH 082/155] Remove newlines. --- include/chaiscript/dispatchkit/type_conversions.hpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/chaiscript/dispatchkit/type_conversions.hpp b/include/chaiscript/dispatchkit/type_conversions.hpp index 20f1295e..9d07ddaa 100644 --- a/include/chaiscript/dispatchkit/type_conversions.hpp +++ b/include/chaiscript/dispatchkit/type_conversions.hpp @@ -38,8 +38,6 @@ namespace chaiscript : bad_boxed_cast(t_from, (*t_to.bare_type_info()), what), type_to(t_to) {}; Type_Info type_to; - - }; class bad_boxed_dynamic_cast : public bad_boxed_cast From 4be5e876b8a1cd406f96fb9d1ea484837f289583 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Wed, 15 Aug 2018 11:19:09 -0600 Subject: [PATCH 083/155] Add failing test for returning of & to * --- unittests/compiled_tests.cpp | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/unittests/compiled_tests.cpp b/unittests/compiled_tests.cpp index 8723d23d..614dcb73 100644 --- a/unittests/compiled_tests.cpp +++ b/unittests/compiled_tests.cpp @@ -204,6 +204,31 @@ TEST_CASE("Throw int or double") } } +TEST_CASE("Deduction of pointer return types") +{ + int val = 5; + int *val_ptr = &val; + auto &val_ptr_ref = val_ptr; + const auto &val_ptr_const_ref = val_ptr; + + auto get_val_ptr = [&]() -> int * { return val_ptr; }; + auto get_val_const_ptr = [&]() -> int const * { return val_ptr; }; + auto get_val_ptr_ref = [&]() -> int *& { return val_ptr_ref; }; + auto get_val_const_ptr_ref = [&]() -> int * const & { return val_ptr_const_ref; }; + + chaiscript::ChaiScript_Basic chai(create_chaiscript_stdlib(), create_chaiscript_parser()); + chai.add(chaiscript::fun(get_val_ptr), "get_val_ptr"); + chai.add(chaiscript::fun(get_val_const_ptr), "get_val_const_ptr"); + chai.add(chaiscript::fun(get_val_ptr_ref), "get_val_ptr_ref"); + chai.add(chaiscript::fun(get_val_const_ptr_ref), "get_val_const_ptr_ref"); + + CHECK(chai.eval("get_val_ptr()") == &val); + CHECK(chai.eval("get_val_const_ptr()") == &val); + CHECK(chai.eval("get_val_ptr_ref()") == &val); + CHECK(chai.eval("get_val_const_ptr_ref()") == &val); +} + + TEST_CASE("Throw a runtime_error") { chaiscript::ChaiScript_Basic chai(create_chaiscript_stdlib(),create_chaiscript_parser()); From 44dab4d45c1b9f7753b9480d622a4e3e3067c15d Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Wed, 15 Aug 2018 13:10:23 -0600 Subject: [PATCH 084/155] Deal with returning of & to * types --- .../chaiscript/dispatchkit/handle_return.hpp | 26 +++++++++++++++---- unittests/compiled_tests.cpp | 20 ++++++++++---- 2 files changed, 36 insertions(+), 10 deletions(-) diff --git a/include/chaiscript/dispatchkit/handle_return.hpp b/include/chaiscript/dispatchkit/handle_return.hpp index 8570c8d0..5a98c9a9 100644 --- a/include/chaiscript/dispatchkit/handle_return.hpp +++ b/include/chaiscript/dispatchkit/handle_return.hpp @@ -167,17 +167,33 @@ namespace chaiscript } }; - - - template - struct Handle_Return + template + struct Handle_Return_Ref { - static Boxed_Value handle(const Ret &r) + template + static Boxed_Value handle(T &&r) { return Boxed_Value(std::cref(r), true); } }; + template + struct Handle_Return_Ref + { + template + static Boxed_Value handle(T &&r) + { + return Boxed_Value(typename std::remove_reference::type{r}, true); + } + }; + + template + struct Handle_Return : Handle_Return_Ref::type>::value> + { + + }; + + template struct Handle_Return { diff --git a/unittests/compiled_tests.cpp b/unittests/compiled_tests.cpp index 614dcb73..705d34b3 100644 --- a/unittests/compiled_tests.cpp +++ b/unittests/compiled_tests.cpp @@ -214,18 +214,28 @@ TEST_CASE("Deduction of pointer return types") auto get_val_ptr = [&]() -> int * { return val_ptr; }; auto get_val_const_ptr = [&]() -> int const * { return val_ptr; }; auto get_val_ptr_ref = [&]() -> int *& { return val_ptr_ref; }; - auto get_val_const_ptr_ref = [&]() -> int * const & { return val_ptr_const_ref; }; + auto get_val_ptr_const_ref = [&]() -> int * const & { return val_ptr_const_ref; }; +// auto get_val_const_ptr_const_ref = [ref=std::cref(val_ptr)]() -> int const * const & { return ref.get(); }; chaiscript::ChaiScript_Basic chai(create_chaiscript_stdlib(), create_chaiscript_parser()); chai.add(chaiscript::fun(get_val_ptr), "get_val_ptr"); chai.add(chaiscript::fun(get_val_const_ptr), "get_val_const_ptr"); chai.add(chaiscript::fun(get_val_ptr_ref), "get_val_ptr_ref"); - chai.add(chaiscript::fun(get_val_const_ptr_ref), "get_val_const_ptr_ref"); + chai.add(chaiscript::fun(get_val_ptr_const_ref), "get_val_ptr_const_ref"); +// chai.add(chaiscript::fun(get_val_const_ptr_const_ref), "get_val_const_ptr_const_ref"); CHECK(chai.eval("get_val_ptr()") == &val); - CHECK(chai.eval("get_val_const_ptr()") == &val); - CHECK(chai.eval("get_val_ptr_ref()") == &val); - CHECK(chai.eval("get_val_const_ptr_ref()") == &val); + CHECK(*chai.eval("get_val_ptr()") == val); + CHECK(chai.eval("get_val_const_ptr()") == &val); + CHECK(*chai.eval("get_val_const_ptr()") == val); + + // note that we cannot maintain the references here, + // chaiscript internals cannot handle that, effectively pointer to pointer + CHECK(chai.eval("get_val_ptr_ref()") == &val); + CHECK(*chai.eval("get_val_ptr_ref()") == val); + CHECK(chai.eval("get_val_ptr_const_ref()") == &val); + CHECK(*chai.eval("get_val_ptr_const_ref()") == val); +// CHECK(chai.eval("get_val_const_ptr_const_ref()") == &val); } From 3af55d60f23c6a3ef4e3becc16ade6364ca15f7d Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Wed, 15 Aug 2018 13:12:36 -0600 Subject: [PATCH 085/155] Update version to 6.1.1 --- CMakeLists.txt | 2 +- include/chaiscript/chaiscript_defines.hpp | 2 +- releasenotes.md | 6 +++++- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1ab8f3b1..8a66d287 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -100,7 +100,7 @@ set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/description.txt" set(CPACK_PACKAGE_VERSION_MAJOR 6) set(CPACK_PACKAGE_VERSION_MINOR 1) -set(CPACK_PACKAGE_VERSION_PATCH 0) +set(CPACK_PACKAGE_VERSION_PATCH 1) set(CPACK_PACKAGE_EXECUTABLES "chai;ChaiScript Eval") set(CPACK_PACKAGE_VENDOR "ChaiScript.com") diff --git a/include/chaiscript/chaiscript_defines.hpp b/include/chaiscript/chaiscript_defines.hpp index 4508d603..bf9a13d7 100644 --- a/include/chaiscript/chaiscript_defines.hpp +++ b/include/chaiscript/chaiscript_defines.hpp @@ -77,7 +77,7 @@ static_assert(_MSC_FULL_VER >= 190024210, "Visual C++ 2015 Update 3 or later req namespace chaiscript { static const int version_major = 6; static const int version_minor = 1; - static const int version_patch = 0; + static const int version_patch = 1; static const char *compiler_version = CHAISCRIPT_COMPILER_VERSION; static const char *compiler_name = CHAISCRIPT_COMPILER_NAME; diff --git a/releasenotes.md b/releasenotes.md index c4ab63be..cdccd888 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -1,6 +1,10 @@ Notes: ======= -Current Version: 6.1.0 +Current Version: 6.1.1 + +### Changes since 6.1.0 + + * Handle the returning of `&` to `*` types. This specifically comes up with `std::vector` and similar containers ### Changes since 6.0.0 From e729e4e86c883b5f8c2c741de8a22099b3ec0467 Mon Sep 17 00:00:00 2001 From: ninnghazad Date: Tue, 25 Sep 2018 15:02:47 +0200 Subject: [PATCH 086/155] Single typo (Mame -> Name) Fixed a typo (Mame -> Name) i came across. --- cheatsheet.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cheatsheet.md b/cheatsheet.md index 907fe329..81758062 100644 --- a/cheatsheet.md +++ b/cheatsheet.md @@ -566,7 +566,7 @@ If both a 2 parameter and a 3 parameter signature match, the 3 parameter functio * `__LINE__` Current file line number * `__FILE__` Full path of current file * `__CLASS__` Name of current class - * `__FUNC__` Mame of current function + * `__FUNC__` Name of current function # Built In Functions From 8d0fc743418385451146bed97c75b27a8e38acdb Mon Sep 17 00:00:00 2001 From: Alek Mosingiewicz Date: Sat, 20 Oct 2018 16:50:08 +0200 Subject: [PATCH 087/155] Ci fix after moving to cpp17 (#455) * Update travis configuration. * Update GCC_VER in travis configuration. * Leave only Visual Studio 15 in Appveyor. * Travis - remove GCC_VER 4.9. * Travis - update clang-xcode. * Travis - update clang compiler. * Travis - downgrade clang compiler to 3.4. * Revert "Travis - downgrade clang compiler to 3.4." This reverts commit bd6698bccea9252dd00e8f28fb31334b0e3ea743. * Travis - clang-6.0 package and compiler. * Travis - remove (perhaps unnecessary) compiler option. * Travis - restore clang compiler option. * Update .travis.yml * Another attempt to fix Travis config for clang. * Another attempt to fix Travis config for clang. * Compiler package for clang. * Compiler package for clang. * Xcode 10. * Remove xcode from equation. * Force install clang-6.0. * Does it install these packages at all???. * Does it install these packages at all???. * Some appveyor fixes. * Update CMakeLists.txt Enforce C++17 standard * Update .travis.yml Restore xcode, block CLANG_VER. * experimental/variant for Apple compilers. * Remove OSX pipeline. * Remove OSX pipeline. * Attempt at fixing AppVeyor pipeline. * Restore proper VS version in AppVeyor configuration. * Revert preprocessor changes in json.hpp. --- .travis.yml | 30 +++++++++++++++++------------- CMakeLists.txt | 3 +++ appveyor.yml | 7 +++---- 3 files changed, 23 insertions(+), 17 deletions(-) diff --git a/.travis.yml b/.travis.yml index 7333e3b0..6a103736 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,10 +5,12 @@ addons: apt: sources: - ubuntu-toolchain-r-test + - llvm-toolchain-trusty-5.0 + - sourceline: 'deb http://apt.llvm.org/trusty/ llvm-toolchain-trusty-5.0 main' + key_url: 'https://apt.llvm.org/llvm-snapshot.gpg.key' packages: - - g++-4.9 - - g++-5 - - g++-6 + - g++-7 + - g++-8 coverity_scan: project: name: "ChaiScript/ChaiScript" @@ -22,7 +24,7 @@ matrix: include: - os: linux sudo: false - env: GCC_VER="4.9" + env: GCC_VER="7" compiler: gcc # - os: linux #sudo: false @@ -30,19 +32,20 @@ matrix: #compiler: gcc - os: linux sudo: false - env: GCC_VER="5" CPPCHECK=1 CMAKE_OPTIONS="-D RUN_FUZZY_TESTS:BOOL=TRUE" + env: GCC_VER="7" CPPCHECK=1 CMAKE_OPTIONS="-D RUN_FUZZY_TESTS:BOOL=TRUE" compiler: gcc - os: linux sudo: false - env: GCC_VER="6" CPPCHECK=1 COVERAGE=1 CMAKE_OPTIONS="-D RUN_FUZZY_TESTS:BOOL=TRUE" + env: GCC_VER="8" CPPCHECK=1 COVERAGE=1 CMAKE_OPTIONS="-D RUN_FUZZY_TESTS:BOOL=TRUE" compiler: gcc - - os: osx - compiler: clang - osx_image: xcode8 - - os: osx - compiler: clang - osx_image: xcode8 - env: CMAKE_OPTIONS="-D DYNLOAD_ENABLED:BOOL=FALSE -D MULTITHREAD_SUPPORT_ENABLED:BOOL=FALSE -D USE_STD_MAKE_SHARED:BOOL=TRUE" BUILD_ONLY=1 + #- os: osx + # compiler: clang + # osx_image: xcode10 + # env: CLANG_VER="5.0" + #- os: osx + # compiler: clang + # osx_image: xcode10 + # env: CLANG_VER="5.0" CMAKE_OPTIONS="-D DYNLOAD_ENABLED:BOOL=FALSE -D MULTITHREAD_SUPPORT_ENABLED:BOOL=FALSE -D USE_STD_MAKE_SHARED:BOOL=TRUE" BUILD_ONLY=1 env: global: @@ -52,6 +55,7 @@ env: before_install: - if [ "${GCC_VER}" != "" ]; then export CXX="g++-$GCC_VER" CC="gcc-$GCC_VER" GCOV="gcov-$GCC_VER" ; fi + #- if [ "${CLANG_VER}" != "" ]; then export CXX="clang++-$CLANG_VER"; fi - pip install --user cpp-coveralls script: diff --git a/CMakeLists.txt b/CMakeLists.txt index 3cfec822..2d7dcced 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,6 +4,9 @@ if(NOT ${CMAKE_VERSION} VERSION_LESS "3.1") cmake_policy(SET CMP0054 NEW) endif() +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + project(chaiscript) option(MULTITHREAD_SUPPORT_ENABLED "Multithreaded Support Enabled" TRUE) diff --git a/appveyor.yml b/appveyor.yml index 19187929..a5528862 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,10 +1,9 @@ version: 6.1.x.{build} -image: - - Visual Studio 2017 +image: + - Visual Studio 2017 environment: matrix: - - VS_VERSION: "Visual Studio 14" - - VS_VERSION: "Visual Studio 15" + - VS_VERSION: "Visual Studio 15" build_script: - cmd: >- mkdir build From 7a67963ca77aa2c092348ebf195fadc54c3467dd Mon Sep 17 00:00:00 2001 From: Yuri Yaryshev Date: Thu, 15 Nov 2018 18:59:18 +0300 Subject: [PATCH 088/155] Fix: added 'static' to thread_local variable in chaiscript/chaiscript_threading.hpp Because it's a singleton and should be one instance per thread, without it will be singleton per call, also it won't compile on VS2017 15.8.9 The error: chaiscript\include\chaiscript\chaiscript_threading.hpp(107): error C2480: 'my_t': 'thread' is only valid for data items of static extent --- include/chaiscript/chaiscript_threading.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/chaiscript/chaiscript_threading.hpp b/include/chaiscript/chaiscript_threading.hpp index 3875f9cf..9bfa44fc 100644 --- a/include/chaiscript/chaiscript_threading.hpp +++ b/include/chaiscript/chaiscript_threading.hpp @@ -107,7 +107,7 @@ namespace chaiscript /// does there is no possible way to recover static std::unordered_map &t() noexcept { - thread_local std::unordered_map my_t; + static thread_local std::unordered_map my_t; return my_t; } }; From cba13f94d675eaea428a00c25c45b5242657cfc5 Mon Sep 17 00:00:00 2001 From: vocaviking Date: Wed, 19 Dec 2018 13:03:30 +0100 Subject: [PATCH 089/155] Updated cheatsheet.md - Simplified the part about ChaiScript initialization - Added a link to the ChaiScriptExtras helper library - Removed the Subsection about built-ins, because they are not longer in the code --- cheatsheet.md | 24 ++++-------------------- 1 file changed, 4 insertions(+), 20 deletions(-) diff --git a/cheatsheet.md b/cheatsheet.md index 81758062..350863fa 100644 --- a/cheatsheet.md +++ b/cheatsheet.md @@ -11,13 +11,11 @@ ChaiScript tries to follow the [Semantic Versioning](http://semver.org/) scheme. # Initializing ChaiScript ``` -chaiscript::ChaiScript chai; // loads stdlib from loadable module on file system -chaiscript::ChaiScript chai(chaiscript::Std_Lib::library()); // compiles in stdlib +chaiscript::ChaiScript chai; // initializes ChaiScript, adding the standard ChaiScript types (map, string, ...) ``` Note that ChaiScript cannot be used as a global / static object unless it is being compiled with `CHAISCRIPT_NO_THREADS`. - # Adding Things To The Engine ## Adding a Function / Method / Member @@ -200,6 +198,9 @@ chai.eval(R"_( )_"); ``` +## Adding STL math +ChaiScript itself does not provide a link to the math functions defined in ``. You can either add them yourself, or use the [https://github.com/ChaiScript/ChaiScript_Extras](ChaiScript_Extras) helper library. (Which also provides some additional string functions.) + # Executing Script ## General @@ -571,23 +572,6 @@ If both a 2 parameter and a 3 parameter signature match, the 3 parameter functio # Built In Functions -## Disabling Built-Ins - -When constructing a ChaiScript object, a vector of parameters can be passed in to disable or enable various built-in methods. - -Current options: - -``` -enum class Options -{ - Load_Modules, - No_Load_Modules, - External_Scripts, - No_External_Scripts -}; -``` - - ## Evaluation ``` From c0f217ababf0f5f07da3589159187c8907ae1005 Mon Sep 17 00:00:00 2001 From: vocaviking Date: Fri, 21 Dec 2018 15:43:52 +0100 Subject: [PATCH 090/155] Moved ChaiScript_Extras to the bottom --- cheatsheet.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cheatsheet.md b/cheatsheet.md index 350863fa..80d4b3a8 100644 --- a/cheatsheet.md +++ b/cheatsheet.md @@ -198,9 +198,6 @@ chai.eval(R"_( )_"); ``` -## Adding STL math -ChaiScript itself does not provide a link to the math functions defined in ``. You can either add them yourself, or use the [https://github.com/ChaiScript/ChaiScript_Extras](ChaiScript_Extras) helper library. (Which also provides some additional string functions.) - # Executing Script ## General @@ -587,3 +584,6 @@ Both `use` and `eval_file` search the 'usepaths' passed to the ChaiScript constr * `from_json` converts a JSON string into its strongly typed (map, vector, int, double, string) representations * `to_json` converts a ChaiScript object (either a `Object` or one of map, vector, int, double, string) tree into its JSON string representation + +## Extras +ChaiScript itself does not provide a link to the math functions defined in ``. You can either add them yourself, or use the [https://github.com/ChaiScript/ChaiScript_Extras](ChaiScript_Extras) helper library. (Which also provides some additional string functions.) From 62ccd6d2ff73bec88142c0e3d2597a248666987a Mon Sep 17 00:00:00 2001 From: Rob Loach Date: Thu, 31 Jan 2019 09:16:59 -0500 Subject: [PATCH 091/155] docs: Add push_back_ref() note --- cheatsheet.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/cheatsheet.md b/cheatsheet.md index 80d4b3a8..8c71ebe4 100644 --- a/cheatsheet.md +++ b/cheatsheet.md @@ -389,11 +389,23 @@ switch (myvalue) { ## Built in Types +There are a number of build-in types that are part of ChaiScript. + +### Vectors and Maps + ``` var v = [1,2,3u,4ll,"16", `+`]; // creates vector of heterogenous values var m = ["a":1, "b":2]; // map of string:value pairs + +// Add a value to the vector by value. +v.push_back(123); + +// Add an object to the vector by reference. +v.push_back_ref(m); ``` +### Numbers + Floating point values default to `double` type and integers default to `int` type. All C++ suffixes such as `f`, `ll`, `u` as well as scientific notation are supported From b7e26b90762a696e81a0fa8e3f572b39fe49c7e8 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Sat, 20 Apr 2019 12:09:24 -0600 Subject: [PATCH 092/155] 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 093/155] 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 a5a756a20e37debd4e559b5fa0571004e07a58d1 Mon Sep 17 00:00:00 2001 From: Glen Fraser Date: Sun, 21 Apr 2019 20:07:19 +0200 Subject: [PATCH 094/155] Add pair_conversion registration helper with unit test --- .../dispatchkit/type_conversions.hpp | 17 ++++++++++++++ unittests/compiled_tests.cpp | 23 +++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/include/chaiscript/dispatchkit/type_conversions.hpp b/include/chaiscript/dispatchkit/type_conversions.hpp index 9d07ddaa..91ee1336 100644 --- a/include/chaiscript/dispatchkit/type_conversions.hpp +++ b/include/chaiscript/dispatchkit/type_conversions.hpp @@ -654,6 +654,23 @@ namespace chaiscript return chaiscript::make_shared>(user_type>(), user_type(), func); } + + template + Type_Conversion pair_conversion() + { + auto func = [](const Boxed_Value &t_bv) -> Boxed_Value { + const std::pair &from_pair = detail::Cast_Helper &>::cast(t_bv, nullptr); + + auto pair = std::make_pair( + detail::Cast_Helper::cast(from_pair.first, nullptr), + detail::Cast_Helper::cast(from_pair.second, nullptr) + ); + + return Boxed_Value(std::move(pair)); + }; + + return chaiscript::make_shared>(user_type>(), user_type>(), func); + } } diff --git a/unittests/compiled_tests.cpp b/unittests/compiled_tests.cpp index 76c31bc8..a5261655 100644 --- a/unittests/compiled_tests.cpp +++ b/unittests/compiled_tests.cpp @@ -996,6 +996,29 @@ TEST_CASE("Map conversions") } +TEST_CASE("Pair conversions") +{ + chaiscript::ChaiScript_Basic chai(create_chaiscript_stdlib(),create_chaiscript_parser()); + chai.add(chaiscript::pair_conversion()); + chai.add(chaiscript::pair_conversion()); + + { + const auto p = chai.eval>(R"cs( + Pair("chai", "script"); + )cs"); + CHECK(p.first == std::string{"chai"}); + CHECK(p.second == "script"); + } + { + const auto p = chai.eval>(R"cs( + Pair(5, 3.14); + )cs"); + CHECK(p.first == 5); + CHECK(p.second == Approx(3.14)); + } +} + + TEST_CASE("Parse floats with non-posix locale") { #ifdef CHAISCRIPT_MSVC From 57ebd9d4039a3f724e48f909973fe663dac819ee Mon Sep 17 00:00:00 2001 From: medithe <40990424+medithe@users.noreply.github.com> Date: Thu, 25 Apr 2019 23:18:51 +0200 Subject: [PATCH 095/155] Update cheatsheet.md: Adding Lambda correction. Currently, the example where a lambda function was added to chaiscript didn't work for me. I use g++7, g++8,g++9 both with c++14 and c++17 mode. It doesn't work either in clang++-7. If the lambda is wrapped into a std::function<> it will work again! --- cheatsheet.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cheatsheet.md b/cheatsheet.md index 80d4b3a8..5e712d4e 100644 --- a/cheatsheet.md +++ b/cheatsheet.md @@ -66,7 +66,7 @@ chai.add(chaiscript::fun(static_cast(&Derived::data)), "data"); ``` chai.add( - chaiscript::fun( + chaiscript::fun>( [](bool type) { if (type) { return "x"; } else { return "y"; } From 273bc4a94aa61ad466f676cf981e8ce28508e9ec Mon Sep 17 00:00:00 2001 From: Vladyslav Tronko Date: Wed, 5 Jun 2019 15:19:31 +0300 Subject: [PATCH 096/155] Fix description of ChaiScriptBasic::use Add missing word --- include/chaiscript/language/chaiscript_engine.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/chaiscript/language/chaiscript_engine.hpp b/include/chaiscript/language/chaiscript_engine.hpp index 2a68341c..63f9fc4e 100644 --- a/include/chaiscript/language/chaiscript_engine.hpp +++ b/include/chaiscript/language/chaiscript_engine.hpp @@ -386,9 +386,9 @@ namespace chaiscript } - /// \brief Loads and parses a file. If the file is already, it is not reloaded - /// The use paths specified at ChaiScript construction time are searched for the - /// requested file. + /// \brief Loads and parses a file. If the file is already open, it is not + /// reloaded. The use paths specified at ChaiScript construction time are + /// searched for the requested file. /// /// \param[in] t_filename Filename to load and evaluate Boxed_Value use(const std::string &t_filename) From 8e5d4a712c0c047786ed69c722b507fc8edfe669 Mon Sep 17 00:00:00 2001 From: Rob Loach Date: Wed, 26 Jun 2019 14:51:34 -0400 Subject: [PATCH 097/155] docs: Fix gendering Fixes #491 --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 8323a128..cba11ac4 100644 --- a/readme.md +++ b/readme.md @@ -29,7 +29,7 @@ Introduction ChaiScript is one of the only embedded scripting language designed from the ground up to directly target C++ and take advantage of modern C++ development -techniques, working with the developer like he expects it to work. Being a +techniques, working with the developer how they would expect it to work. Being a native C++ application, it has some advantages over existing embedded scripting languages: From af7a5d7c492992d513537c3b36dd1882f0c5f38d Mon Sep 17 00:00:00 2001 From: Joshua Thompson Date: Thu, 22 Aug 2019 10:00:37 -0400 Subject: [PATCH 098/155] #487: Fix warning for implicit 'this' lambda capture in C++20. --- include/chaiscript/language/chaiscript_engine.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/chaiscript/language/chaiscript_engine.hpp b/include/chaiscript/language/chaiscript_engine.hpp index 63f9fc4e..d7da1257 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( - [=](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( - [=](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"); From eeda632846b19a0125954594325d60d5f2b22b17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20M=C5=82okosiewicz?= Date: Mon, 2 Sep 2019 23:12:57 +0200 Subject: [PATCH 099/155] cheatsheet: fix link to ChaiScript_Extras --- cheatsheet.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cheatsheet.md b/cheatsheet.md index 805f69a3..32d1c3b5 100644 --- a/cheatsheet.md +++ b/cheatsheet.md @@ -598,4 +598,4 @@ Both `use` and `eval_file` search the 'usepaths' passed to the ChaiScript constr * `to_json` converts a ChaiScript object (either a `Object` or one of map, vector, int, double, string) tree into its JSON string representation ## Extras -ChaiScript itself does not provide a link to the math functions defined in ``. You can either add them yourself, or use the [https://github.com/ChaiScript/ChaiScript_Extras](ChaiScript_Extras) helper library. (Which also provides some additional string functions.) +ChaiScript itself does not provide a link to the math functions defined in ``. You can either add them yourself, or use the [ChaiScript_Extras](https://github.com/ChaiScript/ChaiScript_Extras) helper library. (Which also provides some additional string functions.) From 2de0844616d15f0a75435b7984724b1ed9ec10a3 Mon Sep 17 00:00:00 2001 From: grdowns Date: Fri, 27 Sep 2019 02:16:37 -0700 Subject: [PATCH 100/155] Add vcpkg installation instructions --- readme.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/readme.md b/readme.md index cba11ac4..88f8a516 100644 --- a/readme.md +++ b/readme.md @@ -48,6 +48,19 @@ templates. It has been tested with gcc 4.9 and clang 3.6 (with libcxx). For more information see the build [dashboard](http://chaiscript.com/ChaiScript-BuildResults/index.html). +Installation using vcpkg +======================== + +You can download and install ChaiScript using the [vcpkg](https://github.com/Microsoft/vcpkg/) dependency manager: + + git clone https://github.com/Microsoft/vcpkg.git + cd vcpkg + ./bootstrap-vcpkg.sh + ./vcpkg integrate install + vcpkg install chaiscript + +The ChaiScript port in vcpkg is kept up to date by Microsoft team members and community contributors. If the version is out of date, please [create an issue or pull request](https://github.com/Microsoft/vcpkg) on the vcpkg repository. + Usage ===== From 3e621814143ebc433d2fa90c7765e4a159c2ada3 Mon Sep 17 00:00:00 2001 From: Guo Yunhe Date: Sat, 9 Nov 2019 11:10:45 +0200 Subject: [PATCH 101/155] Use LIBDIR instead of lib In Linux, the library should be installed to /usr/lib64 on 64bit machine --- CMakeLists.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2d7dcced..ff221858 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -426,7 +426,7 @@ if(BUILD_TESTING) target_link_libraries(multifile_test ${LIBS}) add_test(NAME MultiFile_Test COMMAND multifile_test) - install(TARGETS test_module RUNTIME DESTINATION bin LIBRARY DESTINATION lib/chaiscript) + install(TARGETS test_module RUNTIME DESTINATION bin LIBRARY DESTINATION LIBDIR/chaiscript) endif() endif() @@ -439,7 +439,7 @@ if(BUILD_LIBFUZZ_TESTER) endif() -install(TARGETS chai chaiscript_stdlib-${CHAI_VERSION} ${MODULES} RUNTIME DESTINATION bin LIBRARY DESTINATION lib/chaiscript) +install(TARGETS chai chaiscript_stdlib-${CHAI_VERSION} ${MODULES} RUNTIME DESTINATION bin LIBRARY DESTINATION LIBDIR/chaiscript) install(DIRECTORY include/chaiscript DESTINATION include PATTERN "*.hpp" @@ -458,8 +458,8 @@ install(DIRECTORY samples DESTINATION share/chaiscript PATTERN "*/.git*" EXCLUDE PATTERN "*~" EXCLUDE) -configure_file(contrib/pkgconfig/chaiscript.pc.in lib/pkgconfig/chaiscript.pc @ONLY) +configure_file(contrib/pkgconfig/chaiscript.pc.in LIBDIR/pkgconfig/chaiscript.pc @ONLY) install(FILES "${chaiscript_BINARY_DIR}/lib/pkgconfig/chaiscript.pc" - DESTINATION lib/pkgconfig) + DESTINATION LIBDIR/pkgconfig) From 741893204aad5f147b0cba257279d98fc3e8bb7e Mon Sep 17 00:00:00 2001 From: Guo Yunhe Date: Sat, 9 Nov 2019 11:19:38 +0200 Subject: [PATCH 102/155] Update CMakeLists.txt --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ff221858..897fe3d8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -458,7 +458,7 @@ install(DIRECTORY samples DESTINATION share/chaiscript PATTERN "*/.git*" EXCLUDE PATTERN "*~" EXCLUDE) -configure_file(contrib/pkgconfig/chaiscript.pc.in LIBDIR/pkgconfig/chaiscript.pc @ONLY) +configure_file(contrib/pkgconfig/chaiscript.pc.in lib/pkgconfig/chaiscript.pc @ONLY) install(FILES "${chaiscript_BINARY_DIR}/lib/pkgconfig/chaiscript.pc" DESTINATION LIBDIR/pkgconfig) From 63951d06f2af1ff80e97353927be74c73ec984e0 Mon Sep 17 00:00:00 2001 From: Guo Yunhe Date: Sat, 9 Nov 2019 11:36:31 +0200 Subject: [PATCH 103/155] Update CMakeLists.txt --- CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 897fe3d8..a2ca72e5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -426,7 +426,7 @@ if(BUILD_TESTING) target_link_libraries(multifile_test ${LIBS}) add_test(NAME MultiFile_Test COMMAND multifile_test) - install(TARGETS test_module RUNTIME DESTINATION bin LIBRARY DESTINATION LIBDIR/chaiscript) + install(TARGETS test_module RUNTIME DESTINATION bin LIBRARY DESTINATION ${LIBDIR}/chaiscript) endif() endif() @@ -439,7 +439,7 @@ if(BUILD_LIBFUZZ_TESTER) endif() -install(TARGETS chai chaiscript_stdlib-${CHAI_VERSION} ${MODULES} RUNTIME DESTINATION bin LIBRARY DESTINATION LIBDIR/chaiscript) +install(TARGETS chai chaiscript_stdlib-${CHAI_VERSION} ${MODULES} RUNTIME DESTINATION bin LIBRARY DESTINATION ${LIBDIR}/chaiscript) install(DIRECTORY include/chaiscript DESTINATION include PATTERN "*.hpp" @@ -460,6 +460,6 @@ install(DIRECTORY samples DESTINATION share/chaiscript configure_file(contrib/pkgconfig/chaiscript.pc.in lib/pkgconfig/chaiscript.pc @ONLY) install(FILES "${chaiscript_BINARY_DIR}/lib/pkgconfig/chaiscript.pc" - DESTINATION LIBDIR/pkgconfig) + DESTINATION ${LIBDIR}/pkgconfig) From 0aa186abbe1ab9d5050bd9fcece88fc1596dd05c Mon Sep 17 00:00:00 2001 From: Guo Yunhe Date: Sat, 9 Nov 2019 11:37:32 +0200 Subject: [PATCH 104/155] Update CMakeLists.txt --- CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a2ca72e5..f04149bc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -426,7 +426,7 @@ if(BUILD_TESTING) target_link_libraries(multifile_test ${LIBS}) add_test(NAME MultiFile_Test COMMAND multifile_test) - install(TARGETS test_module RUNTIME DESTINATION bin LIBRARY DESTINATION ${LIBDIR}/chaiscript) + install(TARGETS test_module RUNTIME DESTINATION bin LIBRARY DESTINATION "${LIBDIR}/chaiscript") endif() endif() @@ -439,7 +439,7 @@ if(BUILD_LIBFUZZ_TESTER) endif() -install(TARGETS chai chaiscript_stdlib-${CHAI_VERSION} ${MODULES} RUNTIME DESTINATION bin LIBRARY DESTINATION ${LIBDIR}/chaiscript) +install(TARGETS chai chaiscript_stdlib-${CHAI_VERSION} ${MODULES} RUNTIME DESTINATION bin LIBRARY DESTINATION "${LIBDIR}/chaiscript") install(DIRECTORY include/chaiscript DESTINATION include PATTERN "*.hpp" @@ -460,6 +460,6 @@ install(DIRECTORY samples DESTINATION share/chaiscript configure_file(contrib/pkgconfig/chaiscript.pc.in lib/pkgconfig/chaiscript.pc @ONLY) install(FILES "${chaiscript_BINARY_DIR}/lib/pkgconfig/chaiscript.pc" - DESTINATION ${LIBDIR}/pkgconfig) + DESTINATION "${LIBDIR}/pkgconfig") From cb1867dfd160f005425d0878b3758d1fe75072df Mon Sep 17 00:00:00 2001 From: Guo Yunhe Date: Sat, 9 Nov 2019 12:01:50 +0200 Subject: [PATCH 105/155] Update CMakeLists.txt --- CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f04149bc..7e1e754b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -426,7 +426,7 @@ if(BUILD_TESTING) target_link_libraries(multifile_test ${LIBS}) add_test(NAME MultiFile_Test COMMAND multifile_test) - install(TARGETS test_module RUNTIME DESTINATION bin LIBRARY DESTINATION "${LIBDIR}/chaiscript") + install(TARGETS test_module RUNTIME DESTINATION bin LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}/chaiscript") endif() endif() @@ -439,7 +439,7 @@ if(BUILD_LIBFUZZ_TESTER) endif() -install(TARGETS chai chaiscript_stdlib-${CHAI_VERSION} ${MODULES} RUNTIME DESTINATION bin LIBRARY DESTINATION "${LIBDIR}/chaiscript") +install(TARGETS chai chaiscript_stdlib-${CHAI_VERSION} ${MODULES} RUNTIME DESTINATION bin LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}/chaiscript") install(DIRECTORY include/chaiscript DESTINATION include PATTERN "*.hpp" @@ -460,6 +460,6 @@ install(DIRECTORY samples DESTINATION share/chaiscript configure_file(contrib/pkgconfig/chaiscript.pc.in lib/pkgconfig/chaiscript.pc @ONLY) install(FILES "${chaiscript_BINARY_DIR}/lib/pkgconfig/chaiscript.pc" - DESTINATION "${LIBDIR}/pkgconfig") + DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig") From a7dae37a2320de198923fe8873a9c0d982fe4498 Mon Sep 17 00:00:00 2001 From: Rob Loach Date: Sat, 9 Nov 2019 09:44:07 -0500 Subject: [PATCH 106/155] Update release notes for 6.1.1 --- releasenotes.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/releasenotes.md b/releasenotes.md index cdccd888..a622566e 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -5,6 +5,9 @@ Current Version: 6.1.1 ### Changes since 6.1.0 * Handle the returning of `&` to `*` types. This specifically comes up with `std::vector` and similar containers + * Update CMake to use `LIBDIR` instead of `lib` #502 by @guoyunhe + * Add documentation for installing ChaiScript with vcpkg #500 by @grdowns + * Fix warning for implicit 'this' lambda capture in C++20 #495 by @Josh-Thompson ### Changes since 6.0.0 @@ -18,7 +21,6 @@ Current Version: 6.1.1 * Support for C++17 compilers! * Support for UTF8 BOM #439 @AlekMosingiewicz @MarioLiebisch - ### Changes since 5.8.6 *6.0.0 is a massive rework compared to 5.x. It now requires a C++14 enabled compiler* From a3c033d1db07a74e5f0c1b7a3910b51a226aba83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dariusz=20Py=C5=9B?= Date: Sun, 10 Nov 2019 00:46:22 +0100 Subject: [PATCH 107/155] Fix bug #481 Applied solution sent by SG-Skril here: https://github.com/ChaiScript/ChaiScript/issues/481 --- 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..73213080 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 0e243b006a0f0794ccd88fc13073bab094498c62 Mon Sep 17 00:00:00 2001 From: SG-Skril Date: Sun, 10 Nov 2019 18:07:47 +0100 Subject: [PATCH 108/155] 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 109/155] =?UTF-8?q?Fix=20for=20warnings:=20by-copy=20captu?= =?UTF-8?q?re=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 110/155] 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 111/155] 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 112/155] 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 113/155] 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 114/155] 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 115/155] 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 116/155] 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 117/155] 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 118/155] 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 119/155] 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))); } From 940afb399c6d3bcfa366c7b6452d31be8904bd9f Mon Sep 17 00:00:00 2001 From: draghan Date: Sat, 27 Mar 2021 21:17:03 +0100 Subject: [PATCH 120/155] Revert "Fix bug #481" This reverts commit a3c033d1db07a74e5f0c1b7a3910b51a226aba83. --- 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 73213080..6071898b 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 && !std::is_same_v>, bool>) { + if constexpr (std::is_arithmetic_v) { 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 0a3bc48788f398d2786128896eb6501fe512eeb5 Mon Sep 17 00:00:00 2001 From: draghan Date: Tue, 12 Nov 2019 21:51:46 +0100 Subject: [PATCH 121/155] Add unit test covering issue #481 Implemented unit test which is validating whether a lambda from Chaiscript could return a boolean value without throwing any exception. The same test case is checking whether lambda with boolean return value could be called peacefully from Chaiscript. --- unittests/compiled_tests.cpp | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/unittests/compiled_tests.cpp b/unittests/compiled_tests.cpp index 365386ad..ddb17365 100644 --- a/unittests/compiled_tests.cpp +++ b/unittests/compiled_tests.cpp @@ -50,6 +50,26 @@ TEST_CASE("C++11 Lambdas Can Be Registered") CHECK(chai.eval("f2()") == "world"); } +TEST_CASE("Lambdas can return boolean") +{ + chaiscript::ChaiScript_Basic chai(create_chaiscript_stdlib(),create_chaiscript_parser()); + + // check lambdas returning bool from chaiscript: + std::function chai_function; + + CHECK_NOTHROW(chai_function = chai.eval>("fun() { 42 != 0 }")); + + bool result = false; + CHECK_NOTHROW(result = chai_function()); + + CHECK(result == true); + + // check lambdas returning bool from C++: + auto cpp_function = [](int x) { return x == 42; }; + CHECK_NOTHROW(chai.add(chaiscript::fun(cpp_function), "cpp_function")); + CHECK_NOTHROW(result = chai.eval("cpp_function(314)")); + CHECK(result == false); +} // dynamic_object tests TEST_CASE("Dynamic_Object attributes can be shared with C++") From 52a9fa47c181c777844b53ccb5bc3fb183e919fb Mon Sep 17 00:00:00 2001 From: Bernd Amend Date: Sat, 22 May 2021 13:16:44 +0200 Subject: [PATCH 122/155] replace std::vector::push_back with emplace_back --- src/main.cpp | 8 ++++---- unittests/multithreaded_test.cpp | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 7fbc1cb1..0c045c6e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -282,19 +282,19 @@ int main(int argc, char *argv[]) #endif std::vector usepaths; - usepaths.push_back(""); + usepaths.emplace_back(""); if (usepath != nullptr) { - usepaths.push_back(usepath); + usepaths.emplace_back(usepath); } std::vector modulepaths; std::vector searchpaths = default_search_paths(); modulepaths.insert(modulepaths.end(), searchpaths.begin(), searchpaths.end()); - modulepaths.push_back(""); + modulepaths.emplace_back(""); if (modulepath != nullptr) { - modulepaths.push_back(modulepath); + modulepaths.emplace_back(modulepath); } chaiscript::ChaiScript_Basic chai(create_chaiscript_stdlib(),create_chaiscript_parser(),modulepaths,usepaths); diff --git a/unittests/multithreaded_test.cpp b/unittests/multithreaded_test.cpp index e2d0240b..9241f743 100644 --- a/unittests/multithreaded_test.cpp +++ b/unittests/multithreaded_test.cpp @@ -53,10 +53,10 @@ int main() #endif std::vector usepaths; - usepaths.push_back(""); + usepaths.emplace_back(""); if (usepath) { - usepaths.push_back(usepath); + usepaths.emplace_back(usepath); } std::vector modulepaths; @@ -64,10 +64,10 @@ int main() #ifdef CHAISCRIPT_NO_DYNLOAD chaiscript::ChaiScript chai(/* unused */modulepaths, usepaths); #else - modulepaths.push_back(""); + modulepaths.emplace_back(""); if (modulepath) { - modulepaths.push_back(modulepath); + modulepaths.emplace_back(modulepath); } // For this test we are going to load the dynamic stdlib From 180a6d4a1cc28a73cbb97ac1ecc3e2cea5325fd7 Mon Sep 17 00:00:00 2001 From: Bernd Amend Date: Sat, 22 May 2021 13:18:49 +0200 Subject: [PATCH 123/155] update catch to version 2.13.6 --- unittests/catch.hpp | 8951 +++++++++++++++++++++++++++++++++---------- 1 file changed, 6919 insertions(+), 2032 deletions(-) diff --git a/unittests/catch.hpp b/unittests/catch.hpp index ecd8907e..36eaeb27 100644 --- a/unittests/catch.hpp +++ b/unittests/catch.hpp @@ -1,9 +1,9 @@ /* - * Catch v2.2.2 - * Generated: 2018-04-06 12:05:03.186665 + * Catch v2.13.6 + * Generated: 2021-04-16 18:23:38.044268 * ---------------------------------------------------------- * This file has been merged from multiple headers. Please don't edit it directly - * Copyright (c) 2018 Two Blue Cubes Ltd. All rights reserved. + * Copyright (c) 2021 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -14,8 +14,8 @@ #define CATCH_VERSION_MAJOR 2 -#define CATCH_VERSION_MINOR 2 -#define CATCH_VERSION_PATCH 2 +#define CATCH_VERSION_MINOR 13 +#define CATCH_VERSION_PATCH 6 #ifdef __clang__ # pragma clang system_header @@ -30,14 +30,17 @@ # pragma warning(push) # pragma warning(disable: 161 1682) # else // __ICC -# pragma clang diagnostic ignored "-Wunused-variable" # pragma clang diagnostic push # pragma clang diagnostic ignored "-Wpadded" # pragma clang diagnostic ignored "-Wswitch-enum" # pragma clang diagnostic ignored "-Wcovered-switch-default" # endif #elif defined __GNUC__ -# pragma GCC diagnostic ignored "-Wparentheses" + // Because REQUIREs trigger GCC's -Wparentheses, and because still + // supported version of g++ have only buggy support for _Pragmas, + // Wparentheses have to be suppressed globally. +# pragma GCC diagnostic ignored "-Wparentheses" // See #674 for details + # pragma GCC diagnostic push # pragma GCC diagnostic ignored "-Wunused-variable" # pragma GCC diagnostic ignored "-Wpadded" @@ -55,24 +58,29 @@ # if defined(CATCH_CONFIG_DISABLE_MATCHERS) # undef CATCH_CONFIG_DISABLE_MATCHERS # endif -# define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER +# if !defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER) +# define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER +# endif #endif #if !defined(CATCH_CONFIG_IMPL_ONLY) // start catch_platform.h +// See e.g.: +// https://opensource.apple.com/source/CarbonHeaders/CarbonHeaders-18.1/TargetConditionals.h.auto.html #ifdef __APPLE__ -# include -# if TARGET_OS_OSX == 1 -# define CATCH_PLATFORM_MAC -# elif TARGET_OS_IPHONE == 1 -# define CATCH_PLATFORM_IPHONE -# endif +# include +# if (defined(TARGET_OS_OSX) && TARGET_OS_OSX == 1) || \ + (defined(TARGET_OS_MAC) && TARGET_OS_MAC == 1) +# define CATCH_PLATFORM_MAC +# elif (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE == 1) +# define CATCH_PLATFORM_IPHONE +# endif #elif defined(linux) || defined(__linux) || defined(__linux__) # define CATCH_PLATFORM_LINUX -#elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) +#elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) || defined(__MINGW32__) # define CATCH_PLATFORM_WINDOWS #endif @@ -104,6 +112,7 @@ namespace Catch { // CATCH_CONFIG_COUNTER : is the __COUNTER__ macro supported? // CATCH_CONFIG_WINDOWS_SEH : is Windows SEH supported? // CATCH_CONFIG_POSIX_SIGNALS : are POSIX signals supported? +// CATCH_CONFIG_DISABLE_EXCEPTIONS : Are exceptions enabled? // **************** // Note to maintainers: if new toggles are added please document them // in configuration.md, too @@ -116,34 +125,61 @@ namespace Catch { #ifdef __cplusplus -# if __cplusplus >= 201402L +# if (__cplusplus >= 201402L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201402L) # define CATCH_CPP14_OR_GREATER # endif -# if __cplusplus >= 201703L +# if (__cplusplus >= 201703L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) # define CATCH_CPP17_OR_GREATER # endif #endif -#if defined(CATCH_CPP17_OR_GREATER) -# define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS +// Only GCC compiler should be used in this block, so other compilers trying to +// mask themselves as GCC should be ignored. +#if defined(__GNUC__) && !defined(__clang__) && !defined(__ICC) && !defined(__CUDACC__) && !defined(__LCC__) +# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "GCC diagnostic push" ) +# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma( "GCC diagnostic pop" ) + +# define CATCH_INTERNAL_IGNORE_BUT_WARN(...) (void)__builtin_constant_p(__VA_ARGS__) + #endif -#ifdef __clang__ +#if defined(__clang__) -# define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ - _Pragma( "clang diagnostic push" ) \ - _Pragma( "clang diagnostic ignored \"-Wexit-time-destructors\"" ) \ - _Pragma( "clang diagnostic ignored \"-Wglobal-constructors\"") -# define CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \ - _Pragma( "clang diagnostic pop" ) +# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "clang diagnostic push" ) +# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma( "clang diagnostic pop" ) -# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \ - _Pragma( "clang diagnostic push" ) \ - _Pragma( "clang diagnostic ignored \"-Wparentheses\"" ) -# define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \ - _Pragma( "clang diagnostic pop" ) +// As of this writing, IBM XL's implementation of __builtin_constant_p has a bug +// which results in calls to destructors being emitted for each temporary, +// without a matching initialization. In practice, this can result in something +// like `std::string::~string` being called on an uninitialized value. +// +// For example, this code will likely segfault under IBM XL: +// ``` +// REQUIRE(std::string("12") + "34" == "1234") +// ``` +// +// Therefore, `CATCH_INTERNAL_IGNORE_BUT_WARN` is not implemented. +# if !defined(__ibmxl__) && !defined(__CUDACC__) +# define CATCH_INTERNAL_IGNORE_BUT_WARN(...) (void)__builtin_constant_p(__VA_ARGS__) /* NOLINT(cppcoreguidelines-pro-type-vararg, hicpp-vararg) */ +# endif + +# define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ + _Pragma( "clang diagnostic ignored \"-Wexit-time-destructors\"" ) \ + _Pragma( "clang diagnostic ignored \"-Wglobal-constructors\"") + +# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \ + _Pragma( "clang diagnostic ignored \"-Wparentheses\"" ) + +# define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \ + _Pragma( "clang diagnostic ignored \"-Wunused-variable\"" ) + +# define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \ + _Pragma( "clang diagnostic ignored \"-Wgnu-zero-variadic-macro-arguments\"" ) + +# define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \ + _Pragma( "clang diagnostic ignored \"-Wunused-template\"" ) #endif // __clang__ @@ -164,6 +200,25 @@ namespace Catch { # define CATCH_CONFIG_COLOUR_NONE #endif +//////////////////////////////////////////////////////////////////////////////// +// Android somehow still does not support std::to_string +#if defined(__ANDROID__) +# define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING +# define CATCH_INTERNAL_CONFIG_ANDROID_LOGWRITE +#endif + +//////////////////////////////////////////////////////////////////////////////// +// Not all Windows environments support SEH properly +#if defined(__MINGW32__) +# define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH +#endif + +//////////////////////////////////////////////////////////////////////////////// +// PS4 +#if defined(__ORBIS__) +# define CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE +#endif + //////////////////////////////////////////////////////////////////////////////// // Cygwin #ifdef __CYGWIN__ @@ -171,16 +226,22 @@ namespace Catch { // Required for some versions of Cygwin to declare gettimeofday // see: http://stackoverflow.com/questions/36901803/gettimeofday-not-declared-in-this-scope-cygwin # define _BSD_SOURCE +// some versions of cygwin (most) do not support std::to_string. Use the libstd check. +// https://gcc.gnu.org/onlinedocs/gcc-4.8.2/libstdc++/api/a01053_source.html line 2812-2813 +# if !((__cplusplus >= 201103L) && defined(_GLIBCXX_USE_C99) \ + && !defined(_GLIBCXX_HAVE_BROKEN_VSWPRINTF)) +# define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING + +# endif #endif // __CYGWIN__ //////////////////////////////////////////////////////////////////////////////// // Visual C++ -#ifdef _MSC_VER +#if defined(_MSC_VER) -# if _MSC_VER >= 1900 // Visual Studio 2015 or newer -# define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS -# endif +# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION __pragma( warning(push) ) +# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION __pragma( warning(pop) ) // Universal Windows platform does not support SEH // Or console colours (or console at all...) @@ -190,15 +251,40 @@ namespace Catch { # define CATCH_INTERNAL_CONFIG_WINDOWS_SEH # endif +// MSVC traditional preprocessor needs some workaround for __VA_ARGS__ +// _MSVC_TRADITIONAL == 0 means new conformant preprocessor +// _MSVC_TRADITIONAL == 1 means old traditional non-conformant preprocessor +# if !defined(__clang__) // Handle Clang masquerading for msvc +# if !defined(_MSVC_TRADITIONAL) || (defined(_MSVC_TRADITIONAL) && _MSVC_TRADITIONAL) +# define CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR +# endif // MSVC_TRADITIONAL +# endif // __clang__ + +#endif // _MSC_VER + +#if defined(_REENTRANT) || defined(_MSC_VER) +// Enable async processing, as -pthread is specified or no additional linking is required +# define CATCH_INTERNAL_CONFIG_USE_ASYNC #endif // _MSC_VER //////////////////////////////////////////////////////////////////////////////// +// Check if we are compiled with -fno-exceptions or equivalent +#if defined(__EXCEPTIONS) || defined(__cpp_exceptions) || defined(_CPPUNWIND) +# define CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED +#endif +//////////////////////////////////////////////////////////////////////////////// // DJGPP #ifdef __DJGPP__ # define CATCH_INTERNAL_CONFIG_NO_WCHAR #endif // __DJGPP__ +//////////////////////////////////////////////////////////////////////////////// +// Embarcadero C++Build +#if defined(__BORLANDC__) + #define CATCH_INTERNAL_CONFIG_POLYFILL_ISNAN +#endif + //////////////////////////////////////////////////////////////////////////////// // Use of __COUNTER__ is suppressed during code analysis in @@ -210,10 +296,62 @@ namespace Catch { #define CATCH_INTERNAL_CONFIG_COUNTER #endif +//////////////////////////////////////////////////////////////////////////////// + +// RTX is a special version of Windows that is real time. +// This means that it is detected as Windows, but does not provide +// the same set of capabilities as real Windows does. +#if defined(UNDER_RTSS) || defined(RTX64_BUILD) + #define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH + #define CATCH_INTERNAL_CONFIG_NO_ASYNC + #define CATCH_CONFIG_COLOUR_NONE +#endif + +#if !defined(_GLIBCXX_USE_C99_MATH_TR1) +#define CATCH_INTERNAL_CONFIG_GLOBAL_NEXTAFTER +#endif + +// Various stdlib support checks that require __has_include +#if defined(__has_include) + // Check if string_view is available and usable + #if __has_include() && defined(CATCH_CPP17_OR_GREATER) + # define CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW + #endif + + // Check if optional is available and usable + # if __has_include() && defined(CATCH_CPP17_OR_GREATER) + # define CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL + # endif // __has_include() && defined(CATCH_CPP17_OR_GREATER) + + // Check if byte is available and usable + # if __has_include() && defined(CATCH_CPP17_OR_GREATER) + # include + # if __cpp_lib_byte > 0 + # define CATCH_INTERNAL_CONFIG_CPP17_BYTE + # endif + # endif // __has_include() && defined(CATCH_CPP17_OR_GREATER) + + // Check if variant is available and usable + # if __has_include() && defined(CATCH_CPP17_OR_GREATER) + # if defined(__clang__) && (__clang_major__ < 8) + // work around clang bug with libstdc++ https://bugs.llvm.org/show_bug.cgi?id=31852 + // fix should be in clang 8, workaround in libstdc++ 8.2 + # include + # if defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9) + # define CATCH_CONFIG_NO_CPP17_VARIANT + # else + # define CATCH_INTERNAL_CONFIG_CPP17_VARIANT + # endif // defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9) + # else + # define CATCH_INTERNAL_CONFIG_CPP17_VARIANT + # endif // defined(__clang__) && (__clang_major__ < 8) + # endif // __has_include() && defined(CATCH_CPP17_OR_GREATER) +#endif // defined(__has_include) + #if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER) # define CATCH_CONFIG_COUNTER #endif -#if defined(CATCH_INTERNAL_CONFIG_WINDOWS_SEH) && !defined(CATCH_CONFIG_NO_WINDOWS_SEH) && !defined(CATCH_CONFIG_WINDOWS_SEH) +#if defined(CATCH_INTERNAL_CONFIG_WINDOWS_SEH) && !defined(CATCH_CONFIG_NO_WINDOWS_SEH) && !defined(CATCH_CONFIG_WINDOWS_SEH) && !defined(CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH) # define CATCH_CONFIG_WINDOWS_SEH #endif // This is set by default, because we assume that unix compilers are posix-signal-compatible by default. @@ -225,17 +363,103 @@ namespace Catch { # define CATCH_CONFIG_WCHAR #endif -#if defined(CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) && !defined(CATCH_CONFIG_NO_CPP17_UNCAUGHT_EXCEPTIONS) && !defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) -# define CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS +#if !defined(CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_CPP11_TO_STRING) +# define CATCH_CONFIG_CPP11_TO_STRING #endif +#if defined(CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL) && !defined(CATCH_CONFIG_NO_CPP17_OPTIONAL) && !defined(CATCH_CONFIG_CPP17_OPTIONAL) +# define CATCH_CONFIG_CPP17_OPTIONAL +#endif + +#if defined(CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_NO_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_CPP17_STRING_VIEW) +# define CATCH_CONFIG_CPP17_STRING_VIEW +#endif + +#if defined(CATCH_INTERNAL_CONFIG_CPP17_VARIANT) && !defined(CATCH_CONFIG_NO_CPP17_VARIANT) && !defined(CATCH_CONFIG_CPP17_VARIANT) +# define CATCH_CONFIG_CPP17_VARIANT +#endif + +#if defined(CATCH_INTERNAL_CONFIG_CPP17_BYTE) && !defined(CATCH_CONFIG_NO_CPP17_BYTE) && !defined(CATCH_CONFIG_CPP17_BYTE) +# define CATCH_CONFIG_CPP17_BYTE +#endif + +#if defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT) +# define CATCH_INTERNAL_CONFIG_NEW_CAPTURE +#endif + +#if defined(CATCH_INTERNAL_CONFIG_NEW_CAPTURE) && !defined(CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE) && !defined(CATCH_CONFIG_NO_NEW_CAPTURE) && !defined(CATCH_CONFIG_NEW_CAPTURE) +# define CATCH_CONFIG_NEW_CAPTURE +#endif + +#if !defined(CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED) && !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) +# define CATCH_CONFIG_DISABLE_EXCEPTIONS +#endif + +#if defined(CATCH_INTERNAL_CONFIG_POLYFILL_ISNAN) && !defined(CATCH_CONFIG_NO_POLYFILL_ISNAN) && !defined(CATCH_CONFIG_POLYFILL_ISNAN) +# define CATCH_CONFIG_POLYFILL_ISNAN +#endif + +#if defined(CATCH_INTERNAL_CONFIG_USE_ASYNC) && !defined(CATCH_INTERNAL_CONFIG_NO_ASYNC) && !defined(CATCH_CONFIG_NO_USE_ASYNC) && !defined(CATCH_CONFIG_USE_ASYNC) +# define CATCH_CONFIG_USE_ASYNC +#endif + +#if defined(CATCH_INTERNAL_CONFIG_ANDROID_LOGWRITE) && !defined(CATCH_CONFIG_NO_ANDROID_LOGWRITE) && !defined(CATCH_CONFIG_ANDROID_LOGWRITE) +# define CATCH_CONFIG_ANDROID_LOGWRITE +#endif + +#if defined(CATCH_INTERNAL_CONFIG_GLOBAL_NEXTAFTER) && !defined(CATCH_CONFIG_NO_GLOBAL_NEXTAFTER) && !defined(CATCH_CONFIG_GLOBAL_NEXTAFTER) +# define CATCH_CONFIG_GLOBAL_NEXTAFTER +#endif + +// Even if we do not think the compiler has that warning, we still have +// to provide a macro that can be used by the code. +#if !defined(CATCH_INTERNAL_START_WARNINGS_SUPPRESSION) +# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION +#endif +#if !defined(CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION) +# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION +#endif #if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS) # define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS -# define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS #endif #if !defined(CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS) # define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS -# define CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS +#endif +#if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS) +# define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS +#endif +#if !defined(CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS) +# define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS +#endif + +// The goal of this macro is to avoid evaluation of the arguments, but +// still have the compiler warn on problems inside... +#if !defined(CATCH_INTERNAL_IGNORE_BUT_WARN) +# define CATCH_INTERNAL_IGNORE_BUT_WARN(...) +#endif + +#if defined(__APPLE__) && defined(__apple_build_version__) && (__clang_major__ < 10) +# undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS +#elif defined(__clang__) && (__clang_major__ < 5) +# undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS +#endif + +#if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS) +# define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS +#endif + +#if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) +#define CATCH_TRY if ((true)) +#define CATCH_CATCH_ALL if ((false)) +#define CATCH_CATCH_ANON(type) if ((false)) +#else +#define CATCH_TRY try +#define CATCH_CATCH_ALL catch (...) +#define CATCH_CATCH_ANON(type) catch (type) +#endif + +#if defined(CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR) && !defined(CATCH_CONFIG_NO_TRADITIONAL_MSVC_PREPROCESSOR) && !defined(CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR) +#define CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR #endif // end catch_compiler_capabilities.h @@ -251,6 +475,10 @@ namespace Catch { #include #include +// We need a dummy global operator<< so we can bring it into Catch namespace later +struct Catch_global_namespace_dummy {}; +std::ostream& operator<<(std::ostream&, Catch_global_namespace_dummy); + namespace Catch { struct CaseSensitive { enum Choice { @@ -277,12 +505,12 @@ namespace Catch { line( _line ) {} - SourceLineInfo( SourceLineInfo const& other ) = default; - SourceLineInfo( SourceLineInfo && ) = default; - SourceLineInfo& operator = ( SourceLineInfo const& ) = default; - SourceLineInfo& operator = ( SourceLineInfo && ) = default; + SourceLineInfo( SourceLineInfo const& other ) = default; + SourceLineInfo& operator = ( SourceLineInfo const& ) = default; + SourceLineInfo( SourceLineInfo&& ) noexcept = default; + SourceLineInfo& operator = ( SourceLineInfo&& ) noexcept = default; - bool empty() const noexcept; + bool empty() const noexcept { return file[0] == '\0'; } bool operator == ( SourceLineInfo const& other ) const noexcept; bool operator < ( SourceLineInfo const& other ) const noexcept; @@ -292,6 +520,11 @@ namespace Catch { std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ); + // Bring in operator<< from global namespace into Catch namespace + // This is necessary because the overload of operator<< above makes + // lookup stop at namespace Catch + using ::operator<<; + // Use this in variadic streaming macros to allow // >> +StreamEndStop // as well as @@ -318,9 +551,10 @@ namespace Catch { } // end namespace Catch #define CATCH_REGISTER_TAG_ALIAS( alias, spec ) \ + CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \ CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ namespace{ Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); } \ - CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS + CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION // end catch_tag_alias_autoregistrar.h // start catch_test_registry.h @@ -328,7 +562,6 @@ namespace Catch { // start catch_interfaces_testcase.h #include -#include namespace Catch { @@ -339,8 +572,6 @@ namespace Catch { virtual ~ITestInvoker(); }; - using ITestCasePtr = std::shared_ptr; - class TestCase; struct IConfig; @@ -350,6 +581,7 @@ namespace Catch { virtual std::vector const& getAllTestsSorted( IConfig const& config ) const = 0; }; + bool isThrowSafe( TestCase const& testCase, IConfig const& config ); bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config ); std::vector filterTests( std::vector const& testCases, TestSpec const& testSpec, IConfig const& config ); std::vector const& getAllTestCasesSorted( IConfig const& config ); @@ -362,55 +594,30 @@ namespace Catch { #include #include #include +#include namespace Catch { - class StringData; - /// A non-owning string class (similar to the forthcoming std::string_view) /// Note that, because a StringRef may be a substring of another string, - /// it may not be null terminated. c_str() must return a null terminated - /// string, however, and so the StringRef will internally take ownership - /// (taking a copy), if necessary. In theory this ownership is not externally - /// visible - but it does mean (substring) StringRefs should not be shared between - /// threads. + /// it may not be null terminated. class StringRef { public: using size_type = std::size_t; + using const_iterator = const char*; private: - friend struct StringRefTestAccess; - - char const* m_start; - size_type m_size; - - char* m_data = nullptr; - - void takeOwnership(); - static constexpr char const* const s_empty = ""; - public: // construction/ assignment - StringRef() noexcept - : StringRef( s_empty, 0 ) - {} + char const* m_start = s_empty; + size_type m_size = 0; - StringRef( StringRef const& other ) noexcept - : m_start( other.m_start ), - m_size( other.m_size ) - {} - - StringRef( StringRef&& other ) noexcept - : m_start( other.m_start ), - m_size( other.m_size ), - m_data( other.m_data ) - { - other.m_data = nullptr; - } + public: // construction + constexpr StringRef() noexcept = default; StringRef( char const* rawChars ) noexcept; - StringRef( char const* rawChars, size_type size ) noexcept + constexpr StringRef( char const* rawChars, size_type size ) noexcept : m_start( rawChars ), m_size( size ) {} @@ -420,65 +627,333 @@ namespace Catch { m_size( stdString.size() ) {} - ~StringRef() noexcept { - delete[] m_data; + explicit operator std::string() const { + return std::string(m_start, m_size); } - auto operator = ( StringRef const &other ) noexcept -> StringRef& { - delete[] m_data; - m_data = nullptr; - m_start = other.m_start; - m_size = other.m_size; - return *this; - } - - operator std::string() const; - - void swap( StringRef& other ) noexcept; - public: // operators auto operator == ( StringRef const& other ) const noexcept -> bool; - auto operator != ( StringRef const& other ) const noexcept -> bool; + auto operator != (StringRef const& other) const noexcept -> bool { + return !(*this == other); + } - auto operator[] ( size_type index ) const noexcept -> char; + auto operator[] ( size_type index ) const noexcept -> char { + assert(index < m_size); + return m_start[index]; + } public: // named queries - auto empty() const noexcept -> bool { + constexpr auto empty() const noexcept -> bool { return m_size == 0; } - auto size() const noexcept -> size_type { + constexpr auto size() const noexcept -> size_type { return m_size; } - auto numberOfCharacters() const noexcept -> size_type; + // Returns the current start pointer. If the StringRef is not + // null-terminated, throws std::domain_exception auto c_str() const -> char const*; public: // substrings and searches - auto substr( size_type start, size_type size ) const noexcept -> StringRef; + // Returns a substring of [start, start + length). + // If start + length > size(), then the substring is [start, size()). + // If start > size(), then the substring is empty. + auto substr( size_type start, size_type length ) const noexcept -> StringRef; - // Returns the current start pointer. - // Note that the pointer can change when if the StringRef is a substring - auto currentData() const noexcept -> char const*; + // Returns the current start pointer. May not be null-terminated. + auto data() const noexcept -> char const*; - private: // ownership queries - may not be consistent between calls - auto isOwned() const noexcept -> bool; - auto isSubstring() const noexcept -> bool; + constexpr auto isNullTerminated() const noexcept -> bool { + return m_start[m_size] == '\0'; + } + + public: // iterators + constexpr const_iterator begin() const { return m_start; } + constexpr const_iterator end() const { return m_start + m_size; } }; - auto operator + ( StringRef const& lhs, StringRef const& rhs ) -> std::string; - auto operator + ( StringRef const& lhs, char const* rhs ) -> std::string; - auto operator + ( char const* lhs, StringRef const& rhs ) -> std::string; - auto operator += ( std::string& lhs, StringRef const& sr ) -> std::string&; auto operator << ( std::ostream& os, StringRef const& sr ) -> std::ostream&; - inline auto operator "" _sr( char const* rawChars, std::size_t size ) noexcept -> StringRef { + constexpr auto operator "" _sr( char const* rawChars, std::size_t size ) noexcept -> StringRef { return StringRef( rawChars, size ); } +} // namespace Catch + +constexpr auto operator "" _catch_sr( char const* rawChars, std::size_t size ) noexcept -> Catch::StringRef { + return Catch::StringRef( rawChars, size ); +} + +// end catch_stringref.h +// start catch_preprocessor.hpp + + +#define CATCH_RECURSION_LEVEL0(...) __VA_ARGS__ +#define CATCH_RECURSION_LEVEL1(...) CATCH_RECURSION_LEVEL0(CATCH_RECURSION_LEVEL0(CATCH_RECURSION_LEVEL0(__VA_ARGS__))) +#define CATCH_RECURSION_LEVEL2(...) CATCH_RECURSION_LEVEL1(CATCH_RECURSION_LEVEL1(CATCH_RECURSION_LEVEL1(__VA_ARGS__))) +#define CATCH_RECURSION_LEVEL3(...) CATCH_RECURSION_LEVEL2(CATCH_RECURSION_LEVEL2(CATCH_RECURSION_LEVEL2(__VA_ARGS__))) +#define CATCH_RECURSION_LEVEL4(...) CATCH_RECURSION_LEVEL3(CATCH_RECURSION_LEVEL3(CATCH_RECURSION_LEVEL3(__VA_ARGS__))) +#define CATCH_RECURSION_LEVEL5(...) CATCH_RECURSION_LEVEL4(CATCH_RECURSION_LEVEL4(CATCH_RECURSION_LEVEL4(__VA_ARGS__))) + +#ifdef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR +#define INTERNAL_CATCH_EXPAND_VARGS(...) __VA_ARGS__ +// MSVC needs more evaluations +#define CATCH_RECURSION_LEVEL6(...) CATCH_RECURSION_LEVEL5(CATCH_RECURSION_LEVEL5(CATCH_RECURSION_LEVEL5(__VA_ARGS__))) +#define CATCH_RECURSE(...) CATCH_RECURSION_LEVEL6(CATCH_RECURSION_LEVEL6(__VA_ARGS__)) +#else +#define CATCH_RECURSE(...) CATCH_RECURSION_LEVEL5(__VA_ARGS__) +#endif + +#define CATCH_REC_END(...) +#define CATCH_REC_OUT + +#define CATCH_EMPTY() +#define CATCH_DEFER(id) id CATCH_EMPTY() + +#define CATCH_REC_GET_END2() 0, CATCH_REC_END +#define CATCH_REC_GET_END1(...) CATCH_REC_GET_END2 +#define CATCH_REC_GET_END(...) CATCH_REC_GET_END1 +#define CATCH_REC_NEXT0(test, next, ...) next CATCH_REC_OUT +#define CATCH_REC_NEXT1(test, next) CATCH_DEFER ( CATCH_REC_NEXT0 ) ( test, next, 0) +#define CATCH_REC_NEXT(test, next) CATCH_REC_NEXT1(CATCH_REC_GET_END test, next) + +#define CATCH_REC_LIST0(f, x, peek, ...) , f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1) ) ( f, peek, __VA_ARGS__ ) +#define CATCH_REC_LIST1(f, x, peek, ...) , f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST0) ) ( f, peek, __VA_ARGS__ ) +#define CATCH_REC_LIST2(f, x, peek, ...) f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1) ) ( f, peek, __VA_ARGS__ ) + +#define CATCH_REC_LIST0_UD(f, userdata, x, peek, ...) , f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1_UD) ) ( f, userdata, peek, __VA_ARGS__ ) +#define CATCH_REC_LIST1_UD(f, userdata, x, peek, ...) , f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST0_UD) ) ( f, userdata, peek, __VA_ARGS__ ) +#define CATCH_REC_LIST2_UD(f, userdata, x, peek, ...) f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1_UD) ) ( f, userdata, peek, __VA_ARGS__ ) + +// Applies the function macro `f` to each of the remaining parameters, inserts commas between the results, +// and passes userdata as the first parameter to each invocation, +// e.g. CATCH_REC_LIST_UD(f, x, a, b, c) evaluates to f(x, a), f(x, b), f(x, c) +#define CATCH_REC_LIST_UD(f, userdata, ...) CATCH_RECURSE(CATCH_REC_LIST2_UD(f, userdata, __VA_ARGS__, ()()(), ()()(), ()()(), 0)) + +#define CATCH_REC_LIST(f, ...) CATCH_RECURSE(CATCH_REC_LIST2(f, __VA_ARGS__, ()()(), ()()(), ()()(), 0)) + +#define INTERNAL_CATCH_EXPAND1(param) INTERNAL_CATCH_EXPAND2(param) +#define INTERNAL_CATCH_EXPAND2(...) INTERNAL_CATCH_NO## __VA_ARGS__ +#define INTERNAL_CATCH_DEF(...) INTERNAL_CATCH_DEF __VA_ARGS__ +#define INTERNAL_CATCH_NOINTERNAL_CATCH_DEF +#define INTERNAL_CATCH_STRINGIZE(...) INTERNAL_CATCH_STRINGIZE2(__VA_ARGS__) +#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR +#define INTERNAL_CATCH_STRINGIZE2(...) #__VA_ARGS__ +#define INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS(param) INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_REMOVE_PARENS(param)) +#else +// MSVC is adding extra space and needs another indirection to expand INTERNAL_CATCH_NOINTERNAL_CATCH_DEF +#define INTERNAL_CATCH_STRINGIZE2(...) INTERNAL_CATCH_STRINGIZE3(__VA_ARGS__) +#define INTERNAL_CATCH_STRINGIZE3(...) #__VA_ARGS__ +#define INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS(param) (INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_REMOVE_PARENS(param)) + 1) +#endif + +#define INTERNAL_CATCH_MAKE_NAMESPACE2(...) ns_##__VA_ARGS__ +#define INTERNAL_CATCH_MAKE_NAMESPACE(name) INTERNAL_CATCH_MAKE_NAMESPACE2(name) + +#define INTERNAL_CATCH_REMOVE_PARENS(...) INTERNAL_CATCH_EXPAND1(INTERNAL_CATCH_DEF __VA_ARGS__) + +#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR +#define INTERNAL_CATCH_MAKE_TYPE_LIST2(...) decltype(get_wrapper()) +#define INTERNAL_CATCH_MAKE_TYPE_LIST(...) INTERNAL_CATCH_MAKE_TYPE_LIST2(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__)) +#else +#define INTERNAL_CATCH_MAKE_TYPE_LIST2(...) INTERNAL_CATCH_EXPAND_VARGS(decltype(get_wrapper())) +#define INTERNAL_CATCH_MAKE_TYPE_LIST(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_MAKE_TYPE_LIST2(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__))) +#endif + +#define INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(...)\ + CATCH_REC_LIST(INTERNAL_CATCH_MAKE_TYPE_LIST,__VA_ARGS__) + +#define INTERNAL_CATCH_REMOVE_PARENS_1_ARG(_0) INTERNAL_CATCH_REMOVE_PARENS(_0) +#define INTERNAL_CATCH_REMOVE_PARENS_2_ARG(_0, _1) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_1_ARG(_1) +#define INTERNAL_CATCH_REMOVE_PARENS_3_ARG(_0, _1, _2) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_2_ARG(_1, _2) +#define INTERNAL_CATCH_REMOVE_PARENS_4_ARG(_0, _1, _2, _3) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_3_ARG(_1, _2, _3) +#define INTERNAL_CATCH_REMOVE_PARENS_5_ARG(_0, _1, _2, _3, _4) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_4_ARG(_1, _2, _3, _4) +#define INTERNAL_CATCH_REMOVE_PARENS_6_ARG(_0, _1, _2, _3, _4, _5) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_5_ARG(_1, _2, _3, _4, _5) +#define INTERNAL_CATCH_REMOVE_PARENS_7_ARG(_0, _1, _2, _3, _4, _5, _6) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_6_ARG(_1, _2, _3, _4, _5, _6) +#define INTERNAL_CATCH_REMOVE_PARENS_8_ARG(_0, _1, _2, _3, _4, _5, _6, _7) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_7_ARG(_1, _2, _3, _4, _5, _6, _7) +#define INTERNAL_CATCH_REMOVE_PARENS_9_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_8_ARG(_1, _2, _3, _4, _5, _6, _7, _8) +#define INTERNAL_CATCH_REMOVE_PARENS_10_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_9_ARG(_1, _2, _3, _4, _5, _6, _7, _8, _9) +#define INTERNAL_CATCH_REMOVE_PARENS_11_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_10_ARG(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10) + +#define INTERNAL_CATCH_VA_NARGS_IMPL(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N + +#define INTERNAL_CATCH_TYPE_GEN\ + template struct TypeList {};\ + template\ + constexpr auto get_wrapper() noexcept -> TypeList { return {}; }\ + template class...> struct TemplateTypeList{};\ + template class...Cs>\ + constexpr auto get_wrapper() noexcept -> TemplateTypeList { return {}; }\ + template\ + struct append;\ + template\ + struct rewrap;\ + template class, typename...>\ + struct create;\ + template class, typename>\ + struct convert;\ + \ + template \ + struct append { using type = T; };\ + template< template class L1, typename...E1, template class L2, typename...E2, typename...Rest>\ + struct append, L2, Rest...> { using type = typename append, Rest...>::type; };\ + template< template class L1, typename...E1, typename...Rest>\ + struct append, TypeList, Rest...> { using type = L1; };\ + \ + template< template class Container, template class List, typename...elems>\ + struct rewrap, List> { using type = TypeList>; };\ + template< template class Container, template class List, class...Elems, typename...Elements>\ + struct rewrap, List, Elements...> { using type = typename append>, typename rewrap, Elements...>::type>::type; };\ + \ + template