qualifier_flags.hpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. /*
  2. Defines `qualifier_flags`
  3. @Copyright Barrett Adair 2015-2017
  4. Distributed under the Boost Software License, Version 1.0.
  5. (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
  6. */
  7. #ifndef BOOST_CLBL_TRTS_QUALIFIER_FLAGS_HPP
  8. #define BOOST_CLBL_TRTS_QUALIFIER_FLAGS_HPP
  9. #include <boost/callable_traits/detail/config.hpp>
  10. namespace boost { namespace callable_traits { namespace detail {
  11. //bit qualifier_flags used to signify cv/ref qualifiers
  12. using qualifier_flags = std::uint32_t;
  13. /*
  14. | && & V C |
  15. --------------------------------------------
  16. 0 | 0 0 0 0 | default
  17. 1 | 0 0 0 1 | const
  18. 2 | 0 0 1 0 | volatile
  19. 3 | 0 0 1 1 | const volatile
  20. --------------------------------------------
  21. 4 | 0 1 0 0 | &
  22. 5 | 0 1 0 1 | const &
  23. 6 | 0 1 1 0 | volatile &
  24. 7 | 0 1 1 1 | const volatile &
  25. --------------------------------------------
  26. 8 | 1 0 0 0 | &&
  27. 9 | 1 0 0 1 | const &&
  28. 10 | 1 0 1 0 | volatile &&
  29. 11 | 1 0 1 1 | const volatile &&
  30. */
  31. // Flag representing the default qualifiers on a type
  32. // or member function overload.
  33. constexpr qualifier_flags default_ = 0;
  34. // Flag representing a const qualifier on a type or
  35. // member function overload.
  36. constexpr qualifier_flags const_ = 1;
  37. // Flag representing a volatile qualifier on a type
  38. // or member function overload.
  39. constexpr qualifier_flags volatile_ = 2;
  40. #ifdef BOOST_CLBL_TRTS_DISABLE_REFERENCE_QUALIFIERS
  41. constexpr qualifier_flags lref_ = default_;
  42. constexpr qualifier_flags rref_ = default_;
  43. #else
  44. // Flag representing an lvalue reference type, or
  45. // an lvalue-reference-qualified member function
  46. // overload.
  47. constexpr qualifier_flags lref_ = 4;
  48. // Flag representing an lvalue reference type, or
  49. // an rvalue-reference-qualified member function
  50. // overload.
  51. constexpr qualifier_flags rref_ = 8;
  52. #endif //#ifdef BOOST_CLBL_TRTS_DISABLE_REFERENCE_QUALIFIERS
  53. constexpr qualifier_flags cv_ = 3;
  54. template<qualifier_flags Flags>
  55. using remove_const_flag = std::integral_constant<
  56. qualifier_flags, Flags & ~const_>;
  57. template<qualifier_flags Flags>
  58. using is_const = std::integral_constant<bool,
  59. (Flags & const_) != 0>;
  60. template<qualifier_flags Flags>
  61. using remove_volatile_flag = std::integral_constant<
  62. qualifier_flags, Flags & ~volatile_>;
  63. template<typename U, typename T = typename std::remove_reference<U>::type>
  64. using cv_of = std::integral_constant<qualifier_flags,
  65. (std::is_const<T>::value ? const_ : default_)
  66. | (std::is_volatile<T>::value ? volatile_ : default_)>;
  67. template<typename T>
  68. using ref_of = std::integral_constant<qualifier_flags,
  69. std::is_rvalue_reference<T>::value ? rref_
  70. : (std::is_lvalue_reference<T>::value ? lref_
  71. : default_)>;
  72. //bit-flag implementation of C++11 reference collapsing rules
  73. template<qualifier_flags Existing,
  74. qualifier_flags Other,
  75. bool AlreadyHasRef = (Existing & (lref_ | rref_)) != 0,
  76. bool AlreadyHasLRef = (Existing & lref_) == lref_,
  77. bool IsAddingLRef = (Other & lref_) == lref_
  78. >
  79. using collapse_flags = std::integral_constant<qualifier_flags,
  80. !AlreadyHasRef ? (Existing | Other)
  81. : (AlreadyHasLRef ? (Existing | (Other & ~rref_))
  82. : (IsAddingLRef ? ((Existing & ~rref_) | Other )
  83. : (Existing | Other)))>;
  84. template<typename T> struct flag_map { static constexpr qualifier_flags value = default_; };
  85. template<typename T> struct flag_map<T &> { static constexpr qualifier_flags value = lref_; };
  86. template<typename T> struct flag_map<T &&> { static constexpr qualifier_flags value = rref_; };
  87. template<typename T> struct flag_map<T const> { static constexpr qualifier_flags value = const_; };
  88. template<typename T> struct flag_map<T const &> { static constexpr qualifier_flags value = const_ | lref_; };
  89. template<typename T> struct flag_map<T const &&> { static constexpr qualifier_flags value = const_ | rref_; };
  90. template<typename T> struct flag_map<T volatile> { static constexpr qualifier_flags value = volatile_; };
  91. template<typename T> struct flag_map<T volatile &> { static constexpr qualifier_flags value = volatile_ | lref_; };
  92. template<typename T> struct flag_map<T volatile &&> { static constexpr qualifier_flags value = volatile_ | rref_; };
  93. template<typename T> struct flag_map<T const volatile> { static constexpr qualifier_flags value = const_ | volatile_; };
  94. template<typename T> struct flag_map<T const volatile &> { static constexpr qualifier_flags value = const_ | volatile_ | lref_; };
  95. template<typename T> struct flag_map<T const volatile &&> { static constexpr qualifier_flags value = const_ | volatile_ | rref_; };
  96. }}} // namespace boost::callable_traits::detail
  97. #endif // #ifndef BOOST_CLBL_TRTS_QUALIFIER_FLAGS_HPP