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 4
00056 # define STLSOFT_VER_STLSOFT_ITERATORS_HPP_FILTER_ITERATOR_EDIT 40
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_META_HPP_YESNO
00087 # include <stlsoft/meta/yesno.hpp>
00088 #endif
00089 #ifndef STLSOFT_INCL_STLSOFT_META_HPP_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
00136 template< ss_typename_param_k I
00137 , ss_typename_param_k P
00138 , ss_typename_param_k T = adapted_iterator_traits<I>
00139 >
00140
00141 class filter_iterator
00142 {
00145 public:
00146 typedef I base_iterator_type;
00147 typedef P filter_predicate_type;
00148 typedef T traits_type;
00149 typedef filter_iterator<I, P, T> class_type;
00150 #if 0
00151 typedef ss_typename_type_k traits_type::iterator_category iterator_category;
00152 #else
00153 typedef ss_typename_type_k min_iterator_category< ss_typename_type_k traits_type::iterator_category
00154 , std::bidirectional_iterator_tag
00155 >::iterator_category iterator_category;
00156 #endif
00157 typedef ss_typename_type_k traits_type::value_type value_type;
00158 typedef ss_typename_type_k traits_type::difference_type difference_type;
00159 typedef ss_typename_type_k traits_type::pointer pointer;
00160 typedef ss_typename_type_k traits_type::const_pointer const_pointer;
00161 typedef ss_typename_type_k traits_type::reference reference;
00162 typedef ss_typename_type_k traits_type::const_reference const_reference;
00163 typedef ss_typename_type_k traits_type::effective_reference effective_reference;
00164 typedef ss_typename_type_k traits_type::effective_const_reference effective_const_reference;
00165 typedef ss_typename_type_k traits_type::effective_pointer effective_pointer;
00166 typedef ss_typename_type_k traits_type::effective_const_pointer effective_const_pointer;
00168
00171 public:
00172 filter_iterator(base_iterator_type begin, base_iterator_type end, filter_predicate_type pr)
00173 : m_it(begin)
00174 , m_begin(begin)
00175 , m_end(end)
00176 , m_predicate(pr)
00177 {
00178 for(; m_it != m_end; ++m_it)
00179 {
00180 if(m_predicate(*m_it))
00181 {
00182 break;
00183 }
00184 }
00185 }
00186
00188 base_iterator_type base() const
00189 {
00190 return m_it;
00191 }
00193
00196 public:
00197 class_type& operator ++()
00198 {
00199 STLSOFT_MESSAGE_ASSERT("Attempting to increment an endpoint iterator", m_it != m_end);
00200
00201 for(++m_it; m_it != m_end; ++m_it)
00202 {
00203 if(m_predicate(*m_it))
00204 {
00205 break;
00206 }
00207 }
00208
00209 return *this;
00210 }
00211 class_type operator ++(int)
00212 {
00213 class_type ret(*this);
00214
00215 operator ++();
00216
00217 return ret;
00218 }
00219
00220 effective_reference operator *()
00221 {
00222 return *m_it;
00223 }
00224 effective_const_reference operator *() const
00225 {
00226 return *m_it;
00227 }
00228
00229 #ifdef STLSOFT_FILTER_ITERATOR_MEM_SEL_OP_SUPPORT
00230 # ifdef STLSOFT_FILTER_ITERATOR_MUTABLE_OP_SUPPORT
00231 effective_pointer operator ->()
00232 {
00233 enum { is_iterator_pointer_type = is_pointer_type<base_iterator_type>::value };
00234
00235
00236 typedef ss_typename_type_k value_to_yesno_type<is_iterator_pointer_type>::type yesno_t;
00237
00238 return invoke_member_selection_operator_(yesno_t());
00239 }
00240 # endif
00241
00242 effective_const_pointer operator ->() const
00243 {
00244 enum { is_iterator_pointer_type = is_pointer_type<base_iterator_type>::value };
00245
00246
00247 typedef ss_typename_type_k value_to_yesno_type<is_iterator_pointer_type>::type yesno_t;
00248
00249 return invoke_member_selection_operator_(yesno_t());
00250 }
00251 #endif
00253
00256 public:
00257 class_type& operator --()
00258 {
00259 STLSOFT_MESSAGE_ASSERT("Attempting to increment a start-of-range iterator", m_it != m_begin);
00260
00261 for(--m_it; m_it != m_begin; --m_it)
00262 {
00263 if(m_predicate(*m_it))
00264 {
00265 break;
00266 }
00267 }
00268
00269 return *this;
00270 }
00271 class_type operator --(int)
00272 {
00273 class_type ret(*this);
00274
00275 operator --();
00276
00277 return ret;
00278 }
00280
00283 public:
00284 ss_bool_t equal(class_type const& rhs) const
00285 {
00286 STLSOFT_MESSAGE_ASSERT("Comparing iterators from different sequences", m_end == rhs.m_end);
00287
00288 return m_it == rhs.m_it;
00289 }
00291 ss_bool_t equals(class_type const& rhs) const
00292 {
00293 return equal(rhs);
00294 }
00296
00299 public:
00300 difference_type distance() const
00301 {
00302 return m_end - m_it;
00303 }
00305
00308 private:
00309 #ifdef STLSOFT_FILTER_ITERATOR_MEM_SEL_OP_SUPPORT
00310 effective_pointer invoke_member_selection_operator_(yes_type)
00311 {
00312 return m_it;
00313 }
00314 effective_pointer invoke_member_selection_operator_(no_type)
00315 {
00316 return m_it.operator ->();
00317 }
00318
00319 effective_const_pointer invoke_member_selection_operator_(yes_type) const
00320 {
00321 return m_it;
00322 }
00323 effective_const_pointer invoke_member_selection_operator_(no_type) const
00324 {
00325 return m_it.operator ->();
00326 }
00327 #endif
00329
00332 private:
00333 base_iterator_type m_it;
00334 base_iterator_type m_begin;
00335 base_iterator_type m_end;
00336 filter_predicate_type m_predicate;
00338 };
00339
00340
00341
00342
00343
00354 template< ss_typename_param_k I
00355 , ss_typename_param_k P
00356 >
00357 inline filter_iterator<I, P> make_filter_iterator(I from, I to, P pr)
00358 {
00359 return filter_iterator<I, P>(from, to, pr);
00360 }
00361
00374 template< ss_typename_param_k I
00375 , ss_typename_param_k P
00376 >
00377 inline filter_iterator<I, P> filter(I from, I to, P pr)
00378 {
00379 return make_filter_iterator(from, to, pr);
00380 }
00381
00382
00383
00384
00385
00386
00387
00388 template< ss_typename_param_k I
00389 , ss_typename_param_k P
00390 , ss_typename_param_k T
00391 >
00392 inline ss_bool_t operator ==(filter_iterator<I, P, T> const& lhs, filter_iterator<I, P, T> const& rhs)
00393 {
00394 return lhs.equal(rhs);
00395 }
00396
00397
00398
00399 template< ss_typename_param_k I
00400 , ss_typename_param_k P
00401 , ss_typename_param_k T
00402 >
00403 inline ss_bool_t operator !=(filter_iterator<I, P, T> const& lhs, filter_iterator<I, P, T> const& rhs)
00404 {
00405 return !lhs.equal(rhs);
00406 }
00407
00409
00410
00411 #ifdef STLSOFT_UNITTEST
00412 # include "./unittest/filter_iterator_unittest_.h"
00413 #endif
00414
00415
00416
00417 #ifndef _STLSOFT_NO_NAMESPACE
00418 }
00419 #endif
00420
00421
00422
00423 #endif
00424
00425