Warning, file /include/boost/proto/detail/decltype.hpp was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef BOOST_PROTO_DETAIL_DECLTYPE_HPP_EAN_04_04_2008
0010 #define BOOST_PROTO_DETAIL_DECLTYPE_HPP_EAN_04_04_2008
0011
0012 #include <boost/config.hpp>
0013 #include <boost/detail/workaround.hpp>
0014 #include <boost/get_pointer.hpp>
0015 #include <boost/preprocessor/cat.hpp>
0016 #include <boost/preprocessor/repetition/enum_params.hpp>
0017 #include <boost/preprocessor/repetition/enum_trailing_params.hpp>
0018 #include <boost/preprocessor/repetition/enum_binary_params.hpp>
0019 #include <boost/preprocessor/repetition/repeat.hpp>
0020 #include <boost/preprocessor/repetition/repeat_from_to.hpp>
0021 #include <boost/preprocessor/iteration/local.hpp>
0022 #include <boost/mpl/if.hpp>
0023 #include <boost/mpl/eval_if.hpp>
0024 #include <boost/mpl/identity.hpp>
0025 #include <boost/type_traits/is_class.hpp>
0026 #include <boost/type_traits/remove_reference.hpp>
0027 #include <boost/type_traits/is_pointer.hpp>
0028 #include <boost/type_traits/is_function.hpp>
0029 #include <boost/type_traits/is_member_object_pointer.hpp>
0030 #include <boost/type_traits/add_const.hpp>
0031 #include <boost/type_traits/add_reference.hpp>
0032 #include <boost/typeof/typeof.hpp>
0033 #include <boost/utility/addressof.hpp>
0034 #include <boost/utility/result_of.hpp>
0035 #include <boost/utility/enable_if.hpp>
0036 #include <boost/proto/proto_fwd.hpp>
0037 #include <boost/proto/detail/any.hpp>
0038
0039 #if defined(_MSC_VER)
0040 # pragma warning(push)
0041 # pragma warning(disable : 4714)
0042 #endif
0043
0044
0045
0046 #if !defined(BOOST_NO_CXX11_DECLTYPE) && !BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1700))
0047 # define BOOST_PROTO_DECLTYPE_(EXPR, TYPE) typedef decltype((EXPR)) TYPE;
0048 #else
0049 # define BOOST_PROTO_DECLTYPE_NESTED_TYPEDEF_TPL_(NESTED, EXPR) \
0050 BOOST_TYPEOF_NESTED_TYPEDEF_TPL(BOOST_PP_CAT(nested_and_hidden_, NESTED), EXPR) \
0051 static int const BOOST_PP_CAT(sz, NESTED) = sizeof(boost::proto::detail::check_reference(EXPR));\
0052 struct NESTED \
0053 : boost::mpl::if_c< \
0054 1 == BOOST_PP_CAT(sz, NESTED) \
0055 , typename BOOST_PP_CAT(nested_and_hidden_, NESTED)::type & \
0056 , typename BOOST_PP_CAT(nested_and_hidden_, NESTED)::type \
0057 > \
0058 {};
0059 # define BOOST_PROTO_DECLTYPE_(EXPR, TYPE) \
0060 BOOST_PROTO_DECLTYPE_NESTED_TYPEDEF_TPL_(BOOST_PP_CAT(nested_, TYPE), (EXPR)) \
0061 typedef typename BOOST_PP_CAT(nested_, TYPE)::type TYPE;
0062 #endif
0063
0064 namespace boost { namespace proto
0065 {
0066 namespace detail
0067 {
0068
0069 template<typename T>
0070 struct as_mutable
0071 {
0072 typedef T &type;
0073 };
0074
0075 template<typename T>
0076 struct as_mutable<T &>
0077 {
0078 typedef T &type;
0079 };
0080
0081 template<typename T>
0082 struct as_mutable<T const &>
0083 {
0084 typedef T &type;
0085 };
0086
0087
0088 template<typename T>
0089 T make();
0090
0091
0092 template<typename T>
0093 typename as_mutable<T>::type make_mutable();
0094
0095
0096 template<typename T>
0097 struct subscript_wrapper
0098 : T
0099 {
0100 using T::operator[];
0101
0102 #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500))
0103 any operator[](any const volatile &) const volatile;
0104 #else
0105 any operator[](any const &) const volatile;
0106 #endif
0107 };
0108
0109
0110 template<typename T>
0111 struct as_subscriptable
0112 {
0113 typedef
0114 typename mpl::if_c<
0115 is_class<T>::value
0116 , subscript_wrapper<T>
0117 , T
0118 >::type
0119 type;
0120 };
0121
0122 template<typename T>
0123 struct as_subscriptable<T const>
0124 {
0125 typedef
0126 typename mpl::if_c<
0127 is_class<T>::value
0128 , subscript_wrapper<T> const
0129 , T const
0130 >::type
0131 type;
0132 };
0133
0134 template<typename T>
0135 struct as_subscriptable<T &>
0136 {
0137 typedef
0138 typename mpl::if_c<
0139 is_class<T>::value
0140 , subscript_wrapper<T> &
0141 , T &
0142 >::type
0143 type;
0144 };
0145
0146 template<typename T>
0147 struct as_subscriptable<T const &>
0148 {
0149 typedef
0150 typename mpl::if_c<
0151 is_class<T>::value
0152 , subscript_wrapper<T> const &
0153 , T const &
0154 >::type
0155 type;
0156 };
0157
0158
0159 template<typename T>
0160 typename as_subscriptable<T>::type make_subscriptable();
0161
0162
0163 template<typename T>
0164 char check_reference(T &);
0165
0166 template<typename T>
0167 char (&check_reference(T const &))[2];
0168
0169 namespace has_get_pointerns
0170 {
0171 using boost::get_pointer;
0172 void *(&get_pointer(...))[2];
0173
0174
0175 template<typename T>
0176 struct has_get_pointer
0177 {
0178 static const bool value = sizeof(void *) == sizeof(get_pointer(make<T &>()));
0179 typedef mpl::bool_<value> type;
0180 };
0181 }
0182
0183 using has_get_pointerns::has_get_pointer;
0184
0185
0186 template<typename T>
0187 struct class_member_traits;
0188
0189 template<typename T, typename U>
0190 struct class_member_traits<T U::*>
0191 {
0192 typedef U class_type;
0193 typedef T result_type;
0194 };
0195
0196
0197 #include <boost/proto/detail/class_member_traits.hpp>
0198
0199
0200 template<typename T>
0201 T &lvalue(T &t)
0202 {
0203 return t;
0204 }
0205
0206 template<typename T>
0207 T const &lvalue(T const &t)
0208 {
0209 return t;
0210 }
0211
0212
0213 template<typename U, typename V, typename T>
0214 U *proto_get_pointer(T &t, V *, U *)
0215 {
0216 return boost::addressof(t);
0217 }
0218
0219 template<typename U, typename V, typename T>
0220 U const *proto_get_pointer(T &t, V *, U const *)
0221 {
0222 return boost::addressof(t);
0223 }
0224
0225 template<typename U, typename V, typename T>
0226 V *proto_get_pointer(T &t, V *, ...)
0227 {
0228 return get_pointer(t);
0229 }
0230
0231
0232 #define BOOST_PROTO_USE_GET_POINTER() \
0233 using namespace boost::proto::detail::get_pointerns \
0234
0235
0236 #define BOOST_PROTO_GET_POINTER(Type, Obj) \
0237 boost::proto::detail::proto_get_pointer<Type>( \
0238 boost::proto::detail::lvalue(Obj) \
0239 , (true ? 0 : get_pointer(Obj)) \
0240 , (true ? 0 : boost::addressof(boost::proto::detail::lvalue(Obj))) \
0241 ) \
0242
0243
0244
0245 namespace get_pointerns
0246 {
0247 using boost::get_pointer;
0248
0249 template<typename T>
0250 typename disable_if_c<has_get_pointer<T>::value, T *>::type
0251 get_pointer(T &t)
0252 {
0253 return boost::addressof(t);
0254 }
0255
0256 template<typename T>
0257 typename disable_if_c<has_get_pointer<T>::value, T const *>::type
0258 get_pointer(T const &t)
0259 {
0260 return boost::addressof(t);
0261 }
0262
0263 char test_ptr_to_const(void *);
0264 char (&test_ptr_to_const(void const *))[2];
0265
0266 template<typename U> char test_V_is_a_U(U *);
0267 template<typename U> char test_V_is_a_U(U const *);
0268 template<typename U> char (&test_V_is_a_U(...))[2];
0269
0270
0271
0272
0273 template<typename T, typename Void = void>
0274 struct result_of_
0275 : BOOST_PROTO_RESULT_OF<T>
0276 {};
0277
0278 template<typename T, typename U, typename V>
0279 struct result_of_<T U::*(V), typename enable_if_c<is_member_object_pointer<T U::*>::value>::type>
0280 {
0281 static const bool is_V_a_smart_ptr = 2 == sizeof(test_V_is_a_U<U>(&lvalue(make<V>())));
0282 static const bool is_ptr_to_const = 2 == sizeof(test_ptr_to_const(BOOST_PROTO_GET_POINTER(U, make<V>())));
0283
0284
0285
0286 typedef
0287 typename mpl::eval_if_c<
0288 (is_V_a_smart_ptr || is_reference<V>::value)
0289 , mpl::eval_if_c<
0290 is_ptr_to_const
0291 , add_reference<typename add_const<T>::type>
0292 , add_reference<T>
0293 >
0294 , mpl::identity<T>
0295 >::type
0296 type;
0297 };
0298
0299
0300 template<
0301 typename T
0302 , typename U
0303 , bool IsMemPtr = is_member_object_pointer<
0304 typename remove_reference<U>::type
0305 >::value
0306 >
0307 struct mem_ptr_fun
0308 {
0309 BOOST_PROTO_DECLTYPE_(
0310 proto::detail::make_mutable<T>() ->* proto::detail::make<U>()
0311 , result_type
0312 )
0313
0314 result_type operator()(
0315 typename add_reference<typename add_const<T>::type>::type t
0316 , typename add_reference<typename add_const<U>::type>::type u
0317 ) const
0318 {
0319 return t ->* u;
0320 }
0321 };
0322
0323
0324 template<typename T, typename U>
0325 struct mem_ptr_fun<T, U, true>
0326 {
0327 typedef
0328 typename class_member_traits<
0329 typename uncvref<U>::type
0330 >::class_type
0331 V;
0332
0333 BOOST_PROTO_DECLTYPE_(
0334 BOOST_PROTO_GET_POINTER(V, proto::detail::make_mutable<T>()) ->* proto::detail::make<U>()
0335 , result_type
0336 )
0337
0338 result_type operator()(
0339 typename add_reference<typename add_const<T>::type>::type t
0340 , U u
0341 ) const
0342 {
0343 return BOOST_PROTO_GET_POINTER(V, t) ->* u;
0344 }
0345 };
0346 }
0347
0348 using get_pointerns::result_of_;
0349 using get_pointerns::mem_ptr_fun;
0350
0351
0352 template<typename A0, typename A1>
0353 struct comma_result
0354 {
0355 BOOST_PROTO_DECLTYPE_((proto::detail::make<A0>(), proto::detail::make<A1>()), type)
0356 };
0357
0358 template<typename A0>
0359 struct comma_result<A0, void>
0360 {
0361 typedef void type;
0362 };
0363
0364 template<typename A1>
0365 struct comma_result<void, A1>
0366 {
0367 typedef A1 type;
0368 };
0369
0370 template<>
0371 struct comma_result<void, void>
0372 {
0373 typedef void type;
0374 };
0375
0376
0377
0378 template<typename T, typename U = T>
0379 struct result_of_fixup
0380 : mpl::if_c<is_function<T>::value, T *, U>
0381 {};
0382
0383 template<typename T, typename U>
0384 struct result_of_fixup<T &, U>
0385 : result_of_fixup<T, T>
0386 {};
0387
0388 template<typename T, typename U>
0389 struct result_of_fixup<T const &, U>
0390 : result_of_fixup<T, T>
0391 {};
0392
0393 template<typename T, typename U>
0394 struct result_of_fixup<T *, U>
0395 : result_of_fixup<T, U>
0396 {};
0397
0398 template<typename R, typename T, typename U>
0399 struct result_of_fixup<R T::*, U>
0400 {
0401 typedef R T::*type;
0402 };
0403
0404 template<typename T, typename U>
0405 struct result_of_fixup<T const, U>
0406 : result_of_fixup<T, U>
0407 {};
0408
0409
0410
0411
0412
0413
0414
0415
0416
0417
0418
0419
0420 template<typename T, typename PMF>
0421 struct memfun
0422 {
0423 typedef typename uncvref<PMF>::type pmf_type;
0424 typedef typename class_member_traits<pmf_type>::class_type V;
0425 typedef typename class_member_traits<pmf_type>::result_type result_type;
0426
0427 memfun(T t, pmf_type p)
0428 : obj(t)
0429 , pmf(p)
0430 {}
0431
0432 result_type operator()() const
0433 {
0434 BOOST_PROTO_USE_GET_POINTER();
0435 return (BOOST_PROTO_GET_POINTER(V, obj) ->* pmf)();
0436 }
0437
0438
0439 #include <boost/proto/detail/memfun_funop.hpp>
0440
0441 private:
0442 T obj;
0443 pmf_type pmf;
0444 };
0445
0446 }
0447 }}
0448
0449 #if defined(_MSC_VER)
0450 # pragma warning(pop)
0451 #endif
0452
0453 #endif