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_ITERATOR_RANGE
00044 #define RANGELIB_INCL_RANGELIB_HPP_ITERATOR_RANGE
00045
00046 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00047 # define RANGELIB_VER_RANGELIB_HPP_ITERATOR_RANGE_MAJOR 2
00048 # define RANGELIB_VER_RANGELIB_HPP_ITERATOR_RANGE_MINOR 6
00049 # define RANGELIB_VER_RANGELIB_HPP_ITERATOR_RANGE_REVISION 4
00050 # define RANGELIB_VER_RANGELIB_HPP_ITERATOR_RANGE_EDIT 43
00051 #endif
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071 #ifndef RANGELIB_INCL_RANGELIB_HPP_RANGELIB
00072 # include <rangelib/rangelib.hpp>
00073 #endif
00074
00075 #ifndef STLSOFT_CF_TEMPLATE_PARTIAL_SPECIALISATION_SUPPORT
00076 # error rangelib/iterator_range.hpp is not compatible with compilers that do not support partial template specialisation
00077 #endif
00078
00079 #ifndef RANGELIB_INCL_RANGELIB_HPP_RANGE_CATEGORIES
00080 # include <rangelib/range_categories.hpp>
00081 #endif
00082 #ifndef STLSOFT_INCL_STLSOFT_UTIL_HPP_OPERATOR_BOOL
00083 # include <stlsoft/util/operator_bool.hpp>
00084 #endif
00085 #ifndef STLSOFT_INCL_STLSOFT_META_HPP_CAPABILITIES
00086 # include <stlsoft/meta/capabilities.hpp>
00087 #endif
00088 #ifndef STLSOFT_INCL_STLSOFT_META_HPP_BASE_TYPE_TRAITS
00089 # include <stlsoft/meta/base_type_traits.hpp>
00090 #endif
00091 #ifndef STLSOFT_INCL_STLSOFT_UTIL_STD_HPP_ITERATOR_HELPER
00092 # include <stlsoft/util/std/iterator_helper.hpp>
00093 #endif
00094
00095 #ifdef STLSOFT_UNITTEST
00096 # include <algorithm>
00097 # include <deque>
00098 # include <list>
00099 # include <numeric>
00100 # include <vector>
00101 #endif
00102
00103
00104
00105
00106
00107 #ifndef RANGELIB_NO_NAMESPACE
00108 # if defined(_STLSOFT_NO_NAMESPACE) || \
00109 defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
00110
00111 namespace rangelib
00112 {
00113 # else
00114
00115
00116 namespace stlsoft
00117 {
00118
00119 namespace rangelib_project
00120 {
00121
00122 # endif
00123 #endif
00124
00125
00126
00127
00128
00129 #ifdef STLSOFT_CF_TEMPLATE_PARTIAL_SPECIALISATION_SUPPORT
00130
00135 template< ss_typename_param_k I
00136 , bool B_CONST
00137 >
00138 struct iterator_range_traits
00139 {
00140 public:
00142 typedef I iterator_type;
00144 typedef ss_typename_type_k I::value_type value_type;
00145 private:
00146 #ifdef STLSOFT_ITERATOR_ITERATOR_FORM2_SUPPORT
00147
00148 enum { is_const = base_type_traits<value_type>::is_const };
00149 #else
00150
00151 typedef std::iterator_traits<I> traits_type_;
00152
00153 typedef ss_typename_type_k traits_type_::pointer pointer_type_;
00154
00155 enum { is_const = base_type_traits<pointer_type_>::is_const };
00156 #endif
00157
00158 typedef ss_typename_type_k base_type_traits<value_type>::base_type base_value_type;
00159
00160 public:
00162 typedef I iterator;
00164 typedef ss_typename_type_k base_type_traits<iterator>::base_type const& const_iterator;
00166 typedef ss_typename_type_k select_first_type_if<base_value_type const&
00167 , base_value_type &, is_const>::type reference;
00169 typedef base_value_type const& const_reference;
00170
00172 typedef ss_typename_type_k iterator_type::difference_type difference_type;
00174 typedef ss_typename_type_k iterator_type::size_type size_type;
00175 };
00176
00177 # ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00178
00179 template< ss_typename_param_k T
00180 , bool B_CONST
00181 >
00182 struct iterator_range_traits<T*, B_CONST>
00183 {
00184 typedef T value_type;
00185 typedef value_type* iterator;
00186 typedef value_type const* const_iterator;
00187 typedef value_type& reference;
00188 typedef value_type const& const_reference;
00189 };
00190
00191 template< ss_typename_param_k T
00192 , bool B_CONST
00193 >
00194 struct iterator_range_traits<T const*, B_CONST>
00195 {
00196 typedef T value_type;
00197 typedef value_type const* iterator;
00198 typedef value_type const* const_iterator;
00199 typedef value_type const& reference;
00200 typedef value_type const& const_reference;
00201 };
00202
00203 # endif
00204
00205 #else
00206
00207 template< ss_typename_param_k I
00208 >
00209 struct iterator_range_traits
00210 {
00211 public:
00212 typedef I iterator_type;
00213 typedef ss_typename_type_k iterator_type::value_type value_type;
00214 typedef ss_typename_type_k iterator_type::iterator iterator;
00215 typedef ss_typename_type_k iterator_type::const_iterator const_iterator;
00216 typedef ss_typename_type_k iterator_type::reference reference;
00217 typedef ss_typename_type_k iterator_type::const_reference const_reference;
00218
00219 typedef ss_typename_type_k iterator_type::difference_type difference_type;
00220 typedef ss_typename_type_k iterator_type::size_type size_type;
00221 };
00222
00223 template< ss_typename_param_k I
00224 >
00225 struct const_iterator_range_traits
00226 {
00227 public:
00228 typedef I iterator_type;
00229 typedef ss_typename_type_k iterator_type::value_type value_type;
00230 typedef ss_typename_type_k iterator_type::const_iterator iterator;
00231 typedef ss_typename_type_k iterator_type::const_iterator const_iterator;
00232 typedef ss_typename_type_k iterator_type::const_reference reference;
00233 typedef ss_typename_type_k iterator_type::const_reference const_reference;
00234 typedef ss_typename_type_k iterator_type::difference_type difference_type;
00235 typedef ss_typename_type_k iterator_type::size_type size_type;
00236 };
00237
00238 template< ss_typename_param_k T
00239 >
00240 struct pointer_iterator_range_traits
00241 {
00242 typedef T value_type;
00243 typedef T* iterator;
00244 typedef T const* const_iterator;
00245 typedef T& reference;
00246 typedef T const& const_reference;
00247 typedef ptrdiff_t difference_type;
00248 typedef size_t size_type;
00249 };
00250
00251 template< ss_typename_param_k T
00252 >
00253 struct const_pointer_iterator_range_traits
00254 {
00255 typedef T value_type;
00256 typedef T const* iterator;
00257 typedef T const* const_iterator;
00258 typedef T const& reference;
00259 typedef T const& const_reference;
00260 typedef ptrdiff_t difference_type;
00261 typedef size_t size_type;
00262 };
00263
00264 #endif
00265
00266
00288 template< ss_typename_param_k I
00289 #ifdef STLSOFT_CF_TEMPLATE_PARTIAL_SPECIALISATION_SUPPORT
00290 , ss_typename_param_k T = iterator_range_traits<I, is_const_type<I>::value>
00291 #else
00292 , ss_typename_param_k T
00293 #endif
00294 >
00295 class iterator_range
00296 : public iterable_range_tag
00297 {
00300 public:
00302 typedef I iterator_type;
00304 typedef T traits_type;
00306 typedef iterable_range_tag range_tag_type;
00308 typedef iterator_range<I, T> class_type;
00310 typedef ss_typename_type_k traits_type::value_type value_type;
00312 typedef ss_typename_type_k traits_type::iterator iterator;
00314 typedef ss_typename_type_k traits_type::const_iterator const_iterator;
00316 typedef ss_typename_type_k traits_type::reference reference;
00318 typedef ss_typename_type_k traits_type::const_reference const_reference;
00320
00323 public:
00324 #if !defined(STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT) || \
00325 defined(STLSOFT_CF_MEMBER_TEMPLATE_CTOR_OVERLOAD_DISCRIMINATED) || \
00326 ( defined(STLSOFT_COMPILER_IS_MSVC) && \
00327 _MSC_VER == 1200)
00329 iterator_range(iterator first, iterator last)
00330 : m_position(first)
00331 , m_last(last)
00332 {}
00333 #endif
00334
00335 #if defined(STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT) && \
00336 ( !defined(STLSOFT_COMPILER_IS_MSVC) || \
00337 _MSC_VER != 1200)
00339 template <ss_typename_param_k I2>
00340 iterator_range(I2 first, I2 last)
00341 : m_position(first)
00342 , m_last(last)
00343 {}
00344 #endif
00345
00346 #ifdef STLSOFT_CF_STATIC_ARRAY_SIZE_DETERMINATION_SUPPORT
00348 template <ss_typename_param_k T2, ss_size_t N>
00349 iterator_range(T2 (&ar)[N])
00350 : m_position(&ar[0])
00351 , m_last(&ar[N])
00352 {}
00353 #endif
00355
00358 private:
00359 STLSOFT_DEFINE_OPERATOR_BOOL_TYPES_T(class_type, boolean_generator_type, boolean_type);
00360 public:
00362 ss_bool_t is_open() const
00363 {
00364 return m_position != m_last;
00365 }
00367 reference current()
00368 {
00369 STLSOFT_ASSERT(is_open());
00370
00371 return *m_position;
00372 }
00374 const_reference current() const
00375 {
00376 STLSOFT_ASSERT(is_open());
00377
00378 return *m_position;
00379 }
00380
00382 operator boolean_type() const
00383 {
00384 return boolean_generator_type::translate(is_open());
00385 }
00387 reference operator *()
00388 {
00389 return current();
00390 }
00392 const_reference operator *() const
00393 {
00394 return current();
00395 }
00396
00398 class_type& advance()
00399 {
00400 STLSOFT_MESSAGE_ASSERT("Attempting to increment the range past its end point", is_open());
00401
00402 ++m_position;
00403
00404 return *this;
00405 }
00407 class_type& operator ++()
00408 {
00409 return advance();
00410 }
00413 class_type operator ++(int)
00414 {
00415 class_type ret(*this);
00416
00417 operator ++();
00418
00419 return ret;
00420 }
00422
00425 public:
00427 iterator begin()
00428 {
00429 return m_position;
00430 }
00432 iterator end()
00433 {
00434 return m_last;
00435 }
00436
00438 const_iterator begin() const
00439 {
00440 return m_position;
00441 }
00443 const_iterator end() const
00444 {
00445 return m_last;
00446 }
00448
00451 private:
00452 iterator m_position;
00453 iterator m_last;
00455 };
00456
00458
00459
00460 #ifdef STLSOFT_CF_TEMPLATE_PARTIAL_SPECIALISATION_SUPPORT
00461
00462 template<ss_typename_param_k I>
00463 inline iterator_range<I> make_iterator_range(I &first, I &last)
00464 {
00465 return iterator_range<I>(first, last);
00466 }
00467
00468 #else
00469
00470 template<ss_typename_param_k I>
00471 inline iterator_range<I, iterator_range_traits<I> > make_iterator_range(I &first, I &last)
00472 {
00473 return iterator_range<I, iterator_range_traits<I> >(first, last);
00474 }
00475
00476 #if 0
00477 template<ss_typename_param_k T>
00478 inline iterator_range<T*, iterator_range_traits<T> > make_iterator_range(T *first, T* last)
00479 {
00480 return iterator_range<T*, iterator_range_traits<T> >(first, last);
00481 }
00482 #endif
00483
00484 template<ss_typename_param_k T>
00485 inline iterator_range<T const*, const_pointer_iterator_range_traits<const T> > make_iterator_range(T const* first, T const* last)
00486 {
00487 return iterator_range<T const*, const_pointer_iterator_range_traits<const T> >(first, last);
00488 }
00489
00490 #endif
00491
00493
00494
00495 #ifdef STLSOFT_UNITTEST
00496 # include "./unittest/iterator_range_unittest_.h"
00497 #endif
00498
00499
00500
00501 #ifndef RANGELIB_NO_NAMESPACE
00502 # if defined(_STLSOFT_NO_NAMESPACE) || \
00503 defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
00504 }
00505 # else
00506 }
00507 }
00508 # endif
00509 #endif
00510
00511
00512
00513 #endif
00514
00515