STLSoft - ... Robust, Lightweight, Cross-platform, Template Software ... ATLSTL - Template Software for the Active Template Library COMSTL - The Standard Template Library meets the Component Object Model .netSTL - Standard Template Library meets the Microsoft.NET Common Language Runtime InetSTL - The Standard Template Library meets WinInet MFCSTL - Template Software for the Microsoft Foundation Classes UNIXSTL - Template Software for the UNIX Operating System WinSTL - where the Standard Template Library meets the Win32 API

Main Page   Modules   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

algorithms.hpp

Go to the documentation of this file.
00001 /* 
00002  * File:        rangelib/algorithms.hpp
00003  *
00004  * Purpose:     Range algorithms.
00005  *
00006  * Created:     4th November 2003
00007  * Updated:     12th September 2004
00008  *
00009  * Home:        http://stlsoft.org/
00010  *
00011  * Copyright (c) 2003-2004, Matthew Wilson and Synesis Software
00012  * All rights reserved.
00013  *
00014  * Redistribution and use in source and binary forms, with or without
00015  * modification, are permitted provided that the following conditions are met:
00016  *
00017  * - Redistributions of source code must retain the above copyright notice, this
00018  *   list of conditions and the following disclaimer.
00019  * - Redistributions in binary form must reproduce the above copyright notice,
00020  *   this list of conditions and the following disclaimer in the documentation
00021  *   and/or other materials provided with the distribution.
00022  * - Neither the name(s) of Matthew Wilson and Synesis Software nor the names of
00023  *   any contributors may be used to endorse or promote products derived from
00024  *   this software without specific prior written permission.
00025  *
00026  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00027  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00028  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00029  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00030  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00031  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00032  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00033  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00034  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00035  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00036  * POSSIBILITY OF SUCH DAMAGE.
00037  *
00038  * 
00039 
00040 
00043 #ifndef STLSOFT_INCL_RANGELIB_HPP_ALGORITHMS
00044 #define STLSOFT_INCL_RANGELIB_HPP_ALGORITHMS
00045 
00046 #ifndef __STLSOFT_DOCUMENTATION_SKIP_SECTION
00047 # define STLSOFT_VER_RANGELIB_HPP_ALGORITHMS_MAJOR    1
00048 # define STLSOFT_VER_RANGELIB_HPP_ALGORITHMS_MINOR    7
00049 # define STLSOFT_VER_RANGELIB_HPP_ALGORITHMS_REVISION 3
00050 # define STLSOFT_VER_RANGELIB_HPP_ALGORITHMS_EDIT     14
00051 #endif /* !__STLSOFT_DOCUMENTATION_SKIP_SECTION */
00052 
00053 /* 
00054  * Includes
00055  */
00056 
00057 #ifndef STLSOFT_INCL_H_STLSOFT
00058 # include <stlsoft.h>                   // Include the STLSoft root header
00059 #endif /* !STLSOFT_INCL_H_STLSOFT */
00060 #ifndef STLSOFT_INCL_RANGELIB_HPP_RANGE_CATEGORIES
00061 # include <rangelib/range_categories.hpp>
00062 #endif /* !STLSOFT_INCL_RANGELIB_HPP_RANGE_CATEGORIES */
00063 #ifndef STLSOFT_INCL_RANGELIB_HPP_BASIC_INDIRECT_RANGE_ADAPTOR
00064 # include <rangelib/basic_indirect_range_adaptor.hpp>
00065 #endif /* !STLSOFT_INCL_RANGELIB_HPP_BASIC_INDIRECT_RANGE_ADAPTOR */
00066 #include <algorithm>
00067 #include <numeric>
00068 
00069 /* 
00070  * Namespace
00071  */
00072 
00073 #ifndef _STLSOFT_NO_NAMESPACE
00074 namespace stlsoft
00075 {
00076 #endif /* _STLSOFT_NO_NAMESPACE */
00077 
00078 /* 
00079 
00084 
00085 /* 
00086  * Functions
00087  */
00088 
00089 /* *********************************************************
00090  * accumulate (2)
00091  */
00092 
00093 template<   ss_typename_param_k R
00094         ,   ss_typename_param_k T
00095         >
00096 inline T r_accumulate_2_impl(R r, T val, notional_range_tag const &)
00097 {
00098     for(; r; ++r)
00099     {
00100         val = val + *r;
00101     }
00102 
00103     return val;
00104 }
00105 
00106 template<   ss_typename_param_k R
00107         ,   ss_typename_param_k T
00108         >
00109 inline T r_accumulate_2_impl(R r, T val, iterable_range_tag const &)
00110 {
00111     return std::accumulate(r.begin(), r.end(), val);
00112 }
00113 
00114 template<   ss_typename_param_k R
00115         ,   ss_typename_param_k T
00116         >
00117 inline T r_accumulate_2_impl(R r, T val, basic_indirect_range_tag const &)
00118 {
00119     return indirect_range_adaptor<R>(r).accumulate(val);
00120 }
00121 
00122 template<   ss_typename_param_k R
00123         ,   ss_typename_param_k T
00124         >
00125 inline T r_accumulate_2_impl(R r, T val, indirect_range_tag const &)
00126 {
00127     return r.accumulate(val);
00128 }
00129 
00137 template<   ss_typename_param_k R
00138         ,   ss_typename_param_k T
00139         >
00140 inline T r_accumulate(R r, T val)
00141 {
00142     return r_accumulate_2_impl(r, val, r);
00143 }
00144 
00145 /* *********************************************************
00146  * accumulate (3)
00147  */
00148 
00149 template<   ss_typename_param_k R
00150         ,   ss_typename_param_k T
00151         ,   ss_typename_param_k P
00152         >
00153 inline T r_accumulate_3_impl(R r, T val, P pr, notional_range_tag const &)
00154 {
00155     for(; r; ++r)
00156     {
00157         val = pr(val, *r);
00158     }
00159 
00160     return val;
00161 }
00162 
00163 template<   ss_typename_param_k R
00164         ,   ss_typename_param_k T
00165         ,   ss_typename_param_k P
00166         >
00167 inline T r_accumulate_3_impl(R r, T val, P pr, iterable_range_tag const &)
00168 {
00169     return std::accumulate(r.begin(), r.end(), val, pr);
00170 }
00171 
00172 template<   ss_typename_param_k R
00173         ,   ss_typename_param_k T
00174         ,   ss_typename_param_k P
00175         >
00176 inline T r_accumulate_2_impl(R r, T val, P pr, basic_indirect_range_tag const &)
00177 {
00178     return indirect_range_adaptor<R>(r).accumulate(val, pr);
00179 }
00180 
00181 template<   ss_typename_param_k R
00182         ,   ss_typename_param_k T
00183         ,   ss_typename_param_k P
00184         >
00185 inline T r_accumulate_3_impl(R r, T val, P pr, indirect_range_tag const &)
00186 {
00187     return r.accumulate(val, pr);
00188 }
00189 
00198 template<   ss_typename_param_k R
00199         ,   ss_typename_param_k T
00200         ,   ss_typename_param_k P
00201         >
00202 inline T r_accumulate(R r, T val, P pr)
00203 {
00204     return r_accumulate_3_impl(r, val, pr, r);
00205 }
00206 
00207 
00208 /* *********************************************************
00209  * copy
00210  */
00211 
00212 template<   ss_typename_param_k R
00213         ,   ss_typename_param_k O
00214         >
00215 inline O r_copy_impl(R r, O o, notional_range_tag const &)
00216 {
00217     for(; r; ++r, ++o)
00218     {
00219         *o = *r;
00220     }
00221 
00222     return o;
00223 }
00224 
00225 template<   ss_typename_param_k R
00226         ,   ss_typename_param_k O
00227         >
00228 inline O r_copy_impl(R r, O o, iterable_range_tag const &)
00229 {
00230     return std::copy(r.begin(), r.end(), o);
00231 }
00232 
00233 template<   ss_typename_param_k R
00234         ,   ss_typename_param_k O
00235         >
00236 inline O r_copy_impl(R r, O o, indirect_range_tag const &)
00237 {
00238     return r.copy(o);
00239 }
00240 
00241 template<   ss_typename_param_k R
00242         ,   ss_typename_param_k O
00243         >
00244 inline O r_copy_impl(R r, O o, basic_indirect_range_tag const &)
00245 {
00246     return indirect_range_adaptor<R>(r).copy(o);
00247 }
00248 
00255 template<   ss_typename_param_k R
00256         ,   ss_typename_param_k O
00257         >
00258 inline O r_copy(R r, O o)
00259 {
00260     return r_copy_impl(r, o, r);
00261 }
00262 
00263 
00264 /* *********************************************************
00265  * count
00266  */
00267 
00268 template<   ss_typename_param_k R
00269         ,   ss_typename_param_k T
00270         >
00271 inline ss_size_t r_count_impl(R r, const T &val, notional_range_tag const &)
00272 {
00273     ss_size_t n;
00274 
00275     for(n = 0; r; ++r)
00276     {
00277         if(val == *r)
00278         {
00279             ++n;
00280         }
00281     }
00282 
00283     return n;
00284 }
00285 
00286 template<   ss_typename_param_k R
00287         ,   ss_typename_param_k T
00288         >
00289 inline ss_size_t r_count_impl(R r, const T &val, iterable_range_tag const &)
00290 {
00291     return std::count(r.begin(), r.end(), val);
00292 }
00293 
00294 template<   ss_typename_param_k R
00295         ,   ss_typename_param_k T
00296         >
00297 inline ss_size_t r_count_impl(R r, const T &val, basic_indirect_range_tag const &)
00298 {
00299     return indirect_range_adaptor<R>(r).count(val);
00300 }
00301 
00302 template<   ss_typename_param_k R
00303         ,   ss_typename_param_k T
00304         >
00305 inline ss_size_t r_count_impl(R r, const T &val, indirect_range_tag const &)
00306 {
00307     return r.count(val);
00308 }
00309 
00317 template<   ss_typename_param_k R
00318         ,   ss_typename_param_k T
00319         >
00320 inline ss_size_t r_count(R r, const T &val)
00321 {
00322     return r_count_impl(r, val, r);
00323 }
00324 
00325 
00326 /* *********************************************************
00327  * count_if
00328  */
00329 
00330 template<   ss_typename_param_k R
00331         ,   ss_typename_param_k P
00332         >
00333 inline ss_size_t r_count_if_impl(R r, P pr, notional_range_tag const &)
00334 {
00335     ss_size_t n;
00336 
00337     for(n = 0; r; ++r)
00338     {
00339         if(pr(*r))
00340         {
00341             ++n;
00342         }
00343     }
00344 
00345     return n;
00346 }
00347 
00348 template<   ss_typename_param_k R
00349         ,   ss_typename_param_k P
00350         >
00351 inline ss_size_t r_count_if_impl(R r, P pr, iterable_range_tag const &)
00352 {
00353     return std::count_if(r.begin(), r.end(), pr);
00354 }
00355 
00356 template<   ss_typename_param_k R
00357         ,   ss_typename_param_k P
00358         >
00359 inline ss_size_t r_count_if_impl(R r, P pr, basic_indirect_range_tag const &)
00360 {
00361     return indirect_range_adaptor<R>(r).count_if(pr);
00362 }
00363 
00364 template<   ss_typename_param_k R
00365         ,   ss_typename_param_k P
00366         >
00367 inline ss_size_t r_count_if_impl(R r, P pr, indirect_range_tag const &)
00368 {
00369     return r.count_if(pr);
00370 }
00371 
00379 template<   ss_typename_param_k R
00380         ,   ss_typename_param_k P
00381         >
00382 inline ss_size_t r_count_if(R r, P pr)
00383 {
00384     return r_count_if_impl(r, pr, r);
00385 }
00386 
00387 
00388 /* *********************************************************
00389  * distance
00390  */
00391 
00392 template <ss_typename_param_k R>
00393 inline ss_ptrdiff_t r_distance_1_impl(R r, notional_range_tag const &)
00394 {
00395     ss_ptrdiff_t    d = 0;
00396 
00397     for(; r; ++r, ++d)
00398     {}
00399 
00400     return d;
00401 }
00402 
00403 template <ss_typename_param_k R>
00404 inline ss_ptrdiff_t r_distance_1_impl(R r, iterable_range_tag const &)
00405 {
00406     return std::distance(r.begin(), r.end());
00407 }
00408 
00409 template <ss_typename_param_k R>
00410 inline ss_ptrdiff_t r_distance_1_impl(R r, indirect_range_tag const &)
00411 {
00412     return r.distance();
00413 }
00414 
00415 template <ss_typename_param_k R>
00416 inline ss_ptrdiff_t r_distance_1_impl(R r, basic_indirect_range_tag const &)
00417 {
00418     return indirect_range_adaptor<R>(r).distance();
00419 }
00420 
00427 template <ss_typename_param_k R>
00428 inline ss_ptrdiff_t r_distance(R r)
00429 {
00430     return r_distance_1_impl(r, r);
00431 }
00432 
00433 /* *********************************************************
00434  * equal (2)
00435  */
00436 
00437 template<   ss_typename_param_k R1
00438         ,   ss_typename_param_k R2
00439         >
00440 inline ss_bool_t r_equal_1_impl(R1 r1, R2 r2, notional_range_tag const &, notional_range_tag const &)
00441 {
00442     for(; r1 && r2; ++r1, ++r2)
00443     {
00444         if(*r1 != *r2)
00445         {
00446             return false;
00447         }
00448     }
00449 
00450     return true;
00451 }
00452 
00453 template<   ss_typename_param_k R1
00454         ,   ss_typename_param_k R2
00455         >
00456 inline ss_bool_t r_equal_1_impl(R1 r1, R2 r2, iterable_range_tag const &, iterable_range_tag const &)
00457 {
00458     return std::equal(r1.begin(), r1.end(), r2.begin());
00459 }
00460 
00468 template<   ss_typename_param_k R1
00469         ,   ss_typename_param_k R2
00470         >
00471 inline ss_bool_t r_equal(R1 r1, R2 r2)
00472 {
00473     stlsoft_assert(r_distance(r1) <= r_distance(r2));
00474 
00475     return r_equal_1_impl(r1, r2, r1, r2);
00476 }
00477 
00478 /* *********************************************************
00479  * equal (3)
00480  */
00481 
00482 template<   ss_typename_param_k R1
00483         ,   ss_typename_param_k R2
00484         ,   ss_typename_param_k P
00485         >
00486 inline ss_bool_t r_equal_1_impl(R1 r1, R2 r2, P pr, notional_range_tag const &, notional_range_tag const &)
00487 {
00488     for(; r1 && r2; ++r1, ++r2)
00489     {
00490         if(!pr(*r1, *r2))
00491         {
00492             return false;
00493         }
00494     }
00495 
00496     return true;
00497 }
00498 
00499 template<   ss_typename_param_k R1
00500         ,   ss_typename_param_k R2
00501         ,   ss_typename_param_k P
00502         >
00503 inline ss_bool_t r_equal_1_impl(R1 r1, R2 r2, P pr, iterable_range_tag const &, iterable_range_tag const &)
00504 {
00505     return std::equal(r1.begin(), r1.end(), r2.begin(), pr);
00506 }
00507 
00516 template<   ss_typename_param_k R1
00517         ,   ss_typename_param_k R2
00518         ,   ss_typename_param_k P
00519         >
00520 inline ss_bool_t r_equal(R1 r1, R2 r2, P pr)
00521 {
00522     stlsoft_assert(r_distance(r1) <= r_distance(r2));
00523 
00524     return r_equal_1_impl(r1, r2, pr, r1, r2);
00525 }
00526 
00527 /* *********************************************************
00528  * exists
00529  */
00530 
00531 template<   ss_typename_param_k R
00532         ,   ss_typename_param_k T
00533         >
00534 inline ss_bool_t r_exists_impl(R r, T const &val, notional_range_tag const &)
00535 {
00536     for(; r; ++r)
00537     {
00538         if(val == *r)
00539         {
00540             return true;
00541         }
00542     }
00543 
00544     return false;
00545 }
00546 
00547 template<   ss_typename_param_k R
00548         ,   ss_typename_param_k T
00549         >
00550 inline ss_bool_t r_exists_impl(R r, T const &val, iterable_range_tag const &)
00551 {
00552     return std::find(r.begin(), r.end(), val) != r.end();
00553 }
00554 
00555 template<   ss_typename_param_k R
00556         ,   ss_typename_param_k T
00557         >
00558 inline ss_bool_t r_exists_impl(R r, T const &val, basic_indirect_range_tag const &)
00559 {
00560     return indirect_range_adaptor<R>(r).exists(val);
00561 }
00562 
00563 template<   ss_typename_param_k R
00564         ,   ss_typename_param_k T
00565         >
00566 inline ss_bool_t r_exists_impl(R r, T const &val, indirect_range_tag const &)
00567 {
00568     return r.exists(val);
00569 }
00570 
00577 template<   ss_typename_param_k R
00578         ,   ss_typename_param_k T
00579         >
00580 inline R r_exists(R r, T const &val)
00581 {
00582     return r_exists_impl(r, val, r);
00583 }
00584 
00585 /* *********************************************************
00586  * exists_if (1)
00587  */
00588 
00589 template<   ss_typename_param_k R
00590         ,   ss_typename_param_k P
00591         >
00592 inline ss_bool_t r_exists_if_1_impl(R r, P pr, notional_range_tag const &)
00593 {
00594     for(; r; ++r)
00595     {
00596         if(pr(*r))
00597         {
00598             return true;
00599         }
00600     }
00601 
00602     return false;
00603 }
00604 
00605 template<   ss_typename_param_k R
00606         ,   ss_typename_param_k P
00607         >
00608 inline ss_bool_t r_exists_if_1_impl(R r, P pr, iterable_range_tag const &)
00609 {
00610     return std::find(r.begin(), r.end(), pr) != r.end();
00611 }
00612 
00613 template<   ss_typename_param_k R
00614         ,   ss_typename_param_k P
00615         >
00616 inline ss_bool_t r_exists_if_1_impl(R r, P pr, basic_indirect_range_tag const &)
00617 {
00618     return indirect_range_adaptor<R>(r).exists_if(pr);
00619 }
00620 
00621 template<   ss_typename_param_k R
00622         ,   ss_typename_param_k P
00623         >
00624 inline ss_bool_t r_exists_if_1_impl(R r, P pr, indirect_range_tag const &)
00625 {
00626     return r.exists_if(pr);
00627 }
00628 
00635 template<   ss_typename_param_k R
00636         ,   ss_typename_param_k P
00637         >
00638 inline R r_exists_if(R r, P pr)
00639 {
00640     return r_exists_if_1_impl(r, pr, r);
00641 }
00642 
00643 /* *********************************************************
00644  * exists_if (2)
00645  */
00646 
00647 template<   ss_typename_param_k R
00648         ,   ss_typename_param_k P
00649         ,   ss_typename_param_k T
00650         >
00651 inline ss_bool_t r_exists_if_2_impl(R r, P pr, T &result, notional_range_tag const &)
00652 {
00653     for(; r; ++r)
00654     {
00655         if(pr(*r))
00656         {
00657             result = *r;
00658 
00659             return true;
00660         }
00661     }
00662 
00663     return false;
00664 }
00665 
00666 template<   ss_typename_param_k I
00667         ,   ss_typename_param_k V
00668         >
00669 inline ss_bool_t r_exists_if_2_impl_helper_(I from, I to, V &val)
00670 {
00671     if(from == to)
00672     {
00673         return false;
00674     }
00675     else
00676     {
00677         val = *from;
00678 
00679         return true;
00680     }
00681 }
00682 
00683 template<   ss_typename_param_k R
00684         ,   ss_typename_param_k P
00685         ,   ss_typename_param_k T
00686         >
00687 inline ss_bool_t r_exists_if_2_impl(R r, P pr, T &result, iterable_range_tag const &)
00688 {
00689     return r_exists_if_2_impl_helper_(std::find(r.begin(), r.end(), pr), r.end());
00690 }
00691 
00692 template<   ss_typename_param_k R
00693         ,   ss_typename_param_k P
00694         ,   ss_typename_param_k T
00695         >
00696 inline ss_bool_t r_exists_if_2_impl(R r, P pr, T &result, basic_indirect_range_tag const &)
00697 {
00698     return indirect_range_adaptor<R>(r).exists_if(pr, result);
00699 }
00700 
00701 template<   ss_typename_param_k R
00702         ,   ss_typename_param_k P
00703         ,   ss_typename_param_k T
00704         >
00705 inline ss_bool_t r_exists_if_2_impl(R r, P pr, T &result, indirect_range_tag const &)
00706 {
00707     return r.exists_if(pr, result);
00708 }
00709 
00716 template<   ss_typename_param_k R
00717         ,   ss_typename_param_k P
00718         ,   ss_typename_param_k T
00719         >
00720 inline R r_exists_if(R r, P pr, T &result)
00721 {
00722     return r_exists_if_2_impl(r, pr, result, r);
00723 }
00724 
00725 /* *********************************************************
00726  * fill
00727  */
00728 
00729 template<   ss_typename_param_k R
00730         ,   ss_typename_param_k T
00731         >
00732 inline void r_fill_impl(R r, T const &val, iterable_range_tag const &)
00733 {
00734     std::fill(r.begin(), r.end(), val);
00735 }
00736 
00743 template<   ss_typename_param_k R
00744         ,   ss_typename_param_k T
00745         >
00746 inline void r_fill(R r, const T &val)
00747 {
00748     r_fill_impl(r, val, r);
00749 }
00750 
00751 /* *********************************************************
00752  * fill_n
00753  */
00754 
00755 template<   ss_typename_param_k R
00756         ,   ss_typename_param_k S
00757         ,   ss_typename_param_k T
00758         >
00759 inline void r_fill_n_impl(R r, S n, T const &val, iterable_range_tag const &)
00760 {
00761     std::fill(r.begin(), n, val);
00762 }
00763 
00771 template<   ss_typename_param_k R
00772         ,   ss_typename_param_k S
00773         ,   ss_typename_param_k T
00774         >
00775 inline void r_fill_n(R r, S n, T const &val)
00776 {
00777     stlsoft_assert(n <= r_distance(r));
00778 
00779     r_fill_1_impl(r, n, val, r);
00780 }
00781 
00782 /* *********************************************************
00783  * find
00784  */
00785 
00786 template<   ss_typename_param_k R
00787         ,   ss_typename_param_k T
00788         >
00789 inline R r_find_impl(R r, T const &val, notional_range_tag const &)
00790 {
00791     for(; r; ++r)
00792     {
00793         if(val == *r)
00794         {
00795             break;
00796         }
00797     }
00798 
00799     return r;
00800 }
00801 
00802 template<   ss_typename_param_k R
00803         ,   ss_typename_param_k T
00804         >
00805 inline R r_find_impl(R r, T const &val, iterable_range_tag const &)
00806 {
00807     return R(std::find(r.begin(), r.end(), val), r.end());
00808 }
00809 
00816 template<   ss_typename_param_k R
00817         ,   ss_typename_param_k T
00818         >
00819 inline R r_find(R r, T const &val)
00820 {
00821     return r_find_impl(r, val, r);
00822 }
00823 
00824 /* *********************************************************
00825  * find_if
00826  */
00827 
00828 // find_if
00829 
00830 template<   ss_typename_param_k R
00831         ,   ss_typename_param_k P
00832         >
00833 inline R r_find_if_impl(R r, P pr, notional_range_tag const &)
00834 {
00835     for(; r; ++r)
00836     {
00837         if(pr(*r))
00838         {
00839             break;
00840         }
00841     }
00842 
00843     return r;
00844 }
00845 
00846 template<   ss_typename_param_k R
00847         ,   ss_typename_param_k P
00848         >
00849 inline R r_find_if_impl(R r, P pr, iterable_range_tag const &)
00850 {
00851     return R(std::find(r.begin(), r.end(), pr), r.end());
00852 }
00853 
00860 template<   ss_typename_param_k R
00861         ,   ss_typename_param_k P
00862         >
00863 inline R r_find(R r, P pr)
00864 {
00865     return r_find_if_impl(r, pr, r);
00866 }
00867 
00868 /* *********************************************************
00869  * for_each
00870  */
00871 
00872 template<   ss_typename_param_k R
00873         ,   ss_typename_param_k F
00874         >
00875 inline F r_for_each_impl(R r, F f, notional_range_tag const &)
00876 {
00877     for(; r; ++r)
00878     {
00879         f(*r);
00880     }
00881 
00882     return f;
00883 }
00884 
00885 template<   ss_typename_param_k R
00886         ,   ss_typename_param_k F
00887         >
00888 inline F r_for_each_impl(R r, F f, iterable_range_tag const &)
00889 {
00890     return std::for_each(r.begin(), r.end(), f);
00891 }
00892 
00893 template<   ss_typename_param_k R
00894         ,   ss_typename_param_k F
00895         >
00896 inline F r_for_each_impl(R r, F f, basic_indirect_range_tag const &)
00897 {
00898     return indirect_range_adaptor<R>(r).for_each(f);
00899 }
00900 
00901 template<   ss_typename_param_k R
00902         ,   ss_typename_param_k F
00903         >
00904 inline F r_for_each_impl(R r, F f, indirect_range_tag const &)
00905 {
00906     return r.for_each(f);
00907 }
00908 
00915 template<   ss_typename_param_k R
00916         ,   ss_typename_param_k F
00917         >
00918 inline F r_for_each(R r, F f)
00919 {
00920     return r_for_each_impl(r, f, r);
00921 }
00922 
00923 /* *********************************************************
00924  * generate
00925  */
00926 
00927 template<   ss_typename_param_k R
00928         ,   ss_typename_param_k F
00929         >
00930 inline void r_generate_impl(R r, F f, iterable_range_tag const &)
00931 {
00932     std::generate(r.begin(), r.end(), f);
00933 }
00934 
00941 template<   ss_typename_param_k R
00942         ,   ss_typename_param_k F
00943         >
00944 inline void r_generate(R r, F f)
00945 {
00946     r_generate_impl(r, f, r);
00947 }
00948 
00949 /* *********************************************************
00950  * max_element (1)
00951  */
00952 
00953 template <ss_typename_param_k R>
00954 inline ss_typename_type_k R::value_type r_max_element_1_impl(R r, notional_range_tag const &)
00955 {
00956     typedef ss_typename_type_k R::value_type    value_type_t;
00957 
00958     value_type_t    max_    =   value_type_t();
00959 
00960     for(; r; ++r)
00961     {
00962         if(max_ < *r)
00963         {
00964             max_ = *r;
00965         }
00966     }
00967 
00968     return max_;
00969 }
00970 
00971 template <ss_typename_param_k R>
00972 inline ss_typename_type_k R::value_type r_max_element_1_impl(R r, iterable_range_tag const &)
00973 {
00974     return *std::max_element(r.begin(), r.end());
00975 }
00976 
00977 template <ss_typename_param_k R>
00978 inline ss_typename_type_k R::value_type r_max_element_1_impl(R r, basic_indirect_range_tag const &)
00979 {
00980     return indirect_range_adaptor<R>(r).max_element();
00981 }
00982 
00983 template <ss_typename_param_k R>
00984 inline ss_typename_type_k R::value_type r_max_element_1_impl(R r, indirect_range_tag const &)
00985 {
00986     return r.max_element();
00987 }
00988 
00995 template <ss_typename_param_k R>
00996 inline ss_typename_type_k R::value_type r_max_element(R r)
00997 {
00998     stlsoft_assert(r_distance(r) > 0);
00999 
01000     return r_max_element_1_impl(r, r);
01001 }
01002 
01003 /* *********************************************************
01004  * max_element (2)
01005  */
01006 
01007 template<   ss_typename_param_k R
01008         ,   ss_typename_param_k F
01009         >
01010 inline ss_typename_type_k R::value_type r_max_element_2_impl(R r, F f, iterable_range_tag const &)
01011 {
01012     return *std::max_element(r.begin(), r.end(), f);
01013 }
01014 
01015 template<   ss_typename_param_k R
01016         ,   ss_typename_param_k F
01017         >
01018 inline ss_typename_type_k R::value_type r_max_element_2_impl(R r, F f, notional_range_tag const &)
01019 {
01020     typedef ss_typename_type_k R::value_type    value_type_t;
01021 
01022     value_type_t    max_    =   value_type_t();
01023 
01024     for(; r; ++r)
01025     {
01026         if(f(max_, *r))
01027         {
01028             max_ = *r;
01029         }
01030     }
01031 
01032     return max_;
01033 }
01034 
01035 template<   ss_typename_param_k R
01036         ,   ss_typename_param_k F
01037         >
01038 inline ss_typename_type_k R::value_type r_max_element_2_impl(R r, F f, basic_indirect_range_tag const &)
01039 {
01040     return indirect_range_adaptor<R>(r).max_element(f);
01041 }
01042 
01043 template<   ss_typename_param_k R
01044         ,   ss_typename_param_k F
01045         >
01046 inline ss_typename_type_k R::value_type r_max_element_2_impl(R r, F f, indirect_range_tag const &)
01047 {
01048     return r.max_element(f);
01049 }
01050 
01058 template<   ss_typename_param_k R
01059         ,   ss_typename_param_k F
01060         >
01061 inline ss_typename_type_k R::value_type r_max_element(R r, F f)
01062 {
01063     stlsoft_assert(r_distance(r) > 0);
01064 
01065     return r_max_element_2_impl(r, f, r);
01066 }
01067 
01068 /* *********************************************************
01069  * min_element (1)
01070  */
01071 
01072 template <ss_typename_param_k R>
01073 inline ss_typename_type_k R::value_type r_min_element_1_impl(R r, iterable_range_tag const &)
01074 {
01075     return *std::min_element(r.begin(), r.end());
01076 }
01077 
01078 template <ss_typename_param_k R>
01079 inline ss_typename_type_k R::value_type r_min_element_1_impl(R r, notional_range_tag const &)
01080 {
01081     typedef ss_typename_type_k R::value_type    value_type_t;
01082 
01083     if(!r)
01084     {
01085         return value_type_t();
01086     }
01087     else
01088     {
01089         value_type_t    min_    =   *r;
01090 
01091         for(; ++r; )
01092         {
01093             if(*r < min_)
01094             {
01095                 min_ = *r;
01096             }
01097         }
01098 
01099         return min_;
01100     }
01101 }
01102 
01103 template <ss_typename_param_k R>
01104 inline ss_typename_type_k R::value_type r_min_element_1_impl(R r, basic_indirect_range_tag const &)
01105 {
01106     return indirect_range_adaptor<R>(r).min_element();
01107 }
01108 
01109 template <ss_typename_param_k R>
01110 inline ss_typename_type_k R::value_type r_min_element_1_impl(R r, indirect_range_tag const &)
01111 {
01112     return r.min_element();
01113 }
01114 
01121 template <ss_typename_param_k R>
01122 inline ss_typename_type_k R::value_type r_min_element(R r)
01123 {
01124     stlsoft_assert(r_distance(r) > 0);
01125 
01126     return r_min_element_1_impl(r, r);
01127 }
01128 
01129 /* *********************************************************
01130  * min_element (2)
01131  */
01132 
01133 template<   ss_typename_param_k R
01134         ,   ss_typename_param_k F
01135         >
01136 inline ss_typename_type_k R::value_type r_min_element_2_impl(R r, F f, iterable_range_tag const &)
01137 {
01138     return *std::min_element(r.begin(), r.end(), f);
01139 }
01140 
01141 template<   ss_typename_param_k R
01142         ,   ss_typename_param_k F
01143         >
01144 inline ss_typename_type_k R::value_type r_min_element_2_impl(R r, F f, notional_range_tag const &)
01145 {
01146     typedef ss_typename_type_k R::value_type    value_type_t;
01147 
01148     value_type_t    min_    =   value_type_t();
01149 
01150     for(; r; ++r)
01151     {
01152         if(f(min_, *r))
01153         {
01154             min_ = *r;
01155         }
01156     }
01157 
01158     return min_;
01159 }
01160 
01161 template<   ss_typename_param_k R
01162         ,   ss_typename_param_k F
01163         >
01164 inline ss_typename_type_k R::value_type r_min_element_2_impl(R r, F f, basic_indirect_range_tag const &)
01165 {
01166     return indirect_range_adaptor<R>(r).min_element(f);
01167 }
01168 
01169 template<   ss_typename_param_k R
01170         ,   ss_typename_param_k F
01171         >
01172 inline ss_typename_type_k R::value_type r_min_element_2_impl(R r, F f, indirect_range_tag const &)
01173 {
01174     return r.min_element(f);
01175 }
01176 
01184 template<   ss_typename_param_k R
01185         ,   ss_typename_param_k F
01186         >
01187 inline ss_typename_type_k R::value_type r_min_element(R r, F f)
01188 {
01189     stlsoft_assert(r_distance(r) > 0);
01190 
01191     return r_min_element_2_impl(r, f, r);
01192 }
01193 
01194 /* *********************************************************
01195  * replace
01196  */
01197 
01198 template<   ss_typename_param_k R
01199         ,   ss_typename_param_k T
01200         >
01201 inline void r_replace_impl(R r, T oldVal, T newVal, iterable_range_tag const &)
01202 {
01203     std::replace(r.begin(), r.end(), oldVal, newVal);
01204 }
01205 
01206 template<   ss_typename_param_k R
01207         ,   ss_typename_param_k T
01208         >
01209 inline void r_replace_impl(R r, T oldVal, T newVal, indirect_range_tag const &)
01210 {
01211     r.replace(r, oldVal, newVal);
01212 }
01213 
01214 
01222 template<   ss_typename_param_k R
01223         ,   ss_typename_param_k T
01224         >
01225 inline void r_replace(R r, T oldVal, T newVal)
01226 {
01227     r_replace_impl(r, oldVal, newVal, r);
01228 }
01229 
01230 
01231 /* *********************************************************
01232  * replace_copy
01233  */
01234 
01235 #if 0
01236 template<   ss_typename_param_k RI
01237         ,   ss_typename_param_k RO
01238         ,   ss_typename_param_k T
01239         >
01240 inline void r_replace_copy_impl(RI ri, RO ro, T oldVal, T newVal, iterable_range_tag const &, iterable_range_tag const &)
01241 {
01242     std::replace_copy(ri.begin(), ri.end(), ro.begin(), oldVal, newVal);
01243 }
01244 
01245 template<   ss_typename_param_k RI
01246         ,   ss_typename_param_k RO
01247         ,   ss_typename_param_k T
01248         >
01249 inline void r_replace_copy_impl(RI ri, RO ro, T oldVal, T newVal, indirect_range_tag const &, indirect_range_tag const &)
01250 {
01251     ri.replace_copy(ro, oldVal, newVal);
01252 }
01253 
01261 template<   ss_typename_param_k RI
01262         ,   ss_typename_param_k RO
01263         ,   ss_typename_param_k T
01264         >
01265 inline void r_replace_copy(RI ri, RO ro, T oldVal, T newVal)
01266 {
01267     r_replace_copy_impl(ri, ro, oldVal, newVal, ri, ro);
01268 }
01269 #endif /* 0 */
01270 
01271 /* *********************************************************
01272  * replace_if
01273  */
01274 
01275 template<   ss_typename_param_k R
01276         ,   ss_typename_param_k P
01277         ,   ss_typename_param_k T
01278         >
01279 inline void r_replace_if_impl(R r, P pr, T newVal, iterable_range_tag const &)
01280 {
01281     std::replace_if(r.begin(), r.end(), pr, newVal);
01282 }
01283 
01284 template<   ss_typename_param_k R
01285         ,   ss_typename_param_k P
01286         ,   ss_typename_param_k T
01287         >
01288 inline void r_replace_if_impl(R r, P pr, T newVal, indirect_range_tag const &)
01289 {
01290     r.replace_if(r, pr, newVal);
01291 }
01292 
01300 template<   ss_typename_param_k R
01301         ,   ss_typename_param_k P
01302         ,   ss_typename_param_k T
01303         >
01304 inline void r_replace_if(R r, P pr, T newVal)
01305 {
01306     r_replace_if_impl(r, pr, newVal, r);
01307 }
01308 
01309 
01310 /* *********************************************************
01311  * replace_copy_if
01312  */
01313 
01314 #if 0
01315 template<   ss_typename_param_k RI
01316         ,   ss_typename_param_k RO
01317         ,   ss_typename_param_k P
01318         ,   ss_typename_param_k T
01319         >
01320 inline void r_replace_copy_if_impl(RI ri, RO ro, P pr, T newVal, iterable_range_tag const &, iterable_range_tag const &)
01321 {
01322     std::replace_copy_if(ri.begin(), ri.end(), ro.begin(), pr, newVal);
01323 }
01324 
01325 template<   ss_typename_param_k RI
01326         ,   ss_typename_param_k RO
01327         ,   ss_typename_param_k P
01328         ,   ss_typename_param_k T
01329         >
01330 inline void r_replace_copy_if_impl(RI ri, RO ro, P pr, T newVal, notional_range_tag const &, notional_range_tag const &)
01331 {
01332     for(; ri; ++ri, ++ro)
01333     {
01334         stlsoft_assert(!(!ro));
01335 
01336         if(pr(*ri))
01337         {
01338             *ro = newVal;
01339         }
01340     }
01341 }
01342 
01343 template<   ss_typename_param_k RI
01344         ,   ss_typename_param_k RO
01345         ,   ss_typename_param_k P
01346         ,   ss_typename_param_k T
01347         >
01348 inline void r_replace_copy_if_impl(RI ri, RO ro, P pr, T newVal, indirect_range_tag const &, indirect_range_tag const &)
01349 {
01350     ri.replace_copy_if(ro, pr, newVal);
01351 }
01352 
01353 template<   ss_typename_param_k RI
01354         ,   ss_typename_param_k RO
01355         ,   ss_typename_param_k P
01356         ,   ss_typename_param_k T
01357         >
01358 inline void r_replace_copy_if(RI ri, RO ro, P pr, T newVal)
01359 {
01360     r_replace_copy_if_impl(ri, ro, pe, newVal, ri, ro);
01361 }
01362 #endif /* 0 */
01363 
01365 // Unit-testing
01366 
01367 #ifdef STLSOFT_UNITTEST
01368 
01369 namespace unittest
01370 {
01371     ss_bool_t test_rangelib_algorithms(unittest_reporter *r)
01372     {
01373         using stlsoft::unittest::unittest_initialiser;
01374 
01375         ss_bool_t               bSuccess    =   true;
01376 
01377         unittest_initialiser    init(r, "RangeLib", "algorithms", __FILE__);
01378 
01379 #if 0
01380         if(NULL != pi1)
01381         {
01382             ator1.construct(pi1, 1968);
01383 
01384             if(1968 != *pi1)
01385             {
01386                 r->report("construct() failed ", __LINE__);
01387                 bSuccess = false;
01388             }
01389         }
01390 #endif /* 0 */
01391 
01392         return bSuccess;
01393     }
01394 
01395     unittest_registrar    unittest_rangelib_algorithms(test_rangelib_algorithms);
01396 
01397 } // namespace unittest
01398 
01399 #endif /* STLSOFT_UNITTEST */
01400 
01401 /* 
01402 
01404 
01405 /* 
01406 
01407 #ifndef _STLSOFT_NO_NAMESPACE
01408 } // namespace stlsoft
01409 #endif /* _STLSOFT_NO_NAMESPACE */
01410 
01411 /* 
01412 
01413 #endif /* !STLSOFT_INCL_RANGELIB_HPP_ALGORITHMS */
01414 
01415 /* 

STLSoft Libraries documentation © Synesis Software Pty Ltd, 2001-2004