diff --git a/include/chaiscript/dispatchkit/dynamic_cast_conversion.hpp b/include/chaiscript/dispatchkit/dynamic_cast_conversion.hpp index 2bafa1ec..8856f686 100644 --- a/include/chaiscript/dispatchkit/dynamic_cast_conversion.hpp +++ b/include/chaiscript/dispatchkit/dynamic_cast_conversion.hpp @@ -7,6 +7,7 @@ #include "bad_boxed_cast.hpp" #include #include +#include namespace chaiscript { @@ -118,21 +119,32 @@ namespace chaiscript class Dynamic_Conversions { public: + static Dynamic_Conversions &get() + { + static Dynamic_Conversions obj; + return obj; + } + template - static void add_conversion() + void add_conversion() { - get_conversions().push_back( +#ifndef CHAISCRIPT_NO_THREADS + boost::unique_lock l(m_mutex); +#endif + + m_conversions.push_back( boost::shared_ptr(new Dynamic_Conversion_Impl()) ); } - static bool has_conversion(const Type_Info &base, const Type_Info &derived) + bool has_conversion(const Type_Info &base, const Type_Info &derived) { - const std::vector > &convs - = get_conversions(); +#ifndef CHAISCRIPT_NO_THREADS + boost::shared_lock l(m_mutex); +#endif - for (std::vector >::const_iterator itr = convs.begin(); - itr != convs.end(); + for (std::vector >::const_iterator itr = m_conversions.begin(); + itr != m_conversions.end(); ++itr) { if ((*itr)->base().bare_equal(base) && (*itr)->derived().bare_equal(derived)) @@ -144,13 +156,14 @@ namespace chaiscript return false; } - static boost::shared_ptr get_conversion(const Type_Info &base, const Type_Info &derived) + boost::shared_ptr get_conversion(const Type_Info &base, const Type_Info &derived) { - const std::vector > &convs - = get_conversions(); +#ifndef CHAISCRIPT_NO_THREADS + boost::shared_lock l(m_mutex); +#endif - for (std::vector >::const_iterator itr = convs.begin(); - itr != convs.end(); + for (std::vector >::const_iterator itr = m_conversions.begin(); + itr != m_conversions.end(); ++itr) { if ((*itr)->base().bare_equal(base) && (*itr)->derived().bare_equal(derived)) @@ -162,12 +175,12 @@ namespace chaiscript throw std::out_of_range("No such conversion exists from " + derived.bare_name() + " to " + base.bare_name()); } - private: - static std::vector > &get_conversions() - { - static std::vector > convs; - return convs; - } + private: + Dynamic_Conversions() {} +#ifndef CHAISCRIPT_NO_THREADS + boost::shared_mutex m_mutex; +#endif + std::vector > m_conversions; }; } @@ -180,7 +193,7 @@ namespace chaiscript BOOST_STATIC_ASSERT(boost::is_polymorphic::value); BOOST_STATIC_ASSERT(boost::is_polymorphic::value); - detail::Dynamic_Conversions::add_conversion(); + detail::Dynamic_Conversions::get().add_conversion(); } template @@ -191,14 +204,14 @@ namespace chaiscript bool dynamic_cast_converts(const Type_Info &base, const Type_Info &derived) { - return detail::Dynamic_Conversions::has_conversion(base, derived); + return detail::Dynamic_Conversions::get().has_conversion(base, derived); } template Boxed_Value boxed_dynamic_cast(const Boxed_Value &derived) { try { - return detail::Dynamic_Conversions::get_conversion(user_type(), derived.get_type_info())->convert(derived); + return detail::Dynamic_Conversions::get().get_conversion(user_type(), derived.get_type_info())->convert(derived); } catch (const std::out_of_range &) { throw bad_boxed_dynamic_cast(derived.get_type_info(), typeid(Base), "No known conversion"); } catch (const std::bad_cast &) {