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.
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
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.) 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.