Boost logo

Boost :

From: Jeff Garland (jeff_at_[hidden])
Date: 2006-08-29 13:29:18


Ben Strasser wrote:
> Jeff Garland <jeff <at> crystalclearsoftware.com> writes:
>
>> I/O turns out to be something that is quite difficult to do well. There's
>> plenty of issues like: support for wide streams, support for different domain
>> contexts (eg: sometimes I want it to be 'm' and sometimes 'meters'),
>> internationalization of number format, support for serialization. In
>> date-time, there's probably more effort in I/O than any other single aspect of
>> the library.
> I fully agree with you.
>
>> For me, a units library that doesn't seriously address I/O doesn't really
>> finish the job of providing a set of types for application programmers that
>> don't require major extension to use correctly. The whole point of this
>> should be that I can put a 'unit type' in place of an double or some native
>> type. If I have to write an ostream operator to use the library it doesn't
>> make it as a 'double replacement'.
> I agree with you on this point.
>
> However I hope you do agree with me that everybody uses units a bit differently
> so it is impossible to provide all possibilities.

Not if you give the user the correct hooks in the library.

> Even if you supported all
> existing standards many people will want non standard units. This means that
> most of the units will have to be user defined.

I agree on being able to generate new unit types. The 'physics only' view of
the world isn't very interesting to me. I'm really much more interested in
the general idea of 'value types' of which units part of the puzzle.

> Now let us imagine we could realize every infterface we wanted. How would the
> interface look like? For simple situations it should be simple and be able to
> adabte to complex ones.
>
> The simplest situation would be to have a non unicode unit postfix. So the ideal
> interface would look similar to
>
> typedef unit<length, "m"> meter;

This isn't valid code...can't give char strings to templates.

> by not providing I/O support we actually get extremly close to this
>
> typedef unit<length> meter;
> ostream&operator<<(ostream&out, meter n){return out<<n.raw()<<"m";}

The problem is hardcoding the "m" anywhere -- this shouldn't be done. You
need an I/O facet that has the defaults and can be overridden by the user at
runtime. This allows different output for the same value in the same process.
  Your view of how to solve this is on the wrong course in my view...

Just to give you the flavor of how this actually needs to look, here's some
code to output a 'date duration' type:

template <class CharT, class TraitsT>
inline std::basic_ostream<CharT, TraitsT>&
operator<<(std::basic_ostream<CharT, TraitsT>& os, const date_duration& dd) {
     boost::io::ios_flags_saver iflags(os);
     typedef boost::date_time::date_facet<date, CharT> custom_date_facet;
     std::ostreambuf_iterator<CharT> output_itr(os);
     if (std::has_facet<custom_date_facet>(os.getloc()))
       std::use_facet<custom_date_facet>(os.getloc()).put(output_itr, os,
os.fill(), dd);
     else {
       custom_date_facet* f = new custom_date_facet();
       std::locale l = std::locale(os.getloc(), f);
       os.imbue(l);
       f->put(output_itr, os, os.fill(), dd);

     }
     return os;
   }

As you can see it's reasonably complex to output what amounts to an integer
across wide streams and with customizeable formats. But really, output is
trivial compared to input.

> It is indeed a bit verbose but every feasable unit interface is in my eyes more
> verbose. The only real alternative is a macro that expands to the operator<<.

You may need macros...it isn't easy I agree.

> In more complex situations you run accross the problem that you can no longer
> deduce the correct unit type. This is also the reason why PQU (= Physical
> Quantities Units) has introduced annomymous units. However in what way does this
> help? None that I can think of because in both situation (meaning non printable
> units and annomymous units) the users has to indicate how to print the units.

Agree.

> The conclusion that I come to is there is nothing that even an ideal interface
> could provide that isn't already just as simply possible with the interface the
> iostreams provide for every type.
>
> All you can do is making things more complicated.

Well I believe that someone should attempt to create a toolkit that will
allows these user defined units to be created with a minimum of pain and fuss.
  It may indeed require some macros and other 'ugly coding' in the
library...but once it works the user doesn't care much about that -- only that
they don't have to figure out how to write a flexible, wide string enabled,
i/o framework b/c that's in the library.

Don't take this as criticism -- I suppose I could have taken this on by now
given my experience. I'm just hoping someone will take up my challenge ;-)

Jeff


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