Boost logo

Boost-Commit :

From: chochlik_at_[hidden]
Date: 2008-04-21 12:40:26


Author: matus.chochlik
Date: 2008-04-21 12:40:25 EDT (Mon, 21 Apr 2008)
New Revision: 44700
URL: http://svn.boost.org/trac/boost/changeset/44700

Log:
Added support for accessing the types and values of inherited class member attributes
Updated support for virtual inheritance (still some minor problems though)
Updated example on virtual inheritance
Updated example on serialization (not finished, yet)
Text files modified:
   sandbox/mirror/boost/mirror/meta_attribs_base.hpp | 11 +-
   sandbox/mirror/boost/mirror/meta_attribs_getset.hpp | 16 ++-
   sandbox/mirror/boost/mirror/meta_class.hpp | 175 +++++++++++++++++++++++++++++----------
   sandbox/mirror/libs/examples/registering/virtual_bases.cpp | 33 ++++++
   sandbox/mirror/libs/examples/serialization/cube.cpp | 94 ++++++++++++++++++++
   5 files changed, 262 insertions(+), 67 deletions(-)

Modified: sandbox/mirror/boost/mirror/meta_attribs_base.hpp
==============================================================================
--- sandbox/mirror/boost/mirror/meta_attribs_base.hpp (original)
+++ sandbox/mirror/boost/mirror/meta_attribs_base.hpp 2008-04-21 12:40:25 EDT (Mon, 21 Apr 2008)
@@ -163,9 +163,10 @@
         {\
                 return context.NAME;\
         }\
- static TYPE& query(const the_class& context, mpl::int_<NUMBER>, TYPE& dest)\
+ template <typename dest_type>\
+ static dest_type& query(const the_class& context, mpl::int_<NUMBER>, dest_type& dest)\
         {\
- dest = context.NAME;\
+ dest = dest_type(context.NAME);\
                 return dest;\
         }
 
@@ -173,15 +174,15 @@
  */
 #define BOOST_MIRROR_REG_CLASS_ATTRIB_DECL_NO_GETTER(NUMBER, TYPE) \
         static void get(const the_class& context, mpl::int_<NUMBER>){ }\
- static void query(const the_class& context, mpl::int_<NUMBER>, TYPE& dest){ }
+ template <typename dest_type>\
+ static void query(const the_class& context, mpl::int_<NUMBER>, dest_type& dest){ }
 
 /** Helper macros
  */
 #define BOOST_MIRROR_REG_CLASS_ATTRIB_DECL_SIMPLE_SET(NUMBER, TYPE, NAME) \
- static call_traits<TYPE>::param_type set(the_class& context, mpl::int_<NUMBER>, call_traits<TYPE>::param_type val)\
+ static void set(the_class& context, mpl::int_<NUMBER>, call_traits<TYPE>::param_type val)\
         {\
                 context.NAME = val;\
- return val;\
         } \
         static void set(const the_class& context, mpl::int_<NUMBER>, call_traits<TYPE>::param_type val)\
         {\

Modified: sandbox/mirror/boost/mirror/meta_attribs_getset.hpp
==============================================================================
--- sandbox/mirror/boost/mirror/meta_attribs_getset.hpp (original)
+++ sandbox/mirror/boost/mirror/meta_attribs_getset.hpp 2008-04-21 12:40:25 EDT (Mon, 21 Apr 2008)
@@ -50,21 +50,24 @@
         {\
                 return const_cast<the_class&>(context).GETTER_NAME(BOOST_PP_LIST_ENUM(BOOST_PP_TUPLE_TO_LIST(ARG_COUNT, GETTER_ARGS_TUPLE)));\
         } \
- static TYPE& do_query(the_class& context, mpl::int_<NUMBER>, TYPE& dest, mpl::bool_<true>)\
+ template <typename dest_type>\
+ static dest_type& do_query(the_class& context, mpl::int_<NUMBER>, dest_type& dest, mpl::bool_<true>)\
         {\
- dest = context.GETTER_NAME(BOOST_PP_LIST_ENUM(BOOST_PP_TUPLE_TO_LIST(ARG_COUNT, GETTER_ARGS_TUPLE)));\
+ dest = dest_type(context.GETTER_NAME(BOOST_PP_LIST_ENUM(BOOST_PP_TUPLE_TO_LIST(ARG_COUNT, GETTER_ARGS_TUPLE))));\
                 return dest;\
         } \
- static TYPE& do_query(const the_class& context, mpl::int_<NUMBER>, TYPE& dest, mpl::bool_<function_types::is_member_function_pointer<BOOST_TYPEOF(&the_class::GETTER_NAME), function_types::const_qualified>::value>)\
+ template <typename dest_type>\
+ static dest_type& do_query(const the_class& context, mpl::int_<NUMBER>, dest_type& dest, mpl::bool_<function_types::is_member_function_pointer<BOOST_TYPEOF(&the_class::GETTER_NAME), function_types::const_qualified>::value>)\
         {\
- dest = const_cast<the_class&>(context).GETTER_NAME(BOOST_PP_LIST_ENUM(BOOST_PP_TUPLE_TO_LIST(ARG_COUNT, GETTER_ARGS_TUPLE)));\
+ dest = dest_type(const_cast<the_class&>(context).GETTER_NAME(BOOST_PP_LIST_ENUM(BOOST_PP_TUPLE_TO_LIST(ARG_COUNT, GETTER_ARGS_TUPLE))));\
                 return dest;\
         } \
         template <class a_class> static call_traits<TYPE>::param_type get(a_class& context, mpl::int_<NUMBER>)\
         {\
                 return do_get(context, mpl::int_<NUMBER>(), mpl::bool_<true>());\
         }\
- template <class a_class> static TYPE& query(a_class& context, mpl::int_<NUMBER>, TYPE& dest)\
+ template <class a_class, typename dest_type> \
+ static dest_type& query(a_class& context, mpl::int_<NUMBER>, dest_type& dest)\
         {\
                 return do_query(context, mpl::int_<NUMBER>(), dest, mpl::bool_<true>());\
         }
@@ -75,10 +78,9 @@
 /** Helper macro for implementing setter based set meta-class function
  */
 #define BOOST_MIRROR_REG_CLASS_ATTRIB_DECL_SETTER_ARGS(NUMBER, TYPE, SETTER_NAME, SETTER_ARGS_TUPLE, ARG_COUNT) \
- static call_traits<TYPE>::param_type set(the_class& context, mpl::int_<NUMBER>, call_traits<TYPE>::param_type val)\
+ static void set(the_class& context, mpl::int_<NUMBER>, call_traits<TYPE>::param_type val)\
         {\
                 context.SETTER_NAME(BOOST_PP_LIST_ENUM(BOOST_PP_TUPLE_TO_LIST(ARG_COUNT, SETTER_ARGS_TUPLE)));\
- return val;\
         }
 
 

Modified: sandbox/mirror/boost/mirror/meta_class.hpp
==============================================================================
--- sandbox/mirror/boost/mirror/meta_class.hpp (original)
+++ sandbox/mirror/boost/mirror/meta_class.hpp 2008-04-21 12:40:25 EDT (Mon, 21 Apr 2008)
@@ -262,17 +262,17 @@
                         struct get_base_class_attrib_owner_and_offs
                         {
                                 typedef typename meta_inheritance::
- meta_class meta_class;
+ meta_class base_meta_class;
 
- typedef typename meta_class::
+ typedef typename base_meta_class::
                                                 attributes::
                                                 type_list type_list;
 
                                 typedef typename mpl::size<
                                                 current_list
- > offset;
+ >::type offset;
                                 typedef typename mpl::pair<
- meta_class,
+ base_meta_class,
                                                 offset
> pair;
                                 
@@ -304,40 +304,10 @@
>
>::type inherited_attrib_owners_and_offsets;
 
-
- /** The count of virtually inherited attributes
- */
- typedef typename mpl::accumulate<
- typename mpl::transform<
- virtual_base_class_layout,
- get_base_class_attrib_type_list<
- mpl::_1
- >
- >::type,
- mpl::int_<0>,
- mpl::plus<
- mpl::_1,
- mpl::size< mpl::_2 >
- >
- >::type virtual_attrib_count;
-
-
- /** Is a true type if the I-th member attribute is
- * virtually inherited.
- */
- template <long I>
- struct is_virtually_inherited
- : mpl::less<
- mpl::int_<I>,
- virtual_attrib_count
- >::type { };
-
-
-
                         /** This template is used to query the return value
                          * type of the getter for the I-th member attribute
                          */
- template <long I>
+ template <int I>
                         struct result_of_get
                         {
                                 typedef typename mpl::at<
@@ -348,11 +318,11 @@
         
                 
                         /** This function is used to get the member attributes
- * base classes.
+ * from the base classes.
                           */
- template <class a_class, long I>
+ template <class a_class, int I>
                         static typename result_of_get<I>::type
- get(a_class context, mpl::int_<I> pos)
+ get(a_class context, mpl::int_<I> pos, mpl::bool_<true>)
                         {
                                 typedef typename mpl::at<
                                         typename detail::inherited_attrib_owners_and_offsets,
@@ -360,14 +330,92 @@
>::type owner_and_offset;
 
                                 typedef typename owner_and_offset::first meta_class;
- typedef typename mpl::minus<
+ typedef typename mpl::int_<mpl::minus<
                                         mpl::int_<I>,
                                         typename owner_and_offset::second
- >::type new_pos_type;
+ >::value> new_pos_type;
 
                                 return meta_class::attributes::get(context, new_pos_type());
 
                         }
+ template <class a_class, int I>
+ static typename result_of_get<I>::type
+ get(a_class context, mpl::int_<I> pos, mpl::bool_<false>)
+ {
+ typedef typename mpl::int_<mpl::minus<
+ mpl::int_<I>,
+ mpl::size<inherited_member_attrib_type_list>::type
+ >::value> new_pos_type;
+ return meta_class::attributes::get(context, new_pos_type());
+ }
+
+
+ /** This function is used to query the member attributes
+ * from the base classes.
+ */
+ template <class a_class, int I, typename dest_type>
+ static dest_type&
+ query(a_class context, mpl::int_<I> pos, dest_type& dest, mpl::bool_<true>)
+ {
+ typedef typename mpl::at<
+ typename detail::inherited_attrib_owners_and_offsets,
+ mpl::int_<I>
+ >::type owner_and_offset;
+
+ typedef typename owner_and_offset::first meta_class;
+ typedef typename mpl::int_<mpl::minus<
+ mpl::int_<I>,
+ typename owner_and_offset::second
+ >::value> new_pos_type;
+
+ return meta_class::attributes::query(context, new_pos_type(), dest);
+
+ }
+
+ template <class a_class, int I, typename dest_type>
+ static dest_type&
+ query(a_class context, mpl::int_<I> pos, dest_type& dest, mpl::bool_<false>)
+ {
+ typedef typename mpl::int_<mpl::minus<
+ mpl::int_<I>,
+ mpl::size<inherited_member_attrib_type_list>::type
+ >::value> new_pos_type;
+ return meta_class::attributes::query(context, new_pos_type(), dest);
+ }
+
+
+ /** This function is used to query the member attributes
+ * from the base classes.
+ */
+ template <class a_class, int I, typename value_type>
+ static void
+ set(a_class& context, mpl::int_<I> pos, value_type value, mpl::bool_<true>)
+ {
+ typedef typename mpl::at<
+ typename detail::inherited_attrib_owners_and_offsets,
+ mpl::int_<I>
+ >::type owner_and_offset;
+
+ typedef typename owner_and_offset::first meta_class;
+ typedef typename mpl::int_<mpl::minus<
+ mpl::int_<I>,
+ typename owner_and_offset::second
+ >::value> new_pos_type;
+
+ meta_class::attributes::set(context, new_pos_type(), value);
+ }
+
+ template <class a_class, int I, typename value_type>
+ static void
+ set(a_class& context, mpl::int_<I> pos, value_type value, mpl::bool_<false>)
+ {
+ typedef typename mpl::int_<mpl::minus<
+ mpl::int_<I>,
+ mpl::size<inherited_member_attrib_type_list>::type
+ >::value> new_pos_type;
+ meta_class::attributes::set(context, new_pos_type(), value);
+ }
+
                 }; // struct detail
                 
                 /** The list of inherited attribute types
@@ -387,18 +435,51 @@
                  */
                 struct size : public mpl::size<type_list> { };
                 
- /**
+ /** Gets the value of the I-th member (including
+ * the inherited ones)
                  */
- template <class a_class, long I>
+ template <class a_class, int I>
                 static typename detail::template result_of_get<I>::type
                 get(a_class context, mpl::int_<I> pos)
                 {
- return detail::get(
- context,
- pos
- );
+ typedef typename mpl::less<
+ mpl::int_<I>,
+ inherited_size
+ >::type is_inherited;
+
+ return detail::get(context, pos, is_inherited());
+ }
+
+ /** Queries the value of the I-th member (including
+ * the inherited ones)
+ */
+ template <class a_class, int I, typename dest_type>
+ static dest_type&
+ query(a_class context, mpl::int_<I> pos, dest_type& dest)
+ {
+ typedef typename mpl::less<
+ mpl::int_<I>,
+ inherited_size
+ >::type is_inherited;
+
+ return detail::query(context, pos, dest, is_inherited());
+ }
+
+ /** Sets the value of the I-th member (including
+ * the inherited ones)
+ */
+ template <class a_class, int I, typename value_type>
+ static void
+ set(a_class& context, mpl::int_<I> pos, value_type value)
+ {
+ typedef typename mpl::less<
+ mpl::int_<I>,
+ inherited_size
+ >::type is_inherited;
+
+ detail::set(context, pos, value, is_inherited());
                 }
- }; // all_attrbutes
+ }; // all_attributes
 
 };
 

Modified: sandbox/mirror/libs/examples/registering/virtual_bases.cpp
==============================================================================
--- sandbox/mirror/libs/examples/registering/virtual_bases.cpp (original)
+++ sandbox/mirror/libs/examples/registering/virtual_bases.cpp 2008-04-21 12:40:25 EDT (Mon, 21 Apr 2008)
@@ -255,13 +255,38 @@
         t.c = '9';
         t.w = L'0';
         //
- bcout << meta_T::all_attributes::get(t, mpl::int_<0>()) << endl;
+ // the values of all attributes can be accessed via get() ...
         //
- bcout << "--------------------------------------------" << endl;
+ assert(t.l == meta_T::all_attributes::get(t, mpl::int_<0>()));
+ assert(t.i == meta_T::all_attributes::get(t, mpl::int_<1>()));
+ assert(t.d == meta_T::all_attributes::get(t, mpl::int_<2>()));
+ assert(t.s == meta_T::all_attributes::get(t, mpl::int_<3>()));
+ assert(t.f == meta_T::all_attributes::get(t, mpl::int_<4>()));
+ assert(t.b == meta_T::all_attributes::get(t, mpl::int_<5>()));
+ assert(t.c == meta_T::all_attributes::get(t, mpl::int_<6>()));
+ assert(t.w == meta_T::all_attributes::get(t, mpl::int_<7>()));
+ //
+ // ... they can be queried using query() ...
+ //
+ int dest_for_f = 0;
+ assert(int(t.f) == meta_T::all_attributes::query(t, mpl::int_<4>(), dest_for_f));
+ wchar_t dest_for_w = L'1';
+ assert(t.w == meta_T::all_attributes::query(t, mpl::int_<7>(), dest_for_w));
         //
- bcout << meta_T::all_attributes::detail::is_virtually_inherited<4>::value << endl;
- bcout << meta_T::all_attributes::detail::is_virtually_inherited<5>::value << endl;
+ // ... and set
         //
+ meta_T::all_attributes::set(t, mpl::int_<0>(), 2345L);
+ assert(t.l == 2345L);
+ meta_T::all_attributes::set(t, mpl::int_<2>(), 456.7);
+ assert(t.d == 456.7);
+ meta_T::all_attributes::set(t, mpl::int_<4>(), 789.0f);
+ assert(t.f == 789.0f);
+ meta_T::all_attributes::set(t, mpl::int_<5>(), false);
+ assert(t.b == false);
+ meta_T::all_attributes::set(t, mpl::int_<7>(), L'A');
+ assert(t.w == L'A');
+ //
+ bcout << "--------------------------------------------" << endl;
         //
         return 0;
 }

Modified: sandbox/mirror/libs/examples/serialization/cube.cpp
==============================================================================
--- sandbox/mirror/libs/examples/serialization/cube.cpp (original)
+++ sandbox/mirror/libs/examples/serialization/cube.cpp 2008-04-21 12:40:25 EDT (Mon, 21 Apr 2008)
@@ -20,6 +20,10 @@
 #include <boost/mpl/size.hpp>
 #include <boost/mpl/at.hpp>
 
+#include <fstream>
+#include <boost/archive/xml_iarchive.hpp>
+#include <boost/archive/xml_oarchive.hpp>
+
 #include <boost/char_type_switch/iostream.hpp>
 
 #include <boost/mirror/meta_namespace.hpp>
@@ -82,6 +86,41 @@
         private:
         };
 
+ // a cube
+ class Cube
+ {
+ public:
+ typedef Vector::float_type float_type;
+ //
+ Cube(float_type _width = 1.0f, float_type _height = 1.0f, float_type _depth = 1.0f)
+ : lbb(-_width/2.0f, -_height/2.0f, -_depth/2.0f)
+ , lbf(-_width/2.0f, -_height/2.0f, _depth/2.0f)
+ , ltb(-_width/2.0f, _height/2.0f, -_depth/2.0f)
+ , ltf(-_width/2.0f, _height/2.0f, _depth/2.0f)
+ , rbb( _width/2.0f, -_height/2.0f, -_depth/2.0f)
+ , rbf( _width/2.0f, -_height/2.0f, _depth/2.0f)
+ , rtb( _width/2.0f, _height/2.0f, -_depth/2.0f)
+ , rtf( _width/2.0f, _height/2.0f, _depth/2.0f)
+ { }
+ private:
+ // left-bottom-back
+ Vector lbb;
+ // left-bottom-front
+ Vector lbf;
+ // left-top-back
+ Vector ltb;
+ // left-top-front
+ Vector ltf;
+ // right-bottom-back
+ Vector rbb;
+ // right-bottom-front
+ Vector rbf;
+ // right-top-back
+ Vector rtb;
+ // right-top-front
+ Vector rtf;
+ };
+
 } // namespace Graphics
 
 
@@ -138,8 +177,54 @@
         )
 BOOST_MIRROR_REG_CLASS_ATTRIBS_END
 
+/** Support for serialization
+ */
+
+template <class Class>
+struct to_be_loaded
+{
+ to_be_loaded(Class& _inst):inst(_inst){ }
+ Class& inst;
+};
+
+template <class Class>
+struct to_be_saved
+{
+ to_be_saved(const Class& _inst):inst(_inst){ }
+ const Class& inst;
+};
+
+template<class Archive, class Class>
+void load(Archive & ar, Class & c, const unsigned int version)
+{
+ typedef BOOST_MIRROR_REFLECT_CLASS(Class) meta_Class;
+}
+
+template<class Archive, class Class>
+void save(Archive & ar, const Class & c, const unsigned int version)
+{
+ typedef BOOST_MIRROR_REFLECT_CLASS(Class) meta_Class;
+}
+
 
 } // namespace mirror
+
+namespace serialization {
+
+template<class Archive, class Class>
+void serialize(Archive & ar, mirror::to_be_saved<Class> dst, const unsigned int version)
+{
+ mirror::save(ar, dst.inst, version);
+}
+
+template<class Archive, class Class>
+void serialize(Archive & ar, mirror::to_be_loaded<Class> src, const unsigned int version)
+{
+ mirror::load(ar, src.inst, version);
+}
+
+
+} // namespace serialization
 } // namespace boost
 
 int main(void)
@@ -150,12 +235,13 @@
         //
         using ::Graphics::Coords;
         using ::Graphics::Vector;
+ using ::Graphics::Cube;
+ //
+ Cube c1(2.0f, 2.0f, 2.0f), c2;
         //
- typedef BOOST_MIRROR_REFLECT_CLASS(Vector) meta_Vector;
+ boost::archive::xml_oarchive oa(cout);
         //
- bcout << meta_Vector::base_classes::size::value << endl;
- bcout << meta_Vector::attributes::size::value << endl;
- //bcout << meta_Vector::all_attributes::size::value << endl;
+ oa << BOOST_SERIALIZATION_NVP(to_be_saved<Cube>(c1));
         //
         //
         bcout << "Finished" << endl;


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk