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
00050 #ifndef STLSOFT_INCL_STLSOFT_COLLECTIONS_HPP_ARRAY_VIEW
00051 #define STLSOFT_INCL_STLSOFT_COLLECTIONS_HPP_ARRAY_VIEW
00052
00053 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00054 # define STLSOFT_VER_STLSOFT_COLLECTIONS_HPP_ARRAY_VIEW_MAJOR 4
00055 # define STLSOFT_VER_STLSOFT_COLLECTIONS_HPP_ARRAY_VIEW_MINOR 1
00056 # define STLSOFT_VER_STLSOFT_COLLECTIONS_HPP_ARRAY_VIEW_REVISION 1
00057 # define STLSOFT_VER_STLSOFT_COLLECTIONS_HPP_ARRAY_VIEW_EDIT 70
00058 #endif
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074 #ifndef STLSOFT_INCL_STLSOFT_H_STLSOFT
00075 # include <stlsoft/stlsoft.h>
00076 #endif
00077 #ifndef STLSOFT_INCL_STLSOFT_UTIL_STD_HPP_ITERATOR_HELPER
00078 # include <stlsoft/util/std/iterator_helper.hpp>
00079 #endif
00080 #ifndef STLSOFT_INCL_STLSOFT_COLLECTIONS_UTIL_HPP_COLLECTIONS
00081 # include <stlsoft/collections/util/collections.hpp>
00082 #endif
00083 #ifndef STLSOFT_INCL_STLSOFT_UTIL_HPP_STD_SWAP
00084 # include <stlsoft/util/std_swap.hpp>
00085 #endif
00086 #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
00087 # include <stdexcept>
00088 #endif
00089
00090
00091
00092
00093
00094 #ifndef _STLSOFT_NO_NAMESPACE
00095 namespace stlsoft
00096 {
00097 #endif
00098
00099
00100
00101
00102
00109 template <ss_typename_param_k T>
00110 class array_view
00111 : public stl_collection_tag
00112 {
00115 public:
00116 typedef T value_type;
00117 typedef array_view<T> class_type;
00118 typedef value_type* pointer;
00119 typedef value_type const* const_pointer;
00120 typedef value_type& reference;
00121 typedef value_type const& const_reference;
00122 typedef ss_size_t size_type;
00123 typedef ss_ptrdiff_t difference_type;
00124 #if !defined(STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT)
00126 typedef value_type* iterator;
00128 typedef value_type const* const_iterator;
00129 #else
00131 typedef
00132 # if !defined(STLSOFT_COMPILER_IS_BORLAND)
00133 ss_typename_type_k
00134 # endif
00135 pointer_iterator < value_type
00136 , pointer
00137 , reference
00138 >::type iterator;
00140 typedef
00141 # if !defined(STLSOFT_COMPILER_IS_BORLAND)
00142 ss_typename_type_k
00143 # endif
00144 pointer_iterator < value_type const
00145 , const_pointer
00146 , const_reference
00147 >::type const_iterator;
00148
00150 typedef reverse_iterator_base < iterator
00151 , value_type
00152 , reference
00153 , pointer
00154 , difference_type
00155 > reverse_iterator;
00156
00158 typedef const_reverse_iterator_base < const_iterator
00159 , value_type const
00160 , const_reference
00161 , const_pointer
00162 , difference_type
00163 > const_reverse_iterator;
00164 #endif
00166
00169 public:
00173 array_view()
00174 : m_size(0)
00175 , m_base(NULL)
00176 {
00177 STLSOFT_ASSERT(is_valid());
00178 }
00179
00180 #ifdef STLSOFT_CF_STATIC_ARRAY_SIZE_DETERMINATION_SUPPORT
00184 template <size_type N>
00185 ss_explicit_k array_view(T (&t)[N])
00186 : m_size(N)
00187 , m_base(&t[0])
00188 {
00189 STLSOFT_ASSERT(is_valid());
00190 }
00191 #endif
00192
00197 array_view(pointer begin, pointer end)
00198 : m_size(stlsoft_ns_qual_std(distance)(begin, end))
00199 , m_base(begin)
00200 {
00201 STLSOFT_ASSERT(is_valid());
00202 }
00203
00208 array_view(pointer p, size_type n)
00209 : m_size(n)
00210 , m_base(p)
00211 {
00212 STLSOFT_ASSERT(is_valid());
00213 }
00214
00216 void swap(class_type& rhs) stlsoft_throw_0()
00217 {
00218 STLSOFT_ASSERT(is_valid());
00219
00220 std_swap(m_size, rhs.m_size);
00221 std_swap(m_base, rhs.m_base);
00222
00223 STLSOFT_ASSERT(is_valid());
00224 }
00225
00228 public:
00231 pointer base()
00232 {
00233 STLSOFT_ASSERT(is_valid());
00234
00235 return m_base;
00236 }
00239 pointer base() const
00240 {
00241 STLSOFT_ASSERT(is_valid());
00242
00243 return m_base;
00244 }
00246 size_type size() const
00247 {
00248 STLSOFT_ASSERT(is_valid());
00249
00250 return m_size;
00251 }
00253 ss_bool_t empty() const
00254 {
00255 STLSOFT_ASSERT(is_valid());
00256
00257 return 0 == m_size;
00258 }
00260 static size_type max_size()
00261 {
00262 return static_cast<size_type>(-1) / sizeof(value_type);
00263 }
00265
00268 public:
00273 reference operator [](size_type index)
00274 {
00275 STLSOFT_MESSAGE_ASSERT("index out of bounds, in array_view", !(size() < index));
00276
00277 STLSOFT_ASSERT(is_valid());
00278
00279 return m_base[index];
00280 }
00285 const_reference operator [](size_type index) const
00286 {
00287 STLSOFT_MESSAGE_ASSERT("index out of bounds, in array_view", !(size() < index));
00288
00289 STLSOFT_ASSERT(is_valid());
00290
00291 return const_cast<pointer>(m_base)[index];
00292 }
00293
00294 # ifdef STLSOFT_CF_EXCEPTION_SUPPORT
00300 reference at(size_type index)
00301 {
00302 STLSOFT_ASSERT(is_valid());
00303
00304 range_check_(index);
00305
00306 return m_base[index];
00307 }
00313 const_reference at(size_type index) const
00314 {
00315 STLSOFT_ASSERT(is_valid());
00316
00317 range_check_(index);
00318
00319 return const_cast<pointer>(m_base)[index];
00320 }
00321 #endif
00323
00326 public:
00330 iterator begin()
00331 {
00332 STLSOFT_ASSERT(is_valid());
00333
00334 return m_base;
00335 }
00339 iterator end()
00340 {
00341 STLSOFT_ASSERT(is_valid());
00342
00343 return begin() + size();
00344 }
00348 const_iterator begin() const
00349 {
00350 STLSOFT_ASSERT(is_valid());
00351
00352 return m_base;
00353 }
00357 const_iterator end() const
00358 {
00359 STLSOFT_ASSERT(is_valid());
00360
00361 return begin() + size();
00362 }
00363
00364 #if defined(STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT)
00368 const_reverse_iterator rbegin() const
00369 {
00370 return const_reverse_iterator(end());
00371 }
00375 const_reverse_iterator rend() const
00376 {
00377 return const_reverse_iterator(begin());
00378 }
00382 reverse_iterator rbegin()
00383 {
00384 return reverse_iterator(end());
00385 }
00389 reverse_iterator rend()
00390 {
00391 return reverse_iterator(begin());
00392 }
00393 #endif
00395
00398 #ifdef STLSOFT_UNITTEST
00399 public:
00400 #else
00401 private:
00402 #endif
00403 ss_bool_t is_valid() const
00404 {
00405 if( 0 != m_size &&
00406 NULL == m_base)
00407 {
00408 #ifdef STLSOFT_UNITTEST
00409 fprintf(err, "Cannot have non-empty array view with NULL base pointer\n");
00410 #endif
00411
00412 return false;
00413 }
00414
00415 return true;
00416 }
00418
00421 private:
00422 # ifdef STLSOFT_CF_EXCEPTION_SUPPORT
00423 void range_check_(size_type index) const
00424 {
00425 if(!(index < size()))
00426 {
00427 STLSOFT_THROW_X(stlsoft_ns_qual_std(out_of_range)("array view index out of range"));
00428 }
00429 }
00430 #endif
00432
00435 private:
00436 size_type m_size;
00437 pointer m_base;
00439 };
00440
00441
00442
00443
00444
00445 #ifdef STLSOFT_CF_STATIC_ARRAY_SIZE_DETERMINATION_SUPPORT
00446 template <ss_typename_param_k T, ss_size_t N>
00447 inline array_view<T> make_array_view(T (&t)[N])
00448 {
00449 return array_view<T>(&t[0], &t[N]);
00450
00451 }
00452 #endif
00453
00454 template <ss_typename_param_k T>
00455 inline array_view<T> make_array_view(T *begin, T *end)
00456 {
00457 return array_view<T>(begin, end);
00458 }
00459
00460 template <ss_typename_param_k T>
00461 inline array_view<const T> make_array_view(T const* begin, T const* end)
00462 {
00463 return array_view<const T>(begin, end);
00464 }
00465
00466 template <ss_typename_param_k T>
00467 inline array_view<T> make_array_view(T *p, ss_size_t n)
00468 {
00469 return array_view<T>(p, n);
00470 }
00471
00472 #if 0
00473 template <ss_typename_param_k T>
00474 inline array_view<const T> make_array_view(T const* p, ss_size_t n)
00475 {
00476 return array_view<const T>(p, n);
00477 }
00478 #endif
00479
00481
00482
00483 #ifdef STLSOFT_UNITTEST
00484 # include "./unittest/array_view_unittest_.h"
00485 #endif
00486
00487
00488
00489 #ifndef _STLSOFT_NO_NAMESPACE
00490 }
00491 #endif
00492
00493
00494
00495 #endif
00496
00497