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_ITERATOR
00067 # include <stlsoft_iterator.h>
00068 #endif
00069 #ifndef STLSOFT_INCL_H_STLSOFT_CONSTRAINTS
00070 # include <stlsoft_constraints.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
00109 template <ss_typename_param_k C>
00110 class cstring_range
00111 : public notional_range_tag
00112 {
00113 public:
00115 typedef C value_type;
00117 typedef cstring_range<C> class_type;
00119 typedef value_type const *const_pointer;
00121 typedef value_type const &const_reference;
00122
00125 public:
00129 cstring_range(value_type const *s)
00130 : m_s(s)
00131 {
00132 stlsoft_message_assert("NULL string passed to cstring_range constructor", NULL != s);
00133 }
00135 ~cstring_range()
00136 {
00137
00138
00139 stlsoft_static_assert(0 != is_integral_type<value_type>::value);
00140 stlsoft_static_assert(0 == is_numeric_type<value_type>::value);
00141 stlsoft_static_assert(0 == is_bool_type<value_type>::value);
00142 }
00144
00147 private:
00148 STLSOFT_DEFINE_OPERATOR_BOOL_TYPES_T(class_type, boolean_generator_type, boolean_type);
00149 public:
00151 ss_bool_t is_open() const
00152 {
00153 stlsoft_assert(NULL != m_s);
00154
00155 return '\0' != *m_s;
00156 }
00158 const_reference current() const
00159 {
00160 stlsoft_message_assert("Attempting to access the value of a closed range", is_open());
00161
00162 return *m_s;
00163 }
00165 class_type &advance()
00166 {
00167 stlsoft_message_assert("Attempting to advance a closed range", is_open());
00168
00169 ++m_s;
00170
00171 return *this;
00172 }
00173
00175 operator boolean_type() const
00176 {
00177 return boolean_generator_type::translate(is_open());
00178 }
00180 const_reference operator *() const
00181 {
00182 return current();
00183 }
00185 class_type &operator ++()
00186 {
00187 return advance();
00188 }
00191 class_type operator ++(int)
00192 {
00193 class_type ret(*this);
00194
00195 operator ++();
00196
00197 return ret;
00198 }
00200
00201
00202 private:
00203 value_type const *m_s;
00204 };
00205
00207
00208
00209 #ifdef STLSOFT_UNITTEST
00210
00211 namespace unittest
00212 {
00213 namespace
00214 {
00215 }
00216
00217 ss_bool_t test_stlsoft_rangelib_cstring_range(unittest_reporter *r)
00218 {
00219 using stlsoft::unittest::unittest_initialiser;
00220
00221 ss_bool_t bSuccess = true;
00222
00223 unittest_initialiser init(r, "RangeLib", "cstring_range", __FILE__);
00224
00225 typedef cstring_range<char> cstring_range_t;
00226
00227 cstring_range_t r1("Hello, Natty!");
00228 size_t len;
00229
00230 for(len = 0; r1; ++r1, ++len)
00231 {}
00232
00233 if(13 != len)
00234 {
00235 r->report("manual enumeration failed", __LINE__);
00236 bSuccess = false;
00237 }
00238
00239 if(r1.is_open())
00240 {
00241 r->report("closed range presents as open (is_open() method)", __LINE__);
00242 bSuccess = false;
00243 }
00244
00245 if(r1)
00246 {
00247 r->report("closed range presents as open (operator \"bool\"())", __LINE__);
00248 bSuccess = false;
00249 }
00250
00251 if(cstring_range_t(""))
00252 {
00253 r->report("closed range presents as open", __LINE__);
00254 bSuccess = false;
00255 }
00256
00257 return bSuccess;
00258 }
00259
00260 unittest_registrar unittest_stlsoft_rangelib_cstring_range(test_stlsoft_rangelib_cstring_range);
00261
00262 }
00263
00264 #endif
00265
00266
00267
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280