#include "sequence.hpp" #include #include #include #include #include #include #include #include #include #include #include #include #define REOPEN_STD #ifdef REOPEN_STD namespace std { template std::basic_ostream >& operator<<(std::basic_ostream >& os, const std::pair& p) {return os<<"("< class doubler { public: doubler() {} T operator()(T current) const {return current+current; } bool operator==(const doubler& other) const {return true; } template bool operator==(const X&) const {return false; } }; template class squarer { public: squarer() {} std::pair operator()(std::pair current) const {++current.first; return std::make_pair(current.first, T2(current.first)*T2(current.first)); } bool operator==(const squarer& other) const {return true; } template bool operator==(const X&) const {return false; } }; template class powers { public: powers(int power=2) : power_(power) {} std::pair operator()(std::pair current) const {++current.first; return std::make_pair(current.first, pow(T2(current.first), power_)); } bool operator==(const powers& other) const {return power_==other.power_; } template bool operator==(const X&) const {return false; } private: const int power_; }; template class fibonacci { public: fibonacci() {} std::pair operator()(std::pair current) const {return std::make_pair(current.second, current.first+current.second); } bool operator==(const fibonacci& other) const {return true; } template bool operator==(const X&) const {return false; } }; template class hailstone { public: hailstone() : converged_(false) {} T operator()(T current) {converged_=current==1; return current%2?current*3+1:current/2; } bool operator==(const hailstone& other) const {return true; } template bool operator==(const X&) const {return false; } bool converged() const {return converged_; } private: bool converged_; }; template class primes { public: typedef std::set primelist_t; typedef T value_type; primes(T first=2) { if (primes_.empty()) { primes_.insert(2); primes_.insert(largest_=3); } if (first>1) { populate(first); } } T operator()(T current) { if (current==1) { return 2; } populate(current); typename primelist_t::const_iterator it=primes_.find(current); if (it == primes_.end()) throw std::runtime_error("primes::operator() given non-prime"); return *++it; } bool operator==(const primes& other) const {return true; } template bool operator==(const X&) const {return false; } private: class divisible { public: divisible(T candidate) : candidate_(candidate) {} bool operator()(T prime) const {return candidate_%prime==0; } private: T candidate_; }; void populate(T value) { for (T candidate=largest_+2; value >= largest_; candidate+=2) { divisible is_div(candidate); if (std::find_if(primes_.begin(), primes_.end(), is_div) != primes_.end()) continue; primes_.insert(largest_=candidate); } } static primelist_t primes_; static T largest_; }; primes::primelist_t primes::primes_; primes::value_type primes::largest_; template class randomiser { public: randomiser(std::pair range) : range_(range) {} T operator()(T) const {return rand()%range_.second+range_.first; } bool operator==(const randomiser& other) const {return range_==other.range_; } template bool operator==(const X&) const {return false; } private: const std::pair range_; }; template > class circular { public: template circular(const IC& container) : dataset_(container.begin(), container.end()), it_(dataset_.begin()) {} template circular(std::pair range) : dataset_(range.first, range.second), it_(dataset_.begin()) {} circular(const circular& other) : dataset_(other.dataset_), it_(dataset_.begin()) {} circular& operator=(const circular& other) {dataset_=other.dataset_; it_=dataset_.begin(); } const T& operator()(T current) { if (current!=*it_) { if ((it_=std::find(dataset_.begin(), dataset_.end(), current))==dataset_.end()) { throw std::runtime_error("circulate::operator() current not in dataset"); } } if (++it_==dataset_.end()) { it_=dataset_.begin(); } return *it_; } bool operator==(const circular& other) const {return dataset_==other.dataset_; } template bool operator==(const X&) const {return false; } private: circular(); //not allowed const C dataset_; typename C::const_iterator it_; }; class MyNumber { public: explicit MyNumber() : value_(-1L) {} MyNumber(const MyNumber& other) : value_(other.value_) {} explicit MyNumber(long value) : value_(value) {} MyNumber& operator+(const MyNumber& other) {value_+=other.value_; return *this; } MyNumber& operator+(int value) {value_+=value; return *this; } bool operator==(const MyNumber& other) const {return value_==other.value_; } bool operator!=(const MyNumber& other) const {return !operator==(other); } bool operator<(const MyNumber& other) const {return value_(const MyNumber& other) const {return value_>other.value_; } bool operator<=(const MyNumber& other) const {return value_<=other.value_; } bool operator>=(const MyNumber& other) const {return value_>=other.value_; } friend std::ostream& operator<<(std::ostream& os, const MyNumber& value); private: long value_; }; std::ostream& operator<<(std::ostream& os, const MyNumber& value) {return os< class formatter { public: formatter(const T& t) : t_(t) {} void print(std::ostream& os) const { os << t_; } private: const T & t_; }; template class formatter > { public: formatter(const std::pair& p) : p_(p) {} void print(std::ostream& os) const { os << "(" << p_.first << "," << p_.second << ")"; } private: const std::pair& p_; }; template std::ostream& operator<<(std::ostream& os, const formatter& f) { f.print(os); return os; } //}//namespace lib //}//namespace e2 //using e2::lib::formatter; #endif using e2::lib::sequence; using std::copy; using std::cout; using std::endl; using std::find; using std::list; using std::make_pair; using std::ostream_iterator; using std::pair; using std::string; using std::vector; const char* printbool(bool b) { return b?"true":"false"; } template void show(const string& description, const C& container, typename C::difference_type count=25) { cout << "TEST: " << description << endl; #ifdef REOPEN_STD cout << "front: " << container.front() << endl; #else cout << "front: " << formatter(container.front()) << endl; #endif cout << "size: " << container.size() << endl; cout << "max_size: " << container.max_size() << endl; cout << "empty: " << printbool(container.empty()) << endl; cout << "begin to end iterator: "; #ifdef REOPEN_STD copy(container.begin(), container.end(), ostream_iterator(cout, " ")); #else copy(container.begin(), container.end(), ostream_iterator >(cout, " ")); //for (typename C::iterator it=container.begin(); it!=container.end(); it++) //cout << formatter(*it) << " "; #endif cout << endl; cout << " const iterator: "; const C& const_container=container; #ifdef REOPEN_STD copy(const_container.begin(), const_container.end(), ostream_iterator(cout, " ")); #else copy(const_container.begin(), const_container.end(), ostream_iterator >(cout, " ")); //for (typename C::const_iterator it=container.begin(); it!=container.end(); it++) //cout << formatter(*it) << " "; #endif cout << endl; cout << "begin to " << count << " counted: "; for (typename C::const_iterator it=container.begin(); it-container.begin()!=count; it++) #ifdef REOPEN_STD cout << *it << " "; #else cout << formatter(*it) << " "; #endif cout << endl; } int main() { { typedef sequence<> sequence_t; sequence_t seq; show("default 0 (1,2,3...)", seq); cout << "for!=end: "; for (sequence_t::iterator it=seq.begin(); it!=seq.end(); ++it) cout << *it << " "; cout << endl; seq.set_size(16); vector vecint(seq.begin(), seq.end()); show("vector copy", vecint, vecint.size()); sequence_t dupl(seq); show("duplicate", dupl); cout << "TRUE:\n"; cout << "seq==vecint: " << printbool(seq==vecint) << endl; #ifndef INTEL cout << "vecint==seq: " << printbool(vecint==seq) << endl; #endif cout << "seq==dupl: " << printbool(seq==dupl) << endl; cout << "seq<=vecint: " << printbool(seq<=vecint) << endl; #ifndef INTEL cout << "vecint<=seq: " << printbool(vecint<=seq) << endl; #endif #ifndef _MSC_VER cout << "seq<=dupl: " << printbool(seq<=dupl) << endl; #endif cout << "seq>=vecint: " << printbool(seq>=vecint) << endl; cout << "vecint>=seq: " << printbool(seq>=vecint) << endl; #ifndef _MSC_VER cout << "seq>=dupl: " << printbool(seq>=dupl) << endl; #endif cout << "FALSE:\n"; cout << "seq!=vecint: " << printbool(seq!=vecint) << endl; #ifndef INTEL cout << "vecint!=seq: " << printbool(vecint!=seq) << endl; #endif cout << "seqvecint: " << printbool(seq>vecint) << endl; #ifndef INTEL cout << "vecint>seq: " << printbool(vecint>seq) << endl; #endif #ifndef _MSC_VER cout << "seq!=dupl: " << printbool(seq!=dupl) << endl; #endif } { typedef sequence<> sequence_t; sequence_t seq(5); show("start 5 (6,7,8...)", seq); cout << "for!==end: "; for (sequence_t::iterator it=seq.begin(); !(it==seq.end()); it++) cout << *it << " "; cout << endl; } { typedef sequence<> sequence_t; sequence_t seq(-1,15); show("start,size -1,0,1,2...13", seq); cout << "for!=count: "; for (sequence_t::iterator it=seq.begin(); it-seq.begin()!=5; ++it) cout << *it << " "; cout << endl; list listint(seq.begin(), seq.end()); ++*find(listint.begin(), listint.end(), 5); cout << "TRUE:\n"; cout << "seqseq: " << printbool(listint>seq) << endl; cout << "listint>=seq: " << printbool(listint>=seq) << endl; #endif cout << "FALSE:\n"; cout << "seq>listint: " << printbool(seq>listint) << endl; cout << "seq>=listint: " << printbool(seq>=listint) << endl; #ifndef INTEL cout << "listint sequence_t; sequence_t seq(2,2,5); show("start,step,size 2,4,6,8,10", seq); cout << "for!=count: "; for (sequence_t::iterator it=seq.begin(); it-seq.begin()!=5; it++) cout << *it << " "; cout << endl; } { typedef sequence sequence_t; sequence_t seq('A',1,26); show("char A...Z", seq, 30); cout << "for!=end: "; for (sequence_t::iterator it=seq.begin(); it!=seq.end(); ++it) cout << *it << " "; cout << endl; } { typedef sequence sequence_t; sequence_t seq(2.5,0.1,5); show("double", seq); cout << "for!=end: "; for (sequence_t::iterator it=seq.begin(); it!=seq.end(); ++it) cout << *it << " "; cout << endl; } { typedef sequence > sequence_t; sequence_t seq(1,16); show("doubler", seq, 20); cout << "for!=end: "; for (sequence_t::iterator it=seq.begin(); it!=seq.end(); ++it) cout << *it << " "; cout << endl; } { typedef sequence,squarer > sequence_t; sequence_t seq; seq.set_size(10); show("squares using ->second", seq, 10); cout << "for!=end using ->: "; for (sequence_t::iterator it=seq.begin(); it!=seq.end(); ++it) cout << it->second << " "; cout << endl; } { typedef sequence,squarer,double,e2::lib::second > sequence_t; sequence_t seq; seq.set_size(10); show("squares using *", seq); } { typedef sequence,powers,double,e2::lib::second > sequence_t; sequence_t seq2; seq2.set_size(10); show("power 2", seq2); cout << endl; sequence_t seq3(make_pair(1,1), 3, 10); show("power 3", seq3); //cout << "Swapped:\n"; //seq2.swap(seq3); //copy(seq2.begin(), seq2.end(), ostream_iterator(cout, " ")); //copy(seq3.begin(), seq3.end(), ostream_iterator(cout, " ")); //cout << "Swapped back:\n"; //swap(seq2,seq3); //copy(seq2.begin(), seq2.end(), ostream_iterator(cout, " ")); //copy(seq3.begin(), seq3.end(), ostream_iterator(cout, " ")); } { typedef sequence,fibonacci,int,e2::lib::first > sequence_t; sequence_t seq(make_pair(0,1),5); show("fibonacci", seq); } { typedef sequence > sequence_t; cout << "TEST: hailstone\n"; for (int start=1; start<30; ++start) { sequence_t seq(start); for (sequence_t::iterator it=seq.begin(); !it.converged(); ++it) cout << *it << " "; cout << endl; } } { typedef sequence > sequence_t; sequence_t seq(1,10); show("primes from 1", seq); sequence_t seq2(2,10); show("primes from 2", seq2); } { typedef sequence,int,e2::lib::transparent > sequence_t; sequence_t seq(0, make_pair(5,15), 5); show("random[5,15]", seq); } { typedef sequence,char,e2::lib::transparent > sequence_t; sequence init('A',26); //sequence_t seq('A', sequence('A',26), 30); sequence_t seq('A', init, 30); show("circular A-Z", seq, 40); } { typedef sequence sequence_t; sequence_t seq; seq.set_size(15); show("MyNumber -1 (0,1,2...)", seq); seq.set_size(20); cout << "size 20,for!=end: "; for (sequence_t::iterator it=seq.begin(); it!=seq.end(); ++it) cout << *it << " "; cout << endl; } }