// 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" 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 std::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 std::cref((ob.get().cast >()).get()); } else { return ob.get().cast >(); } } else { if (!ob.get_type_info().is_const()) { return std::cref(*(ob.get().cast >())); } else { return std::cref(*(ob.get().cast >())); } } } }; 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 &(ob.get().cast >()).get(); } else { return &(ob.get().cast >()).get(); } } else { if (!ob.get_type_info().is_const()) { return (ob.get().cast >()).get(); } else { return (ob.get().cast >()).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 &(ob.get().cast >()).get(); } else { return (ob.get().cast >()).get(); } } }; /** * Cast_Helper_Inner for casting to a & type */ template struct Cast_Helper_Inner { typedef Result& Result_Type; static Result &cast(const Boxed_Value &ob) { if (ob.is_ref()) { return ob.get().cast >(); } else { Result &r = *(ob.get().cast >()); return r; } } }; /** * Cast_Helper_Inner for casting to a std::shared_ptr<> type */ template struct Cast_Helper_Inner > { typedef typename std::shared_ptr Result_Type; static Result_Type cast(const Boxed_Value &ob) { return ob.get().cast >(); } }; /** * Cast_Helper_Inner for casting to a std::shared_ptr type */ template struct Cast_Helper_Inner > { typedef typename std::shared_ptr Result_Type; static Result_Type cast(const Boxed_Value &ob) { if (!ob.get_type_info().is_const()) { return std::const_pointer_cast(ob.get().cast >()); } else { return ob.get().cast >(); } } }; /** * Cast_Helper_Inner for casting to a const std::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 std::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 std::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