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
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057 #ifndef STLSOFT_INCL_H_STLSOFT
00058 # include <stlsoft.h>
00059 #endif
00060 #ifndef STLSOFT_INCL_RANGELIB_HPP_RANGE_CATEGORIES
00061 # include <rangelib/range_categories.hpp>
00062 #endif
00063 #ifndef STLSOFT_INCL_H_STLSOFT_OPERATOR_BOOL
00064 # include <stlsoft_operator_bool.h>
00065 #endif
00066 #ifndef STLSOFT_INCL_H_STLSOFT_META
00067 # include <stlsoft_meta.h>
00068 #endif
00069 #ifndef STLSOFT_INCL_H_STLSOFT_FILTER_ITERATOR
00070 # include <stlsoft_filter_iterator.h>
00071 #endif
00072
00073
00074
00075
00076
00077 #ifndef _STLSOFT_NO_NAMESPACE
00078 namespace stlsoft
00079 {
00080 #endif
00081
00082
00083
00088
00089
00090
00091
00092
00098 template< ss_typename_param_k R
00099 , ss_typename_param_k P
00100 , ss_typename_param_k RT = ss_typename_type_k R::range_tag_type
00101 >
00102 class filtered_range
00103 : public RT
00104 {
00105 public:
00106 typedef R filtered_range_type;
00107 typedef P filter_predicate_type;
00108 typedef RT range_tag_type;
00109 typedef filtered_range<R, P, RT> class_type;
00110 private:
00111 typedef ss_typename_type_k filtered_range_type::iterator iterator_base_type;
00112 typedef ss_typename_type_k filtered_range_type::const_iterator const_iterator_base_type;
00113 public:
00114 typedef filtered_iterator<iterator_base_type, filter_predicate_type> iterator;
00115 typedef filtered_iterator<const_iterator_base_type, filter_predicate_type> const_iterator;
00116 typedef ss_typename_type_k filtered_range_type::reference reference;
00117 typedef ss_typename_type_k filtered_range_type::const_reference const_reference;
00118 typedef ss_typename_type_k filtered_range_type::value_type value_type;
00119
00120 public:
00125 filtered_range(filtered_range_type r, filter_predicate_type pr)
00126 : m_range(r)
00127 , m_predicate(pr)
00128 {
00129 for(; m_range; ++m_range)
00130 {
00131 if(m_predicate(*m_range))
00132 {
00133 break;
00134 }
00135 }
00136 }
00137
00140 private:
00141 STLSOFT_DEFINE_OPERATOR_BOOL_TYPES_T(class_type, boolean_generator_type, boolean_type);
00142 public:
00144 ss_bool_t is_open() const
00145 {
00146 return m_range.is_open();
00147 }
00149 reference current()
00150 {
00151 stlsoft_assert(is_open());
00152
00153 return m_range.current();
00154 }
00156 const_reference current() const
00157 {
00158 stlsoft_assert(is_open());
00159
00160 return m_range.current();
00161 }
00163 class_type &advance()
00164 {
00165 stlsoft_message_assert("Attempting to increment the range past its end point", is_open());
00166
00167 for(++m_range; m_range; ++m_range)
00168 {
00169 if(m_predicate(*m_range))
00170 {
00171 break;
00172 }
00173 }
00174
00175 return *this;
00176 }
00177
00179 operator boolean_type() const
00180 {
00181 return boolean_generator_type::translate(is_open());
00182 }
00184 reference operator *()
00185 {
00186 return current();
00187 }
00189 const_reference operator *() const
00190 {
00191 return current();
00192 }
00194 class_type &operator ++()
00195 {
00196 return advance();
00197 }
00200 class_type operator ++(int)
00201 {
00202 class_type ret(*this);
00203
00204 operator ++();
00205
00206 return ret;
00207 }
00209
00212 public:
00214 iterator begin()
00215 {
00216 return iterator(m_range.begin(), m_range.end(), m_predicate);
00217 }
00219 iterator end()
00220 {
00221 return iterator(m_range.end(), m_range.end(), m_predicate);
00222 }
00223
00225 const_iterator begin() const
00226 {
00227 return const_iterator(m_range.begin(), m_range.end(), m_predicate);
00228 }
00230 const_iterator end() const
00231 {
00232 return const_iterator(m_range.end(), m_range.end(), m_predicate);
00233 }
00235
00236
00237 private:
00238 filtered_range_type m_range;
00239 filter_predicate_type m_predicate;
00240 };
00241
00242 template< ss_typename_param_k R
00243 , ss_typename_param_k P
00244 >
00245 inline filtered_range<R, P> filter_range(R r, P p)
00246 {
00247 return filtered_range<R, P>(r, p);
00248 }
00249
00251
00252
00253 #ifdef STLSOFT_UNITTEST
00254
00255 namespace unittest
00256 {
00257 ss_bool_t test_rangelib_filtered_range(unittest_reporter *r)
00258 {
00259 using stlsoft::unittest::unittest_initialiser;
00260
00261 ss_bool_t bSuccess = true;
00262
00263 unittest_initialiser init(r, "RangeLib", "filtered_range", __FILE__);
00264
00265 #if 0
00266 if(NULL != pi1)
00267 {
00268 ator1.construct(pi1, 1968);
00269
00270 if(1968 != *pi1)
00271 {
00272 r->report("construct() failed ", __LINE__);
00273 bSuccess = false;
00274 }
00275 }
00276 #endif
00277
00278 return bSuccess;
00279 }
00280
00281 unittest_registrar unittest_rangelib_filtered_range(test_rangelib_filtered_range);
00282
00283 }
00284
00285 #endif
00286
00287
00288
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301