Boost logo

Boost :

From: Preston A. Elder (prez_at_[hidden])
Date: 2005-01-25 22:20:58


I've been working with boost::options, and these is one gaping hole in it,
that I have noticed. There is no way to use a custom converter in the
default po::typed_value class.

This is such a flaw, I've actually copied typed_value, and created one
that accepts a function of parser(), which you would supply a
boost::function2<void, boost::any &, const
std::vector<std::basic_string<charT> > &

Why would I want to do this? I have created a bunch of generic converters
that can be used for a number of things, from validation to translation.

The ones I have so far are:
validate_oneof - used as:
        value<T>()->parser(validate_oneof<T>(first_val)
                + second_val
                + third_val
                + fourth_val))
This will then ensure that the value supplied is one of these values
(obviously validate_oneof is a class with an overridden operator+ and an
operator() for calling).

validate_range - used as:
        value<T>()->parser(validate_range<T>(first, last))
This will ensure that the value lies between these values.

You might be able to achieve the same with notifiers, I don't know, but
from here, it gets more interesting.

validate_mapped - used as:
        value<T>()->parser(validate_mapped<K,T>(first_key, first_val)
                + std::make_pair(second_key, second_val)
                + std::make_pair(third_key, third_val))
This will then allow you to specify a value of one type, but have a
different type stored. This is particularly useful to allow, say:
LogLevel = info
and then have that actually stored as an in (say, 5) in the values.

I have others to do syntax validation too, so say validate_ipaddr which
will ensure that it is a valid IP address before storing it, and so on.

Again, I'm not sure how much notifiers would do this too. But also
consider the following.

A 'validator' that allows you to take an IP address as text, verify it is
a valid IP address (hell, if someone wanted to add logic, verify it is
within a certain range if they wanted to), and then store it as an
in_addr_t.

Or even better, a 'validator' that checks to see if 'http://' is prefixed
to a web address, and either removes it or adds it, depending on what you
need.

A notifier might be able to catch bad values, but not change types or
correct the data.

And all in all, the change to do this was minimal, apart from adding the
'parser' function, my xparse function is simply:
        if (m_parser)
                m_parser(value_store, new_tokens)
        else
                validate(value_store, new_tokens, (T*) 0, 0);

Feel free to e-mail me if you want my code, or want me to post it.

-- 
PreZ :)
Founder. The Neuromancy Society (http://www.neuromancy.net)

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk