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
00044
00052 #ifndef COMSTL_INCL_COMSTL_COLLECTIONS_HPP_COLLECTION_SEQUENCE
00053 #define COMSTL_INCL_COMSTL_COLLECTIONS_HPP_COLLECTION_SEQUENCE
00054
00055 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00056 # define COMSTL_VER_COMSTL_COLLECTIONS_HPP_COLLECTION_SEQUENCE_MAJOR 6
00057 # define COMSTL_VER_COMSTL_COLLECTIONS_HPP_COLLECTION_SEQUENCE_MINOR 1
00058 # define COMSTL_VER_COMSTL_COLLECTIONS_HPP_COLLECTION_SEQUENCE_REVISION 10
00059 # define COMSTL_VER_COMSTL_COLLECTIONS_HPP_COLLECTION_SEQUENCE_EDIT 103
00060 #endif
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076 #ifndef COMSTL_INCL_COMSTL_H_COMSTL
00077 # include <comstl/comstl.h>
00078 #endif
00079 #ifndef COMSTL_INCL_COMSTL_UTIL_H_REFCOUNT_FUNCTIONS
00080 # include <comstl/util/refcount_functions.h>
00081 #endif
00082 #ifndef COMSTL_INCL_COMSTL_COLLECTIONS_HPP_ENUMERATION_POLICIES
00083 # include <comstl/collections/enumeration_policies.hpp>
00084 #endif
00085 #ifndef COMSTL_INCL_COMSTL_UTIL_HPP_INTERFACE_TRAITS
00086 # include <comstl/util/interface_traits.hpp>
00087 #endif
00088 #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
00089 # ifndef COMSTL_INCL_COMSTL_ERROR_HPP_EXCEPTIONS
00090 # include <comstl/error/exceptions.hpp>
00091 # endif
00092 #endif
00093 #ifndef COMSTL_INCL_COMSTL_COLLECTIONS_HPP_ENUMERATOR_SEQUENCE
00094 # include <comstl/collections/enumerator_sequence.hpp>
00095 #endif
00096 #ifndef STLSOFT_INCL_STLSOFT_UTIL_STD_HPP_ITERATOR_HELPER
00097 # include <stlsoft/util/std/iterator_helper.hpp>
00098 #endif
00099 #ifndef STLSOFT_INCL_STLSOFT_COLLECTIONS_UTIL_HPP_COLLECTIONS
00100 # include <stlsoft/collections/util/collections.hpp>
00101 #endif
00102
00103 #ifndef STLSOFT_INCL_ALGORITHM
00104 # define STLSOFT_INCL_ALGORITHM
00105 # include <algorithm>
00106 #endif
00107
00108 #ifdef STLSOFT_UNITTEST
00109 # include <comstl/util/value_policies.hpp>
00110 # if !defined(STLSOFT_COMPILER_IS_DMC)
00111 # include "./unittest/_recls_COM_decl_.h"
00112 # endif
00113 # include <stdio.h>
00114 #endif
00115
00116
00117
00118
00119
00120 #ifndef _COMSTL_NO_NAMESPACE
00121 # if defined(_STLSOFT_NO_NAMESPACE) || \
00122 defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
00123
00124 namespace comstl
00125 {
00126 # else
00127
00128
00129 namespace stlsoft
00130 {
00131
00132 namespace comstl_project
00133 {
00134
00135 # endif
00136 #endif
00137
00138
00139
00140
00141
00205
00206 template< ss_typename_param_k CI
00207 , ss_typename_param_k EI
00208 , ss_typename_param_k V
00209 , ss_typename_param_k VP
00210 , ss_typename_param_k R = V const&
00211 , ss_typename_param_k CP = input_cloning_policy<EI>
00212 , cs_size_t Q = 8
00213 , ss_typename_param_k EAP = new_enum_property_policy<CI>
00214 >
00215 class collection_sequence
00216 : public stlsoft_ns_qual(stl_collection_tag)
00217 {
00220 private:
00221 typedef enumerator_sequence<EI, V, VP, R, CP, Q> enumerator_sequence_type;
00222 public:
00224 typedef CI collection_interface_type;
00226 typedef ss_typename_type_k enumerator_sequence_type::interface_type enumerator_interface_type;
00228 typedef ss_typename_type_k enumerator_sequence_type::value_type value_type;
00230 typedef ss_typename_type_k enumerator_sequence_type::value_policy_type value_policy_type;
00232 typedef ss_typename_type_k enumerator_sequence_type::reference reference;
00233 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00234 typedef ss_typename_type_k enumerator_sequence_type::reference_type reference_type;
00235 #endif
00237 typedef ss_typename_type_k enumerator_sequence_type::pointer pointer;
00239 typedef ss_typename_type_k enumerator_sequence_type::const_pointer const_pointer;
00241 typedef ss_typename_type_k enumerator_sequence_type::iterator iterator;
00243 typedef ss_typename_type_k enumerator_sequence_type::const_iterator const_iterator;
00245 typedef ss_typename_type_k enumerator_sequence_type::cloning_policy_type cloning_policy_type;
00247 typedef ss_typename_type_k enumerator_sequence_type::iterator_tag_type iterator_tag_type;
00248 #ifdef STLSOFT_COMPILER_IS_BORLAND
00249 # define retrievalQuanta Q
00250 #else
00252 enum { retrievalQuanta = enumerator_sequence_type::retrievalQuanta };
00253 #endif
00255 typedef EAP enumerator_acquisition_policy_type;
00257 typedef collection_sequence<CI, EI, V, VP, R, CP, Q, EAP> class_type;
00259 typedef ss_typename_type_k enumerator_sequence_type::size_type size_type;
00261 typedef ss_typename_type_k enumerator_sequence_type::difference_type difference_type;
00263
00264 public:
00278 collection_sequence(collection_interface_type *i, cs_bool_t bAddRef, size_type quanta = 0)
00279 : m_i(i)
00280 , m_quanta(validate_quanta_(quanta))
00281 {
00282 COMSTL_ASSERT(NULL != i);
00283 COMSTL_MESSAGE_ASSERT("Cannot set a quantum that exceeds the value specified in the template specialisation", quanta <= retrievalQuanta);
00284
00285 if(bAddRef)
00286 {
00287 m_i->AddRef();
00288 }
00289
00290 COMSTL_ASSERT(is_valid());
00291 }
00293 ~collection_sequence() stlsoft_throw_0()
00294 {
00295 COMSTL_ASSERT(is_valid());
00296
00297 m_i->Release();
00298 }
00299
00302 public:
00306 iterator begin() const
00307 {
00308 COMSTL_ASSERT(is_valid());
00309
00310 LPUNKNOWN punkEnum;
00311 HRESULT hr = enumerator_acquisition_policy_type::acquire(m_i, &punkEnum);
00312
00313 if(SUCCEEDED(hr))
00314 {
00315 enumerator_interface_type *ei;
00316
00317 hr = punkEnum->QueryInterface(IID_traits<enumerator_interface_type>::iid(), reinterpret_cast<void**>(&ei));
00318
00319 punkEnum->Release();
00320
00321 if(SUCCEEDED(hr))
00322 {
00323 COMSTL_ASSERT(is_valid());
00324
00325 return enumerator_sequence_type(ei, false, m_quanta).begin();
00326 }
00327 else
00328 {
00329 #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
00330 COMSTL_ASSERT(is_valid());
00331
00332 STLSOFT_THROW_X(com_exception("the enumerator does not provide the requested interface", hr));
00333 #endif
00334 }
00335 }
00336 else
00337 {
00338 #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
00339 COMSTL_ASSERT(is_valid());
00340
00341 STLSOFT_THROW_X(com_exception("enumerator could not be elicited from the collection", hr));
00342 #endif
00343 }
00344
00345 COMSTL_ASSERT(is_valid());
00346
00347 return iterator();
00348 }
00352 iterator end() const
00353 {
00354 COMSTL_ASSERT(is_valid());
00355
00356 return iterator();
00357 }
00359
00362 public:
00375 size_type size() const
00376 {
00377 COMSTL_ASSERT(is_valid());
00378
00379 ULONG count;
00380 HRESULT hr = m_i->get_Count(&count);
00381
00382 COMSTL_ASSERT(is_valid());
00383
00384 return SUCCEEDED(hr) ? count : 0;
00385 }
00387
00390 private:
00391 cs_bool_t is_valid() const
00392 {
00393 if(NULL == m_i)
00394 {
00395 return false;
00396 }
00397
00398 return true;
00399 }
00401
00402
00403 private:
00404 static size_type validate_quanta_(size_type quanta)
00405 {
00406 COMSTL_MESSAGE_ASSERT("Cannot set a quantum that exceeds the value specified in the template specialisation", quanta <= retrievalQuanta);
00407
00408 if( 0 == quanta ||
00409 quanta > retrievalQuanta)
00410 {
00411 quanta = retrievalQuanta;
00412 }
00413
00414 return quanta;
00415 }
00416
00417
00418 private:
00419 collection_interface_type *m_i;
00420 size_type const m_quanta;
00421
00422
00423 private:
00424 collection_sequence(class_type const&);
00425 class_type const& operator =(class_type const&);
00426 };
00427
00429
00430
00431 #ifdef STLSOFT_COMPILER_IS_BORLAND
00432 # undef retrievalQuanta
00433 #endif
00434
00436
00437
00438 #ifdef STLSOFT_UNITTEST
00439 # include "./unittest/collection_sequence_unittest_.h"
00440 #endif
00441
00442
00443
00444 #ifndef _COMSTL_NO_NAMESPACE
00445 # if defined(_STLSOFT_NO_NAMESPACE) || \
00446 defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
00447 }
00448 # else
00449 }
00450 }
00451 # endif
00452 #endif
00453
00454
00455
00456 #endif
00457
00458