|
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