|
Boost : |
From: Marcin Kalicinski (kalita_at_[hidden])
Date: 2006-04-23 11:30:05
Hi Ivan,
I know get/put functions in general serve two orthogonal tasks: (1) access
by path, and (2) type conversion. Please note that these tasks are also
split in the interface:
get_child() does only (1)
get_own() does only (2)
get() does first (1) and then (2).
I expect get() to be by far most often used function from the three (at
least in my experience using the library).
I don't think that completely redesigning the interface by changing names
and moving functions outside class will provide any extra value. The library
definitely must provide the above, in this form or another. Member functions
or not, it makes little difference. We must also remember that the main goal
for the library is simplicity, i.e. we cannot destroy current result of
three (readable) lines of code plus 1 include to get appropriately typed
value from a config file.
By introducing path class and splitting traits I'm going to make these tasks
even more obviously independent.
> 1) value <-> ptree conversion templates
>
> void set( const Value& v, ptree& storage );
> void get( Value& v, ptree const& storage ); //throws if conv. fails
These functions could be made more generic by operating only on data stored
in ptree. They do not need the whole tree, because they do not use paths.
> 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.
You can already do that. You have to provide your own inserter/extractor,
and specialize it for the types you want. Alternatively, you can provide
stream operations for your types (i.e operator << and >>), in this case you
do not have to do anything else.
> Ambiguous keys
It might be useful in some contexts to make find function throw if there is
more than one key with specified name. On the other hand, it would then be
quite hard to get a value for any instance of that key. The reverse
operation (i.e. find does not throw but I still want to simulate throwing
behaviour) is easy. Just do that:
if (pt.count(key) > 1) throw ...;
I think the deciding point is "if in doubt, do as std containers do". In
this case what std::multimap does.
Thank you for the time you spent preparing this far reaching proposal.
Looking at the practical side of things, you must be aware that implementing
that, and getting all corner cases right would require months. How can you
be sure that the end result would be significantly better than what we have
now? I think you can do everything you want with the current version, the
only difference is in syntax.
Best regards,
Marcin
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk