|
Boost : |
Subject: Re: [boost] boost::string namespace and string-conversion functions
From: Hartmut Kaiser (hartmut.kaiser_at_[hidden])
Date: 2009-02-14 11:38:18
> > Boost already has a library for that problem:
> > Spirit. With Spirit2, in fact, my understanding is that it has a
> > consistent way to both directions as well. (Arguably serialization
> > does as well, but there any parsing is an implementation detail.)
>
> I am glad you brought it up. Something along these lines was nagging me
> as I
> was using boost::serialization for ultimately conversion to/from XML
> (i.e.
> string) and Hartmut mentioned Spirit capable of doing conversions. So,
> I was
> wondering if that my noise about conversion was not mis-guided. I
> played
> with Spirit (the parser part) only a little bit. I only managed to
> write a
> half-a-page parsing grammar just to happily replace it with a two-liner
> regular expression. Never looked back.
>
> Could you show how to convert int-to-string-to-int with Spirit? Can we
> apply
> hex/scientific/etc. formatting? Does it deal with user types (as
> lexical_cast does)?
namespace qi = boost::spirit::qi;
namespace karma = boost::spirit::karma;
int i = 0;
if (qi::parse("1", int_, i))
karma::generate(outiter, int_, i);
where outiter is some output iterator. 'int_' is only one of the available
primitives, there are more: uint, long_, ulong, double_, float_, you get the
picture. Full customization for special formats is provided, just write your
own policies. Example:
template <typename T>
struct scientific_policy
: karma::real_generator_policies<T>
{
// we want the numbers always to be in scientific format
typedef karma::real_generator_policies<T> base_type;
static int floatfield(T) { return base_type::scientific; }
};
typedef karma::real_spec<double, scientific_policy<double> >
science_type;
double d = 1.2345;
karma::generate(outiter, science_type(), d);
which will generate: "1.234e00" (the default number of fractional digits is
3, but this can be changed easily as well).
etc.
the parse/generate functions are just one possible interface, another is to
use iostream base manipulators:
int i = 0;
std::ci >> qi::match(int_, i);
std::cout << karma::format(int_, i) << std::endl;
HTH
Regards Hartmut
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk