apply_member_pointer.hpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. /*
  2. @Copyright Barrett Adair 2015-2017
  3. Distributed under the Boost Software License, Version 1.0.
  4. (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
  5. */
  6. #ifndef BOOST_CLBL_TRTS_APPLY_MEMBER_POINTER_HPP
  7. #define BOOST_CLBL_TRTS_APPLY_MEMBER_POINTER_HPP
  8. #include <boost/callable_traits/detail/core.hpp>
  9. namespace boost { namespace callable_traits {
  10. BOOST_CLBL_TRTS_DEFINE_SFINAE_ERROR_ORIGIN(apply_member_pointer)
  11. BOOST_CLBL_TRTS_SFINAE_MSG(apply_member_pointer, members_cannot_have_a_type_of_void)
  12. BOOST_CLBL_TRTS_SFINAE_MSG(apply_member_pointer, second_template_argument_must_be_a_class_or_struct)
  13. namespace detail {
  14. template<typename T, typename C, bool = std::is_class<C>::value>
  15. struct make_member_pointer;
  16. template<typename T, typename C>
  17. struct make_member_pointer<T, C, true> {
  18. using type = typename std::remove_reference<T>::type C::*;
  19. };
  20. template<typename C>
  21. struct make_member_pointer<void, C, true> {
  22. using type = invalid_type;
  23. };
  24. template<typename T, typename C>
  25. struct make_member_pointer<T, C, false> {
  26. using type = error_type<T>;
  27. };
  28. template<typename T, typename C>
  29. using make_member_pointer_t = typename make_member_pointer<T, C>::type;
  30. }
  31. //[ apply_member_pointer_hpp
  32. /*`
  33. [section:ref_apply_member_pointer apply_member_pointer]
  34. [heading Header]
  35. ``#include <boost/callable_traits/apply_member_pointer.hpp>``
  36. [heading Definition]
  37. */
  38. template<typename T, typename C>
  39. using apply_member_pointer_t = //see below
  40. //<-
  41. detail::sfinae_try<
  42. detail::fallback_if_invalid<
  43. typename detail::traits<T>::template apply_member_pointer<C>,
  44. typename detail::make_member_pointer<T, C>::type>,
  45. detail::fail_when_same<void, T, members_cannot_have_a_type_of_void>,
  46. detail::fail_if<!std::is_class<C>::value,
  47. second_template_argument_must_be_a_class_or_struct> >;
  48. namespace detail {
  49. template<typename T, typename C, typename = std::false_type>
  50. struct apply_member_pointer_impl {};
  51. template<typename T, typename C>
  52. struct apply_member_pointer_impl <T, C, typename std::is_same<
  53. apply_member_pointer_t<T, C>, detail::dummy>::type>
  54. {
  55. using type = apply_member_pointer_t<T, C>;
  56. };
  57. }
  58. //->
  59. template<typename T, typename C>
  60. struct apply_member_pointer : detail::apply_member_pointer_impl<T, C> {};
  61. //<-
  62. }} // namespace boost::callable_traits
  63. //->
  64. /*`
  65. [heading Constraints]
  66. * `T` may be any type except `void`
  67. * `C` must be a user-defined type
  68. [heading Behavior]
  69. * A substitution failure occurs if the constraints are violated.
  70. * 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.
  71. * 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.
  72. * Otherwise, the aliased type is a member data pointer equivalent to `std::remove_reference_t<T> C::*`.
  73. [heading Input/Output Examples]
  74. [table
  75. [[`T`] [`apply_member_pointer_t<T, foo>`]]
  76. [[`int()`] [`int(foo::*)()`]]
  77. [[`int (&)()`] [`int(foo::*)()`]]
  78. [[`int (*)()`] [`int(foo::*)()`]]
  79. [[`int(bar::*)()`] [`int(foo::*)()`]]
  80. [[`int(bar::*)() &`] [`int(foo::*)() &`]]
  81. [[`int(bar::*)() &&`] [`int(foo::*)() &&`]]
  82. [[`int(bar::*)() const`] [`int(foo::*)() const`]]
  83. [[`int(bar::*)() transaction_safe`] [`int(foo::*)() transaction_safe`]]
  84. [[`int bar::*`] [`int foo::*`]]
  85. [[`int`] [`int foo::*`]]
  86. [[`int &`] [`int foo::*`]]
  87. [[`const int &`] [`const int foo::*`]]
  88. [[`int (*const)()`] [`int (*const foo::*)()`]]
  89. [[`void`] [(substitution failure)]]
  90. ]
  91. [heading Example Program]
  92. [import ../example/apply_member_pointer.cpp]
  93. [apply_member_pointer]
  94. [endsect]
  95. */
  96. //]
  97. #endif