Boost logo

Boost-Commit :

From: chochlik_at_[hidden]
Date: 2008-06-19 10:45:04


Author: matus.chochlik
Date: 2008-06-19 10:45:02 EDT (Thu, 19 Jun 2008)
New Revision: 46512
URL: http://svn.boost.org/trac/boost/changeset/46512

Log:
Rewrite of the traversal contexts
Added first two meta-path axes (self and ancestors)

Added:
   sandbox/mirror/boost/mirror/meta_path/
   sandbox/mirror/boost/mirror/meta_path/ancestors.hpp (contents, props changed)
   sandbox/mirror/boost/mirror/meta_path/at.hpp (contents, props changed)
   sandbox/mirror/boost/mirror/meta_path/node_context.hpp (contents, props changed)
   sandbox/mirror/boost/mirror/meta_path/self.hpp (contents, props changed)
   sandbox/mirror/boost/mirror/meta_path/size.hpp (contents, props changed)
Text files modified:
   sandbox/mirror/boost/mirror/detail/traversal.hpp | 122 +++++++++++++++++++++++++++++----------
   sandbox/mirror/boost/mirror/traversal.hpp | 48 +++++++++++---
   sandbox/mirror/boost/mirror/visitors/sample.hpp | 7 ++
   sandbox/mirror/libs/mirror/doc/xml/mirror/_library.xml | 4
   sandbox/mirror/libs/mirror/example/traversal/sample_visitor.cpp | 3
   5 files changed, 140 insertions(+), 44 deletions(-)

Modified: sandbox/mirror/boost/mirror/detail/traversal.hpp
==============================================================================
--- sandbox/mirror/boost/mirror/detail/traversal.hpp (original)
+++ sandbox/mirror/boost/mirror/detail/traversal.hpp 2008-06-19 10:45:02 EDT (Thu, 19 Jun 2008)
@@ -12,6 +12,7 @@
 
 #include <boost/mirror/meta_class.hpp>
 #include <boost/mirror/algorithm/for_each.hpp>
+#include <boost/mirror/meta_path/node_context.hpp>
 //
 #include <boost/ref.hpp>
 //
@@ -21,22 +22,22 @@
 namespace mirror {
 
 
-template <class MetaClass, class Context> class deep_traversal_of;
-template <class MetaClass, class Context> class flat_traversal_of;
+template <class MetaClass, class NodePath> class deep_traversal_of;
+template <class MetaClass, class NodePath> class flat_traversal_of;
 
 namespace detail {
 
         template <
                 class MetaClass,
- class Context,
+ class NodePath,
                 class MetaAttributes,
                 template <class, class> class TraversalType
>
         struct traversal_utils
         {
         protected:
- typedef typename mpl::push_back<Context, MetaClass>::type
- ClassContext;
+ typedef typename mpl::push_back<NodePath, MetaClass>::type
+ ClassNodePath;
 
                 template <class VisitorType>
                 class attribute_traversal
@@ -52,7 +53,10 @@
                                 visitor.enter_attributes(
                                         MetaClass(),
                                         MetaAttributes(),
- ClassContext()
+ meta_path::make_node_context(
+ ClassNodePath(),
+ MetaAttributes()
+ )
                                 );
                         }
         
@@ -61,7 +65,10 @@
                                 visitor.leave_attributes(
                                         MetaClass(),
                                         MetaAttributes(),
- ClassContext()
+ meta_path::make_node_context(
+ ClassNodePath(),
+ MetaAttributes()
+ )
                                 );
                         }
         
@@ -70,14 +77,14 @@
                         {
                                 // update the traversal context
                                 typename mpl::push_back<
- ClassContext,
+ ClassNodePath,
                                         MetaAttributes
- >::type ctx;
+ >::type path;
                                 //
                                 // process a single attribute
                                 process_single(
                                         ma,
- ctx,
+ path,
                                         typename VisitorType::works_on_instances()
                                 );
                         }
@@ -86,15 +93,21 @@
                         typename MetaClass::reflected_type* ptr_to_inst;
 
                         // process single attribute WITH an instance
- template <class MetaAttribute, class AttribsContext>
+ template <class MetaAttribute, class AttribsNodePath>
                         void process_single(
                                 MetaAttribute ma,
- AttribsContext ctx,
+ AttribsNodePath path,
                                 mpl::bool_<true>
                         ) const
                         {
                                 // enter the attribute
- visitor.enter_attribute(ma, ctx);
+ visitor.enter_attribute(
+ ma,
+ meta_path::make_node_context(
+ path,
+ ma
+ )
+ );
                                 //
                                 // get the type of the attribute
                                 typedef typename MetaAttribute::type attrib_type;
@@ -110,38 +123,56 @@
                                 TraversalType<
                                         BOOST_MIRROR_REFLECT_CLASS(attrib_type),
                                         typename mpl::push_back<
- AttribsContext,
+ AttribsNodePath,
                                                 MetaAttribute
>::type
>::accept(visitor, &instance);
                                 //
                                 // leave the attribute
- visitor.leave_attribute(ma, ctx);
+ visitor.leave_attribute(
+ ma,
+ meta_path::make_node_context(
+ path,
+ ma
+ )
+ );
                         }
 
                         // process single attribute W/O an instance
- template <class MetaAttribute, class AttribsContext>
+ template <class MetaAttribute, class AttribsNodePath>
                         void process_single(
                                 MetaAttribute ma,
- AttribsContext ctx,
+ AttribsNodePath path,
                                 mpl::bool_<false>
                         ) const
                         {
                                 // enter the attribute
- visitor.enter_attribute(ma, ctx);
+ visitor.enter_attribute(
+ ma,
+ meta_path::make_node_context(
+ path,
+ ma
+ )
+ );
                                 //
                                 // traverse the attributes
                                 typedef typename MetaAttribute::type attrib_type;
                                 TraversalType<
                                         BOOST_MIRROR_REFLECT_CLASS(attrib_type),
                                         typename mpl::push_back<
- AttribsContext,
+ AttribsNodePath,
                                                 MetaAttribute
>::type
>::accept(visitor, 0);
                                 //
                                 // leave the attributes
- visitor.leave_attribute(ma, ctx);
+ visitor.leave_attribute(
+ ma,
+ meta_path::make_node_context(
+ path,
+ ma
+ )
+ );
                         }
                 };
         
@@ -170,7 +201,10 @@
                         {
                                 visitor.enter_base_classes(
                                         MetaClass(),
- ClassContext()
+ meta_path::make_node_context(
+ ClassNodePath(),
+ MetaClass::base_classes()
+ )
                                 );
                         }
         
@@ -178,17 +212,30 @@
                         {
                                 visitor.leave_base_classes(
                                         MetaClass(),
- ClassContext()
+ meta_path::make_node_context(
+ ClassNodePath(),
+ MetaClass::base_classes()
+ )
                                 );
                         }
         
                         template <class MetaInheritance>
                         void operator ()(MetaInheritance mbc) const
                         {
- ClassContext ctx;
+ typedef typename mpl::push_back<
+ ClassNodePath,
+ MetaClass::base_classes
+ >::type BaseClassesNodePath;
+ BaseClassesNodePath path;
                                 //
                                 // enter the base cass
- visitor.enter_base_class(mbc, ctx);
+ visitor.enter_base_class(
+ mbc,
+ meta_path::make_node_context(
+ path,
+ mbc
+ )
+ );
                                 //
                                 // get the meta-class of the base class
                                 typedef typename MetaInheritance::meta_base_class
@@ -197,12 +244,18 @@
                                 TraversalType<
                                         meta_base_class,
                                         typename mpl::push_back<
- ClassContext,
+ BaseClassesNodePath,
                                                 MetaInheritance
>::type
>::accept(visitor, ptr_to_inst);
                                 // leave the base class
- visitor.leave_base_class(mbc, ctx);
+ visitor.leave_base_class(
+ mbc,
+ meta_path::make_node_context(
+ path,
+ mbc
+ )
+ );
                         }
                 private:
                         VisitorType& visitor;
@@ -227,14 +280,14 @@
                 inline static void lead_to_instance(
                         reference_wrapper<VisitorType> visitor,
                         MetaClass mc,
- Context ctx,
+ NodePath path,
                         InstanceType* ptr_to_inst
                 )
                 {
                         do_lead_to_instance(
                                 visitor,
                                 mc,
- ctx,
+ path,
                                 ptr_to_inst,
                                 typename VisitorType::works_on_instances()
                         );
@@ -248,7 +301,7 @@
                 inline static void do_lead_to_instance(
                         reference_wrapper<VisitorType> visitor,
                         MetaClass,
- Context,
+ NodePath,
                         InstanceType* ptr_to_inst,
                         mpl::bool_<false>
                 ){ }
@@ -260,12 +313,19 @@
                 inline static void do_lead_to_instance(
                         reference_wrapper<VisitorType> visitor,
                         MetaClass mc,
- Context ctx,
+ NodePath path,
                         InstanceType* ptr_to_inst,
                         mpl::bool_<true>
                 )
                 {
- visitor.get().visit_instance(mc, ctx, ptr_to_inst);
+ visitor.get().visit_instance(
+ mc,
+ meta_path::make_node_context(
+ path,
+ mc
+ ),
+ ptr_to_inst
+ );
                 }
 
         };

Added: sandbox/mirror/boost/mirror/meta_path/ancestors.hpp
==============================================================================
--- (empty file)
+++ sandbox/mirror/boost/mirror/meta_path/ancestors.hpp 2008-06-19 10:45:02 EDT (Thu, 19 Jun 2008)
@@ -0,0 +1,108 @@
+/**
+ * \file boost/mirror/meta_path/ancestors.hpp
+ *
+ * Copyright 2008 Matus Chochlik. Distributed under the Boost
+ * Software License, Version 1.0. (See accompanying file
+ * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+#ifndef BOOST_MIRROR_META_PATH_ANCESTORS_HPP
+#define BOOST_MIRROR_META_PATH_ANCESTORS_HPP
+
+#include <boost/mirror/meta_path/node_context.hpp>
+#include <boost/mpl/vector.hpp>
+#include <boost/mpl/pair.hpp>
+#include <boost/mpl/accumulate.hpp>
+#include <boost/mpl/front.hpp>
+#include <boost/mpl/pop_front.hpp>
+#include <boost/mpl/back.hpp>
+#include <boost/mpl/push_back.hpp>
+
+namespace boost {
+namespace mirror {
+namespace meta_path {
+
+namespace detail {
+
+ template <class NodeContext>
+ struct ancestors_base
+ {
+ private:
+ typedef typename NodeContext::paths_and_nodes
+ passed_paths_and_nodes;
+ // the nodes and their paths
+ struct append_path_and_node
+ {
+ template <class PathsAndNodes, class Node>
+ struct apply
+ {
+ typedef typename mpl::push_back<
+ PathsAndNodes,
+ mpl::pair<
+ typename mpl::push_back<
+ typename mpl::first<
+ typename mpl::back<PathsAndNodes>::type
+ >::type,
+ typename mpl::second<
+ typename mpl::back<PathsAndNodes>::type
+ >::type
+ >::type,
+ Node
+ >
+ >::type type;
+ };
+ };
+
+ struct process_single_path_and_node
+ {
+ template <class PathsAndNodes, class Pair>
+ struct apply
+ {
+ typedef typename mpl::accumulate<
+ // the given paths and nodes without the
+ // the root
+ typename mpl::pop_front<
+ typename mpl::first<Pair>::type
+ >::type,
+ // a pair containing an empty path and
+ // the root node
+ typename mpl::push_back<
+ PathsAndNodes,
+ mpl::pair<
+ mpl::vector0<>,
+ mpl::front<
+ typename mpl::first<Pair>::type
+ >
+ >
+ >::type,
+ // appends a new path/node pair to the state
+ append_path_and_node
+ >::type type;
+ };
+ };
+
+ public:
+ typedef typename mpl::accumulate<
+ passed_paths_and_nodes,
+ mpl::vector0<>,
+ process_single_path_and_node
+ >::type paths_and_nodes;
+ };
+
+} // namespace detail
+
+/** A nodeset containing ancestor nodes of the
+ * given node context
+ */
+template <class NodeContext>
+struct ancestors : node_set<detail::ancestors_base<NodeContext> >
+{
+ typedef ancestors<NodeContext> type;
+};
+
+} // namespace meta_path
+} // namespace mirror
+} // namespace boost
+
+#endif //include guard
+

Added: sandbox/mirror/boost/mirror/meta_path/at.hpp
==============================================================================
--- (empty file)
+++ sandbox/mirror/boost/mirror/meta_path/at.hpp 2008-06-19 10:45:02 EDT (Thu, 19 Jun 2008)
@@ -0,0 +1,30 @@
+/**
+ * \file boost/mirror/meta_path/at.hpp
+ *
+ * Copyright 2008 Matus Chochlik. Distributed under the Boost
+ * Software License, Version 1.0. (See accompanying file
+ * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+#ifndef BOOST_MIRROR_META_PATH_AT_HPP
+#define BOOST_MIRROR_META_PATH_AT_HPP
+
+#include <boost/mirror/meta_path/node_context.hpp>
+#include <boost/mpl/at.hpp>
+
+namespace boost {
+namespace mirror {
+
+namespace meta_path {
+
+/** Returns the i-th node in the nodeset
+ */
+template <class NodeSet, class Position>
+struct at : public mpl::at<typename NodeSet::nodes, Position> { };
+
+} // namespace meta_path
+} // namespace mirror
+} // namespace boost
+
+#endif //include guard
+

Added: sandbox/mirror/boost/mirror/meta_path/node_context.hpp
==============================================================================
--- (empty file)
+++ sandbox/mirror/boost/mirror/meta_path/node_context.hpp 2008-06-19 10:45:02 EDT (Thu, 19 Jun 2008)
@@ -0,0 +1,59 @@
+/**
+ * \file boost/mirror/meta_path/node_context.hpp
+ *
+ * Copyright 2008 Matus Chochlik. Distributed under the Boost
+ * Software License, Version 1.0. (See accompanying file
+ * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+#ifndef BOOST_MIRROR_META_PATH_NODE_CONTEXT_HPP
+#define BOOST_MIRROR_META_PATH_NODE_CONTEXT_HPP
+
+#include <boost/mpl/transform_view.hpp>
+#include <boost/mpl/pair.hpp>
+#include <boost/mpl/vector.hpp>
+
+namespace boost {
+namespace mirror {
+
+namespace meta_path {
+
+/** Context for a 'node' (meta_class/meta_attributes/meta_attribute/
+ * meta_inheritance/... in a meta_class traversal
+ *
+ * This template is instantiated by the class traversals
+ * and passed to the visitors
+ */
+template <class FullPath, class MetaObject>
+struct node_context
+{
+ typedef mpl::vector1<
+ mpl::pair<
+ FullPath,
+ MetaObject
+ >
+ > paths_and_nodes;
+};
+
+template <class FullPath, class MetaObject>
+node_context<FullPath, MetaObject>
+make_node_context(FullPath, MetaObject)
+{
+ return node_context<FullPath, MetaObject>();
+}
+
+template <class NodeContext>
+struct node_set
+{
+ typedef typename mpl::transform_view<
+ typename NodeContext::paths_and_nodes,
+ mpl::first< mpl::_ >
+ >::type nodes;
+};
+
+} // namespace meta_path
+} // namespace mirror
+} // namespace boost
+
+#endif //include guard
+

Added: sandbox/mirror/boost/mirror/meta_path/self.hpp
==============================================================================
--- (empty file)
+++ sandbox/mirror/boost/mirror/meta_path/self.hpp 2008-06-19 10:45:02 EDT (Thu, 19 Jun 2008)
@@ -0,0 +1,45 @@
+/**
+ * \file boost/mirror/meta_path/self.hpp
+ *
+ * Copyright 2008 Matus Chochlik. Distributed under the Boost
+ * Software License, Version 1.0. (See accompanying file
+ * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+#ifndef BOOST_MIRROR_META_PATH_SELF_HPP
+#define BOOST_MIRROR_META_PATH_SELF_HPP
+
+#include <boost/mirror/meta_path/node_context.hpp>
+
+namespace boost {
+namespace mirror {
+namespace meta_path {
+
+namespace detail {
+
+ template <class NodeContext>
+ struct self_base
+ {
+ // the nodes and their paths
+ typedef typename NodeContext::paths_and_nodes
+ paths_and_nodes;
+ };
+
+} // namespace detail
+
+/** A nodeset containing only the nodes of the
+ * given node context
+ */
+template <class NodeContext>
+struct self : node_set<detail::self_base<NodeContext> >
+{
+ //
+ typedef self<NodeContext> type;
+};
+
+} // namespace meta_path
+} // namespace mirror
+} // namespace boost
+
+#endif //include guard
+

Added: sandbox/mirror/boost/mirror/meta_path/size.hpp
==============================================================================
--- (empty file)
+++ sandbox/mirror/boost/mirror/meta_path/size.hpp 2008-06-19 10:45:02 EDT (Thu, 19 Jun 2008)
@@ -0,0 +1,30 @@
+/**
+ * \file boost/mirror/meta_path/size.hpp
+ *
+ * Copyright 2008 Matus Chochlik. Distributed under the Boost
+ * Software License, Version 1.0. (See accompanying file
+ * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+#ifndef BOOST_MIRROR_META_PATH_SIZE_HPP
+#define BOOST_MIRROR_META_PATH_SIZE_HPP
+
+#include <boost/mirror/meta_path/node_context.hpp>
+#include <boost/mpl/size.hpp>
+
+namespace boost {
+namespace mirror {
+
+namespace meta_path {
+
+/** Size - count of nodes in a node set
+ */
+template <class NodeSet>
+struct size : public mpl::size<typename NodeSet::nodes> { };
+
+} // namespace meta_path
+} // namespace mirror
+} // namespace boost
+
+#endif //include guard
+

Modified: sandbox/mirror/boost/mirror/traversal.hpp
==============================================================================
--- sandbox/mirror/boost/mirror/traversal.hpp (original)
+++ sandbox/mirror/boost/mirror/traversal.hpp 2008-06-19 10:45:02 EDT (Thu, 19 Jun 2008)
@@ -16,11 +16,11 @@
 namespace mirror {
 
 
-template <class MetaClass, class Context = mpl::vector0<> >
+template <class MetaClass, class NodePath = mpl::vector0<> >
 class deep_traversal_of
 : detail::traversal_utils<
         MetaClass,
- Context,
+ NodePath,
         typename MetaClass::attributes,
         deep_traversal_of
>
@@ -51,11 +51,17 @@
         )
         {
                 MetaClass mc;
- Context ctx;
+ NodePath path;
                 // enter the type
- visitor.get().enter_type(mc, ctx);
+ visitor.get().enter_type(
+ mc,
+ meta_path::make_node_context(
+ path,
+ mc
+ )
+ );
                 // visit the instance
- lead_to_instance(visitor, mc, ctx, ptr_to_inst);
+ lead_to_instance(visitor, mc, path, ptr_to_inst);
                 // go through the base classes
                 for_each<typename MetaClass::base_classes>(
                         cref(show_bases_to(visitor, ptr_to_inst))
@@ -65,15 +71,21 @@
                         cref(show_attribs_to(visitor, ptr_to_inst))
                 );
                 // leave the type
- visitor.get().leave_type(mc, ctx);
+ visitor.get().leave_type(
+ mc,
+ meta_path::make_node_context(
+ path,
+ mc
+ )
+ );
         }
 };
 
-template <class MetaClass, class Context = mpl::vector0<> >
+template <class MetaClass, class NodePath = mpl::vector0<> >
 class flat_traversal_of
 : detail::traversal_utils<
         MetaClass,
- Context,
+ NodePath,
         typename MetaClass::all_attributes,
         flat_traversal_of
>
@@ -103,17 +115,29 @@
         )
         {
                 MetaClass mc;
- Context ctx;
+ NodePath path;
                 // enter the type
- visitor.get().enter_type(mc, ctx);
+ visitor.get().enter_type(
+ mc,
+ meta_path::make_node_context(
+ path,
+ mc
+ )
+ );
                 // visit the instance
- lead_to_instance(visitor, mc, ctx, ptr_to_inst);
+ lead_to_instance(visitor, mc, path, ptr_to_inst);
                 // go through all of the class' attributes
                 for_each<typename MetaClass::all_attributes>(
                         cref(show_attribs_to(visitor, ptr_to_inst))
                 );
                 // leave the type
- visitor.get().leave_type(mc, ctx);
+ visitor.get().leave_type(
+ mc,
+ meta_path::make_node_context(
+ path,
+ 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-19 10:45:02 EDT (Thu, 19 Jun 2008)
@@ -148,8 +148,15 @@
                         MetaAttribute::position::value <<
                         "' name='" <<
                         MetaAttribute::base_name() <<
+ "' static='" <<
+ (MetaAttribute::traits::is_static::value?"true":"false") <<
                         "'>" <<
                         endl;
+bcout <<
+ "---" << meta_path::size<meta_path::self<Context> >::value << "---" <<
+ endl <<
+ "---" << meta_path::size<meta_path::ancestors<Context> >::value << "---" <<
+ endl;
         }
 
         template <class MetaAttribute, class Context>

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-19 10:45:02 EDT (Thu, 19 Jun 2008)
@@ -184,9 +184,11 @@
                         - Tested with gcc 4.3.0 on SuSE
                         - Tested with intel 10.1 on SuSE
                 </revision>
- <revision id="20080618" major="0" minor="1" micro="29" author="m_ch">
+ <revision id="20080619" major="0" minor="1" micro="29" author="m_ch">
                         - Added meta-attribute traits (currently containing only is_static 'flag')
                         - Done some cleanup in the sources
+ - Rewrite of the traversal contexts
+ - Added first two meta-path axes (self and ancestors)
                         - Tested with MSVC++ 2008 EE On Vista
                 </revision>
         </revisions>

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-19 10:45:02 EDT (Thu, 19 Jun 2008)
@@ -22,6 +22,9 @@
 #include <boost/mirror/meta_types/boost_tuple.hpp>
 #include <boost/mirror/meta_classes/boost_tuple.hpp>
 
+#include <boost/mirror/meta_path/self.hpp>
+#include <boost/mirror/meta_path/ancestors.hpp>
+#include <boost/mirror/meta_path/size.hpp>
 
 #include <boost/mirror/visitors/sample.hpp>
 #include <boost/mirror/traversal.hpp>


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