// this program showcases some of the capabilities of the // foreach and stringutil headers. // compile and run : g++ test_foreach.cc ; a.out #define EXPERIMENT #include "foreach.hh" #include "stringutil.hh" using namespace stringutil; #include #include #include #include #include using namespace std; struct A { int x; A() : x(1) {} A(int a ) : x(a) {} }; std::ostream& operator<<( std::ostream& out, const A& obj) { out << "A" << obj.x; return out; } template T* toptr(const T& v) { return &v;} //void sort_by_member( const T& container, double func( double x ) { return x*x; } string funcs(double x) { return "bye"; } int main() { // vector v = pack( 1,2,3,4,5 ); // vector V = apply( func, v ); // foreach.hh has a range function. We can use print to // print the vector in a nice way. cout << sizeof (A::x) << endl; vector av(10); for(int i=0; i<10; i++) { av[i].x = 100-i; } print ("sorted=", sort_by ( av, &A::x ) ); // make_member_comparer( toptr( A::x) ); vector R = range(0,20,3); using namespace coolprinter; print ( R ); print (slice(R, 1 ) ); print (slice(R,-2,0) ); // foreach can be used to loop over std containers foreach ( x, R ) { // if (atfirst) print ("first"); // if (atlast) print ("last"); print( x ); } // enumerate is a forach that also gives you a counter enumerate( i, n, R ) { if (!i) print ("first one"); print (i,n); } // loop over the vector with foreach, the 3rd argument can be // used to select elements. The following multiplies all even // number by 100, except 6 and it stops after 12. // foreach( x, R , x%2 == 0 ) // works but causes warning foreach( x, R ) { if ( x == 6 ) continue; // continue and break work as expected x *= 100; // note we can change x in place if ( x == 1200 ) break; } print( R ); // there is also a foreach to loop over maps map M; M["answer"] = 42; M["ten"] = 10; print ("map = ", M ); // pretty printing for maps foreach_map( key, value, M ) { print ( key, value ); } // And one for maps of maps map< int , map< int, string > > M2; M2[1][2] = "one two"; M2[3][0] = "three zero"; foreach_map_map ( k1, k2, ss , M2 ) { print (k1, k2 , ss ); } // The following are some obvious functions. // note : all(R) == 0 because of the 1st element (0) does is not true. print ( max(R), min(R), sum(R), mean(R), any(R), all(R) ); // All this should work with other types and (some) containers too. std::list< A > L; L.push_back( A(10) ); L.push_back( A(30) ); foreach( q, L ) print( q ); // print uses operator<< //-------------------------------------------------------- // hzip (h=homogeneous) zips vectors of the same type //-------------------------------------------------------- vector X = range(5); vector Y; foreach(x, X ) Y.push_back( x*x); foreach( couple, hzip( X, Y ) ) { print ( couple[0] ,"squared is", couple[1] ); } // vector< vector< int > > XX = pack( X, X ); // print( XX ); }