From ef333e491ad5f74b4a10e0208793d1bf9c7c5f35 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Thu, 20 Jul 2017 21:16:54 -0600 Subject: [PATCH 01/53] 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 02/53] 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 03/53] 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 04/53] 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 05/53] 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 06/53] 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 07/53] 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 08/53] 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 09/53] 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 10/53] 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 11/53] 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 12/53] 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 13/53] 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 14/53] 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 15/53] 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 16/53] 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 17/53] 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 18/53] 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 19/53] 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 20/53] 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 21/53] 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 22/53] 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 23/53] 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 24/53] 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 25/53] 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 26/53] 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 27/53] 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 28/53] 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 29/53] 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 30/53] 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 31/53] 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 32/53] 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 33/53] 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 34/53] 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 35/53] 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 36/53] 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 37/53] 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 38/53] 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 39/53] 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 40/53] 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 41/53] 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 42/53] 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 43/53] 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 44/53] 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 45/53] 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 46/53] 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 47/53] 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 48/53] 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 49/53] 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 50/53] 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 51/53] 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 52/53] 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 4a61d1e5116c0a8fdf3f8c9858c38f391435bf99 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Thu, 14 Dec 2017 08:13:19 -0700 Subject: [PATCH 53/53] 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