Boost logo

Boost :

Subject: Re: [boost] [Range] New I/O functions for ranges
From: Indiana (indi.in.the.wired_at_[hidden])
Date: 2014-09-30 16:53:16


On 14-09-29 01:24 PM, Paul A. Bristow wrote:
> I wonder if you have studied the examples of Steven Watanbe's type erasure
> library?
>
> http://www.boost.org/doc/libs/1_55_0/doc/html/boost_typeerasure.html
>
> I found this useful, but it didn't cover all the options that I wanted, so I
> added a prefix string and a suffix string to the existing delimiter string.
>
> I would urge you to consider this as it increases the possible use-cases covered
> considerably.
Well, the range I/O functions i'm proposing are not intended to cover
every imaginable I/O situation. The goal is just to make the simplest
cases - which cover the *VAST* majority of usage - simple to do. Trying
to cover things that are very complex, very rare, or that would require
a ton of customization options (like automatic line wrapping) would add
too much complexity for too little payoff. But that's not really a cop
out, because the truth is that the *VAST* majority of things you might
want to do are already covered.

To demonstrate that, i took the code you pasted, and reimplemented it
using write_all(). I tried to match the output exactly, and to keep the
code in main() changed as little as possible except for the parts
pertaining to output.

Of the 19 output operations in the original code:
  * 13 could be done with just a call to write_all() and no additional
code;
  * 5 could be done with (the same, reused) ~30 lines of additional
code to create a smart delimiter (these were the ones that print the
range in columns in row-major order);
  * 1 required ~100 lines of additional code to create a smart
delimiter and range adaptor (this was the one that prints the range in
column-major order; because it prints the range out of order, it
requires a custom range adaptor to do the reordering).*

You can see the code i wrote here: http://pastebin.com/R1SwvBEr . In
total the whole program came to ~300 lines (compared to the original at
~480 lines, around at least 40% less code). Not only that, every output
statement handles formatting correctly. (Compare doing "std::cout <<
std::setw(4) << std::setfill('0'); separator_printer p1(",");
p1.print(std::cout, test); std::cout << '\n';" to doing "std::cout <<
std::setw(4) << std::setfill('0') << write_all(test, ",") << '\n';". The
former will print "0001,2,3,4,...", the latter will do
"0001,0002,0003,0004,...".) And they also correctly handle I/O errors.

What I'm trying to demonstrate is: all the complexity you *think* you
need in range I/O functions... you probably don't. You will probably
never find a case where what you need in range output cannot be handled
by a simple function that just prints the range elements in order,
possibly with a delimiter between. Anything else - like reordering the
elements, skipping elements conditionally, etc. - is outside that scope;
that is the domain of (for example) range adaptors (because you're
adapting the range). Combining range adaptors, smart delimiters, and
write_all() will cover just about every range output situation you can
conceive of.

So if we can get printing the elements of a range in order - possibly
with a delimiter - done *RIGHT* (ie, doing formatting, error handling,
etc. right) and *EASY*, then we will have covered a hell of a lot of
ground. That is the philosophy i had in mind, not trying to design an
interface that can do *everything*.

(*Incidentally, maybe there *should* be a column-major reordering range
adaptor added to Boost. Or rather, a "transpose" adaptor that takes a
forward range that is presumed to be a MxN matrix in row major format,
and returns a view of it transposed. I can see that as being generally
useful.)
> In particular, it is seems desirable to be able to output values in the C++
> syntax for the compiler to read back in?
You mean serialization? There's already a Boost library for that, and
anyway that's not the problem domain i'm tackling; i'm dealing with
generalized I/O. Whether or not data can round trip depends on the
formatting options you choose when doing input and output, and the way
you've written your class's stream inserter and extractor. For example,
if you print a number in a German or French locale then try to read it
into a US locale, it's probably not going to work. If you pick the right
options, round tripping is certainly possible.


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