Warning, file /include/boost/python/object/class_metadata.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 #ifndef boost_python_object_class_metadata_hpp_
0008 #define boost_python_object_class_metadata_hpp_
0009
0010 #include <boost/python/converter/shared_ptr_from_python.hpp>
0011 #include <boost/python/object/inheritance.hpp>
0012 #include <boost/python/object/class_wrapper.hpp>
0013 #include <boost/python/object/make_instance.hpp>
0014 #include <boost/python/object/value_holder.hpp>
0015 #include <boost/python/object/pointer_holder.hpp>
0016 #include <boost/python/object/make_ptr_instance.hpp>
0017
0018 #include <boost/python/detail/force_instantiate.hpp>
0019 #include <boost/python/detail/not_specified.hpp>
0020 #include <boost/python/detail/type_traits.hpp>
0021
0022 #include <boost/python/has_back_reference.hpp>
0023 #include <boost/python/bases.hpp>
0024
0025 #include <boost/mpl/if.hpp>
0026 #include <boost/mpl/eval_if.hpp>
0027 #include <boost/mpl/bool.hpp>
0028 #include <boost/mpl/or.hpp>
0029 #include <boost/mpl/identity.hpp>
0030 #include <boost/mpl/for_each.hpp>
0031 #include <boost/mpl/placeholders.hpp>
0032 #include <boost/mpl/single_view.hpp>
0033
0034 #include <boost/mpl/assert.hpp>
0035
0036 #include <boost/noncopyable.hpp>
0037 #include <boost/detail/workaround.hpp>
0038
0039 namespace boost { namespace python { namespace objects {
0040
0041 BOOST_PYTHON_DECL
0042 void copy_class_object(type_info const& src, type_info const& dst);
0043
0044
0045
0046
0047 template <class Derived>
0048 struct register_base_of
0049 {
0050 template <class Base>
0051 inline void operator()(Base*) const
0052 {
0053 BOOST_MPL_ASSERT_NOT((boost::python::detail::is_same<Base,Derived>));
0054
0055
0056 register_dynamic_id<Base>();
0057
0058
0059 register_conversion<Derived,Base>(false);
0060
0061
0062 this->register_downcast((Base*)0, boost::python::detail::is_polymorphic<Base>());
0063 }
0064
0065 private:
0066 static inline void register_downcast(void*, boost::python::detail::false_) {}
0067
0068 template <class Base>
0069 static inline void register_downcast(Base*, boost::python::detail::true_)
0070 {
0071 register_conversion<Base, Derived>(true);
0072 }
0073
0074 };
0075
0076
0077
0078
0079
0080
0081 template <class T, class Bases>
0082 inline void register_shared_ptr_from_python_and_casts(T*, Bases)
0083 {
0084
0085 python::detail::force_instantiate(converter::shared_ptr_from_python<T, boost::shared_ptr>());
0086 #if !defined(BOOST_NO_CXX11_SMART_PTR)
0087 python::detail::force_instantiate(converter::shared_ptr_from_python<T, std::shared_ptr>());
0088 #endif
0089
0090
0091
0092
0093
0094 register_dynamic_id<T>();
0095 mpl::for_each(register_base_of<T>(), (Bases*)0, (boost::python::detail::add_pointer<mpl::_>*)0);
0096 }
0097
0098
0099
0100
0101 template <class T, class Prev>
0102 struct select_held_type
0103 : mpl::if_<
0104 mpl::or_<
0105 python::detail::specifies_bases<T>
0106 , boost::python::detail::is_same<T,noncopyable>
0107 >
0108 , Prev
0109 , T
0110 >
0111 {
0112 };
0113
0114 template <
0115 class T
0116 , class X1
0117 , class X2
0118 , class X3
0119 >
0120 struct class_metadata
0121 {
0122
0123
0124
0125
0126
0127
0128
0129 typedef typename select_held_type<
0130 X1
0131 , typename select_held_type<
0132 X2
0133 , typename select_held_type<
0134 X3
0135 , python::detail::not_specified
0136 >::type
0137 >::type
0138 >::type held_type_arg;
0139
0140
0141 typedef typename python::detail::select_bases<
0142 X1
0143 , typename python::detail::select_bases<
0144 X2
0145 , typename python::detail::select_bases<
0146 X3
0147 , python::bases<>
0148 >::type
0149 >::type
0150 >::type bases;
0151
0152 typedef mpl::or_<
0153 boost::python::detail::is_same<X1,noncopyable>
0154 , boost::python::detail::is_same<X2,noncopyable>
0155 , boost::python::detail::is_same<X3,noncopyable>
0156 > is_noncopyable;
0157
0158
0159
0160
0161
0162
0163 typedef typename mpl::if_<
0164 boost::python::detail::is_same<held_type_arg,python::detail::not_specified>, T, held_type_arg
0165 >::type held_type;
0166
0167
0168 typedef mpl::bool_<boost::python::detail::is_convertible<held_type*,T*>::value> use_value_holder;
0169
0170
0171
0172 typedef typename mpl::eval_if<
0173 use_value_holder
0174 , mpl::identity<held_type>
0175 , pointee<held_type>
0176 >::type wrapped;
0177
0178
0179 typedef mpl::bool_<
0180 mpl::or_<
0181 has_back_reference<T>
0182 , boost::python::detail::is_same<held_type_arg,T>
0183 , is_base_and_derived<T,wrapped>
0184 >::value
0185 > use_back_reference;
0186
0187
0188 typedef typename mpl::eval_if<
0189 use_back_reference
0190 , mpl::if_<
0191 use_value_holder
0192 , value_holder_back_reference<T, wrapped>
0193 , pointer_holder_back_reference<held_type,T>
0194 >
0195 , mpl::if_<
0196 use_value_holder
0197 , value_holder<T>
0198 , pointer_holder<held_type,wrapped>
0199 >
0200 >::type holder;
0201
0202 inline static void register_()
0203 {
0204 class_metadata::register_aux((T*)0);
0205 }
0206
0207 private:
0208 template <class T2>
0209 inline static void register_aux(python::wrapper<T2>*)
0210 {
0211 typedef typename mpl::not_<boost::python::detail::is_same<T2,wrapped> >::type use_callback;
0212 class_metadata::register_aux2((T2*)0, use_callback());
0213 }
0214
0215 inline static void register_aux(void*)
0216 {
0217 typedef typename is_base_and_derived<T,wrapped>::type use_callback;
0218 class_metadata::register_aux2((T*)0, use_callback());
0219 }
0220
0221 template <class T2, class Callback>
0222 inline static void register_aux2(T2*, Callback)
0223 {
0224 objects::register_shared_ptr_from_python_and_casts((T2*)0, bases());
0225 class_metadata::maybe_register_callback_class((T2*)0, Callback());
0226
0227 class_metadata::maybe_register_class_to_python((T2*)0, is_noncopyable());
0228
0229 class_metadata::maybe_register_pointer_to_python(
0230 (T2*)0, (use_value_holder*)0, (use_back_reference*)0);
0231 }
0232
0233
0234
0235
0236
0237 inline static void maybe_register_pointer_to_python(...) {}
0238
0239 #ifndef BOOST_PYTHON_NO_PY_SIGNATURES
0240 inline static void maybe_register_pointer_to_python(void*,void*,mpl::true_*)
0241 {
0242 objects::copy_class_object(python::type_id<T>(), python::type_id<back_reference<T const &> >());
0243 objects::copy_class_object(python::type_id<T>(), python::type_id<back_reference<T &> >());
0244 }
0245 #endif
0246
0247 template <class T2>
0248 inline static void maybe_register_pointer_to_python(T2*, mpl::false_*, mpl::false_*)
0249 {
0250 python::detail::force_instantiate(
0251 objects::class_value_wrapper<
0252 held_type
0253 , make_ptr_instance<T2, pointer_holder<held_type, T2> >
0254 >()
0255 );
0256 #ifndef BOOST_PYTHON_NO_PY_SIGNATURES
0257
0258 objects::copy_class_object(python::type_id<T2>(), python::type_id<held_type>());
0259 #endif
0260 }
0261
0262
0263
0264 inline static void maybe_register_class_to_python(void*, mpl::true_) {}
0265
0266
0267 template <class T2>
0268 inline static void maybe_register_class_to_python(T2*, mpl::false_)
0269 {
0270 python::detail::force_instantiate(class_cref_wrapper<T2, make_instance<T2, holder> >());
0271 #ifndef BOOST_PYTHON_NO_PY_SIGNATURES
0272
0273 objects::copy_class_object(python::type_id<T2>(), python::type_id<held_type>());
0274 #endif
0275 }
0276
0277
0278
0279
0280 inline static void maybe_register_callback_class(void*, mpl::false_) {}
0281
0282 template <class T2>
0283 inline static void maybe_register_callback_class(T2*, mpl::true_)
0284 {
0285 objects::register_shared_ptr_from_python_and_casts(
0286 (wrapped*)0, mpl::single_view<T2>());
0287
0288 objects::copy_class_object(python::type_id<T2>(), python::type_id<wrapped>());
0289 }
0290 };
0291
0292 }}}
0293
0294 #endif