/usr/include/boost/proto/detail
Edit: /usr/include/boost/proto/detail/decltype.hpp (16619B)
///////////////////////////////////////////////////////////////////////////////
/// \file decltype.hpp
/// Contains definition the BOOST_PROTO_DECLTYPE_() macro and assorted helpers
//
// Copyright 2008 Eric Niebler. 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)
#ifndef BOOST_PROTO_DETAIL_DECLTYPE_HPP_EAN_04_04_2008
#define BOOST_PROTO_DETAIL_DECLTYPE_HPP_EAN_04_04_2008
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#if defined(_MSC_VER)
# pragma warning(push)
# pragma warning(disable : 4714) // function 'xxx' marked as __forceinline not inlined
#endif
// We're STILL using Boost.Typeof on MSVC even for msvc-11.0 because of this bug:
// https://connect.microsoft.com/VisualStudio/feedback/details/765392/decltype-of-a-pointer-to-member-operator-gets-ref-qualification-wrong
#if !defined(BOOST_NO_CXX11_DECLTYPE) && !BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1700))
# define BOOST_PROTO_DECLTYPE_(EXPR, TYPE) typedef decltype((EXPR)) TYPE;
#else
# define BOOST_PROTO_DECLTYPE_NESTED_TYPEDEF_TPL_(NESTED, EXPR) \
BOOST_TYPEOF_NESTED_TYPEDEF_TPL(BOOST_PP_CAT(nested_and_hidden_, NESTED), EXPR) \
static int const BOOST_PP_CAT(sz, NESTED) = sizeof(boost::proto::detail::check_reference(EXPR));\
struct NESTED \
: boost::mpl::if_c< \
1 == BOOST_PP_CAT(sz, NESTED) \
, typename BOOST_PP_CAT(nested_and_hidden_, NESTED)::type & \
, typename BOOST_PP_CAT(nested_and_hidden_, NESTED)::type \
> \
{};
# define BOOST_PROTO_DECLTYPE_(EXPR, TYPE) \
BOOST_PROTO_DECLTYPE_NESTED_TYPEDEF_TPL_(BOOST_PP_CAT(nested_, TYPE), (EXPR)) \
typedef typename BOOST_PP_CAT(nested_, TYPE)::type TYPE;
#endif
namespace boost { namespace proto
{
namespace detail
{
////////////////////////////////////////////////////////////////////////////////////////////
template
struct as_mutable
{
typedef T &type;
};
template
struct as_mutable
{
typedef T &type;
};
template
struct as_mutable
{
typedef T &type;
};
////////////////////////////////////////////////////////////////////////////////////////////
template
T make();
////////////////////////////////////////////////////////////////////////////////////////////
template
typename as_mutable::type make_mutable();
////////////////////////////////////////////////////////////////////////////////////////////
template
struct subscript_wrapper
: T
{
using T::operator[];
#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500))
any operator[](any const volatile &) const volatile;
#else
any operator[](any const &) const volatile;
#endif
};
////////////////////////////////////////////////////////////////////////////////////////////
template
struct as_subscriptable
{
typedef
typename mpl::if_c<
is_class::value
, subscript_wrapper
, T
>::type
type;
};
template
struct as_subscriptable
{
typedef
typename mpl::if_c<
is_class::value
, subscript_wrapper const
, T const
>::type
type;
};
template
struct as_subscriptable
{
typedef
typename mpl::if_c<
is_class::value
, subscript_wrapper &
, T &
>::type
type;
};
template
struct as_subscriptable
{
typedef
typename mpl::if_c<
is_class::value
, subscript_wrapper const &
, T const &
>::type
type;
};
////////////////////////////////////////////////////////////////////////////////////////////
template
typename as_subscriptable::type make_subscriptable();
////////////////////////////////////////////////////////////////////////////////////////////
template
char check_reference(T &);
template
char (&check_reference(T const &))[2];
namespace has_get_pointerns
{
using boost::get_pointer;
void *(&get_pointer(...))[2];
////////////////////////////////////////////////////////////////////////////////////////////
template
struct has_get_pointer
{
static const bool value = sizeof(void *) == sizeof(get_pointer(make()));
typedef mpl::bool_ type;
};
}
using has_get_pointerns::has_get_pointer;
////////////////////////////////////////////////////////////////////////////////////////////
template
struct class_member_traits;
template
struct class_member_traits
{
typedef U class_type;
typedef T result_type;
};
// Other specializations are generated by the preprocessor
#include
////////////////////////////////////////////////////////////////////////////////////////////
template
T &lvalue(T &t)
{
return t;
}
template
T const &lvalue(T const &t)
{
return t;
}
////////////////////////////////////////////////////////////////////////////////////////////
template
U *proto_get_pointer(T &t, V *, U *)
{
return boost::addressof(t);
}
template
U const *proto_get_pointer(T &t, V *, U const *)
{
return boost::addressof(t);
}
template
V *proto_get_pointer(T &t, V *, ...)
{
return get_pointer(t);
}
////////////////////////////////////////////////////////////////////////////////////////////
#define BOOST_PROTO_USE_GET_POINTER() \
using namespace boost::proto::detail::get_pointerns \
/**/
#define BOOST_PROTO_GET_POINTER(Type, Obj) \
boost::proto::detail::proto_get_pointer( \
boost::proto::detail::lvalue(Obj) \
, (true ? 0 : get_pointer(Obj)) \
, (true ? 0 : boost::addressof(boost::proto::detail::lvalue(Obj))) \
) \
/**/
////////////////////////////////////////////////////////////////////////////////////////////
namespace get_pointerns
{
using boost::get_pointer;
template
typename disable_if_c::value, T *>::type
get_pointer(T &t)
{
return boost::addressof(t);
}
template
typename disable_if_c::value, T const *>::type
get_pointer(T const &t)
{
return boost::addressof(t);
}
char test_ptr_to_const(void *);
char (&test_ptr_to_const(void const *))[2];
template char test_V_is_a_U(U *);
template char test_V_is_a_U(U const *);
template char (&test_V_is_a_U(...))[2];
////////////////////////////////////////////////////////////////////////////////////////////
// result_of_ is a wrapper around boost::result_of that also handles "invocations" of
// member object pointers.
template
struct result_of_
: BOOST_PROTO_RESULT_OF
{};
template
struct result_of_::value>::type>
{
static const bool is_V_a_smart_ptr = 2 == sizeof(test_V_is_a_U(&lvalue(make())));
static const bool is_ptr_to_const = 2 == sizeof(test_ptr_to_const(BOOST_PROTO_GET_POINTER(U, make())));
// If V is not a U, then it is a (smart) pointer and we can always return an lvalue.
// Otherwise, we can only return an lvalue if we are given one.
typedef
typename mpl::eval_if_c<
(is_V_a_smart_ptr || is_reference::value)
, mpl::eval_if_c<
is_ptr_to_const
, add_reference::type>
, add_reference
>
, mpl::identity
>::type
type;
};
////////////////////////////////////////////////////////////////////////////////////////////
template<
typename T
, typename U
, bool IsMemPtr = is_member_object_pointer<
typename remove_reference::type
>::value
>
struct mem_ptr_fun
{
BOOST_PROTO_DECLTYPE_(
proto::detail::make_mutable() ->* proto::detail::make()
, result_type
)
result_type operator()(
typename add_reference::type>::type t
, typename add_reference::type>::type u
) const
{
return t ->* u;
}
};
////////////////////////////////////////////////////////////////////////////////////////////
template
struct mem_ptr_fun
{
typedef
typename class_member_traits<
typename uncvref::type
>::class_type
V;
BOOST_PROTO_DECLTYPE_(
BOOST_PROTO_GET_POINTER(V, proto::detail::make_mutable()) ->* proto::detail::make()
, result_type
)
result_type operator()(
typename add_reference::type>::type t
, U u
) const
{
return BOOST_PROTO_GET_POINTER(V, t) ->* u;
}
};
}
using get_pointerns::result_of_;
using get_pointerns::mem_ptr_fun;
////////////////////////////////////////////////////////////////////////////////////////////
template
struct comma_result
{
BOOST_PROTO_DECLTYPE_((proto::detail::make(), proto::detail::make()), type)
};
template
struct comma_result
{
typedef void type;
};
template
struct comma_result
{
typedef A1 type;
};
template<>
struct comma_result
{
typedef void type;
};
////////////////////////////////////////////////////////////////////////////////////////////
// normalize a function type for use with boost::result_of
template
struct result_of_fixup
: mpl::if_c::value, T *, U>
{};
template
struct result_of_fixup
: result_of_fixup
{};
template
struct result_of_fixup
: result_of_fixup
{};
template
struct result_of_fixup
: result_of_fixup
{};
template
struct result_of_fixup
{
typedef R T::*type;
};
template
struct result_of_fixup
: result_of_fixup
{};
//// Tests for result_of_fixup
//struct bar {};
//BOOST_MPL_ASSERT((is_same::type>));
//BOOST_MPL_ASSERT((is_same::type>));
//BOOST_MPL_ASSERT((is_same::type>));
//BOOST_MPL_ASSERT((is_same::type>));
//BOOST_MPL_ASSERT((is_same::type>));
//BOOST_MPL_ASSERT((is_same::type>));
//BOOST_MPL_ASSERT((is_same::type>));
//BOOST_MPL_ASSERT((is_same::type>));
template
struct memfun
{
typedef typename uncvref::type pmf_type;
typedef typename class_member_traits::class_type V;
typedef typename class_member_traits::result_type result_type;
memfun(T t, pmf_type p)
: obj(t)
, pmf(p)
{}
result_type operator()() const
{
BOOST_PROTO_USE_GET_POINTER();
return (BOOST_PROTO_GET_POINTER(V, obj) ->* pmf)();
}
// Other overloads generated by the preprocessor
#include
private:
T obj;
pmf_type pmf;
};
} // namespace detail
}}
#if defined(_MSC_VER)
# pragma warning(pop)
#endif
#endif