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
00042
00043
00046 #ifndef RANGELIB_INCL_RANGELIB_HPP_SEQUENCE_RANGE
00047 #define RANGELIB_INCL_RANGELIB_HPP_SEQUENCE_RANGE
00048
00049 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00050 # define RANGELIB_VER_RANGELIB_HPP_SEQUENCE_RANGE_MAJOR 2
00051 # define RANGELIB_VER_RANGELIB_HPP_SEQUENCE_RANGE_MINOR 12
00052 # define RANGELIB_VER_RANGELIB_HPP_SEQUENCE_RANGE_REVISION 2
00053 # define RANGELIB_VER_RANGELIB_HPP_SEQUENCE_RANGE_EDIT 62
00054 #endif
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 #ifndef RANGELIB_INCL_RANGELIB_HPP_RANGE_CATEGORIES
00075 # include <rangelib/range_categories.hpp>
00076 #endif
00077 #ifndef RANGELIB_INCL_RANGELIB_HPP_OPERATOR_ADAPTORS
00078 # include <rangelib/operator_adaptors.hpp>
00079 #endif
00080 #ifndef STLSOFT_INCL_STLSOFT_META_HPP_CAPABILITIES
00081 # include <stlsoft/meta/capabilities.hpp>
00082 #endif
00083 #ifndef STLSOFT_INCL_STLSOFT_META_HPP_IS_CONST_TYPE
00084 # include <stlsoft/meta/is_const_type.hpp>
00085 #endif
00086 #ifdef STLSOFT_CF_HAS_MEMBER_TYPE_SUPPORTED
00087 # ifndef STLSOFT_INCL_STLSOFT_META_TYPEFIXER_HPP_DIFFERENCE_TYPE
00088 # include <stlsoft/meta/typefixer/difference_type.hpp>
00089 # endif
00090 # ifndef STLSOFT_INCL_STLSOFT_META_TYPEFIXER_HPP_REFERENCE
00091 # include <stlsoft/meta/typefixer/reference.hpp>
00092 # endif
00093 # ifndef STLSOFT_INCL_STLSOFT_META_TYPEFIXER_HPP_ITERATOR
00094 # include <stlsoft/meta/typefixer/iterator.hpp>
00095 # endif
00096 # ifndef STLSOFT_INCL_STLSOFT_META_TYPEFIXER_HPP_POINTER
00097 # include <stlsoft/meta/typefixer/pointer.hpp>
00098 # endif
00099 # ifndef STLSOFT_INCL_STLSOFT_META_HPP_MEMBER_TRAITS
00100 # include <stlsoft/meta/member_traits.hpp>
00101 # endif
00102 #endif
00103
00104 #ifdef STLSOFT_UNITTEST
00105 # include <algorithm>
00106 # include <deque>
00107 # include <list>
00108 # include <numeric>
00109 # include <vector>
00110 #endif
00111
00112
00113
00114
00115
00116 #ifndef RANGELIB_NO_NAMESPACE
00117 # if defined(_STLSOFT_NO_NAMESPACE) || \
00118 defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
00119
00120 namespace rangelib
00121 {
00122 # else
00123
00124
00125 namespace stlsoft
00126 {
00127
00128 namespace rangelib_project
00129 {
00130
00131 # endif
00132 #endif
00133
00134
00135
00136
00137
00138 #if defined(STLSOFT_CF_HAS_MEMBER_TYPE_SUPPORTED)
00139
00144 template< ss_typename_param_k S
00145 , bool B_CONST = false
00146 >
00147 struct sequence_range_traits
00148 {
00149 private:
00156 #if defined(STLSOFT_COMPILER_IS_MWERKS)
00157 enum { HAS_MEMBER_REFERENCE = 0 != member_traits<S>::has_member_reference };
00158 enum { HAS_MEMBER_CONST_REFERENCE = 0 != member_traits<S>::has_member_const_reference };
00159 #else
00160 enum { HAS_MEMBER_REFERENCE = 0 != member_traits<S>::has_member_iterator };
00161 enum { HAS_MEMBER_CONST_REFERENCE = 0 != member_traits<S>::has_member_const_iterator };
00162 #endif
00163 enum { HAS_MEMBER_ITERATOR = 0 != member_traits<S>::has_member_iterator };
00164 enum { HAS_MEMBER_CONST_ITERATOR = 0 != member_traits<S>::has_member_const_iterator };
00165 enum { HAS_MEMBER_DIFFERENCE_TYPE = 0 != member_traits<S>::has_member_difference_type };
00166 enum { HAS_MEMBER_POINTER = 0 != member_traits<S>::has_member_pointer };
00167 enum { HAS_MEMBER_CONST_POINTER = 0 != member_traits<S>::has_member_const_pointer };
00168
00169 public:
00171 typedef S sequence_type;
00173 typedef S& sequence_reference_type;
00175 typedef ss_typename_type_k sequence_type::value_type value_type;
00177 typedef ss_typename_type_k select_first_type_if<ss_typename_type_k ::stlsoft::typefixer::fixer_iterator<S, HAS_MEMBER_ITERATOR>::iterator
00178 , ss_typename_type_k ::stlsoft::typefixer::fixer_const_iterator<S, HAS_MEMBER_CONST_ITERATOR>::const_iterator
00179 , HAS_MEMBER_ITERATOR
00180 >::type iterator;
00182 typedef ss_typename_type_k ::stlsoft::typefixer::fixer_const_iterator<S, HAS_MEMBER_CONST_ITERATOR>::const_iterator
00183 const_iterator;
00185 typedef ss_typename_type_k select_first_type_if<ss_typename_type_k ::stlsoft::typefixer::fixer_reference<sequence_type, HAS_MEMBER_REFERENCE>::reference
00186 , ss_typename_type_k ::stlsoft::typefixer::fixer_const_reference<sequence_type, HAS_MEMBER_CONST_REFERENCE>::const_reference
00187 , HAS_MEMBER_REFERENCE
00188 >::type reference;
00190 typedef ss_typename_type_k ::stlsoft::typefixer::fixer_const_reference<S, HAS_MEMBER_CONST_REFERENCE>::const_reference
00191 const_reference;
00193 typedef ss_typename_type_k select_first_type_if<ss_typename_type_k ::stlsoft::typefixer::fixer_pointer<sequence_type, HAS_MEMBER_POINTER>::pointer
00194 , ss_typename_type_k ::stlsoft::typefixer::fixer_const_pointer<sequence_type, HAS_MEMBER_CONST_POINTER>::const_pointer
00195 , HAS_MEMBER_POINTER
00196 >::type pointer;
00198 typedef ss_typename_type_k ::stlsoft::typefixer::fixer_const_pointer<S, HAS_MEMBER_CONST_POINTER>::const_pointer
00199 const_pointer;
00201 typedef ss_typename_type_k select_first_type_if<ss_typename_type_k ::stlsoft::typefixer::fixer_difference_type<S, HAS_MEMBER_DIFFERENCE_TYPE>::difference_type
00202 , ss_ptrdiff_t
00203 , HAS_MEMBER_DIFFERENCE_TYPE
00204 >::type difference_type;
00206 typedef ss_typename_type_k sequence_type::size_type size_type;
00207 };
00208
00213 template< ss_typename_param_k S
00214 >
00215 struct sequence_range_traits<S, true>
00216 {
00217 public:
00219 typedef S sequence_type;
00221 typedef S& sequence_reference_type;
00223 typedef ss_typename_type_k sequence_type::value_type value_type;
00225 typedef ss_typename_type_k sequence_type::const_iterator iterator;
00227 typedef ss_typename_type_k sequence_type::const_iterator const_iterator;
00229 typedef ss_typename_type_k sequence_type::const_reference reference;
00231 typedef ss_typename_type_k sequence_type::const_reference const_reference;
00232
00234 typedef ss_typename_type_k sequence_type::difference_type difference_type;
00236 typedef ss_typename_type_k sequence_type::size_type size_type;
00237 };
00238
00239 #else
00240
00241 template< ss_typename_param_k S
00242 >
00243 struct sequence_range_traits
00244 {
00245 public:
00246 typedef S sequence_type;
00247 typedef S& sequence_reference_type;
00248 typedef ss_typename_type_k sequence_type::value_type value_type;
00249 typedef ss_typename_type_k sequence_type::iterator iterator;
00250 typedef ss_typename_type_k sequence_type::const_iterator const_iterator;
00251 typedef ss_typename_type_k sequence_type::reference reference;
00252 typedef ss_typename_type_k sequence_type::const_reference const_reference;
00253 typedef ss_typename_type_k sequence_type::difference_type difference_type;
00254 typedef ss_typename_type_k sequence_type::size_type size_type;
00255 };
00256
00257 template< ss_typename_param_k S
00258 >
00259 struct const_sequence_range_traits
00260 {
00261 public:
00262 typedef S sequence_type;
00263 typedef S const& sequence_reference_type;
00264 typedef ss_typename_type_k sequence_type::value_type value_type;
00265 typedef ss_typename_type_k sequence_type::const_iterator iterator;
00266 typedef ss_typename_type_k sequence_type::const_iterator const_iterator;
00267 typedef ss_typename_type_k sequence_type::const_reference reference;
00268 typedef ss_typename_type_k sequence_type::const_reference const_reference;
00269 typedef ss_typename_type_k sequence_type::difference_type difference_type;
00270 typedef ss_typename_type_k sequence_type::size_type size_type;
00271 };
00272
00273 template< ss_typename_param_k S
00274 >
00275 struct non_const_sequence_range_traits
00276 {
00277 public:
00278 typedef S sequence_type;
00279 typedef S const& sequence_reference_type;
00280 typedef ss_typename_type_k sequence_type::value_type value_type;
00281 typedef ss_typename_type_k sequence_type::iterator iterator;
00282 typedef ss_typename_type_k sequence_type::iterator const_iterator;
00283 typedef ss_typename_type_k sequence_type::reference reference;
00284 typedef ss_typename_type_k sequence_type::reference const_reference;
00285 typedef ss_typename_type_k sequence_type::difference_type difference_type;
00286 typedef ss_typename_type_k sequence_type::size_type size_type;
00287 };
00288 #endif
00289
00310 template< ss_typename_param_k S
00311 #if defined(STLSOFT_CF_HAS_MEMBER_TYPE_SUPPORTED)
00312 , ss_typename_param_k T = sequence_range_traits<S, is_const_type<S>::value>
00313 #else
00314 , ss_typename_param_k T = const_sequence_range_traits<S>
00315 #endif
00316 >
00317 class sequence_range
00318 : public mutating_operator_adaptor<sequence_range<S, T>, T>
00319 , public iterable_range_tag
00320 {
00321 public:
00323 typedef S sequence_type;
00325 typedef T traits_type;
00327 typedef iterable_range_tag range_tag_type;
00329 typedef sequence_range<S, T> class_type;
00331 typedef ss_typename_type_k traits_type::sequence_reference_type sequence_reference_type;
00333 typedef ss_typename_type_k traits_type::value_type value_type;
00335 typedef ss_typename_type_k traits_type::iterator iterator;
00337 typedef ss_typename_type_k traits_type::const_iterator const_iterator;
00339 typedef ss_typename_type_k traits_type::reference reference;
00341 typedef ss_typename_type_k traits_type::const_reference const_reference;
00343 typedef ss_typename_type_k traits_type::difference_type difference_type;
00345 typedef ss_typename_type_k traits_type::size_type size_type;
00346
00347 public:
00348
00349 #if !defined(STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT) || \
00350 defined(STLSOFT_CF_MEMBER_TEMPLATE_CTOR_OVERLOAD_DISCRIMINATED) || \
00351 ( defined(STLSOFT_COMPILER_IS_MSVC) && \
00352 _MSC_VER == 1200)
00356 sequence_range(sequence_reference_type rhs) // The constness of this will require some thinking about. Maybe need sequence_range and const_sequence_range??
00357 : m_position(rhs.begin())
00358 , m_last(rhs.end())
00359 {}
00360 #endif
00361
00362 #if defined(STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT) && \
00363 ( !defined(STLSOFT_COMPILER_IS_MSVC) || \
00364 _MSC_VER != 1200)
00368 template <ss_typename_param_k S1>
00369 sequence_range(S1& rhs)
00370 : m_position(rhs.begin())
00371 , m_last(rhs.end())
00372 {}
00373 #endif
00374
00375 #ifdef STLSOFT_CF_STATIC_ARRAY_SIZE_DETERMINATION_SUPPORT
00377 template <ss_size_t N>
00378 sequence_range(S (&ar)[N])
00379 : m_position(&ar[0])
00380 , m_last(&ar[N])
00381 {}
00382 #endif
00383
00388 sequence_range(iterator position, iterator last)
00389 : m_position(position)
00390 , m_last(last)
00391 {}
00392
00396 sequence_range(class_type const& rhs)
00397 : m_position(rhs.m_position)
00398 , m_last(rhs.m_last)
00399 {}
00400
00404 class_type& operator =(class_type const& rhs)
00405 {
00406 m_position = rhs.m_position;
00407 m_last = rhs.m_last;
00408
00409 return *this;
00410 }
00411
00414 public:
00416 ss_bool_t is_open() const
00417 {
00418 return m_position != m_last;
00419 }
00421 reference current()
00422 {
00423 STLSOFT_ASSERT(is_open());
00424
00425 return *m_position;
00426 }
00428 const_reference current() const
00429 {
00430 STLSOFT_ASSERT(is_open());
00431
00432 return *m_position;
00433 }
00435 class_type& advance()
00436 {
00437 STLSOFT_MESSAGE_ASSERT("Attempting to increment the range past its end point", is_open());
00438
00439 ++m_position;
00440
00441 return *this;
00442 }
00444
00447 public:
00449 iterator begin()
00450 {
00451 return m_position;
00452 }
00454 iterator end()
00455 {
00456 return m_last;
00457 }
00458
00460 const_iterator begin() const
00461 {
00462 return m_position;
00463 }
00465 const_iterator end() const
00466 {
00467 return m_last;
00468 }
00470
00471
00472 private:
00473 iterator m_position;
00474 iterator m_last;
00475 };
00476
00478
00479
00480 template<ss_typename_param_k S>
00481 #ifdef STLSOFT_CF_TEMPLATE_PARTIAL_SPECIALISATION_SUPPORT
00482 inline sequence_range<S> make_sequence_range(S &s)
00483 #else
00484 inline sequence_range<S> make_sequence_range(S const& s)
00485 #endif
00486 {
00487 return sequence_range<S>(s);
00488 }
00489
00491
00492
00493 #ifdef STLSOFT_UNITTEST
00494 # include "./unittest/sequence_range_unittest_.h"
00495 #endif
00496
00497
00498
00499 #ifndef RANGELIB_NO_NAMESPACE
00500 # if defined(_STLSOFT_NO_NAMESPACE) || \
00501 defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
00502 }
00503 # else
00504 }
00505 }
00506 # endif
00507 #endif
00508
00509
00510
00511 #endif
00512
00513