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);