//: C06:Generators.h // Different ways to fill sequences. #ifndef GENERATORS_H #define GENERATORS_H #include <cstring> #include <set> #include <cstdlib> // A generator that can skip over numbers: class SkipGen { int i; int skp; public: SkipGen(int start = 0, int skip = 1) : i(start), skp(skip) {} int operator()() { int r = i; i += skp; return r; } }; // Generate unique random numbers from 0 to mod: class URandGen { std::set<int> used; int limit; public: URandGen(int lim) : limit(lim) {} int operator()() { while(true) { int i = int(std::rand()) % limit; if(used.find(i) == used.end()) { used.insert(i); return i; } } } }; // Produces random characters: class CharGen { static const char* source; static const int len; public: char operator()() { return source[std::rand() % len]; } }; #endif // GENERATORS_H ///:~
Listado 7.14. C06/Generators.h
//: C06:Generators.cpp {O} #include "Generators.h" const char* CharGen::source = "ABCDEFGHIJK" "LMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; const int CharGen::len = std::strlen(source); ///:~
Listado 7.15. C06/Generators.cpp
//: C06:FunctionObjects.cpp {-bor} // Illustrates selected predefined function object // templates from the Standard C++ library. //{L} Generators #include <algorithm> #include <cstdlib> #include <ctime> #include <functional> #include <iostream> #include <iterator> #include <vector> #include "Generators.h" #include "PrintSequence.h" using namespace std; template<typename Contain, typename UnaryFunc> void testUnary(Contain& source, Contain& dest, UnaryFunc f) { transform(source.begin(), source.end(), dest.begin(), f); } template<typename Contain1, typename Contain2, typename BinaryFunc> void testBinary(Contain1& src1, Contain1& src2, Contain2& dest, BinaryFunc f) { transform(src1.begin(), src1.end(), src2.begin(), dest.begin(), f); } // Executes the expression, then stringizes the // expression into the print statement: #define T(EXPR) EXPR; print(r.begin(), r.end(), \ "After " #EXPR); // For Boolean tests: #define B(EXPR) EXPR; print(br.begin(), br.end(), \ "After " #EXPR); // Boolean random generator: struct BRand { bool operator()() { return rand() % 2 == 0; } }; int main() { const int SZ = 10; const int MAX = 50; vector<int> x(SZ), y(SZ), r(SZ); // An integer random number generator: URandGen urg(MAX); srand(time(0)); // Randomize generate_n(x.begin(), SZ, urg); generate_n(y.begin(), SZ, urg); // Add one to each to guarantee nonzero divide: transform(y.begin(), y.end(), y.begin(), bind2nd(plus<int>(), 1)); // Guarantee one pair of elements is ==: x[0] = y[0]; print(x.begin(), x.end(), "x"); print(y.begin(), y.end(), "y"); // Operate on each element pair of x & y, // putting the result into r: T(testBinary(x, y, r, plus<int>())); T(testBinary(x, y, r, minus<int>())); T(testBinary(x, y, r, multiplies<int>())); T(testBinary(x, y, r, divides<int>())); T(testBinary(x, y, r, modulus<int>())); T(testUnary(x, r, negate<int>())); vector<bool> br(SZ); // For Boolean results B(testBinary(x, y, br, equal_to<int>())); B(testBinary(x, y, br, not_equal_to<int>())); B(testBinary(x, y, br, greater<int>())); B(testBinary(x, y, br, less<int>())); B(testBinary(x, y, br, greater_equal<int>())); B(testBinary(x, y, br, less_equal<int>())); B(testBinary(x, y, br, not2(greater_equal<int>()))); B(testBinary(x,y,br,not2(less_equal<int>()))); vector<bool> b1(SZ), b2(SZ); generate_n(b1.begin(), SZ, BRand()); generate_n(b2.begin(), SZ, BRand()); print(b1.begin(), b1.end(), "b1"); print(b2.begin(), b2.end(), "b2"); B(testBinary(b1, b2, br, logical_and<int>())); B(testBinary(b1, b2, br, logical_or<int>())); B(testUnary(b1, br, logical_not<int>())); B(testUnary(b1, br, not1(logical_not<int>()))); } ///:~
Listado 7.16. C06/FunctionObjects.cpp
//: C06:FBinder.cpp // Binders aren't limited to producing predicates. //{L} Generators #include <algorithm> #include <cstdlib> #include <ctime> #include <functional> #include <iostream> #include <iterator> #include <vector> #include "Generators.h" using namespace std; int main() { ostream_iterator<int> out(cout," "); vector<int> v(15); srand(time(0)); // Randomize generate(v.begin(), v.end(), URandGen(20)); copy(v.begin(), v.end(), out); transform(v.begin(), v.end(), v.begin(), bind2nd(multiplies<int>(), 10)); copy(v.begin(), v.end(), out); } ///:~
Listado 7.17. C06/FBinder.cpp
//: C06:BinderValue.cpp // The bound argument can vary. #include <algorithm> #include <functional> #include <iostream> #include <iterator> #include <cstdlib> using namespace std; int boundedRand() { return rand() % 100; } int main() { const int SZ = 20; int a[SZ], b[SZ] = {0}; generate(a, a + SZ, boundedRand); int val = boundedRand(); int* end = remove_copy_if(a, a + SZ, b, bind2nd(greater<int>(), val)); // Sort for easier viewing: sort(a, a + SZ); sort(b, end); ostream_iterator<int> out(cout, " "); cout << "Original Sequence:" << endl; copy(a, a + SZ, out); cout << endl; cout << "Values <= " << val << endl; copy(b, end, out); cout << endl; } ///:~
Listado 7.18. C06/BinderValue.cpp