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