• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 
3 @Copyright Barrett Adair 2015-2018
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 */
8 
9 #ifndef BOOST_CLBL_TRTS_ADD_MEMBER_LVALUE_REFERENCE_HPP
10 #define BOOST_CLBL_TRTS_ADD_MEMBER_LVALUE_REFERENCE_HPP
11 
12 #include <boost/callable_traits/detail/core.hpp>
13 
14 namespace boost { namespace callable_traits {
15 
16 //[ add_member_lvalue_reference_hpp
17 /*`
18 [section:ref_add_member_lvalue_reference add_member_lvalue_reference]
19 [heading Header]
20 ``#include <boost/callable_traits/add_member_lvalue_reference.hpp>``
21 [heading Definition]
22 */
23 //<-
24 #ifdef BOOST_CLBL_TRTS_DISABLE_REFERENCE_QUALIFIERS
25 
26 template<typename T>
27 struct add_member_lvalue_reference_t {
28     static_assert(std::is_same<T, detail::dummy>::value,
29         "Reference member qualifiers are not supported by this configuration.");
30 };
31 
32 #else
33 //->
34 template<typename T>
35 using add_member_lvalue_reference_t = //see below
36 //<-
37 #ifdef BOOST_CLBL_TRTS_DISABLE_ABOMINABLE_FUNCTIONS
38 
39     detail::sfinae_try<
40         typename detail::traits<T>::add_member_lvalue_reference,
41 
42         detail::fail_when_same<typename detail::traits<T>::add_member_lvalue_reference,
43             detail::abominable_functions_not_supported_on_this_compiler,
44             this_compiler_doesnt_support_abominable_function_types>,
45 
46         detail::fail_if_invalid<
47             typename detail::traits<T>::add_member_lvalue_reference,
48             member_qualifiers_are_illegal_for_this_type>>;
49 #else
50 
51     detail::try_but_fail_if_invalid<
52         typename detail::traits<T>::add_member_lvalue_reference,
53         member_qualifiers_are_illegal_for_this_type>;
54 
55 #endif // #ifdef BOOST_CLBL_TRTS_DISABLE_ABOMINABLE_FUNCTIONS
56 #endif // #ifdef BOOST_CLBL_TRTS_DISABLE_REFERENCE_QUALIFIERS
57 
58 namespace detail {
59 
60     template<typename T, typename = std::false_type>
61     struct add_member_lvalue_reference_impl {};
62 
63     template<typename T>
64     struct add_member_lvalue_reference_impl <T, typename std::is_same<
65         add_member_lvalue_reference_t<T>, detail::dummy>::type>
66     {
67         using type = add_member_lvalue_reference_t<T>;
68     };
69 }
70 //->
71 
72 template<typename T>
73 struct add_member_lvalue_reference
74   : detail::add_member_lvalue_reference_impl<T> {};
75 
76 //<-
77 }} // namespace boost::callable_traits
78 //->
79 
80 /*`
81 [heading Constraints]
82 * `T` must be a function type or a member function pointer type
83 * If `T` is a pointer, it may not be cv/ref qualified
84 
85 [heading Behavior]
86 * A substitution failure occurs if the constraints are violated.
87 * Adds a member lvalue reference qualifier (`&`) to `T`, if not already present.
88 * If an rvalue reference qualifier is present, the lvalue reference qualifier replaces it (in accordance with reference collapsing rules).
89 
90 [heading Input/Output Examples]
91 [table
92     [[`T`]                              [`add_member_lvalue_reference_t<T>`]]
93     [[`int()`]                          [`int() &`]]
94     [[`int(foo::*)()`]                  [`int(foo::*)() &`]]
95     [[`int(foo::*)() &`]                [`int(foo::*)() &`]]
96     [[`int(foo::*)() &&`]               [`int(foo::*)() &`]]
97     [[`int(foo::*)() const`]            [`int(foo::*)() const &`]]
98     [[`int(foo::*)() transaction_safe`] [`int(foo::*)() & transaction_safe`]]
99     [[`int`]                            [(substitution failure)]]
100     [[`int (&)()`]                      [(substitution failure)]]
101     [[`int (*)()`]                      [(substitution failure)]]
102     [[`int foo::*`]                     [(substitution failure)]]
103     [[`int (foo::* const)()`]           [(substitution failure)]]
104 ]
105 
106 [heading Example Program]
107 [import ../example/add_member_lvalue_reference.cpp]
108 [add_member_lvalue_reference]
109 [endsect]
110 */
111 //]
112 
113 #endif
114 
115