Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members

data_node_algo.h

00001 #ifndef s11n_DATA_ALGO_H_INCLUDED
00002 #define s11n_DATA_ALGO_H_INCLUDED
00003 ////////////////////////////////////////////////////////////////////////
00004 // data_node_algo.h:
00005 //
00006 // Defines some helper algorithms for working with Serializables and
00007 // Data Nodes.
00008 //
00009 // License: Public Domain
00010 // Author: stephan@s11n.net
00011 ////////////////////////////////////////////////////////////////////////
00012 
00013 #include <string>
00014 #include <list>
00015 #include <iterator>
00016 #include <algorithm> // for_each
00017 #include <cassert>
00018 
00019 #include <s11n/debuggering_macros.h> // COUT/CERR
00020 #include <s11n/to_string.h> // to/from_string()
00021 #include <s11n/functor.h> // object_reference_wrapper, same_name, et al
00022 #include <s11n/pointer_stripper.h> // pointer_stripper class
00023 
00024 #include <s11n/abstract_creator.h> // abstract_creator class
00025 
00026 
00027 ////////////////////////////////////////////////////////////////////////
00028 // NO DEPS ON data_node.h ALLOWED!
00029 ////////////////////////////////////////////////////////////////////////
00030 
00031 namespace s11n {
00032 
00033 
00034 
00035         /**
00036            Adds ch as a child of parent. Parent takes over ownership
00037            of ch.
00038 
00039            ContainerType must support:
00040 
00041            children().push_back( ChildType * );
00042 
00043         */
00044         template <typename NodeType, typename ChildType>
00045         void add_child( NodeType & parent, ChildType * ch )
00046         {
00047                 parent.children().push_back( ch );
00048         }
00049 
00050  
00051  
00052 
00053         /**
00054            Creates a new node, named nodename, as a child of parent.
00055 
00056            Returns a reference to the new child, which parent now
00057            owns.
00058 
00059            NodeType must support:
00060 
00061            name( string );
00062 
00063            children().push_back( NodeType * );
00064 
00065         */
00066         template <typename NodeType>
00067         NodeType & create_child( NodeType & parent,
00068                                   const std::string nodename )
00069         {
00070                 NodeType * n = new NodeType;
00071                 n->name( nodename );
00072                 parent.children().push_back( n );
00073                 return *n;
00074         }
00075 
00076 
00077 
00078         
00079 
00080 
00081 
00082 
00083 
00084         /**
00085            Each child in parent.children() which has the given name is
00086            copied into the target container.
00087 
00088            Returns the number of items added to target.
00089 
00090            DestContainerT must support an insert iterator which will
00091            insert the pointer type contained in the list returned by
00092            parent.children(). i.e., it must hold (const
00093            SomeSerializableType *).
00094 
00095            Ownership of the children does not change by calling this
00096            function. Normally they are owned by the parent node
00097            (unless the client explicitely did something about that.
00098         */
00099         template <typename NodeT, typename DestContainerT>
00100         size_t find_children_by_name( const NodeT & parent,
00101                                const std::string & name,
00102                                DestContainerT & target )
00103         {
00104                 size_t c = target.size();
00105                 s11n::copy_if( parent.children().begin(),
00106                                          parent.children().end(),
00107                                          std::insert_iterator<DestContainerT>( target,
00108                                                                                target.begin() ),
00109                                          s11n::same_name<NodeT>( name )
00110                                          );
00111                 // you gotta love the STL, man.
00112                 return target.size() - c;
00113         }
00114 
00115         /**
00116            Finds the FIRST child in parent with the given name and
00117            returns a pointer to it, or 0 if no such child is found.
00118 
00119            Ownership of the children does not change by calling this
00120            function: parent still owns it.
00121         */
00122         template <typename NodeT>
00123         const NodeT *
00124         find_child_by_name( const NodeT & parent, const std::string & name )
00125         {
00126                 typedef typename NodeT::child_list_type::const_iterator CIT;
00127                 CIT it = std::find_if( parent.children().begin(),
00128                                        parent.children().end(),
00129                                        s11n::same_name<NodeT>( name )
00130                                        );
00131                 return (parent.children().end() == it) ? 0 : *it;
00132         }
00133 
00134         /**
00135            A non-const overload of find_child_by_name(). Functionally
00136            identical to the const form, except for the constness of
00137            the parent argument and return value.
00138 
00139            Ownership of the returned pointer is not changed by calling
00140            this function (normally parent owns it, but clients may
00141            change that without affecting this function). When in
00142            doubt, i.e. during "normal usage", do NOT delete the returned
00143            pointer, because the parent node owns it.
00144         */
00145         template <typename NodeT>
00146         NodeT *
00147         find_child_by_name( NodeT & parent, const std::string & name )
00148         {
00149                 typedef typename NodeT::child_list_type::iterator IT;
00150                 IT it = std::find_if( parent.children().begin(),
00151                                        parent.children().end(),
00152                                        s11n::same_name<NodeT>( name )
00153                                        );
00154                 return (parent.children().end() == it) ? 0 : *it;
00155         }
00156 
00157 
00158 } // namespace s11n
00159 
00160 #endif // s11n_DATA_ALGO_H_INCLUDED

Generated on Tue Oct 26 18:25:59 2004 for s11n by  doxygen 1.3.9.1