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
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00049 #ifndef STLSOFT_INCL_STLSOFT_ITERATORS_HPP_FILTER_ITERATOR
00050 #define STLSOFT_INCL_STLSOFT_ITERATORS_HPP_FILTER_ITERATOR
00051
00052 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00053 # define STLSOFT_VER_STLSOFT_ITERATORS_HPP_FILTER_ITERATOR_MAJOR 4
00054 # define STLSOFT_VER_STLSOFT_ITERATORS_HPP_FILTER_ITERATOR_MINOR 2
00055 # define STLSOFT_VER_STLSOFT_ITERATORS_HPP_FILTER_ITERATOR_REVISION 3
00056 # define STLSOFT_VER_STLSOFT_ITERATORS_HPP_FILTER_ITERATOR_EDIT 33
00057 #endif
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075 #ifndef STLSOFT_INCL_STLSOFT_H_STLSOFT
00076 # include <stlsoft/stlsoft.h>
00077 #endif
00078
00079 #if !defined(STLSOFT_CF_TEMPLATE_PARTIAL_SPECIALISATION_SUPPORT)
00080 # error filter_iterator cannot be used with compilers that do not support partial template specialisation
00081 #else
00082 # ifndef STLSOFT_INCL_STLSOFT_ITERATOR_HPP_ADAPTED_ITERATOR_TRAITS
00083 # include <stlsoft/iterators/adapted_iterator_traits.hpp>
00084 # endif
00085 #endif
00086 #ifndef STLSOFT_INCL_STLSOFT_HPP_META_YESNO
00087 # include <stlsoft/meta/yesno.hpp>
00088 #endif
00089 #ifndef STLSOFT_INCL_STLSOFT_HPP_META_IS_POINTER_TYPE
00090 # include <stlsoft/meta/is_pointer_type.hpp>
00091 #endif
00092 #ifndef STLSOFT_INCL_STLSOFT_UTIL_STD_HPP_ITERATOR_CATEGORY_LIMITERS
00093 #include <stlsoft/util/std/iterator_category_limiters.hpp>
00094 #endif
00095
00096
00097
00098
00099
00100 #ifdef STLSOFT_CF_TEMPLATE_PARTIAL_SPECIALISATION_SUPPORT
00101 # define STLSOFT_FILTER_ITERATOR_MUTABLE_OP_SUPPORT
00102 #endif
00103
00104 #if defined(STLSOFT_CF_TEMPLATE_PARTIAL_SPECIALISATION_SUPPORT)
00105 # if !defined(STLSOFT_COMPILER_IS_GCC) || \
00106 __GNUC__ > 4 || \
00107 ( __GNUC__ == 3 && \
00108 __GNUC_MINOR__ >= 4)
00109 # define STLSOFT_FILTER_ITERATOR_MEM_SEL_OP_SUPPORT
00110 # endif
00111 #endif
00112
00113
00114
00115
00116
00117 #ifndef _STLSOFT_NO_NAMESPACE
00118 namespace stlsoft
00119 {
00120 #endif
00121
00122
00123
00124
00125
00131 template< ss_typename_param_k I
00132 , ss_typename_param_k P
00133 , ss_typename_param_k T = adapted_iterator_traits<I>
00134 >
00135
00136 class filter_iterator
00137 {
00140 public:
00141 typedef I base_iterator_type;
00142 typedef P filter_predicate_type;
00143 typedef T traits_type;
00144 typedef filter_iterator<I, P, T> class_type;
00145 #if 0
00146 typedef ss_typename_type_k traits_type::iterator_category iterator_category;
00147 #else
00148 typedef ss_typename_type_k min_iterator_category< ss_typename_type_k traits_type::iterator_category
00149 , std::bidirectional_iterator_tag
00150 >::iterator_category iterator_category;
00151 #endif
00152 typedef ss_typename_type_k traits_type::value_type value_type;
00153 typedef ss_typename_type_k traits_type::difference_type difference_type;
00154 typedef ss_typename_type_k traits_type::pointer pointer;
00155 typedef ss_typename_type_k traits_type::const_pointer const_pointer;
00156 typedef ss_typename_type_k traits_type::reference reference;
00157 typedef ss_typename_type_k traits_type::const_reference const_reference;
00158 typedef ss_typename_type_k traits_type::effective_reference effective_reference;
00159 typedef ss_typename_type_k traits_type::effective_const_reference effective_const_reference;
00160 typedef ss_typename_type_k traits_type::effective_pointer effective_pointer;
00161 typedef ss_typename_type_k traits_type::effective_const_pointer effective_const_pointer;
00163
00166 public:
00167 filter_iterator(base_iterator_type begin, base_iterator_type end, filter_predicate_type pr)
00168 : m_it(begin)
00169 , m_begin(begin)
00170 , m_end(end)
00171 , m_predicate(pr)
00172 {
00173 for(; m_it != m_end; ++m_it)
00174 {
00175 if(m_predicate(*m_it))
00176 {
00177 break;
00178 }
00179 }
00180 }
00181
00183 base_iterator_type base() const
00184 {
00185 return m_it;
00186 }
00188
00191 public:
00192 class_type &operator ++()
00193 {
00194 STLSOFT_MESSAGE_ASSERT("Attempting to increment an end-point iterator", m_it != m_end);
00195
00196 for(++m_it; m_it != m_end; ++m_it)
00197 {
00198 if(m_predicate(*m_it))
00199 {
00200 break;
00201 }
00202 }
00203
00204 return *this;
00205 }
00206 class_type operator ++(int)
00207 {
00208 class_type ret(*this);
00209
00210 operator ++();
00211
00212 return ret;
00213 }
00214
00215 effective_reference operator *()
00216 {
00217 return *m_it;
00218 }
00219 effective_const_reference operator *() const
00220 {
00221 return *m_it;
00222 }
00223
00224 #ifdef STLSOFT_FILTER_ITERATOR_MEM_SEL_OP_SUPPORT
00225 # ifdef STLSOFT_FILTER_ITERATOR_MUTABLE_OP_SUPPORT
00226 effective_pointer operator ->()
00227 {
00228 enum { is_iterator_pointer_type = is_pointer_type<base_iterator_type>::value };
00229
00230
00231 typedef ss_typename_type_k value_to_yesno_type<is_iterator_pointer_type>::type yesno_t;
00232
00233 return invoke_member_selection_operator_(yesno_t());
00234 }
00235 # endif
00236
00237 effective_const_pointer operator ->() const
00238 {
00239 enum { is_iterator_pointer_type = is_pointer_type<base_iterator_type>::value };
00240
00241
00242 typedef ss_typename_type_k value_to_yesno_type<is_iterator_pointer_type>::type yesno_t;
00243
00244 return invoke_member_selection_operator_(yesno_t());
00245 }
00246 #endif
00248
00251 public:
00252 class_type &operator --()
00253 {
00254 STLSOFT_MESSAGE_ASSERT("Attempting to increment a start-of-range iterator", m_it != m_begin);
00255
00256 for(--m_it; m_it != m_begin; --m_it)
00257 {
00258 if(m_predicate(*m_it))
00259 {
00260 break;
00261 }
00262 }
00263
00264 return *this;
00265 }
00266 class_type operator --(int)
00267 {
00268 class_type ret(*this);
00269
00270 operator --();
00271
00272 return ret;
00273 }
00275
00278 public:
00279 ss_bool_t equal(class_type const &rhs) const
00280 {
00281 STLSOFT_MESSAGE_ASSERT("Comparing iterators from different sequences", m_end == rhs.m_end);
00282
00283 return m_it == rhs.m_it;
00284 }
00286 ss_bool_t equals(class_type const &rhs) const
00287 {
00288 return equal(rhs);
00289 }
00291
00294 public:
00295 difference_type distance() const
00296 {
00297 return m_end - m_it;
00298 }
00300
00303 private:
00304 #ifdef STLSOFT_FILTER_ITERATOR_MEM_SEL_OP_SUPPORT
00305 effective_pointer invoke_member_selection_operator_(yes_type)
00306 {
00307 return m_it;
00308 }
00309 effective_pointer invoke_member_selection_operator_(no_type)
00310 {
00311 return m_it.operator ->();
00312 }
00313
00314 effective_const_pointer invoke_member_selection_operator_(yes_type) const
00315 {
00316 return m_it;
00317 }
00318 effective_const_pointer invoke_member_selection_operator_(no_type) const
00319 {
00320 return m_it.operator ->();
00321 }
00322 #endif
00324
00327 private:
00328 base_iterator_type m_it;
00329 base_iterator_type m_begin;
00330 base_iterator_type m_end;
00331 filter_predicate_type m_predicate;
00333 };
00334
00335
00336
00337
00338
00349 template< ss_typename_param_k I
00350 , ss_typename_param_k P
00351 >
00352 inline filter_iterator<I, P> make_filter_iterator(I from, I to, P pr)
00353 {
00354 return filter_iterator<I, P>(from, to, pr);
00355 }
00356
00369 template< ss_typename_param_k I
00370 , ss_typename_param_k P
00371 >
00372 inline filter_iterator<I, P> filter(I from, I to, P pr)
00373 {
00374 return make_filter_iterator(from, to, pr);
00375 }
00376
00377
00378
00379
00380
00381
00382
00383 template< ss_typename_param_k I
00384 , ss_typename_param_k P
00385 , ss_typename_param_k T
00386 >
00387 inline ss_bool_t operator ==(filter_iterator<I, P, T> const &lhs, filter_iterator<I, P, T> const &rhs)
00388 {
00389 return lhs.equal(rhs);
00390 }
00391
00392
00393
00394 template< ss_typename_param_k I
00395 , ss_typename_param_k P
00396 , ss_typename_param_k T
00397 >
00398 inline ss_bool_t operator !=(filter_iterator<I, P, T> const &lhs, filter_iterator<I, P, T> const &rhs)
00399 {
00400 return !lhs.equal(rhs);
00401 }
00402
00404
00405
00406 #ifdef STLSOFT_UNITTEST
00407 # include "./unittest/filter_iterator_unittest_.h"
00408 #endif
00409
00410
00411
00412 #ifndef _STLSOFT_NO_NAMESPACE
00413 }
00414 #endif
00415
00416
00417
00418 #endif
00419
00420