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 Wed Jul 28 16:04:14 2004 for s11n by doxygen 1.3.7