00001
00002 #ifndef _INSTIGATE_STL_INTERNAL_HEADER_IN_ALGORITHM
00003 #error This is an internal header file used to implement Instigate STL.\
00004 It should never be included directly by a program.
00005 #endif
00006
00007 #ifndef INSTIGATE_STL_FIND_IF_HPP
00008 #define INSTIGATE_STL_FIND_IF_HPP
00009
00059
00060 #include "concept.hpp"
00061 #include "_basis.hpp"
00062
00063
00064
00065
00066
00067
00068 namespace instigate {
00069 namespace stl {
00073 namespace implementation {
00074 template <typename I, typename P>
00075 I find_if_aux(I b, I e, P p,
00076 instigate::stl::random_access_iterator::tag);
00077 template <typename I, typename P>
00078 I find_if_aux(I b, I e, P p, instigate::stl::
00079 single_pass_iterator::tag);
00080 }
00081 template <typename I, typename P>
00082 I find_if(I b, I e, P p);
00083 }
00084 }
00085
00118 template <typename I, typename P>
00119 inline I instigate::stl::find_if(I b, I e, P p)
00120 {
00121 CHECK(instigate::stl::single_pass_iterator::requirements<I>);
00122 CHECK(instigate::stl::readable_iterator::requirements<I>);
00123 CHECK(instigate::stl::unary_predicate::requirements<P>);
00124 typedef typename instigate::stl::single_pass_iterator::interface<I>::
00125 iterator_category category;
00126 return instigate::stl::implementation::find_if_aux(b, e, p, category());
00127 }
00128
00133 template <typename I, typename P>
00134 inline I instigate::stl::implementation::find_if_aux(I b, I e, P p,
00135 instigate::stl::random_access_iterator::tag)
00136 {
00137 typename instigate::stl::random_access_iterator::interface<I>::
00138 difference_type t = instigate::stl::distance(b, e) >> 2;
00139 for (; 0 < t;) {
00140 assign(t, t - 1);
00141 if (invoke_predicate(p, const_dereference(b))) {
00142 return b;
00143 }
00144 increment(b);
00145 if (invoke_predicate(p, const_dereference(b))) {
00146 return b;
00147 }
00148 increment(b);
00149 if (invoke_predicate(p, const_dereference(b))) {
00150 return b;
00151 }
00152 increment(b);
00153 if (invoke_predicate(p, const_dereference(b))) {
00154 return b;
00155 }
00156 increment(b);
00157 }
00158 switch (instigate::stl::distance(b, e)) {
00159 case 3:
00160 if (invoke_predicate(p, const_dereference(b))) {
00161 return b;
00162 }
00163 increment(b);
00164 case 2:
00165 if (invoke_predicate(p, const_dereference(b))) {
00166 return b;
00167 }
00168 increment(b);
00169 case 1:
00170 if (invoke_predicate(p, const_dereference(b))) {
00171 return b;
00172 }
00173 increment(b);
00174 case 0:
00175 default:
00176 return e;
00177 }
00178 }
00179
00184 template <typename I, typename P>
00185 inline I instigate::stl::implementation::find_if_aux(I b, I e, P p,
00186 instigate::stl::single_pass_iterator::tag)
00187 {
00188 while (!equal(b, e) && !invoke_predicate(p, const_dereference(b)))
00189 {
00190 increment(b);
00191 }
00192 return b;
00193 }
00194
00195
00196
00197 #endif // INSTIGATE_STL_FIND_IF_HPP