Simple Application Framework  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
Saf/Math/Range.h
Go to the documentation of this file.
00001 /*
00002     This file is part of Simple Application Framework (Saf) library.
00003     Copyright (C) 2010 - 2012 Ondrej Danek <ondrej.danek@gmail.com>
00004 
00005     This library is free software: you can redistribute it and/or modify
00006     it under the terms of the GNU General Public License as published 
00007     by the Free Software Foundation, either version 3 of the License, or
00008     (at your option) any later version.
00009 
00010     Saf is distributed in the hope that it will be useful,
00011     but WITHOUT ANY WARRANTY; without even the implied warranty of
00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013     GNU General Public License for more details.
00014 
00015     You should have received a copy of the GNU General Public License
00016     along with Simple Application Framework library. If not, 
00017     see <http://www.gnu.org/licenses/>.
00018 */
00019 
00028 #ifndef SAF_MATH_RANGE_H
00029 #define SAF_MATH_RANGE_H
00030 
00031 #include "../Algo/Range.h"
00032 #include "../Algo/Predicate.h"
00033 #include "../Type/IteratorTraits.h"
00034 
00035 namespace Saf
00036 {
00037     namespace Math
00038     {
00043         namespace Range
00044         {
00062             template <class FwdIter, class Val, class Comp>
00063             inline FwdIter LowerBound(FwdIter begin, FwdIter end, const Val& val, Comp comp)
00064             {
00065                 Size len = Algo::Range::Distance(begin, end);
00066 
00067                 while (len > 0)
00068                 {
00069                     Size halfLen = len / 2;
00070 
00071                     FwdIter mid = begin;
00072                     Algo::Range::Advance(mid, halfLen);
00073 
00074                     if (comp(*mid, val))
00075                     {
00076                         begin = ++mid;
00077                         len -= halfLen + 1;
00078                     }
00079                     else
00080                     {
00081                         len = halfLen;
00082                     }
00083                 }
00084 
00085                 return begin;
00086             }
00087 
00106             template <class FwdIter, class Val>
00107             inline FwdIter LowerBound(FwdIter begin, FwdIter end, const Val& val)
00108             {
00109                 return LowerBound(begin, end, val, Algo::Predicate::Less<Val>());
00110             }
00111 
00129             template <class FwdIter, class Val, class Comp>
00130             inline FwdIter UpperBound(FwdIter begin, FwdIter end, const Val& val, Comp comp)
00131             {
00132                 Size len = Algo::Range::Distance(begin, end);
00133 
00134                 while (len > 0)
00135                 {
00136                     Size halfLen = len / 2;
00137 
00138                     FwdIter mid = begin;
00139                     Algo::Range::Advance(mid, halfLen);
00140 
00141                     if (!comp(val, *mid))
00142                     {
00143                         begin = ++mid;
00144                         len -= halfLen + 1;
00145                     }
00146                     else
00147                     {
00148                         len = halfLen;
00149                     }
00150                 }
00151 
00152                 return begin;
00153             }
00154 
00173             template <class FwdIter, class Val>
00174             inline FwdIter UpperBound(FwdIter begin, FwdIter end, const Val& val)
00175             {
00176                 return UpperBound(begin, end, val, Algo::Predicate::Less<Val>());
00177             }
00178 
00185             template <class FwdIter>
00186             inline typename Type::IteratorTraits<FwdIter>::ValType Sum(FwdIter begin, FwdIter end)
00187             {
00188                 typename Type::IteratorTraits<FwdIter>::ValType sum = 0;
00189 
00190                 while (begin != end)
00191                 {
00192                     sum += *begin;
00193                     ++begin;
00194                 }
00195 
00196                 return sum;
00197             }
00198 
00205             template <class FwdIter>
00206             inline typename Type::IteratorTraits<FwdIter>::ValType Product(FwdIter begin, FwdIter end)
00207             {
00208                 typename Type::IteratorTraits<FwdIter>::ValType prod = 1;
00209 
00210                 while (begin != end)
00211                 {
00212                     prod *= *begin;
00213                     ++begin;
00214                 }
00215 
00216                 return prod;
00217             }            
00218         }
00219     }
00220 }
00221 
00222 #endif