/* Defines class iteration_counter, for use in measuring the performance of certain STL generic algorithms. Objects of this class behave like those of type RandomAccessIterator, but the class also keeps counts of all iterator operations, using values of type Counting. Type T should be the value type of RandomAccessIterator, and Reference should be the reference type of T. Type Distance should be a distance type for RandomAccessIterator, and Counting is the type used for the counts. */ /* * Copyright (c) 1997 Rensselaer Polytechnic Institute * * Permission to use, copy, modify, distribute and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appear in all copies and * that both that copyright notice and this permission notice appear * in supporting documentation. Rensselaer Polytechnic Institute makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. * */ #ifndef ITERCOUNT_H #define ITERCOUNT_H template class iteration_counter : public random_access_iterator { typedef iteration_counter self; friend bool operator==(const self& x, const self& y); friend bool operator<(const self& x, const self& y); friend Distance operator-(const self& x, const self& y); friend self operator+(const Distance& n, const self& x); friend self operator+(const DistanceBase& n, const self& x); protected: RandomAccessIterator current; Counting generation; public: static Counting constructions; static Counting assignments; static Counting increments; static Counting dereferences; static Counting bigjumps; static Counting equality_comparisons; static Counting less_comparisons; static Counting differences; static Counting max_generation; static void reset() { constructions = 0; assignments = 0; increments = 0; dereferences = 0; bigjumps = 0; differences = 0; equality_comparisons = 0; less_comparisons = 0; max_generation = 0; } static Counting total() { return constructions + assignments + increments + dereferences + bigjumps + differences + equality_comparisons + less_comparisons; } static void report(ostream& o) { o << "Iterator stats: \n" << " Constructions: " << constructions << "\n" << " Assignments: " << assignments << "\n" << " Increments: " << increments << "\n" << " Dereferences: " << dereferences << "\n" << " Big jumps: " << bigjumps << "\n" << " Differences " << differences << "\n" << " Equality comps: " << equality_comparisons << "\n" << " Less comps: " << less_comparisons << "\n" << " TOTAL: " << total() << endl; o << " Maximum generation: " << max_generation << endl; } iteration_counter() : generation(0) { ++constructions; } iteration_counter(RandomAccessIterator x) : current(x), generation(0) { ++constructions; } iteration_counter(const self& c) : current(c.current), generation(c.generation + 1) { ++constructions; if (generation > max_generation) { max_generation = generation; } } RandomAccessIterator base() { return current; } Reference operator*() const { ++dereferences; return *current; } self& operator++() { ++increments; ++current; return *this; } self operator++(int) { self tmp = *this; ++increments; ++current; return tmp; } self& operator--() { ++increments; --current; return *this; } self operator--(int) { self tmp = *this; ++increments; --current; return tmp; } self operator+(const Distance& n) const { ++bigjumps; return self(current + n); } self& operator+=(const Distance& n) { ++bigjumps; current += n; return *this; } self operator-(const Distance& n) const { ++bigjumps; return self(current - n); } self& operator-=(const Distance& n) { ++bigjumps; current -= n; return *this; } Reference operator[](const Distance& n) { return *(*this + n); } self operator+(const DistanceBase& n) const { ++bigjumps; return self(current + n); } self& operator+=(const DistanceBase& n) { ++bigjumps; current += n; return *this; } self operator-(const DistanceBase& n) const { ++bigjumps; return self(current - n); } self& operator-=(const DistanceBase& n) { ++bigjumps; current -= n; return *this; } Reference operator[](const DistanceBase& n) { return *(*this + n); } friend ostream& operator << (ostream& o, const self& n) { return o << n.current; } }; template inline bool operator==(const iteration_counter& x, const iteration_counter& y) { ++iteration_counter::equality_comparisons; return x.current == y.current; } template inline bool operator<(const iteration_counter& x, const iteration_counter& y) { ++iteration_counter::less_comparisons; return x.current < y.current; } template inline Distance operator-(const iteration_counter& x, const iteration_counter& y) { ++iteration_counter::differences; return x.current - y.current; } template inline iteration_counter operator+(const Distance& n, const iteration_counter& x) { return iteration_counter(x.current + n); } template inline iteration_counter operator+(const DistanceBase& n, const iteration_counter& x) { return iteration_counter(x.current + n); } template Counting iteration_counter:: constructions = 0; template Counting iteration_counter:: assignments = 0; template Counting iteration_counter:: increments = 0; template Counting iteration_counter:: dereferences = 0; template Counting iteration_counter:: bigjumps = 0; template Counting iteration_counter:: equality_comparisons = 0; template Counting iteration_counter:: less_comparisons = 0; template Counting iteration_counter:: differences = 0; template Counting iteration_counter:: max_generation = 0; #endif