diff --git a/include/chaiscript/dispatchkit/type_conversions.hpp b/include/chaiscript/dispatchkit/type_conversions.hpp index 8b57d79c..9d07ddaa 100644 --- a/include/chaiscript/dispatchkit/type_conversions.hpp +++ b/include/chaiscript/dispatchkit/type_conversions.hpp @@ -30,6 +30,16 @@ namespace chaiscript { namespace exception { + /// \brief Error thrown when there's a problem with type conversion + 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) noexcept + : 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 { public: @@ -362,10 +372,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 (find_bidir(conversion->to(), conversion->from()) != m_conversions.end()) { + 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(); diff --git a/unittests/compiled_tests.cpp b/unittests/compiled_tests.cpp index 705d34b3..76c31bc8 100644 --- a/unittests/compiled_tests.cpp +++ b/unittests/compiled_tests.cpp @@ -1389,4 +1389,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 same 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 << "My_int type conversion 1\n"; + return my_int(x); + })); + CHECK_THROWS_AS(chai.add(chaiscript::type_conversion([](int x) { + std::cout << "My_int type conversion 2\n"; + return my_int(x); + })), chaiscript::exception::conversion_error); + +} +