edelib 2.0.0

edelib/Functional.h

00001 /*
00002  * $Id: List.h 2839 2009-09-28 11:36:20Z karijes $
00003  *
00004  * Functional approach for lists
00005  * Copyright (c) 2005-2011 edelib authors
00006  *
00007  * This library is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2 of the License, or (at your option) any later version.
00011  *
00012  * This library is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00015  * Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public License
00018  * along with this library. If not, see <http://www.gnu.org/licenses/>.
00019  */
00020 
00021 #ifndef __EDELIB_FUNCTIONAL_H__
00022 #define __EDELIB_FUNCTIONAL_H__
00023 
00024 #include "Debug.h"
00025 
00026 EDELIB_NS_BEGIN
00027 
00037 template <typename T, typename F>
00038 unsigned int filter(const F& func, const T& container, T& ret) {
00039         typename T::const_iterator it  = container.begin();
00040         typename T::const_iterator ite = container.end();
00041 
00042         for(; it != ite; ++it) {
00043                 if(func(*it))
00044                         ret.push_back(*it);
00045         }
00046 
00047         return ret.size();
00048 }
00049 
00054 template <typename T, typename F>
00055 void map(F& func, const T& container, T& ret) {
00056         typename T::const_iterator it  = container.begin();
00057         typename T::const_iterator ite = container.end();
00058 
00059         for(; it != ite; ++it)
00060                 ret.push_back(func(*it));
00061 }
00062 
00078 template <typename T, typename R, typename F>
00079 void reduce(F& func, const T& container, R& ret) {
00080         unsigned int sz = container.size();
00081         if(sz == 0) {
00082                 // nothing
00083         } else if(sz == 1)
00084                 ret = *container.begin();
00085         else {
00086                 typename T::const_iterator it  = container.begin();
00087                 typename T::const_iterator it2 = it;
00088                 ++it2;
00089                 typename T::const_iterator ite = container.end();
00090 
00091                 ret = func(*it, *it2);
00092                 for(++it2; it2 != ite; ++it2)
00093                         ret = func(*it2, ret);
00094         }
00095 }
00096 
00101 template <typename T, typename F>
00102 void for_each(const F& func, const T& container) {
00103         typename T::const_iterator it  = container.begin();
00104         typename T::const_iterator ite = container.end();
00105 
00106         for(; it != ite; ++it)
00107                 func(*it);
00108 }
00109 
00115 template <typename T, typename F>
00116 void for_each(const F& func, const T& container, void* p) {
00117         typename T::const_iterator it  = container.begin();
00118         typename T::const_iterator ite = container.end();
00119 
00120         for(; it != ite; ++it)
00121                 func(*it, p);
00122 }
00123 
00124 EDELIB_NS_END
00125 #endif