/* Copyright 2003-2014 Joaquin M Lopez Munoz. * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * See http://www.boost.org/libs/multi_index for library home page. */ #ifndef BOOST_MULTI_INDEX_DETAIL_IS_TRANSPARENT_HPP #define BOOST_MULTI_INDEX_DETAIL_IS_TRANSPARENT_HPP #if defined(_MSC_VER) #pragma once #endif #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ #include <boost/mpl/bool.hpp> #include <boost/type_traits/intrinsics.hpp> namespace boost{ namespace multi_index{ namespace detail{ /* Metafunction that checks if f(arg,arg2) executes without argument type * conversion. By default (i.e. when it cannot be determined) it evaluates to * true. */ template<typename F,typename Arg1,typename Arg2,typename=void> struct is_transparent:mpl::true_{}; } /* namespace multi_index::detail */ } /* namespace multi_index */ } /* namespace boost */ #if !defined(BOOST_NO_SFINAE)&&!defined(BOOST_NO_SFINAE_EXPR)&& \ !defined(BOOST_NO_CXX11_DECLTYPE)&& \ (defined(BOOST_NO_CXX11_FINAL)||defined(BOOST_IS_FINAL)) #include <boost/mpl/and.hpp> #include <boost/mpl/not.hpp> #include <boost/mpl/or.hpp> #include <boost/type_traits/function_traits.hpp> #include <boost/type_traits/is_class.hpp> #include <boost/type_traits/is_final.hpp> #include <boost/type_traits/is_function.hpp> #include <boost/type_traits/is_same.hpp> #include <boost/type_traits/remove_pointer.hpp> #include <boost/utility/declval.hpp> #include <boost/utility/enable_if.hpp> namespace boost{ namespace multi_index{ namespace detail{ struct not_is_transparent_result_type{}; template<typename F,typename Arg1,typename Arg2> struct is_transparent_class_helper:F { using F::operator(); template<typename T,typename Q> not_is_transparent_result_type operator()(const T&,const Q&)const; }; template<typename F,typename Arg1,typename Arg2,typename=void> struct is_transparent_class:mpl::true_{}; template<typename F,typename Arg1,typename Arg2> struct is_transparent_class< F,Arg1,Arg2, typename enable_if< is_same< decltype( declval<const is_transparent_class_helper<F,Arg1,Arg2> >()( declval<const Arg1&>(),declval<const Arg2&>()) ), not_is_transparent_result_type > >::type >:mpl::false_{}; template<typename F,typename Arg1,typename Arg2> struct is_transparent< F,Arg1,Arg2, typename enable_if< mpl::and_< is_class<F>, mpl::not_<is_final<F> > /* is_transparent_class_helper derives from F */ > >::type >:is_transparent_class<F,Arg1,Arg2>{}; template<typename F,typename Arg1,typename Arg2,typename=void> struct is_transparent_function:mpl::true_{}; template<typename F,typename Arg1,typename Arg2> struct is_transparent_function< F,Arg1,Arg2, typename enable_if< mpl::or_< mpl::not_<mpl::or_< is_same<typename function_traits<F>::arg1_type,const Arg1&>, is_same<typename function_traits<F>::arg1_type,Arg1> > >, mpl::not_<mpl::or_< is_same<typename function_traits<F>::arg2_type,const Arg2&>, is_same<typename function_traits<F>::arg2_type,Arg2> > > > >::type >:mpl::false_{}; template<typename F,typename Arg1,typename Arg2> struct is_transparent< F,Arg1,Arg2, typename enable_if< is_function<typename remove_pointer<F>::type> >::type >:is_transparent_function<typename remove_pointer<F>::type,Arg1,Arg2>{}; } /* namespace multi_index::detail */ } /* namespace multi_index */ } /* namespace boost */ #endif #endif