lean cpp library
A lean C++ library providing efficient utility classes for high-performance C++ applications.
algorithm.h
00001 /*****************************************************/
00002 /* lean Functional              (c) Tobias Zirr 2011 */
00003 /*****************************************************/
00004 
00005 #ifndef LEAN_FUNCTIONAL_ALGORITHM
00006 #define LEAN_FUNCTIONAL_ALGORITHM
00007 
00008 #include "../lean.h"
00009 #include "../tags/noncopyable.h"
00010 #include <functional>
00011 #include <algorithm>
00012 
00013 namespace lean
00014 {
00015 namespace functional
00016 {
00017 
00019 template <class Iterator1, class Iterator2>
00020 inline bool equal(Iterator1 begin1, Iterator1 end1, Iterator2 begin2, Iterator2 end2)
00021 {
00022     Iterator1 it1 = begin1;
00023     Iterator1 it2 = begin2;
00024 
00025     bool ended1 = (it1 == end1);
00026     bool ended2 = (it2 == end2);
00027 
00028     while (!ended1 && !ended2)
00029     {
00030         if (!(*it1 == *it2))
00031             return false;
00032 
00033         ended1 = (++it1 == end1);
00034         ended2 = (++it2 == end2);
00035     }
00036 
00037     return ended1 && ended2;
00038 }
00039 
00041 template <class Iterator1, class Iterator2, class Pred>
00042 inline bool equal(Iterator1 begin1, Iterator1 end1, Iterator2 begin2, Iterator2 end2, Pred pred)
00043 {
00044     Iterator1 it1 = begin1;
00045     Iterator1 it2 = begin2;
00046 
00047     bool ended1 = (it1 == end1);
00048     bool ended2 = (it2 == end2);
00049 
00050     while (!ended1 && !ended2)
00051     {
00052         if (!pred(*it1, *it2))
00053             return false;
00054 
00055         ended1 = (++it1 == end1);
00056         ended2 = (++it2 == end2);
00057     }
00058 
00059     return ended1 && ended2;
00060 }
00061 
00063 template <class Range1, class Range2>
00064 inline bool equal(const Range1 &range1, const Range2 &range2)
00065 {
00066     return equal(range1.begin(), range1.end(), range2.begin(), range2.end());
00067 }
00068 
00070 template <class Range1, class Range2, class Pred>
00071 inline bool equal(const Range1 &range1, const Range2 &range2, Pred pred)
00072 {
00073     return equal(range1.begin(), range1.end(), range2.begin(), range2.end(), pred);
00074 }
00075 
00077 template <class Range1, class Range2>
00078 inline bool lexicographical_compare(const Range1 &range1, const Range2 &range2)
00079 {
00080     return std::lexicographical_compare(range1.begin(), range1.end(), range2.begin(), range2.end());
00081 }
00082 
00084 template <class Range1, class Range2, class Pred>
00085 inline bool lexicographical_compare(const Range1 &range1, const Range2 &range2, Pred pred)
00086 {
00087     return std::lexicographical_compare(range1.begin(), range1.end(), range2.begin(), range2.end(), pred);
00088 }
00089 
00091 template <class Iterator>
00092 inline Iterator insert_last(Iterator first, Iterator last)
00093 {
00094     for  (Iterator current = first; current != last; ++current)
00095         if (*last < *current)
00096         {
00097             std::rotate(current, last, next(last));
00098             return current;
00099         }
00100 
00101     return last;
00102 }
00103 
00105 template <class Iterator, class Predicate>
00106 inline Iterator insert_last(Iterator first, Iterator last, Predicate predicate)
00107 {
00108     for  (Iterator current = first; current != last; ++current)
00109         if (predicate(*last, *current))
00110         {
00111             std::rotate(current, last, next(last));
00112             return current;
00113         }
00114 
00115     return last;
00116 }
00117 
00118 #ifndef LEAN0X_NO_RVALUE_REFERENCES
00119 
00121 template <class Vector, class Value>
00122 inline typename Vector::iterator push_sorted(Vector &vector, Value &&value)
00123 {
00124     vector.push_back( std::forward<Value>(value) );
00125     return insert_last( vector.begin(), prev(vector.end()) );
00126 }
00127 
00129 template <class Vector, class Value, class Predicate>
00130 inline typename Vector::iterator push_sorted(Vector &vector, Value &&value, Predicate &&predicate)
00131 {
00132     vector.push_back( std::forward<Value>(value) );
00133     return insert_last( vector.begin(), prev(vector.end()), std::forward<Predicate>(predicate) );
00134 }
00135 
00136 #else
00137 
00139 template <class Vector, class Value>
00140 inline typename Vector::iterator push_sorted(Vector &vector, const Value &value)
00141 {
00142     vector.push_back( value );
00143     return insert_last( vector.begin(), prev(vector.end()) );
00144 }
00145 
00147 template <class Vector, class Value, class Predicate>
00148 inline typename Vector::iterator push_sorted(Vector &vector, const Value &value, Predicate predicate)
00149 {
00150     vector.push_back( value );
00151     return insert_last( vector.begin(), prev(vector.end()), predicate );
00152 }
00153 
00154 #endif
00155 
00157 template <class Iterator, class Value>
00158 inline Iterator find_sorted(Iterator begin, Iterator end, const Value &value)
00159 {
00160     Iterator element = std::lower_bound(begin, end, value);
00161 
00162     if (element != end && !(*element == value))
00163         element = end;
00164 
00165     return element;
00166 }
00167 
00169 template <class Iterator, class Value, class Ord, class Eq>
00170 inline Iterator find_sorted(Iterator begin, Iterator end, const Value &value, Ord order, Eq equal)
00171 {
00172     Iterator element = std::lower_bound(begin, end, value, order);
00173 
00174     if (element != end && !equal(*element, value))
00175         element = end;
00176 
00177     return element;
00178 }
00179 
00181 template <class Vector, class Value>
00182 inline bool remove(Vector &vector, const Value &value)
00183 {
00184     bool bRemoved = false;
00185 
00186     typename Vector::iterator newEnd = std::remove(vector.begin(), vector.end(), value);
00187     bRemoved = (newEnd != vector.end());
00188 
00189     vector.erase(newEnd, vector.end());
00190 
00191     return bRemoved;
00192 }
00193 
00195 template <class Vector, class Value>
00196 inline bool remove_ordered(Vector &vector, const Value &value)
00197 {
00198     bool bRemoved = false;
00199 
00200     typename Vector::const_iterator it = vector.begin();
00201 
00202     while (it != vector.end())
00203     {
00204         if (*it == value)
00205         {
00206             // Not quite optimal, assuming that elements mostly occur only once
00207             it = vector.erase(it);
00208             bRemoved = true;
00209         }
00210         else
00211             ++it;
00212     }
00213 
00214     return bRemoved;
00215 }
00216 
00217 } // namespace
00218 
00219 using functional::equal;
00220 using functional::lexicographical_compare;
00221 using functional::insert_last;
00222 using functional::push_sorted;
00223 using functional::find_sorted;
00224 using functional::remove;
00225 using functional::remove_ordered;
00226 
00227 } // namespace
00228 
00229 #endif