00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00031 #ifndef _VGTL_HELPERS_H_
00032 #define _VGTL_HELPERS_H_
00033
00034 #include <vgtl_config.h>
00035
00036 __VGTL_BEGIN_NAMESPACE
00037
00044 template <class _BidirIter, class _Tp>
00045 inline _BidirIter rfind(_BidirIter __first, _BidirIter __last,
00046 const _Tp& __val,
00047 std::bidirectional_iterator_tag)
00048 {
00049 _BidirIter __c(__last);
00050 --__c;
00051 while (__c != __first && *__c != __val)
00052 --__c;
00053 if(__c == __first && *__c != __val)
00054 __c = __last;
00055 return __c;
00056 }
00057
00064 template <class _BidirIter, class _Predicate>
00065 inline _BidirIter rfind_if(_BidirIter __first, _BidirIter __last,
00066 _Predicate __pred,
00067 std::bidirectional_iterator_tag)
00068 {
00069 _BidirIter __c(__last);
00070 --__c;
00071 while (__c != __first && !__pred(*__c))
00072 --__c;
00073 if(__c == __first && *__pred(*__c))
00074 __c = __last;
00075 return __c;
00076 }
00077
00078 #ifdef __VGTL_CLASS_PARTIAL_SPECIALIZATION
00079
00086 template <class _RandomAccessIter, class _Tp>
00087 _RandomAccessIter rfind(_RandomAccessIter __first, _RandomAccessIter __last,
00088 const _Tp& __val,
00089 std::random_access_iterator_tag)
00090 {
00091 typename std::iterator_traits<_RandomAccessIter>::difference_type __trip_count
00092 = ((__last - __first)-1) >> 2;
00093 _RandomAccessIter __c(__last);
00094 --__c;
00095
00096 for ( ; __trip_count > 0 ; --__trip_count) {
00097 if (*__c == __val) return __c;
00098 --__c;
00099
00100 if (*__c == __val) return __c;
00101 --__c;
00102
00103 if (*__c == __val) return __c;
00104 --__c;
00105
00106 if (*__c == __val) return __c;
00107 --__c;
00108 }
00109
00110 switch(__c - __first) {
00111 case 3:
00112 if (*__c == __val) return __c;
00113 --__c;
00114 case 2:
00115 if (*__c == __val) return __c;
00116 --__c;
00117 case 1:
00118 if (*__c == __val) return __c;
00119 --__c;
00120 case 0:
00121 if(*__c == __val)
00122 return __c;
00123 else
00124 return __last;
00125 default:
00126 return __last;
00127 }
00128 }
00129
00136 template <class _RandomAccessIter, class _Predicate>
00137 _RandomAccessIter rfind_if(_RandomAccessIter __first, _RandomAccessIter __last,
00138 _Predicate __pred,
00139 std::random_access_iterator_tag)
00140 {
00141 typename std::iterator_traits<_RandomAccessIter>::difference_type __trip_count
00142 = (__last - __first) >> 2;
00143 _RandomAccessIter __c(__last);
00144 --__c;
00145
00146 for ( ; __trip_count > 0 ; --__trip_count) {
00147 if (__pred(*__c)) return __c;
00148 --__c;
00149
00150 if (__pred(*__c)) return __c;
00151 --__c;
00152
00153 if (__pred(*__c)) return __c;
00154 --__c;
00155
00156 if (__pred(*__c)) return __c;
00157 --__c;
00158 }
00159
00160 switch(__c - __first) {
00161 case 3:
00162 if (__pred(*__c)) return __c;
00163 --__c;
00164 case 2:
00165 if (__pred(*__c)) return __c;
00166 --__c;
00167 case 1:
00168 if (__pred(*__c)) return __c;
00169 --__c;
00170 case 0:
00171 if(__pred(*__c))
00172 return __c;
00173 else
00174 return __last;
00175 default:
00176 return __last;
00177 }
00178 }
00179
00180 #endif
00181
00191 template <class _BidirIter, class _Tp>
00192 inline _BidirIter rfind(_BidirIter __first, _BidirIter __last,
00193 const _Tp& __val)
00194 {
00195 return rfind(__first, __last, __val, __ITERATOR_CATEGORY(__first));
00196 }
00197
00207 template <class _BidirIter, class _Predicate>
00208 inline _BidirIter rfind_if(_BidirIter __first, _BidirIter __last,
00209 _Predicate __pred) {
00210 return rfind_if(__first, __last, __pred, __ITERATOR_CATEGORY(__first));
00211 }
00212
00213 __VGTL_END_NAMESPACE
00214
00215 #endif
00216