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
00043 #ifndef RANGELIB_INCL_RANGELIB_HPP_FILTERED_RANGE
00044 #define RANGELIB_INCL_RANGELIB_HPP_FILTERED_RANGE
00045
00046 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00047 # define RANGELIB_VER_RANGELIB_HPP_FILTERED_RANGE_MAJOR 2
00048 # define RANGELIB_VER_RANGELIB_HPP_FILTERED_RANGE_MINOR 5
00049 # define RANGELIB_VER_RANGELIB_HPP_FILTERED_RANGE_REVISION 2
00050 # define RANGELIB_VER_RANGELIB_HPP_FILTERED_RANGE_EDIT 31
00051 #endif
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070 #ifndef RANGELIB_INCL_RANGELIB_HPP_RANGELIB
00071 # include <rangelib/rangelib.hpp>
00072 #endif
00073 #ifndef RANGELIB_INCL_RANGELIB_HPP_RANGE_CATEGORIES
00074 # include <rangelib/range_categories.hpp>
00075 #endif
00076 #ifndef RANGELIB_INCL_RANGELIB_HPP_OPERATOR_ADAPTORS
00077 # include <rangelib/operator_adaptors.hpp>
00078 #endif
00079 #ifndef STLSOFT_INCL_STLSOFT_META_HPP_CAPABILITIES
00080 # include <stlsoft/meta/capabilities.hpp>
00081 #endif
00082 #if !defined(STLSOFT_CF_HAS_MEMBER_TYPE_SUPPORTED)
00083 # error This file is not compatible with compilers that do not support member type detection
00084 #else
00085 # ifndef STLSOFT_INCL_STLSOFT_META_TYPEFIXER_HPP_DIFFERENCE_TYPE
00086 # include <stlsoft/meta/typefixer/difference_type.hpp>
00087 # endif
00088 # ifndef STLSOFT_INCL_STLSOFT_META_TYPEFIXER_HPP_REFERENCE
00089 # include <stlsoft/meta/typefixer/reference.hpp>
00090 # endif
00091 # ifndef STLSOFT_INCL_STLSOFT_META_TYPEFIXER_HPP_ITERATOR
00092 # include <stlsoft/meta/typefixer/iterator.hpp>
00093 # endif
00094 # ifndef STLSOFT_INCL_STLSOFT_META_HPP_MEMBER_TRAITS
00095 # include <stlsoft/meta/member_traits.hpp>
00096 # endif
00097 #endif
00098 #ifndef STLSOFT_INCL_STLSOFT_HPP_FILTER_ITERATOR
00099 # include <stlsoft/iterators/filter_iterator.hpp>
00100 #endif
00101
00102
00103
00104
00105
00106 #ifndef RANGELIB_NO_NAMESPACE
00107 # if defined(_STLSOFT_NO_NAMESPACE) || \
00108 defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
00109
00110 namespace rangelib
00111 {
00112 # else
00113
00114
00115 namespace stlsoft
00116 {
00117
00118 namespace rangelib_project
00119 {
00120
00121 # endif
00122 #endif
00123
00124
00125
00126
00127
00136 template< ss_typename_param_k R
00137 , ss_typename_param_k P
00138 , ss_typename_param_k RC = ss_typename_type_k R::range_tag_type
00139 >
00140 class filtered_range
00141 #if defined(STLSOFT_CF_HAS_MEMBER_TYPE_SUPPORTED)
00142 : public operator_adaptor_selector<filtered_range<R, P, RC>, R>::type
00143 #else
00144 : public non_mutating_operator_adaptor<filtered_range<R, P, RC>, R>
00145 #endif
00146 , public RC
00147 {
00150 public:
00151 typedef R filtered_range_type;
00152 typedef P filter_predicate_type;
00153 typedef RC range_tag_type;
00154 typedef filtered_range<R, P, RC> class_type;
00155 private:
00156 #ifdef STLSOFT_CF_HAS_MEMBER_TYPE_SUPPORTED
00163 enum { HAS_MEMBER_ITERATOR = 0 != member_traits<filtered_range_type>::has_member_iterator };
00164 enum { HAS_MEMBER_CONST_ITERATOR = 0 != member_traits<filtered_range_type>::has_member_const_iterator };
00165 # if defined(STLSOFT_COMPILER_IS_MWERKS)
00166 enum { HAS_MEMBER_REFERENCE = 0 != member_traits<filtered_range_type>::has_member_reference };
00167 # else
00168 enum { HAS_MEMBER_REFERENCE = 0 != HAS_MEMBER_ITERATOR };
00169 # endif
00170 #endif
00171 private:
00173 typedef ss_typename_type_k select_first_type_if< ss_typename_type_k ::stlsoft::typefixer::fixer_const_iterator<filtered_range_type, HAS_MEMBER_CONST_ITERATOR>::const_iterator
00174 , void
00175 , HAS_MEMBER_CONST_ITERATOR
00176 >::type const_iterator_base_type;
00177
00179 typedef ss_typename_type_k select_first_type_if< ss_typename_type_k ::stlsoft::typefixer::fixer_iterator<filtered_range_type, HAS_MEMBER_ITERATOR>::iterator
00180 , const_iterator_base_type
00181 , HAS_MEMBER_ITERATOR
00182 >::type iterator_base_type;
00183 public:
00185 typedef filter_iterator<iterator_base_type, filter_predicate_type> iterator;
00187 typedef filter_iterator<const_iterator_base_type, filter_predicate_type> const_iterator;
00189 typedef ss_typename_type_k select_first_type_if< ss_typename_type_k ::stlsoft::typefixer::fixer_reference<filtered_range_type, HAS_MEMBER_REFERENCE>::reference
00190 , ss_typename_type_k filtered_range_type::const_reference
00191 , HAS_MEMBER_REFERENCE
00192 >::type reference;
00194 typedef ss_typename_type_k filtered_range_type::const_reference const_reference;
00196 typedef ss_typename_type_k filtered_range_type::value_type value_type;
00198
00201 public:
00206 ss_explicit_k filtered_range(filtered_range_type r, filter_predicate_type pr = filter_predicate_type())
00207 : m_range(r)
00208 , m_predicate(pr)
00209 {
00210 for(; m_range; ++m_range)
00211 {
00212 if(m_predicate(*m_range))
00213 {
00214 break;
00215 }
00216 }
00217 }
00219
00222 public:
00224 ss_bool_t is_open() const
00225 {
00226 return m_range.is_open();
00227 }
00229 reference current()
00230 {
00231 STLSOFT_ASSERT(is_open());
00232
00233 return m_range.current();
00234 }
00236 const_reference current() const
00237 {
00238 STLSOFT_ASSERT(is_open());
00239
00240 return m_range.current();
00241 }
00243 class_type& advance()
00244 {
00245 STLSOFT_MESSAGE_ASSERT("Attempting to increment the range past its end point", is_open());
00246
00247 for(++m_range; m_range; ++m_range)
00248 {
00249 if(m_predicate(*m_range))
00250 {
00251 break;
00252 }
00253 }
00254
00255 return *this;
00256 }
00258
00261 public:
00263 iterator begin()
00264 {
00265 return iterator(m_range.begin(), m_range.end(), m_predicate);
00266 }
00268 iterator end()
00269 {
00270 return iterator(m_range.end(), m_range.end(), m_predicate);
00271 }
00272
00274 const_iterator begin() const
00275 {
00276 return const_iterator(m_range.begin(), m_range.end(), m_predicate);
00277 }
00279 const_iterator end() const
00280 {
00281 return const_iterator(m_range.end(), m_range.end(), m_predicate);
00282 }
00284
00287 private:
00288 filtered_range_type m_range;
00289 filter_predicate_type m_predicate;
00291 };
00292
00293
00294
00295
00296
00297 template< ss_typename_param_k R
00298 , ss_typename_param_k P
00299 >
00300 inline filtered_range<R, P> make_filtered_range(R r, P pr)
00301 {
00302 return filtered_range<R, P>(r, pr);
00303 }
00304
00305 template< ss_typename_param_k R
00306 , ss_typename_param_k P
00307 >
00308 inline filtered_range<R, P> filter_range(R r, P pr)
00309 {
00310 return filtered_range<R, P>(r, pr);
00311 }
00312
00314
00315
00316 #ifdef STLSOFT_UNITTEST
00317 # include "./unittest/filtered_range_unittest_.h"
00318 #endif
00319
00320
00321
00322 #ifndef RANGELIB_NO_NAMESPACE
00323 # if defined(_STLSOFT_NO_NAMESPACE) || \
00324 defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
00325 }
00326 # else
00327 }
00328 }
00329 # endif
00330 #endif
00331
00332
00333
00334 #endif
00335
00336