|
Rcpp Version 0.9.10
|
00001 // -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8 -*- 00002 // 00003 // algo.h: Rcpp R/C++ interface class library -- STL-style algorithms 00004 // 00005 // Copyright (C) 2010 - 2011 Dirk Eddelbuettel and Romain Francois 00006 // 00007 // This file is part of Rcpp. 00008 // 00009 // Rcpp is free software: you can redistribute it and/or modify it 00010 // under the terms of the GNU General Public License as published by 00011 // the Free Software Foundation, either version 2 of the License, or 00012 // (at your option) any later version. 00013 // 00014 // Rcpp is distributed in the hope that it will be useful, but 00015 // WITHOUT ANY WARRANTY; without even the implied warranty of 00016 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00017 // GNU General Public License for more details. 00018 // 00019 // You should have received a copy of the GNU General Public License 00020 // along with Rcpp. If not, see <http://www.gnu.org/licenses/>. 00021 00022 #ifndef Rcpp__algo_h 00023 #define Rcpp__algo_h 00024 00025 #include <iterator> 00026 #include <algorithm> 00027 00028 namespace Rcpp{ 00029 00030 /* generic implementation for the input iterator case */ 00031 template<class InputIterator, class T> 00032 inline bool __any( InputIterator first, InputIterator last, const T& value, std::input_iterator_tag ){ 00033 for ( ;first!=last; first++) if ( *first==value ) return true; 00034 return false; 00035 } 00036 00037 /* RAI case */ 00038 template<class RandomAccessIterator, class T> 00039 inline bool __any( RandomAccessIterator __first, RandomAccessIterator __last, const T& __val, std::random_access_iterator_tag ){ 00040 00041 typename std::iterator_traits<RandomAccessIterator>::difference_type __trip_count = (__last - __first) >> 2; 00042 00043 for ( ; __trip_count > 0 ; --__trip_count) { 00044 if (*__first == __val) 00045 return true; 00046 ++__first; 00047 00048 if (*__first == __val) 00049 return true; 00050 ++__first; 00051 00052 if (*__first == __val) 00053 return true; 00054 ++__first; 00055 00056 if (*__first == __val) 00057 return true; 00058 ++__first; 00059 } 00060 00061 switch (__last - __first) 00062 { 00063 case 3: 00064 if (*__first == __val) 00065 return true; 00066 ++__first; 00067 case 2: 00068 if (*__first == __val) 00069 return true; 00070 ++__first; 00071 case 1: 00072 if (*__first == __val) 00073 return true; 00074 ++__first; 00075 case 0: 00076 default: 00077 return false; 00078 } 00079 00080 00081 } 00082 00083 00088 template<class InputIterator, class T> 00089 inline bool any( InputIterator first, InputIterator last, const T& value){ 00090 return __any( first, last, value, typename std::iterator_traits<InputIterator>::iterator_category() ) ; 00091 } 00092 00093 00094 00095 00096 /* generic implementation for the input iterator case */ 00097 template<class InputIterator, class Predicate> 00098 inline bool __any_if( InputIterator first, InputIterator last, Predicate pred, std::input_iterator_tag ){ 00099 for ( ; first!=last ; first++ ) if ( pred(*first) ) return true ; 00100 return false; 00101 } 00102 00103 /* RAI case */ 00104 template<class RandomAccessIterator, class Predicate> 00105 inline bool __any_if( RandomAccessIterator __first, RandomAccessIterator __last, Predicate __pred, std::random_access_iterator_tag ){ 00106 00107 typename std::iterator_traits<RandomAccessIterator>::difference_type __trip_count = (__last - __first) >> 2; 00108 00109 for ( ; __trip_count > 0 ; --__trip_count) { 00110 if (__pred(*__first)) 00111 return true; 00112 ++__first; 00113 00114 if (__pred(*__first)) 00115 return true; 00116 ++__first; 00117 00118 if (__pred(*__first)) 00119 return true; 00120 ++__first; 00121 00122 if (__pred(*__first)) 00123 return true; 00124 ++__first; 00125 } 00126 00127 switch (__last - __first) 00128 { 00129 case 3: 00130 if (__pred(*__first)) 00131 return true; 00132 ++__first; 00133 case 2: 00134 if (__pred(*__first)) 00135 return true; 00136 ++__first; 00137 case 1: 00138 if (__pred(*__first)) 00139 return true; 00140 ++__first; 00141 case 0: 00142 default: 00143 return false; 00144 } 00145 00146 00147 } 00148 00149 00154 template<class InputIterator, class Predicate> 00155 inline bool any_if( InputIterator first, InputIterator last, Predicate pred){ 00156 return __any_if( first, last, pred, typename std::iterator_traits<InputIterator>::iterator_category() ) ; 00157 } 00158 00159 } 00160 00161 #endif