libstdc++
find_selectors.h
Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00003 // Copyright (C) 2007, 2008, 2009 Free Software Foundation, Inc.
00004 //
00005 // This file is part of the GNU ISO C++ Library.  This library is free
00006 // software; you can redistribute it and/or modify it under the terms
00007 // of the GNU General Public License as published by the Free Software
00008 // Foundation; either version 3, or (at your option) any later
00009 // version.
00010 
00011 // This library is distributed in the hope that it will be useful, but
00012 // WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 // General Public License for more details.
00015 
00016 // Under Section 7 of GPL version 3, you are granted additional
00017 // permissions described in the GCC Runtime Library Exception, version
00018 // 3.1, as published by the Free Software Foundation.
00019 
00020 // You should have received a copy of the GNU General Public License and
00021 // a copy of the GCC Runtime Library Exception along with this program;
00022 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
00023 // <http://www.gnu.org/licenses/>.
00024 
00025 /** @file parallel/find_selectors.h
00026  *  @brief _Function objects representing different tasks to be plugged
00027  *  into the parallel find algorithm.
00028  *  This file is a GNU parallel extension to the Standard C++ Library.
00029  */
00030 
00031 // Written by Felix Putze.
00032 
00033 #ifndef _GLIBCXX_PARALLEL_FIND_SELECTORS_H
00034 #define _GLIBCXX_PARALLEL_FIND_SELECTORS_H 1
00035 
00036 #include <parallel/tags.h>
00037 #include <parallel/basic_iterator.h>
00038 #include <bits/stl_pair.h>
00039 
00040 namespace __gnu_parallel
00041 {
00042   /** @brief Base class of all __gnu_parallel::__find_template selectors. */
00043   struct __generic_find_selector
00044   { };
00045 
00046   /** 
00047    *  @brief Test predicate on a single element, used for std::find()
00048    *  and std::find_if ().
00049    */
00050   struct __find_if_selector : public __generic_find_selector
00051   {
00052     /** @brief Test on one position.
00053      * @param __i1 _Iterator on first sequence.
00054      * @param __i2 _Iterator on second sequence (unused).
00055      * @param __pred Find predicate.
00056      */
00057     template<typename _RAIter1, typename _RAIter2,
00058              typename _Pred>
00059       bool 
00060       operator()(_RAIter1 __i1, _RAIter2 __i2, _Pred __pred)
00061       { return __pred(*__i1); }
00062 
00063     /** @brief Corresponding sequential algorithm on a sequence.
00064      *  @param __begin1 Begin iterator of first sequence.
00065      *  @param __end1 End iterator of first sequence.
00066      *  @param __begin2 Begin iterator of second sequence.
00067      *  @param __pred Find predicate.
00068      */
00069     template<typename _RAIter1, typename _RAIter2,
00070              typename _Pred>
00071       std::pair<_RAIter1, _RAIter2> 
00072       _M_sequential_algorithm(_RAIter1 __begin1,
00073                            _RAIter1 __end1,
00074                            _RAIter2 __begin2, _Pred __pred)
00075       { return std::make_pair(find_if(__begin1, __end1, __pred,
00076                                       sequential_tag()), __begin2); }
00077   };
00078 
00079   /** @brief Test predicate on two adjacent elements. */
00080   struct __adjacent_find_selector : public __generic_find_selector
00081   {
00082     /** @brief Test on one position.
00083      *  @param __i1 _Iterator on first sequence.
00084      *  @param __i2 _Iterator on second sequence (unused).
00085      *  @param __pred Find predicate.
00086      */
00087     template<typename _RAIter1, typename _RAIter2,
00088              typename _Pred>
00089       bool 
00090       operator()(_RAIter1 __i1, _RAIter2 __i2, _Pred __pred)
00091       {
00092         // Passed end iterator is one short.
00093         return __pred(*__i1, *(__i1 + 1));
00094       }
00095 
00096     /** @brief Corresponding sequential algorithm on a sequence.
00097      *  @param __begin1 Begin iterator of first sequence.
00098      *  @param __end1 End iterator of first sequence.
00099      *  @param __begin2 Begin iterator of second sequence.
00100      *  @param __pred Find predicate.
00101      */
00102     template<typename _RAIter1, typename _RAIter2,
00103              typename _Pred>
00104       std::pair<_RAIter1, _RAIter2>
00105       _M_sequential_algorithm(_RAIter1 __begin1,
00106                   _RAIter1 __end1,
00107                   _RAIter2 __begin2, _Pred __pred)
00108       {
00109         // Passed end iterator is one short.
00110         _RAIter1 __spot = adjacent_find(__begin1, __end1 + 1,
00111                     __pred, sequential_tag());
00112         if (__spot == (__end1 + 1))
00113           __spot = __end1;
00114         return std::make_pair(__spot, __begin2);
00115       }
00116   };
00117 
00118   /** @brief Test inverted predicate on a single element. */
00119   struct __mismatch_selector : public __generic_find_selector
00120   {
00121     /** 
00122      *  @brief Test on one position.
00123      *  @param __i1 _Iterator on first sequence.
00124      *  @param __i2 _Iterator on second sequence (unused).
00125      *  @param __pred Find predicate. 
00126      */
00127     template<typename _RAIter1, typename _RAIter2,
00128              typename _Pred>
00129       bool 
00130       operator()(_RAIter1 __i1, _RAIter2 __i2, _Pred __pred)
00131       { return !__pred(*__i1, *__i2); }
00132 
00133     /** 
00134      *  @brief Corresponding sequential algorithm on a sequence.
00135      *  @param __begin1 Begin iterator of first sequence.
00136      *  @param __end1 End iterator of first sequence.
00137      *  @param __begin2 Begin iterator of second sequence.
00138      *  @param __pred Find predicate. 
00139      */
00140     template<typename _RAIter1, typename _RAIter2,
00141              typename _Pred>
00142       std::pair<_RAIter1, _RAIter2>
00143       _M_sequential_algorithm(_RAIter1 __begin1,
00144                   _RAIter1 __end1,
00145                   _RAIter2 __begin2, _Pred __pred)
00146       { return mismatch(__begin1, __end1, __begin2,
00147             __pred, sequential_tag()); }
00148   };
00149 
00150 
00151   /** @brief Test predicate on several elements. */
00152   template<typename _FIterator>
00153     struct __find_first_of_selector : public __generic_find_selector
00154     {
00155       _FIterator _M_begin;
00156       _FIterator _M_end;
00157 
00158       explicit __find_first_of_selector(_FIterator __begin,
00159                     _FIterator __end)
00160       : _M_begin(__begin), _M_end(__end) { }
00161 
00162       /** @brief Test on one position.
00163        *  @param __i1 _Iterator on first sequence.
00164        *  @param __i2 _Iterator on second sequence (unused).
00165        *  @param __pred Find predicate. */
00166       template<typename _RAIter1, typename _RAIter2,
00167            typename _Pred>
00168         bool
00169         operator()(_RAIter1 __i1, _RAIter2 __i2, _Pred __pred)
00170         {
00171       for (_FIterator __pos_in_candidates = _M_begin;
00172            __pos_in_candidates != _M_end; ++__pos_in_candidates)
00173         if (__pred(*__i1, *__pos_in_candidates))
00174           return true;
00175       return false;
00176     }
00177 
00178       /** @brief Corresponding sequential algorithm on a sequence.
00179        *  @param __begin1 Begin iterator of first sequence.
00180        *  @param __end1 End iterator of first sequence.
00181        *  @param __begin2 Begin iterator of second sequence.
00182        *  @param __pred Find predicate. */
00183       template<typename _RAIter1, typename _RAIter2,
00184            typename _Pred>
00185         std::pair<_RAIter1, _RAIter2>
00186         _M_sequential_algorithm(_RAIter1 __begin1,
00187                 _RAIter1 __end1,
00188                 _RAIter2 __begin2, _Pred __pred)
00189         {
00190       return std::make_pair(find_first_of(__begin1, __end1,
00191                           _M_begin, _M_end, __pred,
00192                           sequential_tag()), __begin2);
00193     }
00194      };
00195 }
00196 
00197 #endif /* _GLIBCXX_PARALLEL_FIND_SELECTORS_H */