File indexing completed on 2025-01-18 09:31:06
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef BOOST_FT_COMPONENTS_HPP_INCLUDED
0010 #define BOOST_FT_COMPONENTS_HPP_INCLUDED
0011
0012 #include <cstddef>
0013
0014 #include <boost/config.hpp>
0015
0016 #include <boost/detail/workaround.hpp>
0017 #include <boost/mpl/aux_/lambda_support.hpp>
0018
0019 #include <boost/type_traits/integral_constant.hpp>
0020
0021 #include <boost/mpl/if.hpp>
0022 #include <boost/mpl/integral_c.hpp>
0023 #include <boost/mpl/vector/vector0.hpp>
0024
0025 #if BOOST_WORKAROUND(BOOST_BORLANDC, <= 0x565)
0026 # include <boost/type_traits/remove_cv.hpp>
0027
0028 # include <boost/mpl/identity.hpp>
0029 # include <boost/mpl/bitand.hpp>
0030 # include <boost/mpl/vector/vector10.hpp>
0031 # include <boost/mpl/front.hpp>
0032 # include <boost/mpl/begin.hpp>
0033 # include <boost/mpl/advance.hpp>
0034 # include <boost/mpl/iterator_range.hpp>
0035 # include <boost/mpl/joint_view.hpp>
0036 # include <boost/mpl/equal_to.hpp>
0037 # include <boost/mpl/copy.hpp>
0038 # include <boost/mpl/front_inserter.hpp>
0039
0040 # include <boost/function_types/detail/classifier.hpp>
0041 #endif
0042
0043 #ifndef BOOST_FT_NO_CV_FUNC_SUPPORT
0044 # include <boost/mpl/remove.hpp>
0045 #endif
0046
0047 #include <boost/function_types/config/config.hpp>
0048
0049 # if BOOST_FT_MAX_ARITY < 10
0050 # include <boost/mpl/vector/vector10.hpp>
0051 # elif BOOST_FT_MAX_ARITY < 20
0052 # include <boost/mpl/vector/vector20.hpp>
0053 # elif BOOST_FT_MAX_ARITY < 30
0054 # include <boost/mpl/vector/vector30.hpp>
0055 # elif BOOST_FT_MAX_ARITY < 40
0056 # include <boost/mpl/vector/vector40.hpp>
0057 # elif BOOST_FT_MAX_ARITY < 50
0058 # include <boost/mpl/vector/vector50.hpp>
0059 # endif
0060
0061 #include <boost/function_types/detail/class_transform.hpp>
0062 #include <boost/function_types/property_tags.hpp>
0063
0064
0065
0066 namespace boost
0067 {
0068 namespace function_types
0069 {
0070
0071 using mpl::placeholders::_;
0072
0073 template< typename T, typename ClassTypeTransform = add_reference<_> >
0074 struct components;
0075
0076 namespace detail
0077 {
0078 template<typename T, typename L> struct components_impl;
0079 #if BOOST_WORKAROUND(BOOST_BORLANDC, <= 0x565)
0080 template<typename T, typename OrigT, typename L> struct components_bcc;
0081 #endif
0082 }
0083
0084 template<typename T, typename ClassTypeTransform>
0085 struct components
0086 #if !BOOST_WORKAROUND(BOOST_BORLANDC, <= 0x565)
0087 : detail::components_impl<T, ClassTypeTransform>
0088 #else
0089 : detail::components_bcc<typename remove_cv<T>::type,T,
0090 ClassTypeTransform>
0091 #endif
0092 {
0093 typedef components<T,ClassTypeTransform> type;
0094
0095 BOOST_MPL_AUX_LAMBDA_SUPPORT(2,components,(T,ClassTypeTransform))
0096 };
0097
0098
0099
0100 namespace detail {
0101
0102 struct components_mpl_sequence_tag;
0103
0104 struct components_non_func_base
0105 {
0106 typedef mpl::vector0<> types;
0107 typedef void function_arity;
0108
0109 typedef detail::constant<0> bits;
0110 typedef detail::constant<0> mask;
0111
0112 typedef components_mpl_sequence_tag tag;
0113 };
0114
0115 template
0116 < typename Components
0117 , typename IfTagged
0118 , typename ThenTag
0119 , typename DefaultBase = components_non_func_base
0120 >
0121 struct retagged_if
0122 : mpl::if_
0123 < detail::represents_impl<Components, IfTagged>
0124 , detail::changed_tag<Components,IfTagged,ThenTag>
0125 , DefaultBase
0126 >::type
0127 { };
0128
0129
0130
0131
0132
0133 template<typename T, typename L>
0134 struct components_impl
0135 : detail::retagged_if
0136 < detail::components_impl<T*,L>
0137 , pointer_tag, function_tag >
0138 { };
0139 template<typename T, typename L>
0140 struct components_impl<T&, L>
0141 : detail::retagged_if
0142 < detail::components_impl<T*,L>
0143 , pointer_tag, reference_tag >
0144 { };
0145
0146 #if !BOOST_FT_NO_CV_FUNC_SUPPORT
0147
0148 class a_class;
0149
0150 template<typename Base, typename T, typename L>
0151 struct cv_func_base
0152 : detail::retagged_if<Base,member_pointer_tag,function_tag>
0153 {
0154 typedef typename
0155 mpl::remove
0156 < typename Base::types
0157 , typename detail::class_transform<a_class,L>::type>::type
0158 types;
0159 };
0160
0161 template<typename T, typename L>
0162 struct components_impl<T*, L>
0163 : mpl::if_
0164 < detail::represents_impl< detail::components_impl<T a_class::*, L>
0165 , member_pointer_tag >
0166 , detail::cv_func_base< detail::components_impl<T a_class::*, L>, T, L>
0167 , components_non_func_base
0168 >::type
0169 { };
0170
0171 template<typename T, typename L>
0172 struct components_impl<T a_class::*, L>
0173 : components_non_func_base
0174 { };
0175 #else
0176 template<typename T, typename L>
0177 struct components_impl<T*, L>
0178 : components_non_func_base
0179 { };
0180 #endif
0181
0182 template<typename T, typename L>
0183 struct components_impl<T* const, L>
0184 : components_impl<T*,L>
0185 { };
0186
0187 template<typename T, typename L>
0188 struct components_impl<T* volatile, L>
0189 : components_impl<T*,L>
0190 { };
0191
0192 template<typename T, typename L>
0193 struct components_impl<T* const volatile, L>
0194 : components_impl<T*,L>
0195 { };
0196
0197 template<typename T, typename L>
0198 struct components_impl<T const, L>
0199 : components_impl<T,L>
0200 { };
0201
0202 template<typename T, typename L>
0203 struct components_impl<T volatile, L>
0204 : components_impl<T,L>
0205 { };
0206
0207 template<typename T, typename L>
0208 struct components_impl<T const volatile, L>
0209 : components_impl<T,L>
0210 { };
0211
0212
0213 template<typename T, class C>
0214 struct member_obj_ptr_result
0215 { typedef T & type; };
0216
0217 template<typename T, class C>
0218 struct member_obj_ptr_result<T, C const>
0219 { typedef T const & type; };
0220
0221 template<typename T, class C>
0222 struct member_obj_ptr_result<T, C volatile>
0223 { typedef T volatile & type; };
0224
0225 template<typename T, class C>
0226 struct member_obj_ptr_result<T, C const volatile>
0227 { typedef T const volatile & type; };
0228
0229 template<typename T, class C>
0230 struct member_obj_ptr_result<T &, C>
0231 { typedef T & type; };
0232
0233 template<typename T, class C>
0234 struct member_obj_ptr_result<T &, C const>
0235 { typedef T & type; };
0236
0237 template<typename T, class C>
0238 struct member_obj_ptr_result<T &, C volatile>
0239 { typedef T & type; };
0240
0241 template<typename T, class C>
0242 struct member_obj_ptr_result<T &, C const volatile>
0243 { typedef T & type; };
0244
0245 template<typename T, class C, typename L>
0246 struct member_obj_ptr_components
0247 : member_object_pointer_base
0248 {
0249 typedef function_types::components<T C::*, L> type;
0250 typedef components_mpl_sequence_tag tag;
0251
0252 typedef mpl::integral_c<std::size_t,1> function_arity;
0253
0254 typedef mpl::vector2< typename detail::member_obj_ptr_result<T,C>::type,
0255 typename detail::class_transform<C,L>::type > types;
0256 };
0257
0258 #if !BOOST_WORKAROUND(BOOST_BORLANDC, <= 0x565)
0259 # define BOOST_FT_variations BOOST_FT_pointer|BOOST_FT_member_pointer
0260
0261 template<typename T, class C, typename L>
0262 struct components_impl<T C::*, L>
0263 : member_obj_ptr_components<T,C,L>
0264 { };
0265
0266 #else
0267 # define BOOST_FT_variations BOOST_FT_pointer
0268
0269
0270
0271 template<typename T, typename C, typename L>
0272 struct components_impl<T C::*, L>
0273 : detail::retagged_if
0274 < detail::components_impl<typename boost::remove_cv<T>::type *, L>
0275 , pointer_tag, member_function_pointer_tag
0276 , member_obj_ptr_components<T,C,L> >
0277 { };
0278
0279
0280
0281
0282
0283
0284
0285 template<typename T> struct encode_cv
0286 { typedef char (& type)[1]; BOOST_STATIC_CONSTANT(std::size_t, value = 1); };
0287 template<typename T> struct encode_cv<T const *>
0288 { typedef char (& type)[2]; BOOST_STATIC_CONSTANT(std::size_t, value = 2); };
0289 template<typename T> struct encode_cv<T volatile *>
0290 { typedef char (& type)[3]; BOOST_STATIC_CONSTANT(std::size_t, value = 3); };
0291 template<typename T> struct encode_cv<T const volatile *>
0292 { typedef char (& type)[4]; BOOST_STATIC_CONSTANT(std::size_t, value = 4); };
0293
0294
0295
0296
0297 template<typename T, typename C>
0298 typename encode_cv<T *>::type mfp_cv_tester(T C::*);
0299
0300 template<typename T> struct encode_mfp_cv
0301 {
0302 BOOST_STATIC_CONSTANT(std::size_t, value =
0303 sizeof(detail::mfp_cv_tester((T)0L)));
0304 };
0305
0306
0307 template<std::size_t> struct cv_tag_mfp_impl;
0308
0309 template<typename T> struct cv_tag_mfp
0310 : detail::cv_tag_mfp_impl
0311 < ::boost::function_types::detail::encode_mfp_cv<T>::value >
0312 { };
0313
0314 template<> struct cv_tag_mfp_impl<1> : non_cv { };
0315 template<> struct cv_tag_mfp_impl<2> : const_non_volatile { };
0316 template<> struct cv_tag_mfp_impl<3> : volatile_non_const { };
0317 template<> struct cv_tag_mfp_impl<4> : cv_qualified { };
0318
0319
0320
0321 template<typename T, std::size_t CV> struct decode_cv;
0322
0323 template<typename T> struct decode_cv<T,1> : mpl::identity<T *> {};
0324 template<typename T> struct decode_cv<T,2> : mpl::identity<T const *> {};
0325 template<typename T> struct decode_cv<T,3> : mpl::identity<T volatile *> {};
0326 template<typename T> struct decode_cv<T,4>
0327 : mpl::identity<T const volatile *> {};
0328
0329
0330
0331 template<typename T, typename L> struct bcc_class_transform_impl;
0332 template<typename T, typename L> struct bcc_class_transform_impl<T *, L>
0333 : class_transform<T,L>
0334 { };
0335
0336 template<typename T, typename D, typename L> struct bcc_class_transform
0337 : bcc_class_transform_impl
0338 < typename decode_cv
0339 < T
0340 , ::boost::function_types::detail::encode_mfp_cv<D>::value
0341 >::type
0342 , L
0343 >
0344 { };
0345
0346
0347
0348
0349
0350
0351
0352
0353
0354 template<typename Base, typename MFP, typename OrigT, typename L>
0355 struct mfp_components;
0356
0357
0358 template<typename Base, typename T, typename C, typename OrigT, typename L>
0359 struct mfp_components<Base,T C::*,OrigT,L>
0360 {
0361 private:
0362 typedef typename mpl::front<typename Base::types>::type result_type;
0363 typedef typename detail::bcc_class_transform<C,OrigT,L>::type class_type;
0364
0365 typedef mpl::vector2<result_type, class_type> result_and_class_type;
0366
0367 typedef typename
0368 mpl::advance
0369 < typename mpl::begin<typename Base::types>::type
0370 , typename mpl::if_
0371 < mpl::equal_to< typename detail::classifier<OrigT>::function_arity
0372 , typename Base::function_arity >
0373 , mpl::integral_c<int,2> , mpl::integral_c<int,1>
0374 >::type
0375 >::type
0376 from;
0377 typedef typename mpl::end<typename Base::types>::type to;
0378
0379 typedef mpl::iterator_range<from,to> param_types;
0380
0381 typedef mpl::joint_view< result_and_class_type, param_types> types_view;
0382 public:
0383
0384 typedef typename
0385 mpl::reverse_copy<types_view, mpl::front_inserter< mpl::vector0<> > >::type
0386 types;
0387
0388 typedef typename
0389 function_types::tag< Base, detail::cv_tag_mfp<OrigT> >::bits
0390 bits;
0391
0392 typedef typename Base::mask mask;
0393
0394 typedef typename detail::classifier<OrigT>::function_arity function_arity;
0395
0396 typedef components_mpl_sequence_tag tag;
0397 };
0398
0399
0400
0401 template<typename T, typename OrigT, typename L>
0402 struct components_bcc
0403 : mpl::if_
0404 < detail::represents_impl< detail::components_impl<T,L>
0405 , member_function_pointer_tag>
0406 , detail::mfp_components<detail::components_impl<T,L>,T,OrigT,L>
0407 , detail::components_impl<T,L>
0408 >::type
0409 { };
0410
0411 #endif
0412
0413 #define BOOST_FT_al_path boost/function_types/detail/components_impl
0414 #include <boost/function_types/detail/pp_loop.hpp>
0415
0416 } }
0417
0418 }
0419
0420 #include <boost/function_types/detail/components_as_mpl_sequence.hpp>
0421 #include <boost/function_types/detail/retag_default_cc.hpp>
0422
0423 #endif
0424