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