// This file is distributed under the BSD License. // See "license.txt" for details. // Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) // and Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com #ifndef CHAISCRIPT_BOXED_CAST_HELPER_HPP_ #define CHAISCRIPT_BOXED_CAST_HELPER_HPP_ #include "type_info.hpp" #include "boxed_value.hpp" #include #include #include #include namespace chaiscript { namespace detail { // Cast_Helper_Inner helper classes /** * Generic Cast_Helper_Inner, for casting to any type */ template struct Cast_Helper_Inner { typedef typename boost::reference_wrapper::type > Result_Type; static Result_Type cast(const Boxed_Value &ob) { if (ob.is_ref()) { if (!ob.get_type_info().is_const()) { return boost::cref((boost::any_cast >(ob.get())).get()); } else { return boost::any_cast >(ob.get()); } } else { if (!ob.get_type_info().is_const()) { return boost::cref(*(boost::any_cast >(ob.get()))); } else { return boost::cref(*(boost::any_cast >(ob.get()))); } } } }; template struct Cast_Helper_Inner : Cast_Helper_Inner { }; /** * Cast_Helper_Inner for casting to a const & type */ template struct Cast_Helper_Inner : Cast_Helper_Inner { }; /** * Cast_Helper_Inner for casting to a const * type */ template struct Cast_Helper_Inner { typedef const Result * Result_Type; static Result_Type cast(const Boxed_Value &ob) { if (ob.is_ref()) { if (!ob.get_type_info().is_const()) { return (boost::any_cast >(ob.get())).get_pointer(); } else { return (boost::any_cast >(ob.get())).get_pointer(); } } else { if (!ob.get_type_info().is_const()) { return (boost::any_cast >(ob.get())).get(); } else { return (boost::any_cast >(ob.get())).get(); } } } }; /** * Cast_Helper_Inner for casting to a * type */ template struct Cast_Helper_Inner { typedef Result * Result_Type; static Result_Type cast(const Boxed_Value &ob) { if (ob.is_ref()) { return (boost::any_cast >(ob.get())).get_pointer(); } else { return (boost::any_cast >(ob.get())).get(); } } }; /** * Cast_Helper_Inner for casting to a & type */ template struct Cast_Helper_Inner { typedef typename boost::reference_wrapper Result_Type; static Result_Type cast(const Boxed_Value &ob) { if (ob.is_ref()) { return boost::any_cast >(ob.get()); } else { return boost::ref(*(boost::any_cast >(ob.get()))); } } }; /** * Cast_Helper_Inner for casting to a boost::shared_ptr<> type */ template struct Cast_Helper_Inner > { typedef typename boost::shared_ptr Result_Type; static Result_Type cast(const Boxed_Value &ob) { return boost::any_cast >(ob.get()); } }; /** * Cast_Helper_Inner for casting to a boost::shared_ptr type */ template struct Cast_Helper_Inner > { typedef typename boost::shared_ptr Result_Type; static Result_Type cast(const Boxed_Value &ob) { if (!ob.get_type_info().is_const()) { return boost::const_pointer_cast(boost::any_cast >(ob.get())); } else { return boost::any_cast >(ob.get()); } } }; /** * Cast_Helper_Inner for casting to a const boost::shared_ptr<> & type */ template struct Cast_Helper_Inner > : Cast_Helper_Inner > { }; template struct Cast_Helper_Inner &> : Cast_Helper_Inner > { }; /** * Cast_Helper_Inner for casting to a const boost::shared_ptr & type */ template struct Cast_Helper_Inner > : Cast_Helper_Inner > { }; template struct Cast_Helper_Inner &> : Cast_Helper_Inner > { }; /** * Cast_Helper_Inner for casting to a Boxed_Value type */ template<> struct Cast_Helper_Inner { typedef const Boxed_Value & Result_Type; static Result_Type cast(const Boxed_Value &ob) { return ob; } }; /** * Cast_Helper_Inner for casting to a const Boxed_Value & type */ template<> struct Cast_Helper_Inner : Cast_Helper_Inner { }; template<> struct Cast_Helper_Inner : Cast_Helper_Inner { }; /** * Cast_Helper_Inner for casting to a boost::reference_wrapper type */ template struct Cast_Helper_Inner > : Cast_Helper_Inner { }; template struct Cast_Helper_Inner > : Cast_Helper_Inner { }; template struct Cast_Helper_Inner &> : Cast_Helper_Inner { }; template struct Cast_Helper_Inner > : Cast_Helper_Inner { }; template struct Cast_Helper_Inner > : Cast_Helper_Inner { }; template struct Cast_Helper_Inner & > : Cast_Helper_Inner { }; /** * The exposed Cast_Helper object that by default just calls the Cast_Helper_Inner */ template struct Cast_Helper { typedef typename Cast_Helper_Inner::Result_Type Result_Type; static Result_Type cast(const Boxed_Value &ob) { return Cast_Helper_Inner::cast(ob); } }; } } #endif