/************************************************************************************ * * * Copyright (c) 2014 - 2018 Axel Menzel * * * * This file is part of RTTR (Run Time Type Reflection) * * License: MIT License * * * * Permission is hereby granted, free of charge, to any person obtaining * * a copy of this software and associated documentation files (the "Software"), * * to deal in the Software without restriction, including without limitation * * the rights to use, copy, modify, merge, publish, distribute, sublicense, * * and/or sell copies of the Software, and to permit persons to whom the * * Software is furnished to do so, subject to the following conditions: * * * * The above copyright notice and this permission notice shall be included in * * all copies or substantial portions of the Software. * * * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * * SOFTWARE. * * * *************************************************************************************/ #ifndef RTTR_WRAPPER_MAPPER_IMPL_H_ #define RTTR_WRAPPER_MAPPER_IMPL_H_ #include "rttr/detail/base/core_prerequisites.h" #include "rttr/detail/misc/std_type_traits.h" #include "rttr/detail/misc/utility.h" #include #include namespace rttr { class type; ////////////////////////////////////////////////////////////////////////////////////// template struct wrapper_mapper> { using wrapped_type = decltype(std::shared_ptr().get()); using type = std::shared_ptr; static RTTR_INLINE wrapped_type get(const type& obj) { return obj.get(); } static RTTR_INLINE type create(const wrapped_type& t) { return type(t); } template static std::shared_ptr convert(const type& source, bool& ok) { if (auto p = rttr_cast::element_type*>(source.get())) { ok = true; return std::shared_ptr(source, p); } else { ok = false; return std::shared_ptr(); } } }; ////////////////////////////////////////////////////////////////////////////////////// template struct wrapper_mapper> { using wrapped_type = decltype(std::declval>().get()); using type = std::reference_wrapper; static RTTR_INLINE wrapped_type get(const type& obj) { return obj.get(); } static RTTR_INLINE type create(const wrapped_type& t) { return type(t); } }; ////////////////////////////////////////////////////////////////////////////////////// template struct wrapper_mapper> { using wrapped_type = decltype(std::declval>().get()); using type = std::unique_ptr; static RTTR_INLINE wrapped_type get(const type& obj) { return obj.get(); } static RTTR_INLINE type create(const wrapped_type& t) { return type(t); } }; ////////////////////////////////////////////////////////////////////////////////////// template struct wrapper_mapper> { using wrapped_type = decltype(std::declval>().lock().get()); using type = std::weak_ptr; static RTTR_INLINE wrapped_type get(const type& obj) { return obj.lock().get(); } // there is no create method because, weak pointer can only be created by a referencing a shared_ptr. // And a tmp shared_ptr which goes out of scope immediately, result always in an empty weak_ptr. }; namespace detail { ////////////////////////////////////////////////////////////////////////////////////// template using wrapper_mapper_t = typename wrapper_mapper::type >::type>::wrapped_type; ////////////////////////////////////////////////////////////////////////////////////// template using is_wrapper = std::integral_constant>::value >; ////////////////////////////////////////////////////////////////////////////////////// template using wrapper_address_return_type_t = conditional_t::value, raw_addressof_return_type_t< wrapper_mapper_t< T > >, raw_addressof_return_type_t>; ////////////////////////////////////////////////////////////////////////////////////// template typename std::enable_if::value, raw_addressof_return_type_t< wrapper_mapper_t> >::type wrapped_raw_addressof(T& obj) { using raw_wrapper_type = remove_cv_t>; wrapper_mapper_t value = wrapper_mapper::get(obj); return raw_addressof(value); } ////////////////////////////////////////////////////////////////////////////////////// template typename std::enable_if::value, raw_addressof_return_type_t>::type wrapped_raw_addressof(T& obj) { return raw_addressof(obj); } ////////////////////////////////////////////////////////////////////////////////////// /*! * Determine if the given type \a T is a wrapper and has the member method * 'wrapper create(const wrapper_type&)' declared. */ template ::type>::type> class has_create_wrapper_func_impl { using YesType = char[1]; using NoType = char[2]; template class check { }; template static YesType& f(check, &wrapper_mapper::create>*); template static NoType& f(...); public: static RTTR_CONSTEXPR_OR_CONST bool value = (sizeof(f(0)) == sizeof(YesType)); }; template using has_create_wrapper_func = std::integral_constant::value>; ////////////////////////////////////////////////////////////////////////////////////// } // end namespace detail } // end namespace rttr #endif // RTTR_WRAPPER_MAPPER_IMPL_H_