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  

basic_indirect_range_adaptor.hpp

Go to the documentation of this file.
00001 /* 
00002  * File:        rangelib/basic_indirect_range_adaptor.hpp
00003  *
00004  * Purpose:     basic_indirect_range_adaptor.
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_BASIC_INDIRECT_RANGE_ADAPTOR
00044 #define STLSOFT_INCL_RANGELIB_HPP_BASIC_INDIRECT_RANGE_ADAPTOR
00045 
00046 #ifndef __STLSOFT_DOCUMENTATION_SKIP_SECTION
00047 # define STLSOFT_VER_RANGELIB_HPP_BASIC_INDIRECT_RANGE_ADAPTOR_MAJOR      1
00048 # define STLSOFT_VER_RANGELIB_HPP_BASIC_INDIRECT_RANGE_ADAPTOR_MINOR      0
00049 # define STLSOFT_VER_RANGELIB_HPP_BASIC_INDIRECT_RANGE_ADAPTOR_REVISION   8
00050 # define STLSOFT_VER_RANGELIB_HPP_BASIC_INDIRECT_RANGE_ADAPTOR_EDIT       10
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 #include <iterator>
00064 #include <functional>
00065 
00066 /* 
00067  * Namespace
00068  */
00069 
00070 #ifndef _STLSOFT_NO_NAMESPACE
00071 namespace stlsoft
00072 {
00073 #endif /* _STLSOFT_NO_NAMESPACE */
00074 
00075 /* 
00076 
00081 
00082 /* 
00083  * Functions
00084  */
00085 
00086 #ifndef __STLSOFT_DOCUMENTATION_SKIP_SECTION
00087 namespace
00088 {
00089     template <ss_typename_param_k T>
00090     struct accumulate_1_function
00091     {
00092     public:
00093         accumulate_1_function(T &total)
00094             : m_total(total)
00095         {}
00096 
00097     public:
00098         template <ss_typename_param_k T2>
00099         ss_bool_t operator ()(T2 val)
00100         {
00101             m_total = m_total + val;
00102 
00103             return true;
00104         }
00105 
00106     private:
00107         T   &m_total;
00108     };
00109 
00110     template<   ss_typename_param_k T
00111             ,   ss_typename_param_k P
00112             >
00113     struct accumulate_2_function
00114     {
00115     public:
00116         accumulate_2_function(T &total, P pr)
00117             : m_total(total)
00118             , m_pr(pr)
00119         {}
00120 
00121     public:
00122         template <ss_typename_param_k T2>
00123         ss_bool_t operator ()(T2 val)
00124         {
00125             m_total = m_pr(m_total, val);
00126 
00127             return true;
00128         }
00129 
00130     private:
00131         T   &m_total;
00132         P   m_pr;
00133     };
00134 
00135     template <ss_typename_param_k O>
00136     struct copy_function
00137     {
00138     public:
00139         copy_function(O o)
00140             : m_o(o)
00141         {}
00142 
00143     public:
00144         template <ss_typename_param_k T2>
00145         ss_bool_t operator ()(T2 val)
00146         {
00147             *m_o++ = val;
00148 
00149             return true;
00150         }
00151 
00152     public:
00153         operator O()
00154         {
00155             return m_o;
00156         }
00157 
00158     private:
00159         O   m_o;
00160     };
00161 
00162     template <ss_typename_param_k T>
00163     struct count_function
00164     {
00165     public:
00166         count_function(size_t &n, T const &val)
00167             : m_n(n)
00168             , m_val(val)
00169         {}
00170 
00171     public:
00172         template <ss_typename_param_k T2>
00173         ss_bool_t operator ()(T2 val) const
00174         {
00175             if(m_val == val)
00176             {
00177                 ++m_n;
00178             }
00179 
00180             return true;
00181         }
00182     private:
00183         size_t  &m_n;
00184         T const &m_val;
00185     };
00186 
00187     template <ss_typename_param_k P>
00188     struct count_if_function
00189     {
00190     public:
00191         count_if_function(size_t &n, P pr)
00192             : m_n(n)
00193             , m_pr(pr)
00194         {}
00195 
00196     public:
00197         template <ss_typename_param_k T2>
00198         ss_bool_t operator ()(T2 val) const
00199         {
00200             if(m_pr(val))
00201             {
00202                 ++m_n;
00203             }
00204 
00205             return true;
00206         }
00207     private:
00208         size_t  &m_n;
00209         P       m_pr;
00210     };
00211 
00212     struct distance_function
00213     {
00214     public:
00215         distance_function(ptrdiff_t &count)
00216             : m_count(count)
00217         {}
00218     public:
00219         template <ss_typename_param_k T>
00220         ss_bool_t operator ()(T /* v */) const
00221         {
00222             return (++m_count, true);
00223         }
00224     private:
00225         ptrdiff_t   &m_count;
00226 
00227     private:
00228         distance_function &operator =(distance_function const &);
00229     };
00230 
00231     template <ss_typename_param_k T>
00232     struct exists_function
00233     {
00234     public:
00235         exists_function(ss_bool_t &b, T const &val)
00236             : m_b(b)
00237             , m_val(val)
00238         {
00239             stlsoft_assert(!b);
00240         }
00241 
00242     public:
00243         template <ss_typename_param_k T2>
00244         ss_bool_t operator ()(T2 val) const
00245         {
00246             if(m_val == val)
00247             {
00248                 m_b = true;
00249 
00250                 return false; // break out of loop
00251             }
00252 
00253             return true;
00254         }
00255     private:
00256         ss_bool_t   &m_b;
00257         T const     &m_val;
00258     };
00259 
00260     template <ss_typename_param_k P>
00261     struct exists_if_1_function
00262     {
00263     public:
00264         exists_if_1_function(ss_bool_t &b, P pr)
00265             : m_b(b)
00266             , m_pr(pr)
00267         {
00268             stlsoft_assert(!b);
00269         }
00270 
00271     public:
00272         template <ss_typename_param_k T2>
00273         ss_bool_t operator ()(T2 val) const
00274         {
00275             if(pf(val))
00276             {
00277                 m_b = true;
00278 
00279                 return false; // break out of loop
00280             }
00281 
00282             return true;
00283         }
00284     private:
00285         ss_bool_t   &m_b;
00286         P           m_pr;
00287     };
00288 
00289     template<   ss_typename_param_k P
00290             ,   ss_typename_param_k V
00291             >
00292     struct exists_if_2_function
00293     {
00294     public:
00295         exists_if_2_function(ss_bool_t &b, P pr, V &result)
00296             : m_b(b)
00297             , m_pr(pr)
00298             , m_result(result)
00299         {
00300             stlsoft_assert(!b);
00301         }
00302 
00303     public:
00304         template <ss_typename_param_k T2>
00305         ss_bool_t operator ()(T2 val) const
00306         {
00307             if(pf(val))
00308             {
00309                 m_b         =   true;
00310                 m_result    =   val;
00311 
00312                 return false; // break out of loop
00313             }
00314 
00315             return true;
00316         }
00317     private:
00318         ss_bool_t   &m_b;
00319         P           m_pr;
00320         V           &m_result;
00321     };
00322 
00323     template <ss_typename_param_k F>
00324     struct for_each_function
00325     {
00326     public:
00327         for_each_function(F f)
00328             : m_f(f)
00329         {}
00330     public:
00331         template <ss_typename_param_k T>
00332         ss_bool_t operator ()(T v) const
00333         {
00334             return (m_f(v), true);
00335         }
00336     private:
00337         F   m_f;
00338     };
00339 
00340     template<   ss_typename_param_k V
00341             ,   ss_typename_param_k P
00342             >
00343     struct minmax_element_2_function
00344     {
00345     public:
00346         minmax_element_2_function(ss_bool_t &bRetrieved, P pr, V &result)
00347             : m_bRetrieved(bRetrieved)
00348             , m_pr(pr)
00349             , m_result(result)
00350         {}
00351     public:
00352         template <ss_typename_param_k T>
00353         ss_bool_t operator ()(T val) const
00354         {
00355             if(!m_bRetrieved)
00356             {
00357                 m_result = val;
00358 
00359                 m_bRetrieved = true;
00360             }
00361             else
00362             {
00363                 if(m_pr(m_result, val))
00364                 {
00365                     m_result = val;
00366                 }
00367             }
00368 
00369             return true;
00370         }
00371     private:
00372         ss_bool_t   &m_bRetrieved;
00373         P           m_pr;
00374         V           &m_result;
00375     };
00376 
00377 } // anonymous namespace
00378 
00379 #endif /* !__STLSOFT_DOCUMENTATION_SKIP_SECTION */
00380 
00381 /* 
00382  * Classes
00383  */
00384 
00386 template <ss_typename_param_k R>
00387 class indirect_range_adaptor
00388     : public indirect_range_tag
00389 {
00390 public:
00391     typedef R                                   range_type;
00392     typedef ss_typename_type_k R::value_type    value_type;
00393 
00394 public:
00398     indirect_range_adaptor(range_type r)
00399         : m_r(r)
00400     {}
00401 
00403     template <ss_typename_param_k T>
00404     T accumulate(T val) const
00405     {
00406         T   total   =   val;
00407 
00408         m_r.for_each_cancelable(accumulate_1_function<T>(total));
00409 
00410         return total;
00411     }
00412 
00414     template<   ss_typename_param_k T
00415             ,   ss_typename_param_k P
00416             >
00417     T accumulate(T val, P pr) const
00418     {
00419         T   total   =   val;
00420 
00421         m_r.for_each_cancelable(accumulate_2_function<T, P>(total, pr));
00422 
00423         return total;
00424     }
00425 
00427     template <ss_typename_param_k O>
00428     O copy(O o) const
00429     {
00430         copy_function<O>    cf(o);
00431 
00432         m_r.for_each_cancelable(cf);
00433 
00434         return cf;
00435     }
00436 
00438     template <ss_typename_param_k T>
00439     size_t count(T const &val) const
00440     {
00441         size_t  n   =   0;
00442 
00443         m_r.for_each_cancelable(count_function<T>(n, val));
00444 
00445         return n;
00446     }
00447 
00449     template <ss_typename_param_k P>
00450     size_t count_if(P pr) const
00451     {
00452         size_t  n   =   0;
00453 
00454         m_r.for_each_cancelable(count_if_function<P>(n, pr));
00455 
00456         return n;
00457     }
00458 
00460     ptrdiff_t distance() const
00461     {
00462         ptrdiff_t   n = 0;
00463 
00464         m_r.for_each_cancelable(distance_function(n));
00465 
00466         return n;
00467     }
00468 
00470     template <ss_typename_param_k F>
00471     F for_each(F f)
00472     {
00473         m_r.for_each_cancelable(for_each_function<F>(f));
00474 
00475         return f;
00476     }
00477 
00479     template <ss_typename_param_k T>
00480     ss_bool_t exists(T const &val) const
00481     {
00482         ss_bool_t   bExists = false;
00483 
00484         m_r.for_each_cancelable(exists_function<T>(bExists, val));
00485 
00486         return bExists;
00487     }
00488 
00491     template <ss_typename_param_k P>
00492     ss_bool_t exists_if(P pr) const
00493     {
00494         ss_bool_t   bExists = false;
00495 
00496         m_r.for_each_cancelable(exists_if_1_function<P>(bExists, pr));
00497 
00498         return bExists;
00499     }
00500 
00503     template<   ss_typename_param_k P
00504             ,   ss_typename_param_k T>
00505     ss_bool_t exists_if(P pr, T &result) const
00506     {
00507         ss_bool_t   bExists = false;
00508 
00509         m_r.for_each_cancelable(exists_if_2_function<P, T>(bExists, pr, result));
00510 
00511         return bExists;
00512     }
00513 
00515     value_type max_element() const
00516     {
00517         return minmax_element(std::less<value_type>());
00518     }
00519 
00522     template <ss_typename_param_k P>
00523     value_type max_element(P pr) const
00524     {
00525         return minmax_element(pr);
00526     }
00527 
00529     value_type min_element() const
00530     {
00531         return minmax_element(std::greater<value_type>());
00532     }
00533 
00536     template <ss_typename_param_k P>
00537     value_type min_element(P pr) const
00538     {
00539         return minmax_element(std::not2(pr));
00540     }
00541 
00542 private:
00543     template <ss_typename_param_k P>
00544     value_type minmax_element(P pr) const
00545     {
00546         ss_bool_t   bRetrieved;
00547         value_type  result;
00548 
00549         m_r.for_each_cancelable(minmax_element_2_function<value_type, P>(bRetrieved, pr, result));
00550 
00551         stlsoft_assert(bRetrieved);
00552 
00553         return result;
00554     }
00555 
00556 private:
00557     range_type  m_r;
00558 };
00559 
00561 // Unit-testing
00562 
00563 #ifdef STLSOFT_UNITTEST
00564 
00565 namespace unittest
00566 {
00567     ss_bool_t test_rangelib_indirect_range_adaptors(unittest_reporter *r)
00568     {
00569         using stlsoft::unittest::unittest_initialiser;
00570 
00571         ss_bool_t               bSuccess    =   true;
00572 
00573         unittest_initialiser    init(r, "RangeLib", "indirect_range_adaptors", __FILE__);
00574 
00575 #if 0
00576         if(
00577         {
00578             r->report("construct() failed ", __LINE__);
00579             bSuccess = false;
00580         }
00581 #endif /* 0 */
00582 
00583         return bSuccess;
00584     }
00585 
00586     unittest_registrar    unittest_rangelib_indirect_range_adaptors(test_rangelib_indirect_range_adaptors);
00587 
00588 } // namespace unittest
00589 
00590 #endif /* STLSOFT_UNITTEST */
00591 
00592 /* 
00593 
00595 
00596 /* 
00597 
00598 #ifndef _STLSOFT_NO_NAMESPACE
00599 } // namespace stlsoft
00600 #endif /* _STLSOFT_NO_NAMESPACE */
00601 
00602 /* 
00603 
00604 #endif /* !STLSOFT_INCL_RANGELIB_HPP_BASIC_INDIRECT_RANGE_ADAPTOR */
00605 
00606 /* 

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