diff options
author | Vlad Voicu <vladv@rosedu.org> | 2012-03-02 10:01:11 (GMT) |
---|---|---|
committer | Kevin Smith <git@kismith.co.uk> | 2012-03-09 15:04:05 (GMT) |
commit | 1c8cd160b79b6bbcec72042bdb104ba530508a93 (patch) | |
tree | cff302b81e74c557fbc9e30fd43144d981b613d0 /3rdParty/Boost/src/boost/proto/detail/decltype.hpp | |
parent | 2944711aefec9a9dd66052440bc4f921910dd780 (diff) | |
download | swift-contrib-1c8cd160b79b6bbcec72042bdb104ba530508a93.zip swift-contrib-1c8cd160b79b6bbcec72042bdb104ba530508a93.tar.bz2 |
Added spirit to bundled boost
Diffstat (limited to '3rdParty/Boost/src/boost/proto/detail/decltype.hpp')
-rw-r--r-- | 3rdParty/Boost/src/boost/proto/detail/decltype.hpp | 522 |
1 files changed, 522 insertions, 0 deletions
diff --git a/3rdParty/Boost/src/boost/proto/detail/decltype.hpp b/3rdParty/Boost/src/boost/proto/detail/decltype.hpp new file mode 100644 index 0000000..b8ad6d4 --- /dev/null +++ b/3rdParty/Boost/src/boost/proto/detail/decltype.hpp @@ -0,0 +1,522 @@ +/////////////////////////////////////////////////////////////////////////////// +/// \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 <boost/config.hpp> +#include <boost/detail/workaround.hpp> +#include <boost/get_pointer.hpp> +#include <boost/preprocessor/cat.hpp> +#include <boost/preprocessor/repetition/enum_params.hpp> +#include <boost/preprocessor/repetition/enum_trailing_params.hpp> +#include <boost/preprocessor/repetition/enum_binary_params.hpp> +#include <boost/preprocessor/repetition/repeat_from_to.hpp> +#include <boost/preprocessor/iteration/local.hpp> +#include <boost/mpl/if.hpp> +#include <boost/mpl/eval_if.hpp> +#include <boost/mpl/identity.hpp> +#include <boost/type_traits/is_class.hpp> +#include <boost/type_traits/remove_reference.hpp> +#include <boost/type_traits/is_pointer.hpp> +#include <boost/type_traits/is_function.hpp> +#include <boost/type_traits/is_member_object_pointer.hpp> +#include <boost/type_traits/add_const.hpp> +#include <boost/type_traits/add_reference.hpp> +#include <boost/typeof/typeof.hpp> +#include <boost/utility/addressof.hpp> +#include <boost/utility/result_of.hpp> +#include <boost/utility/enable_if.hpp> +#include <boost/proto/repeat.hpp> + +#ifndef BOOST_NO_DECLTYPE +# 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 sz = sizeof(boost::proto::detail::check_reference(EXPR)); \ + struct NESTED \ + : boost::mpl::if_c< \ + 1==sz \ + , 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 + { + namespace anyns + { + //////////////////////////////////////////////////////////////////////////////////////////// + struct any + { + any(...); + any operator=(any); + any operator[](any); + #define M0(Z, N, DATA) any operator()(BOOST_PP_ENUM_PARAMS_Z(Z, N, any BOOST_PP_INTERCEPT)); + BOOST_PP_REPEAT(BOOST_PROTO_MAX_ARITY, M0, ~) + #undef M0 + + template<typename T> + operator T &() const volatile; + + any operator+(); + any operator-(); + any operator*(); + any operator&(); + any operator~(); + any operator!(); + any operator++(); + any operator--(); + any operator++(int); + any operator--(int); + + friend any operator<<(any, any); + friend any operator>>(any, any); + friend any operator*(any, any); + friend any operator/(any, any); + friend any operator%(any, any); + friend any operator+(any, any); + friend any operator-(any, any); + friend any operator<(any, any); + friend any operator>(any, any); + friend any operator<=(any, any); + friend any operator>=(any, any); + friend any operator==(any, any); + friend any operator!=(any, any); + friend any operator||(any, any); + friend any operator&&(any, any); + friend any operator&(any, any); + friend any operator|(any, any); + friend any operator^(any, any); + friend any operator,(any, any); + friend any operator->*(any, any); + + friend any operator<<=(any, any); + friend any operator>>=(any, any); + friend any operator*=(any, any); + friend any operator/=(any, any); + friend any operator%=(any, any); + friend any operator+=(any, any); + friend any operator-=(any, any); + friend any operator&=(any, any); + friend any operator|=(any, any); + friend any operator^=(any, any); + }; + } + + using anyns::any; + + //////////////////////////////////////////////////////////////////////////////////////////// + template<typename T> + struct as_mutable + { + typedef T &type; + }; + + template<typename T> + struct as_mutable<T &> + { + typedef T &type; + }; + + template<typename T> + struct as_mutable<T const &> + { + typedef T &type; + }; + + //////////////////////////////////////////////////////////////////////////////////////////// + template<typename T> + T make(); + + //////////////////////////////////////////////////////////////////////////////////////////// + template<typename T> + typename as_mutable<T>::type make_mutable(); + + //////////////////////////////////////////////////////////////////////////////////////////// + template<typename T> + 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<typename T> + struct as_subscriptable + { + typedef + typename mpl::if_c< + is_class<T>::value + , subscript_wrapper<T> + , T + >::type + type; + }; + + template<typename T> + struct as_subscriptable<T const> + { + typedef + typename mpl::if_c< + is_class<T>::value + , subscript_wrapper<T> const + , T const + >::type + type; + }; + + template<typename T> + struct as_subscriptable<T &> + { + typedef + typename mpl::if_c< + is_class<T>::value + , subscript_wrapper<T> & + , T & + >::type + type; + }; + + template<typename T> + struct as_subscriptable<T const &> + { + typedef + typename mpl::if_c< + is_class<T>::value + , subscript_wrapper<T> const & + , T const & + >::type + type; + }; + + //////////////////////////////////////////////////////////////////////////////////////////// + template<typename T> + typename as_subscriptable<T>::type make_subscriptable(); + + //////////////////////////////////////////////////////////////////////////////////////////// + template<typename T> + char check_reference(T &); + + template<typename T> + char (&check_reference(T const &))[2]; + + namespace has_get_pointerns + { + using boost::get_pointer; + void *(&get_pointer(...))[2]; + + //////////////////////////////////////////////////////////////////////////////////////////// + template<typename T> + struct has_get_pointer + { + BOOST_STATIC_CONSTANT(bool, value = sizeof(void *) == sizeof(get_pointer(make<T &>()))); + typedef mpl::bool_<value> type; + }; + } + + using has_get_pointerns::has_get_pointer; + + //////////////////////////////////////////////////////////////////////////////////////////// + template<typename T> + struct classtypeof; + + template<typename T, typename U> + struct classtypeof<T U::*> + { + typedef U type; + }; + + #define BOOST_PP_LOCAL_MACRO(N) \ + template<typename T, typename U BOOST_PP_ENUM_TRAILING_PARAMS(N, typename A)> \ + struct classtypeof<T (U::*)(BOOST_PP_ENUM_PARAMS(N, A))> \ + { \ + typedef U type; \ + }; \ + template<typename T, typename U BOOST_PP_ENUM_TRAILING_PARAMS(N, typename A)> \ + struct classtypeof<T (U::*)(BOOST_PP_ENUM_PARAMS(N, A)) const> \ + { \ + typedef U type; \ + }; \ + /**/ + #define BOOST_PP_LOCAL_LIMITS (0, BOOST_PROTO_MAX_ARITY) + #include BOOST_PP_LOCAL_ITERATE() + + //////////////////////////////////////////////////////////////////////////////////////////// + template<typename T> + T &lvalue(T &t) + { + return t; + } + + template<typename T> + T const &lvalue(T const &t) + { + return t; + } + + //////////////////////////////////////////////////////////////////////////////////////////// + template<typename U, typename V, typename T> + U *proto_get_pointer(T &t, V *, U *) + { + return boost::addressof(t); + } + + template<typename U, typename V, typename T> + U const *proto_get_pointer(T &t, V *, U const *) + { + return boost::addressof(t); + } + + template<typename U, typename V, typename T> + 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<Type>( \ + 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 T> + typename disable_if_c<has_get_pointer<T>::value, T *>::type + get_pointer(T &t) + { + return boost::addressof(t); + } + + template<typename T> + typename disable_if_c<has_get_pointer<T>::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<typename U> char test_V_is_a_U(U *); + template<typename U> char test_V_is_a_U(U const *); + template<typename U> 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<typename T, typename Void = void> + struct result_of_ + : BOOST_PROTO_RESULT_OF<T> + {}; + + template<typename T, typename U, typename V> + struct result_of_<T U::*(V), typename enable_if_c<is_member_object_pointer<T U::*>::value>::type> + { + BOOST_STATIC_CONSTANT(bool, is_V_a_smart_ptr = 2 == sizeof(test_V_is_a_U<U>(&lvalue(make<V>())))); + BOOST_STATIC_CONSTANT(bool, is_ptr_to_const = 2 == sizeof(test_ptr_to_const(BOOST_PROTO_GET_POINTER(U, make<V>())))); + + // 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<V>::value) + , mpl::eval_if_c< + is_ptr_to_const + , add_reference<typename add_const<T>::type> + , add_reference<T> + > + , mpl::identity<T> + >::type + type; + }; + + //////////////////////////////////////////////////////////////////////////////////////////// + template< + typename T + , typename U + , bool IsMemPtr = is_member_object_pointer< + typename remove_reference<U>::type + >::value + > + struct mem_ptr_fun + { + BOOST_PROTO_DECLTYPE_( + proto::detail::make_mutable<T>() ->* proto::detail::make<U>() + , result_type + ) + + result_type operator()( + typename add_reference<typename add_const<T>::type>::type t + , typename add_reference<typename add_const<U>::type>::type u + ) const + { + return t ->* u; + } + }; + + //////////////////////////////////////////////////////////////////////////////////////////// + template<typename T, typename U> + struct mem_ptr_fun<T, U, true> + { + typedef + typename classtypeof< + typename uncvref<U>::type + >::type + V; + + BOOST_PROTO_DECLTYPE_( + BOOST_PROTO_GET_POINTER(V, proto::detail::make_mutable<T>()) ->* proto::detail::make<U>() + , result_type + ) + + result_type operator()( + typename add_reference<typename add_const<T>::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<typename A0, typename A1> + struct comma_result + { + BOOST_PROTO_DECLTYPE_((proto::detail::make<A0>(), proto::detail::make<A1>()), type) + }; + + template<typename A0> + struct comma_result<A0, void> + { + typedef void type; + }; + + template<typename A1> + struct comma_result<void, A1> + { + typedef A1 type; + }; + + template<> + struct comma_result<void, void> + { + typedef void type; + }; + + //////////////////////////////////////////////////////////////////////////////////////////// + // normalize a function type for use with boost::result_of + template<typename T, typename U = T> + struct result_of_fixup + : mpl::if_c<is_function<T>::value, T *, U> + {}; + + template<typename T, typename U> + struct result_of_fixup<T &, U> + : result_of_fixup<T, T> + {}; + + template<typename T, typename U> + struct result_of_fixup<T const &, U> + : result_of_fixup<T, T> + {}; + + template<typename T, typename U> + struct result_of_fixup<T *, U> + : result_of_fixup<T, U> + {}; + + template<typename R, typename T, typename U> + struct result_of_fixup<R T::*, U> + { + typedef R T::*type; + }; + + template<typename T, typename U> + struct result_of_fixup<T const, U> + : result_of_fixup<T, U> + {}; + + //// Tests for result_of_fixup + //struct bar {}; + //BOOST_MPL_ASSERT((is_same<bar, result_of_fixup<bar>::type>)); + //BOOST_MPL_ASSERT((is_same<bar const, result_of_fixup<bar const>::type>)); + //BOOST_MPL_ASSERT((is_same<bar, result_of_fixup<bar &>::type>)); + //BOOST_MPL_ASSERT((is_same<bar const, result_of_fixup<bar const &>::type>)); + //BOOST_MPL_ASSERT((is_same<void(*)(), result_of_fixup<void(*)()>::type>)); + //BOOST_MPL_ASSERT((is_same<void(*)(), result_of_fixup<void(* const)()>::type>)); + //BOOST_MPL_ASSERT((is_same<void(*)(), result_of_fixup<void(* const &)()>::type>)); + //BOOST_MPL_ASSERT((is_same<void(*)(), result_of_fixup<void(&)()>::type>)); + + template<typename T, typename PMF> + struct memfun + { + typedef typename uncvref<PMF>::type pmf_type; + typedef typename classtypeof<pmf_type>::type V; + typedef typename BOOST_PROTO_RESULT_OF<pmf_type(T)>::type result_type; + + memfun(T t, PMF p) + : obj(t) + , pmf(p) + {} + + result_type operator()() const + { + BOOST_PROTO_USE_GET_POINTER(); + return (BOOST_PROTO_GET_POINTER(V, obj) ->* pmf)(); + } + + #define BOOST_PROTO_LOCAL_MACRO(N, typename_A, A_const_ref, A_const_ref_a, a) \ + template<typename_A(N)> \ + result_type operator()(A_const_ref_a(N)) const \ + { \ + BOOST_PROTO_USE_GET_POINTER(); \ + return (BOOST_PROTO_GET_POINTER(V, obj) ->* pmf)(a(N)); \ + } \ + /**/ + #define BOOST_PROTO_LOCAL_a BOOST_PROTO_a + #define BOOST_PROTO_LOCAL_LIMITS (1, BOOST_PROTO_MAX_ARITY) + #include BOOST_PROTO_LOCAL_ITERATE() + + private: + T obj; + PMF pmf; + }; + + } // namespace detail +}} + +#endif |