Boost logo

Boost Users :

From: Samuel Krempp (krempp_at_[hidden])
Date: 2004-08-30 18:33:12


le Monday 30 August 2004 19:43, findlay_at_[hidden] écrivit :

> I've got some code that uses the format library to format output, not out
> of necessity, but rather out of a wanton enjoyment derived from using the
> syntax, having lately (relatively) discovered boost, prefering the
> boost::format simple syntax to the posix printf and std::ostringstream
> flavored solutions. The "problem" I have is that for the output of every
> double, I have to specify the precision:
>
> int main()
> {
> cout << setprecision(18);
> cout << format("Bunner p' air: %1% torr\t\tN$_2$: %2% torr\n"
> " C air: %3%\t\tN$_2$: %4%")
> % group(setprecision(18), bunner::air::pp_av)
> % group(setprecision(18), bunner::N2::pp_av)
> % group(setprecision(18), bunner::air::c_av)
> % group(setprecision(18), bunner::N2::c_av) << endl;
> //...
>
> return 0;
> }
>
> Is there a graceful solution, or am I using this library beyond what it
> was intended for?

Well, making manipulators *non* sticky was in fact a desired feature of the
library. Quite a bit of work is done to insure that.
Letting manipulators (and whatever other stream modification) stack from one
argument formatting to the next would be much easier..

In your case, using the stream directly, with a sticky setprecision, seems
natural.

If you really want to use format, you can either :

A/ pass the precision via printf-style syntax (at each item), e.g. :
   cout << format("Bunner p' air: %|1$.18| %|2$.18|")
                  % bunner::air::pp_av % bunner::N2::pp_av
        << endl;
  Does this solution fit you ?

B/ define a number + format-style wrapper class, e.g. 'StyledNumber', on
which you overload operator<<(stream&, ..) so that it temporarily overrides
the stream's precision parameter, and them format StyledNumber objects :
   cout << format("Bunner p' air: %1% %2%")
         % StyledNumber(bunner::air::pp_av)
         % StyledNumber(bunner::N2::pp_av)
        << endl;
here, it's not much shorter than the original version, but if you replace
calls to the constructor by calls to short-named wrapper function, it can
improve the situation a bit and you get all the flexibility you want

I can think about adding this feature as a member function to boost::format
that would apply one manipulator to all items in one go, like :
   cout << format("Bunner p' air: %1% %2%").stick(setprecision(18))
         % bunner::air::pp_av
         % bunner::N2::pp_av;
Is it what you'd need ?

There's already an undocumented member function, 'modify_item', that applies
a manipulator to one "format item", so 'stick' would just have to do the
same, except for all the items.
The only problem is : it's only able to clone the manipulator's effects on
*standard* stream parameters, while a user-defined manipulator could very
well act on unknown user-defined stream parmaters (think xalloc, etc..).
So such a feature would have to be documented along with the details on its
limits, and interfaces full of functions-with-special-cases are better
avoided IMO.

Anyway I need to take some time and finally document the undocumented
functions (modify_item, bind_arg, etc..), and then I might add a 'stick'
function along those.

In the meantime, you can use the 'modify_item' function to define an
external 'stick' function.

-- 
Samuel

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