# 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 */