
Preston A. Elder wrote:
just the validator function is more convenient, so I intend to implement this functionality. Why does your vector validator not share a common ancestor with your non-vector validator?
It does a lexical_cast<T> inside it - when it would much more sense to use a structure somewhat similar to the following:
// Implemented as a class so we can partially specialize it later on
Sorry, previous version of the library used partial specialisation and did not work on borland as the result.
template<class T, class charT> validate(boost::any &v, const std::vector<std::basic_string<charT> >& xs) std::vector<T> *, long) { if (v.empty()) v = boost::any(std::vector<T>()); std::vector<T> *tv = boost::any_cast<std::vector<T> >(&v); assert(tv); static validate_internal<T> validator; for (unsigned int i = 0; i < xs.size(); ++i) tv->push_back(validator(xs[i])); }
I think it would make sense to call 'validate' for the single element from 'validate' for vector. That would solve you problem.
As an aside, I know it would be easy, but is there any reason you did not include the validators for std::set, std::multiset, std::list, std::deque, std::queue and std::stack (the other 'big' single-storage containers)? They would be very easy to do, except the first two use 'insert', the second two use 'push_back' and the third two use 'push' to add an entry to the container, respectively :)
There were no demand for that ;-)
Next - what is the use of the fourth argument to the validate() function?
This is a workaround for compilers without partial template specialization. The generic version is defined as template<class T, class charT> void validate(boost::any& v, const std::vector< std::basic_string<charT> >& xs, T*, long) and specific version is template<class T, class charT> void validate(boost::any& v, const std::vector< std::basic_string<charT> >& xs, std::vector<T>*, int) When 'validate' is called with vector<T>* and '0' as third and fourth parameter, such compilers see that third parameter can be passed to both function. However '0' -> int conversion is no-op and '0' -> long conversion is integer promotion. So, the second version of the function is selected.
Finally, as a feature request, I'd LOVE to have a way to be able to have something like: mykey.1.host = some_host mykey.1.port = some_port mykey.1.password = some_pass mykey.1.priority = some_prio mykey.2.host = some_host mykey.2.port = some_port mykey.2.password = some_password mykey.2.priority = some_prio
Without having to define every possible 'middle' portion (1, 2, etc). Even if this only allowed sequential numbers as the 'middle' portion. Right now, one of my data items is defined as:
mykey = some_host1 some_port1 some_pass1 some_prio1 mykey = some_host2 some_port2 some_pass2 some_prio2
Which is kind of ugly, when it would make much more sense to do: [mykey.1] host = some_host1 port = some_port1 password = some_password1 priority = some_priority1
and so on.
Anyway, let me know :)
Request noted. I'll try to do something. - Volodya