ahAlgo.H

00001 
00002 /*
00003   This file is part of Aleph system
00004 
00005   Copyright (c) 2002, 2003, 2004, 2005, 2006
00006   UNIVERSITY LOS ANDES (ULA) Merida - REPÚBLICA BOLIVARIANA DE VENEZUELA  
00007 
00008   - Center of Studies in Microelectronics & Distributed Systems (CEMISID) 
00009   - ULA Computer Science Department
00010   - FUNDACITE Mérida - Ministerio de Ciencia y Tecnología
00011 
00012   PERMISSION TO USE, COPY, MODIFY AND DISTRIBUTE THIS SOFTWARE AND ITS
00013   DOCUMENTATION IS HEREBY GRANTED, PROVIDED THAT BOTH THE COPYRIGHT
00014   NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES OF THE
00015   SOFTWARE, DERIVATIVE WORKS OR MODIFIED VERSIONS, AND ANY PORTIONS
00016   THEREOF, AND THAT BOTH NOTICES APPEAR IN SUPPORTING DOCUMENTATION.
00017 
00018   Aleph is distributed in the hope that it will be useful, but WITHOUT
00019   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
00020   or FITNESS FOR A PARTICULAR PURPOSE.
00021 
00022   UNIVERSIDAD DE LOS ANDES requests users of this software to return to 
00023 
00024   Leandro Leon
00025   CEMISID 
00026   Ed La Hechicera 
00027   3er piso, ala sur
00028   Facultad de Ingenieria 
00029   Universidad de Los Andes 
00030   Merida - REPÚBLICA BOLIVARIANA DE VENEZUELA    or
00031 
00032   lrleon@ula.ve
00033 
00034   any improvements or extensions that they make and grant Universidad 
00035   de Los Andes (ULA) the rights to redistribute these changes. 
00036 
00037   Aleph is (or was) granted by: 
00038   - Consejo de Desarrollo Cientifico, Humanistico, Tecnico de la ULA 
00039     (CDCHT)
00040   - Fundacite Mérida
00041 */
00042 
00043 
00044 /*
00045         Aleph implementation of C++ standard algorithms
00046 */
00047 
00048 # ifndef AHALGO_H
00049 # define AHALGO_H
00050 
00051 # include <ahAssert.H>
00052 # include <ahUtils.H>
00053 # include <ahPair.H> 
00054 
00055 typedef size_t size_type;
00056 
00057 // Non Modifying Algorithms
00058 
00059 
00060 namespace Aleph
00061 {
00062 
00063 
00064     template <class Itor, class Operation> inline
00065 Operation for_each (Itor beg, const Itor & end, Operation op)
00066 {
00067   while (beg not_eq end)
00068     op (beg++);
00069      
00070   return op;
00071 }
00072 
00073 
00074     template<class Itor, class Operation> inline
00075 typename Itor::difference_type count_if (Itor beg, 
00076                           const Itor & end, 
00077                           Operation op)
00078 {
00079   typename Itor::difference_type n = 0;
00080 
00081   while (beg not_eq end)
00082     if (op (beg++))
00083       ++n;
00084      
00085   return n;
00086 }
00087 
00088 
00089     template <class Itor, class T> inline
00090 typename Itor::difference_type count (const Itor & beg, 
00091                           const Itor & end, 
00092                           const T & value)
00093 {
00094   return Aleph::count_if (beg, end, Aleph::bind2nd(equal_to<T>(), value));
00095 }
00096 
00097 
00098     template<class Itor, class CompFunc> inline
00099 Itor min_element (Itor beg, const Itor& end, CompFunc op)
00100 {
00101   Itor min = beg;
00102   beg++;
00103 
00104   while (beg not_eq end)
00105     {
00106       if (op (*beg, *min))
00107      min = beg;
00108 
00109       ++beg;
00110     }
00111 
00112   return min;
00113 }
00114 
00115 
00116     template<class Itor> inline
00117 Itor min_element (const Itor& beg, const Itor& end)
00118 {
00119   return 
00120     Aleph::min_element (beg, end, Aleph::less<typename Itor::value_type>());
00121 }
00122 
00123 
00124     template<class Itor, class CompFunc> inline
00125 Itor max_element (const Itor& beg, const Itor& end, CompFunc op)
00126 {
00127   return Aleph::min_element (beg, end, op);
00128 }
00129 
00130 
00131     template<class Itor> inline
00132 Itor max_element (const Itor& beg, const Itor& end)
00133 {
00134   return 
00135     Aleph::max_element (beg, end, Aleph::greater<typename Itor::value_type>());
00136 }
00137 
00138 
00139     template<class Itor, class UnaryPredicate> inline
00140 Itor find_if (Itor beg, Itor end, UnaryPredicate op)
00141 {
00142   while (beg not_eq end and not op(*beg))
00143     ++beg;
00144 
00145   I(beg == end or op(*beg));
00146 
00147   return beg;
00148 }    
00149 
00150      
00151     template<class Itor, class T> inline
00152 Itor find (const Itor& beg, const Itor& end, const T & value)
00153 {
00154   return 
00155     Aleph::find_if (beg, end, Aleph::bind2nd(Aleph::equal_to<T>(), value));
00156 }
00157 
00158 
00159     template<class Itor, class Size, class T, class BinaryPredicate> inline
00160 Itor search_n (Itor            beg, 
00161             const Itor &    end, 
00162             Size            count, 
00163             const T &       value, 
00164             BinaryPredicate op)
00165 {
00166   if (count <= 0)
00167     return beg;
00168 
00169   Size i = 0;
00170   Itor first;
00171 
00172   while (beg not_eq end and i < count)
00173     {
00174       if (op(*beg, value))
00175      {
00176        if (i == 0)
00177          first = beg;
00178        ++i;
00179      }
00180       else
00181      i = 0;
00182           
00183       ++beg;
00184     }
00185 
00186   if (i == count)
00187     return first;
00188 
00189   return end;
00190 }
00191 
00192 
00193     template<class Itor, class Size, class T> inline
00194 Itor search_n (const Itor& beg, const Itor & end, Size count, const T & value)
00195 {
00196   return Aleph::search_n (beg, end, count, value, Aleph::equal_to<T>());
00197 }
00198 
00199 
00200     template<class Itor1, class Itor2, class BinaryPredicate> inline
00201 Itor1 search (Itor1 beg, const Itor1& end, 
00202            Itor2 searchBeg, const Itor2& searchEnd, 
00203            BinaryPredicate op)
00204 {
00205   Itor1 first;
00206   Itor2 pivot = searchBeg;
00207   int count = 0;
00208 
00209   while (beg not_eq end and pivot not_eq searchEnd)
00210     {     
00211       if (op(*beg, *pivot))
00212      {
00213        if (*beg == *searchBeg and count == 0)
00214          first = beg;
00215           
00216        ++pivot;
00217        ++count;
00218      }
00219       else
00220      {
00221        pivot = searchBeg;
00222        count = 0;
00223      }
00224 
00225       ++beg;
00226     }
00227      
00228   if (pivot == searchEnd)
00229     return first;
00230 
00231   return end;
00232 }
00233 
00234 
00235     template<class Itor1, class Itor2> inline
00236 Itor1 search (const Itor1& beg, const Itor1& end, 
00237            const Itor2& searchBeg, const Itor2& searchEnd)
00238 {
00239   return Aleph::search (beg, end, searchBeg, searchEnd, 
00240                Aleph::equal_to<typename Itor1::value_type>());
00241 } 
00242 
00243 
00244     template<class Itor1, class Itor2, class BinaryPredicate> inline
00245 Itor1 find_end (Itor1 beg, Itor1 end, 
00246           Itor2 searchBeg, Itor2 searchEnd, 
00247           BinaryPredicate op)
00248 {
00249   /* 
00250      Puesto que se busca entre [searchBeg .. searchEnd), debemos
00251      decrementar ambos iteradores en sus extremos end. La busqueda
00252      sera equivalente a ladel primer rango (search) pero de derecha a
00253      izquierda
00254   */ 
00255 
00256       /* Respaldo de searchBeg, pues sera decrementado */
00257   Itor2 searchFirst = searchBeg;
00258 
00259       /* Decrementamos extremo izquierdo, pues sino el while se detiene
00260       sin verificar el primer elemento del sub-rango */
00261   --beg;
00262   --searchBeg;
00263 
00264   Itor1 backup_end = end;
00265 
00266       /* Ahora decrementamos el extremo derecho, pues este no es parte del
00267       rango buscado */
00268   --end;
00269   --searchEnd;
00270 
00271   Itor1 first;
00272   Itor2 pivot = searchEnd;
00273   int count = 0;
00274 
00275   while (beg not_eq end and pivot not_eq searchBeg)
00276     {     
00277       if (op(*end, *pivot))
00278      { /* Va coincidiendo el rango */
00279        if (*searchFirst == *end and count > 0)
00280          first = end;
00281        --pivot;
00282        ++count;
00283      }
00284       else
00285      {
00286        pivot = searchEnd;
00287        count = 0;
00288      }
00289 
00290       --end;
00291     }
00292      
00293   if (pivot == searchBeg)
00294     return first;
00295 
00296   return backup_end;     
00297 }
00298 
00299 
00300     template<class Itor1, class Itor2> inline
00301 Itor1 find_end (const Itor1& beg, Itor1 end, 
00302           const Itor2& searchBeg, Itor2 searchEnd)
00303 {
00304   return Aleph::find_end (beg, end, searchBeg, searchEnd, 
00305                  Aleph::equal_to<typename Itor1::value_type>());
00306 }
00307 
00308 
00309     template<class Itor1, class Itor2, class BinaryPredicate> inline
00310 Itor1 find_first_of (const Itor1& beg, const Itor1& end, 
00311                Itor2 searchBeg, const Itor2& searchEnd, 
00312                BinaryPredicate op)
00313 {
00314   while (searchBeg not_eq searchEnd)
00315     {
00316       Itor1 current = beg;
00317 
00318       while (current not_eq end)
00319      {
00320        if (op (*current, *searchBeg))
00321          return current;
00322 
00323        ++current;
00324      }
00325 
00326       ++searchBeg;
00327     }
00328   
00329   return end;
00330 }
00331 
00332 
00333     template<class Itor1, class Itor2> inline
00334 Itor1 find_first_of (const Itor1& beg, const Itor1& end, 
00335                const Itor2& searchBeg, const Itor2& searchEnd)
00336 {
00337   return Aleph::find_first_of (beg, end, searchBeg, searchEnd, 
00338                       Aleph::equal_to<typename Itor1::value_type>());
00339 }
00340 
00341 
00342     template<class Itor, class BinaryPredicate> inline
00343 Itor adjacent_find (Itor beg, const Itor & end, BinaryPredicate op)
00344 {
00345   Itor next (beg);
00346   ++next;
00347 
00348   while (next not_eq end)
00349     {
00350       if (op (*beg, *next))
00351      return beg;
00352 
00353       ++beg;
00354       ++next;
00355     }
00356 
00357   return end;
00358 }
00359 
00360 
00361     template<class Itor> inline
00362 Itor adjacent_find (const Itor& beg, const Itor& end)
00363 {
00364   return Aleph::adjacent_find(beg, end, 
00365                      Aleph::equal_to<typename Itor::value_type>());
00366 }
00367 
00368 
00369     template <class Itor1, class Itor2, class BinaryPredicate> inline
00370 bool equal(Itor1 beg, const Itor1 & end,
00371         Itor2 cmpBeg, BinaryPredicate op)
00372 {
00373   while (beg not_eq end)
00374     {
00375       if (not op (*beg, *cmpBeg))
00376      return false;
00377 
00378       ++beg;
00379       ++cmpBeg;
00380     }
00381 
00382   return true;
00383 }
00384 
00385 
00386     template <class Itor1, class Itor2> inline
00387 bool equal(const Itor1 & beg, const Itor1 & end, const Itor2 & cmpBeg)
00388 {
00389   return Aleph::equal(beg, end, cmpBeg, 
00390                 Aleph::equal_to<typename Itor1::value_type>());
00391 }
00392 
00393 
00394     template <class Itor1, class Itor2, class BinaryPredicate> inline
00395 Aleph::pair<Itor1, Itor2> mismatch (Itor1 beg, const Itor1& end, 
00396                         Itor2 cmpBeg, 
00397                         BinaryPredicate op)
00398 {
00399   while (beg not_eq end and op (*beg,*cmpBeg))
00400     {
00401       ++beg;
00402       ++cmpBeg;
00403     }
00404   
00405   return Aleph::make_pair (beg, cmpBeg);
00406 }
00407 
00408 
00409     template <class Itor1, class Itor2> inline
00410 Aleph::pair<Itor1, Itor2> mismatch (const Itor1& beg, const Itor1& end, 
00411                         const Itor2& cmpBeg)
00412 {
00413   return Aleph::mismatch (beg, end, cmpBeg, 
00414                  Aleph::equal_to<typename Itor1::value_type>());
00415 }
00416                
00417 
00418     template <class Itor1, class Itor2, class CompFunc> inline
00419 bool lexicographical_compare (Itor1 beg1, const Itor1 & end1, 
00420                      Itor2 beg2, const Itor2 & end2, 
00421                      CompFunc op)
00422 {
00423   while (beg1 not_eq end1 and beg2 not_eq end2) 
00424     {
00425       if (op (*beg1, *beg2))
00426      return true;
00427       else if (op (*beg2, *beg1))
00428      return false;
00429      
00430       ++beg1;
00431       ++beg2;
00432     }
00433 
00434   return beg1 == end1 and beg2 not_eq end2;
00435 }
00436 
00437 
00438     template <class Itor1, class Itor2> inline
00439 bool lexicographical_compare (const Itor1 & beg1, const Itor1 & end1, 
00440                      const Itor2 & beg2, const Itor2 & end2)
00441 {
00442   return Aleph::lexicographical_compare 
00443     (beg1, end1, beg2, end2, 
00444      Aleph::equal_to<typename Itor1::value_type>());
00445 }
00446 
00447 
00448 // Modifying Algorithms
00449 
00450     template <class Itor1, class Itor2> inline
00451 Itor2 copy (Itor1 sourceBeg, const Itor1& sourceEnd, Itor2 destBeg)
00452 {
00453   while (sourceBeg not_eq sourceEnd)
00454     destBeg++ = sourceBeg++;
00455 
00456   return destBeg;
00457 }
00458 
00459 
00460     template <class Itor1, class Itor2> inline
00461 Itor2 copy_backward (const Itor1& sourceBeg, Itor1 sourceEnd, Itor2 destEnd)
00462 {
00463   while (sourceBeg not_eq sourceEnd)
00464       destEnd-- = sourceEnd--;
00465 
00466   return destEnd;
00467 }
00468 
00469 
00470     template <class Itor1, class Itor2, class UnaryFunc> inline
00471 Itor2 transform (Itor1 sourceBeg, const Itor1& sourceEnd, 
00472            Itor2 destBeg, 
00473            UnaryFunc op)
00474 {
00475   while (sourceBeg not_eq sourceEnd)
00476     destBeg++ = op (sourceBeg++);
00477   
00478   return destBeg;
00479 }
00480 
00481 
00482     template <class Itor1, class Itor2, class Itor3, class UnaryFunc> inline
00483 Itor3 transform (Itor1 source1Beg, Itor1 source1End, 
00484            Itor2 source2Beg, 
00485            Itor3 destBeg, 
00486            UnaryFunc op)
00487 {
00488   while (source1Beg not_eq source1End)
00489     destBeg++ = op (source1Beg++, source2Beg++);
00490 
00491   return destBeg;
00492 }
00493 
00494     template <class Itor1, class Itor2> inline
00495 Itor2 swap_ranges (Itor1 beg1, const Itor1& end1, Itor2 beg2)
00496 {
00497   while (beg1 not_eq end1)
00498     Aleph::swap (beg1++, beg2++);
00499 
00500   return beg2;
00501 }
00502 
00503 
00504     template <class Itor, class T> inline
00505 void fill (Itor beg, const Itor& end, const T & value)
00506 {
00507   while (beg not_eq end)
00508     beg++ = value;
00509 }
00510 
00511 
00512     template <class Itor, class T, class Size> inline
00513 void fill_n (Itor beg, Size num, const T & value)
00514 {
00515   while (num-- > 0)
00516     beg++ = value;
00517 }    
00518 
00519 
00520     template <class Itor, class Func> inline
00521 void generate (Itor beg, const Itor& end, Func op)
00522 {
00523   while (beg not_eq end)
00524     beg++ = op ();
00525 }
00526 
00527 
00528     template <class Itor, class Size, class Func> inline
00529 void generate_n (Itor beg, Size num, Func op)
00530 {
00531   while (num-- > 0)
00532     beg++ = op ();
00533 }
00534 
00535 
00536     template <class Itor, class UnaryPredicate, class T> inline
00537 void replace_if (Itor beg, const Itor& end, 
00538            UnaryPredicate op, 
00539            const T & value)
00540 {
00541   while (beg not_eq end)
00542     {
00543       if (op (*beg))
00544      *beg = value;
00545 
00546       ++beg;
00547     }
00548 }
00549 
00550 
00551     template <class Itor, class T> inline
00552 void replace (Itor beg, const Itor& end, 
00553            const T & old_value, 
00554            const T & new_value)
00555 {
00556   Aleph::replace_if (beg, end, 
00557                Aleph::bind2nd(equal_to<T>(), old_value), new_value);
00558 }
00559 
00560 
00561     template <class Itor1, class Itor2, class UnaryPredicate, class T> inline
00562 Itor2 replace_copy_if (Itor1 sourceBeg, const Itor1& sourceEnd, 
00563                  Itor2 destBeg, 
00564                  UnaryPredicate op, 
00565                  const T & value)
00566 {
00567   while (sourceBeg not_eq sourceEnd)
00568     {
00569       if (op (*sourceBeg))
00570      *sourceBeg = value;
00571 
00572       destBeg++ = sourceBeg++;
00573     }
00574 
00575   return destBeg;
00576 }
00577 
00578 
00579     template <class Itor1, class Itor2, class T> inline
00580 Itor2 replace_copy (const Itor1& sourceBeg, const Itor1& sourceEnd, 
00581               const Itor2& destBeg, 
00582               const T & old_value, 
00583               const T & new_value)
00584 {
00585   return Aleph::replace_copy_if 
00586     (sourceBeg, sourceEnd, destBeg, 
00587      Aleph::bind2nd(equal_to<T>(), old_value), new_value);
00588 }
00589 
00590 
00591 // Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
00592 //
00593 // This file is part of the GNU ISO C++ Library.  This library is free
00594 // software; you can redistribute it and/or modify it under the
00595 // terms of the GNU General Public License as published by the
00596 // Free Software Foundation; either version 2, or (at your option)
00597 // any later version.
00598 
00599 // This library is distributed in the hope that it will be useful,
00600 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00601 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00602 // GNU General Public License for more details.
00603 
00604 // You should have received a copy of the GNU General Public License along
00605 // with this library; see the file COPYING.  If not, write to the Free
00606 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
00607 // USA.
00608 
00609 // As a special exception, you may use this file as part of a free software
00610 // library without restriction.  Specifically, if other files instantiate
00611 // templates or use macros or inline functions from this file, or you compile
00612 // this file and link it with other files to produce an executable, this
00613 // file does not by itself cause the resulting executable to be covered by
00614 // the GNU General Public License.  This exception does not however
00615 // invalidate any other reasons why the executable file might be covered by
00616 // the GNU General Public License.
00617 
00618 /*
00619  *
00620  * Copyright (c) 1994
00621  * Hewlett-Packard Company
00622  *
00623  * Permission to use, copy, modify, distribute and sell this software
00624  * and its documentation for any purpose is hereby granted without fee,
00625  * provided that the above copyright notice appear in all copies and
00626  * that both that copyright notice and this permission notice appear
00627  * in supporting documentation.  Hewlett-Packard Company makes no
00628  * representations about the suitability of this software for any
00629  * purpose.  It is provided "as is" without express or implied warranty.
00630  *
00631  *
00632  * Copyright (c) 1996
00633  * Silicon Graphics Computer Systems, Inc.
00634  *
00635  * Permission to use, copy, modify, distribute and sell this software
00636  * and its documentation for any purpose is hereby granted without fee,
00637  * provided that the above copyright notice appear in all copies and
00638  * that both that copyright notice and this permission notice appear
00639  * in supporting documentation.  Silicon Graphics makes no
00640  * representations about the suitability of this software for any
00641  * purpose.  It is provided "as is" without express or implied warranty.
00642  */
00643 
00644 
00645     template<class In_Itor, class Out_Itor, class Predicate> inline
00646 Out_Itor remove_copy_if(In_Itor __first, const In_Itor & __last,
00647                Out_Itor __result, 
00648                Predicate __pred)
00649 {
00650   for ( ; __first not_eq __last; ++__first)
00651     if (not __pred(*__first))
00652       {
00653      *__result = *__first;
00654      ++__result;
00655       }
00656 
00657   return __result;
00658 }
00659 
00660 
00661     template<class In_Itor, class Out_Itor, class T> inline
00662 Out_Itor remove_copy(const In_Itor & __first, const In_Itor & __last,
00663                const Out_Itor & __result, 
00664                const T & __value)
00665 {
00666   return Aleph::remove_copy_if(__first, __last, __result,
00667                       Aleph::bind2nd(equal_to<T>(), __value));
00668 }
00669 
00670 
00671     template<class Fw_Itor, class Predicate> inline
00672 Fw_Itor remove_if(Fw_Itor __first, const Fw_Itor & __last,
00673             Predicate __pred)
00674 {
00675   __first = Aleph::find_if(__first, __last, __pred);
00676 
00677   Fw_Itor __i = __first;
00678 
00679   if (__first == __last) 
00680     return __first;
00681   else
00682     return Aleph::remove_copy_if(++__i, __last, __first, __pred);
00683 }
00684 
00685 
00686     template<class Fw_Itor, class T> inline
00687 Fw_Itor remove(Fw_Itor __first, const Fw_Itor & __last, 
00688             const T & __value)
00689 {
00690   __first = Aleph::find(__first, __last, __value);
00691 
00692   Fw_Itor __i = __first;
00693 
00694   if (__first == __last) 
00695     return __first;
00696   else
00697     return Aleph::remove_copy(++__i, __last, __first, __value);
00698 }
00699 
00700 
00701    template<class In_Itor, class Out_Itor, class BinaryPredicate> static inline
00702 Out_Itor __unique_copy(In_Itor __first, In_Itor __last,
00703                  Out_Itor __result,
00704                  BinaryPredicate __binary_pred)
00705 {
00706   typename In_Itor::value_type __value = *__first;
00707 
00708   *__result = __value;
00709   
00710   while (++__first not_eq __last)
00711     if (not __binary_pred(__value, *__first))
00712       {
00713      __value = *__first;
00714      *++__result = __value;
00715       }
00716 
00717   
00718   return ++__result;
00719 }
00720 
00721     template<class In_Itor, class Out_Itor> static inline
00722 Out_Itor __unique_copy(In_Itor __first, In_Itor __last,
00723                  Out_Itor __result)
00724 {
00725   return Aleph::__unique_copy(__first, __last, __result, 
00726                      Aleph::equal_to<typename In_Itor::value_type>());
00727 }
00728 
00729 
00730     template<class In_Itor, class Out_Itor> inline
00731 Out_Itor unique_copy(In_Itor __first, In_Itor __last,
00732                Out_Itor __result)
00733 {
00734   if (__first == __last) 
00735     return __result;
00736    
00737   return Aleph::__unique_copy(__first, __last, __result);
00738 }
00739 
00740 
00741 template<class In_Itor, class Out_Itor, class BinaryPredicate> inline
00742 Out_Itor unique_copy(In_Itor __first, In_Itor __last,
00743                Out_Itor __result,
00744                BinaryPredicate __binary_pred)
00745 {
00746   return Aleph::__unique_copy(__first, __last, __result, __binary_pred);
00747 }
00748 
00749 
00750     template<class Itor, class BinaryPredicate> inline
00751 Itor unique(Itor __first, Itor __last, BinaryPredicate __binary_pred)
00752 {
00753   // Skip the beginning, if already unique.
00754   __first = Aleph::adjacent_find(__first, __last, __binary_pred);
00755 
00756   if (__first == __last)
00757     return __last;
00758 
00759   // Do the real copy work.
00760   Itor __dest = __first;
00761   ++__first;
00762 
00763   while (++__first not_eq __last)
00764     if (not __binary_pred(*__dest, *__first))
00765       *++__dest = *__first;
00766   
00767   return ++__dest;
00768 }
00769 
00770 
00771     template<class Itor> inline
00772 Itor unique(Itor first, Itor last)
00773 {
00774   return
00775     Aleph::unique(first, last, Aleph::equal_to<typename Itor::value_type>());
00776 }
00777 
00778 
00779 
00780 // MUTATING ALGORITHMS
00781 
00782 
00783     template <class Itor> inline
00784 void reverse(Itor beg, Itor end)
00785 {
00786   while (beg not_eq end)
00787     Aleph::swap(beg++, --end);
00788 }
00789 
00790 
00791     template <class Itor1, class Itor2> inline
00792 Itor2 reverse_copy(Itor1 sourceBeg, Itor1 sourceEnd, Itor2 destBeg)
00793 {
00794   while (sourceBeg not_eq sourceEnd)
00795     {
00796       --sourceEnd;
00797       *destBeg = *sourceEnd;
00798       ++destBeg;
00799     }
00800      
00801   return destBeg;
00802 }
00803 
00804 
00805     template <class Itor>
00806 void rotate(Itor beg, Itor pos, Itor end)
00807 {
00808   Aleph::reverse(beg, pos);
00809   Aleph::reverse(pos, end);
00810   Aleph::reverse(beg, end);
00811 }
00812 
00813 
00814     template <class Itor1, class Itor2> inline
00815 Itor2 rotate_copy (const Itor1& beg, const Itor1& pos, const Itor1& end, 
00816              const Itor2& tgt_beg)
00817 {
00818   return Aleph::copy(beg, pos, Aleph::copy(pos, end, tgt_beg));
00819 }
00820 
00821 # ifdef nada
00822 
00823 template<typename Itor> inline
00824 bool next_permutation(Itor first, Itor last)
00825 {
00826   if (first == last)
00827     return false;
00828 
00829   Itor __i = __first;
00830   ++__i;
00831    
00832   if (__i == __last)
00833     return false;
00834     
00835   __i = __last;
00836   --__i;
00837 
00838   while (true)
00839     {
00840       Itor __ii = __i;
00841       --__i;
00842      
00843       if (*__i < *__ii)
00844      {
00845        Itor __j = __last;
00846        
00847        while (not (*__i < *--__j)) 
00848          {}
00849            
00850        std::iter_swap(__i, __j);
00851        std::reverse(__ii, __last);
00852        
00853        return true;
00854      }
00855      
00856       if (__i == __first)
00857      {
00858        std::reverse(__first, __last);
00859        return false;
00860      }
00861     }
00862 }
00863 
00864 
00865     template<class Itor, class Compare> inline
00866 bool next_permutation(Itor first, Itor last, Compare comp)
00867 {
00868   if (first == last)
00869     return false;
00870 
00871   Itor i = first;
00872   ++i;
00873 
00874   if (i == last)
00875     return false;
00876 
00877   i = last;
00878   --i;
00879 
00880   while (true)
00881     {
00882       Itor ii = i;
00883       --i;
00884 
00885       if (comp(*i, *ii))
00886      {
00887        Itor j = last;
00888 
00889        while (not comp(*i, *--j)) { /* empty */ }
00890            
00891        std::iter_swap(i, j);
00892        Aleph::reverse(ii, last);
00893 
00894        return true;
00895      }
00896       
00897       if (i == first)
00898      {
00899        Aleph::reverse(first, last);
00900 
00901        return false;
00902      }
00903     }
00904 }
00905 
00918   template<typename Itor>
00919     bool
00920     prev_permutation(Itor first,
00921                Itor last)
00922     {
00923       // concept requirements
00924       glibcxx_function_requires(ItorConcept<
00925                       Itor>)
00926       glibcxx_function_requires(_LessThanComparableConcept<
00927          typename iterator_traits<Itor>::value_type>)
00928       glibcxx_requires_valid_range(first, last);
00929 
00930       if (first == last)
00931      return false;
00932       Itor i = first;
00933       ++i;
00934       if (i == last)
00935      return false;
00936       i = last;
00937       --i;
00938 
00939       for(;;)
00940      {
00941        Itor ii = i;
00942        --i;
00943        if (*ii < *i)
00944          {
00945            Itor j = last;
00946            while (!(*--j < *i))
00947           {}
00948            std::iter_swap(i, j);
00949            std::reverse(ii, last);
00950            return true;
00951          }
00952        if (i == first)
00953          {
00954            std::reverse(first, last);
00955            return false;
00956          }
00957      }
00958     }
00959 
00974   template<typename Itor, typename _Compare>
00975     bool
00976     prev_permutation(Itor first,
00977                Itor last, _Compare comp)
00978     {
00979       // concept requirements
00980       glibcxx_function_requires(ItorConcept<
00981                       Itor>)
00982       glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
00983          typename iterator_traits<Itor>::value_type,
00984          typename iterator_traits<Itor>::value_type>)
00985       glibcxx_requires_valid_range(first, last);
00986 
00987       if (first == last)
00988      return false;
00989       Itor i = first;
00990       ++i;
00991       if (i == last)
00992      return false;
00993       i = last;
00994       --i;
00995 
00996       for(;;)
00997      {
00998        Itor ii = i;
00999        --i;
01000        if (comp(*ii, *i))
01001          {
01002            Itor j = last;
01003            while (!comp(*--j, *i))
01004           {}
01005            std::iter_swap(i, j);
01006            std::reverse(ii, last);
01007            return true;
01008          }
01009        if (i == first)
01010          {
01011            std::reverse(first, last);
01012            return false;
01013          }
01014      }
01015     }
01016 
01017   // find_first_of, with and without an explicitly supplied comparison function.
01018 
01033   template<typename _InputIterator, typename _ForwardIterator>
01034     _InputIterator
01035     find_first_of(_InputIterator first1, _InputIterator last1,
01036             _ForwardIterator first2, _ForwardIterator last2)
01037     {
01038       // concept requirements
01039       glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
01040       glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
01041       glibcxx_function_requires(_EqualOpConcept<
01042          typename iterator_traits<_InputIterator>::value_type,
01043          typename iterator_traits<_ForwardIterator>::value_type>)
01044       glibcxx_requires_valid_range(first1, last1);
01045       glibcxx_requires_valid_range(first2, last2);
01046 
01047       for ( ; first1 != last1; ++first1)
01048      for (_ForwardIterator iter = first2; iter != last2; ++iter)
01049        if (*first1 == *iter)
01050          return first1;
01051       return last1;
01052     }
01053 
01054 
01055 template<class Itor>
01056 bool next_permutation (Itor beg, Itor end)
01057 {
01058 
01059 }
01060 
01061 
01062 template<class Itor>
01063 bool prev_permutation (Itor beg, Itor end)
01064 {
01065 
01066 }
01067 
01068 
01069 template<class Itor>
01070 void random_shuffle (Itor beg, Itor end)
01071 {
01072 
01073 }
01074 
01075 
01076 template<class Itor, class RandomFunc>
01077 void random_shuffle (Itor beg, Itor end, RandomFunc& op)
01078 {
01079   if (beg == end) 
01080     return;
01081           
01082   Itor iter(beg);
01083      
01084   while(iter not_eq end)
01085     {   
01086       iter_swap(iter, beg + op((i - beg) + 1));
01087       ++iter;
01088     }
01089 
01090 }
01091 
01092 
01093 template<class Itor, class UnaryPredicate>
01094 Itor partition (Itor beg, Itor end, UnaryPredicate op)
01095 {
01096 
01097 }
01098 
01099 
01100 template<class Itor, class UnaryPredicate>
01101 Itor stable_partition (Itor beg, Itor end, UnaryPredicate op)
01102 {
01103 
01104 }
01105 
01106 
01107 // SORTING ALGORITHMS
01108 
01109 // OJO
01110 
01111 template<class Itor>
01112 void sort (Itor beg, Itor end)
01113 {
01114  
01115 }
01116 
01117 
01118 template<class Itor, class BinaryPredicate>
01119 void sort (Itor beg, Itor end, BinaryPredicate op)
01120 {
01121 
01122 }
01123 
01124 
01125 template<class Itor>
01126 void stable_sort (Itor beg, Itor end)
01127 {
01128 
01129 }
01130 
01131 
01132 template<class Itor, class BinaryPredicate>
01133 void stable_sort (Itor beg, Itor end, BinaryPredicate op)
01134 {
01135 
01136 }
01137 
01138 
01139 template <class Itor>
01140 void partial_sort (Itor beg, Itor sortEnd, Itor end)
01141 {
01142 
01143 }
01144 
01145 
01146 template <class Itor, class BinaryPredicate>
01147 void partial_sort (Itor beg, Itor sortEnd, Itor end, BinaryPredicate op)
01148 {
01149 
01150 }
01151 
01152 
01153 template <class Itor1, class Itor2>
01154 Itor2 partial_sort_copy (Itor1 sourceBeg, Itor2 sourceEnd, Itor2 destBeg, Itor2 destEnd)
01155 {
01156 
01157 }
01158 
01159 
01160 template <class Itor1, class Itor2, class BinaryPredicate>
01161 Itor2 partial_sort_copy (Itor1 sourceBeg, Itor2 sourceEnd, Itor2 destBeg, Itor2 destEnd, BinaryPredicate op)
01162 {
01163 
01164 }
01165 
01166 
01167 template <class Itor>
01168 void nth_element (Itor beg, Itor nth, Itor end)
01169 {
01170 
01171 }
01172 
01173 
01174 template <class Itor, class BinaryPredicate>
01175 void nth_element (Itor beg, Itor nth, Itor end, BinaryPredicate op)
01176 {
01177 
01178 }
01179 
01180 
01181 template  <class Itor>
01182 void make_heap (Itor beg, Itor end)
01183 {
01184 
01185 }
01186 
01187 
01188 template  <class Itor, class BinaryPredicate>
01189 void make_heap (Itor beg, Itor end, BinaryPredicate op)
01190 {
01191 
01192 }
01193 
01194 
01195 template <class Itor>
01196 void push_heap (Itor beg, Itor end)
01197 {
01198 
01199 }
01200 
01201 
01202 template <class Itor, class BinaryPredicate>
01203 void push_heap (Itor beg, Itor end, BinaryPredicate op)
01204 {
01205 
01206 }
01207 
01208 
01209 template <class Itor>
01210 void pop_heap (Itor beg, Itor end)
01211 {
01212 
01213 }
01214 
01215 
01216 template <class Itor, class BinaryPredicate>
01217 void pop_heap (Itor beg, Itor end, BinaryPredicate op)
01218 {
01219 
01220 }
01221 
01222 
01223 template <class Itor>
01224 void sort_heap (Itor beg, Itor end)
01225 {
01226 
01227 }
01228 
01229 
01230 template <class Itor, class BinaryPredicate>
01231 void sort_heap (Itor beg, Itor end, BinaryPredicate op)
01232 {
01233 
01234 }
01235 
01236 
01237 // SORTED RANGE ALGORITHMS
01238 
01239 
01240 template<class Itor, class T>
01241 bool binary_search(Itor beg, Itor end, const T& value)
01242 {
01243   Itor i(lower_bound(beg, end, value));
01244   return i not_eq last and not(value < *i);
01245 }
01246 
01247 
01248 template<class Itor, class T, class BinaryPredicate>
01249 bool binary_search(Itor beg, Itor end, const T& value, BinaryPredicate op)
01250 {
01251   Itor i = lower_bound(beg, end, value, op);
01252   return i not_eq last and not(comp(value, *i));
01253 }
01254 
01255 
01256 template <class Itor1, class Itor2>
01257 bool includes (Itor1 beg, Itor1 end, Itor2 searchBeg, Itor2 searchEnd)
01258 {
01259   while (beg not_eq end and searchBeg not_eq searchEnd)
01260     {
01261       if (*searchBeg > *beg)
01262      ++beg;
01263       
01264       else
01265      {         
01266        if (*searchBeg == *beg)
01267          {
01268            ++searchBeg;
01269            
01270            if (*searchBeg > *beg)
01271           ++beg;
01272          }
01273        
01274        else
01275          return false;
01276      }
01277     }
01278   
01279   return true;
01280 }
01281 
01282 
01283 template <class Itor1, class Itor2, class BinaryPredicate>
01284 bool includes (Itor1 beg, Itor1 end, Itor2 searchBeg, Itor2 searchEnd, BinaryPredicate op)
01285 {
01286      
01287 }
01288 
01289 
01290 template <class Itor, class T>
01291 Itor lower_bound (Itor beg, Itor end, const T& value)
01292 {
01293   while (beg not_eq end and *beg < value)
01294     ++beg;
01295 
01296   return beg;
01297 }
01298 
01299 
01300 template <class Itor, class T, class BinaryPredicate>
01301 Itor lower_bound (Itor beg, Itor end, const T& value, BinaryPredicate op)
01302 {
01303   while (beg not_eq end and op(*beg,value))
01304     ++beg;
01305 
01306   return beg;
01307 }
01308 
01309 
01310 template <class Itor, class T>
01311 Itor upper_bound (Itor beg, Itor end, const T& value)
01312 {
01313   while (beg not_eq end and *beg <= value)
01314     ++beg;
01315 
01316   return beg;
01317 }
01318 
01319 
01320 template <class Itor, class T, class BinaryPredicate>
01321 Itor upper_bound (Itor beg, Itor end, const T& value, BinaryPredicate op)
01322 {
01323   while (beg not_eq end and (op(*beg,value) or *beg == value))
01324     ++beg;
01325 
01326   return beg;
01327 }
01328 
01329 
01330 template <class Itor, class T>
01331 pair<Itor, Itor> equal_range (Itor beg, Itor end, const T& value)
01332 {
01333   pair<Itor,Itor> _pair;
01334   Itor _first = lower_bound(beg, end, value);
01335   Itor _second = upper_bound(beg, end, value);
01336   _pair.first = _first;
01337   _pair.second = _second;
01338 
01339 
01340   return _pair;
01341 }
01342 
01343 
01344 template <class Itor, class T, class BinaryPredicate>
01345 pair<Itor, Itor> equal_range (Itor beg, Itor end, const T& value, BinaryPredicate op)
01346 {
01347   return make_pair(lower_bound(beg, end, value, op), upper_bound(beg, end, value, op));
01348 }
01349 
01350 
01351 template <class Itor1, class Itor2, class Itor3>
01352 Itor3 merge(Itor1 source1Beg, Itor1 source1End, Itor2 source2Beg, Itor2 source2End, Itor3 destBeg) 
01353 {
01354   while (source1Beg not_eq source1End and source2Beg not_eq source2End) 
01355     {
01356       if (*source2Beg < *source1Beg) 
01357      {
01358        *destBeg = *source2Beg;
01359        ++source2Beg;
01360      }
01361       else 
01362      {
01363        *destBeg = *source1Beg;
01364        ++source1Beg;
01365      }
01366       ++destBeg;
01367     }
01368   return copy(source2Beg, source2End, copy(source1Beg, source1End, destBeg));
01369 }
01370 
01371 
01372 template <class Itor1, class Itor2, class Itor3, class BinaryPredicate>
01373 Itor3 merge(Itor1 source1Beg, Itor1 source1End, Itor2 source2Beg, Itor2 source2End, Itor3 destBeg, BinaryPredicate op) 
01374 {
01375   while (source1Beg != source1End && source2Beg != source2End) 
01376     {
01377       if (op(*source2Beg, *source1Beg)) 
01378      {
01379        *destBeg = *source2Beg;
01380        ++source2Beg;
01381      }
01382       else 
01383      {
01384        *destBeg = *source1Beg;
01385        ++source1Beg;
01386      }
01387       ++destBeg;
01388     }
01389   return copy(source2Beg, source2End, copy(source1Beg, source1End, destBeg));
01390 }
01391 
01392 
01393 template <class Itor1, class Itor2, class Itor3>
01394 Itor3 set_union (Itor1 source1Beg, Itor1 source1End, Itor2 source2Beg, Itor2 source2End, Itor3 destBeg)
01395 {
01396 
01397 }
01398 
01399 
01400 template <class Itor1, class Itor2, class Itor3, class BinaryPredicate>
01401 Itor3 set_union (Itor1 source1Beg, Itor1 source1End, Itor2 source2Beg, Itor2 source2End, Itor3 destBeg,
01402            BinaryPredicate op)
01403 {
01404 
01405 }
01406 
01407 
01408 template <class Itor1, class Itor2, class Itor3>
01409 Itor3 set_intersection (Itor1 source1Beg, Itor1 source1End, Itor2 source2Beg, Itor2 source2End, Itor3 destBeg)
01410 {
01411 
01412 }
01413 
01414 
01415 template <class Itor1, class Itor2, class Itor3, class BinaryPredicate>
01416 Itor3 set_intersection (Itor1 source1Beg, Itor1 source1End, 
01417                Itor2 source2Beg, Itor2 source2End, Itor3 destBeg,
01418                BinaryPredicate op)
01419 {
01420 
01421 }
01422 
01423 
01424 template <class Itor1, class Itor2, class Itor3>
01425 Itor3 set_difference (Itor1 source1Beg, Itor1 source1End,
01426                 Itor2 source2Beg, Itor2 source2End, Itor3 destBeg)
01427 {
01428 
01429 }
01430 
01431 
01432 template <class Itor1, class Itor2, class Itor3, class BinaryPredicate>
01433 Itor3 set_difference (Itor1 source1Beg, Itor1 source1End,
01434                 Itor2 source2Beg, Itor2 source2End, Itor3 destBeg,
01435                 BinaryPredicate op)
01436 {
01437 
01438 }
01439 
01440 
01441 template <class Itor1, class Itor2, class Itor3>
01442 Itor3 set_symmetric_difference (Itor1 source1Beg, Itor1 source1End,
01443                     Itor2 source2Beg, Itor2 source2End, Itor3 destBeg)
01444 {
01445 
01446 }
01447 
01448 
01449 template <class Itor1, class Itor2, class Itor3, class BinaryPredicate>
01450 Itor3 set_symmetric_difference (Itor1 source1Beg, Itor1 source1End,
01451                     Itor2 source2Beg, Itor2 source2End, Itor3 destBeg,
01452                     BinaryPredicate op)
01453 {
01454 
01455 }
01456 
01457 
01458 template <class Itor>
01459 void inplace_merge (Itor beg1, Itor end1beg2, Itor end2)
01460 {
01461 
01462 }
01463 
01464 
01465 template <class Itor, class BinaryPredicate>
01466 void inplace_merge (Itor beg1, Itor end1beg2, Itor end2, BinaryPredicate op)
01467 {
01468 
01469 }
01470 
01471 
01472 // ALGORITMOS NUMERICOS
01473 
01474 
01475 template <class Itor, class T>
01476 T accumulate (Itor beg, Itor end, T initValue)
01477 {
01478   for( /* nothing */ ; beg not_eq end; ++beg)
01479     initValue = initValue + *beg;
01480 
01481   return initValue;
01482 }
01483 
01484 
01485 template <class Itor, class T, class BinaryFunc>
01486 T accumulate (Itor beg, Itor end, T initValue, BinaryFunc op)
01487 {
01488   for( /* nothing */ ; beg not_eq end; ++beg)
01489     initValue = op(initValue, *beg);
01490 
01491   return initValue;
01492 }
01493 
01494 
01495 template <class Itor1, class Itor2, class T>
01496 T inner_product (Itor1 beg1, Itor1 end1, Itor2 beg2, T initValue)
01497 {
01498   for (/*nothing*/; beg1 not_eq end1; ++beg1, ++beg2)
01499     initValue = initValue + (*beg1 * *beg2);
01500 
01501   return initValue;
01502 }
01503 
01504 
01505 template <class Itor1, class Itor2, class T, class BinaryFunc>
01506 T inner_product (Itor1 beg1, Itor1 end1, Itor2 beg2, T initValue, BinaryFunc op1, BinaryFunc op2)
01507 {
01508   for (/*nothing*/; beg1 not_eq end1; ++beg1, ++beg2)
01509     initValue = op1(initValue, op2(*beg1, *beg2));
01510 
01511   return initValue;
01512 }
01513 
01514 
01515 template <class Itor1, class Itor2, class T>
01516 Itor2 partial_sum (Itor1 sourceBeg, Itor1 sourceEnd, Itor2 destBeg)
01517 {
01518   T sum = *sourceBeg;
01519   sum = 0;
01520 
01521   for (/*nothing*/; sourceBeg not_eq sourceEnd; ++sourceBeg, ++destBeg)
01522     {
01523       sum = sum + *sourceBeg;
01524       *destBeg = sum;
01525     }
01526 
01527   return destBeg;
01528 }
01529 
01530 
01531 template <class Itor1, class Itor2, class BinaryFunc, class T>
01532 Itor2 partial_sum (Itor1 sourceBeg, Itor1 sourceEnd, Itor2 destBeg, BinaryFunc op)
01533 {
01534   T sum = *sourceBeg;
01535   sum = 0;
01536 
01537   for (unsigned int i = 0; sourceBeg not_eq sourceEnd; ++sourceBeg, ++destBeg, i++)
01538     {
01539       if (i = 0)
01540      sum = *sourceBeg;
01541           
01542       else
01543      sum = op(sum,*sourceBeg);
01544           
01545       *destBeg = sum;
01546     }
01547 
01548   return destBeg;
01549 }    
01550 
01551 
01552 template <class Itor1, class Itor2, class T>
01553 Itor2 adjacent_difference (Itor1 sourceBeg, Itor1 sourceEnd, Itor2 destBeg)
01554 {
01555   T diff = *sourceBeg;
01556   diff = 0;
01557 
01558   for (/*nothing*/; sourceBeg not_eq sourceEnd; ++sourceBeg, ++destBeg)
01559     {
01560       *destBeg = *sourceBeg - diff;
01561       diff = *sourceBeg;
01562     }
01563 
01564   return destBeg;
01565 }
01566 
01567 
01568 template <class Itor1, class Itor2, class BinaryFunc, class T>
01569 Itor2 adjacent_difference (Itor1 sourceBeg, Itor1 sourceEnd, Itor2 destBeg, BinaryFunc op)
01570 {
01571   T diff = *sourceBeg;
01572   diff = 0;
01573 
01574   for (unsigned int i = 0; sourceBeg not_eq sourceEnd; ++sourceBeg, ++destBeg, i++)
01575     {
01576       if (i = 0)
01577      *destBeg = *sourceBeg;
01578           
01579       else
01580      *destBeg = op(*sourceBeg, diff);
01581           
01582       diff = *sourceBeg;
01583     }
01584 
01585   return destBeg;
01586 }
01587 
01588 # endif //nada
01589 
01590 }; // end namespace Aleph
01591 
01592 # endif // AHALGO_H

Leandro R. León