STLSoft - ... Robust, Lightweight, Cross-platform, Template Software ... ATLSTL - Template Software for the Active Template Library COMSTL - The Standard Template Library meets the Component Object Model .netSTL - Standard Template Library meets the Microsoft.NET Common Language Runtime InetSTL - The Standard Template Library meets WinInet MFCSTL - Template Software for the Microsoft Foundation Classes UNIXSTL - Template Software for the UNIX Operating System WinSTL - where the Standard Template Library meets the Win32 API

Main Page   Modules   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

stlsoft_simple_string.h

Go to the documentation of this file.
00001 /* 
00002  * File:        stlsoft_simple_string.h (formerly MSString.h, ::SynesisDev)
00003  *
00004  * Purpose:     simple_string class.
00005  *
00006  * Created:     19th March 1993
00007  * Updated:     11th September 2004
00008  *
00009  * Home:        http://stlsoft.org/
00010  *
00011  * Copyright (c) 1993-2004, Matthew Wilson and Synesis Software
00012  * All rights reserved.
00013  *
00014  * Redistribution and use in source and binary forms, with or without
00015  * modification, are permitted provided that the following conditions are met:
00016  *
00017  * - Redistributions of source code must retain the above copyright notice, this
00018  *   list of conditions and the following disclaimer.
00019  * - Redistributions in binary form must reproduce the above copyright notice,
00020  *   this list of conditions and the following disclaimer in the documentation
00021  *   and/or other materials provided with the distribution.
00022  * - Neither the name(s) of Matthew Wilson and Synesis Software nor the names of
00023  *   any contributors may be used to endorse or promote products derived from
00024  *   this software without specific prior written permission.
00025  *
00026  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00027  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00028  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00029  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00030  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00031  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00032  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00033  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00034  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00035  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00036  * POSSIBILITY OF SUCH DAMAGE.
00037  *
00038  * 
00039 
00040 
00044 
00045 #ifndef STLSOFT_INCL_H_STLSOFT_SIMPLE_STRING
00046 #define STLSOFT_INCL_H_STLSOFT_SIMPLE_STRING
00047 
00048 #ifndef __STLSOFT_DOCUMENTATION_SKIP_SECTION
00049 # define STLSOFT_VER_H_STLSOFT_SIMPLE_STRING_MAJOR     2
00050 # define STLSOFT_VER_H_STLSOFT_SIMPLE_STRING_MINOR     0
00051 # define STLSOFT_VER_H_STLSOFT_SIMPLE_STRING_REVISION  1
00052 # define STLSOFT_VER_H_STLSOFT_SIMPLE_STRING_EDIT      152
00053 #endif /* !__STLSOFT_DOCUMENTATION_SKIP_SECTION */
00054 
00055 /* 
00056  * Includes
00057  */
00058 
00059 #ifndef STLSOFT_INCL_H_STLSOFT
00060 # include "stlsoft.h"                   // Include the STLSoft root header
00061 #endif /* !STLSOFT_INCL_H_STLSOFT */
00062 #ifndef STLSOFT_INCL_H_STLSOFT_NEW_ALLOCATOR
00063 # include "stlsoft_new_allocator.h"     // stlsoft::new_allocator
00064 #endif /* !STLSOFT_INCL_H_STLSOFT_NEW_ALLOCATOR */
00065 #ifndef STLSOFT_INCL_H_STLSOFT_CHAR_TRAITS
00066 # include "stlsoft_char_traits.h"      // stlsoft::char_traits
00067 #endif /* !STLSOFT_INCL_H_STLSOFT_CHAR_TRAITS */
00068 #ifndef STLSOFT_INCL_H_STLSOFT_ITERATOR
00069 # include "stlsoft_iterator.h"          // stlsoft iterator bases
00070 #endif /* !STLSOFT_INCL_H_STLSOFT_ITERATOR */
00071 #ifndef STLSOFT_INCL_H_STLSOFT_AUTO_BUFFER
00072 # include "stlsoft_auto_buffer.h"       // stlsoft::auto_buffer
00073 #endif /* !STLSOFT_INCL_H_STLSOFT_AUTO_BUFFER */
00074 #ifndef STLSOFT_INCL_H_STLSOFT_SIMPLE_ALGORITHMS
00075 # include "stlsoft_simple_algorithms.h" // stlsoft::for_each_set_value
00076 #endif /* !STLSOFT_INCL_H_STLSOFT_SIMPLE_ALGORITHMS */
00077 #ifndef STLSOFT_INCL_H_STLSOFT_SAP_CAST
00078 # include "stlsoft_sap_cast.h"          // stlsoft::sap_cast
00079 #endif /* !STLSOFT_INCL_H_STLSOFT_SAP_CAST */
00080 
00081 /* 
00082  *
00083  */
00084 
00085 #if defined(__STLSOFT_COMPILER_IS_MSVC) && \
00086     _MSC_VER < 1200
00087 # define STLSOFT_SIMPLE_STRING_ITERATOR_METHODS_INLINE
00088 #endif /* compiler */
00089 
00090 /* 
00091  * Namespace
00092  */
00093 
00094 #ifndef _STLSOFT_NO_NAMESPACE
00095 namespace stlsoft
00096 {
00097 #endif /* _STLSOFT_NO_NAMESPACE */
00098 
00099 /* 
00100 
00103 
00107 
00112 
00113 /* 
00114  * Classes
00115  */
00116 
00117 // class basic_simple_string
00123 template<   ss_typename_param_k C
00124 #ifdef __STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_CLASS_ARGUMENT_SUPPORT
00125         ,   ss_typename_param_k T = stlsoft_char_traits<C>
00126         ,   ss_typename_param_k A = new_allocator<C>
00127 #else
00128         ,   ss_typename_param_k T /* = stlsoft_char_traits<C> */
00129         ,   ss_typename_param_k A /* = new_allocator<C> */
00130 #endif /* __STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_CLASS_ARGUMENT_SUPPORT */
00131         >
00132 class basic_simple_string
00133 {
00134 public:
00136     typedef C                               value_type;
00138     typedef T                               traits_type;
00140     typedef A                               allocator_type;
00142     typedef basic_simple_string<C, T, A>    class_type;
00144     typedef value_type                      char_type;
00146     typedef value_type                      *pointer;
00148     typedef value_type const                *const_pointer;
00150     typedef value_type                      &reference;
00152     typedef value_type const                &const_reference;
00154     typedef ss_size_t                       size_type;
00156     typedef ss_ptrdiff_t                    difference_type;
00157 
00159     typedef
00160 #if !defined(__STLSOFT_COMPILER_IS_BORLAND)
00161            ss_typename_type_k
00162 #endif /* __STLSOFT_COMPILER_IS_BORLAND */
00163                        pointer_iterator <   value_type
00164                                         ,   pointer
00165                                         ,   reference
00166                                         >::iterator_type    iterator;
00168     typedef
00169 #if !defined(__STLSOFT_COMPILER_IS_BORLAND)
00170          ss_typename_type_k
00171 #endif /* __STLSOFT_COMPILER_IS_BORLAND */
00172                        pointer_iterator <   value_type const
00173                                         ,   const_pointer
00174                                         ,   const_reference
00175                                         >::iterator_type    const_iterator;
00176 
00177 #if defined(__STLSOFT_CF_BIDIRECTIONAL_ITERATOR_SUPPORT)
00178 
00179     typedef reverse_iterator_base       <   iterator
00180                                         ,   value_type
00181                                         ,   reference
00182                                         ,   pointer
00183                                         ,   difference_type
00184                                         >                   reverse_iterator;
00185 
00187     typedef const_reverse_iterator_base <   const_iterator
00188                                         ,   value_type const
00189                                         ,   const_reference
00190                                         ,   const_pointer
00191                                         ,   difference_type
00192                                         >                   const_reverse_iterator;
00193 #endif /* __STLSOFT_CF_BIDIRECTIONAL_ITERATOR_SUPPORT */
00194 
00196 
00197 public:
00199     basic_simple_string();
00201     basic_simple_string(class_type const &rhs);
00203     basic_simple_string(class_type const &s, size_type pos);
00205     basic_simple_string(class_type const &s, size_type pos, size_type cch);
00207     basic_simple_string(char_type const *s); // Not, not explicit. Sigh
00209     basic_simple_string(char_type const *s, size_type cch);
00211     basic_simple_string(size_type cch, char_type ch);
00213 #if !defined(__STLSOFT_CF_MEMBER_TEMPLATE_RANGE_METHOD_SUPPORT)
00214     basic_simple_string(char_type const *first, char_type const *last);
00215 #else
00216     template <ss_typename_param_k II>
00217     basic_simple_string(II first, II last)
00218         : m_buffer(NULL)
00219     {
00220         assign(first, last);
00221     }
00222 #endif /* __STLSOFT_CF_MEMBER_TEMPLATE_RANGE_METHOD_SUPPORT */
00223 
00224     ~basic_simple_string();
00226 
00228 
00229 public:
00231     class_type &assign(char_type const *s);
00233     class_type &assign(char_type const *s, size_type cch);
00235     class_type &assign(class_type const &str, size_type pos, size_type cch);
00237     class_type &assign(class_type const &str);
00239     class_type &assign(size_type cch, char_type ch);
00241 #if !defined(__STLSOFT_CF_MEMBER_TEMPLATE_RANGE_METHOD_SUPPORT)
00242     class_type &assign(const_iterator first, const_iterator last);
00243 #else
00244     template <ss_typename_param_k II>
00245     class_type &assign(II first, II last)
00246     {
00247 # if defined(__STLSOFT_COMPILER_IS_GCC) && \
00248      __GNUC__ < 3
00249         typedef ss_typename_type_k std::iterator_traits<II> traits_t;
00250 
00251         return assign_(first, last, traits_t::iterator_category());
00252 # else
00253         return assign_(first, last, stlsoft_iterator_query_category(II, first));
00254 # endif /* GCC < 3 */
00255     }
00256 #endif /* __STLSOFT_CF_MEMBER_TEMPLATE_RANGE_METHOD_SUPPORT */
00257 
00259     class_type const &operator =(class_type const &rhs);
00261     class_type const &operator =(char_type const *s);
00263     class_type const &operator =(char_type ch);
00265 
00267 
00268 public:
00270     class_type &append(char_type const *s);
00272     class_type &append(char_type const *s, size_type cch);
00274     class_type &append(class_type const &str, size_type pos, size_type cch);
00276     class_type &append(class_type const &str);
00278     class_type &append(size_type cch, char_type ch);
00280 #if !defined(__STLSOFT_CF_MEMBER_TEMPLATE_RANGE_METHOD_SUPPORT)
00281     class_type &append(const_iterator first, const_iterator last);
00282 #else
00283     template <ss_typename_param_k II>
00284     class_type &append(II first, II last)
00285     {
00286 # if defined(__STLSOFT_COMPILER_IS_GCC) && \
00287      __GNUC__ < 3
00288         typedef ss_typename_type_k std::iterator_traits<II> traits_t;
00289 
00290         return append_(first, last, traits_t::iterator_category());
00291 # else
00292         return append_(first, last, stlsoft_iterator_query_category(II, first));
00293 # endif /* GCC < 3 */
00294     }
00295 #endif /* __STLSOFT_CF_MEMBER_TEMPLATE_RANGE_METHOD_SUPPORT */
00296 
00298     class_type &operator +=(char_type ch);
00300     class_type &operator +=(char_type const *s);
00302     class_type &operator +=(class_type const &rhs);
00303 
00305     void push_back(char_type ch);
00307 
00309 
00310 public:
00312     void reserve(size_type cch);
00314     void swap(class_type &other);
00315 
00320     void resize(size_type cch, value_type ch = value_type());
00321 
00323     void clear();
00325 
00327 
00328 public:
00330     size_type size() const;
00332     size_type max_size() const;
00334     size_type length() const;
00336     size_type capacity() const;
00338     ss_bool_t empty() const;
00340 
00342 
00343 public:
00345     ss_sint_t compare(size_type pos, size_type cch, value_type const *s, size_type cchRhs) const;
00347     ss_sint_t compare(size_type pos, size_type cch, value_type const *s) const;
00349     ss_sint_t compare(value_type const *s) const;
00351     ss_sint_t compare(size_type pos, size_type cch, class_type const &rhs, size_type posRhs, size_type cchRhs) const;
00353     ss_sint_t compare(size_type pos, size_type cch, class_type const &rhs) const;
00355     ss_sint_t compare(class_type const &rhs) const;
00357 
00359 
00360 public:
00362     reference       operator [](size_type index);
00364     const_reference operator [](size_type index) const;
00365 
00367     value_type const    *c_str() const;
00369     value_type const    *data() const;
00370 
00374     reference               front();
00378     reference               back();
00382     const_reference         front() const;
00386     const_reference         back() const;
00387 
00389     size_type copy(value_type *dest, size_type cch, size_type pos = 0) const;
00391 
00393 
00394 public:
00398 #ifdef STLSOFT_SIMPLE_STRING_ITERATOR_METHODS_INLINE
00399     const_iterator          begin() const
00400     {
00401         return const_cast<class_type*>(this)->begin_();
00402     }
00403 #else /* ? STLSOFT_SIMPLE_STRING_ITERATOR_METHODS_INLINE */
00404     const_iterator          begin() const;
00405 #endif /* STLSOFT_SIMPLE_STRING_ITERATOR_METHODS_INLINE */
00409 #ifdef STLSOFT_SIMPLE_STRING_ITERATOR_METHODS_INLINE
00410     const_iterator          end() const
00411     {
00412         return const_cast<class_type*>(this)->end_();
00413     }
00414 #else /* ? STLSOFT_SIMPLE_STRING_ITERATOR_METHODS_INLINE */
00415     const_iterator          end() const;
00416 #endif /* STLSOFT_SIMPLE_STRING_ITERATOR_METHODS_INLINE */
00420     iterator                begin();
00424     iterator                end();
00425 
00426 #if defined(__STLSOFT_CF_BIDIRECTIONAL_ITERATOR_SUPPORT)
00430     const_reverse_iterator  rbegin() const;
00434     const_reverse_iterator  rend() const;
00438     reverse_iterator        rbegin();
00442     reverse_iterator        rend();
00443 #endif /* __STLSOFT_CF_BIDIRECTIONAL_ITERATOR_SUPPORT */
00444 
00445 
00447 
00448 private:
00449     enum { alloc_quantum = 31 };    // Must be (2^n - 1)
00450 
00451     struct string_buffer
00452     {
00453         size_type   capacity;       // The number of char places in the buffer
00454         size_type   length;         // The number of chars in the string (<= capacity)
00455         char_type   contents[1];    // The first element in the array
00456     };
00457 
00458 #ifdef STLSOFT_SIMPLE_STRING_NO_PTR_ADJUST
00459     typedef string_buffer       *member_pointer;
00460     typedef string_buffer const *member_const_pointer;
00461 #else /* ? STLSOFT_SIMPLE_STRING_NO_PTR_ADJUST */
00462     typedef char_type           *member_pointer;
00463     typedef char_type const     *member_const_pointer;
00464 #endif /* STLSOFT_SIMPLE_STRING_NO_PTR_ADJUST */
00465 
00466     // Conversion between member pointer and character pointer
00467     static char_type            *char_pointer_from_member_pointer_(member_pointer );
00468 
00469     // Conversion between pointer and buffer
00470     static string_buffer        *string_buffer_from_member_pointer_(member_pointer );
00471     static string_buffer const  *string_buffer_from_member_pointer_(member_const_pointer );
00472 
00473     // Conversion between buffer and pointer
00474     static member_pointer       member_pointer_from_string_buffer_(string_buffer *);
00475 
00476     // Creating buffer
00477     static member_pointer       alloc_buffer_(char_type const *s, size_type capacity, size_type length);
00478     static member_pointer       alloc_buffer_(char_type const *s, size_type cch);
00479     static member_pointer       alloc_buffer_(char_type const *s);
00480 
00481     // Copying a buffer
00482     static member_pointer       copy_buffer_(member_pointer );
00483 
00484     // Destroying buffer
00485     static void                 destroy_buffer_(string_buffer *);
00486     static void                 destroy_buffer_(char_type *);
00487 
00488     // Iteration
00489     pointer                     begin_();
00490     pointer                     end_();
00491 
00492     // Invariance
00493     ss_bool_t is_valid_() const;
00494 
00495     // Empty string
00496     static char_type const *empty_string_();
00497 
00498     // Comparison
00499     static ss_sint_t compare_(char_type const *lhs, size_type lhs_len, char_type const *rhs, size_type rhs_len);
00500 
00501     // Assignment
00502 #if defined(__STLSOFT_CF_MEMBER_TEMPLATE_RANGE_METHOD_SUPPORT)
00503     template <ss_typename_param_k II>
00504     class_type &assign_(II first, II last, stlsoft_ns_qual_std(input_iterator_tag))
00505     {
00506         stlsoft_ns_qual_std(copy)(first, last, stlsoft_ns_qual_std(back_inserter)(*this));
00507 
00508         stlsoft_assert(is_valid_());
00509         return *this;
00510     }
00511     template <ss_typename_param_k II>
00512     class_type &assign_(II first, II last, stlsoft_ns_qual_std(forward_iterator_tag))
00513     {
00514         typedef auto_buffer<char_type, allocator_type>  buffer_t;
00515 
00516         buffer_t    buffer(stlsoft_ns_qual_std(distance)(first, last));
00517 
00518         stlsoft_ns_qual_std(copy)(first, last, buffer.begin());
00519         assign(buffer, buffer.size());
00520 
00521         stlsoft_assert(is_valid_());
00522         return *this;
00523     }
00524 #endif /* __STLSOFT_CF_MEMBER_TEMPLATE_RANGE_METHOD_SUPPORT */
00525 
00526     // Appending
00527 #if defined(__STLSOFT_CF_MEMBER_TEMPLATE_RANGE_METHOD_SUPPORT)
00528     template <ss_typename_param_k II>
00529     class_type &append_(II first, II last, stlsoft_ns_qual_std(input_iterator_tag))
00530     {
00531         stlsoft_ns_qual_std(copy)(first, last, stlsoft_ns_qual_std(back_inserter)(*this));
00532 
00533         stlsoft_assert(is_valid_());
00534         return *this;
00535     }
00536     template <ss_typename_param_k II>
00537     class_type &append_(II first, II last, stlsoft_ns_qual_std(forward_iterator_tag))
00538     {
00539         typedef auto_buffer<char_type, allocator_type>  buffer_t;
00540 
00541         buffer_t    buffer(stlsoft_ns_qual_std(distance)(first, last));
00542 
00543         stlsoft_ns_qual_std(copy)(first, last, buffer.begin());
00544         append(buffer, buffer.size());
00545 
00546         stlsoft_assert(is_valid_());
00547         return *this;
00548     }
00549 #endif /* __STLSOFT_CF_MEMBER_TEMPLATE_RANGE_METHOD_SUPPORT */
00550 
00551 
00553 
00554 private:
00555     member_pointer  m_buffer;
00557 };
00558 
00559 /* 
00560  * Operators
00561  */
00562 
00563 #ifndef __STLSOFT_DOCUMENTATION_SKIP_SECTION
00564 
00565 // operator ==
00566 
00567 template<   ss_typename_param_k C
00568         ,   ss_typename_param_k T
00569         ,   ss_typename_param_k A
00570         >
00571 inline ss_bool_t operator ==(basic_simple_string<C, T, A> const &lhs, basic_simple_string<C, T, A> const &rhs)
00572 {
00573     return 0 == lhs.compare(rhs);
00574 }
00575 
00576 template<   ss_typename_param_k C
00577         ,   ss_typename_param_k T
00578         ,   ss_typename_param_k A
00579         >
00580 #ifdef __STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT
00581 inline ss_bool_t operator ==(basic_simple_string<C, T, A> const &lhs, ss_typename_type_k basic_simple_string<C, T, A>::char_type const *rhs)
00582 #else
00583 inline ss_bool_t operator ==(basic_simple_string<C, T, A> const &lhs, C const *rhs)
00584 #endif /* __STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT */
00585 {
00586     return 0 == lhs.compare(rhs);
00587 }
00588 
00589 template<   ss_typename_param_k C
00590         ,   ss_typename_param_k T
00591         ,   ss_typename_param_k A
00592         >
00593 #ifdef __STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT
00594 inline ss_bool_t operator ==(ss_typename_type_k basic_simple_string<C, T, A>::char_type const *lhs, basic_simple_string<C, T, A> const &rhs)
00595 #else
00596 inline ss_bool_t operator ==(C *lhs, basic_simple_string<C, T, A> const &rhs)
00597 #endif /* __STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT */
00598 {
00599     return 0 == rhs.compare(lhs);
00600 }
00601 
00602 // operator !=
00603 
00604 template<   ss_typename_param_k C
00605         ,   ss_typename_param_k T
00606         ,   ss_typename_param_k A
00607         >
00608 inline ss_bool_t operator !=(basic_simple_string<C, T, A> const &lhs, basic_simple_string<C, T, A> const &rhs)
00609 {
00610     return 0 != lhs.compare(rhs);
00611 }
00612 template<   ss_typename_param_k C
00613         ,   ss_typename_param_k T
00614         ,   ss_typename_param_k A
00615         >
00616 #ifdef __STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT
00617 inline ss_bool_t operator !=(basic_simple_string<C, T, A> const &lhs, ss_typename_type_k basic_simple_string<C, T, A>::char_type const *rhs)
00618 #else
00619 inline ss_bool_t operator !=(basic_simple_string<C, T, A> const &lhs, C const *rhs)
00620 #endif /* __STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT */
00621 {
00622     return 0 != lhs.compare(rhs);
00623 }
00624 template<   ss_typename_param_k C
00625         ,   ss_typename_param_k T
00626         ,   ss_typename_param_k A
00627         >
00628 #ifdef __STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT
00629 inline ss_bool_t operator !=(ss_typename_type_k basic_simple_string<C, T, A>::char_type const *lhs, basic_simple_string<C, T, A> const &rhs)
00630 #else
00631 inline ss_bool_t operator !=(C const *lhs, basic_simple_string<C, T, A> const &rhs)
00632 #endif /* __STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT */
00633 {
00634     return 0 != rhs.compare(lhs);
00635 }
00636 
00637 // operator <
00638 
00639 template<   ss_typename_param_k C
00640         ,   ss_typename_param_k T
00641         ,   ss_typename_param_k A
00642         >
00643 inline ss_bool_t operator <(basic_simple_string<C, T, A> const &lhs, basic_simple_string<C, T, A> const &rhs)
00644 {
00645     return lhs.compare(rhs) < 0;
00646 }
00647 
00648 template<   ss_typename_param_k C
00649         ,   ss_typename_param_k T
00650         ,   ss_typename_param_k A
00651         >
00652 #ifdef __STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT
00653 inline ss_bool_t operator <(basic_simple_string<C, T, A> const &lhs, ss_typename_type_k basic_simple_string<C, T, A>::char_type const *rhs)
00654 #else
00655 inline ss_bool_t operator <(basic_simple_string<C, T, A> const &lhs, C const *rhs)
00656 #endif /* __STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT */
00657 {
00658     return lhs.compare(rhs) < 0;
00659 }
00660 
00661 template<   ss_typename_param_k C
00662         ,   ss_typename_param_k T
00663         ,   ss_typename_param_k A
00664         >
00665 #ifdef __STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT
00666 inline ss_bool_t operator <(ss_typename_type_k basic_simple_string<C, T, A>::char_type const *lhs, basic_simple_string<C, T, A> const &rhs)
00667 #else
00668 inline ss_bool_t operator <(C const *lhs, basic_simple_string<C, T, A> const &rhs)
00669 #endif /* __STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT */
00670 {
00671     return rhs.compare(lhs) > 0;
00672 }
00673 
00674 // operator <=
00675 
00676 template<   ss_typename_param_k C
00677         ,   ss_typename_param_k T
00678         ,   ss_typename_param_k A
00679         >
00680 inline ss_bool_t operator <=(basic_simple_string<C, T, A> const &lhs, basic_simple_string<C, T, A> const &rhs)
00681 {
00682     return lhs.compare(rhs) <= 0;
00683 }
00684 template<   ss_typename_param_k C
00685         ,   ss_typename_param_k T
00686         ,   ss_typename_param_k A
00687         >
00688 #ifdef __STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT
00689 inline ss_bool_t operator <=(basic_simple_string<C, T, A> const &lhs, ss_typename_type_k basic_simple_string<C, T, A>::char_type const *rhs)
00690 #else
00691 inline ss_bool_t operator <=(basic_simple_string<C, T, A> const &lhs, C const *rhs)
00692 #endif /* __STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT */
00693 {
00694     return lhs.compare(rhs) <= 0;
00695 }
00696 template<   ss_typename_param_k C
00697         ,   ss_typename_param_k T
00698         ,   ss_typename_param_k A
00699         >
00700 #ifdef __STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT
00701 inline ss_bool_t operator <=(ss_typename_type_k basic_simple_string<C, T, A>::char_type const *lhs, basic_simple_string<C, T, A> const &rhs)
00702 #else
00703 inline ss_bool_t operator <=(C const *lhs, basic_simple_string<C, T, A> const &rhs)
00704 #endif /* __STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT */
00705 {
00706     return rhs.compare(lhs) >= 0;
00707 }
00708 
00709 // operator >
00710 
00711 template<   ss_typename_param_k C
00712         ,   ss_typename_param_k T
00713         ,   ss_typename_param_k A
00714         >
00715 inline ss_bool_t operator >(basic_simple_string<C, T, A> const &lhs, basic_simple_string<C, T, A> const &rhs)
00716 {
00717     return lhs.compare(rhs) > 0;
00718 }
00719 template<   ss_typename_param_k C
00720         ,   ss_typename_param_k T
00721         ,   ss_typename_param_k A
00722         >
00723 #ifdef __STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT
00724 inline ss_bool_t operator >(basic_simple_string<C, T, A> const &lhs, ss_typename_type_k basic_simple_string<C, T, A>::char_type const *rhs)
00725 #else
00726 inline ss_bool_t operator >(basic_simple_string<C, T, A> const &lhs, C const *rhs)
00727 #endif /* __STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT */
00728 {
00729     return lhs.compare(rhs) > 0;
00730 }
00731 template<   ss_typename_param_k C
00732         ,   ss_typename_param_k T
00733         ,   ss_typename_param_k A
00734         >
00735 #ifdef __STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT
00736 inline ss_bool_t operator >(ss_typename_type_k basic_simple_string<C, T, A>::char_type const *lhs, basic_simple_string<C, T, A> const &rhs)
00737 #else
00738 inline ss_bool_t operator >(C const *lhs, basic_simple_string<C, T, A> const &rhs)
00739 #endif /* __STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT */
00740 {
00741     return rhs.compare(lhs) < 0;
00742 }
00743 
00744 // operator >=
00745 
00746 template<   ss_typename_param_k C
00747         ,   ss_typename_param_k T
00748         ,   ss_typename_param_k A
00749         >
00750 inline ss_bool_t operator >=(basic_simple_string<C, T, A> const &lhs, basic_simple_string<C, T, A> const &rhs)
00751 {
00752     return lhs.compare(rhs) >= 0;
00753 }
00754 template<   ss_typename_param_k C
00755         ,   ss_typename_param_k T
00756         ,   ss_typename_param_k A
00757         >
00758 #ifdef __STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT
00759 inline ss_bool_t operator >=(basic_simple_string<C, T, A> const &lhs, ss_typename_type_k basic_simple_string<C, T, A>::char_type const *rhs)
00760 #else
00761 inline ss_bool_t operator >=(basic_simple_string<C, T, A> const &lhs, C const *rhs)
00762 #endif /* __STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT */
00763 {
00764     return lhs.compare(rhs) >= 0;
00765 }
00766 template<   ss_typename_param_k C
00767         ,   ss_typename_param_k T
00768         ,   ss_typename_param_k A
00769         >
00770 #ifdef __STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT
00771 inline ss_bool_t operator >=(ss_typename_type_k basic_simple_string<C, T, A>::char_type const *lhs, basic_simple_string<C, T, A> const &rhs)
00772 #else
00773 inline ss_bool_t operator >=(C const *lhs, basic_simple_string<C, T, A> const &rhs)
00774 #endif /* __STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT */
00775 {
00776     return rhs.compare(lhs) <= 0;
00777 }
00778 
00779 // operator +
00780 
00781 template<   ss_typename_param_k C
00782         ,   ss_typename_param_k T
00783         ,   ss_typename_param_k A
00784         >
00785 inline basic_simple_string<C, T, A> operator +(basic_simple_string<C, T, A> const &lhs, basic_simple_string<C, T, A> const &rhs)
00786 {
00787     return basic_simple_string<C, T, A>(lhs) += rhs;
00788 }
00789 template<   ss_typename_param_k C
00790         ,   ss_typename_param_k T
00791         ,   ss_typename_param_k A
00792         >
00793 #ifdef __STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT
00794 inline basic_simple_string<C, T, A> operator +(basic_simple_string<C, T, A> const &lhs, ss_typename_type_k basic_simple_string<C, T, A>::char_type const *rhs)
00795 #else
00796 inline basic_simple_string<C, T, A> operator +(basic_simple_string<C, T, A> const &lhs, C const *rhs)
00797 #endif /* __STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT */
00798 {
00799     return basic_simple_string<C, T, A>(lhs) += rhs;
00800 }
00801 template<   ss_typename_param_k C
00802         ,   ss_typename_param_k T
00803         ,   ss_typename_param_k A
00804         >
00805 #ifdef __STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT
00806 inline basic_simple_string<C, T, A> operator +(ss_typename_type_k basic_simple_string<C, T, A>::char_type const *lhs, basic_simple_string<C, T, A> const &rhs)
00807 #else
00808 inline basic_simple_string<C, T, A> operator +(C const *lhs, basic_simple_string<C, T, A> const &rhs)
00809 #endif /* __STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT */
00810 {
00811     return basic_simple_string<C, T, A>(lhs) += rhs;
00812 }
00813 template<   ss_typename_param_k C
00814         ,   ss_typename_param_k T
00815         ,   ss_typename_param_k A
00816         >
00817 #ifdef __STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT
00818 inline basic_simple_string<C, T, A> operator +(basic_simple_string<C, T, A> const &lhs, ss_typename_type_k basic_simple_string<C, T, A>::char_type rhs)
00819 #else
00820 inline basic_simple_string<C, T, A> operator +(basic_simple_string<C, T, A> const &lhs, C rhs)
00821 #endif /* __STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT */
00822 {
00823     return basic_simple_string<C, T, A>(lhs) += rhs;
00824 }
00825 template<   ss_typename_param_k C
00826         ,   ss_typename_param_k T
00827         ,   ss_typename_param_k A
00828         >
00829 #ifdef __STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT
00830 inline basic_simple_string<C, T, A> operator +(ss_typename_type_k basic_simple_string<C, T, A>::char_type lhs, basic_simple_string<C, T, A> const &rhs)
00831 #else
00832 inline basic_simple_string<C, T, A> operator +(C lhs, basic_simple_string<C, T, A> const &rhs)
00833 #endif /* __STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT */
00834 {
00835     return basic_simple_string<C, T, A>(1, lhs) += rhs;
00836 }
00837 
00838 #endif /* !__STLSOFT_DOCUMENTATION_SKIP_SECTION */
00839 
00840 /* 
00841  * Shims
00842  */
00843 
00844 /* c_str_ptr_null */
00845 
00847 template<   ss_typename_param_k C
00848         ,   ss_typename_param_k T
00849         ,   ss_typename_param_k A
00850         >
00851 inline C const *c_str_ptr_null(basic_simple_string<C, T, A> const &s)
00852 {
00853     return (0 == s.length()) ? NULL : s.c_str();
00854 }
00855 
00856 /* c_str_ptr */
00857 
00859 template<   ss_typename_param_k C
00860         ,   ss_typename_param_k T
00861         ,   ss_typename_param_k A
00862         >
00863 inline C const *c_str_ptr(basic_simple_string<C, T, A> const &s)
00864 {
00865     return s.c_str();
00866 }
00867 
00869 template<   ss_typename_param_k T
00870         ,   ss_typename_param_k A
00871         >
00872 inline ss_char_a_t const *c_str_ptr_a(basic_simple_string<ss_char_a_t, T, A> const &s)
00873 {
00874     return s.c_str();
00875 }
00876 
00878 template<   ss_typename_param_k T
00879         ,   ss_typename_param_k A
00880         >
00881 inline ss_char_w_t const *c_str_ptr_w(basic_simple_string<ss_char_w_t, T, A> const &s)
00882 {
00883     return s.c_str();
00884 }
00885 
00886 /* c_str_ptr_len */
00887 
00889 template<   ss_typename_param_k C
00890         ,   ss_typename_param_k T
00891         ,   ss_typename_param_k A
00892         >
00893 inline ss_size_t c_str_len(basic_simple_string<C, T, A> const &s)
00894 {
00895     return s.length();
00896 }
00897 
00898 /* c_str_ptr_size */
00899 
00901 template<   ss_typename_param_k C
00902         ,   ss_typename_param_k T
00903         ,   ss_typename_param_k A
00904         >
00905 inline ss_size_t c_str_size(basic_simple_string<C, T, A> const &s)
00906 {
00907     return c_str_len(s) * sizeof(C);
00908 }
00909 
00910 /* operator << */
00911 template<   ss_typename_param_k S
00912         ,   ss_typename_param_k C
00913         ,   ss_typename_param_k T
00914         ,   ss_typename_param_k A
00915         >
00916 inline S &operator <<(S & s, basic_simple_string<C, T, A> const &str)
00917 {
00918     s << str.c_str();
00919 
00920     return s;
00921 }
00922 
00923 /* 
00924  * Unit-testing
00925  */
00926 
00927 #ifdef STLSOFT_UNITTEST
00928 
00929 namespace unittest
00930 {
00931     ss_bool_t test_stlsoft_simple_string(unittest_reporter *r)
00932     {
00933         ss_bool_t               bSuccess    =   true;
00934 
00935         unittest_initialiser    init(r, "STLSoft", "basic_simple_string", __FILE__);
00936 
00937         typedef basic_simple_string<char
00938                                 ,   stlsoft_char_traits<char>
00939                                 ,   new_allocator<char>
00940                                 >                               string_t;
00941 
00942         if(string_t("abc") != "abc")
00943         {
00944             r->report("construction failed ", __LINE__);
00945             bSuccess = false;
00946         }
00947 
00948         if(string_t("abc") >= "def")
00949         {
00950             r->report("comparison failed ", __LINE__);
00951             bSuccess = false;
00952         }
00953 
00954         // Self assignment
00955         string_t const  s3("abcdefghijklm");
00956         string_t        s4;
00957 
00958         s4 = s3;    // setup
00959         s4 = s4;    // action
00960         if(s3 != s4)
00961         {
00962             r->report("self-assignment (1) failed ", __LINE__);
00963             bSuccess = false;
00964         }
00965 
00966         s4 = s3;            // setup
00967         s4.assign(&s4[2]);  // action
00968         if("abcdefghijklm" + 2 != s4)
00969         {
00970             r->report("self-assignment (2) failed ", __LINE__);
00971             bSuccess = false;
00972         }
00973 
00974         s4 = s3;                // setup
00975         s4.append(&s4[2], 4);   // action
00976         if("abcdefghijklmcdef" != s4)
00977         {
00978             r->report("self-append (1) failed ", __LINE__);
00979             bSuccess = false;
00980         }
00981 
00982         s4 = s3;            // setup
00983         s4.append(&s4[1]);  // action
00984         if("abcdefghijklmbcdefghijklm" != s4)
00985         {
00986             r->report("self-append (2) failed ", __LINE__);
00987             bSuccess = false;
00988         }
00989 
00990         return bSuccess;
00991     }
00992 
00993     unittest_registrar    unittest_stlsoft_simple_string(test_stlsoft_simple_string);
00994 
00995 } // namespace winstl_test
00996 
00997 #endif /* STLSOFT_UNITTEST */
00998 
00999 /* 
01000  * Implementation
01001  */
01002 
01003 #ifndef __STLSOFT_DOCUMENTATION_SKIP_SECTION
01004 
01005 // Implementation
01006 
01007 template<   ss_typename_param_k C
01008         ,   ss_typename_param_k T
01009         ,   ss_typename_param_k A
01010         >
01011 inline /* static */ ss_typename_type_k basic_simple_string<C, T, A>::char_type *basic_simple_string<C, T, A>::char_pointer_from_member_pointer_(ss_typename_type_k basic_simple_string<C, T, A>::member_pointer m)
01012 {
01013 #ifdef STLSOFT_SIMPLE_STRING_NO_PTR_ADJUST
01014     return (NULL == m) ? NULL : m->contents;
01015 #else /* ? STLSOFT_SIMPLE_STRING_NO_PTR_ADJUST */
01016     return m;
01017 #endif /* STLSOFT_SIMPLE_STRING_NO_PTR_ADJUST */
01018 }
01019 
01020 
01021 template<   ss_typename_param_k C
01022         ,   ss_typename_param_k T
01023         ,   ss_typename_param_k A
01024         >
01025 inline /* static */ ss_typename_type_k basic_simple_string<C, T, A>::string_buffer *basic_simple_string<C, T, A>::string_buffer_from_member_pointer_(ss_typename_type_k basic_simple_string<C, T, A>::member_pointer m)
01026 {
01027     stlsoft_message_assert("Attempt to convert a null string_buffer in basic_simple_string", NULL != m);
01028 
01029 #ifdef STLSOFT_SIMPLE_STRING_NO_PTR_ADJUST
01030     return m;
01031 #else /* ? STLSOFT_SIMPLE_STRING_NO_PTR_ADJUST */
01032     return reinterpret_cast<string_buffer*>(const_cast<void*>(ptr_byte_offset(m, -static_cast<ss_ptrdiff_t>(stlsoft_raw_offsetof(string_buffer, contents)))));
01033 #endif /* STLSOFT_SIMPLE_STRING_NO_PTR_ADJUST */
01034 }
01035 
01036 template<   ss_typename_param_k C
01037         ,   ss_typename_param_k T
01038         ,   ss_typename_param_k A
01039         >
01040 inline /* static */ ss_typename_type_k basic_simple_string<C, T, A>::string_buffer const *basic_simple_string<C, T, A>::string_buffer_from_member_pointer_(ss_typename_type_k basic_simple_string<C, T, A>::member_const_pointer m)
01041 {
01042     stlsoft_message_assert("Attempt to convert a null string_buffer in basic_simple_string", NULL != m);
01043 
01044 #ifdef STLSOFT_SIMPLE_STRING_NO_PTR_ADJUST
01045     return m;
01046 #else /* ? STLSOFT_SIMPLE_STRING_NO_PTR_ADJUST */
01047     return reinterpret_cast<string_buffer const*>(ptr_byte_offset(m, -static_cast<ss_ptrdiff_t>(stlsoft_raw_offsetof(string_buffer, contents))));
01048 #endif /* STLSOFT_SIMPLE_STRING_NO_PTR_ADJUST */
01049 }
01050 
01051 template<   ss_typename_param_k C
01052         ,   ss_typename_param_k T
01053         ,   ss_typename_param_k A
01054         >
01055 inline /* static */ ss_typename_type_k basic_simple_string<C, T, A>::member_pointer basic_simple_string<C, T, A>::member_pointer_from_string_buffer_(ss_typename_type_k basic_simple_string<C, T, A>::string_buffer *b)
01056 {
01057 #ifdef STLSOFT_SIMPLE_STRING_NO_PTR_ADJUST
01058     return b;
01059 #else /* ? STLSOFT_SIMPLE_STRING_NO_PTR_ADJUST */
01060     return b->contents;
01061 #endif /* STLSOFT_SIMPLE_STRING_NO_PTR_ADJUST */
01062 }
01063 
01064 template<   ss_typename_param_k C
01065         ,   ss_typename_param_k T
01066         ,   ss_typename_param_k A
01067         >
01068 inline /* static */ ss_typename_type_k basic_simple_string<C, T, A>::member_pointer basic_simple_string<C, T, A>::alloc_buffer_(ss_typename_type_k basic_simple_string<C, T, A>::char_type const    *s
01069                                                                                                                             ,   ss_typename_type_k basic_simple_string<C, T, A>::size_type          capacity
01070                                                                                                                             ,   ss_typename_type_k basic_simple_string<C, T, A>::size_type          length)
01071 {
01072     // Pre-conditions
01073     stlsoft_assert(length <= capacity);
01074     stlsoft_assert(length >= traits_type::length_max_null(s, length));
01075 
01076     const ss_size_t members = (stlsoft_raw_offsetof(string_buffer, contents) + (sizeof(char_type) - 1)) / sizeof(char_type);
01077 
01078     capacity += 1;                                              // For null terminator
01079     capacity += members;                                        // Include the internal members.
01080     capacity = (alloc_quantum + capacity) & ~alloc_quantum;     // Round up to (alloc_quantum + 1)
01081 
01082 
01083 #ifdef STLSOFT_CF_ALLOCATOR_REBIND_SUPPORT
01084 # ifdef STLSOFT_CF_TEMPLATE_QUALIFIER_KEYWORD_SUPPORT
01085     ss_typename_type_k allocator_type::template rebind<ss_byte_t>::other    byte_ator;
01086 # else /* ? STLSOFT_CF_TEMPLATE_QUALIFIER_KEYWORD_SUPPORT */
01087     ss_typename_type_k allocator_type::rebind<ss_byte_t>::other             byte_ator;
01088 # endif /* STLSOFT_CF_TEMPLATE_QUALIFIER_KEYWORD_SUPPORT */
01089 #else /* ? STLSOFT_CF_ALLOCATOR_REBIND_SUPPORT */
01090     new_allocator<ss_byte_t>                                                byte_ator;
01091 #endif /* STLSOFT_CF_ALLOCATOR_REBIND_SUPPORT */
01092 
01093     ss_byte_t       *raw_buffer =   byte_ator.allocate(capacity * sizeof(char_type));
01094     string_buffer   *buffer     =   sap_cast<string_buffer*>(raw_buffer);
01095 
01096     if(NULL != buffer)
01097     {
01098         if(NULL == s)
01099         {
01100             stlsoft_assert(0 == length);
01101 
01102             buffer->contents[0] = traits_type::to_char_type(0);
01103         }
01104         else
01105         {
01106             traits_type::copy(buffer->contents, s, length);
01107             buffer->contents[length] = traits_type::to_char_type(0);
01108         }
01109 
01110         buffer->length      =   length;
01111         buffer->capacity    =   capacity - members;
01112 
01113         return member_pointer_from_string_buffer_(buffer);
01114     }
01115 
01116     return NULL;
01117 }
01118 
01119 template<   ss_typename_param_k C
01120         ,   ss_typename_param_k T
01121         ,   ss_typename_param_k A
01122         >
01123 inline /* static */ ss_typename_type_k basic_simple_string<C, T, A>::member_pointer basic_simple_string<C, T, A>::alloc_buffer_(ss_typename_type_k basic_simple_string<C, T, A>::char_type const    *s
01124                                                                                                                             ,   ss_typename_type_k basic_simple_string<C, T, A>::size_type          cch)
01125 {
01126     size_type   length      =   traits_type::length_max_null(s, cch);
01127     size_type   capacity    =   cch;
01128 
01129     if(cch < length)
01130     {
01131         length = cch;
01132     }
01133 
01134     return alloc_buffer_(s, capacity, length);
01135 }
01136 
01137 template<   ss_typename_param_k C
01138         ,   ss_typename_param_k T
01139         ,   ss_typename_param_k A
01140         >
01141 inline /* static */ ss_typename_type_k basic_simple_string<C, T, A>::member_pointer basic_simple_string<C, T, A>::alloc_buffer_(ss_typename_type_k basic_simple_string<C, T, A>::char_type const *s)
01142 {
01143     member_pointer  res;
01144 
01145     if(NULL == s)
01146     {
01147         res = NULL;
01148     }
01149     else
01150     {
01151         size_type   len =   traits_type::length(s);
01152 
01153         res = alloc_buffer_(s, len, len);
01154     }
01155 
01156     return res;
01157 }
01158 
01159 template<   ss_typename_param_k C
01160         ,   ss_typename_param_k T
01161         ,   ss_typename_param_k A
01162         >
01163 inline /* static */ ss_typename_type_k basic_simple_string<C, T, A>::member_pointer basic_simple_string<C, T, A>::copy_buffer_(ss_typename_type_k basic_simple_string<C, T, A>::member_pointer m)
01164 {
01165     if(NULL != m)
01166     {
01167 #ifdef STLSOFT_CF_ALLOCATOR_REBIND_SUPPORT
01168 # ifdef STLSOFT_CF_TEMPLATE_QUALIFIER_KEYWORD_SUPPORT
01169         ss_typename_type_k allocator_type::template rebind<ss_byte_t>::other    byte_ator;
01170 # else /* ? STLSOFT_CF_TEMPLATE_QUALIFIER_KEYWORD_SUPPORT */
01171         ss_typename_type_k allocator_type::rebind<ss_byte_t>::other             byte_ator;
01172 # endif /* STLSOFT_CF_TEMPLATE_QUALIFIER_KEYWORD_SUPPORT */
01173 #else /* ? STLSOFT_CF_ALLOCATOR_REBIND_SUPPORT */
01174         new_allocator<ss_byte_t>                                                byte_ator;
01175 #endif /* STLSOFT_CF_ALLOCATOR_REBIND_SUPPORT */
01176 
01177         string_buffer   *buffer     =   string_buffer_from_member_pointer_(m);
01178         ss_size_t       cb          =   buffer->capacity * sizeof(char_type) + stlsoft_raw_offsetof(string_buffer, contents);
01179         ss_byte_t       *raw_buffer =   byte_ator.allocate(cb);
01180         string_buffer   *new_buffer =   sap_cast<string_buffer*>(raw_buffer);
01181 
01182         if(NULL != new_buffer)
01183         {
01184             memcpy(new_buffer, buffer, cb);
01185 
01186             return member_pointer_from_string_buffer_(new_buffer);
01187         }
01188     }
01189 
01190     return NULL;
01191 }
01192 
01193 template<   ss_typename_param_k C
01194         ,   ss_typename_param_k T
01195         ,   ss_typename_param_k A
01196         >
01197 inline /* static */ void basic_simple_string<C, T, A>::destroy_buffer_(ss_typename_type_k basic_simple_string<C, T, A>::string_buffer *buffer)
01198 {
01199 #ifdef STLSOFT_CF_ALLOCATOR_REBIND_SUPPORT
01200 # ifdef STLSOFT_CF_TEMPLATE_QUALIFIER_KEYWORD_SUPPORT
01201     ss_typename_type_k allocator_type::template rebind<ss_byte_t>::other    byte_ator;
01202 # else /* ? STLSOFT_CF_TEMPLATE_QUALIFIER_KEYWORD_SUPPORT */
01203     ss_typename_type_k allocator_type::rebind<ss_byte_t>::other             byte_ator;
01204 # endif /* STLSOFT_CF_TEMPLATE_QUALIFIER_KEYWORD_SUPPORT */
01205 #else /* ? STLSOFT_CF_ALLOCATOR_REBIND_SUPPORT */
01206     new_allocator<ss_byte_t>                                                byte_ator;
01207 #endif /* STLSOFT_CF_ALLOCATOR_REBIND_SUPPORT */
01208 
01209 #ifdef STLSOFT_CF_TEMPLATE_QUALIFIER_KEYWORD_SUPPORT
01210 #else /* ? STLSOFT_CF_TEMPLATE_QUALIFIER_KEYWORD_SUPPORT */
01211 #endif /* STLSOFT_CF_TEMPLATE_QUALIFIER_KEYWORD_SUPPORT */
01212 
01213     byte_ator.deallocate(sap_cast<ss_byte_t*>(buffer), 0);
01214 }
01215 
01216 template<   ss_typename_param_k C
01217         ,   ss_typename_param_k T
01218         ,   ss_typename_param_k A
01219         >
01220 inline /* static */ void basic_simple_string<C, T, A>::destroy_buffer_(ss_typename_type_k basic_simple_string<C, T, A>::char_type *s)
01221 {
01222     destroy_buffer_(string_buffer_from_member_pointer_(s));
01223 }
01224 
01225 template<   ss_typename_param_k C
01226         ,   ss_typename_param_k T
01227         ,   ss_typename_param_k A
01228         >
01229 inline ss_typename_type_k basic_simple_string<C, T, A>::pointer basic_simple_string<C, T, A>::begin_()
01230 {
01231     return char_pointer_from_member_pointer_(m_buffer);
01232 }
01233 
01234 template<   ss_typename_param_k C
01235         ,   ss_typename_param_k T
01236         ,   ss_typename_param_k A
01237         >
01238 inline ss_typename_type_k basic_simple_string<C, T, A>::pointer basic_simple_string<C, T, A>::end_()
01239 {
01240     return begin_() + length();
01241 }
01242 
01243 template<   ss_typename_param_k C
01244         ,   ss_typename_param_k T
01245         ,   ss_typename_param_k A
01246         >
01247 inline ss_bool_t basic_simple_string<C, T, A>::is_valid_() const
01248 {
01249     if(NULL != m_buffer)
01250     {
01251         string_buffer const *buffer =   string_buffer_from_member_pointer_(m_buffer);
01252 
01253         if(buffer->capacity < 1)
01254         {
01255             return false;
01256         }
01257         else if(buffer->capacity < buffer->length)
01258         {
01259             return false;
01260         }
01261         else
01262         {
01263             size_type   len =   traits_type::length(buffer->contents);
01264 
01265             if(buffer->length != len)
01266             {
01267                 return false;
01268             }
01269         }
01270     }
01271 
01272     return true;
01273 }
01274 
01275 template<   ss_typename_param_k C
01276         ,   ss_typename_param_k T
01277         ,   ss_typename_param_k A
01278         >
01279 inline /* static */ ss_typename_type_k basic_simple_string<C, T, A>::char_type const *basic_simple_string<C, T, A>::empty_string_()
01280 {
01281     // This character array is initialised to 0, which conveniently happens to
01282     // be the empty string, by the module/application load, so it is
01283     // guaranteed to be valid, and there are no threading/race conditions
01284     static char_type    s_empty[1];
01285 
01286     stlsoft_assert(s_empty[0] == '\0'); // Paranoid check
01287 
01288     return s_empty;
01289 }
01290 
01291 // Construction
01292 
01293 template<   ss_typename_param_k C
01294         ,   ss_typename_param_k T
01295         ,   ss_typename_param_k A
01296         >
01297 inline basic_simple_string<C, T, A>::basic_simple_string()
01298     : m_buffer(NULL)
01299 {
01300     stlsoft_assert(is_valid_());
01301 }
01302 
01303 template<   ss_typename_param_k C
01304         ,   ss_typename_param_k T
01305         ,   ss_typename_param_k A
01306         >
01307 inline basic_simple_string<C, T, A>::basic_simple_string(class_type const &rhs)
01308     : m_buffer(copy_buffer_(rhs.m_buffer))
01309 {
01310     stlsoft_assert(is_valid_());
01311 }
01312 
01313 template<   ss_typename_param_k C
01314         ,   ss_typename_param_k T
01315         ,   ss_typename_param_k A
01316         >
01317 inline basic_simple_string<C, T, A>::basic_simple_string(   ss_typename_type_k basic_simple_string<C, T, A>::class_type const   &rhs
01318                                                         ,   ss_typename_type_k basic_simple_string<C, T, A>::size_type          pos)
01319     : m_buffer(alloc_buffer_(&rhs[pos]))
01320 {
01321     stlsoft_assert(is_valid_());
01322 }
01323 
01324 template<   ss_typename_param_k C
01325         ,   ss_typename_param_k T
01326         ,   ss_typename_param_k A
01327         >
01328 inline basic_simple_string<C, T, A>::basic_simple_string(   ss_typename_type_k basic_simple_string<C, T, A>::class_type const   &rhs
01329                                                         ,   ss_typename_type_k basic_simple_string<C, T, A>::size_type          pos
01330                                                         ,   ss_typename_type_k basic_simple_string<C, T, A>::size_type          cch)
01331     : m_buffer(alloc_buffer_(&rhs[pos], cch, cch))
01332 {
01333     stlsoft_assert(is_valid_());
01334 }
01335 
01336 template<   ss_typename_param_k C
01337         ,   ss_typename_param_k T
01338         ,   ss_typename_param_k A
01339         >
01340 inline basic_simple_string<C, T, A>::basic_simple_string(ss_typename_type_k basic_simple_string<C, T, A>::char_type const *s) // No, not explicit. Sigh
01341     : m_buffer(alloc_buffer_(s))
01342 {
01343     stlsoft_assert(is_valid_());
01344 }
01345 
01346 template<   ss_typename_param_k C
01347         ,   ss_typename_param_k T
01348         ,   ss_typename_param_k A
01349         >
01350 inline basic_simple_string<C, T, A>::basic_simple_string(   ss_typename_type_k basic_simple_string<C, T, A>::char_type const    *s
01351                                                         ,   ss_typename_type_k basic_simple_string<C, T, A>::size_type          cch)
01352     : m_buffer(alloc_buffer_(s, cch))
01353 {
01354     stlsoft_assert(is_valid_());
01355 }
01356 
01357 template<   ss_typename_param_k C
01358         ,   ss_typename_param_k T
01359         ,   ss_typename_param_k A
01360         >
01361 inline basic_simple_string<C, T, A>::basic_simple_string(   ss_typename_type_k basic_simple_string<C, T, A>::size_type  cch
01362                                                         ,   ss_typename_type_k basic_simple_string<C, T, A>::char_type  ch)
01363     : m_buffer(NULL)
01364 {
01365     stlsoft_assert(is_valid_());
01366 
01367     assign(cch, ch);
01368 }
01369 
01370 #if !defined(__STLSOFT_CF_MEMBER_TEMPLATE_RANGE_METHOD_SUPPORT)
01371 template<   ss_typename_param_k C
01372         ,   ss_typename_param_k T
01373         ,   ss_typename_param_k A
01374         >
01375 inline basic_simple_string<C, T, A>::basic_simple_string(   ss_typename_type_k basic_simple_string<C, T, A>::char_type const    *first
01376                                                         ,   ss_typename_type_k basic_simple_string<C, T, A>::char_type const    *last)
01377     : m_buffer(alloc_buffer_(first, last - first))
01378 {
01379     stlsoft_assert(is_valid_());
01380 }
01381 #endif /* !__STLSOFT_CF_MEMBER_TEMPLATE_RANGE_METHOD_SUPPORT */
01382 
01383 template<   ss_typename_param_k C
01384         ,   ss_typename_param_k T
01385         ,   ss_typename_param_k A
01386         >
01387 inline basic_simple_string<C, T, A>::~basic_simple_string()
01388 {
01389     stlsoft_assert(is_valid_());
01390 
01391     if(NULL != m_buffer)
01392     {
01393         destroy_buffer_(m_buffer);
01394     }
01395 }
01396 
01397 // Comparison
01398 
01399 template<   ss_typename_param_k C
01400         ,   ss_typename_param_k T
01401         ,   ss_typename_param_k A
01402         >
01403 inline /* static */ ss_sint_t basic_simple_string<C, T, A>::compare_(   ss_typename_type_k basic_simple_string<C, T, A>::value_type const   *lhs
01404                                                                     ,   ss_typename_type_k basic_simple_string<C, T, A>::size_type          lhs_len
01405                                                                     ,   ss_typename_type_k basic_simple_string<C, T, A>::value_type const   *rhs
01406                                                                     ,   ss_typename_type_k basic_simple_string<C, T, A>::size_type          rhs_len)
01407 {
01408     size_type   cmp_len =   (lhs_len < rhs_len) ? lhs_len : rhs_len;
01409     ss_int_t    result  =   traits_type::compare(lhs, rhs, cmp_len);
01410 
01411     if(0 == result)
01412     {
01413         result = static_cast<ss_int_t>(lhs_len) - static_cast<ss_int_t>(rhs_len);
01414     }
01415 
01416     return result;
01417 }
01418 
01419 template<   ss_typename_param_k C
01420         ,   ss_typename_param_k T
01421         ,   ss_typename_param_k A
01422         >
01423 inline ss_sint_t basic_simple_string<C, T, A>::compare( ss_typename_type_k basic_simple_string<C, T, A>::size_type          pos
01424                                                     ,   ss_typename_type_k basic_simple_string<C, T, A>::size_type          cch
01425                                                     ,   ss_typename_type_k basic_simple_string<C, T, A>::value_type const   *rhs
01426                                                     ,   ss_typename_type_k basic_simple_string<C, T, A>::size_type          cchRhs) const
01427 {
01428     size_type   lhs_len =   length();
01429 
01430     if(!(pos < lhs_len))
01431     {
01432         pos = lhs_len;
01433     }
01434     else
01435     {
01436         lhs_len -= pos;
01437     }
01438 
01439     if(cch < lhs_len)
01440     {
01441         lhs_len = cch;
01442     }
01443 
01444     size_type   rhs_len =   (NULL == rhs) ? 0 : traits_type::length(rhs);
01445 
01446     if(cchRhs < rhs_len)
01447     {
01448         rhs_len = cchRhs;
01449     }
01450 
01451     return compare_(char_pointer_from_member_pointer_(m_buffer) + pos, lhs_len, rhs, rhs_len);
01452 }
01453 
01454 template<   ss_typename_param_k C
01455         ,   ss_typename_param_k T
01456         ,   ss_typename_param_k A
01457         >
01458 inline ss_sint_t basic_simple_string<C, T, A>::compare( ss_typename_type_k basic_simple_string<C, T, A>::size_type          pos
01459                                                     ,   ss_typename_type_k basic_simple_string<C, T, A>::size_type          cch
01460                                                     ,   ss_typename_type_k basic_simple_string<C, T, A>::value_type const   *rhs) const
01461 {
01462     size_type   lhs_len =   length();
01463 
01464     if(!(pos < lhs_len))
01465     {
01466         pos = lhs_len;
01467     }
01468     else
01469     {
01470         lhs_len -= pos;
01471     }
01472 
01473     if(cch < lhs_len)
01474     {
01475         lhs_len = cch;
01476     }
01477 
01478     size_type   rhs_len =   (NULL == rhs) ? 0 : traits_type::length(rhs);
01479 
01480     return compare_(char_pointer_from_member_pointer_(m_buffer) + pos, lhs_len, rhs, rhs_len);
01481 }
01482 
01483 template<   ss_typename_param_k C
01484         ,   ss_typename_param_k T
01485         ,   ss_typename_param_k A
01486         >
01487 inline ss_sint_t basic_simple_string<C, T, A>::compare(ss_typename_type_k basic_simple_string<C, T, A>::value_type const *rhs) const
01488 {
01489     size_type   lhs_len =   length();
01490     size_type   rhs_len =   (NULL == rhs) ? 0 : traits_type::length(rhs);
01491 
01492     return compare_(char_pointer_from_member_pointer_(m_buffer), lhs_len, rhs, rhs_len);
01493 }
01494 
01495 template<   ss_typename_param_k C
01496         ,   ss_typename_param_k T
01497         ,   ss_typename_param_k A
01498         >
01499 inline ss_sint_t basic_simple_string<C, T, A>::compare( ss_typename_type_k basic_simple_string<C, T, A>::size_type          pos
01500                                                     ,   ss_typename_type_k basic_simple_string<C, T, A>::size_type          cch
01501                                                     ,   ss_typename_type_k basic_simple_string<C, T, A>::class_type const   &rhs
01502                                                     ,   ss_typename_type_k basic_simple_string<C, T, A>::size_type          posRhs
01503                                                     ,   ss_typename_type_k basic_simple_string<C, T, A>::size_type          cchRhs) const
01504 {
01505     size_type   lhs_len =   length();
01506 
01507     if(!(pos < lhs_len))
01508     {
01509         pos = lhs_len;
01510     }
01511     else
01512     {
01513         lhs_len -= pos;
01514     }
01515 
01516     if(cch < lhs_len)
01517     {
01518         lhs_len = cch;
01519     }
01520 
01521     size_type   rhs_len =   rhs.length();
01522 
01523     if(!(posRhs < rhs_len))
01524     {
01525         posRhs = rhs_len;
01526     }
01527     else
01528     {
01529         rhs_len -= posRhs;
01530     }
01531 
01532     if(cchRhs < rhs_len)
01533     {
01534         rhs_len = cchRhs;
01535     }
01536 
01537     return compare_(char_pointer_from_member_pointer_(m_buffer) + pos, lhs_len, char_pointer_from_member_pointer_(rhs.m_buffer) + posRhs, rhs_len);
01538 }
01539 
01540 template<   ss_typename_param_k C
01541         ,   ss_typename_param_k T
01542         ,   ss_typename_param_k A
01543         >
01544 inline ss_sint_t basic_simple_string<C, T, A>::compare( ss_typename_type_k basic_simple_string<C, T, A>::size_type          pos
01545                                                     ,   ss_typename_type_k basic_simple_string<C, T, A>::size_type          cch
01546                                                     ,   ss_typename_type_k basic_simple_string<C, T, A>::class_type const   &rhs) const
01547 {
01548     size_type   lhs_len =   length();
01549 
01550     if(!(pos < lhs_len))
01551     {
01552         pos = lhs_len;
01553     }
01554     else
01555     {
01556         lhs_len -= pos;
01557     }
01558 
01559     if(cch < lhs_len)
01560     {
01561         lhs_len = cch;
01562     }
01563 
01564     size_type   rhs_len =   rhs.length();
01565 
01566     return compare_(char_pointer_from_member_pointer_(m_buffer) + pos, lhs_len, char_pointer_from_member_pointer_(rhs.m_buffer), rhs_len);
01567 }
01568 
01569 template<   ss_typename_param_k C
01570         ,   ss_typename_param_k T
01571         ,   ss_typename_param_k A
01572         >
01573 inline ss_sint_t basic_simple_string<C, T, A>::compare(ss_typename_type_k basic_simple_string<C, T, A>::class_type const &rhs) const
01574 {
01575     size_type   lhs_len =   length();
01576     size_type   rhs_len =   rhs.length();
01577 
01578     return compare_(char_pointer_from_member_pointer_(m_buffer), lhs_len, char_pointer_from_member_pointer_(rhs.m_buffer), rhs_len);
01579 }
01580 
01581 // Accessors
01582 template<   ss_typename_param_k C
01583         ,   ss_typename_param_k T
01584         ,   ss_typename_param_k A
01585         >
01586 inline ss_typename_type_k basic_simple_string<C, T, A>::reference basic_simple_string<C, T, A>::operator [](ss_typename_type_k basic_simple_string<C, T, A>::size_type index)
01587 {
01588     stlsoft_message_assert("index access out of range in frame_string", index < length() + 1);   // Has to be +1, since legitimate to take address of one-past-the-end
01589 
01590     stlsoft_assert(is_valid_());
01591 
01592     return char_pointer_from_member_pointer_(m_buffer)[index];
01593 }
01594 
01595 template<   ss_typename_param_k C
01596         ,   ss_typename_param_k T
01597         ,   ss_typename_param_k A
01598         >
01599 inline ss_typename_type_k basic_simple_string<C, T, A>::const_reference basic_simple_string<C, T, A>::operator [](ss_typename_type_k basic_simple_string<C, T, A>::size_type index) const
01600 {
01601     stlsoft_message_assert("index access out of range in frame_string", index < length() + 1);   // Has to be +1, since legitimate to take address of one-past-the-end
01602 
01603     stlsoft_assert(is_valid_());
01604 
01605     return char_pointer_from_member_pointer_(m_buffer)[index];
01606 }
01607 
01608 
01609 template<   ss_typename_param_k C
01610         ,   ss_typename_param_k T
01611         ,   ss_typename_param_k A
01612         >
01613 inline ss_typename_type_k basic_simple_string<C, T, A>::value_type const *basic_simple_string<C, T, A>::c_str() const
01614 {
01615     return (NULL == m_buffer) ? empty_string_() : char_pointer_from_member_pointer_(m_buffer);
01616 }
01617 
01618 template<   ss_typename_param_k C
01619         ,   ss_typename_param_k T
01620         ,   ss_typename_param_k A
01621         >
01622 inline ss_typename_type_k basic_simple_string<C, T, A>::value_type const *basic_simple_string<C, T, A>::data() const
01623 {
01624     return (NULL == m_buffer) ? empty_string_() : char_pointer_from_member_pointer_(m_buffer);
01625 }
01626 
01627 template<   ss_typename_param_k C
01628         ,   ss_typename_param_k T
01629         ,   ss_typename_param_k A
01630         >
01631 inline ss_typename_type_k basic_simple_string<C, T, A>::reference basic_simple_string<C, T, A>::front()
01632 {
01633     return (*this)[0];
01634 }
01635 
01636 template<   ss_typename_param_k C
01637         ,   ss_typename_param_k T
01638         ,   ss_typename_param_k A
01639         >
01640 inline ss_typename_type_k basic_simple_string<C, T, A>::reference basic_simple_string<C, T, A>::back()
01641 {
01642     return (*this)[length() - 1];
01643 }
01644 
01645 template<   ss_typename_param_k C
01646         ,   ss_typename_param_k T
01647         ,   ss_typename_param_k A
01648         >
01649 inline ss_typename_type_k basic_simple_string<C, T, A>::const_reference basic_simple_string<C, T, A>::front() const
01650 {
01651     return (*this)[0];
01652 }
01653 
01654 template<   ss_typename_param_k C
01655         ,   ss_typename_param_k T
01656         ,   ss_typename_param_k A
01657         >
01658 inline ss_typename_type_k basic_simple_string<C, T, A>::const_reference basic_simple_string<C, T, A>::back() const
01659 {
01660     return (*this)[length() - 1];
01661 }
01662 
01663 template<   ss_typename_param_k C
01664         ,   ss_typename_param_k T
01665         ,   ss_typename_param_k A
01666         >
01667 inline ss_typename_type_k basic_simple_string<C, T, A>::size_type basic_simple_string<C, T, A>::copy(   ss_typename_type_k basic_simple_string<C, T, A>::value_type     *dest
01668                                                                                                     ,   ss_typename_type_k basic_simple_string<C, T, A>::size_type      cch
01669                                                                                                     ,   ss_typename_type_k basic_simple_string<C, T, A>::size_type      pos /* = 0 */) const
01670 {
01671     size_type   len =   length();
01672 
01673     if(pos < len)
01674     {
01675         if(len < pos + cch)
01676         {
01677             cch = len - pos;
01678         }
01679 
01680         traits_type::copy(dest, data() + pos, cch);
01681     }
01682     else
01683     {
01684         cch = 0;
01685     }
01686 
01687     return cch;
01688 }
01689 
01690 // Iteration
01691 
01692 #ifndef STLSOFT_SIMPLE_STRING_ITERATOR_METHODS_INLINE
01693 template<   ss_typename_param_k C
01694         ,   ss_typename_param_k T
01695         ,   ss_typename_param_k A
01696         >
01697 inline ss_typename_type_k basic_simple_string<C, T, A>::const_iterator basic_simple_string<C, T, A>::begin() const
01698 {
01699     return const_cast<class_type*>(this)->begin_();
01700 }
01701 
01702 template<   ss_typename_param_k C
01703         ,   ss_typename_param_k T
01704         ,   ss_typename_param_k A
01705         >
01706 inline ss_typename_type_k basic_simple_string<C, T, A>::const_iterator basic_simple_string<C, T, A>::end() const
01707 {
01708     return const_cast<class_type*>(this)->end_();
01709 }
01710 #endif /* !STLSOFT_SIMPLE_STRING_ITERATOR_METHODS_INLINE */
01711 
01712 template<   ss_typename_param_k C
01713         ,   ss_typename_param_k T
01714         ,   ss_typename_param_k A
01715         >
01716 inline ss_typename_type_k basic_simple_string<C, T, A>::iterator basic_simple_string<C, T, A>::begin()
01717 {
01718     return begin_();
01719 }
01720 
01721 template<   ss_typename_param_k C
01722         ,   ss_typename_param_k T
01723         ,   ss_typename_param_k A
01724         >
01725 inline ss_typename_type_k basic_simple_string<C, T, A>::iterator basic_simple_string<C, T, A>::end()
01726 {
01727     return end_();
01728 }
01729 
01730 #if defined(__STLSOFT_CF_BIDIRECTIONAL_ITERATOR_SUPPORT)
01731 template<   ss_typename_param_k C
01732         ,   ss_typename_param_k T
01733         ,   ss_typename_param_k A
01734         >
01735 inline ss_typename_type_k basic_simple_string<C, T, A>::const_reverse_iterator basic_simple_string<C, T, A>::rbegin() const
01736 {
01737     return const_reverse_iterator(end());
01738 }
01739 
01740 template<   ss_typename_param_k C
01741         ,   ss_typename_param_k T
01742         ,   ss_typename_param_k A
01743         >
01744 inline ss_typename_type_k basic_simple_string<C, T, A>::const_reverse_iterator basic_simple_string<C, T, A>::rend() const
01745 {
01746     return const_reverse_iterator(begin());
01747 }
01748 
01749 template<   ss_typename_param_k C
01750         ,   ss_typename_param_k T
01751         ,   ss_typename_param_k A
01752         >
01753 inline ss_typename_type_k basic_simple_string<C, T, A>::reverse_iterator basic_simple_string<C, T, A>::rbegin()
01754 {
01755     return reverse_iterator(end());
01756 }
01757 
01758 template<   ss_typename_param_k C
01759         ,   ss_typename_param_k T
01760         ,   ss_typename_param_k A
01761         >
01762 inline ss_typename_type_k basic_simple_string<C, T, A>::reverse_iterator basic_simple_string<C, T, A>::rend()
01763 {
01764     return reverse_iterator(begin());
01765 }
01766 #endif /* __STLSOFT_CF_BIDIRECTIONAL_ITERATOR_SUPPORT */
01767 
01768 // Assignment
01769 template<   ss_typename_param_k C
01770         ,   ss_typename_param_k T
01771         ,   ss_typename_param_k A
01772         >
01773 inline ss_typename_type_k basic_simple_string<C, T, A>::class_type &basic_simple_string<C, T, A>::assign(   ss_typename_type_k basic_simple_string<C, T, A>::char_type const    *s
01774                                                                                                         ,   ss_typename_type_k basic_simple_string<C, T, A>::size_type          cch)
01775 {
01776     stlsoft_assert(is_valid_());
01777 
01778     if(NULL == m_buffer)
01779     {
01780         if(cch == 0)
01781         {
01782             // Nothing to do
01783         }
01784         else
01785         {
01786             m_buffer = alloc_buffer_(s, cch);
01787         }
01788     }
01789     else
01790     {
01791         if(NULL == s)
01792         {
01793             destroy_buffer_(m_buffer);
01794             m_buffer = NULL;
01795         }
01796         else
01797         {
01798             // Here is an opportunity to optimise a bit. We will do more so in a
01799             // later release, but for the moment we will reuse our existing
01800             // buffer if its capacity is sufficient for our purposes
01801 
01802             string_buffer   *buffer =   string_buffer_from_member_pointer_(m_buffer);
01803             size_type       len     =   traits_type::length(s);
01804 
01805             if(len < cch)
01806             {
01807                 cch = len;
01808             }
01809 
01810             if( cch < buffer->capacity &&
01811                 (   s < &buffer->contents[0] ||
01812                     s > &buffer->contents[len]))
01813             {
01814                 traits_type::copy(buffer->contents, s, cch);
01815                 buffer->contents[cch] = 0;
01816                 buffer->length = cch;
01817             }
01818             else
01819             {
01820                 member_pointer  new_buffer =   alloc_buffer_(s, cch, cch);
01821 
01822                 destroy_buffer_(m_buffer);
01823                 m_buffer = new_buffer;
01824             }
01825         }
01826     }
01827 
01828     stlsoft_assert(is_valid_());
01829     return *this;
01830 }
01831 
01832 template<   ss_typename_param_k C
01833         ,   ss_typename_param_k T
01834         ,   ss_typename_param_k A
01835         >
01836 inline ss_typename_type_k basic_simple_string<C, T, A>::class_type &basic_simple_string<C, T, A>::assign(ss_typename_type_k basic_simple_string<C, T, A>::char_type const *s)
01837 {
01838     return assign(s, (NULL == s) ? 0 : traits_type::length(s));
01839 }
01840 
01841 template<   ss_typename_param_k C
01842         ,   ss_typename_param_k T
01843         ,   ss_typename_param_k A
01844         >
01845 inline ss_typename_type_k basic_simple_string<C, T, A>::class_type &basic_simple_string<C, T, A>::assign(   ss_typename_type_k basic_simple_string<C, T, A>::class_type const   &rhs
01846                                                                                                         ,   ss_typename_type_k basic_simple_string<C, T, A>::size_type          pos
01847                                                                                                         ,   ss_typename_type_k basic_simple_string<C, T, A>::size_type          cch)
01848 {
01849     char_type   *s  =   char_pointer_from_member_pointer_(rhs.m_buffer);
01850     size_type   len =   rhs.length();
01851 
01852     if(len < pos)
01853     {
01854         pos = len;
01855     }
01856 
01857     if(len - pos < cch)
01858     {
01859         cch = len - pos;
01860     }
01861 
01862     if(NULL != s)
01863     {
01864         s += pos;
01865     }
01866     else
01867     {
01868         cch = 0;
01869     }
01870 
01871     return assign(s, cch);
01872 }
01873 
01874 template<   ss_typename_param_k C
01875         ,   ss_typename_param_k T
01876         ,   ss_typename_param_k A
01877         >
01878 inline ss_typename_type_k basic_simple_string<C, T, A>::class_type &basic_simple_string<C, T, A>::assign(ss_typename_type_k basic_simple_string<C, T, A>::class_type const &rhs)
01879 {
01880     return assign(char_pointer_from_member_pointer_(rhs.m_buffer), rhs.length());
01881 }
01882 
01883 template<   ss_typename_param_k C
01884         ,   ss_typename_param_k T
01885         ,   ss_typename_param_k A
01886         >
01887 inline ss_typename_type_k basic_simple_string<C, T, A>::class_type &basic_simple_string<C, T, A>::assign(   ss_typename_type_k basic_simple_string<C, T, A>::size_type  cch
01888                                                                                                         ,   ss_typename_type_k basic_simple_string<C, T, A>::char_type  ch)
01889 {
01890     typedef auto_buffer<char_type, allocator_type>  buffer_t;
01891 
01892     buffer_t    buffer(cch);
01893 
01894     (void)stlsoft_ns_qual_std(fill)(buffer.begin(), buffer.end(), ch);
01895 
01896     return assign(buffer, buffer.size());
01897 }
01898 
01899 #if !defined(__STLSOFT_CF_MEMBER_TEMPLATE_RANGE_METHOD_SUPPORT)
01900 template<   ss_typename_param_k C
01901         ,   ss_typename_param_k T
01902         ,   ss_typename_param_k A
01903         >
01904 inline ss_typename_type_k basic_simple_string<C, T, A>::class_type &basic_simple_string<C, T, A>::assign(   ss_typename_type_k basic_simple_string<C, T, A>::const_iterator     first
01905                                                                                                         ,   ss_typename_type_k basic_simple_string<C, T, A>::const_iterator     last)
01906 {
01907     // We have to use this strange appearing this, because of Visual C++ .NET's
01908     // disgusting STL swill. Sigh!
01909     return assign(&(*first), last - first);
01910 }
01911 #endif /* !__STLSOFT_CF_MEMBER_TEMPLATE_RANGE_METHOD_SUPPORT */
01912 
01913 template<   ss_typename_param_k C
01914         ,   ss_typename_param_k T
01915         ,   ss_typename_param_k A
01916         >
01917 inline ss_typename_type_k basic_simple_string<C, T, A>::class_type const &basic_simple_string<C, T, A>::operator =(ss_typename_type_k basic_simple_string<C, T, A>::class_type const &rhs)
01918 {
01919     return assign(rhs);
01920 }
01921 
01922 template<   ss_typename_param_k C
01923         ,   ss_typename_param_k T
01924         ,   ss_typename_param_k A
01925         >
01926 inline ss_typename_type_k basic_simple_string<C, T, A>::class_type const &basic_simple_string<C, T, A>::operator =(ss_typename_type_k basic_simple_string<C, T, A>::char_type const *s)
01927 {
01928     return assign(s);
01929 }
01930 
01931 template<   ss_typename_param_k C
01932         ,   ss_typename_param_k T
01933         ,   ss_typename_param_k A
01934         >
01935 inline ss_typename_type_k basic_simple_string<C, T, A>::class_type const &basic_simple_string<C, T, A>::operator =(ss_typename_type_k basic_simple_string<C, T, A>::char_type ch)
01936 {
01937     char_type   sz[2] = { ch, traits_type::to_char_type(0) };
01938 
01939     return assign(sz);
01940 }
01941 
01942 
01943 // Appending
01944 template<   ss_typename_param_k C
01945         ,   ss_typename_param_k T
01946         ,   ss_typename_param_k A
01947         >
01948 inline ss_typename_type_k basic_simple_string<C, T, A>::class_type &basic_simple_string<C, T, A>::append(   ss_typename_type_k basic_simple_string<C, T, A>::char_type const    *s
01949                                                                                                         ,   ss_typename_type_k basic_simple_string<C, T, A>::size_type          cch)
01950 {
01951     stlsoft_assert(is_valid_());
01952 
01953     if(NULL == m_buffer)
01954     {
01955         assign(s, cch);
01956     }
01957     else
01958     {
01959         if( NULL == s ||
01960             0 == cch)
01961         {
01962             // Nothing to do
01963         }
01964         else
01965         {
01966 #if 1
01967             // We're taking a length here, which may have been done already.
01968             // This should be optimised out in a subsequent release
01969             size_type len = traits_type::length_max(s, cch);
01970 
01971             if(len < cch)
01972             {
01973                 cch = len;
01974             }
01975 #endif /* 0 */
01976 
01977             string_buffer   *old_buffer =   NULL;
01978             string_buffer   *buffer     =   string_buffer_from_member_pointer_(m_buffer);
01979             size_type       buf_len     =   buffer->length;
01980 
01981             if(buffer->capacity - buf_len < 1 + cch)
01982             {
01983                 // Allocate a new buffer of sufficient size
01984                 member_pointer  new_buffer =   alloc_buffer_(buffer->contents, buf_len + cch);
01985 
01986                 if(NULL == new_buffer) // Some allocators do not throw on failure!
01987                 {
01988                     cch = 0;
01989                 }
01990                 else
01991                 {
01992                     old_buffer = buffer;    // Mark for destruction, but hold around in case appending from self
01993                     m_buffer = new_buffer;
01994                     buffer = string_buffer_from_member_pointer_(new_buffer);
01995                 }
01996             }
01997 
01998             traits_type::copy(buffer->contents + buf_len, s, cch);
01999             buffer->length += cch;
02000             buffer->contents[buffer->length] = traits_type::to_char_type(0);
02001 
02002             if(NULL != old_buffer)
02003             {
02004                 destroy_buffer_(old_buffer);
02005             }
02006         }
02007     }
02008 
02009     stlsoft_assert(is_valid_());
02010     return *this;
02011 }
02012 
02013 template<   ss_typename_param_k C
02014         ,   ss_typename_param_k T
02015         ,   ss_typename_param_k A
02016         >
02017 inline ss_typename_type_k basic_simple_string<C, T, A>::class_type &basic_simple_string<C, T, A>::append(ss_typename_type_k basic_simple_string<C, T, A>::char_type const *s)
02018 {
02019     return append(s, (NULL == s) ? 0 : traits_type::length(s));
02020 }
02021 
02022 template<   ss_typename_param_k C
02023         ,   ss_typename_param_k T
02024         ,   ss_typename_param_k A
02025         >
02026 inline ss_typename_type_k basic_simple_string<C, T, A>::class_type &basic_simple_string<C, T, A>::append(   ss_typename_type_k basic_simple_string<C, T, A>::class_type const   &rhs
02027                                                                                                         ,   ss_typename_type_k basic_simple_string<C, T, A>::size_type          pos
02028                                                                                                         ,   ss_typename_type_k basic_simple_string<C, T, A>::size_type          cch)
02029 {
02030     char_type   *s  =   char_pointer_from_member_pointer_(rhs.m_buffer);
02031     size_type   len =   rhs.length();
02032 
02033     if(len < pos)
02034     {
02035         pos = len;
02036     }
02037 
02038     if(len - pos < cch)
02039     {
02040         cch = len - pos;
02041     }
02042 
02043     if(NULL != s)
02044     {
02045         s += pos;
02046     }
02047     else
02048     {
02049         cch = 0;
02050     }
02051 
02052     return append(s, cch);
02053 }
02054 
02055 template<   ss_typename_param_k C
02056         ,   ss_typename_param_k T
02057         ,   ss_typename_param_k A
02058         >
02059 inline ss_typename_type_k basic_simple_string<C, T, A>::class_type &basic_simple_string<C, T, A>::append(ss_typename_type_k basic_simple_string<C, T, A>::class_type const &s)
02060 {
02061     return append(char_pointer_from_member_pointer_(s.m_buffer), s.length());
02062 }
02063 
02064 template<   ss_typename_param_k C
02065         ,   ss_typename_param_k T
02066         ,   ss_typename_param_k A
02067         >
02068 inline ss_typename_type_k basic_simple_string<C, T, A>::class_type &basic_simple_string<C, T, A>::append(   ss_typename_type_k basic_simple_string<C, T, A>::size_type  cch
02069                                                                                                         ,   ss_typename_type_k basic_simple_string<C, T, A>::char_type  ch)
02070 {
02071     if(NULL == m_buffer)
02072     {
02073         assign(cch, ch);
02074     }
02075     else
02076     {
02077         typedef auto_buffer<char_type, allocator_type>  buffer_t;
02078 
02079         buffer_t    buffer(cch);
02080 
02081         (void)stlsoft_ns_qual_std(fill)(buffer.begin(), buffer.end(), ch);
02082 
02083         append(buffer, buffer.size());
02084     }
02085 
02086     return *this;
02087 }
02088 
02089 #if !defined(__STLSOFT_CF_MEMBER_TEMPLATE_RANGE_METHOD_SUPPORT)
02090 template<   ss_typename_param_k C
02091         ,   ss_typename_param_k T
02092         ,   ss_typename_param_k A
02093         >
02094 inline ss_typename_type_k basic_simple_string<C, T, A>::class_type &basic_simple_string<C, T, A>::append(   ss_typename_type_k basic_simple_string<C, T, A>::const_iterator first
02095                                                                                                         ,   ss_typename_type_k basic_simple_string<C, T, A>::const_iterator last)
02096 {
02097     // We have to use this strange appearing this, because of Visual C++ .NET's
02098     // disgusting STL swill. Sigh!
02099     return append(&(*first), last - first);
02100 }
02101 #endif /* !__STLSOFT_CF_MEMBER_TEMPLATE_RANGE_METHOD_SUPPORT */
02102 
02103 template<   ss_typename_param_k C
02104         ,   ss_typename_param_k T
02105         ,   ss_typename_param_k A
02106         >
02107 inline ss_typename_type_k basic_simple_string<C, T, A>::class_type &basic_simple_string<C, T, A>::operator +=(ss_typename_type_k basic_simple_string<C, T, A>::char_type ch)
02108 {
02109     return append(1, ch);
02110 }
02111 
02112 template<   ss_typename_param_k C
02113         ,   ss_typename_param_k T
02114         ,   ss_typename_param_k A
02115         >
02116 inline ss_typename_type_k basic_simple_string<C, T, A>::class_type &basic_simple_string<C, T, A>::operator +=(const ss_typename_type_k basic_simple_string<C, T, A>::char_type *s)
02117 {
02118     return append(s);
02119 }
02120 
02121 template<   ss_typename_param_k C
02122         ,   ss_typename_param_k T
02123         ,   ss_typename_param_k A
02124         >
02125 inline ss_typename_type_k basic_simple_string<C, T, A>::class_type &basic_simple_string<C, T, A>::operator +=(const ss_typename_type_k basic_simple_string<C, T, A>::class_type &rhs)
02126 {
02127     return append(rhs);
02128 }
02129 
02130 template<   ss_typename_param_k C
02131         ,   ss_typename_param_k T
02132         ,   ss_typename_param_k A
02133         >
02134 inline void basic_simple_string<C, T, A>::push_back(ss_typename_type_k basic_simple_string<C, T, A>::char_type ch)
02135 {
02136     append(1, ch);
02137 }
02138 
02139 // Operations
02140 template<   ss_typename_param_k C
02141         ,   ss_typename_param_k T
02142         ,   ss_typename_param_k A
02143         >
02144 inline void basic_simple_string<C, T, A>::reserve(ss_typename_type_k basic_simple_string<C, T, A>::size_type cch)
02145 {
02146     if(length() < cch)
02147     {
02148         if(NULL == m_buffer)
02149         {
02150             m_buffer = alloc_buffer_(NULL, cch, 0);
02151         }
02152         else
02153         {
02154             // Allocate a new buffer of sufficient size
02155             member_pointer  new_buffer =   alloc_buffer_(c_str(), cch, length());
02156 
02157             if(NULL != new_buffer) // Some allocators do not throw on failure!
02158             {
02159                 destroy_buffer_(m_buffer);
02160                 m_buffer = new_buffer;
02161             }
02162         }
02163     }
02164 }
02165 
02166 template<   ss_typename_param_k C
02167         ,   ss_typename_param_k T
02168         ,   ss_typename_param_k A
02169         >
02170 inline void basic_simple_string<C, T, A>::swap(ss_typename_type_k basic_simple_string<C, T, A>::class_type &other)
02171 {
02172     stlsoft_assert(is_valid_());
02173     stlsoft_assert(other.is_valid_());
02174 
02175     member_pointer  buffer          =   other.m_buffer;
02176                     other.m_buffer  =   m_buffer;
02177                     m_buffer        =   buffer;
02178 }
02179 
02180 template<   ss_typename_param_k C
02181         ,   ss_typename_param_k T
02182         ,   ss_typename_param_k A
02183         >
02184 inline void basic_simple_string<C, T, A>::resize(   ss_typename_type_k basic_simple_string<C, T, A>::size_type  cch
02185                                                 ,   ss_typename_type_k basic_simple_string<C, T, A>::value_type ch)
02186 {
02187     stlsoft_assert(is_valid_());
02188 
02189     size_type const len =   length();
02190 
02191     if(len != cch)
02192     {
02193         if(len < cch)
02194         {
02195             /* Expand the string, using self-assignemt. */
02196             assign(c_str(), cch);
02197 
02198             traits_type::assign(char_pointer_from_member_pointer_(m_buffer) + len, cch - len, ch);
02199         }
02200 
02201         string_buffer   *buffer     =   string_buffer_from_member_pointer_(m_buffer);
02202 
02203         buffer->length = cch;
02204         buffer->contents[buffer->length] = traits_type::to_char_type(0);
02205     }
02206 
02207     stlsoft_assert(is_valid_());
02208 }
02209 
02210 template<   ss_typename_param_k C
02211         ,   ss_typename_param_k T
02212         ,   ss_typename_param_k A
02213         >
02214 inline void basic_simple_string<C, T, A>::clear()
02215 {
02216     if(NULL != m_buffer)
02217     {
02218         string_buffer   *buffer =   string_buffer_from_member_pointer_(m_buffer);
02219 
02220         buffer->length      =   0;
02221         buffer->contents[0] =   traits_type::to_char_type(0);
02222     }
02223 }
02224 
02225 // Attributes
02226 template<   ss_typename_param_k C
02227         ,   ss_typename_param_k T
02228         ,   ss_typename_param_k A
02229         >
02230 inline ss_typename_type_k basic_simple_string<C, T, A>::size_type basic_simple_string<C, T, A>::size() const
02231 {
02232     stlsoft_assert(is_valid_());
02233 
02234     return (NULL == m_buffer) ? 0 : string_buffer_from_member_pointer_(m_buffer)->length;
02235 }
02236 
02237 template<   ss_typename_param_k C
02238         ,   ss_typename_param_k T
02239         ,   ss_typename_param_k A
02240         >
02241 inline ss_typename_type_k basic_simple_string<C, T, A>::size_type basic_simple_string<C, T, A>::max_size() const
02242 {
02243     stlsoft_assert(is_valid_());
02244 
02245     return static_cast<size_type>(-1) / sizeof(char_type);
02246 }
02247 
02248 template<   ss_typename_param_k C
02249         ,   ss_typename_param_k T
02250         ,   ss_typename_param_k A
02251         >
02252 inline ss_typename_type_k basic_simple_string<C, T, A>::size_type basic_simple_string<C, T, A>::length() const
02253 {
02254     stlsoft_assert(is_valid_());
02255 
02256     return size();
02257 }
02258 
02259 template<   ss_typename_param_k C
02260         ,   ss_typename_param_k T
02261         ,   ss_typename_param_k A
02262         >
02263 inline ss_typename_type_k basic_simple_string<C, T, A>::size_type basic_simple_string<C, T, A>::capacity() const
02264 {
02265     stlsoft_assert(is_valid_());
02266 
02267     return (NULL == m_buffer) ? 0 : string_buffer_from_member_pointer_(m_buffer)->capacity;
02268 }
02269 
02270 template<   ss_typename_param_k C
02271         ,   ss_typename_param_k T
02272         ,   ss_typename_param_k A
02273         >
02274 inline ss_bool_t basic_simple_string<C, T, A>::empty() const
02275 {
02276     stlsoft_assert(is_valid_());
02277 
02278     return 0 == length();
02279 }
02280 
02281 #endif /* !__STLSOFT_DOCUMENTATION_SKIP_SECTION */
02282 
02283 /* 
02284 
02286 
02287 /* 
02288 
02289 #ifndef _STLSOFT_NO_NAMESPACE
02290 } // namespace stlsoft
02291 #endif /* _STLSOFT_NO_NAMESPACE */
02292 
02293 /* 
02294 
02295 #endif /* !STLSOFT_INCL_H_STLSOFT_SIMPLE_STRING */
02296 
02297 /* 

STLSoft Libraries documentation © Synesis Software Pty Ltd, 2001-2004