augment_predicate.hpp 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. // Copyright Cromwell D. Enage 2018.
  2. // Distributed under the Boost Software License, Version 1.0.
  3. // (See accompanying file LICENSE_1_0.txt or copy at
  4. // http://www.boost.org/LICENSE_1_0.txt)
  5. #ifndef BOOST_PARAMETER_AUGMENT_PREDICATE_HPP
  6. #define BOOST_PARAMETER_AUGMENT_PREDICATE_HPP
  7. #include <boost/parameter/keyword_fwd.hpp>
  8. #include <boost/mpl/bool.hpp>
  9. #include <boost/mpl/if.hpp>
  10. #include <boost/mpl/eval_if.hpp>
  11. #include <boost/type_traits/is_lvalue_reference.hpp>
  12. #include <boost/type_traits/is_scalar.hpp>
  13. #include <boost/type_traits/is_same.hpp>
  14. namespace boost { namespace parameter { namespace aux {
  15. template <typename V, typename R, typename Tag>
  16. struct augment_predicate_check_consume_ref
  17. : ::boost::mpl::eval_if<
  18. ::boost::is_scalar<V>
  19. , ::boost::mpl::true_
  20. , ::boost::mpl::eval_if<
  21. ::boost::is_same<
  22. typename Tag::qualifier
  23. , ::boost::parameter::consume_reference
  24. >
  25. , ::boost::mpl::if_<
  26. ::boost::is_lvalue_reference<R>
  27. , ::boost::mpl::false_
  28. , ::boost::mpl::true_
  29. >
  30. , boost::mpl::true_
  31. >
  32. >::type
  33. {
  34. };
  35. }}} // namespace boost::parameter::aux
  36. #include <boost/type_traits/is_const.hpp>
  37. namespace boost { namespace parameter { namespace aux {
  38. template <typename V, typename R, typename Tag>
  39. struct augment_predicate_check_out_ref
  40. : ::boost::mpl::eval_if<
  41. ::boost::is_same<
  42. typename Tag::qualifier
  43. , ::boost::parameter::out_reference
  44. >
  45. , ::boost::mpl::eval_if<
  46. ::boost::is_lvalue_reference<R>
  47. , ::boost::mpl::if_<
  48. ::boost::is_const<V>
  49. , ::boost::mpl::false_
  50. , ::boost::mpl::true_
  51. >
  52. , ::boost::mpl::false_
  53. >
  54. , ::boost::mpl::true_
  55. >::type
  56. {
  57. };
  58. }}} // namespace boost::parameter::aux
  59. #include <boost/parameter/aux_/lambda_tag.hpp>
  60. #include <boost/mpl/apply_wrap.hpp>
  61. #include <boost/mpl/lambda.hpp>
  62. namespace boost { namespace parameter { namespace aux {
  63. template <
  64. typename Predicate
  65. , typename R
  66. , typename Tag
  67. , typename T
  68. , typename Args
  69. >
  70. class augment_predicate
  71. {
  72. typedef typename ::boost::mpl::lambda<
  73. Predicate
  74. , ::boost::parameter::aux::lambda_tag
  75. >::type _actual_predicate;
  76. public:
  77. typedef typename ::boost::mpl::eval_if<
  78. typename ::boost::mpl::if_<
  79. ::boost::parameter::aux
  80. ::augment_predicate_check_consume_ref<T,R,Tag>
  81. , ::boost::parameter::aux
  82. ::augment_predicate_check_out_ref<T,R,Tag>
  83. , ::boost::mpl::false_
  84. >::type
  85. , ::boost::mpl::apply_wrap2<_actual_predicate,T,Args>
  86. , ::boost::mpl::false_
  87. >::type type;
  88. };
  89. }}} // namespace boost::parameter::aux
  90. #include <boost/parameter/config.hpp>
  91. #if defined(BOOST_PARAMETER_CAN_USE_MP11)
  92. #include <boost/mp11/integral.hpp>
  93. #include <boost/mp11/utility.hpp>
  94. #include <type_traits>
  95. namespace boost { namespace parameter { namespace aux {
  96. template <typename V, typename R, typename Tag>
  97. using augment_predicate_check_consume_ref_mp11 = ::boost::mp11::mp_if<
  98. ::std::is_scalar<V>
  99. , ::boost::mp11::mp_true
  100. , ::boost::mp11::mp_if<
  101. ::std::is_same<
  102. typename Tag::qualifier
  103. , ::boost::parameter::consume_reference
  104. >
  105. , ::boost::mp11::mp_if<
  106. ::std::is_lvalue_reference<R>
  107. , ::boost::mp11::mp_false
  108. , ::boost::mp11::mp_true
  109. >
  110. , boost::mp11::mp_true
  111. >
  112. >;
  113. template <typename V, typename R, typename Tag>
  114. using augment_predicate_check_out_ref_mp11 = ::boost::mp11::mp_if<
  115. ::std::is_same<
  116. typename Tag::qualifier
  117. , ::boost::parameter::out_reference
  118. >
  119. , ::boost::mp11::mp_if<
  120. ::std::is_lvalue_reference<R>
  121. , ::boost::mp11::mp_if<
  122. ::std::is_const<V>
  123. , ::boost::mp11::mp_false
  124. , ::boost::mp11::mp_true
  125. >
  126. , ::boost::mp11::mp_false
  127. >
  128. , ::boost::mp11::mp_true
  129. >;
  130. }}} // namespace boost::parameter::aux
  131. #include <boost/mp11/list.hpp>
  132. namespace boost { namespace parameter { namespace aux {
  133. template <
  134. typename Predicate
  135. , typename R
  136. , typename Tag
  137. , typename T
  138. , typename Args
  139. >
  140. struct augment_predicate_mp11_impl
  141. {
  142. using type = ::boost::mp11::mp_if<
  143. ::boost::mp11::mp_if<
  144. ::boost::parameter::aux
  145. ::augment_predicate_check_consume_ref_mp11<T,R,Tag>
  146. , ::boost::parameter::aux
  147. ::augment_predicate_check_out_ref_mp11<T,R,Tag>
  148. , ::boost::mp11::mp_false
  149. >
  150. , ::boost::mp11
  151. ::mp_apply_q<Predicate,::boost::mp11::mp_list<T,Args> >
  152. , ::boost::mp11::mp_false
  153. >;
  154. };
  155. }}} // namespace boost::parameter::aux
  156. #include <boost/parameter/aux_/has_nested_template_fn.hpp>
  157. namespace boost { namespace parameter { namespace aux {
  158. template <
  159. typename Predicate
  160. , typename R
  161. , typename Tag
  162. , typename T
  163. , typename Args
  164. >
  165. using augment_predicate_mp11 = ::boost::mp11::mp_if<
  166. ::boost::parameter::aux::has_nested_template_fn<Predicate>
  167. , ::boost::parameter::aux
  168. ::augment_predicate_mp11_impl<Predicate,R,Tag,T,Args>
  169. , ::boost::parameter::aux
  170. ::augment_predicate<Predicate,R,Tag,T,Args>
  171. >;
  172. }}} // namespace boost::parameter::aux
  173. #endif // BOOST_PARAMETER_CAN_USE_MP11
  174. #endif // include guard