stlsoft/memory/auto_buffer.hpp

Go to the documentation of this file.
00001 /* /////////////////////////////////////////////////////////////////////////
00002  * File:        stlsoft/memory/auto_buffer.hpp (originally MTLocBfr.h, ::SynesisStl)
00003  *
00004  * Purpose:     Contains the auto_buffer template class.
00005  *
00006  * Created:     19th January 2002
00007  * Updated:     10th August 2009
00008  *
00009  * Thanks:      To Thorsten Ottosen for pointing out that allocators were
00010  *              not swapped.
00011  *
00012  * Home:        http://stlsoft.org/
00013  *
00014  * Copyright (c) 2002-2009, Matthew Wilson and Synesis Software
00015  * All rights reserved.
00016  *
00017  * Redistribution and use in source and binary forms, with or without
00018  * modification, are permitted provided that the following conditions are met:
00019  *
00020  * - Redistributions of source code must retain the above copyright notice, this
00021  *   list of conditions and the following disclaimer.
00022  * - Redistributions in binary form must reproduce the above copyright notice,
00023  *   this list of conditions and the following disclaimer in the documentation
00024  *   and/or other materials provided with the distribution.
00025  * - Neither the name(s) of Matthew Wilson and Synesis Software nor the names of
00026  *   any contributors may be used to endorse or promote products derived from
00027  *   this software without specific prior written permission.
00028  *
00029  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00030  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00031  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00032  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00033  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00034  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00035  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00036  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00037  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00038  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00039  * POSSIBILITY OF SUCH DAMAGE.
00040  *
00041  * ////////////////////////////////////////////////////////////////////// */
00042 
00043 
00050 #ifndef STLSOFT_INCL_STLSOFT_MEMORY_HPP_AUTO_BUFFER
00051 #define STLSOFT_INCL_STLSOFT_MEMORY_HPP_AUTO_BUFFER
00052 
00053 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00054 # define STLSOFT_VER_STLSOFT_MEMORY_HPP_AUTO_BUFFER_MAJOR       5
00055 # define STLSOFT_VER_STLSOFT_MEMORY_HPP_AUTO_BUFFER_MINOR       2
00056 # define STLSOFT_VER_STLSOFT_MEMORY_HPP_AUTO_BUFFER_REVISION    4
00057 # define STLSOFT_VER_STLSOFT_MEMORY_HPP_AUTO_BUFFER_EDIT        162
00058 #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
00059 
00060 /* /////////////////////////////////////////////////////////////////////////
00061  * Compatibility
00062  */
00063 
00064 /*
00065 [Incompatibilies-start]
00066 STLSOFT_COMPILER_IS_GCC:     __GNUC__ < 3
00067 [Incompatibilies-end]
00068 [DocumentationStatus:Ready]
00069  */
00070 
00071 /* /////////////////////////////////////////////////////////////////////////
00072  * Includes
00073  */
00074 
00075 #ifndef STLSOFT_INCL_STLSOFT_H_STLSOFT
00076 # include <stlsoft/stlsoft.h>
00077 #endif /* !STLSOFT_INCL_STLSOFT_H_STLSOFT */
00078 #ifndef STLSOFT_INCL_STLSOFT_MEMORY_HPP_ALLOCATOR_FEATURES
00079 # include <stlsoft/memory/allocator_features.hpp>   // for STLSOFT_LF_ALLOCATOR_ALLOCATE_HAS_HINT
00080 #endif /* !STLSOFT_INCL_STLSOFT_MEMORY_HPP_ALLOCATOR_FEATURES */
00081 #ifndef STLSOFT_INCL_STLSOFT_MEMORY_HPP_ALLOCATOR_SELECTOR
00082 # include <stlsoft/memory/allocator_selector.hpp>
00083 #endif /* !STLSOFT_INCL_STLSOFT_MEMORY_HPP_ALLOCATOR_SELECTOR */
00084 #ifndef STLSOFT_INCL_STLSOFT_ALGORITHMS_HPP_POD
00085 # include <stlsoft/algorithms/pod.hpp>
00086 #endif /* !STLSOFT_INCL_STLSOFT_HPP_ALGORITHMS_POD */
00087 #ifndef STLSOFT_INCL_STLSOFT_UTIL_HPP_STD_SWAP
00088 # include <stlsoft/util/std_swap.hpp>
00089 #endif /* !STLSOFT_INCL_STLSOFT_UTIL_HPP_STD_SWAP */
00090 #ifdef _STLSOFT_AUTO_BUFFER_ALLOW_UDT
00091 # define _STLSOFT_AUTO_BUFFER_ALLOW_NON_POD
00092 # ifdef STLSOFT_CF_PRAGMA_MESSAGE_SUPPORT
00093 #  pragma message("_STLSOFT_AUTO_BUFFER_ALLOW_UDT is deprecated. Use _STLSOFT_AUTO_BUFFER_ALLOW_NON_POD instead")
00094 # endif /* STLSOFT_CF_PRAGMA_MESSAGE_SUPPORT */
00095 #endif /* _STLSOFT_AUTO_BUFFER_ALLOW_UDT */
00096 #ifndef STLSOFT_INCL_STLSOFT_UTIL_STD_HPP_ITERATOR_HELPER
00097 # include <stlsoft/util/std/iterator_helper.hpp>
00098 #endif /* !STLSOFT_INCL_STLSOFT_UTIL_STD_HPP_ITERATOR_HELPER */
00099 #ifndef _STLSOFT_AUTO_BUFFER_ALLOW_NON_POD
00100 # ifndef STLSOFT_INCL_STLSOFT_UTIL_HPP_CONSTRAINTS
00101 #  include <stlsoft/util/constraints.hpp>
00102 # endif /* !STLSOFT_INCL_STLSOFT_UTIL_HPP_CONSTRAINTS */
00103 #endif /* _STLSOFT_AUTO_BUFFER_ALLOW_NON_POD */
00104 #ifndef STLSOFT_INCL_STLSOFT_COLLECTIONS_UTIL_HPP_COLLECTIONS
00105 # include <stlsoft/collections/util/collections.hpp>
00106 #endif /* !STLSOFT_INCL_STLSOFT_COLLECTIONS_UTIL_HPP_COLLECTIONS */
00107 
00108 #ifdef STLSOFT_UNITTEST
00109 # include <algorithm>
00110 # if defined(STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT)
00111 #  include <numeric>
00112 # endif /* STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT */
00113 # include <stdio.h>
00114 #endif /* STLSOFT_UNITTEST */
00115 
00116 /* /////////////////////////////////////////////////////////////////////////
00117  * Namespace
00118  */
00119 
00120 #ifndef _STLSOFT_NO_NAMESPACE
00121 namespace stlsoft
00122 {
00123 #endif /* _STLSOFT_NO_NAMESPACE */
00124 
00125 /* /////////////////////////////////////////////////////////////////////////
00126  * Classes
00127  */
00128 
00129 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00130 # if !defined(STLSOFT_COMPILER_IS_BORLAND) && \
00131      !defined(STLSOFT_COMPILER_IS_DMC)
00132 
00133 struct auto_buffer_internal_default
00134 {
00135     enum { min_value        =   32      };
00136     enum { max_value        =   256     };
00137     enum { division_factor  =   2       };
00138 };
00139 
00140 template <ss_typename_param_k T>
00141 struct auto_buffer_internal_size_calculator
00142     : private auto_buffer_internal_default
00143 {
00144 private:
00145     // Stupid, stupid, stupid GCC requires them all to share the same
00146     // enum, which totally sucks. It whinges about comparisons between
00147     // enumerals (sic.) of different types. Thankfully it's irrelevant
00148     // because they're private
00149     enum
00150     {
00151             min_value        =   auto_buffer_internal_default::min_value
00152         ,   max_value        =   auto_buffer_internal_default::max_value
00153         ,   division_factor  =   auto_buffer_internal_default::division_factor
00154         ,   divided_value_   =   static_cast<int>((division_factor * max_value) / sizeof(T))
00155         ,   divided_value    =   (max_value < divided_value_)
00156                                     ?   max_value
00157                                     :   divided_value_
00158     };
00159 public:
00160     enum { value            =   1 == sizeof(T)
00161                                     ?   max_value
00162                                     :   divided_value < min_value
00163                                         ?   min_value
00164                                         :   divided_value           };
00165 };
00166 
00167 STLSOFT_TEMPLATE_SPECIALISATION
00168 struct auto_buffer_internal_size_calculator<ss_char_a_t>
00169 {
00170     enum { value    =   auto_buffer_internal_default::max_value     };
00171 };
00172 #  if defined(STLSOFT_CF_NATIVE_WCHAR_T_SUPPORT) || \
00173       defined(STLSOFT_CF_TYPEDEF_WCHAR_T_SUPPORT)
00174 STLSOFT_TEMPLATE_SPECIALISATION
00175 struct auto_buffer_internal_size_calculator<ss_char_w_t>
00176 {
00177     enum { value    =   auto_buffer_internal_default::max_value     };
00178 };
00179 #  endif /* STLSOFT_CF_NATIVE_WCHAR_T_SUPPORT */
00180 
00181 # endif /* compiler */
00182 #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
00183 
00184 
00185 
00186 // class auto_buffer
00187 //
00325 #if defined(STLSOFT_COMPILER_IS_MSVC) && \
00326     _MSC_VER < 1200
00327 # define STLSOFT_AUTO_BUFFER_USE_PRE_1_9_CHARACTERISTICS
00328 #endif /* compiler */
00329 
00330 
00331 #if defined(STLSOFT_AUTO_BUFFER_USE_PRE_1_9_CHARACTERISTICS)
00332 
00333 # ifdef STLSOFT_AUTO_BUFFER_NEW_FORM
00334 #  undef STLSOFT_AUTO_BUFFER_NEW_FORM
00335 # endif /* STLSOFT_AUTO_BUFFER_NEW_FORM */
00336 
00337  // //////////////////////////////////////////////
00338  // This is the pre-1.9 template parameter list
00339 
00340 template<   ss_typename_param_k T
00341 # ifdef STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_CLASS_ARGUMENT_SUPPORT
00342         ,   ss_typename_param_k A = ss_typename_type_def_k allocator_selector<T>::allocator_type
00343 # else /* ? STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_CLASS_ARGUMENT_SUPPORT */
00344         ,   ss_typename_param_k A
00345 # endif /* STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_CLASS_ARGUMENT_SUPPORT */
00346 # ifdef STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_FUNDAMENTAL_ARGUMENT_SUPPORT
00347 #  if defined(STLSOFT_COMPILER_IS_BORLAND)
00348         ,   ss_size_t           space   =   256
00349 #  elif defined(STLSOFT_COMPILER_IS_DMC)
00350         ,   ss_size_t           SPACE   =   256
00351 #  else /* ? compiler */
00352         ,   ss_size_t           SPACE   =   auto_buffer_internal_size_calculator<T>::value
00353 #  endif /* compiler */
00354 # else /* ? STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_CLASS_ARGUMENT_SUPPORT */
00355 #  if !defined(STLSOFT_COMPILER_IS_BORLAND)
00356         ,   ss_size_t           SPACE   /* =   auto_buffer_internal_size_calculator<T>::value */
00357 #  else /* ? compiler */
00358         ,   ss_size_t           space   /* =   256 */
00359 #  endif /* compiler */
00360 # endif /* STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_FUNDAMENTAL_ARGUMENT_SUPPORT */
00361         >
00362 
00363  // End of pre-1.9 template parameter list
00364  // //////////////////////////////////////////////
00365 
00366 #else /* ? STLSOFT_AUTO_BUFFER_USE_PRE_1_9_CHARACTERISTICS */
00367 
00368  // //////////////////////////////////////////////
00369  // This is the 1.9+ template parameter list
00370 
00371 # ifndef STLSOFT_AUTO_BUFFER_NEW_FORM
00372 #  define STLSOFT_AUTO_BUFFER_NEW_FORM
00373 # endif /* !STLSOFT_AUTO_BUFFER_NEW_FORM */
00374 
00375 template<   ss_typename_param_k T
00376 # ifdef STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_FUNDAMENTAL_ARGUMENT_SUPPORT
00377 #  if defined(STLSOFT_COMPILER_IS_BORLAND)
00378         ,   ss_size_t           space   =   256
00379 #  elif defined(STLSOFT_COMPILER_IS_DMC)
00380         ,   ss_size_t           SPACE   =   256
00381 #  else /* ? compiler */
00382         ,   ss_size_t           SPACE   =   auto_buffer_internal_size_calculator<T>::value
00383 #  endif /* compiler */
00384 # else /* ? STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_FUNDAMENTAL_ARGUMENT_SUPPORT */
00385 #  if !defined(STLSOFT_COMPILER_IS_BORLAND)
00386         ,   ss_size_t           SPACE   /* =   auto_buffer_internal_size_calculator<T>::value */
00387 #  else /* ? compiler */
00388         ,   ss_size_t           space   /* =   256 */
00389 #  endif /* compiler */
00390 # endif /* STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_FUNDAMENTAL_ARGUMENT_SUPPORT */
00391 # ifdef STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_CLASS_ARGUMENT_SUPPORT
00392         ,   ss_typename_param_k A = ss_typename_type_def_k allocator_selector<T>::allocator_type
00393 # else /* ? STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_CLASS_ARGUMENT_SUPPORT */
00394         ,   ss_typename_param_k A
00395 # endif /* STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_CLASS_ARGUMENT_SUPPORT */
00396         >
00397 
00398  // End of 1.9+ template parameter list
00399  // //////////////////////////////////////////////
00400 
00401 #endif /* STLSOFT_AUTO_BUFFER_USE_PRE_1_9_CHARACTERISTICS */
00402 
00403 class auto_buffer
00404 #if !defined(STLSOFT_CF_ALLOCATOR_BASE_EXPENSIVE)
00405     : protected A
00406     , public stl_collection_tag
00407 #else /* ? STLSOFT_CF_ALLOCATOR_BASE_EXPENSIVE */
00408     : public stl_collection_tag
00409 #endif /* !STLSOFT_CF_ALLOCATOR_BASE_EXPENSIVE */
00410 {
00413 public:
00415     typedef T                                                   value_type;
00417     typedef A                                                   allocator_type;
00418 #if !defined(STLSOFT_COMPILER_IS_BORLAND)
00419     enum
00420     {
00422         space = int(SPACE) // int() required for 64-bit compatibility
00423     };
00424 #endif /* compiler */
00426 #ifdef STLSOFT_AUTO_BUFFER_USE_PRE_1_9_CHARACTERISTICS
00427     typedef auto_buffer<T, A, space>                            class_type;
00428 #else /* ? STLSOFT_AUTO_BUFFER_USE_PRE_1_9_CHARACTERISTICS */
00429     typedef auto_buffer<T, space, A>                            class_type;
00430 #endif /* STLSOFT_AUTO_BUFFER_USE_PRE_1_9_CHARACTERISTICS */
00432     typedef ss_typename_type_k allocator_type::reference        reference;
00434     typedef ss_typename_type_k allocator_type::const_reference  const_reference;
00436     typedef ss_typename_type_k allocator_type::pointer          pointer;
00438     typedef ss_typename_type_k allocator_type::const_pointer    const_pointer;
00440     typedef ss_size_t                                           size_type;
00442     typedef ss_ptrdiff_t                                        difference_type;
00443 #if !defined(STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT)
00445     typedef value_type*                                         iterator;
00447     typedef value_type const*                                   const_iterator;
00448 #else /* ? !STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT */
00450     typedef
00451 # if !defined(STLSOFT_COMPILER_IS_BORLAND)
00452            ss_typename_type_k
00453 # endif /* compiler */
00454                        pointer_iterator <   value_type
00455                                         ,   pointer
00456                                         ,   reference
00457                                         >::type             iterator;
00459     typedef
00460 # if !defined(STLSOFT_COMPILER_IS_BORLAND)
00461          ss_typename_type_k
00462 # endif /* compiler */
00463                        pointer_iterator <   value_type const
00464                                         ,   const_pointer
00465                                         ,   const_reference
00466                                         >::type             const_iterator;
00467 
00469     typedef reverse_iterator_base       <   iterator
00470                                         ,   value_type
00471                                         ,   reference
00472                                         ,   pointer
00473                                         ,   difference_type
00474                                         >                   reverse_iterator;
00475 
00477     typedef const_reverse_iterator_base <   const_iterator
00478                                         ,   value_type const
00479                                         ,   const_reference
00480                                         ,   const_pointer
00481                                         ,   difference_type
00482                                         >                   const_reverse_iterator;
00483 #endif /* !STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT */
00485 
00488 private:
00489     pointer allocate_(size_type cItems, void const* hint)
00490     {
00491 #ifdef STLSOFT_LF_ALLOCATOR_ALLOCATE_HAS_HINT
00492 # ifdef STLSOFT_CF_STD_LIBRARY_IS_SUNPRO_RW
00493         return static_cast<pointer>(get_allocator().allocate(cItems, const_cast<void*>(hint)));
00494 # else /* ? STLSOFT_CF_STD_LIBRARY_IS_SUNPRO_RW */
00495         return get_allocator().allocate(cItems, hint);
00496 # endif /* STLSOFT_CF_STD_LIBRARY_IS_SUNPRO_RW */
00497 #else /* ? STLSOFT_LF_ALLOCATOR_ALLOCATE_HAS_HINT */
00498         STLSOFT_SUPPRESS_UNUSED(hint);
00499 
00500         return get_allocator().allocate(cItems);
00501 #endif /* STLSOFT_LF_ALLOCATOR_ALLOCATE_HAS_HINT */
00502     }
00503 
00504     pointer allocate_(size_type cItems)
00505     {
00506         return allocate_(cItems, NULL);
00507     }
00508 
00509     void deallocate_(pointer p, size_type cItems)
00510     {
00511         STLSOFT_ASSERT(NULL != p);
00512 
00513 #ifdef STLSOFT_LF_ALLOCATOR_DEALLOCATE_HAS_COUNT
00514         get_allocator().deallocate(p, cItems);
00515 #else /* ? STLSOFT_LF_ALLOCATOR_DEALLOCATE_HAS_COUNT */
00516         STLSOFT_SUPPRESS_UNUSED(cItems);
00517 
00518         get_allocator().deallocate(p);
00519 #endif /* STLSOFT_LF_ALLOCATOR_DEALLOCATE_HAS_COUNT */
00520     }
00521 
00522     pointer reallocate_(pointer p, size_type cItems, size_type cNewItems)
00523     {
00524         pointer new_p = allocate_(cNewItems, p);
00525 
00526         // This test is needed, since some allocators may not throw
00527         // bad_alloc
00528         if(NULL != new_p)
00529         {
00530             block_copy(new_p, p, cItems);
00531 
00532             deallocate_(p, cItems);
00533         }
00534 
00535         return new_p;
00536     }
00537 protected:
00538     static void block_copy(pointer dest, const_pointer src, size_type cItems)
00539     {
00540         pod_copy_n(dest, src, cItems);
00541     }
00542     static void block_set(pointer dest, size_type cItems, const_reference value)
00543     {
00544         pod_fill_n(dest, cItems, value);
00545     }
00547 
00550 public:
00561     ss_explicit_k auto_buffer(size_type cItems)
00562         : m_buffer((space < cItems) ? allocate_(cItems) : const_cast<pointer>(&m_internal[0]))
00563         , m_cItems((NULL != m_buffer) ? cItems : 0)
00564         , m_bExternal(space < cItems)
00565     {
00566         // Can't create one with an empty buffer. Though such is not legal
00567         // it is supported by some compilers, so we must ensure it cannot be
00568         // so
00569         STLSOFT_STATIC_ASSERT(0 != space);
00570 
00571         // These assertions ensure that the member ordering is not
00572         // changed, invalidating the initialisation logic of m_buffer and
00573         // m_cItems. The runtime assert is included for those compilers that
00574         // do not implement compile-time asserts.
00575 #ifdef STLSOFT_CF_USE_RAW_OFFSETOF_IN_STATIC_ASSERT
00576         STLSOFT_STATIC_ASSERT(STLSOFT_RAW_OFFSETOF(class_type, m_buffer) < STLSOFT_RAW_OFFSETOF(class_type, m_cItems));
00577 #endif /* STLSOFT_CF_USE_RAW_OFFSETOF_IN_STATIC_ASSERT */
00578         STLSOFT_MESSAGE_ASSERT("m_buffer must be before m_cItems in the auto_buffer definition", stlsoft_reinterpret_cast(ss_byte_t*, &m_buffer) < stlsoft_reinterpret_cast(ss_byte_t*, &m_cItems));
00579 
00580 #ifndef _STLSOFT_AUTO_BUFFER_ALLOW_NON_POD
00581         // Use the must_be_pod constraint to ensure that
00582         // no type is managed in auto_buffer which would result in
00583         // dangerous mismanagement of the lifetime of its instances.
00584         //
00585         // Preprocessor specification of _STLSOFT_AUTO_BUFFER_ALLOW_NON_POD
00586         // prevents this, but the natural rules of the language will
00587         // still prevent non POD types being placed in m_internal[].
00588         stlsoft_constraint_must_be_pod(value_type);
00589 #endif /* _STLSOFT_AUTO_BUFFER_ALLOW_NON_POD */
00590 
00591         STLSOFT_ASSERT(is_valid());
00592     }
00598 #if defined(STLSOFT_CF_EXCEPTION_SIGNATURE_SUPPORT)
00599     ~auto_buffer()
00600 #else /* ? STLSOFT_CF_EXCEPTION_SIGNATURE_SUPPORT */
00601     ~auto_buffer() stlsoft_throw_0()
00602 #endif /* STLSOFT_CF_EXCEPTION_SIGNATURE_SUPPORT */
00603     {
00604         STLSOFT_ASSERT(is_valid());
00605 
00606         if(is_in_external_array_())
00607         {
00608             STLSOFT_ASSERT(NULL != m_buffer);
00609             STLSOFT_ASSERT(m_bExternal);
00610             STLSOFT_ASSERT(&m_internal[0] != m_buffer);
00611 
00612             deallocate_(m_buffer, m_cItems);
00613         }
00614     }
00616 
00619 private:
00620     // Policy functions
00621     ss_bool_t   is_in_external_array_() const
00622     {
00623 #if defined(STLSOFT_AUTO_BUFFER_AGGRESSIVE_SHRINK)
00624         // Old implementation always uses internal array if size() <= internal_size()
00625         STLSOFT_ASSERT((space < m_cItems) == (m_buffer != &m_internal[0]));
00626 
00627         return space < m_cItems;
00628 #else /* ? STLSOFT_AUTO_BUFFER_AGGRESSIVE_SHRINK */
00629         // Old implementation always uses internal array if size() <= internal_size()
00630 //        STLSOFT_ASSERT((m_buffer != &m_internal[0]) || !(space < m_cItems));
00631         STLSOFT_ASSERT((m_buffer != &m_internal[0]) == m_bExternal);
00632         STLSOFT_ASSERT(m_bExternal || !(space < m_cItems));
00633 
00634 //        return m_buffer != &m_internal[0];
00635         return m_bExternal;
00636 #endif /* STLSOFT_AUTO_BUFFER_AGGRESSIVE_SHRINK */
00637     }
00638 
00639 public:
00661     ss_bool_t resize(size_type cItems)
00662     {
00663         STLSOFT_ASSERT(is_valid());
00664 
00665         // There are four changes possible:
00666         //
00667         // 1. Expansion within the internal buffer
00668         // 2. Contraction within the internal buffer
00669         // 3. Expansion from the internal buffer to an allocated buffer
00670         // 4. Contraction from an allocated buffer to the internal buffer
00671         //  4.a Where n is 0, or when STLSOFT_AUTO_BUFFER_AGGRESSIVE_SHRINK is defined
00672         //  4.b Where 0 < n <= internal_size() - this is new behaviour - we do not go to the internal array
00673         // 5. Expansion from the allocated buffer to another allocated buffer
00674         // 6. Contraction from the allocated buffer to another allocated buffer
00675 
00676         if(m_cItems < cItems)
00677         {
00678             // Expansion; cases 1, 3 & 5
00679 
00680             if(is_in_external_array_())
00681             {
00682                 // Current buffer is allocated: case 5
00683                 pointer new_buffer  =   reallocate_(m_buffer, m_cItems, cItems);
00684 
00685                 // Still test for NULL here, since some allocators will
00686                 // not throw bad_alloc.
00687                 if(NULL == new_buffer)
00688                 {
00689                     return false;
00690                 }
00691 
00692                 // Now repoint to the new buffer
00693                 m_buffer = new_buffer;
00694             }
00695             else
00696             {
00697                 // Expanding from internal buffer; cases 1 & 3
00698 
00699                 if(space < cItems)
00700                 {
00701                     // Expanding to allocated buffer; case 3
00702 
00703                     pointer new_buffer = allocate_(cItems);
00704 
00705                     // Still test for NULL here, since some allocators will
00706                     // not throw bad_alloc.
00707                     if(NULL == new_buffer)
00708                     {
00709                         return false;
00710                     }
00711 
00712                     block_copy(new_buffer, m_buffer, m_cItems);
00713 
00714                     m_buffer = new_buffer;
00715 
00716                     m_bExternal = true;
00717                 }
00718                 else
00719                 {
00720                     // Expanding to internal buffer; case 1
00721 
00722                     // Nothing to do
00723                     STLSOFT_ASSERT(!(space < cItems));
00724                 }
00725             }
00726         }
00727         else
00728         {
00729             // Contraction; cases 2, 4 & 6
00730 
00731             if(is_in_external_array_())
00732             {
00733                 // Current buffer is allocated: cases 4 & 6
00734 
00735                 if(space < cItems)
00736                 {
00737                     // Contracting within allocated buffer; case 6
00738 
00739                     // Nothing to do
00740                     STLSOFT_ASSERT(space < cItems);
00741                 }
00742 #if defined(STLSOFT_AUTO_BUFFER_AGGRESSIVE_SHRINK)
00743                 else
00744 #else /* ? STLSOFT_AUTO_BUFFER_AGGRESSIVE_SHRINK */
00745                 else if(0 == cItems)
00746 #endif /* STLSOFT_AUTO_BUFFER_AGGRESSIVE_SHRINK */
00747                 {
00748                     // Contracting back to internal; case 4
00749 
00750                     block_copy(const_cast<pointer>(&m_internal[0]), m_buffer, cItems);
00751 
00752                     deallocate_(m_buffer, m_cItems);
00753 
00754                     m_buffer = const_cast<pointer>(&m_internal[0]);
00755 
00756                     m_bExternal = false;
00757                 }
00758             }
00759             else
00760             {
00761                 // Current buffer is internal; case 2
00762 
00763                 // Nothing to do
00764                 STLSOFT_ASSERT(!(space < cItems));
00765             }
00766         }
00767 
00768         m_cItems = cItems;
00769 
00770         STLSOFT_ASSERT(is_valid());
00771 
00772         return true;
00773     }
00774 
00782     void swap(class_type& rhs) stlsoft_throw_0()
00783     {
00784         STLSOFT_ASSERT(is_valid());
00785 
00786         // Swap:
00787         //
00788         // 1. Allocator
00789         // 2. Member variables
00790 
00791         // 1. Allocator
00792 #if !defined(STLSOFT_CF_ALLOCATOR_BASE_EXPENSIVE)
00793         std_swap(static_cast<allocator_type&>(*this), static_cast<allocator_type&>(rhs));
00794 #endif /* !STLSOFT_CF_ALLOCATOR_BASE_EXPENSIVE */
00795 
00796         // 2. Member variables
00797         if( is_in_external_array_() &&
00798             rhs.is_in_external_array_())
00799         {
00800             // Both are allocated, so just swap them
00801             std_swap(m_buffer, rhs.m_buffer);
00802         }
00803         else if(is_in_external_array_())
00804         {
00805             // *this is allocated on the heap, rhs is using m_internal
00806 
00807             // 1. Copy the contents of rhs.m_internal to this->m_internal
00808             block_copy(&m_internal[0], &rhs.m_internal[0], rhs.m_cItems);
00809 
00810             // 2. Move m_buffer from *this to rhs
00811             rhs.m_buffer = m_buffer;
00812 
00813             // 3. Tell *this to use its internal buffer
00814             m_buffer = &m_internal[0];
00815         }
00816         else if(rhs.is_in_external_array_())
00817         {
00818             // This is a lazy cheat, but eminently effective.
00819             rhs.swap(*this);
00820 
00821             return;
00822         }
00823         else
00824         {
00825             // Both are using internal buffers, so we exchange the contents
00826             value_type  t[space];
00827 
00828             block_copy(&t[0],               &rhs.m_internal[0], rhs.m_cItems);
00829             block_copy(&rhs.m_internal[0],  &m_internal[0],     m_cItems);
00830             block_copy(&m_internal[0],      &t[0],              rhs.m_cItems);
00831         }
00832 
00833         std_swap(m_cItems,      rhs.m_cItems);
00834         std_swap(m_bExternal,   rhs.m_bExternal);
00835 
00836         STLSOFT_ASSERT(is_valid());
00837     }
00839 
00842 public:
00843     // Note: The following two const and non-const implicit conversion
00844     // operators are correctly implemented. However, GCC will pedantically
00845     // give a verbose warning describing its having selected one over the
00846     // other, and this is, in current versions of the compiler, not
00847     // suppressable. The warnings must, alas, simply be ignored.
00848 
00849 #ifdef _STLSOFT_AUTO_BUFFER_ALLOW_NON_CONST_CONVERSION_OPERATOR
00853     operator pointer ()
00854     {
00855         STLSOFT_ASSERT(is_valid());
00856 
00857         return m_buffer;
00858     }
00859 #else /* ? _STLSOFT_AUTO_BUFFER_ALLOW_NON_CONST_CONVERSION_OPERATOR */
00861     reference operator [](size_type index)
00862     {
00863         STLSOFT_MESSAGE_ASSERT("Index is out of bounds", index <= m_cItems);
00864 
00865         STLSOFT_ASSERT(is_valid());
00866 
00867         return m_buffer[index];
00868     }
00869 
00871     const_reference operator [](size_type index) const
00872     {
00873         STLSOFT_MESSAGE_ASSERT("Index is out of bounds", index <= m_cItems);
00874 
00875         STLSOFT_ASSERT(is_valid());
00876 
00877         return m_buffer[index];
00878     }
00879 #endif /* _STLSOFT_AUTO_BUFFER_ALLOW_NON_CONST_CONVERSION_OPERATOR */
00880 
00881 #ifdef _STLSOFT_AUTO_BUFFER_ALLOW_CONST_CONVERSION_OPERATOR
00883     operator const_pointer () const
00884     {
00885         STLSOFT_ASSERT(is_valid());
00886 
00887         return m_buffer;
00888     }
00889 #endif /* _STLSOFT_AUTO_BUFFER_ALLOW_CONST_CONVERSION_OPERATOR */
00891 
00894 public:
00896     pointer data()
00897     {
00898         STLSOFT_ASSERT(is_valid());
00899 
00900         return m_buffer;
00901     }
00903     const_pointer data() const
00904     {
00905         STLSOFT_ASSERT(is_valid());
00906 
00907         return m_buffer;
00908     }
00909 
00913     reference front()
00914     {
00915         STLSOFT_ASSERT(is_valid());
00916 
00917         STLSOFT_MESSAGE_ASSERT("Cannot call front() on an empty buffer!", !empty());
00918 
00919         return m_buffer[0];
00920     }
00924     reference back()
00925     {
00926         STLSOFT_ASSERT(is_valid());
00927 
00928         STLSOFT_MESSAGE_ASSERT("Cannot call back() on an empty buffer!", !empty());
00929 
00930         return m_buffer[size() - 1];
00931     }
00936     const_reference front() const
00937     {
00938         STLSOFT_ASSERT(is_valid());
00939 
00940         STLSOFT_MESSAGE_ASSERT("Cannot call front() on an empty buffer!", !empty());
00941 
00942         return m_buffer[0];
00943     }
00948     const_reference back() const
00949     {
00950         STLSOFT_ASSERT(is_valid());
00951 
00952         STLSOFT_MESSAGE_ASSERT("Cannot call back() on an empty buffer!", !empty());
00953 
00954         return m_buffer[size() - 1];
00955     }
00957 
00960 public:
00962     const_iterator begin() const
00963     {
00964         STLSOFT_ASSERT(is_valid());
00965 
00966         return m_buffer;
00967     }
00975     const_iterator end() const
00976     {
00977         STLSOFT_ASSERT(is_valid());
00978 
00979         return m_buffer + m_cItems;
00980     }
00981 
00983     iterator begin()
00984     {
00985         STLSOFT_ASSERT(is_valid());
00986 
00987         return m_buffer;
00988     }
00996     iterator end()
00997     {
00998         STLSOFT_ASSERT(is_valid());
00999 
01000         return m_buffer + m_cItems;
01001     }
01002 
01003 #if defined(STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT)
01007     const_reverse_iterator rbegin() const
01008     {
01009         STLSOFT_ASSERT(is_valid());
01010 
01011         return const_reverse_iterator(end());
01012     }
01016     const_reverse_iterator rend() const
01017     {
01018         STLSOFT_ASSERT(is_valid());
01019 
01020         return const_reverse_iterator(begin());
01021     }
01025     reverse_iterator  rbegin()
01026     {
01027         STLSOFT_ASSERT(is_valid());
01028 
01029         return reverse_iterator(end());
01030     }
01034     reverse_iterator  rend()
01035     {
01036         STLSOFT_ASSERT(is_valid());
01037 
01038         return reverse_iterator(begin());
01039     }
01040 #endif /* STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT */
01041 
01043 
01046 public:
01054     size_type size() const
01055     {
01056         STLSOFT_ASSERT(is_valid());
01057 
01058         return m_cItems;
01059     }
01060 
01062     static size_type internal_size()
01063     {
01064         return space;
01065     }
01066 
01071     ss_bool_t empty() const
01072     {
01073         STLSOFT_ASSERT(is_valid());
01074 
01075         return 0 == m_cItems;
01076     }
01077 
01078 #if defined(STLSOFT_CF_ALLOCATOR_BASE_EXPENSIVEx)
01081     static allocator_type &get_allocator()
01082     {
01083 # if !defined(STLSOFT_STRICT) && \
01084      defined(STLSOFT_COMPILER_IS_MSVC) && \
01085      _MSC_VER >= 1310
01086 #  pragma warning(push)
01087 #  pragma warning(disable : 4640)   /* "construction of local static object is not thread-safe" - since it is here! (As long as one uses a 'conformant' allocator) - maybe use a spin_mutex in future */
01088 # endif /* compiler */
01089 
01090         static allocator_type   s_allocator;
01091 
01092         return s_allocator;
01093 
01094 # if !defined(STLSOFT_STRICT) && \
01095      defined(STLSOFT_COMPILER_IS_MSVC) && \
01096      _MSC_VER >= 1310
01097 #  pragma warning(pop)
01098 # endif /* compiler */
01099     }
01100 #else /* ? STLSOFT_CF_ALLOCATOR_BASE_EXPENSIVE */
01103     allocator_type get_allocator() const
01104     {
01105 # if defined(STLSOFT_CF_ALLOCATOR_BASE_EXPENSIVE)
01106         return allocator_type();
01107 # else /* ? STLSOFT_CF_ALLOCATOR_BASE_EXPENSIVE */
01108         return *this;
01109 # endif /* STLSOFT_CF_ALLOCATOR_BASE_EXPENSIVE */
01110     }
01111 #endif /* STLSOFT_CF_ALLOCATOR_BASE_EXPENSIVE */
01113 
01116 private:
01117     ss_bool_t   is_valid() const
01118     {
01119         ss_bool_t   bRet    =   true;
01120 
01121 #if defined(STLSOFT_AUTO_BUFFER_AGGRESSIVE_SHRINK)
01122         if( space < m_cItems &&
01123             !m_bExternal)
01124         {
01125 # ifdef STLSOFT_UNITTEST
01126             printf("auto_buffer is in external domain, but think's it isn't\n");
01127 # endif /* STLSOFT_UNITTEST */
01128 
01129             bRet = false;
01130         }
01131         if( !(space < m_cItems) &&
01132             m_bExternal)
01133         {
01134 # ifdef STLSOFT_UNITTEST
01135             printf("auto_buffer is in internal domain, but think's it isn't\n");
01136 # endif /* STLSOFT_UNITTEST */
01137 
01138             bRet = false;
01139         }
01140 #else /* ? STLSOFT_AUTO_BUFFER_AGGRESSIVE_SHRINK */
01141 
01142         if( space < m_cItems &&
01143             !m_bExternal)
01144         {
01145 # ifdef STLSOFT_UNITTEST
01146             printf("auto_buffer is in external domain, but think's it isn't\n");
01147 # endif /* STLSOFT_UNITTEST */
01148 
01149             bRet = false;
01150         }
01151 #endif /* STLSOFT_AUTO_BUFFER_AGGRESSIVE_SHRINK */
01152 
01153         if(m_bExternal)
01154         {
01155             if(m_buffer == &m_internal[0])
01156             {
01157 #ifdef STLSOFT_UNITTEST
01158                 printf("auto_buffer is in external domain, but buffer refers to internal array\n");
01159 #endif /* STLSOFT_UNITTEST */
01160 
01161                 bRet = false;
01162             }
01163         }
01164         else
01165         {
01166             if(m_buffer != &m_internal[0])
01167             {
01168 #ifdef STLSOFT_UNITTEST
01169                 printf("auto_buffer is in internal domain, but buffer does not refer to internal array\n");
01170 #endif /* STLSOFT_UNITTEST */
01171 
01172                 bRet = false;
01173             }
01174         }
01175 
01176         return bRet;
01177     }
01179 
01182 private:
01183     pointer     m_buffer;           // Pointer to used buffer
01184     size_type   m_cItems;           // Number of items in buffer
01185     ss_bool_t   m_bExternal;        // This is required, since not allowed to compare m_buffer with &m_internal[0] - can't remember why; // NOTE: Check std
01186     value_type  m_internal[space];  // Internal storage
01188 
01189 // Not to be implemented
01190 private:
01191     auto_buffer(class_type const& rhs);
01192     auto_buffer const& operator =(class_type const& rhs);
01193 };
01194 
01195 
01196 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
01197 
01198 template<   ss_typename_param_k T
01199 # ifdef STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_CLASS_ARGUMENT_SUPPORT
01200         ,   ss_typename_param_k A = ss_typename_type_def_k allocator_selector<T>::allocator_type
01201 # else /* ? STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_CLASS_ARGUMENT_SUPPORT */
01202         ,   ss_typename_param_k A
01203 # endif /* STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_CLASS_ARGUMENT_SUPPORT */
01204 # ifdef STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_FUNDAMENTAL_ARGUMENT_SUPPORT
01205 #  if !defined(STLSOFT_COMPILER_IS_BORLAND) && \
01206       !defined(STLSOFT_COMPILER_IS_DMC)
01207         ,   ss_size_t           SPACE   =   auto_buffer_internal_size_calculator<T>::value
01208 #  else /* ? compiler */
01209         ,   ss_size_t           SPACE   =   256
01210 #  endif /* compiler */
01211 # else /* ? STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_FUNDAMENTAL_ARGUMENT_SUPPORT */
01212         ,   ss_size_t           SPACE /* = auto_buffer_internal_size_calculator<T>::value */
01213 # endif /* STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_FUNDAMENTAL_ARGUMENT_SUPPORT */
01214         >
01215 class auto_buffer_old
01216 # if defined(STLSOFT_AUTO_BUFFER_USE_PRE_1_9_CHARACTERISTICS)
01217     : public auto_buffer<T, A, SPACE>
01218 # else /* ? STLSOFT_AUTO_BUFFER_USE_PRE_1_9_CHARACTERISTICS */
01219     : public auto_buffer<T, SPACE, A>
01220 # endif /* STLSOFT_AUTO_BUFFER_USE_PRE_1_9_CHARACTERISTICS */
01221 {
01224 private:
01225 # if defined(STLSOFT_AUTO_BUFFER_USE_PRE_1_9_CHARACTERISTICS)
01226     typedef auto_buffer<T, A, SPACE>                                        parent_class_type;
01227 # else /* ? STLSOFT_AUTO_BUFFER_USE_PRE_1_9_CHARACTERISTICS */
01228     typedef auto_buffer<T, SPACE, A>                                        parent_class_type;
01229 # endif /* STLSOFT_AUTO_BUFFER_USE_PRE_1_9_CHARACTERISTICS */
01230     typedef auto_buffer_old<T, A, SPACE>                                    class_type;
01231 
01232 public:
01233     typedef ss_typename_type_k parent_class_type::value_type                value_type;
01234     typedef ss_typename_type_k parent_class_type::allocator_type            allocator_type;
01235     typedef ss_typename_type_k parent_class_type::reference                 reference;
01236     typedef ss_typename_type_k parent_class_type::const_reference           const_reference;
01237     typedef ss_typename_type_k parent_class_type::pointer                   pointer;
01238     typedef ss_typename_type_k parent_class_type::const_pointer             const_pointer;
01239     typedef ss_typename_type_k parent_class_type::size_type                 size_type;
01240     typedef ss_typename_type_k parent_class_type::difference_type           difference_type;
01241     typedef ss_typename_type_k parent_class_type::iterator                  iterator;
01242     typedef ss_typename_type_k parent_class_type::const_iterator            const_iterator;
01243 # if defined(STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT)
01244     typedef ss_typename_type_k parent_class_type::reverse_iterator          reverse_iterator;
01245     typedef ss_typename_type_k parent_class_type::const_reverse_iterator    const_reverse_iterator;
01246 # endif /* STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT */
01248 
01251 public:
01252     ss_explicit_k auto_buffer_old(size_type cItems)
01253         : parent_class_type(cItems)
01254     {}
01256 
01257 // Not to be implemented
01258 private:
01259     auto_buffer_old(class_type const& rhs);
01260     class_type& operator =(class_type const& rhs);
01261 };
01262 
01263 #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
01264 
01265 /* /////////////////////////////////////////////////////////////////////////
01266  * swapping
01267  */
01268 
01269 #if !defined(STLSOFT_COMPILER_IS_WATCOM)
01270 template<   ss_typename_param_k T
01271 # ifdef STLSOFT_AUTO_BUFFER_USE_PRE_1_9_CHARACTERISTICS
01272         ,   ss_typename_param_k A
01273         ,   ss_size_t           SPACE
01274 # else /* ? STLSOFT_AUTO_BUFFER_USE_PRE_1_9_CHARACTERISTICS */
01275         ,   ss_size_t           SPACE
01276         ,   ss_typename_param_k A
01277 # endif /* STLSOFT_AUTO_BUFFER_USE_PRE_1_9_CHARACTERISTICS */
01278         >
01279 # ifdef STLSOFT_AUTO_BUFFER_USE_PRE_1_9_CHARACTERISTICS
01280 inline void swap(auto_buffer<T, A, SPACE>& lhs, auto_buffer<T, A, SPACE>& rhs)
01281 # else /* ? STLSOFT_AUTO_BUFFER_USE_PRE_1_9_CHARACTERISTICS */
01282 inline void swap(auto_buffer<T, SPACE, A>& lhs, auto_buffer<T, SPACE, A>& rhs)
01283 # endif /* STLSOFT_AUTO_BUFFER_USE_PRE_1_9_CHARACTERISTICS */
01284 {
01285     lhs.swap(rhs);
01286 }
01287 #endif /* compiler */
01288 
01289 /* /////////////////////////////////////////////////////////////////////////
01290  * Shims
01291  */
01292 
01293 #ifndef STLSOFT_CF_TEMPLATE_SHIMS_NOT_SUPPORTED
01294 
01295 template<   ss_typename_param_k T
01296 # ifdef STLSOFT_AUTO_BUFFER_USE_PRE_1_9_CHARACTERISTICS
01297         ,   ss_typename_param_k A
01298         ,   ss_size_t           SPACE
01299 # else /* ? STLSOFT_AUTO_BUFFER_USE_PRE_1_9_CHARACTERISTICS */
01300         ,   ss_size_t           SPACE
01301         ,   ss_typename_param_k A
01302 # endif /* STLSOFT_AUTO_BUFFER_USE_PRE_1_9_CHARACTERISTICS */
01303         >
01304 # ifdef STLSOFT_AUTO_BUFFER_USE_PRE_1_9_CHARACTERISTICS
01305 inline ss_bool_t is_empty(auto_buffer<T, A, SPACE> const& b)
01306 # else /* ? STLSOFT_AUTO_BUFFER_USE_PRE_1_9_CHARACTERISTICS */
01307 inline ss_bool_t is_empty(auto_buffer<T, SPACE, A> const& b)
01308 # endif /* STLSOFT_AUTO_BUFFER_USE_PRE_1_9_CHARACTERISTICS */
01309 {
01310     return b.empty();
01311 }
01312 
01313 #endif /* !STLSOFT_CF_TEMPLATE_SHIMS_NOT_SUPPORTED */
01314 
01316 // Unit-testing
01317 
01318 #ifdef STLSOFT_UNITTEST
01319 # include "./unittest/auto_buffer_unittest_.h"
01320 #endif /* STLSOFT_UNITTEST */
01321 
01322 /* ////////////////////////////////////////////////////////////////////// */
01323 
01324 #ifndef _STLSOFT_NO_NAMESPACE
01325 } // namespace stlsoft
01326 #endif /* _STLSOFT_NO_NAMESPACE */
01327 
01328 /* In the special case of Intel behaving as VC++ 7.0 or earlier on Win32, we
01329  * illegally insert into the std namespace.
01330  */
01331 #if defined(STLSOFT_CF_std_NAMESPACE)
01332 # if ( ( defined(STLSOFT_COMPILER_IS_INTEL) && \
01333          defined(_MSC_VER))) && \
01334      _MSC_VER < 1310
01335 namespace std
01336 {
01337     template<   ss_typename_param_k         T
01338 #  ifdef STLSOFT_AUTO_BUFFER_USE_PRE_1_9_CHARACTERISTICS
01339             ,   ss_typename_param_k         A
01340             ,   stlsoft_ns_qual(ss_size_t)  SPACE
01341 #  else /* ? STLSOFT_AUTO_BUFFER_USE_PRE_1_9_CHARACTERISTICS */
01342             ,   stlsoft_ns_qual(ss_size_t)  SPACE
01343             ,   ss_typename_param_k         A
01344 #  endif /* STLSOFT_AUTO_BUFFER_USE_PRE_1_9_CHARACTERISTICS */
01345             >
01346 #  ifdef STLSOFT_AUTO_BUFFER_USE_PRE_1_9_CHARACTERISTICS
01347     inline void swap(stlsoft_ns_qual(auto_buffer)<T, A, SPACE>& lhs, stlsoft_ns_qual(auto_buffer)<T, A, SPACE>& rhs)
01348 #  else /* ? STLSOFT_AUTO_BUFFER_USE_PRE_1_9_CHARACTERISTICS */
01349     inline void swap(stlsoft_ns_qual(auto_buffer)<T, SPACE, A>& lhs, stlsoft_ns_qual(auto_buffer)<T, SPACE, A>& rhs)
01350 #  endif /* STLSOFT_AUTO_BUFFER_USE_PRE_1_9_CHARACTERISTICS */
01351     {
01352         lhs.swap(rhs);
01353     }
01354 } // namespace std
01355 # endif /* INTEL && _MSC_VER < 1310 */
01356 #endif /* STLSOFT_CF_std_NAMESPACE */
01357 
01358 /* ////////////////////////////////////////////////////////////////////// */
01359 
01360 #endif /* !STLSOFT_INCL_STLSOFT_MEMORY_HPP_AUTO_BUFFER */
01361 
01362 /* ///////////////////////////// end of file //////////////////////////// */

Generated on Fri Mar 5 06:31:39 2010 for STLSoft by  doxygen 1.5.4