
Hi, I wanted to give this a shot, as some others have agreed that the member-interface of ptree should be simplified - to being more like that of a container. I would plainly take out all the member functions labeled as "Ptree-specific operations" (see basic_ptree in the Synopsis in the main doc page: http://kaalus.atspace.com/ptree/doc/index.html ). A first step would be to convert them into a set of non-member functions (preferably in a separate header file). Another issue is that we have a multitude of functions because orthogonal features/concepts are being mixed together: - get, optional-get, default-get, put, and set (to be added) - own-data, child, and any-path access - for paths, custom or default separators - actual conversion of a value to/from a data string (or a ptree) - features such as first-class support for indexing an array also might be desirable Also what about: - stricter error checks: what happens if two children have the same name, making a path ambiguous? what about "hybrid" record/array tree nodes? - customization points: how do I specialize the conversion of a UDT to/from a ptree ? I would like to suggest as a starting point for this decomposition, to make the ptree library more flexible/adaptable to individual needs. How about the following building blocks: ? 1) value <-> ptree conversion templates void set( const Value& v, ptree& storage ); void get( Value& v, ptree const& storage ); //throws if conv. fails bool tryget( Value& v, ptree const& storage ) //ret. false if fails { try{ get(v,storage); return true; }catch(...){} return false; } The default implementation of these functions would use lexical_cast to store/retrieve a value to/from a ptree with only an 'own' value set. The template could of course be specialized for user-defined types. For example, I could implement these functions for a struct used as a member in various locations, and convert it into a ptree with a child for each struct data member. Which of get/tryget (throwing and non-throwing functions) is implemented in terms of the other is TBD. 2) Child access (direct child only) ptree const& getField( ptree const& tree, string childName ); // gets a field, throws in case of failure or ambiguity ptree const& trygetField( ptree const& tree, string childName ); // returns empty_ptree if the field is not found or ambiguous ptree& makeField( ptree& tree, string childName ); // accesses the field, creates it if needed ( like std::map::op[] ) + Do we want an "addField" function that always creates a new child even if one already exists? Or should we provide array-indexing functions ? 3) getoptional etc Shall be defined in terms of a sequence of calls to the previous functions. Exact set to be defined as discussed elsewhere. 4) path access TBD. I'll find it acceptable if existing get/put functions are preserved as non-member functions, but left outside of the class, and maybe preferably in a sub-namespace (ptree_stringpath, or whatever). Various proposals have been discussed in these review posts, and again could be implementable in terms of the above. Comments/opinions ? Ideas for using operator overloading? Ivan -- http://ivan.vecerina.com/contact/?subject=NG_POST <- email contact form