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_ASSOCIATIVE_RANGE
00044 #define RANGELIB_INCL_RANGELIB_HPP_ASSOCIATIVE_RANGE
00045
00046 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00047 # define RANGELIB_VER_RANGELIB_HPP_ASSOCIATIVE_RANGE_MAJOR 1
00048 # define RANGELIB_VER_RANGELIB_HPP_ASSOCIATIVE_RANGE_MINOR 4
00049 # define RANGELIB_VER_RANGELIB_HPP_ASSOCIATIVE_RANGE_REVISION 6
00050 # define RANGELIB_VER_RANGELIB_HPP_ASSOCIATIVE_RANGE_EDIT 33
00051 #endif
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068 #ifndef RANGELIB_INCL_RANGELIB_HPP_RANGELIB
00069 # include <rangelib/rangelib.hpp>
00070 #endif
00071 #ifndef RANGELIB_INCL_RANGELIB_HPP_RANGE_CATEGORIES
00072 # include <rangelib/range_categories.hpp>
00073 #endif
00074 #ifndef STLSOFT_INCL_STLSOFT_UTIL_HPP_OPERATOR_BOOL
00075 # include <stlsoft/util/operator_bool.hpp>
00076 #endif
00077 #ifndef STLSOFT_INCL_STLSOFT_META_HPP_IS_CONST_TYPE
00078 # include <stlsoft/meta/is_const_type.hpp>
00079 #endif
00080 #ifndef STLSOFT_INCL_STLSOFT_UTIL_STD_HPP_ITERATOR_HELPER
00081 # include <stlsoft/util/std/iterator_helper.hpp>
00082 #endif
00083 #if defined(STLSOFT_CF_HAS_MEMBER_TYPE_SUPPORTED)
00084
00085 # ifndef STLSOFT_INCL_STLSOFT_META_HPP_MEMBER_TRAITS
00086 # include <stlsoft/meta/member_traits.hpp>
00087 # endif
00088 # ifndef STLSOFT_INCL_STLSOFT_COLLECTIONS_UTIL_HPP_ASSOCIATIVE_MAPPED_TYPE_DETECTOR
00089 # include <stlsoft/collections/util/associative_mapped_type_detector.hpp>
00090 # endif
00091 #else
00092 # if defined(STLSOFT_CF_STD_LIBRARY_IS_DINKUMWARE_VC)
00093 # if STLSOFT_CF_STD_LIBRARY_DINKUMWARE_VC_VERSION <= STLSOFT_CF_DINKUMWARE_VC_VERSION_6_0
00094 # pragma message("associative_range<> assumes that the adapted type has a 'mapped_type' member type. std::map in the Dinkumware library that ships with Visual C++ 5 & 6 uses the non-standard 'referent_type', so adapting a parameterisation of it will not compile")
00095 # endif
00096 # endif
00097 #endif
00098
00099 #ifdef STLSOFT_UNITTEST
00100 # include <algorithm>
00101 # include <map>
00102 # include <numeric>
00103 #endif
00104
00105
00106
00107
00108
00109 #ifndef RANGELIB_NO_NAMESPACE
00110 # if defined(_STLSOFT_NO_NAMESPACE) || \
00111 defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
00112
00113 namespace rangelib
00114 {
00115 # else
00116
00117
00118 namespace stlsoft
00119 {
00120
00121 namespace rangelib_project
00122 {
00123
00124 # endif
00125 #endif
00126
00127
00128
00129
00130
00131 #if defined(STLSOFT_CF_HAS_MEMBER_TYPE_SUPPORTED)
00132
00137 template< ss_typename_param_k S
00138 , bool B_CONST
00139 >
00140 struct associative_range_traits
00141 {
00142 public:
00144 typedef S associative_type;
00146 typedef S& associative_reference_type;
00148 typedef ss_typename_type_k associative_type::key_type key_type;
00150 typedef ss_typename_type_k associative_mapped_type_detector<S>::mapped_type mapped_type;
00152 typedef ss_typename_type_k associative_type::value_type value_type;
00154 typedef ss_typename_type_k select_first_type_if< ss_typename_type_k associative_type::const_iterator
00155 , ss_typename_type_k associative_type::iterator
00156 , B_CONST
00157 >::type iterator;
00159 typedef ss_typename_type_k associative_type::const_iterator const_iterator;
00161 typedef ss_typename_type_k select_first_type_if< ss_typename_type_k associative_type::const_reference
00162 , ss_typename_type_k associative_type::reference
00163 , B_CONST
00164 >::type reference;
00166 typedef ss_typename_type_k associative_type::const_reference const_reference;
00167
00169 typedef ss_typename_type_k associative_type::difference_type difference_type;
00171 typedef ss_typename_type_k associative_type::size_type size_type;
00172 };
00173
00174 template< ss_typename_param_k S
00175 >
00176 struct associative_range_traits<S, true>
00177 {
00178 public:
00179 typedef S associative_type;
00180 typedef S& associative_reference_type;
00181 typedef ss_typename_type_k associative_type::key_type key_type;
00182 typedef ss_typename_type_k associative_mapped_type_detector<S>::mapped_type mapped_type;
00183
00184 typedef ss_typename_type_k associative_type::value_type value_type;
00185 typedef ss_typename_type_k associative_type::const_iterator iterator;
00186 typedef ss_typename_type_k associative_type::const_iterator const_iterator;
00187 typedef ss_typename_type_k associative_type::const_reference reference;
00188 typedef ss_typename_type_k associative_type::const_reference const_reference;
00189
00190 typedef ss_typename_type_k associative_type::difference_type difference_type;
00191 typedef ss_typename_type_k associative_type::size_type size_type;
00192 };
00193
00194 #else
00195
00196 template< ss_typename_param_k S
00197 >
00198 struct associative_range_traits
00199 {
00200 public:
00201 typedef S associative_type;
00202 typedef S& associative_reference_type;
00203 typedef ss_typename_type_k associative_type::key_type key_type;
00204 typedef ss_typename_type_k associative_type::mapped_type mapped_type;
00205 typedef ss_typename_type_k associative_type::value_type value_type;
00206 typedef ss_typename_type_k associative_type::iterator iterator;
00207 typedef ss_typename_type_k associative_type::const_iterator const_iterator;
00208 typedef ss_typename_type_k associative_type::reference reference;
00209 typedef ss_typename_type_k associative_type::const_reference const_reference;
00210 typedef ss_typename_type_k associative_type::difference_type difference_type;
00211 typedef ss_typename_type_k associative_type::size_type size_type;
00212 };
00213
00214 template< ss_typename_param_k S
00215 >
00216 struct associative_range_traits_dinkumware_early
00217 {
00218 public:
00219 typedef S associative_type;
00220 typedef S& associative_reference_type;
00221 typedef ss_typename_type_k associative_type::key_type key_type;
00222 typedef ss_typename_type_k associative_type::referent_type mapped_type;
00223 typedef ss_typename_type_k associative_type::value_type value_type;
00224 typedef ss_typename_type_k associative_type::iterator iterator;
00225 typedef ss_typename_type_k associative_type::const_iterator const_iterator;
00226 typedef ss_typename_type_k associative_type::reference reference;
00227 typedef ss_typename_type_k associative_type::const_reference const_reference;
00228 typedef ss_typename_type_k associative_type::difference_type difference_type;
00229 typedef ss_typename_type_k associative_type::size_type size_type;
00230 };
00231
00232 template< ss_typename_param_k S
00233 >
00234 struct const_associative_range_traits
00235 {
00236 public:
00237 typedef S associative_type;
00238 typedef S const& associative_reference_type;
00239 typedef ss_typename_type_k associative_type::key_type key_type;
00240 typedef ss_typename_type_k associative_type::mapped_type mapped_type;
00241 typedef ss_typename_type_k associative_type::value_type value_type;
00242 typedef ss_typename_type_k associative_type::const_iterator iterator;
00243 typedef ss_typename_type_k associative_type::const_iterator const_iterator;
00244 typedef ss_typename_type_k associative_type::const_reference reference;
00245 typedef ss_typename_type_k associative_type::const_reference const_reference;
00246 typedef ss_typename_type_k associative_type::difference_type difference_type;
00247 typedef ss_typename_type_k associative_type::size_type size_type;
00248 };
00249
00250 template< ss_typename_param_k S
00251 >
00252 struct const_associative_range_traits_dinkumware_early
00253 {
00254 public:
00255 typedef S associative_type;
00256 typedef S const& associative_reference_type;
00257 typedef ss_typename_type_k associative_type::key_type key_type;
00258 typedef ss_typename_type_k associative_type::referent_type mapped_type;
00259 typedef ss_typename_type_k associative_type::value_type value_type;
00260 typedef ss_typename_type_k associative_type::const_iterator iterator;
00261 typedef ss_typename_type_k associative_type::const_iterator const_iterator;
00262 typedef ss_typename_type_k associative_type::const_reference reference;
00263 typedef ss_typename_type_k associative_type::const_reference const_reference;
00264 typedef ss_typename_type_k associative_type::difference_type difference_type;
00265 typedef ss_typename_type_k associative_type::size_type size_type;
00266 };
00267 #endif
00268
00289 template< ss_typename_param_k S
00290 #if defined(STLSOFT_CF_HAS_MEMBER_TYPE_SUPPORTED)
00291 , ss_typename_param_k T = associative_range_traits<S, is_const_type<S>::value>
00292 #else
00293 , ss_typename_param_k T = const_associative_range_traits<S>
00294 #endif
00295 >
00296 class associative_range
00297 : public iterable_range_tag
00298 {
00299 public:
00301 typedef S associative_type;
00303 typedef T traits_type;
00305 typedef iterable_range_tag range_tag_type;
00307 typedef associative_range<S, T> class_type;
00309 typedef ss_typename_type_k traits_type::associative_reference_type associative_reference_type;
00311 typedef ss_typename_type_k traits_type::key_type key_type;
00313 typedef ss_typename_type_k traits_type::mapped_type mapped_type;
00315 typedef ss_typename_type_k traits_type::value_type value_type;
00317 typedef ss_typename_type_k traits_type::iterator iterator;
00319 typedef ss_typename_type_k traits_type::const_iterator const_iterator;
00321 typedef ss_typename_type_k traits_type::reference reference;
00323 typedef ss_typename_type_k traits_type::const_reference const_reference;
00325 typedef ss_typename_type_k traits_type::difference_type difference_type;
00327 typedef ss_typename_type_k traits_type::size_type size_type;
00328
00329 public:
00330
00331 #if !defined(STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT) || \
00332 defined(STLSOFT_CF_MEMBER_TEMPLATE_CTOR_OVERLOAD_DISCRIMINATED) || \
00333 ( defined(STLSOFT_COMPILER_IS_MSVC) && \
00334 _MSC_VER == 1200)
00338 associative_range(associative_reference_type seq) // The constness of this will require some thinking about. Maybe need associative_range and const_associative_range??
00339 : m_position(seq.begin())
00340 , m_last(seq.end())
00341 {}
00342 #endif
00343
00344 #if defined(STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT) && \
00345 ( !defined(STLSOFT_COMPILER_IS_MSVC) || \
00346 _MSC_VER != 1200)
00350 template <ss_typename_param_k S2>
00351 associative_range(S2 &seq)
00352 : m_position(seq.begin())
00353 , m_last(seq.end())
00354 {}
00355 #endif
00356
00360 associative_range(class_type const& rhs)
00361 : m_position(rhs.m_position)
00362 , m_last(rhs.m_last)
00363 {}
00364
00368 class_type& operator =(class_type const& rhs)
00369 {
00370 m_position = rhs.m_position;
00371 m_last = rhs.m_last;
00372
00373 return *this;
00374 }
00375
00378 private:
00379 STLSOFT_DEFINE_OPERATOR_BOOL_TYPES_T(class_type, boolean_generator_type, boolean_type);
00380 public:
00382 ss_bool_t is_open() const
00383 {
00384 return m_position != m_last;
00385 }
00387 reference current()
00388 {
00389 STLSOFT_ASSERT(is_open());
00390
00391 return *m_position;
00392 }
00394 const_reference current() const
00395 {
00396 STLSOFT_ASSERT(is_open());
00397
00398 return *m_position;
00399 }
00401 key_type current_key()
00402 {
00403 return current().first;
00404 }
00406 key_type current_key() const
00407 {
00408 return current().first;
00409 }
00411 mapped_type current_value()
00412 {
00413 return current().second;
00414 }
00416 mapped_type current_value() const
00417 {
00418 return current().second;
00419 }
00421 class_type& advance()
00422 {
00423 STLSOFT_MESSAGE_ASSERT("Attempting to increment the range past its end point", is_open());
00424
00425 ++m_position;
00426
00427 return *this;
00428 }
00429
00431 operator boolean_type() const
00432 {
00433 return boolean_generator_type::translate(is_open());
00434 }
00436 reference operator *()
00437 {
00438 return current();
00439 }
00441 const_reference operator *() const
00442 {
00443 return current();
00444 }
00446 class_type& operator ++()
00447 {
00448 return advance();
00449 }
00452 class_type operator ++(int)
00453 {
00454 class_type ret(*this);
00455
00456 operator ++();
00457
00458 return ret;
00459 }
00461
00464 public:
00466 iterator begin()
00467 {
00468 return m_position;
00469 }
00471 iterator end()
00472 {
00473 return m_last;
00474 }
00475
00477 const_iterator begin() const
00478 {
00479 return m_position;
00480 }
00482 const_iterator end() const
00483 {
00484 return m_last;
00485 }
00487
00488
00489 private:
00490 iterator m_position;
00491 iterator m_last;
00492 };
00493
00495
00496
00497 #ifdef STLSOFT_UNITTEST
00498 # include "./unittest/associative_range_unittest_.h"
00499 #endif
00500
00501
00502
00503 #ifndef RANGELIB_NO_NAMESPACE
00504 # if defined(_STLSOFT_NO_NAMESPACE) || \
00505 defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
00506 }
00507 # else
00508 }
00509 }
00510 # endif
00511 #endif
00512
00513
00514
00515 #endif
00516
00517