IMHO, general rule should be this:
read_{format} accepts std::basic_istream
write_{format} accepts std::basic_ostream

On the other hand, I quite like the iterator-based interface of Boost.Spirit
and I think it would be easier to flip the idea over:
- provide I/O interfaces based on iterators
- allow users to pass streams through iterators
instead of passing complete stream objects.

Iterators are good for generalisation of both containers and streams.

Bruno, what do you think?

Yep indeed, good point. What I was reacting to initially was the word "container" which was sounding like no higher-level abstractions was going to be used. If we're rather talking about an iterator pair or a range then it makes things different and I agree it's a good choice (as opposed to explicitly taking a vector, a string or any specific container).