1 /* 2 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 */ 8 9 #ifndef BOOST_CLBL_TRTS_APPLY_MEMBER_POINTER_HPP 10 #define BOOST_CLBL_TRTS_APPLY_MEMBER_POINTER_HPP 11 12 #include <boost/callable_traits/detail/core.hpp> 13 14 namespace boost { namespace callable_traits { 15 16 BOOST_CLBL_TRTS_DEFINE_SFINAE_ERROR_ORIGIN(apply_member_pointer) 17 BOOST_CLBL_TRTS_SFINAE_MSG(apply_member_pointer, members_cannot_have_a_type_of_void) 18 BOOST_CLBL_TRTS_SFINAE_MSG(apply_member_pointer, second_template_argument_must_be_a_class_or_struct) 19 20 namespace detail { 21 22 template<typename T, typename C, bool = std::is_class<C>::value> 23 struct make_member_pointer; 24 25 template<typename T, typename C> 26 struct make_member_pointer<T, C, true> { 27 using type = typename std::remove_reference<T>::type C::*; 28 }; 29 30 template<typename C> 31 struct make_member_pointer<void, C, true> { 32 using type = invalid_type; 33 }; 34 35 template<typename T, typename C> 36 struct make_member_pointer<T, C, false> { 37 using type = error_type<T>; 38 }; 39 40 template<typename T, typename C> 41 using make_member_pointer_t = typename make_member_pointer<T, C>::type; 42 } 43 44 //[ apply_member_pointer_hpp 45 /*` 46 [section:ref_apply_member_pointer apply_member_pointer] 47 [heading Header] 48 ``#include <boost/callable_traits/apply_member_pointer.hpp>`` 49 [heading Definition] 50 */ 51 52 template<typename T, typename C> 53 using apply_member_pointer_t = //see below 54 //<- 55 detail::sfinae_try< 56 detail::fallback_if_invalid< 57 typename detail::traits<T>::template apply_member_pointer<C>, 58 typename detail::make_member_pointer<T, C>::type>, 59 60 detail::fail_when_same<void, T, members_cannot_have_a_type_of_void>, 61 62 detail::fail_if<!std::is_class<C>::value, 63 second_template_argument_must_be_a_class_or_struct> >; 64 65 namespace detail { 66 67 template<typename T, typename C, typename = std::false_type> 68 struct apply_member_pointer_impl {}; 69 70 template<typename T, typename C> 71 struct apply_member_pointer_impl <T, C, typename std::is_same< 72 apply_member_pointer_t<T, C>, detail::dummy>::type> 73 { 74 using type = apply_member_pointer_t<T, C>; 75 }; 76 } 77 78 //-> 79 80 template<typename T, typename C> 81 struct apply_member_pointer : detail::apply_member_pointer_impl<T, C> {}; 82 83 //<- 84 }} // namespace boost::callable_traits 85 //-> 86 87 /*` 88 [heading Constraints] 89 * `T` may be any type except `void` 90 * `C` must be a user-defined type 91 92 [heading Behavior] 93 * A substitution failure occurs if the constraints are violated. 94 * When `T` is a function, function pointer (unqualified), or function reference, then the aliased type is a member function pointer of `C` with the same parameters and return type. 95 * When `T` is a member function pointer (unqualified) of any type, the aliased type is a member function pointer of `C` with the same parameters and return type. 96 * Otherwise, the aliased type is a member data pointer equivalent to `std::remove_reference_t<T> C::*`. 97 98 [heading Input/Output Examples] 99 [table 100 [[`T`] [`apply_member_pointer_t<T, foo>`]] 101 [[`int()`] [`int(foo::*)()`]] 102 [[`int (&)()`] [`int(foo::*)()`]] 103 [[`int (*)()`] [`int(foo::*)()`]] 104 [[`int(bar::*)()`] [`int(foo::*)()`]] 105 [[`int(bar::*)() &`] [`int(foo::*)() &`]] 106 [[`int(bar::*)() &&`] [`int(foo::*)() &&`]] 107 [[`int(bar::*)() const`] [`int(foo::*)() const`]] 108 [[`int(bar::*)() transaction_safe`] [`int(foo::*)() transaction_safe`]] 109 [[`int bar::*`] [`int foo::*`]] 110 [[`int`] [`int foo::*`]] 111 [[`int &`] [`int foo::*`]] 112 [[`const int &`] [`const int foo::*`]] 113 [[`int (*const)()`] [`int (*const foo::*)()`]] 114 [[`void`] [(substitution failure)]] 115 ] 116 117 [heading Example Program] 118 [import ../example/apply_member_pointer.cpp] 119 [apply_member_pointer] 120 [endsect] 121 */ 122 //] 123 #endif 124