// UnderC Development Project, 2001 // First draft of some useful standard algorithms #ifndef __ALGORITHM_H #define __ALGORITHM_H namespace std { // until our template function resolution is a little more // sophisticated, we just use specialized versions. int min(int a, int b) { return a > b ? b : a; } int max(int a, int b) { return a > b ? a : b; } double min(double a, double b) { return a > b ? b : a; } double max(double a, double b) { return a > b ? a : b; } template IT find(IT start, IT finis, T val) { while (start != finis) { if (*start == val) return start; ++start; } return finis; } template IT find_if(IT i1, IT i2, P pred) { while (i1 != i2) { if (pred(*i1)) return i1; ++i1; } return i2; } template void copy(In i1, In i2, Out j) { while (i1 != i2) { *j = *i1; ++j; ++i1; } } template void for_each(In i1, In i2, Fn fn) { while (i1 != i2) { fn(*i1); ++i1; } } template void transform(In i1, In i2, Out oi, Fn fn) { while (i1 != i2) { *oi = fn(*i1); ++i1; ++oi; } } template int count(In i1, In i2, T val) { int res = 0; while (i1 != i2) { if (*i1 == val) ++res; ++i1; } return res; } template int count_if(In i1, In i2, P pred) { int res = 0; while (i1 != i2) { if (pred(*i1)) ++res; ++i1; } return res; } template void remove_copy_if(In i1, In i2, Out o, Pr fn) { while (i1 != i2) { if (! fn(*i1)) { *o = *i1; ++o; } ++i1; } } template void remove_if(In i1, In i2, Pr fn) { i1 = find_if(i1,i2,fn); if (i1==i2) return i1; In ii = i1; ++ii; return remove_copy_if(ii,i2,i1,fn); } template IT binary_search(IT low, IT end, T val) { IT high = end-1; while (low <= high) { IT mid = (low+high)/2; cout << mid << endl; if (val == *mid) return mid; if (val < *mid) high = mid-1; else low = mid+1; } return end; } template void fill(IT start, IT finish, T val) { while (start != finish) { *start = val; ++start; } } template void fill_n(IT start, int n, T val) { for(int i = 0; i < n; i++) *start++ = val; } template IT min_element(IT i1, IT i2) { IT imin = i1; while (i1 != i2) { if (*i1 < *imin) imin = i1; ++i1; } return imin; } template IT max_element(IT i1, IT i2) { IT imax = i1; while (i1 != i2) { if (*i1 > *imax) imax = i1; ++i1; } return imax; } template void replace(In i1, In i2, T v1, T v2) { while (i1 != i2) { if (*i1 == v1) *i1 = v2; ++i1; } } template class _back_inserter { private: C& m_container; C::value_type m_val; public: typedef C::value_type value_type; _back_inserter(C& c) : m_container(c) { } _back_inserter(const _back_inserter& c) : m_container(c.m_container) { } value_type& operator*() { return m_val; } _back_inserter& operator++() { m_container.push_back(m_val); return *this; } }; template _back_inserter back_inserter(C& c) { typedef _back_inserter BI; //int i=0; //,j=1,k=2; BI bb(c); //cout << i << ' ' << j << ' ' << k << endl; return bb; } // should go in template T accumulate(In i1, In i2, T val) { // there's a bug in the list postfix ++ while (i1 != i2) { val = val + *i1; i1++; } return val; } // note: we don't have the iterator_traits mechanism, // so I've used the (experimental and non-standard) typeof operator. // These versions are of course only intended for numerical types. template Out partial_sum(In i1, In i2, Out j) { if (i1 == i2) return j; typeof(*i1) sum = 0; while (i1 != i2) { sum += *i1; *j = sum; ++i1; ++j; } return j; } template Out adjacent_difference(In i1, In i2, Out j) { if (i1 == i2) return j; typeof(*i1) sum = 0; while (i1 != i2) { *j = *i1 - sum; sum += *i1; ++i1; ++j; } return j; } // *add 1.2.4 Simple Sort template void swap(T& x, T& y) { T tmp = x; x = y; y = tmp; } template void sort(It s, It e) { It f; for(; s != e; ++s) { f = s; ++f; for(; f != e; ++f) if (*f < *s) swap(*f,*s); } } } // namespace std #endif