Boost logo

Boost-Commit :

From: chochlik_at_[hidden]
Date: 2008-06-04 12:56:31


Author: matus.chochlik
Date: 2008-06-04 12:56:30 EDT (Wed, 04 Jun 2008)
New Revision: 46126
URL: http://svn.boost.org/trac/boost/changeset/46126

Log:
Visitors can now also work on instances
Text files modified:
   sandbox/mirror/boost/mirror/traversal.hpp | 146 ++++++++++++++++++++++++++++++++-------
   sandbox/mirror/boost/mirror/visitors/sample.hpp | 40 ++++++++++
   sandbox/mirror/libs/mirror/doc/xml/mirror/_library.xml | 4 +
   sandbox/mirror/libs/mirror/example/traversal/sample_visitor.cpp | 18 +++-
   4 files changed, 173 insertions(+), 35 deletions(-)

Modified: sandbox/mirror/boost/mirror/traversal.hpp
==============================================================================
--- sandbox/mirror/boost/mirror/traversal.hpp (original)
+++ sandbox/mirror/boost/mirror/traversal.hpp 2008-06-04 12:56:30 EDT (Wed, 04 Jun 2008)
@@ -14,6 +14,8 @@
 #include <boost/mirror/algorithm/for_each.hpp>
 //
 #include <boost/ref.hpp>
+//
+#include <assert.h>
 
 namespace boost {
 namespace mirror {
@@ -24,7 +26,11 @@
 
 namespace detail {
 
- template <class MetaClass, class MetaAttributes>
+ template <
+ class MetaClass,
+ class MetaAttributes,
+ template <class> class TraversalType
+ >
         struct traversal_utils
         {
         protected:
@@ -32,8 +38,12 @@
                 class attribute_traversal
                 {
                 public:
- attribute_traversal(reference_wrapper<VisitorType> _visitor)
+ attribute_traversal(
+ reference_wrapper<VisitorType> _visitor,
+ typename MetaClass::reflected_type* _ptr_to_inst
+ )
                         : visitor(_visitor)
+ , ptr_to_inst(_ptr_to_inst)
                         {
                                 visitor.enter_attributes<MetaClass, MetaAttributes>();
                         }
@@ -46,31 +56,61 @@
                         template <class MetaAttribute>
                         void operator ()(MetaAttribute ma)
                         {
+ process_single(ma, typename VisitorType::works_on_instances());
+ }
+ private:
+ VisitorType& visitor;
+ typename MetaClass::reflected_type* ptr_to_inst;
+
+ // process single attribute WITH an instance
+ template <class MetaAttribute>
+ void process_single(MetaAttribute ma, mpl::bool_<true>)
+ {
                                 visitor.enter_attribute(ma);
- typedef MetaAttribute meta_attribute;
- typedef typename meta_attribute::type attrib_type;
- deep_traversal_of<
+ typedef typename MetaAttribute::type attrib_type;
+ assert(ptr_to_inst != 0);
+ typedef BOOST_TYPEOF(ma.get(*ptr_to_inst)) instance_type;
+ instance_type instance(ma.get(*ptr_to_inst));
+ TraversalType<
                                         BOOST_MIRROR_REFLECT_CLASS(attrib_type)
- >::accept(visitor);
+ >::accept(visitor, &instance);
+ visitor.leave_attribute(ma);
+ }
+
+ // process single attribute W/O an instance
+ template <class MetaAttribute>
+ void process_single(MetaAttribute ma, mpl::bool_<false>)
+ {
+ visitor.enter_attribute(ma);
+ typedef typename MetaAttribute::type attrib_type;
+ TraversalType<
+ BOOST_MIRROR_REFLECT_CLASS(attrib_type)
+ >::accept(visitor, 0);
                                 visitor.leave_attribute(ma);
                         }
- private:
- VisitorType& visitor;
                 };
         
                 template <class VisitorType>
                 static inline attribute_traversal<VisitorType>
- show_attribs_to(reference_wrapper<VisitorType> visitor)
+ show_attribs_to(
+ reference_wrapper<VisitorType> visitor,
+ typename MetaClass::reflected_type* ptr_to_inst
+ )
                 {
- return attribute_traversal<VisitorType>(visitor);
+ return attribute_traversal<VisitorType>(visitor, ptr_to_inst);
                 }
         
+
                 template <class VisitorType>
                 class base_class_traversal
                 {
                 public:
- base_class_traversal(reference_wrapper<VisitorType> _visitor)
+ base_class_traversal(
+ reference_wrapper<VisitorType> _visitor,
+ typename MetaClass::reflected_type* _ptr_to_inst
+ )
                         : visitor(_visitor)
+ , ptr_to_inst(_ptr_to_inst)
                         {
                                 visitor.enter_base_classes<MetaClass>();
                         }
@@ -87,18 +127,22 @@
                                 typedef MetaInheritance meta_inheritance;
                                 typedef typename meta_inheritance::meta_base_class
                                         meta_base_class;
- deep_traversal_of<meta_base_class>::accept(visitor);
+ TraversalType<meta_base_class>::accept(visitor, ptr_to_inst);
                                 visitor.leave_base_class(mbc);
                         }
                 private:
                         VisitorType& visitor;
+ typename MetaClass::reflected_type* ptr_to_inst;
                 };
 
                 template <class VisitorType>
                 static inline base_class_traversal<VisitorType>
- show_bases_to(reference_wrapper<VisitorType> visitor)
+ show_bases_to(
+ reference_wrapper<VisitorType> visitor,
+ typename MetaClass::reflected_type* ptr_to_inst
+ )
                 {
- return base_class_traversal<VisitorType>(visitor);
+ return base_class_traversal<VisitorType>(visitor, ptr_to_inst);
                 }
         };
 
@@ -107,55 +151,99 @@
 
 template <class MetaClass>
 class deep_traversal_of
-: detail::traversal_utils<MetaClass, typename MetaClass::attributes>
+: detail::traversal_utils<
+ MetaClass,
+ typename MetaClass::attributes,
+ deep_traversal_of
+>
 {
 public:
         template <class VisitorType>
- static void accept(VisitorType visitor)
+ static void accept(
+ VisitorType visitor,
+ typename MetaClass::reflected_type* ptr_to_inst = 0
+ )
         {
- do_accept(ref<VisitorType>(visitor));
+ do_accept(ref<VisitorType>(visitor), ptr_to_inst);
         }
+
         template <class VisitorType>
- static void accept(reference_wrapper<VisitorType> visitor)
+ static void accept(
+ reference_wrapper<VisitorType> visitor,
+ typename MetaClass::reflected_type* ptr_to_inst = 0
+ )
         {
- do_accept(visitor);
+ do_accept(visitor, ptr_to_inst);
         }
 private:
         template <class VisitorType>
- static void do_accept(reference_wrapper<VisitorType> visitor)
+ static void do_accept(
+ reference_wrapper<VisitorType> visitor,
+ typename MetaClass::reflected_type* ptr_to_inst
+ )
         {
                 typedef MetaClass meta_class;
                 meta_class mc;
+ // enter the type
                 visitor.get().enter_type(mc);
- for_each<typename meta_class::base_classes>(ref(show_bases_to(visitor)));
- for_each<typename meta_class::attributes>(ref(show_attribs_to(visitor)));
+ // visit the instance
+ visitor.get().visit_instance(mc, ptr_to_inst);
+ // go through the base classes
+ for_each<typename meta_class::base_classes>(
+ ref(show_bases_to(visitor, ptr_to_inst))
+ );
+ // go through the own class' attributes
+ for_each<typename meta_class::attributes>(
+ ref(show_attribs_to(visitor, ptr_to_inst))
+ );
+ // leave the type
                 visitor.get().leave_type(mc);
         }
 };
 
 template <class MetaClass>
 class flat_traversal_of
-: detail::traversal_utils<MetaClass, typename MetaClass::all_attributes>
+: detail::traversal_utils<
+ MetaClass,
+ typename MetaClass::all_attributes,
+ flat_traversal_of
+>
 {
 public:
         template <class VisitorType>
- static void accept(VisitorType visitor)
+ static void accept(
+ VisitorType visitor,
+ typename MetaClass::reflected_type* ptr_to_inst = 0
+ )
         {
- do_accept(ref<VisitorType>(visitor));
+ do_accept(ref<VisitorType>(visitor), ptr_to_inst);
         }
         template <class VisitorType>
- static void accept(reference_wrapper<VisitorType> visitor)
+ static void accept(
+ reference_wrapper<VisitorType> visitor,
+ typename MetaClass::reflected_type* ptr_to_inst = 0
+ )
         {
- do_accept(visitor);
+ do_accept(visitor, ptr_to_inst);
         }
 private:
         template <class VisitorType>
- static void do_accept(reference_wrapper<VisitorType> visitor)
+ static void do_accept(
+ reference_wrapper<VisitorType> visitor,
+ typename MetaClass::reflected_type* ptr_to_inst
+ )
         {
                 typedef MetaClass meta_class;
                 meta_class mc;
+ // enter the type
                 visitor.get().enter_type(mc);
- for_each<typename meta_class::all_attributes>(ref(show_attribs_to(visitor)));
+ // visit the instance
+ visitor.get().visit_instance(mc, ptr_to_inst);
+ // go through all of the class' attributes
+ for_each<typename meta_class::all_attributes>(
+ ref(show_attribs_to(visitor, ptr_to_inst))
+ );
+ // leave the type
                 visitor.get().leave_type(mc);
         }
 };

Modified: sandbox/mirror/boost/mirror/visitors/sample.hpp
==============================================================================
--- sandbox/mirror/boost/mirror/visitors/sample.hpp (original)
+++ sandbox/mirror/boost/mirror/visitors/sample.hpp 2008-06-04 12:56:30 EDT (Wed, 04 Jun 2008)
@@ -26,9 +26,12 @@
 namespace boost {
 namespace mirror {
 
+template <bool WorksOnInstances>
 class sample_visitor
 {
 public:
+ typedef mpl::bool_<WorksOnInstances> works_on_instances;
+
         sample_visitor(void):indent(0){ }
 
         // enter a class/type
@@ -104,7 +107,10 @@
         {
                 using namespace ::std;
                 using namespace ::boost;
- if(!is_fundamental<MetaClass::reflected_type>::value && (mirror::size<MetaAttributes>::value > 0))
+ if(
+ !is_fundamental<MetaClass::reflected_type>::value &&
+ (mirror::size<MetaAttributes>::value > 0)
+ )
                 {
                         print_indentation();
                         ++indent;
@@ -119,7 +125,10 @@
         {
                 using namespace ::std;
                 using namespace ::boost;
- if(!is_fundamental<MetaClass::reflected_type>::value && (mirror::size<MetaAttributes>::value > 0))
+ if(
+ !is_fundamental<MetaClass::reflected_type>::value &&
+ (mirror::size<MetaAttributes>::value > 0)
+ )
                 {
                         --indent;
                         print_indentation();
@@ -152,7 +161,34 @@
                 print_indentation();
                 bcout << "</attribute>" << endl;
         }
+
+ template <class MetaClass, typename InstanceType>
+ void visit_instance(MetaClass, InstanceType* ptr_to_inst)
+ {
+ print_value(
+ ptr_to_inst,
+ is_fundamental<typename MetaClass::reflected_type>()
+ );
+ }
+
 private:
+
+ template <typename Type>
+ void print_value(Type* ptr_to_inst, mpl::bool_<false>){ }
+
+ template <typename Type>
+ void print_value(Type* ptr_to_inst, mpl::bool_<true>)
+ {
+ using namespace ::std;
+ using namespace ::boost;
+ print_indentation();
+ bcout <<
+ "<value>" <<
+ *ptr_to_inst <<
+ "</value>" <<
+ endl;
+ }
+
         int indent;
         void print_indentation(void)
         {

Modified: sandbox/mirror/libs/mirror/doc/xml/mirror/_library.xml
==============================================================================
--- sandbox/mirror/libs/mirror/doc/xml/mirror/_library.xml (original)
+++ sandbox/mirror/libs/mirror/doc/xml/mirror/_library.xml 2008-06-04 12:56:30 EDT (Wed, 04 Jun 2008)
@@ -167,5 +167,9 @@
                         - Updated several things concerning visitors
                         - Tested with MSVC++ 2008 EE On Vista
                 </revision>
+ <revision id="20080604" major="0" minor="1" micro="26" author="m_ch">
+ - Visitors can now also work on instances
+ - Tested with MSVC++ 2008 EE On Vista
+ </revision>
         </revisions>
 </library>

Modified: sandbox/mirror/libs/mirror/example/traversal/sample_visitor.cpp
==============================================================================
--- sandbox/mirror/libs/mirror/example/traversal/sample_visitor.cpp (original)
+++ sandbox/mirror/libs/mirror/example/traversal/sample_visitor.cpp 2008-06-04 12:56:30 EDT (Wed, 04 Jun 2008)
@@ -172,11 +172,20 @@
         using namespace ::Test;
         //
         typedef BOOST_MIRROR_REFLECT_CLASS(H) meta_H;
+ H h;
+ h.l = 1234567890;
+ h.i = 123;
+ h.d = 456.7890123;
+ h.s = 456;
+ h.f = 78.9f;
+ h.b = false;
+ h.c = '1';
+ h.w = L'2';
         //
         bcout << "--------------------------------------------" << endl;
- deep_traversal_of<meta_H>::accept(sample_visitor());
+ deep_traversal_of<meta_H>::accept(sample_visitor<true>(), &h);
         bcout << "--------------------------------------------" << endl;
- flat_traversal_of<meta_H>::accept(sample_visitor());
+ flat_traversal_of<meta_H>::accept(sample_visitor<true>(), &h);
         bcout << "--------------------------------------------" << endl;
         //
         //
@@ -190,10 +199,11 @@
         typedef tuple<T1, T2, T3, T4, T5, T6, T7> T;
         typedef BOOST_MIRROR_REFLECT_CLASS(T) meta_T;
         //
+ //
         bcout << "--------------------------------------------" << endl;
- deep_traversal_of<meta_T>::accept(sample_visitor());
+ deep_traversal_of<meta_T>::accept(sample_visitor<false>());
         bcout << "--------------------------------------------" << endl;
- flat_traversal_of<meta_T>::accept(sample_visitor());
+ flat_traversal_of<meta_T>::accept(sample_visitor<false>());
         bcout << "--------------------------------------------" << endl;
         //
         return 0;


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