/* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * Permission to copy, use, modify, sell and distribute this software * is granted provided this copyright notice appears in all copies. * This software is provided "as is" without express or implied * warranty, and with no claim as to its suitability for any purpose. */ #if 0 ////////// fo/sort1.cpp p294 #pragma warning( disable : 4786 ) #include #include #include #include #include using namespace std; /* class Person */ class Person { private: string fn; // first name string ln; // last name public: Person() { } Person(const string& f, const string& n) : fn(f), ln(n) { } string firstname() const; string lastname() const; // ... }; inline string Person::firstname() const { return fn; } inline string Person::lastname() const { return ln; } ostream& operator<< (ostream& s, const Person& p) { s << "[" << p.firstname() << " " << p.lastname() << "]"; return s; } /* class for function predicate * - operator () returns whether a person is less than another person */ class PersonSortCriterion { public: bool operator() (const Person& p1, const Person& p2) const { /* a person is less than another person * - if the last name is less * - if the last name is equal and the first name is less */ return p1.lastname() PersonSet; // create such a collection PersonSet coll; coll.insert(p1); coll.insert(p2); coll.insert(p3); coll.insert(p4); coll.insert(p5); coll.insert(p6); coll.insert(p7); // do something with the elements // - in this case: output them cout << "set:" << endl; PersonSet::iterator pos; for (pos = coll.begin(); pos != coll.end(); ++pos) { cout << *pos << endl; } return 0; } // set: // [lucas arm] // [anica holle] // [anica josuttis] // [lucas josuttis] // [nicolai josuttis] // [ulli josuttis] // [lucas otto] ////////// fo/genera1.cpp p296 #include #include #include #include "print.hpp" using namespace std; class IntSequence { private: int value; public: // constructor IntSequence (int initialValue) : value(initialValue) { } // ``function call'' int operator() () { return value++; } }; int main() { list coll; // insert values from 1 to 9 generate_n (back_inserter(coll), // start 9, // number of elements IntSequence(1)); // generates values PRINT_ELEMENTS(coll); // replace elements 2..8 with values starting at 42 generate (++coll.begin(), // start --coll.end(), // end IntSequence(42)); // generates values PRINT_ELEMENTS(coll); return 0; } // 1 2 3 4 5 6 7 8 9 // 1 42 43 44 45 46 47 48 9 ////////// fo/genera2.cpp p298 #include #include #include #include "print.hpp" using namespace std; class IntSequence { private: int value; public: // constructor IntSequence (int initialValue) : value(initialValue) { } // ``function call'' int operator() () { return value++; } }; int main() { list coll; IntSequence seq(1); // integral sequence starting with 1 // insert values from 1 to 4 // - pass function object by reference // so that it will continue with 5 generate_n >, int, IntSequence&>(back_inserter(coll), // start 4, // number of elements seq); // generates values PRINT_ELEMENTS(coll); // insert values from 42 to 45 generate_n (back_inserter(coll), // start 4, // number of elements IntSequence(42)); // generates values PRINT_ELEMENTS(coll); // continue with first sequence // - pass function object by value // so that it will continue with 5 again generate_n (back_inserter(coll), // start 4, // number of elements seq); // generates values PRINT_ELEMENTS(coll); // continue with first sequence again generate_n (back_inserter(coll), // start 4, // number of elements seq); // generates values PRINT_ELEMENTS(coll); return 0; } // 1 2 3 4 // 1 2 3 4 42 43 44 45 // 1 2 3 4 42 43 44 45 5 6 7 8 // 1 2 3 4 42 43 44 45 5 6 7 8 5 6 7 8 ////////// fo/foreach3.cpp p300 #include #include #include using namespace std; // function object to process the mean value class MeanValue { private: long num; // number of elements long sum; // sum of all element values public: // constructor MeanValue () : num(0), sum(0) { } // ``function call'' // - process one more element of the sequence void operator() (int elem) { num++; // increment count sum += elem; // add value } // return mean value double value () { return static_cast(sum) / static_cast(num); } }; int main() { vector coll; // insert elments from 1 to 8 for (int i=1; i<=8; ++i) { coll.push_back(i); } // process and print mean value MeanValue mv = for_each (coll.begin(), coll.end(), // range MeanValue()); // operation cout << "mean value: " << mv.value() << endl; return 0; } // mean value: 4.5 ////////// fo/removeif.cpp p302 #include #include #include #include "print.hpp" using namespace std; class Nth { // function object that returns true for the nth call private: int nth; // call for which to return true int count; // call counter public: Nth (int n) : nth(n), count(0) { } bool operator() (int) { return ++count == nth; } }; int main() { list coll; // insert elements from 1 to 9 for (int i=1; i<=9; ++i) { coll.push_back(i); } PRINT_ELEMENTS(coll,"coll: "); // remove third element list::iterator pos; pos = remove_if(coll.begin(),coll.end(), // range Nth(3)); // remove criterion coll.erase(pos,coll.end()); PRINT_ELEMENTS(coll,"nth removed: "); return 0; } // coll: 1 2 3 4 5 6 7 8 9 // nth removed: 1 2 4 5 7 8 9 ////////// fo/memfun1.cpp p307 ////////// NOT COMPILING //#define mem_fun1 mem_fun #include #include #include #include #include class Person { private: std::string name; public: //... void print () const { std::cout << name << std::endl; } void printWithPrefix (std::string prefix) const { std::cout << prefix << name << std::endl; } }; void foo (const std::vector& coll) { using std::for_each; using std::bind2nd; using std::mem_fun_ref; // call member function print() for each element for_each (coll.begin(), coll.end(), mem_fun_ref(&Person::print)); // call member function printWithPrefix() for each element // - "person: " is passed as an argument to the member function for_each (coll.begin(), coll.end(), bind2nd(mem_fun_ref(&Person::printWithPrefix), "person: ")); } void ptrfoo (const std::vector& coll) // ^^^ pointer ! { using std::for_each; using std::bind2nd; using std::mem_fun; // call member function print() for each referred object for_each (coll.begin(), coll.end(), mem_fun(&Person::print)); // call member function printWithPrefix() for each referred object // - "person: " is passed as an argument to the member function for_each (coll.begin(), coll.end(), bind2nd(mem_fun(&Person::printWithPrefix), "person: ")); } int main() { std::vector coll(5); foo(coll); std::vector coll2; coll2.push_back(new Person); ptrfoo(coll2); } ////////// fo/fopow1.cpp p311 #include #include #include using namespace std; // include self-defined fopow<> /********* #include "fopow.hpp" *********/ #include #include template struct fopow : public std::binary_function { T1 operator() (T1 base, T2 exp) const { return pow(base,exp); } }; /********* #include "fopow.hpp" *********/ int main() { vector coll; // insert elements from 1 to 9 for (int i=1; i<=9; ++i) { coll.push_back(i); } // print 3 raised to the power of all elements transform (coll.begin(), coll.end(), // source ostream_iterator(cout," "), // destination bind1st(fopow(),3)); // operation cout << endl; // print all elements raised to the power of 3 transform (coll.begin(), coll.end(), // source ostream_iterator(cout," "), // destination bind2nd(fopow(),3)); // operation cout << endl; return 0; } // 3 9 27 81 243 729 2187 6561 19683 // 1 8 27 64 125 216 343 512 729 ////////// fo/compose1.cpp p315 #include #include #include #include #include #include "print.hpp" /********* #include "compose11.hpp" *********/ #include /* class for the compose_f_gx adapter */ template class compose_f_gx_t : public std::unary_function { private: OP1 op1; // process: op1(op2(x)) OP2 op2; public: // constructor compose_f_gx_t(const OP1& o1, const OP2& o2) : op1(o1), op2(o2) { } // function call typename OP1::result_type operator()(const typename OP2::argument_type& x) const { return op1(op2(x)); } }; /* convenience functions for the compose_f_gx adapter */ template inline compose_f_gx_t compose_f_gx (const OP1& o1, const OP2& o2) { return compose_f_gx_t(o1,o2); } /********* #include "compose11.hpp" *********/ using namespace std; int main() { vector coll; // insert elements from 1 to 9 for (int i=1; i<=9; ++i) { coll.push_back(i); } PRINT_ELEMENTS(coll); // for each element add 10 and multiply by 5 transform (coll.begin(),coll.end(), ostream_iterator(cout," "), compose_f_gx(bind2nd(multiplies(),5), bind2nd(plus(),10))); cout << endl; return 0; } // 1 2 3 4 5 6 7 8 9 // 55 60 65 70 75 80 85 90 95 ////////// fo/compose2.cpp p317 #include #include #include #include #include "print.hpp" /********* #include "compose21.hpp" *********/ #include /* class for the compose_f_gx_hx adapter */ template class compose_f_gx_hx_t : public std::unary_function { private: OP1 op1; // process: op1(op2(x),op3(x)) OP2 op2; OP3 op3; public: // constructor compose_f_gx_hx_t (const OP1& o1, const OP2& o2, const OP3& o3) : op1(o1), op2(o2), op3(o3) { } // function call typename OP1::result_type operator()(const typename OP2::argument_type& x) const { return op1(op2(x),op3(x)); } }; /* convenience functions for the compose_f_gx_hx adapter */ template inline compose_f_gx_hx_t compose_f_gx_hx (const OP1& o1, const OP2& o2, const OP3& o3) { return compose_f_gx_hx_t(o1,o2,o3); } /********* #include "compose21.hpp" *********/ using namespace std; int main() { vector coll; // insert elements from 1 to 9 for (int i=1; i<=9; ++i) { coll.push_back(i); } PRINT_ELEMENTS(coll); // remove all elements that are greater than four and less than seven // - retain new end vector::iterator pos; pos = remove_if (coll.begin(),coll.end(), compose_f_gx_hx(logical_and(), bind2nd(greater(),4), bind2nd(less(),7))); // remove "removed" elements in coll coll.erase(pos,coll.end()); PRINT_ELEMENTS(coll); return 0; } // 1 2 3 4 5 6 7 8 9 // 1 2 3 4 7 8 9 ////////// fo/compose3.cpp p319 #include #include #include #include #include /********* #include "compose22.hpp" *********/ #include /* class for the compose_f_gx_hy adapter */ template class compose_f_gx_hy_t : public std::binary_function { private: OP1 op1; // process: op1(op2(x),op3(y)) OP2 op2; OP3 op3; public: // constructor compose_f_gx_hy_t (const OP1& o1, const OP2& o2, const OP3& o3) : op1(o1), op2(o2), op3(o3) { } // function call typename OP1::result_type operator()(const typename OP2::argument_type& x, const typename OP3::argument_type& y) const { return op1(op2(x),op3(y)); } }; /* convenience function for the compose_f_gx_hy adapter */ template inline compose_f_gx_hy_t compose_f_gx_hy (const OP1& o1, const OP2& o2, const OP3& o3) { return compose_f_gx_hy_t(o1,o2,o3); } /********* #include "compose22.hpp" *********/ using namespace std; int main() { string s("Internationalization"); string sub("Nation"); // search substring case insensitive string::iterator pos; pos = search (s.begin(),s.end(), // string to search in sub.begin(),sub.end(), // substring to search compose_f_gx_hy(equal_to(), // compar. criterion ptr_fun(::toupper), ptr_fun(::toupper))); if (pos != s.end()) { cout << "\"" << sub << "\" is part of \"" << s << "\"" << endl; } return 0; } // "Nation" is part of "Internationalization" ////////// fo/compose4.cpp p??? #include #include #include #include #include "print.hpp" /********* #include "compose10.hpp" *********/ #include /********* #include "nullary.hpp" *********/ /********************************************************** * type nullary_function * - as supplement to unary_function and binary_function **********************************************************/ template struct nullary_function { typedef Result result_type; }; /********************************************************** * ptr_fun for functions with no argument **********************************************************/ template class pointer_to_nullary_function : public nullary_function { protected: Result (*ptr)(); public: pointer_to_nullary_function() { } explicit pointer_to_nullary_function(Result (*x)()) : ptr(x) { } Result operator()() const { return ptr(); } }; template inline pointer_to_nullary_function ptr_fun(Result (*x)()) { return pointer_to_nullary_function(x); } /********* #include "nullary.hpp" *********/ /* class for the compose_f_g adapter */ template class compose_f_g_t : public nullary_function { private: OP1 op1; // process: op1(op2()) OP2 op2; public: // constructor compose_f_g_t(const OP1& o1, const OP2& o2) : op1(o1), op2(o2) { } // function call typename OP1::result_type operator()() const { return op1(op2()); } }; /* convenience functions for the compose_f_g adapter */ template inline compose_f_g_t compose_f_g (const OP1& o1, const OP2& o2) { return compose_f_g_t(o1,o2); } /********* #include "compose10.hpp" *********/ using namespace std; #include int main() { srand( time(0) ); list coll; // insert five random numbers generate_n (back_inserter(coll), // beginning of destination range 5, // count rand); // new value generator PRINT_ELEMENTS(coll); // overwrite with five new random numbers // in the range between 0 (including) and 10 (excluding) generate (coll.begin(), coll.end(), // destination range compose_f_g(bind2nd(modulus(),10), ptr_fun(rand))); PRINT_ELEMENTS(coll); return 0; } // 6527 24038 30286 9707 28553 // 0 3 2 1 8 #endif