From ecd6000d54f9212464f811403f47a9a89e0a8fba Mon Sep 17 00:00:00 2001 From: Alek Mosingiewicz Date: Tue, 7 Aug 2018 18:00:58 +0200 Subject: [PATCH 1/7] Throw conversion error when conversion already exists. --- .../dispatchkit/type_conversions.hpp | 31 ++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/include/chaiscript/dispatchkit/type_conversions.hpp b/include/chaiscript/dispatchkit/type_conversions.hpp index 8b57d79c..8ba6bfc8 100644 --- a/include/chaiscript/dispatchkit/type_conversions.hpp +++ b/include/chaiscript/dispatchkit/type_conversions.hpp @@ -30,6 +30,25 @@ namespace chaiscript { namespace exception { + /// \brief Error thrown when there's a problem with type conversion + class conversion_error + { + public: + conversion_error(const Type_Info& t_to, const Type_Info& t_from, const utility::Static_String what): to(t_to), + from(t_from), m_what(std::move(what)) {}; + + const char * what() const noexcept + { + return m_what.c_str(); + } + + private: + const Type_Info& to; + const Type_Info& from; + utility::Static_String m_what; + + }; + class bad_boxed_dynamic_cast : public bad_boxed_cast { public: @@ -362,10 +381,14 @@ namespace chaiscript return cache; } + void add_conversion(const std::shared_ptr &conversion) { chaiscript::detail::threading::unique_lock l(m_mutex); - /// \todo error if a conversion already exists + if (has_conversion(conversion)) { + throw exception::conversion_error(conversion->to(), conversion->from(), + "Trying to re-insert an existing conversion!"); + } m_conversions.insert(conversion); m_convertableTypes.insert({conversion->to().bare_type_info(), conversion->from().bare_type_info()}); m_num_types = m_convertableTypes.size(); @@ -452,6 +475,12 @@ namespace chaiscript return find_bidir(to, from) != m_conversions.end(); } + /// \brief has_conversion overloaded for Type_Conversion_Base parameter + bool has_conversion(const std::shared_ptr &conversion) + { + return has_conversion(conversion->to(), conversion->from()); + } + std::shared_ptr get_conversion(const Type_Info &to, const Type_Info &from) const { chaiscript::detail::threading::shared_lock l(m_mutex); From 27bee4a266dc8d2469d1eb65b7a91d6338f1ba77 Mon Sep 17 00:00:00 2001 From: Alek Mosingiewicz Date: Fri, 10 Aug 2018 17:29:46 +0200 Subject: [PATCH 2/7] Bypass the mutex problem when looking for conversion, automatic test. --- .../dispatchkit/type_conversions.hpp | 8 +------- unittests/compiled_tests.cpp | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/include/chaiscript/dispatchkit/type_conversions.hpp b/include/chaiscript/dispatchkit/type_conversions.hpp index 8ba6bfc8..05c03fc1 100644 --- a/include/chaiscript/dispatchkit/type_conversions.hpp +++ b/include/chaiscript/dispatchkit/type_conversions.hpp @@ -385,7 +385,7 @@ namespace chaiscript void add_conversion(const std::shared_ptr &conversion) { chaiscript::detail::threading::unique_lock l(m_mutex); - if (has_conversion(conversion)) { + if (find_bidir(conversion->to(), conversion->from()) != m_conversions.end()) { throw exception::conversion_error(conversion->to(), conversion->from(), "Trying to re-insert an existing conversion!"); } @@ -475,12 +475,6 @@ namespace chaiscript return find_bidir(to, from) != m_conversions.end(); } - /// \brief has_conversion overloaded for Type_Conversion_Base parameter - bool has_conversion(const std::shared_ptr &conversion) - { - return has_conversion(conversion->to(), conversion->from()); - } - std::shared_ptr get_conversion(const Type_Info &to, const Type_Info &from) const { chaiscript::detail::threading::shared_lock l(m_mutex); diff --git a/unittests/compiled_tests.cpp b/unittests/compiled_tests.cpp index 8723d23d..f6141b09 100644 --- a/unittests/compiled_tests.cpp +++ b/unittests/compiled_tests.cpp @@ -1354,4 +1354,23 @@ TEST_CASE("Test ability to get 'use' function from default construction") const auto use_function = chai.eval>("use"); } +TEST_CASE("Throw an exception when trying to add one conversion twice") +{ + struct my_int { + int value; + my_int(int val): value(val) {}; + }; + + chaiscript::ChaiScript chai; + chai.add(chaiscript::type_conversion([](int x) { + std::cout << "Foo type conversion 1\n"; + return my_int(x); + })); + CHECK_THROWS_AS(chai.add(chaiscript::type_conversion([](int x) { + std::cout << "Foo type conversion 2\n"; + return my_int(x); + })), chaiscript::exception::conversion_error); + +} + From 80f11de41ef77f33a46339b0ceb5977afad2c1f9 Mon Sep 17 00:00:00 2001 From: Alek Mosingiewicz Date: Fri, 10 Aug 2018 17:57:15 +0200 Subject: [PATCH 3/7] Make information on source and target types in Type Conversion Exception public. --- include/chaiscript/dispatchkit/type_conversions.hpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/include/chaiscript/dispatchkit/type_conversions.hpp b/include/chaiscript/dispatchkit/type_conversions.hpp index 05c03fc1..f0065243 100644 --- a/include/chaiscript/dispatchkit/type_conversions.hpp +++ b/include/chaiscript/dispatchkit/type_conversions.hpp @@ -42,9 +42,10 @@ namespace chaiscript return m_what.c_str(); } - private: - const Type_Info& to; - const Type_Info& from; + const Type_Info& to; + const Type_Info& from; + + private: utility::Static_String m_what; }; From eb3ee28cee2174d489c1a59d1f66cdf08ccb7b0e Mon Sep 17 00:00:00 2001 From: Alek Mosingiewicz Date: Mon, 13 Aug 2018 17:56:49 +0200 Subject: [PATCH 4/7] Some better naming for test. --- include/chaiscript/dispatchkit/type_conversions.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/chaiscript/dispatchkit/type_conversions.hpp b/include/chaiscript/dispatchkit/type_conversions.hpp index f0065243..caec282a 100644 --- a/include/chaiscript/dispatchkit/type_conversions.hpp +++ b/include/chaiscript/dispatchkit/type_conversions.hpp @@ -34,7 +34,7 @@ namespace chaiscript class conversion_error { public: - conversion_error(const Type_Info& t_to, const Type_Info& t_from, const utility::Static_String what): to(t_to), + conversion_error(const Type_Info t_to, const Type_Info t_from, const utility::Static_String what): to(t_to), from(t_from), m_what(std::move(what)) {}; const char * what() const noexcept @@ -42,8 +42,8 @@ namespace chaiscript return m_what.c_str(); } - const Type_Info& to; - const Type_Info& from; + Type_Info to; + Type_Info from; private: utility::Static_String m_what; From a254e112862317af77fa657aa02f3d1343fde38b Mon Sep 17 00:00:00 2001 From: Alek Mosingiewicz Date: Mon, 13 Aug 2018 17:57:38 +0200 Subject: [PATCH 5/7] Make information on source and target types in Type Conversion Exception public. --- unittests/compiled_tests.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/unittests/compiled_tests.cpp b/unittests/compiled_tests.cpp index f6141b09..b05fdb2e 100644 --- a/unittests/compiled_tests.cpp +++ b/unittests/compiled_tests.cpp @@ -1354,7 +1354,7 @@ TEST_CASE("Test ability to get 'use' function from default construction") const auto use_function = chai.eval>("use"); } -TEST_CASE("Throw an exception when trying to add one conversion twice") +TEST_CASE("Throw an exception when trying to add same conversion twice") { struct my_int { int value; @@ -1363,11 +1363,11 @@ TEST_CASE("Throw an exception when trying to add one conversion twice") chaiscript::ChaiScript chai; chai.add(chaiscript::type_conversion([](int x) { - std::cout << "Foo type conversion 1\n"; + std::cout << "My_int type conversion 1\n"; return my_int(x); })); CHECK_THROWS_AS(chai.add(chaiscript::type_conversion([](int x) { - std::cout << "Foo type conversion 2\n"; + std::cout << "My_int type conversion 2\n"; return my_int(x); })), chaiscript::exception::conversion_error); From b9741d94330948ffa535e13422b9a98fdc4039be Mon Sep 17 00:00:00 2001 From: Alek Mosingiewicz Date: Mon, 13 Aug 2018 18:25:43 +0200 Subject: [PATCH 6/7] Make conversion_error inherit from bad_boxed_cast. --- .../chaiscript/dispatchkit/type_conversions.hpp | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/include/chaiscript/dispatchkit/type_conversions.hpp b/include/chaiscript/dispatchkit/type_conversions.hpp index caec282a..20f1295e 100644 --- a/include/chaiscript/dispatchkit/type_conversions.hpp +++ b/include/chaiscript/dispatchkit/type_conversions.hpp @@ -31,22 +31,14 @@ namespace chaiscript namespace exception { /// \brief Error thrown when there's a problem with type conversion - class conversion_error + class conversion_error: public bad_boxed_cast { public: - conversion_error(const Type_Info t_to, const Type_Info t_from, const utility::Static_String what): to(t_to), - from(t_from), m_what(std::move(what)) {}; + conversion_error(const Type_Info t_to, const Type_Info t_from, const utility::Static_String what) noexcept + : bad_boxed_cast(t_from, (*t_to.bare_type_info()), what), type_to(t_to) {}; - const char * what() const noexcept - { - return m_what.c_str(); - } + Type_Info type_to; - Type_Info to; - Type_Info from; - - private: - utility::Static_String m_what; }; From 9f9436e741c50ced4c8d33b0946e5f7e4f2eaa6d Mon Sep 17 00:00:00 2001 From: Alek Mosingiewicz Date: Mon, 13 Aug 2018 21:19:15 +0200 Subject: [PATCH 7/7] Remove newlines. --- include/chaiscript/dispatchkit/type_conversions.hpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/chaiscript/dispatchkit/type_conversions.hpp b/include/chaiscript/dispatchkit/type_conversions.hpp index 20f1295e..9d07ddaa 100644 --- a/include/chaiscript/dispatchkit/type_conversions.hpp +++ b/include/chaiscript/dispatchkit/type_conversions.hpp @@ -38,8 +38,6 @@ namespace chaiscript : bad_boxed_cast(t_from, (*t_to.bare_type_info()), what), type_to(t_to) {}; Type_Info type_to; - - }; class bad_boxed_dynamic_cast : public bad_boxed_cast