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
00048 #ifndef COMSTL_INCL_COMSTL_COLLECTIONS_HPP_SAFEARRAY_SEQUENCE
00049 #define COMSTL_INCL_COMSTL_COLLECTIONS_HPP_SAFEARRAY_SEQUENCE
00050
00051 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00052 # define COMSTL_VER_COMSTL_COLLECTIONS_HPP_SAFEARRAY_SEQUENCE_MAJOR 4
00053 # define COMSTL_VER_COMSTL_COLLECTIONS_HPP_SAFEARRAY_SEQUENCE_MINOR 2
00054 # define COMSTL_VER_COMSTL_COLLECTIONS_HPP_SAFEARRAY_SEQUENCE_REVISION 1
00055 # define COMSTL_VER_COMSTL_COLLECTIONS_HPP_SAFEARRAY_SEQUENCE_EDIT 61
00056 #endif
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072 #ifndef COMSTL_INCL_COMSTL_H_COMSTL
00073 # include <comstl/comstl.h>
00074 #endif
00075
00076 #if defined(STLSOFT_COMPILER_IS_MSVC) && \
00077 _MSC_VER < 1200
00078 # error comstl/collections/safearray_sequence.hpp is not compatible with Visual C++ 5.0 or earlier
00079 #endif
00080
00081 #ifndef COMSTL_INCL_COMSTL_ERROR_HPP_EXCEPTIONS
00082 # include <comstl/error/exceptions.hpp>
00083 #endif
00084 #ifndef STLSOFT_INCL_STLSOFT_UTIL_STD_HPP_ITERATOR_HELPER
00085 # include <stlsoft/util/std/iterator_helper.hpp>
00086 #endif
00087 #ifndef STLSOFT_INCL_STLSOFT_COLLECTIONS_UTIL_HPP_COLLECTIONS
00088 # include <stlsoft/collections/util/collections.hpp>
00089 #endif
00090
00091 #ifdef STLSOFT_UNITTEST
00092 # include <algorithm>
00093 #endif
00094
00095
00096
00097
00098
00099 #ifndef _COMSTL_NO_NAMESPACE
00100 # if defined(_STLSOFT_NO_NAMESPACE) || \
00101 defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
00102
00103 namespace comstl
00104 {
00105 # else
00106
00107
00108 namespace stlsoft
00109 {
00110
00111 namespace comstl_project
00112 {
00113
00114 # endif
00115 #endif
00116
00117
00118
00119
00120
00125 template <ss_typename_param_k T>
00126 class safearray_sequence
00127 : public stlsoft_ns_qual(stl_collection_tag)
00128 {
00131 private:
00132 typedef SAFEARRAY const* LPCSAFEARRAY;
00133 public:
00135 typedef T value_type;
00137 typedef safearray_sequence<T> class_type;
00139 typedef cs_size_t size_type;
00141 typedef cs_ptrdiff_t difference_type;
00143 typedef value_type& reference;
00145 typedef value_type const& const_reference;
00147 typedef value_type* pointer;
00149 typedef value_type const* const_pointer;
00151 typedef
00152 #if !defined(STLSOFT_COMPILER_IS_BORLAND)
00153 ss_typename_type_k
00154 #endif
00155 pointer_iterator<value_type
00156 , pointer
00157 , reference
00158 >::type iterator;
00160 typedef
00161 #if !defined(STLSOFT_COMPILER_IS_BORLAND)
00162 ss_typename_type_k
00163 #endif
00164 pointer_iterator<value_type const
00165 , const_pointer
00166 , const_reference
00167 >::type const_iterator;
00168
00170 #if defined(STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT)
00171 typedef stlsoft_ns_qual(reverse_iterator_base)< iterator
00172 , value_type
00173 , reference
00174 , pointer
00175 , difference_type
00176 > reverse_iterator;
00177
00178 typedef stlsoft_ns_qual(const_reverse_iterator_base)< const_iterator
00179 , value_type const
00180 , const_reference
00181 , const_pointer
00182 , difference_type
00183 > const_reverse_iterator;
00184 #endif
00186
00189 public:
00190 ss_explicit_k safearray_sequence(LPCSAFEARRAY array);
00192
00195 public:
00199 const_iterator begin() const;
00203 const_iterator end() const;
00204 #if defined(STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT)
00208 const_reverse_iterator rbegin() const;
00212 const_reverse_iterator rend() const;
00213 #endif
00214
00218 iterator begin();
00222 iterator end();
00223 #if defined(STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT)
00227 reverse_iterator rbegin();
00231 reverse_iterator rend();
00232 #endif
00234
00237 public:
00239 size_type size() const;
00241 bool empty() const;
00243
00246 public:
00247
00248
00250
00253 private:
00254 static bool type_is_compatible_(LPCSAFEARRAY array);
00255 static DWORD calc_size_(LPCSAFEARRAY array);
00257
00260 private:
00261 LPCSAFEARRAY m_sa;
00262 DWORD const m_cItems;
00264
00267 private:
00268 class_type& operator =(class_type const&);
00270 };
00271
00273
00274
00275 #ifdef STLSOFT_UNITTEST
00276 # include "./unittest/safearray_sequence_unittest_.h"
00277 #endif
00278
00280
00281
00282 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00283
00284 template <ss_typename_param_k T>
00285 inline bool safearray_sequence<T>::type_is_compatible_(LPCSAFEARRAY array)
00286 {
00287 return sizeof(value_type) == array->cbElements;
00288 }
00289
00290 template <ss_typename_param_k T>
00291 inline DWORD safearray_sequence<T>::calc_size_(LPCSAFEARRAY array)
00292 {
00293 DWORD cItems = 1;
00294
00295 for(USHORT dim = 0; dim < array->cDims; ++dim)
00296 {
00297 cItems *= array->rgsabound[dim].cElements;
00298 }
00299
00300 return cItems;
00301 }
00302
00303 template <ss_typename_param_k T>
00304 inline safearray_sequence<T>::safearray_sequence(LPCSAFEARRAY array)
00305 : m_sa(array)
00306 , m_cItems(calc_size_(array))
00307 {
00308 if(!type_is_compatible_(array))
00309 {
00310 STLSOFT_THROW_X(variant_type_exception("initialising safearray_sequence from safe array to incompatible type", DISP_E_BADVARTYPE));
00311 }
00312 }
00313
00314 template <ss_typename_param_k T>
00315 inline ss_typename_type_ret_k safearray_sequence<T>::const_iterator safearray_sequence<T>::begin() const
00316 {
00317 return static_cast<pointer>(m_sa->pvData);
00318 }
00319
00320 template <ss_typename_param_k T>
00321 inline ss_typename_type_ret_k safearray_sequence<T>::const_iterator safearray_sequence<T>::end() const
00322 {
00323 return static_cast<pointer>(m_sa->pvData) + size();
00324 }
00325
00326 #if defined(STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT)
00327 template <ss_typename_param_k T>
00328 inline ss_typename_type_ret_k safearray_sequence<T>::const_reverse_iterator safearray_sequence<T>::rbegin() const
00329 {
00330 return const_reverse_iterator(end());
00331 }
00332
00333 template <ss_typename_param_k T>
00334 inline ss_typename_type_ret_k safearray_sequence<T>::const_reverse_iterator safearray_sequence<T>::rend() const
00335 {
00336 return const_reverse_iterator(begin());
00337 }
00338 #endif
00339
00340 template <ss_typename_param_k T>
00341 inline ss_typename_type_ret_k safearray_sequence<T>::iterator safearray_sequence<T>::begin()
00342 {
00343 return static_cast<pointer>(m_sa->pvData);
00344 }
00345
00346 template <ss_typename_param_k T>
00347 inline ss_typename_type_ret_k safearray_sequence<T>::iterator safearray_sequence<T>::end()
00348 {
00349 return static_cast<pointer>(m_sa->pvData) + size();
00350 }
00351
00352 #if defined(STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT)
00353 template <ss_typename_param_k T>
00354 inline ss_typename_type_ret_k safearray_sequence<T>::reverse_iterator safearray_sequence<T>::rbegin()
00355 {
00356 return reverse_iterator(end());
00357 }
00358
00359 template <ss_typename_param_k T>
00360 inline ss_typename_type_ret_k safearray_sequence<T>::reverse_iterator safearray_sequence<T>::rend()
00361 {
00362 return reverse_iterator(begin());
00363 }
00364 #endif
00365
00366 template <ss_typename_param_k T>
00367 inline ss_typename_type_ret_k safearray_sequence<T>::size_type safearray_sequence<T>::size() const
00368 {
00369 return m_cItems;
00370 }
00371
00372 template <ss_typename_param_k T>
00373 inline bool safearray_sequence<T>::empty() const
00374 {
00375 return 0 != size();
00376 }
00377
00378 #endif
00379
00380
00381
00382 #ifndef _COMSTL_NO_NAMESPACE
00383 # if defined(_STLSOFT_NO_NAMESPACE) || \
00384 defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
00385 }
00386 # else
00387 }
00388 }
00389 # endif
00390 #endif
00391
00392
00393
00394 #endif
00395
00396