
On Wed, Jan 30, 2013 at 6:45 PM, meta221 <talzion12@gmail.com> wrote:
Hello, lately I've been working on a library that can output different kinds of containers to standard output streams. The library is currently completely generic and can output any object that models the input range concept or Boost.Fusion's sequence concept. It doesn't restrict itself to std containers. If an object looks like a sequence, then it is a sequence in the eyes of the library.
The library uses different open and close characters for different kinds of containers. For example the output of the following: std::cout << std::vector<int> {1,2,3} << '\n'; std::cout << std::set<int> {1,2,3} << '\n'; std::cout << std::map<int,int> { {1,2}, {2,3}, {3,1} } << '\n'; is: [1,2,3] {1,2,3} {(1,2), (2,3), (3,1)}
In the example std::vector is interpreted as an ordered_dynamic container and std::set and std::map are interpreted as associative_dynamic containers by the library. The library recursively outputs the contents of each container, so because std::map::value_type is a std::pair (which models Boost.Fusion's sequence concept) it can also output that. std::pair is interpreted as an ordered_fixed container by the library. The library picks the appropriate category for each type being outputted by using Boost.MPL to introspect the type of the object being outputted.
In the future I would like to extend the library to offer facilities to help users implement a operator<< (std::ostream&, T) function for arbitrary types but I haven't really given that a lot of thought yet.
The library's name is currently Boost.Stringize but I don't really like that name and I'm really open for suggestions.
Overall I think this library would make a good addition to Boost as it simplifies things for the end user. If a user wants to output a vector, he/she shouldn't have to iterate over it. It should be as simple as outputting an int. In Python a user can just "print [1,2,3]". Why can't we have something similar in C++?
Is there any interest for this library in Boost?
Does the library define operator<< for the containers themselves? Does it support arbitrary ranges (e.g. iterator_range<T>)? It really worries me that in the examples you presented you create containers rather than some manipulator that refers to the (external) container or range. This implies that you don't have to copy the container or elements in order to output them. I intend to provide different manipulators, including the one for logging ranges, in Boost.Log eventually but I haven't got to it yet.