STLAlgorithmExtensions

Dear all, I have a question for the Boost moderators: there seems to be already an STL extension library for Boost. This is of course great, but why isn't it in production? It seems to me that this one of the basic libraries and serves many common needs, like the copy_if request in the development group. It can almost replace our company private STL extension library except for: transform_if is_unique contains contains_if delete_all delete_if and container variants of STL algorithms (i.e. for_each(vec, fc) instead of for_each(vec.begin(), vec.end(), fc). Especially handy for implicit modifying algorithms like remove etc.) Further more there was in 2002 a discussion about a sorted vector. Didn't make it either, which is unfortunate. Wkr, me

Hi! If I read the documentation correctly about boost::lexical_cast, for a convertion between two types to work, the source type must be OutputStreamable and the target type must be InputStreamable (plus some other requirements about copying and default construction). Then, any idea why the following code does not work? ///////////////////////////////////////////////////////////////////////// #include <boost/lexical_cast.hpp> #include <iostream> using namespace std ; struct vec { enum static_size_type { size = 2 } ; double data[ size ] ; vec() { for ( int i = 0 ; i < size ; ++ i ) data[ i ] = 0.0 ; } } ; istream& operator >> ( istream& in , vec& v ) { for ( int i = 0 ; i < vec::size ; ++ i ) in >> v.data[ i ] ; return in ; } ostream& operator << ( ostream& out , const vec& v ) { out << v.data[ 0 ] ; for ( int i = 1 ; i < vec::size ; ++ i ) out << ' ' << v.data[ i ] ; return out ; } int main() { string arg = "1 2" ; try { vec v2 = boost::lexical_cast< vec >( arg ) ; cerr << "lexical_cast: " << v2 << endl ; } catch ( const boost::bad_lexical_cast& e ) { cerr << e.what() << endl ; } return 0 ; } ///////////////////////////////////////////////////////////////////////// I use g++ 4.0.2 and Boost 1.33.1. The program compiles, but when executed, I get a boost::bad_lexical_cast exception. However, if I change vec::size to 1 and the variable arg in the main function to "1", then everything runs fine. Any other values greater than 1 won't work (with an appropriate source string, of course). There is an example a little more detailed here: http://www-etud.iro.umontreal.ca/~duranlef/code/lexical_cast_problem.cpp In that example, I manually output the string to a stringstream and then input a vec from the stream, check that I at the end of the stream, and everything runs ok, but not with the lexical cast. I guess I must be doing something stupid somewhere, but I don't see it. Thanks for any help, -- François Duranleau LIGUM, Université de Montréal "Conflict may erupt at any time and any place. War is the destiny of which humanity can never wash its hands." - Emperor Dornkirk, in _The Vision of Escaflowne_

François Duranleau wrote:
If I read the documentation correctly about boost::lexical_cast, for a convertion between two types to work, the source type must be OutputStreamable and the target type must be InputStreamable (plus some other requirements about copying and default construction).
The problem with your example was that after you read the first double there was a blank space in the input so you could not read the second double. Something like this will do: istream& operator >> ( istream& in , vec& v ) { for ( int i = 0 ; i < vec::size ; ++ i ) if ((in >> v.data[ i ]) && !in.eof()) in.get(); return in ; } I ran into another little problem while debugging your example so I thought I would mention it. Although the documentation does not explicitly say so you kind of make sense that lexical_cast expects the destination object's operator>> to use the complete output produced by the source object's operator<<. In other words: stream << source stream >> target !!! stream.eof() must be true at this point So if you try (like I did) lexical_cast<vec>("1 2 3") with vec.size = 2 it will fail. Hope this helps, -delfin

On Wed, 15 Mar 2006, Delfin Rojas wrote:
The problem with your example was that after you read the first double there was a blank space in the input so you could not read the second double. Something like this will do:
istream& operator >> ( istream& in , vec& v ) { for ( int i = 0 ; i < vec::size ; ++ i ) if ((in >> v.data[ i ]) && !in.eof()) in.get(); return in ; }
As far as I know, when using operator>> on numbers (or any types supported by the standard library), preceding spaces are skept, unless explicitly told not to. Mm, after peeking a little more deeply in <boost/lexical_cast.hpp>, I noticed that they do deactivate white space skipping... Argh, my damn old habits... Well, I'll have to use ">> ws" everywhere in operator>>'s now, or temporarily reenable it.
I ran into another little problem while debugging your example so I thought I would mention it. Although the documentation does not explicitly say so you kind of make sense that lexical_cast expects the destination object's operator>> to use the complete output produced by the source object's operator<<. In other words:
stream << source stream >> target !!! stream.eof() must be true at this point
So if you try (like I did) lexical_cast<vec>("1 2 3") with vec.size = 2 it will fail.
I know that. Thanks for your help! -- François Duranleau LIGUM, Université de Montréal "The real source of wealth is correct ideas: workable ideas: that is, negative entropy -- Information." - Robert Anton Wilson, _Prometheus Rising_, 1983
participants (3)
-
Delfin Rojas
-
François Duranleau
-
gast128