const.hpp 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  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. #ifndef BOOST_TYPE_ERASURE_DETAIL_CONST_HPP_INCLUDED
  11. #define BOOST_TYPE_ERASURE_DETAIL_CONST_HPP_INCLUDED
  12. #include <boost/mpl/if.hpp>
  13. #include <boost/mpl/bool.hpp>
  14. #include <boost/mpl/or.hpp>
  15. #include <boost/mpl/and.hpp>
  16. #include <boost/mpl/not.hpp>
  17. #include <boost/type_traits/is_same.hpp>
  18. #include <boost/type_traits/is_const.hpp>
  19. #include <boost/type_traits/is_reference.hpp>
  20. #include <boost/type_traits/remove_reference.hpp>
  21. #include <boost/type_traits/remove_cv.hpp>
  22. #include <boost/type_erasure/placeholder_of.hpp>
  23. #include <boost/type_erasure/derived.hpp>
  24. namespace boost {
  25. namespace type_erasure {
  26. namespace detail {
  27. template<class T>
  28. struct is_non_const_ref : boost::mpl::false_ {};
  29. template<class T>
  30. struct is_non_const_ref<T&> : boost::mpl::true_ {};
  31. template<class T>
  32. struct is_non_const_ref<const T&> : boost::mpl::false_ {};
  33. template<class Placeholder, class Base>
  34. struct should_be_const :
  35. ::boost::mpl::or_<
  36. ::boost::is_const<Placeholder>,
  37. ::boost::type_erasure::detail::is_non_const_ref<
  38. typename ::boost::type_erasure::placeholder_of<Base>::type
  39. >
  40. >
  41. {};
  42. template<class Placeholder, class Base>
  43. struct should_be_non_const :
  44. ::boost::mpl::and_<
  45. ::boost::mpl::not_< ::boost::is_const<Placeholder> >,
  46. ::boost::mpl::not_<
  47. ::boost::is_reference<
  48. typename ::boost::type_erasure::placeholder_of<Base>::type
  49. >
  50. >
  51. >
  52. {};
  53. template<class Base>
  54. struct non_const_this_param
  55. {
  56. typedef typename ::boost::type_erasure::placeholder_of<Base>::type placeholder;
  57. typedef typename ::boost::type_erasure::derived<Base>::type plain_type;
  58. typedef typename ::boost::mpl::if_<
  59. ::boost::is_same<
  60. placeholder,
  61. typename ::boost::remove_cv<
  62. typename ::boost::remove_reference<placeholder>::type
  63. >::type&
  64. >,
  65. const plain_type,
  66. plain_type
  67. >::type type;
  68. };
  69. template<class T>
  70. struct uncallable {};
  71. template<class Placeholder, class Base>
  72. struct maybe_const_this_param
  73. {
  74. typedef typename ::boost::type_erasure::derived<Base>::type plain_type;
  75. typedef typename ::boost::remove_reference<Placeholder>::type plain_placeholder;
  76. typedef typename ::boost::mpl::if_< ::boost::is_reference<Placeholder>,
  77. typename ::boost::mpl::if_<
  78. ::boost::type_erasure::detail::should_be_non_const<plain_placeholder, Base>,
  79. plain_type&,
  80. typename ::boost::mpl::if_<
  81. ::boost::type_erasure::detail::should_be_const<plain_placeholder, Base>,
  82. const plain_type&,
  83. uncallable<plain_type>
  84. >::type
  85. >::type,
  86. plain_type
  87. >::type type;
  88. };
  89. #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
  90. template<class Placeholder, class Base>
  91. struct maybe_const_this_param<Placeholder&&, Base>
  92. {
  93. typedef typename ::boost::type_erasure::derived<Base>::type plain_type;
  94. typedef typename ::boost::remove_reference<Placeholder>::type plain_placeholder;
  95. typedef typename ::boost::type_erasure::placeholder_of<plain_type>::type self_placeholder;
  96. typedef typename ::boost::mpl::if_< ::boost::is_lvalue_reference<self_placeholder>,
  97. ::boost::type_erasure::detail::uncallable<plain_type>,
  98. typename ::boost::mpl::if_< ::boost::is_rvalue_reference<self_placeholder>,
  99. const plain_type&,
  100. plain_type&&
  101. >::type
  102. >::type type;
  103. };
  104. #endif
  105. }
  106. }
  107. }
  108. #endif