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 RandomAccessIterator1, typename RandomAccessIterator2,
00058          typename Pred>
00059       bool 
00060       operator()(RandomAccessIterator1 i1, RandomAccessIterator2 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 RandomAccessIterator1, typename RandomAccessIterator2,
00070          typename Pred>
00071       std::pair<RandomAccessIterator1, RandomAccessIterator2> 
00072       sequential_algorithm(RandomAccessIterator1 begin1,
00073                RandomAccessIterator1 end1,
00074                RandomAccessIterator2 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 RandomAccessIterator1, typename RandomAccessIterator2,
00088          typename Pred>
00089       bool 
00090       operator()(RandomAccessIterator1 i1, RandomAccessIterator2 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 RandomAccessIterator1, typename RandomAccessIterator2,
00103          typename Pred>
00104       std::pair<RandomAccessIterator1, RandomAccessIterator2>
00105       sequential_algorithm(RandomAccessIterator1 begin1,
00106                RandomAccessIterator1 end1,
00107                RandomAccessIterator2 begin2, Pred pred)
00108       {
00109     // Passed end iterator is one short.
00110     RandomAccessIterator1 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 RandomAccessIterator1, typename RandomAccessIterator2,
00128          typename Pred>
00129       bool 
00130       operator()(RandomAccessIterator1 i1, RandomAccessIterator2 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 RandomAccessIterator1, typename RandomAccessIterator2,
00141          typename Pred>
00142       std::pair<RandomAccessIterator1, RandomAccessIterator2>
00143       sequential_algorithm(RandomAccessIterator1 begin1,
00144                RandomAccessIterator1 end1,
00145                RandomAccessIterator2 begin2, Pred pred)
00146       { return mismatch(begin1, end1, begin2, pred, sequential_tag()); }
00147   };
00148 
00149 
00150   /** @brief Test predicate on several elements. */
00151   template<typename ForwardIterator>
00152   struct find_first_of_selector : public generic_find_selector
00153   {
00154     ForwardIterator begin;
00155     ForwardIterator end;
00156 
00157     explicit find_first_of_selector(ForwardIterator begin, ForwardIterator end)
00158     : begin(begin), end(end) { }
00159 
00160     /** @brief Test on one position.
00161      *  @param i1 Iterator on first sequence.
00162      *  @param i2 Iterator on second sequence (unused).
00163      *  @param pred Find predicate. */
00164     template<typename RandomAccessIterator1, typename RandomAccessIterator2,
00165          typename Pred>
00166       bool 
00167       operator()(RandomAccessIterator1 i1, RandomAccessIterator2 i2, Pred pred)
00168       {
00169     for (ForwardIterator pos_in_candidates = begin;
00170          pos_in_candidates != end; ++pos_in_candidates)
00171       if (pred(*i1, *pos_in_candidates))
00172         return true;
00173     return false;
00174       }
00175 
00176     /** @brief Corresponding sequential algorithm on a sequence.
00177      *  @param begin1 Begin iterator of first sequence.
00178      *  @param end1 End iterator of first sequence.
00179      *  @param begin2 Begin iterator of second sequence.
00180      *  @param pred Find predicate. */
00181     template<typename RandomAccessIterator1, typename RandomAccessIterator2,
00182          typename Pred>
00183       std::pair<RandomAccessIterator1, RandomAccessIterator2>
00184       sequential_algorithm(RandomAccessIterator1 begin1,
00185                RandomAccessIterator1 end1,
00186                RandomAccessIterator2 begin2, Pred pred)
00187       { return std::make_pair(find_first_of(begin1, end1, begin, end, pred,
00188                         sequential_tag()), begin2); }
00189   };
00190 }
00191 
00192 #endif /* _GLIBCXX_PARALLEL_FIND_SELECTORS_H */

Generated on Tue Apr 21 13:13:26 2009 for libstdc++ by  doxygen 1.5.8