is_transparent.hpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. /* Copyright 2003-2014 Joaquin M Lopez Munoz.
  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. *
  6. * See http://www.boost.org/libs/multi_index for library home page.
  7. */
  8. #ifndef BOOST_MULTI_INDEX_DETAIL_IS_TRANSPARENT_HPP
  9. #define BOOST_MULTI_INDEX_DETAIL_IS_TRANSPARENT_HPP
  10. #if defined(_MSC_VER)
  11. #pragma once
  12. #endif
  13. #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
  14. #include <boost/mpl/bool.hpp>
  15. #include <boost/type_traits/intrinsics.hpp>
  16. namespace boost{
  17. namespace multi_index{
  18. namespace detail{
  19. /* Metafunction that checks if f(arg,arg2) executes without argument type
  20. * conversion. By default (i.e. when it cannot be determined) it evaluates to
  21. * true.
  22. */
  23. template<typename F,typename Arg1,typename Arg2,typename=void>
  24. struct is_transparent:mpl::true_{};
  25. } /* namespace multi_index::detail */
  26. } /* namespace multi_index */
  27. } /* namespace boost */
  28. #if !defined(BOOST_NO_SFINAE)&&!defined(BOOST_NO_SFINAE_EXPR)&& \
  29. !defined(BOOST_NO_CXX11_DECLTYPE)&& \
  30. (defined(BOOST_NO_CXX11_FINAL)||defined(BOOST_IS_FINAL))
  31. #include <boost/mpl/and.hpp>
  32. #include <boost/mpl/not.hpp>
  33. #include <boost/mpl/or.hpp>
  34. #include <boost/type_traits/function_traits.hpp>
  35. #include <boost/type_traits/is_class.hpp>
  36. #include <boost/type_traits/is_final.hpp>
  37. #include <boost/type_traits/is_function.hpp>
  38. #include <boost/type_traits/is_same.hpp>
  39. #include <boost/type_traits/remove_pointer.hpp>
  40. #include <boost/utility/declval.hpp>
  41. #include <boost/utility/enable_if.hpp>
  42. namespace boost{
  43. namespace multi_index{
  44. namespace detail{
  45. struct not_is_transparent_result_type{};
  46. template<typename F,typename Arg1,typename Arg2>
  47. struct is_transparent_class_helper:F
  48. {
  49. using F::operator();
  50. template<typename T,typename Q>
  51. not_is_transparent_result_type operator()(const T&,const Q&)const;
  52. };
  53. template<typename F,typename Arg1,typename Arg2,typename=void>
  54. struct is_transparent_class:mpl::true_{};
  55. template<typename F,typename Arg1,typename Arg2>
  56. struct is_transparent_class<
  57. F,Arg1,Arg2,
  58. typename enable_if<
  59. is_same<
  60. decltype(
  61. declval<const is_transparent_class_helper<F,Arg1,Arg2> >()(
  62. declval<const Arg1&>(),declval<const Arg2&>())
  63. ),
  64. not_is_transparent_result_type
  65. >
  66. >::type
  67. >:mpl::false_{};
  68. template<typename F,typename Arg1,typename Arg2>
  69. struct is_transparent<
  70. F,Arg1,Arg2,
  71. typename enable_if<
  72. mpl::and_<
  73. is_class<F>,
  74. mpl::not_<is_final<F> > /* is_transparent_class_helper derives from F */
  75. >
  76. >::type
  77. >:is_transparent_class<F,Arg1,Arg2>{};
  78. template<typename F,typename Arg1,typename Arg2,typename=void>
  79. struct is_transparent_function:mpl::true_{};
  80. template<typename F,typename Arg1,typename Arg2>
  81. struct is_transparent_function<
  82. F,Arg1,Arg2,
  83. typename enable_if<
  84. mpl::or_<
  85. mpl::not_<mpl::or_<
  86. is_same<typename function_traits<F>::arg1_type,const Arg1&>,
  87. is_same<typename function_traits<F>::arg1_type,Arg1>
  88. > >,
  89. mpl::not_<mpl::or_<
  90. is_same<typename function_traits<F>::arg2_type,const Arg2&>,
  91. is_same<typename function_traits<F>::arg2_type,Arg2>
  92. > >
  93. >
  94. >::type
  95. >:mpl::false_{};
  96. template<typename F,typename Arg1,typename Arg2>
  97. struct is_transparent<
  98. F,Arg1,Arg2,
  99. typename enable_if<
  100. is_function<typename remove_pointer<F>::type>
  101. >::type
  102. >:is_transparent_function<typename remove_pointer<F>::type,Arg1,Arg2>{};
  103. } /* namespace multi_index::detail */
  104. } /* namespace multi_index */
  105. } /* namespace boost */
  106. #endif
  107. #endif