OSDN Git Service

2009-12-03 Paolo Carlini <paolo.carlini@oracle.com>
[pf3gnuchains/gcc-fork.git] / libstdc++-v3 / include / bits / basic_string.h
index 19c79d1..a574bf6 100644 (file)
@@ -1,13 +1,13 @@
 // Components for manipulating sequences of characters -*- C++ -*-
 
 // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
-// 2006, 2007, 2008
+// 2006, 2007, 2008, 2009
 // Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
 // software; you can redistribute it and/or modify it under the
 // terms of the GNU General Public License as published by the
-// Free Software Foundation; either version 2, or (at your option)
+// Free Software Foundation; either version 3, or (at your option)
 // any later version.
 
 // This library is distributed in the hope that it will be useful,
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 // GNU General Public License for more details.
 
-// You should have received a copy of the GNU General Public License along
-// with this library; see the file COPYING.  If not, write to the Free
-// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
-// USA.
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
 
-// As a special exception, you may use this file as part of a free software
-// library without restriction.  Specifically, if other files instantiate
-// templates or use macros or inline functions from this file, or you compile
-// this file and link it with other files to produce an executable, this
-// file does not by itself cause the resulting executable to be covered by
-// the GNU General Public License.  This exception does not however
-// invalidate any other reasons why the executable file might be covered by
-// the GNU General Public License.
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+// <http://www.gnu.org/licenses/>.
 
 /** @file basic_string.h
  *  This is an internal header file, included by other library headers.
@@ -45,6 +40,7 @@
 
 #include <ext/atomicity.h>
 #include <debug/debug.h>
+#include <initializer_list>
 
 _GLIBCXX_BEGIN_NAMESPACE(std)
 
@@ -52,8 +48,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
    *  @class basic_string basic_string.h <string>
    *  @brief  Managing sequences of characters and character-like objects.
    *
-   *  @ingroup Containers
-   *  @ingroup Sequences
+   *  @ingroup sequences
    *
    *  Meets the requirements of a <a href="tables.html#65">container</a>, a
    *  <a href="tables.html#66">reversible container</a>, and a
@@ -202,12 +197,17 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
 
        void
        _M_set_length_and_sharable(size_type __n)
-       { 
-         this->_M_set_sharable();  // One reference.
-         this->_M_length = __n;
-         traits_type::assign(this->_M_refdata()[__n], _S_terminal);
-         // grrr. (per 21.3.4)
-         // You cannot leave those LWG people alone for a second.
+       {
+#ifndef _GLIBCXX_FULLY_DYNAMIC_STRING
+         if (__builtin_expect(this != &_S_empty_rep(), false))
+#endif
+           {
+             this->_M_set_sharable();  // One reference.
+             this->_M_length = __n;
+             traits_type::assign(this->_M_refdata()[__n], _S_terminal);
+             // grrr. (per 21.3.4)
+             // You cannot leave those LWG people alone for a second.
+           }
        }
 
        _CharT*
@@ -458,7 +458,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
        *  @param  n  Number of characters to copy.
        *  @param  a  Allocator to use (default is default allocator).
        *
-       *  NB: @a s must have at least @a n characters, '\0' has no special
+       *  NB: @a s must have at least @a n characters, '\\0' has no special
        *  meaning.
        */
       basic_string(const _CharT* __s, size_type __n,
@@ -477,6 +477,15 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
        */
       basic_string(size_type __n, _CharT __c, const _Alloc& __a = _Alloc());
 
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+      /**
+       *  @brief  Construct string from an initializer list.
+       *  @param  l  std::initializer_list of characters.
+       *  @param  a  Allocator to use (default is default allocator).
+       */
+      basic_string(initializer_list<_CharT> __l, const _Alloc& __a = _Alloc());
+#endif // __GXX_EXPERIMENTAL_CXX0X__
+
       /**
        *  @brief  Construct string as copy of a range.
        *  @param  beg  Start of range.
@@ -523,6 +532,19 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
        return *this;
       }
 
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+      /**
+       *  @brief  Set value to string constructed from initializer list.
+       *  @param  l  std::initializer_list.
+       */
+      basic_string&
+      operator=(initializer_list<_CharT> __l)
+      {
+       this->assign(__l.begin(), __l.size());
+       return *this;
+      }
+#endif // __GXX_EXPERIMENTAL_CXX0X__
+
       // Iterators:
       /**
        *  Returns a read/write iterator that points to the first character in
@@ -598,6 +620,42 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
       rend() const
       { return const_reverse_iterator(this->begin()); }
 
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+      /**
+       *  Returns a read-only (constant) iterator that points to the first
+       *  character in the %string.
+       */
+      const_iterator
+      cbegin() const
+      { return const_iterator(this->_M_data()); }
+
+      /**
+       *  Returns a read-only (constant) iterator that points one past the
+       *  last character in the %string.
+       */
+      const_iterator
+      cend() const
+      { return const_iterator(this->_M_data() + this->size()); }
+
+      /**
+       *  Returns a read-only (constant) reverse iterator that points
+       *  to the last character in the %string.  Iteration is done in
+       *  reverse element order.
+       */
+      const_reverse_iterator
+      crbegin() const
+      { return const_reverse_iterator(this->end()); }
+
+      /**
+       *  Returns a read-only (constant) reverse iterator that points
+       *  to one before the first character in the %string.  Iteration
+       *  is done in reverse element order.
+       */
+      const_reverse_iterator
+      crend() const
+      { return const_reverse_iterator(this->begin()); }
+#endif
+
     public:
       // Capacity:
       ///  Returns the number of characters in the string, not including any
@@ -794,6 +852,17 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
        return *this;
       }
 
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+      /**
+       *  @brief  Append an initializer_list of characters.
+       *  @param l  The initializer_list of characters to be appended.
+       *  @return  Reference to this string.
+       */
+      basic_string&
+      operator+=(initializer_list<_CharT> __l)
+      { return this->append(__l.begin(), __l.size()); }
+#endif // __GXX_EXPERIMENTAL_CXX0X__
+
       /**
        *  @brief  Append a string to this string.
        *  @param str  The string to append.
@@ -849,6 +918,17 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
       basic_string&
       append(size_type __n, _CharT __c);
 
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+      /**
+       *  @brief  Append an initializer_list of characters.
+       *  @param l  The initializer_list of characters to append.
+       *  @return  Reference to this string.
+       */
+      basic_string&
+      append(initializer_list<_CharT> __l)
+      { return this->append(__l.begin(), __l.size()); }
+#endif // __GXX_EXPERIMENTAL_CXX0X__
+
       /**
        *  @brief  Append a range of characters.
        *  @param first  Iterator referencing the first character to append.
@@ -957,6 +1037,17 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
         assign(_InputIterator __first, _InputIterator __last)
         { return this->replace(_M_ibegin(), _M_iend(), __first, __last); }
 
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+      /**
+       *  @brief  Set value to an initializer_list of characters.
+       *  @param l  The initializer_list of characters to assign.
+       *  @return  Reference to this string.
+       */
+      basic_string&
+      assign(initializer_list<_CharT> __l)
+      { return this->assign(__l.begin(), __l.size()); }
+#endif // __GXX_EXPERIMENTAL_CXX0X__
+
       /**
        *  @brief  Insert multiple characters.
        *  @param p  Iterator referencing location in string to insert at.
@@ -989,6 +1080,21 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
         insert(iterator __p, _InputIterator __beg, _InputIterator __end)
         { this->replace(__p, __p, __beg, __end); }
 
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+      /**
+       *  @brief  Insert an initializer_list of characters.
+       *  @param p  Iterator referencing location in string to insert at.
+       *  @param l  The initializer_list of characters to insert.
+       *  @throw  std::length_error  If new length exceeds @c max_size().
+       */
+      void
+      insert(iterator __p, initializer_list<_CharT> __l)
+      {
+       _GLIBCXX_DEBUG_PEDASSERT(__p >= _M_ibegin() && __p <= _M_iend());
+       this->insert(__p - _M_ibegin(), __l.begin(), __l.size());
+      }
+#endif // __GXX_EXPERIMENTAL_CXX0X__
+
       /**
        *  @brief  Insert value of a string.
        *  @param pos1  Iterator referencing location in string to insert at.
@@ -1164,16 +1270,8 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
        *  The value of the string doesn't change if an error is thrown.
       */
       iterator
-      erase(iterator __first, iterator __last)
-      {
-       _GLIBCXX_DEBUG_PEDASSERT(__first >= _M_ibegin() && __first <= __last
-                                && __last <= _M_iend());
-        const size_type __pos = __first - _M_ibegin();
-       _M_mutate(__pos, __last - __first, size_type(0));
-       _M_rep()->_M_set_leaked();
-       return iterator(_M_data() + __pos);
-      }
-
+      erase(iterator __first, iterator __last);
       /**
        *  @brief  Replace characters with value from another string.
        *  @param pos  Index of first character to replace.
@@ -1434,6 +1532,25 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
                             __k1.base(), __k2 - __k1);
       }
       
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+      /**
+       *  @brief  Replace range of characters with initializer_list.
+       *  @param i1  Iterator referencing start of range to replace.
+       *  @param i2  Iterator referencing end of range to replace.
+       *  @param l  The initializer_list of characters to insert.
+       *  @return  Reference to this string.
+       *  @throw  std::length_error  If new length exceeds @c max_size().
+       *
+       *  Removes the characters in the range [i1,i2).  In place, characters
+       *  in the range [k1,k2) are inserted.  If the length of result exceeds
+       *  max_size(), length_error is thrown.  The value of the string doesn't
+       *  change if an error is thrown.
+      */
+      basic_string& replace(iterator __i1, iterator __i2,
+                           initializer_list<_CharT> __l)
+      { return this->replace(__i1, __i2, __l.begin(), __l.end()); }
+#endif // __GXX_EXPERIMENTAL_CXX0X__
+
     private:
       template<class _Integer>
        basic_string&
@@ -1471,7 +1588,8 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
         static _CharT*
         _S_construct_aux(_Integer __beg, _Integer __end,
                         const _Alloc& __a, __true_type)
-        { return _S_construct(static_cast<size_type>(__beg), __end, __a); }
+        { return _S_construct(static_cast<size_type>(__beg),
+                             static_cast<value_type>(__end), __a); }
 
       template<class _InIterator>
         static _CharT*
@@ -2054,7 +2172,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
        *  result of the comparison is nonzero returns it, otherwise the shorter
        *  one is ordered first.
        *
-       *  NB: s must have at least n2 characters, '\0' has no special
+       *  NB: s must have at least n2 characters, '\\0' has no special
        *  meaning.
       */
       int
@@ -2475,7 +2593,8 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
 
 _GLIBCXX_END_NAMESPACE
 
-#if (defined(__GXX_EXPERIMENTAL_CXX0X__) && defined(_GLIBCXX_USE_C99))
+#if (defined(__GXX_EXPERIMENTAL_CXX0X__) && defined(_GLIBCXX_USE_C99) \
+     && !defined(_GLIBCXX_HAVE_BROKEN_VSWPRINTF))
 
 #include <ext/string_conversions.h>
 
@@ -2521,6 +2640,30 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
   { return __gnu_cxx::__stoa(&std::strtold, "stold", __str.c_str(), __idx); }
 
   // NB: (v)snprintf vs sprintf.
+
+  // DR 1261.
+  inline string
+  to_string(int __val)
+  { return __gnu_cxx::__to_xstring<string>(&std::vsnprintf, 4 * sizeof(int),
+                                          "%d", __val); }
+
+  inline string
+  to_string(unsigned __val)
+  { return __gnu_cxx::__to_xstring<string>(&std::vsnprintf,
+                                          4 * sizeof(unsigned),
+                                          "%u", __val); }
+
+  inline string
+  to_string(long __val)
+  { return __gnu_cxx::__to_xstring<string>(&std::vsnprintf, 4 * sizeof(long),
+                                          "%ld", __val); }
+
+  inline string
+  to_string(unsigned long __val)
+  { return __gnu_cxx::__to_xstring<string>(&std::vsnprintf,
+                                          4 * sizeof(unsigned long),
+                                          "%lu", __val); }
+
   inline string
   to_string(long long __val)
   { return __gnu_cxx::__to_xstring<string>(&std::vsnprintf,
@@ -2534,6 +2677,24 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
                                           "%llu", __val); }
 
   inline string
+  to_string(float __val)
+  {
+    const int __n = 
+      __gnu_cxx::__numeric_traits<float>::__max_exponent10 + 20;
+    return __gnu_cxx::__to_xstring<string>(&std::vsnprintf, __n,
+                                          "%f", __val);
+  }
+
+  inline string
+  to_string(double __val)
+  {
+    const int __n = 
+      __gnu_cxx::__numeric_traits<double>::__max_exponent10 + 20;
+    return __gnu_cxx::__to_xstring<string>(&std::vsnprintf, __n,
+                                          "%f", __val);
+  }
+
+  inline string
   to_string(long double __val)
   {
     const int __n = 
@@ -2581,6 +2742,29 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
   stold(const wstring& __str, size_t* __idx = 0)
   { return __gnu_cxx::__stoa(&std::wcstold, "stold", __str.c_str(), __idx); }
 
+  // DR 1261.
+  inline wstring
+  to_wstring(int __val)
+  { return __gnu_cxx::__to_xstring<wstring>(&std::vswprintf, 4 * sizeof(int),
+                                           L"%d", __val); }
+
+  inline wstring
+  to_wstring(unsigned __val)
+  { return __gnu_cxx::__to_xstring<wstring>(&std::vswprintf,
+                                           4 * sizeof(unsigned),
+                                           L"%u", __val); }
+
+  inline wstring
+  to_wstring(long __val)
+  { return __gnu_cxx::__to_xstring<wstring>(&std::vswprintf, 4 * sizeof(long),
+                                           L"%ld", __val); }
+
+  inline wstring
+  to_wstring(unsigned long __val)
+  { return __gnu_cxx::__to_xstring<wstring>(&std::vswprintf,
+                                           4 * sizeof(unsigned long),
+                                           L"%lu", __val); }
+
   inline wstring
   to_wstring(long long __val)
   { return __gnu_cxx::__to_xstring<wstring>(&std::vswprintf,
@@ -2594,6 +2778,24 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
                                            L"%llu", __val); }
 
   inline wstring
+  to_wstring(float __val)
+  {
+    const int __n =
+      __gnu_cxx::__numeric_traits<float>::__max_exponent10 + 20;
+    return __gnu_cxx::__to_xstring<wstring>(&std::vswprintf, __n,
+                                           L"%f", __val);
+  }
+
+  inline wstring
+  to_wstring(double __val)
+  {
+    const int __n =
+      __gnu_cxx::__numeric_traits<double>::__max_exponent10 + 20;
+    return __gnu_cxx::__to_xstring<wstring>(&std::vswprintf, __n,
+                                           L"%f", __val);
+  }
+
+  inline wstring
   to_wstring(long double __val)
   {
     const int __n =