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