$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
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;