Boost logo

Boost Users :

From: Bryan Green (bgreen_at_[hidden])
Date: 2007-07-18 18:28:59


Ian McCulloch writes:
> Bryan Green wrote:
>
> > Vladimir Prus writes:
> >>
> >> Speaking about -v -v -v, there's no stock way to achieve that. However,
> >> the provided interfaces seem to make it possible:
> >>
> >> 1. Derive from value_semantics.
> >>
> >> 2. Define the 'parse' method to add one to already stored value.
> >
> > Thanks for the suggestion - I will give it a try!
>
> If it works out, please post the solution to the list. It would be very
> useful! Also as an example for how to extend the library.

Done! That wasn't so bad after all. It's pretty cool to see it working.
Hurrah for extensibility!

I created an 'accumulating_value' class, with a 'accum_value()' function.
Here is the usage:

desc.add_options()
    ("verbose,v", po_ext::accum_value<int>(), "print extra information")
    ;
 ...
    if (vm.count("verbose")) {
        verbose = vm["verbose"].as<int>();

It also supports the 'default_value()' method the way I think it should.

Here is the code:

==========================================================================
namespace po_ext {
    template <class T, class charT = char>
    class accumulating_value : public po::typed_value<T,charT>
    {
    public:
        accumulating_value(T* store_to=0)
            : po::typed_value<T,charT>(store_to), origin(0)
        {
            (void) po::typed_value<T,charT>::zero_tokens();
        }

        accumulating_value* default_value(const T &v)
        {
            // setting a default value sets the origin to that value
            origin = v;
            (void) po::typed_value<T,charT>::default_value(v);
            return this;
        }

        accumulating_value* default_value(const T &v,const std::string&
textual)
        {
            // setting a default value sets the origin to that value
            origin = v;
            (void) po::typed_value<T,charT>::default_value(v, textual);
            return this;
        }

        void xparse(boost::any& value_store,
               const std::vector<std::basic_string<charT> >& new_tokens)
const
        {
            // if this is the first occurrence of the option, initialize it
            // to the origin.
            if (value_store.empty())
                value_store = boost::any(origin);

            ++boost::any_cast<T&>(value_store);
        }

    private:
        T origin; // the numeric origin from which to increment upward.
    };

    template <class T>
    accumulating_value<T>*
    accum_value(T *v)
    {
        accumulating_value<T>* r = new accumulating_value<T>(v);
        return r;
    }

    template <class T>
    accumulating_value<T>*
    accum_value()
    {
        return accum_value<T>(0);
    }
}
==========================================================================


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net