1 // Boost.TypeErasure library 2 // 3 // Copyright 2012 Steven Watanabe 4 // 5 // Distributed under the Boost Software License Version 1.0. (See 6 // accompanying file LICENSE_1_0.txt or copy at 7 // http://www.boost.org/LICENSE_1_0.txt) 8 // 9 // $Id$ 10 11 #ifndef BOOST_TYPE_ERASURE_DETAIL_CONST_HPP_INCLUDED 12 #define BOOST_TYPE_ERASURE_DETAIL_CONST_HPP_INCLUDED 13 14 #include <boost/mpl/if.hpp> 15 #include <boost/mpl/bool.hpp> 16 #include <boost/mpl/or.hpp> 17 #include <boost/mpl/and.hpp> 18 #include <boost/mpl/not.hpp> 19 #include <boost/type_traits/is_same.hpp> 20 #include <boost/type_traits/is_const.hpp> 21 #include <boost/type_traits/is_reference.hpp> 22 #include <boost/type_traits/remove_reference.hpp> 23 #include <boost/type_traits/remove_cv.hpp> 24 #include <boost/type_erasure/placeholder_of.hpp> 25 #include <boost/type_erasure/derived.hpp> 26 27 namespace boost { 28 namespace type_erasure { 29 namespace detail { 30 31 template<class T> 32 struct is_non_const_ref : boost::mpl::false_ {}; 33 template<class T> 34 struct is_non_const_ref<T&> : boost::mpl::true_ {}; 35 template<class T> 36 struct is_non_const_ref<const T&> : boost::mpl::false_ {}; 37 38 template<class Placeholder, class Base> 39 struct should_be_const : 40 ::boost::mpl::or_< 41 ::boost::is_const<Placeholder>, 42 ::boost::type_erasure::detail::is_non_const_ref< 43 typename ::boost::type_erasure::placeholder_of<Base>::type 44 > 45 > 46 {}; 47 48 template<class Placeholder, class Base> 49 struct should_be_non_const : 50 ::boost::mpl::and_< 51 ::boost::mpl::not_< ::boost::is_const<Placeholder> >, 52 ::boost::mpl::not_< 53 ::boost::is_reference< 54 typename ::boost::type_erasure::placeholder_of<Base>::type 55 > 56 > 57 > 58 {}; 59 60 template<class Base> 61 struct non_const_this_param 62 { 63 typedef typename ::boost::type_erasure::placeholder_of<Base>::type placeholder; 64 typedef typename ::boost::type_erasure::derived<Base>::type plain_type; 65 typedef typename ::boost::mpl::if_< 66 ::boost::is_same< 67 placeholder, 68 typename ::boost::remove_cv< 69 typename ::boost::remove_reference<placeholder>::type 70 >::type& 71 >, 72 const plain_type, 73 plain_type 74 >::type type; 75 }; 76 77 template<class T> 78 struct uncallable {}; 79 80 template<class Placeholder, class Base> 81 struct maybe_const_this_param 82 { 83 typedef typename ::boost::type_erasure::derived<Base>::type plain_type; 84 typedef typename ::boost::remove_reference<Placeholder>::type plain_placeholder; 85 typedef typename ::boost::mpl::if_< ::boost::is_reference<Placeholder>, 86 typename ::boost::mpl::if_< 87 ::boost::type_erasure::detail::should_be_non_const<plain_placeholder, Base>, 88 plain_type&, 89 typename ::boost::mpl::if_< 90 ::boost::type_erasure::detail::should_be_const<plain_placeholder, Base>, 91 const plain_type&, 92 uncallable<plain_type> 93 >::type 94 >::type, 95 plain_type 96 >::type type; 97 }; 98 99 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES 100 101 template<class Placeholder, class Base> 102 struct maybe_const_this_param<Placeholder&&, Base> 103 { 104 typedef typename ::boost::type_erasure::derived<Base>::type plain_type; 105 typedef typename ::boost::remove_reference<Placeholder>::type plain_placeholder; 106 typedef typename ::boost::type_erasure::placeholder_of<plain_type>::type self_placeholder; 107 typedef typename ::boost::mpl::if_< ::boost::is_lvalue_reference<self_placeholder>, 108 ::boost::type_erasure::detail::uncallable<plain_type>, 109 typename ::boost::mpl::if_< ::boost::is_rvalue_reference<self_placeholder>, 110 const plain_type&, 111 plain_type&& 112 >::type 113 >::type type; 114 }; 115 116 #endif 117 118 } 119 } 120 } 121 122 #endif 123