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
00045
00053 #ifndef MFCSTL_INCL_MFCSTL_COLLECTIONS_HPP_CARRAY_ADAPTORS
00054 #define MFCSTL_INCL_MFCSTL_COLLECTIONS_HPP_CARRAY_ADAPTORS
00055
00056 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00057 # define MFCSTL_VER_MFCSTL_COLLECTIONS_HPP_CARRAY_ADAPTORS_MAJOR 4
00058 # define MFCSTL_VER_MFCSTL_COLLECTIONS_HPP_CARRAY_ADAPTORS_MINOR 2
00059 # define MFCSTL_VER_MFCSTL_COLLECTIONS_HPP_CARRAY_ADAPTORS_REVISION 1
00060 # define MFCSTL_VER_MFCSTL_COLLECTIONS_HPP_CARRAY_ADAPTORS_EDIT 82
00061 #endif
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077 #ifndef MFCSTL_INCL_MFCSTL_HPP_MFCSTL
00078 # include <mfcstl/mfcstl.hpp>
00079 #endif
00080 #ifndef MFCSTL_INCL_MFCSTL_MEMORY_HPP_AFX_ALLOCATOR
00081 # include <mfcstl/memory/afx_allocator.hpp>
00082 #endif
00083 #ifndef MFCSTL_INCL_MFCSTL_COLLECTIONS_HPP_CARRAY_SWAP
00084 # include <mfcstl/collections/carray_swap.hpp>
00085 #endif
00086 #ifndef MFCSTL_INCL_MFCSTL_COLLECTIONS_HPP_CARRAY_TRAITS
00087 # include <mfcstl/collections/carray_traits.hpp>
00088 #endif
00089 #ifndef MFCSTL_INCL_MFCSTL_UTIL_HPP_MEMORY_EXCEPTION_TRANSLATION_POLICIES
00090 # include <mfcstl/util/memory_exception_translation_policies.hpp>
00091 #endif
00092 #ifndef STLSOFT_INCL_STLSOFT_UTIL_STD_HPP_ITERATOR_GENERATORS
00093 # include <stlsoft/util/std/iterator_generators.hpp>
00094 #endif
00095 #ifndef STLSOFT_INCL_STLSOFT_META_HPP_CAPABILITIES
00096 # include <stlsoft/meta/capabilities.hpp>
00097 #endif
00098 #ifdef STLSOFT_META_HAS_IS_SAME_TYPE
00099 # ifndef STLSOFT_INCL_STLSOFT_META_HPP_IS_SAME_TYPE
00100 # include <stlsoft/meta/is_same_type.hpp>
00101 # endif
00102 #endif
00103 #ifndef STLSOFT_INCL_STLSOFT_COLLECTIONS_UTIL_HPP_COLLECTIONS
00104 # include <stlsoft/collections/util/collections.hpp>
00105 #endif
00106 #ifndef STLSOFT_INCL_STLSOFT_UTIL_STD_HPP_ITERATOR_HELPER
00107 # include <stlsoft/util/std/iterator_helper.hpp>
00108 #endif
00109
00110 #if defined(STLSOFT_CF_TEMPLATE_PARTIAL_SPECIALISATION_SUPPORT) && \
00111 !defined(MFCSTL_NO_INCLUDE_AFXTEMPL_BY_DEFAULT)
00112 # include <afxtempl.h>
00113 #endif
00114
00115 #ifndef STLSOFT_INCL_ALGORITHM
00116 # define STLSOFT_INCL_ALGORITHM
00117 # include <algorithm>
00118 #endif
00119
00120 #ifdef STLSOFT_UNITTEST
00121 # include <afxtempl.h>
00122 # include <stlsoft/string/simple_string.hpp>
00123 #endif
00124
00125
00126
00127
00128
00129 #ifndef _MFCSTL_NO_NAMESPACE
00130 # if defined(_STLSOFT_NO_NAMESPACE) || \
00131 defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
00132
00133 namespace mfcstl
00134 {
00135 # else
00136
00137
00138 namespace stlsoft
00139 {
00140
00141 namespace mfcstl_project
00142 {
00143
00144 # endif
00145 #endif
00146
00147
00148
00149
00150
00151 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00152
00153 template< ss_typename_param_k A
00154 , ss_typename_param_k I
00155 , ss_typename_param_k T
00156 >
00157 class CArray_adaptor_base;
00158
00159 template< ss_typename_param_k A
00160 , ss_typename_param_k T
00161 >
00162 class CArray_cadaptor;
00163
00164 template< ss_typename_param_k A
00165 , ss_typename_param_k T
00166 >
00167 class CArray_iadaptor;
00168
00169 #endif
00170
00184 template< ss_typename_param_k A
00185 , ss_typename_param_k I
00186 , ss_typename_param_k T
00187 >
00188 class CArray_adaptor_base
00189 : public stlsoft_ns_qual(stl_collection_tag)
00190 {
00193 public:
00195 typedef A array_type;
00196 private:
00197 typedef I interface_class_type;
00198 typedef T array_traits_type;
00199 #if defined(MFCSTL_CARRAY_ADAPTORS_USE_BAD_ALLOC_POLICY)
00200 typedef bad_alloc_throwing_policy exception_translation_policy_type;
00201 #else
00202 typedef CMemoryException_throwing_policy exception_translation_policy_type;
00203 #endif
00204 public:
00209 typedef ss_typename_type_k array_traits_type::value_type value_type;
00211 typedef afx_allocator<value_type> allocator_type;
00213 typedef ss_typename_type_k allocator_type::reference reference;
00215 typedef ss_typename_type_k allocator_type::const_reference const_reference;
00217 typedef ss_typename_type_k allocator_type::pointer pointer;
00219 typedef ss_typename_type_k allocator_type::const_pointer const_pointer;
00221 typedef
00222 # if !defined(STLSOFT_COMPILER_IS_BORLAND)
00223 ss_typename_type_k
00224 # endif
00225 pointer_iterator < value_type
00226 , pointer
00227 , reference
00228 >::type iterator;
00230 typedef
00231 # if !defined(STLSOFT_COMPILER_IS_BORLAND)
00232 ss_typename_type_k
00233 # endif
00234 pointer_iterator < value_type const
00235 , const_pointer
00236 , const_reference
00237 >::type const_iterator;
00239 typedef ms_size_t size_type;
00241 typedef ms_ptrdiff_t difference_type;
00243 typedef CArray_adaptor_base<A, I, T> class_type;
00244 #ifdef STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT
00246 typedef ss_typename_type_k reverse_iterator_generator < iterator
00247 , value_type
00248 , reference
00249 , pointer
00250 , difference_type
00251 >::type reverse_iterator;
00252
00254 typedef ss_typename_type_k const_reverse_iterator_generator < const_iterator
00255 , value_type
00256 , const_reference
00257 , const_pointer
00258 , difference_type
00259 >::type const_reverse_iterator;
00260 #endif
00262
00265 protected:
00266 enum { growthGranularity = 16 };
00267
00268 static size_type calc_increment_(size_type n)
00269 {
00270 size_type numBlocks = n / growthGranularity;
00271
00272 return (1 + numBlocks) * growthGranularity;
00273 }
00275
00278 public:
00280 array_type &get_CArray()
00281 {
00282 return static_cast<interface_class_type*>(this)->get_actual_array();
00283 }
00285 array_type const &get_CArray() const
00286 {
00287 return static_cast<interface_class_type const*>(this)->get_actual_array();
00288 }
00290
00293 protected:
00298 CArray_adaptor_base()
00299 {}
00301 ~CArray_adaptor_base() stlsoft_throw_0()
00302 {}
00303 public:
00305 allocator_type get_allocator() const
00306 {
00307 return allocator_type();
00308 }
00309 #if defined(_DEBUG) || \
00310 defined(MFCSTL_ARRAY_ADAPTORS_ALLOW_CAPACITY_PEEK)
00311 public:
00312 #else
00313 protected:
00314 #endif
00315 size_type grow_increment() const
00316 {
00317 class GrowByGetter
00318 : public array_type
00319 {
00320 public:
00321 size_type grow_increment() const
00322 {
00323 return m_nGrowBy;
00324 }
00325 };
00326
00327 return static_cast<GrowByGetter const&>(get_CArray()).grow_increment();
00328 }
00329 size_type capacity() const
00330 {
00331 class CapacityGetter
00332 : public array_type
00333 {
00334 public:
00335 size_type capacity() const
00336 {
00337 return m_nMaxSize;
00338 }
00339 };
00340
00341 return static_cast<CapacityGetter const&>(get_CArray()).capacity();
00342 }
00344
00347 public:
00356 void assign(size_type n, value_type const& value)
00357 {
00358 #ifdef MFCSTL_CARRAY_SWAP_MEMBERS_SUPPORT
00359 try
00360 {
00361 array_type ar;
00362
00363 ar.SetSize(0, calc_increment_(n));
00364 if(n > 0)
00365 {
00366 ar.InsertAt(0, value, static_cast<int>(n));
00367 }
00368 CArray_swap(this->get_CArray(), ar);
00369 }
00370 catch(CMemoryException *px)
00371 {
00372 exception_translation_policy_type::handle(px);
00373 }
00374 catch(mfcstl_ns_qual_std(bad_alloc) &x)
00375 {
00376 exception_translation_policy_type::handle(x);
00377 }
00378 #else
00379
00380
00381
00382
00383
00384 resize(n);
00385 mfcstl_ns_qual_std(fill_n)(begin(), n, value);
00386 #endif
00387
00388
00389 MFCSTL_ASSERT(size() == n);
00390 }
00391
00400 template <ss_typename_param_k I2>
00401 void assign(I2 first, I2 last)
00402 {
00403
00404 MFCSTL_ASSERT(is_valid_source_range_(first, last));
00405
00406 #ifdef MFCSTL_CARRAY_SWAP_MEMBERS_SUPPORT
00407 if(empty())
00408 {
00409
00410
00411
00412 try
00413 {
00414 clear_and_assign_(first, last);
00415 }
00416 catch(...)
00417 {
00418 clear();
00419
00420 throw;
00421 }
00422 }
00423 else
00424 {
00425
00426
00427 array_type ar;
00428 CArray_iadaptor<array_type
00429 , array_traits_type
00430 > arp(ar);
00431 arp.assign(first, last);
00432
00433 CArray_swap(this->get_CArray(), ar);
00434 }
00435 #else
00436 clear_and_assign_(first, last);
00437 #endif
00438 }
00440
00443 public:
00445 size_type size() const
00446 {
00447 return static_cast<size_type>(get_CArray().GetSize());
00448 }
00450 size_type max_size() const
00451 {
00452 return get_allocator().max_size();
00453 }
00455 ms_bool_t empty() const
00456 {
00457 return 0 == size();
00458 }
00465 void resize(size_type n)
00466 {
00467 try
00468 {
00469 get_CArray().SetSize(n, calc_increment_(n));
00470 }
00471 catch(CMemoryException *px)
00472 {
00473 exception_translation_policy_type::handle(px);
00474 }
00475 catch(mfcstl_ns_qual_std(bad_alloc) &x)
00476 {
00477 exception_translation_policy_type::handle(x);
00478 }
00479
00480
00481 MFCSTL_ASSERT(size() == n);
00482 }
00494 void resize(size_type n, value_type value)
00495 {
00496 const size_type oldSize = size();
00497 resize(n);
00498 if(oldSize < n)
00499 {
00500 try
00501 {
00502 mfcstl_ns_qual_std(fill_n)(begin() + oldSize, n - oldSize, value);
00503 }
00504 catch(...)
00505 {
00506 resize(oldSize);
00507 throw;
00508 }
00509 }
00510 }
00512
00515 public:
00521 reference operator [](size_type n)
00522 {
00523 MFCSTL_MESSAGE_ASSERT("index out of bounds", n < size());
00524
00525 return get_CArray()[n];
00526 }
00532 const_reference operator [](size_type n) const
00533 {
00534 MFCSTL_MESSAGE_ASSERT("index out of bounds", n < size());
00535
00536 return get_CArray()[n];
00537 }
00542 reference at(size_type n)
00543 {
00544 if(n >= size())
00545 {
00546 STLSOFT_THROW_X(mfcstl_ns_qual_std(out_of_range)("Invalid index specified"));
00547 }
00548
00549 return (*this)[n];
00550 }
00555 const_reference at(size_type n) const
00556 {
00557 if(n >= size())
00558 {
00559 STLSOFT_THROW_X(mfcstl_ns_qual_std(out_of_range)("Invalid index specified"));
00560 }
00561 return (*this)[n];
00562 }
00564 reference front()
00565 {
00566 MFCSTL_MESSAGE_ASSERT("front() called on an empty instance", !empty());
00567
00568 return (*this)[0];
00569 }
00571 reference back()
00572 {
00573 MFCSTL_MESSAGE_ASSERT("back() called on an empty instance", !empty());
00574
00575 return (*this)[size() - 1];
00576 }
00578 const_reference front() const
00579 {
00580 MFCSTL_MESSAGE_ASSERT("front() called on an empty instance", !empty());
00581
00582 return (*this)[0];
00583 }
00585 const_reference back() const
00586 {
00587 MFCSTL_MESSAGE_ASSERT("back() called on an empty instance", !empty());
00588
00589 return (*this)[size() - 1];
00590 }
00592
00595 public:
00597 iterator begin()
00598 {
00599 return get_CArray().GetData();
00600 }
00602 iterator end()
00603 {
00604 return begin() + size();
00605 }
00607 const_iterator begin() const
00608 {
00609
00610 value_type const *p1 = get_CArray().GetData();
00611 value_type *const p2 = const_cast<value_type *const>(p1);
00612
00613 return p2;
00614 }
00616 const_iterator end() const
00617 {
00618 return begin() + size();
00619 }
00620 #ifdef STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT
00622 reverse_iterator rbegin()
00623 {
00624 return reverse_iterator(end());
00625 }
00627 reverse_iterator rend()
00628 {
00629 return reverse_iterator(begin());
00630 }
00632 const_reverse_iterator rbegin() const
00633 {
00634 return const_reverse_iterator(end());
00635 }
00637 const_reverse_iterator rend() const
00638 {
00639 return const_reverse_iterator(begin());
00640 }
00641 #endif
00643
00646 public:
00647 template< ss_typename_param_k A2
00648 , ss_typename_param_k I2
00649 , ss_typename_param_k T2
00650 >
00651 ms_bool_t equal(CArray_adaptor_base<A2, I2, T2> const& rhs) const
00652 {
00653 typedef CArray_adaptor_base<A2, I2, T2> rhs_t;
00654 typedef ss_typename_type_k rhs_t::value_type rhs_value_t;
00655
00656 STLSOFT_STATIC_ASSERT(sizeof(value_type) == sizeof(ss_typename_type_k rhs_t::value_type));
00657
00658 #ifdef STLSOFT_META_HAS_IS_SAME_TYPE
00659 STLSOFT_STATIC_ASSERT((stlsoft::is_same_type<value_type, rhs_value_t>::value));
00660 #endif
00661
00662 return size() == rhs.size() && stlsoft_ns_qual_std(equal)(begin(), end(), rhs.begin());
00663 }
00664
00665 ms_bool_t equal(array_type const& rhs) const
00666 {
00667 array_type const &lhs = this->get_CArray();
00668
00669 return lhs.GetSize() == rhs.GetSize() && stlsoft_ns_qual_std(equal)(begin(), end(), rhs.GetData());
00670 }
00671
00672 template< ss_typename_param_k A2
00673 , ss_typename_param_k I2
00674 , ss_typename_param_k T2
00675 >
00676 ms_bool_t less_than(CArray_adaptor_base<A2, I2, T2> const& rhs) const
00677 {
00678 typedef CArray_adaptor_base<A2, I2, T2> rhs_t;
00679 typedef ss_typename_type_k rhs_t::value_type rhs_value_t;
00680
00681 STLSOFT_STATIC_ASSERT(sizeof(value_type) == sizeof(ss_typename_type_k rhs_t::value_type));
00682
00683 #ifdef STLSOFT_META_HAS_IS_SAME_TYPE
00684 STLSOFT_STATIC_ASSERT((stlsoft::is_same_type<value_type, rhs_value_t>::value));
00685 #endif
00686
00687 return stlsoft_ns_qual_std(lexicographical_compare)(begin(), end(), rhs.begin(), rhs.end());
00688 }
00689
00690 ms_bool_t less_than(array_type const& rhs) const
00691 {
00692 return stlsoft_ns_qual_std(lexicographical_compare)(begin(), end(), rhs.GetData(), rhs.GetData() + rhs.GetSize());
00693 }
00694
00695 template< ss_typename_param_k A2
00696 , ss_typename_param_k I2
00697 , ss_typename_param_k T2
00698 >
00699 ms_bool_t greater_than(CArray_adaptor_base<A2, I2, T2> const& rhs) const
00700 {
00701 typedef CArray_adaptor_base<A2, I2, T2> rhs_t;
00702 typedef ss_typename_type_k rhs_t::value_type rhs_value_t;
00703
00704 STLSOFT_STATIC_ASSERT(sizeof(value_type) == sizeof(ss_typename_type_k rhs_t::value_type));
00705
00706 #ifdef STLSOFT_META_HAS_IS_SAME_TYPE
00707 STLSOFT_STATIC_ASSERT((stlsoft::is_same_type<value_type, rhs_value_t>::value));
00708 #endif
00709
00710 return stlsoft_ns_qual_std(lexicographical_compare)(rhs.begin(), rhs.end(), begin(), end());
00711 }
00712
00713 ms_bool_t greater_than(array_type const& rhs) const
00714 {
00715 return stlsoft_ns_qual_std(lexicographical_compare)(rhs.GetData(), rhs.GetData() + rhs.GetSize(), begin(), end());
00716 }
00718
00721 public:
00727 void push_back(value_type const& value)
00728 {
00729 const size_type oldSize = size();
00730
00731 resize(size());
00732
00733 try
00734 {
00735 try
00736 {
00737 get_CArray().Add(value);
00738 }
00739 catch(CMemoryException *px)
00740 {
00741 exception_translation_policy_type::handle(px);
00742 }
00743 catch(mfcstl_ns_qual_std(bad_alloc) &x)
00744 {
00745 exception_translation_policy_type::handle(x);
00746 }
00747 }
00748 catch(...)
00749 {
00750 if(size() != oldSize)
00751 {
00752 MFCSTL_ASSERT(size() == oldSize + 1);
00753
00754 resize(oldSize);
00755 }
00756
00757 throw;
00758 }
00759 }
00763 void pop_back() stlsoft_throw_0()
00764 {
00765
00766 MFCSTL_MESSAGE_ASSERT("pop_back() called on empty container", !empty());
00767
00768 get_CArray().RemoveAt(get_CArray().GetUpperBound());
00769 }
00785 iterator insert(iterator pos, value_type const& value)
00786 {
00787
00788 MFCSTL_ASSERT(pos == end() || (pos >= begin() && pos < end()));
00789
00790 difference_type index = pos - begin();
00791 const size_type oldSize = size();
00792
00793 resize(size());
00794
00795 try
00796 {
00797 try
00798 {
00799 get_CArray().InsertAt(static_cast<int>(index), value, 1);
00800 }
00801 catch(CMemoryException *px)
00802 {
00803 exception_translation_policy_type::handle(px);
00804 }
00805 catch(mfcstl_ns_qual_std(bad_alloc) &x)
00806 {
00807 exception_translation_policy_type::handle(x);
00808 }
00809 }
00810 catch(...)
00811 {
00812 if(size() != oldSize)
00813 {
00814 MFCSTL_ASSERT(size() == oldSize + 1);
00815
00816 get_CArray().RemoveAt(static_cast<int>(index), 1);
00817 }
00818
00819 throw;
00820 }
00821
00822 return begin() + index;
00823 }
00838 void insert(iterator pos, size_type n, value_type const& value)
00839 {
00840
00841 MFCSTL_ASSERT(pos == end() || (pos >= begin() && pos < end()));
00842
00843 difference_type index = pos - begin();
00844
00845 if(empty())
00846 {
00847 MFCSTL_ASSERT(0 == index);
00848
00849 assign(n, value);
00850 }
00851 else
00852 {
00853 const size_type oldSize = size();
00854
00855 resize(size());
00856
00857 try
00858 {
00859 try
00860 {
00861 if(n > 0)
00862 {
00863 get_CArray().InsertAt(static_cast<int>(index), value, n);
00864 }
00865 }
00866 catch(CMemoryException *px)
00867 {
00868 exception_translation_policy_type::handle(px);
00869 }
00870 catch(mfcstl_ns_qual_std(bad_alloc) &x)
00871 {
00872 exception_translation_policy_type::handle(x);
00873 }
00874 }
00875 catch(...)
00876 {
00877 if(size() != oldSize)
00878 {
00879 MFCSTL_ASSERT(size() == oldSize + n);
00880
00881 get_CArray().RemoveAt(static_cast<int>(index), size() - oldSize);
00882 }
00883
00884 throw;
00885 }
00886 }
00887 }
00902 template <ss_typename_param_k I2>
00903 void insert(iterator pos, I2 first, I2 last)
00904 {
00905
00906 MFCSTL_ASSERT(is_valid_source_range_(first, last));
00907 MFCSTL_ASSERT(pos == end() || (pos >= begin() && pos < end()));
00908
00909 array_type ar;
00910 CArray_iadaptor<array_type
00911 , array_traits_type
00912 > arp(ar);
00913 arp.assign(first, last);
00914 difference_type index = pos - begin();
00915 const size_type oldSize = size();
00916 const size_type n = arp.size();
00917
00918 resize(size());
00919
00920 try
00921 {
00922 try
00923 {
00924 get_CArray().InsertAt(static_cast<int>(index), &ar);
00925 }
00926 catch(CMemoryException *px)
00927 {
00928 exception_translation_policy_type::handle(px);
00929 }
00930 catch(mfcstl_ns_qual_std(bad_alloc) &x)
00931 {
00932 exception_translation_policy_type::handle(x);
00933 }
00934 }
00935 catch(...)
00936 {
00937 if(size() != oldSize)
00938 {
00939 MFCSTL_ASSERT(size() == oldSize + n);
00940
00941 get_CArray().RemoveAt(static_cast<int>(index), size() - oldSize);
00942 }
00943
00944 throw;
00945 }
00946 }
00961 iterator erase(iterator pos) stlsoft_throw_0()
00962 {
00963
00964 MFCSTL_ASSERT(pos == end() || (pos >= begin() && pos < end()));
00965
00966 difference_type index = pos - begin();
00967 get_CArray().RemoveAt(static_cast<int>(index), 1);
00968
00969
00970 MFCSTL_ASSERT(pos == begin() + index);
00971
00972 resize(size());
00973
00974 return pos;
00975 }
00991 iterator erase(iterator first, iterator last) stlsoft_throw_0()
00992 {
00993
00994 MFCSTL_ASSERT(first <= last);
00995 MFCSTL_ASSERT(first == end() || (first >= begin() && first < end()));
00996 MFCSTL_ASSERT(last == end() || (last >= begin() && last < end()));
00997
00998 difference_type index = first - begin();
00999 get_CArray().RemoveAt(static_cast<int>(index), mfcstl_ns_qual_std(distance)(first, last));
01000
01001
01002 MFCSTL_ASSERT(first == begin() + index);
01003
01004 resize(size());
01005
01006 return first;
01007 }
01009 void clear() stlsoft_throw_0()
01010 {
01011 get_CArray().RemoveAll();
01012
01013 resize(size());
01014 }
01015
01016 #ifdef MFCSTL_CARRAY_SWAP_MEMBERS_SUPPORT
01024 void swap(class_type& rhs) stlsoft_throw_0()
01025 {
01026 mfcstl::CArray_swap(this->get_CArray(), rhs.get_CArray());
01027 }
01028 #endif
01029
01034 void swap_by_copy(class_type& rhs)
01035 {
01036 class_type t = rhs;
01037 rhs = *this;
01038 *this = t;
01039 }
01041
01044 private:
01045 template <ss_typename_param_k I2>
01046 # if defined(STLSOFT_COMPILER_IS_MWERKS)
01047
01048 void clear_and_assign_(I2 first, I2 last, stlsoft_ns_qual_std(input_iterator_tag) const*)
01049 # else
01050 void clear_and_assign_(I2 first, I2 last, stlsoft_ns_qual_std(input_iterator_tag))
01051 # endif
01052 {
01053 clear();
01054
01055 mfcstl_ns_qual_std(copy)(first, last, mfcstl_ns_qual_std(back_inserter)<class_type>(*this));
01056 }
01057 template <ss_typename_param_k I2>
01058 # if defined(STLSOFT_COMPILER_IS_MWERKS)
01059
01060 void clear_and_assign_(I2 first, I2 last, stlsoft_ns_qual_std(forward_iterator_tag) const*)
01061 # else
01062 void clear_and_assign_(I2 first, I2 last, stlsoft_ns_qual_std(forward_iterator_tag))
01063 # endif
01064 {
01065 resize(mfcstl_ns_qual_std(distance)(first, last));
01066
01067 mfcstl_ns_qual_std(copy)(first, last, begin());
01068 }
01069
01070 template <ss_typename_param_k I2>
01071 void clear_and_assign_(I2 first, I2 last)
01072 {
01073 # if defined(STLSOFT_COMPILER_IS_GCC) && \
01074 __GNUC__ < 3
01075 typedef ss_typename_type_k mfcstl_ns_qual_std(iterator_traits)<I2> traits_t;
01076
01077 clear_and_assign_(first, last, traits_t::iterator_category());
01078 # elif defined(STLSOFT_COMPILER_IS_MWERKS)
01079 clear_and_assign_(first, last, stlsoft_iterator_query_category_ptr(I2, first));
01080 # else
01081 clear_and_assign_(first, last, stlsoft_iterator_query_category(I2, first));
01082 # endif
01083 }
01084
01085 protected:
01086 #if ( !defined(STLSOFT_COMPILER_IS_MSVC) || \
01087 _MSC_VER > 1200)
01088 template <ss_typename_param_k I2>
01089 # if defined(STLSOFT_COMPILER_IS_MWERKS)
01090
01091 static ms_bool_t is_valid_source_range_(I2 first, I2 last, stlsoft_ns_qual_std(input_iterator_tag) const*)
01092 # else
01093 static ms_bool_t is_valid_source_range_(I2 first, I2 last, stlsoft_ns_qual_std(input_iterator_tag))
01094 # endif
01095 {
01096 return true;
01097 }
01098 #endif
01099
01100 template< ss_typename_param_k I2
01101 , ss_typename_param_k T2
01102 >
01103 static ms_bool_t is_valid_source_range_(I2 first, I2 last, T2)
01104 {
01105 return true;
01106 }
01107
01108 #if ( !defined(STLSOFT_COMPILER_IS_MSVC) || \
01109 _MSC_VER > 1200)
01110 template <ss_typename_param_k I2>
01111 # if defined(STLSOFT_COMPILER_IS_MWERKS)
01112
01113 static ms_bool_t is_valid_source_range_(I2 first, I2 last, stlsoft_ns_qual_std(random_access_iterator_tag) const*)
01114 # else
01115 static ms_bool_t is_valid_source_range_(I2 first, I2 last, stlsoft_ns_qual_std(random_access_iterator_tag))
01116 # endif
01117 {
01118 return first <= last;
01119 }
01120 #endif
01121
01122 template <ss_typename_param_k I2>
01123 static ms_bool_t is_valid_source_range_(I2 first, I2 last)
01124 {
01125 # if defined(STLSOFT_COMPILER_IS_GCC) && \
01126 __GNUC__ < 3
01127 typedef ss_typename_type_k mfcstl_ns_qual_std(iterator_traits)<I2> traits_t;
01128
01129 return is_valid_source_range_(first, last, traits_t::iterator_category());
01130 # elif defined(STLSOFT_COMPILER_IS_MWERKS)
01131 return is_valid_source_range_(first, last, stlsoft_iterator_query_category_ptr(I2, first));
01132 # elif defined(STLSOFT_COMPILER_IS_DMC)
01133 return true;
01134 # else
01135 return is_valid_source_range_(first, last, stlsoft_iterator_query_category(I2, first));
01136 # endif
01137 }
01138
01139 #if 0
01140 template <ss_typename_param_k T2>
01141 static ms_bool_t is_valid_source_range_(T2* first, T2* last)
01142 {
01143 return first <= last;
01144 }
01145 #endif
01146
01147 #if 0
01148 template <ss_typename_param_k T2>
01149 static ms_bool_t is_valid_source_range_(T2 const* first, T2 const* last)
01150 {
01151 return first <= last;
01152 }
01153 #endif
01155
01158 private:
01159 CArray_adaptor_base(class_type const& rhs);
01160 class_type& operator =(class_type const& rhs);
01162 };
01163
01164 #ifdef STLSOFT_DOCUMENTATION_SKIP_SECTION
01165
01196 #endif
01197 template< ss_typename_param_k A
01198 , ss_typename_param_k T = CArray_traits<A>
01199 >
01200 class CArray_cadaptor
01201 : public A
01202 , public CArray_adaptor_base<A, CArray_cadaptor<A, T>, T>
01203 {
01206 private:
01207 typedef CArray_adaptor_base<A, CArray_cadaptor<A, T>, T> parent_class_type;
01208 public:
01210 typedef ss_typename_type_k parent_class_type::array_type array_type;
01212 typedef ss_typename_type_k parent_class_type::value_type value_type;
01214 typedef ss_typename_type_k parent_class_type::allocator_type allocator_type;
01216 typedef ss_typename_type_k parent_class_type::reference reference;
01218 typedef ss_typename_type_k parent_class_type::const_reference const_reference;
01220 typedef ss_typename_type_k parent_class_type::pointer pointer;
01222 typedef ss_typename_type_k parent_class_type::const_pointer const_pointer;
01224 typedef ss_typename_type_k parent_class_type::iterator iterator;
01226 typedef ss_typename_type_k parent_class_type::const_iterator const_iterator;
01228 typedef ss_typename_type_k parent_class_type::size_type size_type;
01230 typedef ss_typename_type_k parent_class_type::difference_type difference_type;
01232 typedef CArray_cadaptor<A, T> class_type;
01234
01237 private:
01238 friend class CArray_adaptor_base<A, CArray_cadaptor<A, T>, T>;
01239
01240 array_type &get_actual_array()
01241 {
01242 return *this;
01243 }
01244 array_type const &get_actual_array() const
01245 {
01246 return *this;
01247 }
01249
01252 public:
01258 ss_explicit_k CArray_cadaptor(allocator_type const& = allocator_type())
01259 {
01260 parent_class_type::resize(0);
01261 }
01265 explicit CArray_cadaptor(size_type n)
01266 {
01267 parent_class_type::resize(n);
01268 }
01273 CArray_cadaptor(size_type n, value_type const& value)
01274 {
01275 parent_class_type::assign(n, value);
01276 }
01278 CArray_cadaptor(class_type const& rhs)
01279 {
01280 parent_class_type::assign(rhs.begin(), rhs.end());
01281 }
01283 CArray_cadaptor(array_type const& rhs)
01284 {
01285 parent_class_type::assign(rhs.GetData(), rhs.GetData() + rhs.GetSize());
01286 }
01288 template <ss_typename_param_k I2>
01289 CArray_cadaptor(I2 first, I2 last)
01290 {
01291
01292 MFCSTL_ASSERT(parent_class_type::is_valid_source_range_(first, last));
01293
01294 parent_class_type::assign(first, last);
01295 }
01296 ~CArray_cadaptor() stlsoft_throw_0()
01297 {
01298 STLSOFT_STATIC_ASSERT(sizeof(A) == sizeof(ss_typename_type_k T::array_type));
01299 }
01301
01304 public:
01305 class_type& operator =(class_type const& rhs)
01306 {
01307 #ifdef MFCSTL_CARRAY_SWAP_MEMBERS_SUPPORT
01308 class_type t(rhs);
01309 t.swap(*this);
01310 #else
01311 parent_class_type::assign(rhs.begin(), rhs.end());
01312 #endif
01313
01314 return *this;
01315 }
01317
01320 public:
01321 #if defined(STLSOFT_COMPILER_IS_DMC)
01322 reference operator [](size_type index)
01323 {
01324 return parent_class_type::operator [](index);
01325 }
01326 const_reference operator [](size_type index) const
01327 {
01328 return parent_class_type::operator [](index);
01329 }
01330 #else
01331 using parent_class_type::operator [];
01332 #endif
01334 };
01335
01336
01337 #ifdef STLSOFT_DOCUMENTATION_SKIP_SECTION
01338
01368 #endif
01369 template< ss_typename_param_k A
01370 , ss_typename_param_k T = CArray_traits<A>
01371 >
01372 class CArray_iadaptor
01373 : public CArray_adaptor_base<A, CArray_iadaptor<A, T>, T>
01374 {
01377 private:
01378 typedef CArray_adaptor_base<A, CArray_iadaptor<A, T>, T> parent_class_type;
01379 public:
01381 typedef ss_typename_type_k parent_class_type::array_type array_type;
01383 typedef ss_typename_type_k parent_class_type::value_type value_type;
01385 typedef ss_typename_type_k parent_class_type::allocator_type allocator_type;
01387 typedef ss_typename_type_k parent_class_type::reference reference;
01389 typedef ss_typename_type_k parent_class_type::const_reference const_reference;
01391 typedef ss_typename_type_k parent_class_type::pointer pointer;
01393 typedef ss_typename_type_k parent_class_type::const_pointer const_pointer;
01395 typedef ss_typename_type_k parent_class_type::iterator iterator;
01397 typedef ss_typename_type_k parent_class_type::const_iterator const_iterator;
01399 typedef ss_typename_type_k parent_class_type::size_type size_type;
01401 typedef ss_typename_type_k parent_class_type::difference_type difference_type;
01403 typedef CArray_iadaptor<A, T> class_type;
01405
01408 private:
01409 friend class CArray_adaptor_base<A, CArray_iadaptor<A, T>, T>;
01410
01411 array_type &get_actual_array()
01412 {
01413 MFCSTL_ASSERT(NULL != m_pArray);
01414 return *m_pArray;
01415 }
01416 array_type const &get_actual_array() const
01417 {
01418 MFCSTL_ASSERT(NULL != m_pArray);
01419 return *m_pArray;
01420 }
01422
01425 public:
01426 template <ss_typename_param_k A2>
01427 CArray_iadaptor(A2 &array)
01428 : m_pArray(&array)
01429 {
01430 STLSOFT_STATIC_ASSERT(sizeof(array_type) == sizeof(A2));
01431 #ifdef STLSOFT_META_HAS_IS_SAME_TYPE
01432 STLSOFT_STATIC_ASSERT((stlsoft::is_same_type<array_type, A2>::value));
01433 #else
01434 ASSERT(0 == ::lstrcmpA(array.GetRuntimeClass()->m_lpszClassName, array_type().GetRuntimeClass()->m_lpszClassName));
01435 # ifdef _CPPRTTI
01436 ASSERT(0 == ::lstrcmpA(typeid(A2).name(), typeid(array_type).name()));
01437 # endif
01438 #endif
01439 }
01440 template <ss_typename_param_k A2>
01441 CArray_iadaptor(A2 *pArray)
01442 : m_pArray(pArray)
01443 {
01444 MFCSTL_MESSAGE_ASSERT("Cannot initialise a CArray_iadaptor with a NULL pointer", NULL != pArray);
01445
01446 STLSOFT_STATIC_ASSERT(sizeof(array_type) == sizeof(A2));
01447 #ifdef STLSOFT_META_HAS_IS_SAME_TYPE
01448 STLSOFT_STATIC_ASSERT((stlsoft::is_same_type<array_type, A2>::value));
01449 #else
01450 ASSERT(0 == ::lstrcmpA(pArray->GetRuntimeClass()->m_lpszClassName, array_type().GetRuntimeClass()->m_lpszClassName));
01451 # ifdef _CPPRTTI
01452 ASSERT(0 == ::lstrcmpA(typeid(A2).name(), typeid(array_type).name()));
01453 # endif
01454 #endif
01455 }
01457
01460 private:
01461 array_type *m_pArray;
01463
01466 private:
01467 CArray_iadaptor(class_type const& rhs);
01468 class_type& operator =(class_type const& rhs);
01470 };
01471
01472
01473
01474
01475
01476 template< ss_typename_param_k A1
01477 , ss_typename_param_k A2
01478 , ss_typename_param_k I1
01479 , ss_typename_param_k I2
01480 , ss_typename_param_k T1
01481 , ss_typename_param_k T2
01482 >
01483 inline ms_bool_t operator ==(CArray_adaptor_base<A1, I1, T1> const& lhs, CArray_adaptor_base<A2, I2, T2> const& rhs)
01484 {
01485 return lhs.equal(rhs);
01486 }
01487
01488 template< ss_typename_param_k A1
01489 , ss_typename_param_k A2
01490 , ss_typename_param_k I1
01491 , ss_typename_param_k I2
01492 , ss_typename_param_k T1
01493 , ss_typename_param_k T2
01494 >
01495 inline ms_bool_t operator !=(CArray_adaptor_base<A1, I1, T1> const& lhs, CArray_adaptor_base<A2, I2, T2> const& rhs)
01496 {
01497 return !lhs.equal(rhs);
01498 }
01499
01500 template< ss_typename_param_k A1
01501 , ss_typename_param_k A2
01502 , ss_typename_param_k I1
01503 , ss_typename_param_k I2
01504 , ss_typename_param_k T1
01505 , ss_typename_param_k T2
01506 >
01507 inline ms_bool_t operator <(CArray_adaptor_base<A1, I1, T1> const& lhs, CArray_adaptor_base<A2, I2, T2> const& rhs)
01508 {
01509 return lhs.less_than(rhs);
01510 }
01511
01512 template< ss_typename_param_k A1
01513 , ss_typename_param_k A2
01514 , ss_typename_param_k I1
01515 , ss_typename_param_k I2
01516 , ss_typename_param_k T1
01517 , ss_typename_param_k T2
01518 >
01519 inline ms_bool_t operator <=(CArray_adaptor_base<A1, I1, T1> const& lhs, CArray_adaptor_base<A2, I2, T2> const& rhs)
01520 {
01521 return !lhs.greater_than(rhs);
01522 }
01523
01524 template< ss_typename_param_k A1
01525 , ss_typename_param_k A2
01526 , ss_typename_param_k I1
01527 , ss_typename_param_k I2
01528 , ss_typename_param_k T1
01529 , ss_typename_param_k T2
01530 >
01531 inline ms_bool_t operator >(CArray_adaptor_base<A1, I1, T1> const& lhs, CArray_adaptor_base<A2, I2, T2> const& rhs)
01532 {
01533 return lhs.greater_than(rhs);
01534 }
01535
01536 template< ss_typename_param_k A1
01537 , ss_typename_param_k A2
01538 , ss_typename_param_k I1
01539 , ss_typename_param_k I2
01540 , ss_typename_param_k T1
01541 , ss_typename_param_k T2
01542 >
01543 inline ms_bool_t operator >=(CArray_adaptor_base<A1, I1, T1> const& lhs, CArray_adaptor_base<A2, I2, T2> const& rhs)
01544 {
01545 return !lhs.less_than(rhs);
01546 }
01547
01548
01549
01550 template< ss_typename_param_k A
01551 , ss_typename_param_k I
01552 , ss_typename_param_k T
01553 >
01554 inline ms_bool_t operator ==(CArray_adaptor_base<A, I, T> const& lhs, A const& rhs)
01555 {
01556 return lhs.equal(rhs);
01557 }
01558
01559 template< ss_typename_param_k A
01560 , ss_typename_param_k I
01561 , ss_typename_param_k T
01562 >
01563 inline ms_bool_t operator !=(CArray_adaptor_base<A, I, T> const& lhs, A const& rhs)
01564 {
01565 return !lhs.equal(rhs);
01566 }
01567
01568 template< ss_typename_param_k A
01569 , ss_typename_param_k I
01570 , ss_typename_param_k T
01571 >
01572 inline ms_bool_t operator <(CArray_adaptor_base<A, I, T> const& lhs, A const& rhs)
01573 {
01574 return lhs.less_than(rhs);
01575 }
01576
01577 template< ss_typename_param_k A
01578 , ss_typename_param_k I
01579 , ss_typename_param_k T
01580 >
01581 inline ms_bool_t operator <=(CArray_adaptor_base<A, I, T> const& lhs, A const& rhs)
01582 {
01583 return !lhs.greater_than(rhs);
01584 }
01585
01586 template< ss_typename_param_k A
01587 , ss_typename_param_k I
01588 , ss_typename_param_k T
01589 >
01590 inline ms_bool_t operator >(CArray_adaptor_base<A, I, T> const& lhs, A const& rhs)
01591 {
01592 return lhs.greater_than(rhs);
01593 }
01594
01595 template< ss_typename_param_k A
01596 , ss_typename_param_k I
01597 , ss_typename_param_k T
01598 >
01599 inline ms_bool_t operator >=(CArray_adaptor_base<A, I, T> const& lhs, A const& rhs)
01600 {
01601 return !lhs.less_than(rhs);
01602 }
01603
01604
01605
01606
01607 template< ss_typename_param_k A
01608 , ss_typename_param_k I
01609 , ss_typename_param_k T
01610 >
01611 inline ms_bool_t operator ==(A const& lhs, CArray_adaptor_base<A, I, T> const& rhs)
01612 {
01613 return rhs.equal(lhs);
01614 }
01615
01616 template< ss_typename_param_k A
01617 , ss_typename_param_k I
01618 , ss_typename_param_k T
01619 >
01620 inline ms_bool_t operator !=(A const& lhs, CArray_adaptor_base<A, I, T> const& rhs)
01621 {
01622 return !rhs.equal(lhs);
01623 }
01624
01625 template< ss_typename_param_k A
01626 , ss_typename_param_k I
01627 , ss_typename_param_k T
01628 >
01629 inline ms_bool_t operator <(A const& lhs, CArray_adaptor_base<A, I, T> const& rhs)
01630 {
01631 return !(rhs.greater_than(lhs) || rhs == lhs);
01632 }
01633
01634 template< ss_typename_param_k A
01635 , ss_typename_param_k I
01636 , ss_typename_param_k T
01637 >
01638 inline ms_bool_t operator <=(A const& lhs, CArray_adaptor_base<A, I, T> const& rhs)
01639 {
01640 return !rhs.less_than(lhs);
01641 }
01642
01643 template< ss_typename_param_k A
01644 , ss_typename_param_k I
01645 , ss_typename_param_k T
01646 >
01647 inline ms_bool_t operator >(A const& lhs, CArray_adaptor_base<A, I, T> const& rhs)
01648 {
01649 return !(rhs.less_than(lhs) || rhs == lhs);
01650 }
01651
01652 template< ss_typename_param_k A
01653 , ss_typename_param_k I
01654 , ss_typename_param_k T
01655 >
01656 inline ms_bool_t operator >=(A const& lhs, CArray_adaptor_base<A, I, T> const& rhs)
01657 {
01658 return !rhs.greater_than(lhs);
01659 }
01660
01662
01663
01664 #ifdef STLSOFT_UNITTEST
01665 # include "./unittest/carray_adaptors_unittest_.h"
01666 #endif
01667
01668
01669
01670 #ifndef _MFCSTL_NO_NAMESPACE
01671 # if defined(_STLSOFT_NO_NAMESPACE) || \
01672 defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
01673 }
01674 # else
01675 }
01676 }
01677 # endif
01678 #endif
01679
01680
01681
01682 #endif
01683
01684