This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[RFC 2/2] libstdc++: Add codecvt<char32_t, char, mbstate_t>.


UTF-32/UTF-8 codec converter (codecvt) specialization.

C++11: [locale.codecvt]

* libstdc++-v3/config/abi/pre/gnu.ver: Add vtable/typeinfo for
  __codecvt_abstract_base<char32_t, char, mbstate_t>.
* libstdc++-v3/include/bits/codecvt.h (codecvt<char32_t, char,
  mbstate_t>): New specialization.
* libstdc++-v3/src/c++11/codecvt.cc (codecvt<char32_t, char,
  mbstate_t>): Same.
  (utf32_to_utf8, utf8_to_utf32, utf8_to_utf32_length): New local
  functions.
  (use_facet<codecvt<char32_t, char, mbstate_t> >)
  (has_facet<codecvt<char32_t, char, mbstate_t> >): New specialization.
* libstdc++-v3/include/bits/locale_facets.h (_GLIBCXX_NUM_FACETS):
  Updated for char32_t facets
* libstdc++-v3/src/c++11/Makefile.am: Add locale_init.cc,
  localename.cc, and c32locale-inst.cc.
* libstdc++-v3/src/c++11/Makefile.in: Updated.
* libstdc++-v3/src/c++11/c32locale-inst.cc: New file.
* libstdc++-v3/src/c++11/locale_init.cc: Moved file and added
  codecvt<char32_t, char, mbstate_t> facet.
* libstdc++-v3/src/c++11/localename.cc: Moved file and added
  codecvt<char32_t, char, mbstate_t> facet.
* libstdc++-v3/src/c++98/Makefile.am: Removed localename.cc and
  locale_init.cc.
* libstdc++-v3/src/c++98/Makefile.in: Updated.
* libstdc++-v3/testsuite/22_locale/codecvt/char32_t/1.cc: New test.
---
 libstdc++-v3/config/abi/pre/gnu.ver                |   5 +
 libstdc++-v3/include/bits/codecvt.h                |  76 ++++
 libstdc++-v3/include/bits/locale_facets.h          |   6 +-
 libstdc++-v3/src/c++11/Makefile.am                 |   5 +-
 libstdc++-v3/src/c++11/Makefile.in                 |  14 +-
 libstdc++-v3/src/c++11/c32locale-inst.cc           |  57 +++
 libstdc++-v3/src/c++11/codecvt.cc                  | 259 +++++++++++
 libstdc++-v3/src/c++11/locale_init.cc              | 487 +++++++++++++++++++++
 libstdc++-v3/src/c++11/localename.cc               | 357 +++++++++++++++
 libstdc++-v3/src/c++98/Makefile.am                 |   2 -
 libstdc++-v3/src/c++98/Makefile.in                 |   9 +-
 libstdc++-v3/src/c++98/locale_init.cc              | 472 --------------------
 libstdc++-v3/src/c++98/localename.cc               | 352 ---------------
 .../testsuite/22_locale/codecvt/char32_t/1.cc      | 101 +++++
 14 files changed, 1362 insertions(+), 840 deletions(-)
 create mode 100644 libstdc++-v3/src/c++11/c32locale-inst.cc
 create mode 100644 libstdc++-v3/src/c++11/locale_init.cc
 create mode 100644 libstdc++-v3/src/c++11/localename.cc
 delete mode 100644 libstdc++-v3/src/c++98/locale_init.cc
 delete mode 100644 libstdc++-v3/src/c++98/localename.cc
 create mode 100644 libstdc++-v3/testsuite/22_locale/codecvt/char32_t/1.cc

diff --git a/libstdc++-v3/config/abi/pre/gnu.ver b/libstdc++-v3/config/abi/pre/gnu.ver
index f0ce4f0..e1e75e0 100644
--- a/libstdc++-v3/config/abi/pre/gnu.ver
+++ b/libstdc++-v3/config/abi/pre/gnu.ver
@@ -1365,6 +1365,11 @@ GLIBCXX_3.4.20 {
     # std::regex_error::regex_error(std::regex_constants::error_type)
     _ZNSt11regex_errorC[01]ENSt15regex_constants10error_typeE;
 
+    # typeinfo, vtable for __codecvt_abstract_base<char32_t, char, mbstate_t>
+    _ZTVSt23__codecvt_abstract_baseIDic11__mbstate_tE;
+    _ZTISt23__codecvt_abstract_baseIDic11__mbstate_tE;
+    _ZTSSt23__codecvt_abstract_baseIDic11__mbstate_tE;
+
 } GLIBCXX_3.4.19;
 
 # Symbols in the support library (libsupc++) have their own tag.
diff --git a/libstdc++-v3/include/bits/codecvt.h b/libstdc++-v3/include/bits/codecvt.h
index 18038e1..80ef606 100644
--- a/libstdc++-v3/include/bits/codecvt.h
+++ b/libstdc++-v3/include/bits/codecvt.h
@@ -453,6 +453,71 @@ namespace std _GLIBCXX_VISIBILITY(default)
     };
 #endif //_GLIBCXX_USE_WCHAR_T
 
+#if __cplusplus >= 201103L && defined(_GLIBCXX_USE_C99_STDINT_TR1)
+  /**
+   *  @brief class codecvt<char32_t, char, mbstate_t> specialization.
+   *
+   *  Converts between UTF-32 and UTF-8.
+   */
+  template<>
+    class codecvt<char32_t, char, mbstate_t>
+    : public __codecvt_abstract_base<char32_t, char, mbstate_t>
+    {
+    public:
+      // Types:
+      typedef char32_t			intern_type;
+      typedef char			extern_type;
+      typedef mbstate_t			state_type;
+
+    protected:
+      __c_locale			_M_c_locale_codecvt;
+
+    public:
+      static locale::id			id;
+
+      explicit
+      codecvt(size_t __refs = 0);
+
+      explicit
+      codecvt(__c_locale __cloc, size_t __refs = 0);
+
+    protected:
+      virtual
+      ~codecvt();
+
+      virtual result
+      do_out(state_type& __state, const intern_type* __from,
+	     const intern_type* __from_end, const intern_type*& __from_next,
+	     extern_type* __to, extern_type* __to_end,
+	     extern_type*& __to_next) const;
+
+      virtual result
+      do_unshift(state_type& __state,
+		 extern_type* __to, extern_type* __to_end,
+		 extern_type*& __to_next) const;
+
+      virtual result
+      do_in(state_type& __state,
+	     const extern_type* __from, const extern_type* __from_end,
+	     const extern_type*& __from_next,
+	     intern_type* __to, intern_type* __to_end,
+	     intern_type*& __to_next) const;
+
+      virtual
+      int do_encoding() const _GLIBCXX_NOEXCEPT;
+
+      virtual
+      bool do_always_noconv() const _GLIBCXX_NOEXCEPT;
+
+      virtual
+      int do_length(state_type&, const extern_type* __from,
+		    const extern_type* __end, size_t __max) const;
+
+      virtual int
+      do_max_length() const _GLIBCXX_NOEXCEPT;
+    };
+#endif // __cplusplus >= 201103L && defined(_GLIBCXX_USE_C99_STDINT_TR1)
+
   /// class codecvt_byname [22.2.1.6].
   template<typename _InternT, typename _ExternT, typename _StateT>
     class codecvt_byname : public codecvt<_InternT, _ExternT, _StateT>
@@ -499,8 +564,19 @@ namespace std _GLIBCXX_VISIBILITY(default)
     bool
     has_facet<codecvt<wchar_t, char, mbstate_t> >(const locale&);
 #endif
+
+#if __cplusplus >= 201103L && defined(_GLIBCXX_USE_C99_STDINT_TR1)
+  extern template
+    const codecvt<char32_t, char, mbstate_t>&
+    use_facet<codecvt<char32_t, char, mbstate_t> >(const locale&);
+
+  extern template
+    bool
+    has_facet<codecvt<char32_t, char, mbstate_t> >(const locale&);
 #endif
 
+#endif // _GLIBCXX_EXTERN_TEMPLATE
+
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace std
 
diff --git a/libstdc++-v3/include/bits/locale_facets.h b/libstdc++-v3/include/bits/locale_facets.h
index 453bbed..17eef49 100644
--- a/libstdc++-v3/include/bits/locale_facets.h
+++ b/libstdc++-v3/include/bits/locale_facets.h
@@ -51,8 +51,10 @@ namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
-  // NB: Don't instantiate required wchar_t facets if no wchar_t support.
-#ifdef _GLIBCXX_USE_WCHAR_T
+  // NB: Don't instantiate required wchar_t/char*_t facets if no wchar_t/char*_t support.
+#ifdef _GLIBCXX_USE_C99_STDINT_TR1
+# define  _GLIBCXX_NUM_FACETS 42 // TODO
+#elif defined(_GLIBCXX_USE_WCHAR_T)
 # define  _GLIBCXX_NUM_FACETS 28
 #else
 # define  _GLIBCXX_NUM_FACETS 14
diff --git a/libstdc++-v3/src/c++11/Makefile.am b/libstdc++-v3/src/c++11/Makefile.am
index 921a3a7..c555c9e 100644
--- a/libstdc++-v3/src/c++11/Makefile.am
+++ b/libstdc++-v3/src/c++11/Makefile.am
@@ -38,6 +38,8 @@ sources = \
 	hash_c++0x.cc \
 	hashtable_c++0x.cc \
 	limits.cc \
+	locale_init.cc \
+	localename.cc \
 	mutex.cc \
 	placeholders.cc \
 	random.cc \
@@ -52,7 +54,8 @@ if ENABLE_EXTERN_TEMPLATE
 inst_sources = \
 	fstream-inst.cc \
 	string-inst.cc \
-	wstring-inst.cc
+	wstring-inst.cc \
+	c32locale-inst.cc
 else
 # XTEMPLATE_FLAGS =
 inst_sources =
diff --git a/libstdc++-v3/src/c++11/Makefile.in b/libstdc++-v3/src/c++11/Makefile.in
index d5143c4..f3839c5 100644
--- a/libstdc++-v3/src/c++11/Makefile.in
+++ b/libstdc++-v3/src/c++11/Makefile.in
@@ -69,11 +69,12 @@ LTLIBRARIES = $(noinst_LTLIBRARIES)
 libc__11convenience_la_LIBADD =
 am__objects_1 = chrono.lo condition_variable.lo codecvt.lo debug.lo \
 	functexcept.lo functional.lo future.lo hash_c++0x.lo \
-	hashtable_c++0x.lo limits.lo mutex.lo placeholders.lo \
-	random.lo regex.lo shared_ptr.lo snprintf_lite.lo \
-	system_error.lo thread.lo
+	hashtable_c++0x.lo limits.lo locale_init.lo localename.lo \
+	mutex.lo placeholders.lo random.lo regex.lo shared_ptr.lo \
+	snprintf_lite.lo system_error.lo thread.lo
 @ENABLE_EXTERN_TEMPLATE_TRUE@am__objects_2 = fstream-inst.lo \
-@ENABLE_EXTERN_TEMPLATE_TRUE@	string-inst.lo wstring-inst.lo
+@ENABLE_EXTERN_TEMPLATE_TRUE@	string-inst.lo wstring-inst.lo \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	c32locale-inst.lo
 am_libc__11convenience_la_OBJECTS = $(am__objects_1) $(am__objects_2)
 libc__11convenience_la_OBJECTS = $(am_libc__11convenience_la_OBJECTS)
 DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
@@ -321,6 +322,8 @@ sources = \
 	hash_c++0x.cc \
 	hashtable_c++0x.cc \
 	limits.cc \
+	locale_init.cc \
+	localename.cc \
 	mutex.cc \
 	placeholders.cc \
 	random.cc \
@@ -337,7 +340,8 @@ sources = \
 @ENABLE_EXTERN_TEMPLATE_TRUE@inst_sources = \
 @ENABLE_EXTERN_TEMPLATE_TRUE@	fstream-inst.cc \
 @ENABLE_EXTERN_TEMPLATE_TRUE@	string-inst.cc \
-@ENABLE_EXTERN_TEMPLATE_TRUE@	wstring-inst.cc
+@ENABLE_EXTERN_TEMPLATE_TRUE@	wstring-inst.cc \
+@ENABLE_EXTERN_TEMPLATE_TRUE@	c32locale-inst.cc
 
 libc__11convenience_la_SOURCES = $(sources)  $(inst_sources)
 
diff --git a/libstdc++-v3/src/c++11/c32locale-inst.cc b/libstdc++-v3/src/c++11/c32locale-inst.cc
new file mode 100644
index 0000000..442f862
--- /dev/null
+++ b/libstdc++-v3/src/c++11/c32locale-inst.cc
@@ -0,0 +1,57 @@
+// Locale support -*- C++ -*-
+
+// Copyright (C) 2014 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 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// 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.
+
+// 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/>.
+
+//
+// ISO C++ 14882: 22.1  Locales
+//
+
+#include <locale>
+#include <bits/c++config.h>
+
+#ifdef _GLIBCXX_USE_C99_STDINT_TR1
+
+#define C char32_t
+
+//#include "../c++98/locale-inst.cc"
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+  // codecvt
+  inline template class __codecvt_abstract_base<C, char, mbstate_t>;
+  template class codecvt_byname<C, char, mbstate_t>;
+
+  template
+    const codecvt<C, char, mbstate_t>&
+    use_facet<codecvt<C, char, mbstate_t> >(const locale&);
+
+  template
+    bool
+    has_facet<codecvt<C, char, mbstate_t> >(const locale&);
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace std
+
+#endif //_GLIBCXX_USE_C99_STDINT_TR1
diff --git a/libstdc++-v3/src/c++11/codecvt.cc b/libstdc++-v3/src/c++11/codecvt.cc
index 7c94c38..1f3a718 100644
--- a/libstdc++-v3/src/c++11/codecvt.cc
+++ b/libstdc++-v3/src/c++11/codecvt.cc
@@ -35,6 +35,10 @@ namespace std _GLIBCXX_VISIBILITY(default)
   locale::id codecvt<wchar_t, char, mbstate_t>::id;
 #endif
 
+#ifdef _GLIBCXX_USE_C99_STDINT_TR1
+  locale::id codecvt<char32_t, char, mbstate_t>::id;
+#endif
+
   codecvt<char, char, mbstate_t>::
   codecvt(size_t __refs)
   : __codecvt_abstract_base<char, char, mbstate_t>(__refs),
@@ -147,5 +151,260 @@ namespace std _GLIBCXX_VISIBILITY(default)
   { return false; }
 #endif //  _GLIBCXX_USE_WCHAR_T
 
+#ifdef _GLIBCXX_USE_C99_STDINT_TR1
+
+  // UTF-8 implementation.
+  namespace
+  {
+    codecvt_base::result
+    utf32_to_utf8(const char32_t* from, const char32_t* from_end,
+                  const char32_t*& from_next,
+                  char* to, char* to_end, char*& to_next,
+                  unsigned long maxcode = 0x10FFFF)
+    {
+      for (from_next = from, to_next = to;
+           from_next != from_end and to_next != to_end;
+           ++from_next)
+        {
+          if (*from_next > maxcode)
+            return codecvt_base::error;
+          else if (*from_next <= 0x7F)
+            *to_next++ = uint8_t(*from_next);
+          else if (0x80 <= *from_next and *from_next <= 0x7FF)
+            {
+              if (to_end - to_next < 2)
+                return codecvt_base::partial;
+              // 00000yyy yyxxxxxx
+              *to_next++ = (*from_next >> 6)   | 0xC0; // 110yyyyy
+              *to_next++ = (*from_next & 0x3F) | 0x80; // 10xxxxxx
+            }
+          else if ( (0x800 <= *from_next and *from_next < 0xD800) or
+                    (0xDFFF < *from_next and *from_next <= 0xFFFF))
+            // exclude surrogate pairs (0xD800 to 0xDFFF)
+            {
+              if (to_end - to_next < 3)
+                return codecvt_base::partial;
+              // zzzzyyyy yyxxxxxx
+              *to_next++ = (*from_next  >> 12)        | 0xE0; // 1110zzzz
+              *to_next++ = ((*from_next >> 6) & 0x3F) | 0x80; // 10yyyyyy
+              *to_next++ = (*from_next & 0x3F)        | 0x80; // 10xxxxxx
+            }
+          else if (0x10000 <= *from_next and *from_next <= 0x10FFFF)
+            {
+              if (to_end - to_next < 4)
+                return codecvt_base::partial;
+              // 000uuuzzzzzzyyyy yyxxxxxx
+              *to_next++ = (*from_next  >> 18)         | 0xF0; // 11110uuu
+              *to_next++ = ((*from_next >> 12) & 0x3F) | 0x80; // 10zzzzzz
+              *to_next++ = ((*from_next >> 6)  & 0x3F) | 0x80; // 10yyyyyy
+              *to_next++ = (*from_next         & 0x3F) | 0x80; // 10xxxxxx
+            }
+          else
+            return codecvt_base::error;
+        }
+      if (to_next == to_end && from != from_end)
+        return codecvt_base::partial;
+      else
+        return codecvt_base::ok;
+    }
+
+    codecvt_base::result
+    utf8_to_utf32(const char* from, const char* from_end,
+                  const char*& from_next,
+                  char32_t* to, char32_t* to_end, char32_t*& to_next,
+                  unsigned long maxcode = 0x10FFFF)
+    {
+      // TODO reset from_next on error?
+      for(from_next = from, to_next = to; to_next != to_end; ++from_next)
+        {
+          const size_t len = from_end - from_next;
+          if (len >= 4 and (*from_next & 0xF0) == 0xF0)
+            {
+              const uint32_t first = *from_next++ & 0x07;
+
+              if ((*from_next & 0x80) != 0x80)
+                return codecvt_base::error;
+              const uint32_t second = *from_next++ & 0x3F;
+
+              if ((*from_next & 0x80 ) != 0x80)
+                return codecvt_base::error;
+              const uint32_t third = *from_next++ & 0x3F;
+
+              if ((*from_next & 0x80) != 0x80)
+                return codecvt_base::error;
+
+              *to_next = ((first << 18) | (second << 12) | (third << 6)
+                          | (*from_next & 0x3F));
+              if (*to_next > maxcode)
+                return codecvt_base::error;
+              ++to_next;
+            }
+          else if (len >= 3 and (*from_next & 0xE0) == 0xE0)
+            {
+              const uint32_t first = *from_next++ & 0x0F;
+
+              if ((*from_next & 0x80) != 0x80)
+                return codecvt_base::error;
+              const uint32_t second = *from_next++ & 0x3F;
+
+              if ((*from_next & 0x80) != 0x80)
+                return codecvt_base::error;
+
+              *to_next = (first << 12) | (second << 6) | (*from_next & 0x3F);
+              if (*to_next > maxcode)
+                return codecvt_base::error;
+              ++to_next;
+            }
+          else if (len >= 2 and (*from_next & 0xC0) == 0xC0)
+            {
+              const uint32_t first = *from_next++ & 0x1F;
+
+              if ((*from_next & 0x80) != 0x80)
+                return codecvt_base::error;
+
+              *to_next = (first << 6) | (*from_next & 0x3F);
+              if (*to_next > maxcode)
+                return codecvt_base::error;
+              ++to_next;
+            }
+          else if (len >= 1 and (*from_next & 0x7F) == *from_next)
+            {
+              *to_next = uint8_t(*from_next);
+              if (*to_next > maxcode)
+                return codecvt_base::error;
+              ++to_next;
+            }
+          else if (len == 0)
+            break;
+          else
+            return codecvt_base::partial;
+        }
+      if (to_next == to_end && from != from_end)
+        return codecvt_base::partial;
+      else
+        return codecvt_base::ok;
+    }
+
+    int
+    utf8_to_utf32_length(const char* from, const char* from_end,
+                         size_t max,
+                         unsigned long maxcode = 0x10FFFF)
+    {
+      const char* from_next = from;
+      for(size_t count = 0; count < max; ++count, ++from_next)
+        {
+          const size_t len = from_end - from_next;
+          if (len >= 4 and (*from_next & 0xF0) == 0xF0)
+            {
+              const uint32_t first = *from_next++ & 0x07;
+              if ((*from_next & 0x80) != 0x80)
+                return (from_next - from) - 1;
+              const uint32_t second = *from_next++ & 0x3F;
+              if ((*from_next & 0x80 ) != 0x80)
+                return (from_next - from) - 2;
+              const uint32_t third = *from_next++ & 0x3F;
+              if ((*from_next & 0x80) != 0x80)
+                return (from_next - from) - 3;
+              const char32_t cp = (first << 18) | (second << 12) | (third << 6)
+                | (*from_next & 0x3F);
+              if (cp > maxcode)
+                return (from_next - from) - 3;
+            }
+          else if (len >= 3 and (*from_next & 0xE0) == 0xE0)
+            {
+              const uint32_t first = *from_next++ & 0x0F;
+              if ((*from_next & 0x80) != 0x80)
+                return (from_next - from) - 1;
+              const uint32_t second = *from_next++ & 0x3F;
+              if ((*from_next & 0x80 ) != 0x80)
+                return (from_next - from) - 2;
+              const char32_t cp = (first << 12) | (second << 6)
+                | (*from_next & 0x3F);
+              if (cp > maxcode)
+                return (from_next - from) - 2;
+            }
+          else if (len >= 2 and (*from_next & 0xC0) == 0xC0)
+            {
+              const uint32_t first = *from_next++ & 0x1F;
+              if ((*from_next & 0x80) != 0x80)
+                return (from_next - from) - 1;
+              const char32_t cp = (first << 6) | (*from_next & 0x3F);
+              if (cp > maxcode)
+                return (from_next - from) - 1;
+            }
+          else if (len >= 1 and (*from_next & 0x7F) == *from_next)
+            {
+              if (uint8_t(*from_next) > maxcode)
+                break;
+            }
+          else
+            break;
+        }
+      return from_next - from;
+    }
+  } // anonymous namespace
+
+  // codecvt<char32_t, char, mbstate_t> required specialization
+  codecvt<char32_t, char, mbstate_t>::
+  codecvt(size_t __refs)
+    : __codecvt_abstract_base<char32_t, char, mbstate_t>(__refs),
+    _M_c_locale_codecvt(_S_get_c_locale())
+  { }
+
+  codecvt<char32_t, char, mbstate_t>::
+  codecvt(__c_locale __cloc, size_t __refs)
+    : __codecvt_abstract_base<char32_t, char, mbstate_t>(__refs),
+    _M_c_locale_codecvt(_S_clone_c_locale(__cloc))
+  { }
+
+  codecvt<char32_t, char, mbstate_t>::
+  ~codecvt()
+  { _S_destroy_c_locale(_M_c_locale_codecvt); }
+
+  codecvt_base::result
+  codecvt<char32_t, char, mbstate_t>::
+  do_out(mbstate_t&, const char32_t* from, const char32_t* from_end,
+         const char32_t*& from_next, char* to, char* to_end,
+         char*& to_next) const
+  { return utf32_to_utf8(from, from_end, from_next, to, to_end, to_next); }
+
+  codecvt_base::result
+  codecvt<char32_t, char, mbstate_t>::
+  do_unshift(state_type&, extern_type* __to,
+	     extern_type*, extern_type*& __to_next) const
+  {
+    __to_next = __to;
+    return noconv;
+  }
+
+  codecvt_base::result
+  codecvt<char32_t, char, mbstate_t>::
+  do_in(mbstate_t&, const char* from, const char* from_end,
+        const char*& from_next, char32_t* to, char32_t* to_end,
+        char32_t*& to_next) const
+  { return utf8_to_utf32(from, from_end, from_next, to, to_end, to_next); }
+
+  int
+  codecvt<char32_t, char, mbstate_t>::
+  do_encoding() const _GLIBCXX_NOEXCEPT
+  { return 0; }
+
+  bool
+  codecvt<char32_t, char, mbstate_t>::
+  do_always_noconv() const _GLIBCXX_NOEXCEPT
+  { return false; }
+
+  int
+  codecvt<char32_t, char, mbstate_t>::
+  do_length(state_type&, const extern_type* __from,
+            const extern_type* __end, size_t __max) const
+  { return utf8_to_utf32_length(__from, __end, __max); }
+
+  int
+  codecvt<char32_t, char, mbstate_t>::
+  do_max_length() const _GLIBCXX_NOEXCEPT
+  { return 4; }
+#endif // _GLIBCXX_USE_C99_STDINT_TR1
+
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace std
diff --git a/libstdc++-v3/src/c++11/locale_init.cc b/libstdc++-v3/src/c++11/locale_init.cc
new file mode 100644
index 0000000..80405fe
--- /dev/null
+++ b/libstdc++-v3/src/c++11/locale_init.cc
@@ -0,0 +1,487 @@
+// Copyright (C) 1997-2014 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 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// 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.
+
+// 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/>.
+
+#include <clocale>
+#include <cstring>
+#include <cstdlib>     // For getenv, free.
+#include <cctype>
+#include <cwctype>     // For towupper, etc.
+#include <locale>
+#include <ext/concurrence.h>
+
+namespace 
+{
+  __gnu_cxx::__mutex&
+  get_locale_mutex()
+  {
+    static __gnu_cxx::__mutex locale_mutex;
+    return locale_mutex;
+  }
+
+  using namespace std;
+
+  typedef char fake_locale_Impl[sizeof(locale::_Impl)]
+  __attribute__ ((aligned(__alignof__(locale::_Impl))));
+  fake_locale_Impl c_locale_impl;
+
+  typedef char fake_locale[sizeof(locale)]
+  __attribute__ ((aligned(__alignof__(locale))));
+  fake_locale c_locale;
+
+  typedef char fake_name_vec[sizeof(char*)]
+  __attribute__ ((aligned(__alignof__(char*))));
+  fake_name_vec name_vec[6 + _GLIBCXX_NUM_CATEGORIES];
+
+  typedef char fake_names[sizeof(char[2])]
+  __attribute__ ((aligned(__alignof__(char[2]))));
+  fake_names name_c[6 + _GLIBCXX_NUM_CATEGORIES];
+
+  typedef char fake_facet_vec[sizeof(locale::facet*)]
+  __attribute__ ((aligned(__alignof__(locale::facet*))));
+  fake_facet_vec facet_vec[_GLIBCXX_NUM_FACETS];
+
+  typedef char fake_cache_vec[sizeof(locale::facet*)]
+  __attribute__ ((aligned(__alignof__(locale::facet*))));
+  fake_cache_vec cache_vec[_GLIBCXX_NUM_FACETS];
+
+  typedef char fake_ctype_c[sizeof(std::ctype<char>)]
+  __attribute__ ((aligned(__alignof__(std::ctype<char>))));
+  fake_ctype_c ctype_c;
+
+  typedef char fake_collate_c[sizeof(std::collate<char>)]
+  __attribute__ ((aligned(__alignof__(std::collate<char>))));
+  fake_collate_c collate_c;
+
+  typedef char fake_numpunct_c[sizeof(numpunct<char>)]
+  __attribute__ ((aligned(__alignof__(numpunct<char>))));
+  fake_numpunct_c numpunct_c;
+
+  typedef char fake_num_get_c[sizeof(num_get<char>)]
+  __attribute__ ((aligned(__alignof__(num_get<char>))));
+  fake_num_get_c num_get_c;
+
+  typedef char fake_num_put_c[sizeof(num_put<char>)]
+  __attribute__ ((aligned(__alignof__(num_put<char>))));
+  fake_num_put_c num_put_c;
+
+  typedef char fake_codecvt_c[sizeof(codecvt<char, char, mbstate_t>)]
+  __attribute__ ((aligned(__alignof__(codecvt<char, char, mbstate_t>))));
+  fake_codecvt_c codecvt_c;
+
+  typedef char fake_moneypunct_c[sizeof(moneypunct<char, true>)]
+  __attribute__ ((aligned(__alignof__(moneypunct<char, true>))));
+  fake_moneypunct_c moneypunct_ct;
+  fake_moneypunct_c moneypunct_cf;
+
+  typedef char fake_money_get_c[sizeof(money_get<char>)]
+  __attribute__ ((aligned(__alignof__(money_get<char>))));
+  fake_money_get_c money_get_c;
+  
+  typedef char fake_money_put_c[sizeof(money_put<char>)]
+  __attribute__ ((aligned(__alignof__(money_put<char>))));
+  fake_money_put_c money_put_c;
+
+  typedef char fake_timepunct_c[sizeof(__timepunct<char>)]
+  __attribute__ ((aligned(__alignof__(__timepunct<char>))));
+  fake_timepunct_c timepunct_c;
+
+  typedef char fake_time_get_c[sizeof(time_get<char>)]
+  __attribute__ ((aligned(__alignof__(time_get<char>))));
+  fake_time_get_c time_get_c;
+
+  typedef char fake_time_put_c[sizeof(time_put<char>)]
+  __attribute__ ((aligned(__alignof__(time_put<char>))));
+  fake_time_put_c time_put_c;
+
+  typedef char fake_messages_c[sizeof(messages<char>)]
+  __attribute__ ((aligned(__alignof__(messages<char>))));
+  fake_messages_c messages_c;
+
+#ifdef  _GLIBCXX_USE_WCHAR_T
+  typedef char fake_wtype_w[sizeof(std::ctype<wchar_t>)]
+  __attribute__ ((aligned(__alignof__(std::ctype<wchar_t>))));
+  fake_wtype_w ctype_w;
+
+  typedef char fake_wollate_w[sizeof(std::collate<wchar_t>)]
+  __attribute__ ((aligned(__alignof__(std::collate<wchar_t>))));
+  fake_wollate_w collate_w;
+
+  typedef char fake_numpunct_w[sizeof(numpunct<wchar_t>)]
+  __attribute__ ((aligned(__alignof__(numpunct<wchar_t>))));
+  fake_numpunct_w numpunct_w;
+
+  typedef char fake_num_get_w[sizeof(num_get<wchar_t>)]
+  __attribute__ ((aligned(__alignof__(num_get<wchar_t>))));
+  fake_num_get_w num_get_w;
+
+  typedef char fake_num_put_w[sizeof(num_put<wchar_t>)]
+  __attribute__ ((aligned(__alignof__(num_put<wchar_t>))));
+  fake_num_put_w num_put_w;
+
+  typedef char fake_wodecvt_w[sizeof(codecvt<wchar_t, char, mbstate_t>)]
+  __attribute__ ((aligned(__alignof__(codecvt<wchar_t, char, mbstate_t>))));
+  fake_wodecvt_w codecvt_w;
+
+  typedef char fake_moneypunct_w[sizeof(moneypunct<wchar_t, true>)]
+  __attribute__ ((aligned(__alignof__(moneypunct<wchar_t, true>))));
+  fake_moneypunct_w moneypunct_wt;
+  fake_moneypunct_w moneypunct_wf;
+
+  typedef char fake_money_get_w[sizeof(money_get<wchar_t>)]
+  __attribute__ ((aligned(__alignof__(money_get<wchar_t>))));
+  fake_money_get_w money_get_w;
+  
+  typedef char fake_money_put_w[sizeof(money_put<wchar_t>)]
+  __attribute__ ((aligned(__alignof__(money_put<wchar_t>))));
+  fake_money_put_w money_put_w;
+
+  typedef char fake_timepunct_w[sizeof(__timepunct<wchar_t>)]
+  __attribute__ ((aligned(__alignof__(__timepunct<wchar_t>))));
+  fake_timepunct_w timepunct_w;
+
+  typedef char fake_time_get_w[sizeof(time_get<wchar_t>)]
+  __attribute__ ((aligned(__alignof__(time_get<wchar_t>))));
+  fake_time_get_w time_get_w;
+
+  typedef char fake_time_put_w[sizeof(time_put<wchar_t>)]
+  __attribute__ ((aligned(__alignof__(time_put<wchar_t>))));
+  fake_time_put_w time_put_w;
+
+  typedef char fake_messages_w[sizeof(messages<wchar_t>)]
+  __attribute__ ((aligned(__alignof__(messages<wchar_t>))));
+  fake_messages_w messages_w;
+#endif
+
+#ifdef _GLIBCXX_USE_C99_STDINT_TR1
+  typedef char fake_codecvt_c32[sizeof(codecvt<char32_t, char, mbstate_t>)]
+  __attribute__ ((aligned(__alignof__(codecvt<char32_t, char, mbstate_t>))));
+  fake_codecvt_c32 codecvt_c32;
+#endif //_GLIBCXX_USE_C99_STDINT_TR1
+
+  // Storage for "C" locale caches.
+  typedef char fake_num_cache_c[sizeof(std::__numpunct_cache<char>)]
+  __attribute__ ((aligned(__alignof__(std::__numpunct_cache<char>))));
+  fake_num_cache_c numpunct_cache_c;
+
+  typedef char fake_money_cache_c[sizeof(std::__moneypunct_cache<char, true>)]
+  __attribute__ ((aligned(__alignof__(std::__moneypunct_cache<char, true>))));
+  fake_money_cache_c moneypunct_cache_ct;
+  fake_money_cache_c moneypunct_cache_cf;
+
+  typedef char fake_time_cache_c[sizeof(std::__timepunct_cache<char>)]
+  __attribute__ ((aligned(__alignof__(std::__timepunct_cache<char>))));
+  fake_time_cache_c timepunct_cache_c;
+
+#ifdef _GLIBCXX_USE_WCHAR_T
+  typedef char fake_num_cache_w[sizeof(std::__numpunct_cache<wchar_t>)]
+  __attribute__ ((aligned(__alignof__(std::__numpunct_cache<wchar_t>))));
+  fake_num_cache_w numpunct_cache_w;
+
+  typedef char fake_money_cache_w[sizeof(std::__moneypunct_cache<wchar_t,true>)]
+  __attribute__ ((aligned(__alignof__(std::__moneypunct_cache<wchar_t,true>))));
+  fake_money_cache_w moneypunct_cache_wt;
+  fake_money_cache_w moneypunct_cache_wf;
+
+  typedef char fake_time_cache_w[sizeof(std::__timepunct_cache<wchar_t>)]
+  __attribute__ ((aligned(__alignof__(std::__timepunct_cache<wchar_t>))));
+  fake_time_cache_w timepunct_cache_w;
+#endif
+} // anonymous namespace
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+  locale::locale() throw() : _M_impl(0)
+  { 
+    _S_initialize();
+
+    // Checked locking to optimize the common case where _S_global
+    // still points to _S_classic (locale::_S_initialize_once()):
+    // - If they are the same, just increment the reference count and
+    //   we are done.  This effectively constructs a C locale object
+    //   identical to the static c_locale.
+    // - Otherwise, _S_global can and may be destroyed due to
+    //   locale::global() call on another thread, in which case we
+    //   fall back to lock protected access to both _S_global and
+    //   its reference count.
+    _M_impl = _S_global;
+    if (_M_impl == _S_classic)
+      _M_impl->_M_add_reference();
+    else
+      {
+        __gnu_cxx::__scoped_lock sentry(get_locale_mutex());
+        _S_global->_M_add_reference();
+        _M_impl = _S_global;
+      }
+  }
+
+  locale
+  locale::global(const locale& __other)
+  {
+    _S_initialize();
+    _Impl* __old;
+    {
+      __gnu_cxx::__scoped_lock sentry(get_locale_mutex());
+      __old = _S_global;
+      __other._M_impl->_M_add_reference();
+      _S_global = __other._M_impl;
+      const string __other_name = __other.name();
+      if (__other_name != "*")
+	setlocale(LC_ALL, __other_name.c_str());
+    }
+
+    // Reference count sanity check: one reference removed for the
+    // subsition of __other locale, one added by return-by-value. Net
+    // difference: zero. When the returned locale object's destrutor
+    // is called, then the reference count is decremented and possibly
+    // destroyed.
+    return locale(__old);
+  }
+
+  const locale&
+  locale::classic()
+  { 
+    _S_initialize();
+    return *(new (&c_locale) locale(_S_classic));
+  }
+
+  void
+  locale::_S_initialize_once() throw()
+  {
+    // 2 references.
+    // One reference for _S_classic, one for _S_global
+    _S_classic = new (&c_locale_impl) _Impl(2);
+    _S_global = _S_classic; 	    
+  }
+
+  void  
+  locale::_S_initialize()
+  {
+#ifdef __GTHREADS
+    if (__gthread_active_p())
+      __gthread_once(&_S_once, _S_initialize_once);
+#endif
+    if (!_S_classic)
+      _S_initialize_once();
+  }
+
+  // Definitions for static const data members of locale::_Impl
+  const locale::id* const
+  locale::_Impl::_S_id_ctype[] =
+  {
+    &std::ctype<char>::id, 
+    &codecvt<char, char, mbstate_t>::id,
+#ifdef _GLIBCXX_USE_WCHAR_T
+    &std::ctype<wchar_t>::id,
+    &codecvt<wchar_t, char, mbstate_t>::id,
+#endif
+#ifdef _GLIBCXX_USE_C99_STDINT_TR1
+    //&std::ctype<char32_t>::id, TODO
+    &codecvt<char32_t, char, mbstate_t>::id,
+#endif
+    0
+  };
+
+  const locale::id* const
+  locale::_Impl::_S_id_numeric[] =
+  {
+    &num_get<char>::id,  
+    &num_put<char>::id,  
+    &numpunct<char>::id, 
+#ifdef _GLIBCXX_USE_WCHAR_T
+    &num_get<wchar_t>::id,
+    &num_put<wchar_t>::id,
+    &numpunct<wchar_t>::id,
+#endif
+    0
+  };
+  
+  const locale::id* const
+  locale::_Impl::_S_id_collate[] =
+  {
+    &std::collate<char>::id,
+#ifdef _GLIBCXX_USE_WCHAR_T
+    &std::collate<wchar_t>::id,
+#endif
+    0
+  };
+
+  const locale::id* const
+  locale::_Impl::_S_id_time[] =
+  {
+    &__timepunct<char>::id, 
+    &time_get<char>::id, 
+    &time_put<char>::id, 
+#ifdef _GLIBCXX_USE_WCHAR_T
+    &__timepunct<wchar_t>::id, 
+    &time_get<wchar_t>::id,
+    &time_put<wchar_t>::id,
+#endif
+    0
+  };
+  
+  const locale::id* const
+  locale::_Impl::_S_id_monetary[] =
+  {
+    &money_get<char>::id,        
+    &money_put<char>::id,        
+    &moneypunct<char, false>::id, 
+    &moneypunct<char, true >::id, 
+#ifdef _GLIBCXX_USE_WCHAR_T
+    &money_get<wchar_t>::id,
+    &money_put<wchar_t>::id,
+    &moneypunct<wchar_t, false>::id,
+    &moneypunct<wchar_t, true >::id,
+#endif
+    0
+  };
+
+  const locale::id* const
+  locale::_Impl::_S_id_messages[] =
+  {
+    &std::messages<char>::id, 
+#ifdef _GLIBCXX_USE_WCHAR_T
+    &std::messages<wchar_t>::id,
+#endif
+    0
+  };
+  
+  const locale::id* const* const
+  locale::_Impl::_S_facet_categories[] =
+  {
+    // Order must match the decl order in class locale.
+    locale::_Impl::_S_id_ctype,
+    locale::_Impl::_S_id_numeric,
+    locale::_Impl::_S_id_collate,
+    locale::_Impl::_S_id_time,
+    locale::_Impl::_S_id_monetary,
+    locale::_Impl::_S_id_messages,
+    0
+  };
+
+  // Construct "C" _Impl.
+  locale::_Impl::
+  _Impl(size_t __refs) throw() 
+  : _M_refcount(__refs), _M_facets(0), _M_facets_size(_GLIBCXX_NUM_FACETS),
+  _M_caches(0), _M_names(0)    
+  {
+    _M_facets = new (&facet_vec) const facet*[_M_facets_size];
+    _M_caches = new (&cache_vec) const facet*[_M_facets_size];
+    for (size_t __i = 0; __i < _M_facets_size; ++__i)
+      _M_facets[__i] = _M_caches[__i] = 0;
+
+    // Name the categories.
+    _M_names = new (&name_vec) char*[_S_categories_size];
+    _M_names[0] = new (&name_c[0]) char[2];
+    std::memcpy(_M_names[0], locale::facet::_S_get_c_name(), 2);
+    for (size_t __j = 1; __j < _S_categories_size; ++__j)
+      _M_names[__j] = 0;
+
+    // This is needed as presently the C++ version of "C" locales
+    // != data in the underlying locale model for __timepunct,
+    // numpunct, and moneypunct. Also, the "C" locales must be
+    // constructed in a way such that they are pre-allocated.
+    // NB: Set locale::facets(ref) count to one so that each individual
+    // facet is not destroyed when the locale (and thus locale::_Impl) is
+    // destroyed.
+    _M_init_facet(new (&ctype_c) std::ctype<char>(0, false, 1));
+    _M_init_facet(new (&codecvt_c) codecvt<char, char, mbstate_t>(1));
+
+    typedef __numpunct_cache<char> num_cache_c;
+    num_cache_c* __npc = new (&numpunct_cache_c) num_cache_c(2);
+    _M_init_facet(new (&numpunct_c) numpunct<char>(__npc, 1));
+
+    _M_init_facet(new (&num_get_c) num_get<char>(1));
+    _M_init_facet(new (&num_put_c) num_put<char>(1));
+    _M_init_facet(new (&collate_c) std::collate<char>(1));
+
+    typedef __moneypunct_cache<char, false> money_cache_cf;
+    typedef __moneypunct_cache<char, true> money_cache_ct;
+    money_cache_cf* __mpcf = new (&moneypunct_cache_cf) money_cache_cf(2);
+    _M_init_facet(new (&moneypunct_cf) moneypunct<char, false>(__mpcf, 1));
+    money_cache_ct* __mpct = new (&moneypunct_cache_ct) money_cache_ct(2);
+    _M_init_facet(new (&moneypunct_ct) moneypunct<char, true>(__mpct, 1));
+
+    _M_init_facet(new (&money_get_c) money_get<char>(1));
+    _M_init_facet(new (&money_put_c) money_put<char>(1));
+
+    typedef __timepunct_cache<char> time_cache_c;
+    time_cache_c* __tpc = new (&timepunct_cache_c) time_cache_c(2);
+    _M_init_facet(new (&timepunct_c) __timepunct<char>(__tpc, 1));
+
+    _M_init_facet(new (&time_get_c) time_get<char>(1));
+    _M_init_facet(new (&time_put_c) time_put<char>(1));
+    _M_init_facet(new (&messages_c) std::messages<char>(1));	
+
+#ifdef  _GLIBCXX_USE_WCHAR_T
+    _M_init_facet(new (&ctype_w) std::ctype<wchar_t>(1));
+    _M_init_facet(new (&codecvt_w) codecvt<wchar_t, char, mbstate_t>(1));
+
+    typedef __numpunct_cache<wchar_t> num_cache_w;
+    num_cache_w* __npw = new (&numpunct_cache_w) num_cache_w(2);
+    _M_init_facet(new (&numpunct_w) numpunct<wchar_t>(__npw, 1));
+
+    _M_init_facet(new (&num_get_w) num_get<wchar_t>(1));
+    _M_init_facet(new (&num_put_w) num_put<wchar_t>(1));
+    _M_init_facet(new (&collate_w) std::collate<wchar_t>(1));
+
+    typedef __moneypunct_cache<wchar_t, false> money_cache_wf;
+    typedef __moneypunct_cache<wchar_t, true> money_cache_wt;
+    money_cache_wf* __mpwf = new (&moneypunct_cache_wf) money_cache_wf(2);
+    _M_init_facet(new (&moneypunct_wf) moneypunct<wchar_t, false>(__mpwf, 1));
+    money_cache_wt* __mpwt = new (&moneypunct_cache_wt) money_cache_wt(2);
+    _M_init_facet(new (&moneypunct_wt) moneypunct<wchar_t, true>(__mpwt, 1));
+
+    _M_init_facet(new (&money_get_w) money_get<wchar_t>(1));
+    _M_init_facet(new (&money_put_w) money_put<wchar_t>(1));
+
+    typedef __timepunct_cache<wchar_t> time_cache_w;
+    time_cache_w* __tpw = new (&timepunct_cache_w) time_cache_w(2);
+    _M_init_facet(new (&timepunct_w) __timepunct<wchar_t>(__tpw, 1));
+
+    _M_init_facet(new (&time_get_w) time_get<wchar_t>(1));
+    _M_init_facet(new (&time_put_w) time_put<wchar_t>(1));
+    _M_init_facet(new (&messages_w) std::messages<wchar_t>(1));
+#endif 
+
+#ifdef _GLIBCXX_USE_C99_STDINT_TR1
+    _M_init_facet(new (&codecvt_c32) codecvt<char32_t, char, mbstate_t>(1));
+    // TODO...
+#endif //_GLIBCXX_USE_C99_STDINT_TR1
+     
+    // This locale is safe to pre-cache, after all the facets have
+    // been created and installed.
+    _M_caches[numpunct<char>::id._M_id()] = __npc;
+    _M_caches[moneypunct<char, false>::id._M_id()] = __mpcf;
+    _M_caches[moneypunct<char, true>::id._M_id()] = __mpct;
+    _M_caches[__timepunct<char>::id._M_id()] = __tpc;
+#ifdef  _GLIBCXX_USE_WCHAR_T
+    _M_caches[numpunct<wchar_t>::id._M_id()] = __npw;
+    _M_caches[moneypunct<wchar_t, false>::id._M_id()] = __mpwf;
+    _M_caches[moneypunct<wchar_t, true>::id._M_id()] = __mpwt;
+    _M_caches[__timepunct<wchar_t>::id._M_id()] = __tpw;
+#endif
+  }
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace
diff --git a/libstdc++-v3/src/c++11/localename.cc b/libstdc++-v3/src/c++11/localename.cc
new file mode 100644
index 0000000..5f407a4
--- /dev/null
+++ b/libstdc++-v3/src/c++11/localename.cc
@@ -0,0 +1,357 @@
+// Copyright (C) 1997-2014 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 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// 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.
+
+// 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/>.
+
+#include <clocale>
+#include <cstring>
+#include <cstdlib>
+#include <locale>
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+  using namespace __gnu_cxx;
+
+  locale::locale(const char* __s) : _M_impl(0)
+  {
+    if (__s)
+      {
+	_S_initialize(); 
+	if (std::strcmp(__s, "C") == 0 || std::strcmp(__s, "POSIX") == 0)
+	  (_M_impl = _S_classic)->_M_add_reference();
+	else if (std::strcmp(__s, "") != 0)
+	  _M_impl = new _Impl(__s, 1);
+	else
+	  {
+	    // Get it from the environment.
+	    char* __env = std::getenv("LC_ALL");
+	    // If LC_ALL is set we are done.
+	    if (__env && std::strcmp(__env, "") != 0)
+	      {
+		if (std::strcmp(__env, "C") == 0 
+		    || std::strcmp(__env, "POSIX") == 0)
+		  (_M_impl = _S_classic)->_M_add_reference();
+		else
+		  _M_impl = new _Impl(__env, 1);
+	      }
+	    else
+	      {
+		// LANG may set a default different from "C".
+		string __lang;
+		__env = std::getenv("LANG");
+		if (!__env || std::strcmp(__env, "") == 0 
+		    || std::strcmp(__env, "C") == 0 
+		    || std::strcmp(__env, "POSIX") == 0)
+		  __lang = "C";
+		else 
+		  __lang = __env;
+		
+		// Scan the categories looking for the first one
+		// different from LANG.
+		size_t __i = 0;
+		if (__lang == "C")
+		  for (; __i < _S_categories_size; ++__i)
+		    {
+		      __env = std::getenv(_S_categories[__i]);
+		      if (__env && std::strcmp(__env, "") != 0 
+			  && std::strcmp(__env, "C") != 0 
+			  && std::strcmp(__env, "POSIX") != 0)
+			break;
+		    }
+		else
+		  for (; __i < _S_categories_size; ++__i)
+		    {
+		      __env = std::getenv(_S_categories[__i]);
+		      if (__env && std::strcmp(__env, "") != 0
+			  && __lang != __env)
+			break;
+		    }
+	
+		// If one is found, build the complete string of
+		// the form LC_CTYPE=xxx;LC_NUMERIC=yyy; and so on...
+		if (__i < _S_categories_size)
+		  {
+		    string __str;
+		    __str.reserve(128);
+		    for (size_t __j = 0; __j < __i; ++__j)
+		      {
+			__str += _S_categories[__j];
+			__str += '=';
+			__str += __lang;
+			__str += ';';
+		      }
+		    __str += _S_categories[__i];
+		    __str += '=';
+		    __str += __env;
+		    __str += ';';
+		    ++__i;
+		    for (; __i < _S_categories_size; ++__i)
+		      {
+			__env = std::getenv(_S_categories[__i]);
+			__str += _S_categories[__i];
+			if (!__env || std::strcmp(__env, "") == 0)
+			  {
+			    __str += '=';
+			    __str += __lang;
+			    __str += ';';
+			  }
+			else if (std::strcmp(__env, "C") == 0
+				 || std::strcmp(__env, "POSIX") == 0)
+			  __str += "=C;";
+			else
+			  {
+			    __str += '=';
+			    __str += __env;
+			    __str += ';';
+			  }
+		      }
+		    __str.erase(__str.end() - 1);
+		    _M_impl = new _Impl(__str.c_str(), 1);
+		  }
+		// ... otherwise either an additional instance of
+		// the "C" locale or LANG.
+		else if (__lang == "C")
+		  (_M_impl = _S_classic)->_M_add_reference();
+		else
+		  _M_impl = new _Impl(__lang.c_str(), 1);
+	      }
+	  }
+      }
+    else
+      __throw_runtime_error(__N("locale::locale null not valid"));
+  }
+
+  locale::locale(const locale& __base, const char* __s, category __cat)
+  : _M_impl(0)
+  { 
+    // NB: There are complicated, yet more efficient ways to do
+    // this. Building up locales on a per-category way is tedious, so
+    // let's do it this way until people complain.
+    locale __add(__s);
+    _M_coalesce(__base, __add, __cat);
+  }
+
+  locale::locale(const locale& __base, const locale& __add, category __cat)
+  : _M_impl(0)
+  { _M_coalesce(__base, __add, __cat); }
+
+  void
+  locale::_M_coalesce(const locale& __base, const locale& __add, 
+		      category __cat)
+  {
+    __cat = _S_normalize_category(__cat);  
+    _M_impl = new _Impl(*__base._M_impl, 1);  
+
+    __try 
+      { _M_impl->_M_replace_categories(__add._M_impl, __cat); }
+    __catch(...) 
+      { 
+	_M_impl->_M_remove_reference(); 
+	__throw_exception_again;
+      }
+  }
+
+  // Construct named _Impl.
+  locale::_Impl::
+  _Impl(const char* __s, size_t __refs)
+  : _M_refcount(__refs), _M_facets(0), _M_facets_size(_GLIBCXX_NUM_FACETS),
+    _M_caches(0), _M_names(0)
+  {
+    // Initialize the underlying locale model, which also checks to
+    // see if the given name is valid.
+    __c_locale __cloc;
+    locale::facet::_S_create_c_locale(__cloc, __s);
+    __c_locale __clocm = __cloc;
+
+    __try
+      {
+	_M_facets = new const facet*[_M_facets_size];
+	for (size_t __i = 0; __i < _M_facets_size; ++__i)
+	  _M_facets[__i] = 0;
+	_M_caches = new const facet*[_M_facets_size];
+	for (size_t __j = 0; __j < _M_facets_size; ++__j)
+	  _M_caches[__j] = 0;
+	_M_names = new char*[_S_categories_size];
+	for (size_t __k = 0; __k < _S_categories_size; ++__k)
+	  _M_names[__k] = 0;
+
+	// Name the categories.
+	const char* __smon = __s;
+	const size_t __len = std::strlen(__s);
+	if (!std::memchr(__s, ';', __len))
+	  {
+	    _M_names[0] = new char[__len + 1];
+	    std::memcpy(_M_names[0], __s, __len + 1);
+	  }
+	else
+	  {
+	    const char* __end = __s;
+	    bool __found_ctype = false;
+	    bool __found_monetary = false;
+	    size_t __ci = 0, __mi = 0;
+	    for (size_t __i = 0; __i < _S_categories_size; ++__i)
+	      {
+		const char* __beg = std::strchr(__end + 1, '=') + 1;
+		__end = std::strchr(__beg, ';');
+		if (!__end)
+		  __end = __s + __len;
+		_M_names[__i] = new char[__end - __beg + 1];
+		std::memcpy(_M_names[__i], __beg, __end - __beg);
+		_M_names[__i][__end - __beg] = '\0';
+		if (!__found_ctype
+		    && *(__beg - 2) == 'E' && *(__beg - 3) == 'P')
+		  {
+		    __found_ctype = true;
+		    __ci = __i;
+		  }
+		else if (!__found_monetary && *(__beg - 2) == 'Y')
+		  {
+		    __found_monetary = true;
+		    __mi = __i;
+		  }
+	      }
+
+	    if (std::strcmp(_M_names[__ci], _M_names[__mi]))
+	      {
+		__smon = _M_names[__mi];
+		__clocm = locale::facet::_S_lc_ctype_c_locale(__cloc,
+							      __smon);
+	      }
+	  }
+ 
+	// Construct all standard facets and add them to _M_facets.
+	_M_init_facet(new std::ctype<char>(__cloc, 0, false));
+	_M_init_facet(new codecvt<char, char, mbstate_t>(__cloc));
+	_M_init_facet(new numpunct<char>(__cloc));
+	_M_init_facet(new num_get<char>);
+	_M_init_facet(new num_put<char>);
+	_M_init_facet(new std::collate<char>(__cloc));
+	_M_init_facet(new moneypunct<char, false>(__cloc, 0));
+	_M_init_facet(new moneypunct<char, true>(__cloc, 0));
+	_M_init_facet(new money_get<char>);
+	_M_init_facet(new money_put<char>);
+	_M_init_facet(new __timepunct<char>(__cloc, __s));
+	_M_init_facet(new time_get<char>);
+	_M_init_facet(new time_put<char>);
+	_M_init_facet(new std::messages<char>(__cloc, __s));
+	
+#ifdef  _GLIBCXX_USE_WCHAR_T
+	_M_init_facet(new std::ctype<wchar_t>(__cloc));
+	_M_init_facet(new codecvt<wchar_t, char, mbstate_t>(__cloc));
+	_M_init_facet(new numpunct<wchar_t>(__cloc));
+	_M_init_facet(new num_get<wchar_t>);
+	_M_init_facet(new num_put<wchar_t>);
+	_M_init_facet(new std::collate<wchar_t>(__cloc));
+	_M_init_facet(new moneypunct<wchar_t, false>(__clocm, __smon));
+	_M_init_facet(new moneypunct<wchar_t, true>(__clocm, __smon));
+	_M_init_facet(new money_get<wchar_t>);
+	_M_init_facet(new money_put<wchar_t>);
+	_M_init_facet(new __timepunct<wchar_t>(__cloc, __s));
+	_M_init_facet(new time_get<wchar_t>);
+	_M_init_facet(new time_put<wchar_t>);
+	_M_init_facet(new std::messages<wchar_t>(__cloc, __s));
+#endif	  
+
+#ifdef _GLIBCXX_USE_C99_STDINT_TR1
+        _M_init_facet(new codecvt<char32_t, char, mbstate_t>(__cloc));
+#endif //_GLIBCXX_USE_C99_STDINT_TR1
+
+	locale::facet::_S_destroy_c_locale(__cloc);
+	if (__clocm != __cloc)
+	  locale::facet::_S_destroy_c_locale(__clocm);
+      }
+    __catch(...)
+      {
+	locale::facet::_S_destroy_c_locale(__cloc);
+	if (__clocm != __cloc)
+	  locale::facet::_S_destroy_c_locale(__clocm);
+	this->~_Impl();
+	__throw_exception_again;
+      }	
+  }
+
+  void
+  locale::_Impl::
+  _M_replace_categories(const _Impl* __imp, category __cat)
+  {
+    category __mask = 1;
+    if (!_M_names[0] || !__imp->_M_names[0])
+      {
+	if (_M_names[0])
+	  {
+	    delete [] _M_names[0];
+	    _M_names[0] = 0;   // Unnamed.
+	  }
+
+	for (size_t __ix = 0; __ix < _S_categories_size; ++__ix, __mask <<= 1)
+	  {
+	    if (__mask & __cat)
+	      // Need to replace entry in _M_facets with other locale's info.
+	      _M_replace_category(__imp, _S_facet_categories[__ix]);
+	  }
+      }
+    else
+      {
+	if (!_M_names[1])
+	  {
+	    // A full set of _M_names must be prepared, all identical
+	    // to _M_names[0] to begin with. Then, below, a few will
+	    // be replaced by the corresponding __imp->_M_names. I.e.,
+	    // not a "simple" locale anymore (see locale::operator==).
+	    const size_t __len = std::strlen(_M_names[0]) + 1;
+	    for (size_t __i = 1; __i < _S_categories_size; ++__i)
+	      {
+		_M_names[__i] = new char[__len];
+		std::memcpy(_M_names[__i], _M_names[0], __len);
+	      }
+	  }
+
+	for (size_t __ix = 0; __ix < _S_categories_size; ++__ix, __mask <<= 1)
+	  {
+	    if (__mask & __cat)
+	      {
+		// Need to replace entry in _M_facets with other locale's info.
+		_M_replace_category(__imp, _S_facet_categories[__ix]);
+
+		// FIXME: Hack for libstdc++/29217: the numerical encodings
+		// of the time and collate categories are swapped vs the
+		// order of the names in locale::_S_categories.  We'd like to
+		// adjust the former (the latter is dictated by compatibility
+		// with glibc) but we can't for binary compatibility.
+		size_t __ix_name = __ix;
+		if (__ix == 2 || __ix == 3)
+		  __ix_name = 5 - __ix;
+
+		char* __src = __imp->_M_names[__ix_name] ?
+		              __imp->_M_names[__ix_name] : __imp->_M_names[0];
+		const size_t __len = std::strlen(__src) + 1;
+		char* __new = new char[__len];
+		std::memcpy(__new, __src, __len);
+		delete [] _M_names[__ix_name];
+		_M_names[__ix_name] = __new;
+	      }
+	  }
+      }
+  }
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace
diff --git a/libstdc++-v3/src/c++98/Makefile.am b/libstdc++-v3/src/c++98/Makefile.am
index a714fe9..c0286b5 100644
--- a/libstdc++-v3/src/c++98/Makefile.am
+++ b/libstdc++-v3/src/c++98/Makefile.am
@@ -123,9 +123,7 @@ sources = \
 	list_associated.cc \
 	list_associated-2.cc \
 	locale.cc \
-	locale_init.cc \
 	locale_facets.cc \
-	localename.cc \
 	math_stubs_float.cc \
 	math_stubs_long_double.cc \
 	stdexcept.cc \
diff --git a/libstdc++-v3/src/c++98/Makefile.in b/libstdc++-v3/src/c++98/Makefile.in
index 691614f..5a5b8f1 100644
--- a/libstdc++-v3/src/c++98/Makefile.in
+++ b/libstdc++-v3/src/c++98/Makefile.in
@@ -85,10 +85,9 @@ am__objects_5 = bitmap_allocator.lo pool_allocator.lo mt_allocator.lo \
 	hashtable_tr1.lo ios.lo ios_failure.lo ios_init.lo \
 	ios_locale.lo list.lo list-aux.lo list-aux-2.lo \
 	list_associated.lo list_associated-2.lo locale.lo \
-	locale_init.lo locale_facets.lo localename.lo \
-	math_stubs_float.lo math_stubs_long_double.lo stdexcept.lo \
-	strstream.lo tree.lo istream.lo streambuf.lo valarray.lo \
-	$(am__objects_1) $(am__objects_4)
+	locale_facets.lo math_stubs_float.lo math_stubs_long_double.lo \
+	stdexcept.lo strstream.lo tree.lo istream.lo streambuf.lo \
+	valarray.lo $(am__objects_1) $(am__objects_4)
 am_libc__98convenience_la_OBJECTS = $(am__objects_5)
 libc__98convenience_la_OBJECTS = $(am_libc__98convenience_la_OBJECTS)
 DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
@@ -387,9 +386,7 @@ sources = \
 	list_associated.cc \
 	list_associated-2.cc \
 	locale.cc \
-	locale_init.cc \
 	locale_facets.cc \
-	localename.cc \
 	math_stubs_float.cc \
 	math_stubs_long_double.cc \
 	stdexcept.cc \
diff --git a/libstdc++-v3/src/c++98/locale_init.cc b/libstdc++-v3/src/c++98/locale_init.cc
deleted file mode 100644
index 2c6dfc5..0000000
--- a/libstdc++-v3/src/c++98/locale_init.cc
+++ /dev/null
@@ -1,472 +0,0 @@
-// Copyright (C) 1997-2014 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 3, or (at your option)
-// any later version.
-
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// 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.
-
-// 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/>.
-
-#include <clocale>
-#include <cstring>
-#include <cstdlib>     // For getenv, free.
-#include <cctype>
-#include <cwctype>     // For towupper, etc.
-#include <locale>
-#include <ext/concurrence.h>
-
-namespace 
-{
-  __gnu_cxx::__mutex&
-  get_locale_mutex()
-  {
-    static __gnu_cxx::__mutex locale_mutex;
-    return locale_mutex;
-  }
-
-  using namespace std;
-
-  typedef char fake_locale_Impl[sizeof(locale::_Impl)]
-  __attribute__ ((aligned(__alignof__(locale::_Impl))));
-  fake_locale_Impl c_locale_impl;
-
-  typedef char fake_locale[sizeof(locale)]
-  __attribute__ ((aligned(__alignof__(locale))));
-  fake_locale c_locale;
-
-  typedef char fake_name_vec[sizeof(char*)]
-  __attribute__ ((aligned(__alignof__(char*))));
-  fake_name_vec name_vec[6 + _GLIBCXX_NUM_CATEGORIES];
-
-  typedef char fake_names[sizeof(char[2])]
-  __attribute__ ((aligned(__alignof__(char[2]))));
-  fake_names name_c[6 + _GLIBCXX_NUM_CATEGORIES];
-
-  typedef char fake_facet_vec[sizeof(locale::facet*)]
-  __attribute__ ((aligned(__alignof__(locale::facet*))));
-  fake_facet_vec facet_vec[_GLIBCXX_NUM_FACETS];
-
-  typedef char fake_cache_vec[sizeof(locale::facet*)]
-  __attribute__ ((aligned(__alignof__(locale::facet*))));
-  fake_cache_vec cache_vec[_GLIBCXX_NUM_FACETS];
-
-  typedef char fake_ctype_c[sizeof(std::ctype<char>)]
-  __attribute__ ((aligned(__alignof__(std::ctype<char>))));
-  fake_ctype_c ctype_c;
-
-  typedef char fake_collate_c[sizeof(std::collate<char>)]
-  __attribute__ ((aligned(__alignof__(std::collate<char>))));
-  fake_collate_c collate_c;
-
-  typedef char fake_numpunct_c[sizeof(numpunct<char>)]
-  __attribute__ ((aligned(__alignof__(numpunct<char>))));
-  fake_numpunct_c numpunct_c;
-
-  typedef char fake_num_get_c[sizeof(num_get<char>)]
-  __attribute__ ((aligned(__alignof__(num_get<char>))));
-  fake_num_get_c num_get_c;
-
-  typedef char fake_num_put_c[sizeof(num_put<char>)]
-  __attribute__ ((aligned(__alignof__(num_put<char>))));
-  fake_num_put_c num_put_c;
-
-  typedef char fake_codecvt_c[sizeof(codecvt<char, char, mbstate_t>)]
-  __attribute__ ((aligned(__alignof__(codecvt<char, char, mbstate_t>))));
-  fake_codecvt_c codecvt_c;
-
-  typedef char fake_moneypunct_c[sizeof(moneypunct<char, true>)]
-  __attribute__ ((aligned(__alignof__(moneypunct<char, true>))));
-  fake_moneypunct_c moneypunct_ct;
-  fake_moneypunct_c moneypunct_cf;
-
-  typedef char fake_money_get_c[sizeof(money_get<char>)]
-  __attribute__ ((aligned(__alignof__(money_get<char>))));
-  fake_money_get_c money_get_c;
-  
-  typedef char fake_money_put_c[sizeof(money_put<char>)]
-  __attribute__ ((aligned(__alignof__(money_put<char>))));
-  fake_money_put_c money_put_c;
-
-  typedef char fake_timepunct_c[sizeof(__timepunct<char>)]
-  __attribute__ ((aligned(__alignof__(__timepunct<char>))));
-  fake_timepunct_c timepunct_c;
-
-  typedef char fake_time_get_c[sizeof(time_get<char>)]
-  __attribute__ ((aligned(__alignof__(time_get<char>))));
-  fake_time_get_c time_get_c;
-
-  typedef char fake_time_put_c[sizeof(time_put<char>)]
-  __attribute__ ((aligned(__alignof__(time_put<char>))));
-  fake_time_put_c time_put_c;
-
-  typedef char fake_messages_c[sizeof(messages<char>)]
-  __attribute__ ((aligned(__alignof__(messages<char>))));
-  fake_messages_c messages_c;
-
-#ifdef  _GLIBCXX_USE_WCHAR_T
-  typedef char fake_wtype_w[sizeof(std::ctype<wchar_t>)]
-  __attribute__ ((aligned(__alignof__(std::ctype<wchar_t>))));
-  fake_wtype_w ctype_w;
-
-  typedef char fake_wollate_w[sizeof(std::collate<wchar_t>)]
-  __attribute__ ((aligned(__alignof__(std::collate<wchar_t>))));
-  fake_wollate_w collate_w;
-
-  typedef char fake_numpunct_w[sizeof(numpunct<wchar_t>)]
-  __attribute__ ((aligned(__alignof__(numpunct<wchar_t>))));
-  fake_numpunct_w numpunct_w;
-
-  typedef char fake_num_get_w[sizeof(num_get<wchar_t>)]
-  __attribute__ ((aligned(__alignof__(num_get<wchar_t>))));
-  fake_num_get_w num_get_w;
-
-  typedef char fake_num_put_w[sizeof(num_put<wchar_t>)]
-  __attribute__ ((aligned(__alignof__(num_put<wchar_t>))));
-  fake_num_put_w num_put_w;
-
-  typedef char fake_wodecvt_w[sizeof(codecvt<wchar_t, char, mbstate_t>)]
-  __attribute__ ((aligned(__alignof__(codecvt<wchar_t, char, mbstate_t>))));
-  fake_wodecvt_w codecvt_w;
-
-  typedef char fake_moneypunct_w[sizeof(moneypunct<wchar_t, true>)]
-  __attribute__ ((aligned(__alignof__(moneypunct<wchar_t, true>))));
-  fake_moneypunct_w moneypunct_wt;
-  fake_moneypunct_w moneypunct_wf;
-
-  typedef char fake_money_get_w[sizeof(money_get<wchar_t>)]
-  __attribute__ ((aligned(__alignof__(money_get<wchar_t>))));
-  fake_money_get_w money_get_w;
-  
-  typedef char fake_money_put_w[sizeof(money_put<wchar_t>)]
-  __attribute__ ((aligned(__alignof__(money_put<wchar_t>))));
-  fake_money_put_w money_put_w;
-
-  typedef char fake_timepunct_w[sizeof(__timepunct<wchar_t>)]
-  __attribute__ ((aligned(__alignof__(__timepunct<wchar_t>))));
-  fake_timepunct_w timepunct_w;
-
-  typedef char fake_time_get_w[sizeof(time_get<wchar_t>)]
-  __attribute__ ((aligned(__alignof__(time_get<wchar_t>))));
-  fake_time_get_w time_get_w;
-
-  typedef char fake_time_put_w[sizeof(time_put<wchar_t>)]
-  __attribute__ ((aligned(__alignof__(time_put<wchar_t>))));
-  fake_time_put_w time_put_w;
-
-  typedef char fake_messages_w[sizeof(messages<wchar_t>)]
-  __attribute__ ((aligned(__alignof__(messages<wchar_t>))));
-  fake_messages_w messages_w;
-#endif
-
-  // Storage for "C" locale caches.
-  typedef char fake_num_cache_c[sizeof(std::__numpunct_cache<char>)]
-  __attribute__ ((aligned(__alignof__(std::__numpunct_cache<char>))));
-  fake_num_cache_c numpunct_cache_c;
-
-  typedef char fake_money_cache_c[sizeof(std::__moneypunct_cache<char, true>)]
-  __attribute__ ((aligned(__alignof__(std::__moneypunct_cache<char, true>))));
-  fake_money_cache_c moneypunct_cache_ct;
-  fake_money_cache_c moneypunct_cache_cf;
-
-  typedef char fake_time_cache_c[sizeof(std::__timepunct_cache<char>)]
-  __attribute__ ((aligned(__alignof__(std::__timepunct_cache<char>))));
-  fake_time_cache_c timepunct_cache_c;
-
-#ifdef _GLIBCXX_USE_WCHAR_T
-  typedef char fake_num_cache_w[sizeof(std::__numpunct_cache<wchar_t>)]
-  __attribute__ ((aligned(__alignof__(std::__numpunct_cache<wchar_t>))));
-  fake_num_cache_w numpunct_cache_w;
-
-  typedef char fake_money_cache_w[sizeof(std::__moneypunct_cache<wchar_t,true>)]
-  __attribute__ ((aligned(__alignof__(std::__moneypunct_cache<wchar_t,true>))));
-  fake_money_cache_w moneypunct_cache_wt;
-  fake_money_cache_w moneypunct_cache_wf;
-
-  typedef char fake_time_cache_w[sizeof(std::__timepunct_cache<wchar_t>)]
-  __attribute__ ((aligned(__alignof__(std::__timepunct_cache<wchar_t>))));
-  fake_time_cache_w timepunct_cache_w;
-#endif
-} // anonymous namespace
-
-namespace std _GLIBCXX_VISIBILITY(default)
-{
-_GLIBCXX_BEGIN_NAMESPACE_VERSION
-
-  locale::locale() throw() : _M_impl(0)
-  { 
-    _S_initialize();
-
-    // Checked locking to optimize the common case where _S_global
-    // still points to _S_classic (locale::_S_initialize_once()):
-    // - If they are the same, just increment the reference count and
-    //   we are done.  This effectively constructs a C locale object
-    //   identical to the static c_locale.
-    // - Otherwise, _S_global can and may be destroyed due to
-    //   locale::global() call on another thread, in which case we
-    //   fall back to lock protected access to both _S_global and
-    //   its reference count.
-    _M_impl = _S_global;
-    if (_M_impl == _S_classic)
-      _M_impl->_M_add_reference();
-    else
-      {
-        __gnu_cxx::__scoped_lock sentry(get_locale_mutex());
-        _S_global->_M_add_reference();
-        _M_impl = _S_global;
-      }
-  }
-
-  locale
-  locale::global(const locale& __other)
-  {
-    _S_initialize();
-    _Impl* __old;
-    {
-      __gnu_cxx::__scoped_lock sentry(get_locale_mutex());
-      __old = _S_global;
-      __other._M_impl->_M_add_reference();
-      _S_global = __other._M_impl;
-      const string __other_name = __other.name();
-      if (__other_name != "*")
-	setlocale(LC_ALL, __other_name.c_str());
-    }
-
-    // Reference count sanity check: one reference removed for the
-    // subsition of __other locale, one added by return-by-value. Net
-    // difference: zero. When the returned locale object's destrutor
-    // is called, then the reference count is decremented and possibly
-    // destroyed.
-    return locale(__old);
-  }
-
-  const locale&
-  locale::classic()
-  { 
-    _S_initialize();
-    return *(new (&c_locale) locale(_S_classic));
-  }
-
-  void
-  locale::_S_initialize_once() throw()
-  {
-    // 2 references.
-    // One reference for _S_classic, one for _S_global
-    _S_classic = new (&c_locale_impl) _Impl(2);
-    _S_global = _S_classic; 	    
-  }
-
-  void  
-  locale::_S_initialize()
-  {
-#ifdef __GTHREADS
-    if (__gthread_active_p())
-      __gthread_once(&_S_once, _S_initialize_once);
-#endif
-    if (!_S_classic)
-      _S_initialize_once();
-  }
-
-  // Definitions for static const data members of locale::_Impl
-  const locale::id* const
-  locale::_Impl::_S_id_ctype[] =
-  {
-    &std::ctype<char>::id, 
-    &codecvt<char, char, mbstate_t>::id,
-#ifdef _GLIBCXX_USE_WCHAR_T
-    &std::ctype<wchar_t>::id,
-    &codecvt<wchar_t, char, mbstate_t>::id,
-#endif
-    0
-  };
-
-  const locale::id* const
-  locale::_Impl::_S_id_numeric[] =
-  {
-    &num_get<char>::id,  
-    &num_put<char>::id,  
-    &numpunct<char>::id, 
-#ifdef _GLIBCXX_USE_WCHAR_T
-    &num_get<wchar_t>::id,
-    &num_put<wchar_t>::id,
-    &numpunct<wchar_t>::id,
-#endif
-    0
-  };
-  
-  const locale::id* const
-  locale::_Impl::_S_id_collate[] =
-  {
-    &std::collate<char>::id,
-#ifdef _GLIBCXX_USE_WCHAR_T
-    &std::collate<wchar_t>::id,
-#endif
-    0
-  };
-
-  const locale::id* const
-  locale::_Impl::_S_id_time[] =
-  {
-    &__timepunct<char>::id, 
-    &time_get<char>::id, 
-    &time_put<char>::id, 
-#ifdef _GLIBCXX_USE_WCHAR_T
-    &__timepunct<wchar_t>::id, 
-    &time_get<wchar_t>::id,
-    &time_put<wchar_t>::id,
-#endif
-    0
-  };
-  
-  const locale::id* const
-  locale::_Impl::_S_id_monetary[] =
-  {
-    &money_get<char>::id,        
-    &money_put<char>::id,        
-    &moneypunct<char, false>::id, 
-    &moneypunct<char, true >::id, 
-#ifdef _GLIBCXX_USE_WCHAR_T
-    &money_get<wchar_t>::id,
-    &money_put<wchar_t>::id,
-    &moneypunct<wchar_t, false>::id,
-    &moneypunct<wchar_t, true >::id,
-#endif
-    0
-  };
-
-  const locale::id* const
-  locale::_Impl::_S_id_messages[] =
-  {
-    &std::messages<char>::id, 
-#ifdef _GLIBCXX_USE_WCHAR_T
-    &std::messages<wchar_t>::id,
-#endif
-    0
-  };
-  
-  const locale::id* const* const
-  locale::_Impl::_S_facet_categories[] =
-  {
-    // Order must match the decl order in class locale.
-    locale::_Impl::_S_id_ctype,
-    locale::_Impl::_S_id_numeric,
-    locale::_Impl::_S_id_collate,
-    locale::_Impl::_S_id_time,
-    locale::_Impl::_S_id_monetary,
-    locale::_Impl::_S_id_messages,
-    0
-  };
-
-  // Construct "C" _Impl.
-  locale::_Impl::
-  _Impl(size_t __refs) throw() 
-  : _M_refcount(__refs), _M_facets(0), _M_facets_size(_GLIBCXX_NUM_FACETS),
-  _M_caches(0), _M_names(0)    
-  {
-    _M_facets = new (&facet_vec) const facet*[_M_facets_size];
-    _M_caches = new (&cache_vec) const facet*[_M_facets_size];
-    for (size_t __i = 0; __i < _M_facets_size; ++__i)
-      _M_facets[__i] = _M_caches[__i] = 0;
-
-    // Name the categories.
-    _M_names = new (&name_vec) char*[_S_categories_size];
-    _M_names[0] = new (&name_c[0]) char[2];
-    std::memcpy(_M_names[0], locale::facet::_S_get_c_name(), 2);
-    for (size_t __j = 1; __j < _S_categories_size; ++__j)
-      _M_names[__j] = 0;
-
-    // This is needed as presently the C++ version of "C" locales
-    // != data in the underlying locale model for __timepunct,
-    // numpunct, and moneypunct. Also, the "C" locales must be
-    // constructed in a way such that they are pre-allocated.
-    // NB: Set locale::facets(ref) count to one so that each individual
-    // facet is not destroyed when the locale (and thus locale::_Impl) is
-    // destroyed.
-    _M_init_facet(new (&ctype_c) std::ctype<char>(0, false, 1));
-    _M_init_facet(new (&codecvt_c) codecvt<char, char, mbstate_t>(1));
-
-    typedef __numpunct_cache<char> num_cache_c;
-    num_cache_c* __npc = new (&numpunct_cache_c) num_cache_c(2);
-    _M_init_facet(new (&numpunct_c) numpunct<char>(__npc, 1));
-
-    _M_init_facet(new (&num_get_c) num_get<char>(1));
-    _M_init_facet(new (&num_put_c) num_put<char>(1));
-    _M_init_facet(new (&collate_c) std::collate<char>(1));
-
-    typedef __moneypunct_cache<char, false> money_cache_cf;
-    typedef __moneypunct_cache<char, true> money_cache_ct;
-    money_cache_cf* __mpcf = new (&moneypunct_cache_cf) money_cache_cf(2);
-    _M_init_facet(new (&moneypunct_cf) moneypunct<char, false>(__mpcf, 1));
-    money_cache_ct* __mpct = new (&moneypunct_cache_ct) money_cache_ct(2);
-    _M_init_facet(new (&moneypunct_ct) moneypunct<char, true>(__mpct, 1));
-
-    _M_init_facet(new (&money_get_c) money_get<char>(1));
-    _M_init_facet(new (&money_put_c) money_put<char>(1));
-
-    typedef __timepunct_cache<char> time_cache_c;
-    time_cache_c* __tpc = new (&timepunct_cache_c) time_cache_c(2);
-    _M_init_facet(new (&timepunct_c) __timepunct<char>(__tpc, 1));
-
-    _M_init_facet(new (&time_get_c) time_get<char>(1));
-    _M_init_facet(new (&time_put_c) time_put<char>(1));
-    _M_init_facet(new (&messages_c) std::messages<char>(1));	
-
-#ifdef  _GLIBCXX_USE_WCHAR_T
-    _M_init_facet(new (&ctype_w) std::ctype<wchar_t>(1));
-    _M_init_facet(new (&codecvt_w) codecvt<wchar_t, char, mbstate_t>(1));
-
-    typedef __numpunct_cache<wchar_t> num_cache_w;
-    num_cache_w* __npw = new (&numpunct_cache_w) num_cache_w(2);
-    _M_init_facet(new (&numpunct_w) numpunct<wchar_t>(__npw, 1));
-
-    _M_init_facet(new (&num_get_w) num_get<wchar_t>(1));
-    _M_init_facet(new (&num_put_w) num_put<wchar_t>(1));
-    _M_init_facet(new (&collate_w) std::collate<wchar_t>(1));
-
-    typedef __moneypunct_cache<wchar_t, false> money_cache_wf;
-    typedef __moneypunct_cache<wchar_t, true> money_cache_wt;
-    money_cache_wf* __mpwf = new (&moneypunct_cache_wf) money_cache_wf(2);
-    _M_init_facet(new (&moneypunct_wf) moneypunct<wchar_t, false>(__mpwf, 1));
-    money_cache_wt* __mpwt = new (&moneypunct_cache_wt) money_cache_wt(2);
-    _M_init_facet(new (&moneypunct_wt) moneypunct<wchar_t, true>(__mpwt, 1));
-
-    _M_init_facet(new (&money_get_w) money_get<wchar_t>(1));
-    _M_init_facet(new (&money_put_w) money_put<wchar_t>(1));
-
-    typedef __timepunct_cache<wchar_t> time_cache_w;
-    time_cache_w* __tpw = new (&timepunct_cache_w) time_cache_w(2);
-    _M_init_facet(new (&timepunct_w) __timepunct<wchar_t>(__tpw, 1));
-
-    _M_init_facet(new (&time_get_w) time_get<wchar_t>(1));
-    _M_init_facet(new (&time_put_w) time_put<wchar_t>(1));
-    _M_init_facet(new (&messages_w) std::messages<wchar_t>(1));
-#endif 
-     
-    // This locale is safe to pre-cache, after all the facets have
-    // been created and installed.
-    _M_caches[numpunct<char>::id._M_id()] = __npc;
-    _M_caches[moneypunct<char, false>::id._M_id()] = __mpcf;
-    _M_caches[moneypunct<char, true>::id._M_id()] = __mpct;
-    _M_caches[__timepunct<char>::id._M_id()] = __tpc;
-#ifdef  _GLIBCXX_USE_WCHAR_T
-    _M_caches[numpunct<wchar_t>::id._M_id()] = __npw;
-    _M_caches[moneypunct<wchar_t, false>::id._M_id()] = __mpwf;
-    _M_caches[moneypunct<wchar_t, true>::id._M_id()] = __mpwt;
-    _M_caches[__timepunct<wchar_t>::id._M_id()] = __tpw;
-#endif
-  }
-
-_GLIBCXX_END_NAMESPACE_VERSION
-} // namespace
diff --git a/libstdc++-v3/src/c++98/localename.cc b/libstdc++-v3/src/c++98/localename.cc
deleted file mode 100644
index e93c846..0000000
--- a/libstdc++-v3/src/c++98/localename.cc
+++ /dev/null
@@ -1,352 +0,0 @@
-// Copyright (C) 1997-2014 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 3, or (at your option)
-// any later version.
-
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// 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.
-
-// 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/>.
-
-#include <clocale>
-#include <cstring>
-#include <cstdlib>
-#include <locale>
-
-namespace std _GLIBCXX_VISIBILITY(default)
-{
-_GLIBCXX_BEGIN_NAMESPACE_VERSION
-
-  using namespace __gnu_cxx;
-
-  locale::locale(const char* __s) : _M_impl(0)
-  {
-    if (__s)
-      {
-	_S_initialize(); 
-	if (std::strcmp(__s, "C") == 0 || std::strcmp(__s, "POSIX") == 0)
-	  (_M_impl = _S_classic)->_M_add_reference();
-	else if (std::strcmp(__s, "") != 0)
-	  _M_impl = new _Impl(__s, 1);
-	else
-	  {
-	    // Get it from the environment.
-	    char* __env = std::getenv("LC_ALL");
-	    // If LC_ALL is set we are done.
-	    if (__env && std::strcmp(__env, "") != 0)
-	      {
-		if (std::strcmp(__env, "C") == 0 
-		    || std::strcmp(__env, "POSIX") == 0)
-		  (_M_impl = _S_classic)->_M_add_reference();
-		else
-		  _M_impl = new _Impl(__env, 1);
-	      }
-	    else
-	      {
-		// LANG may set a default different from "C".
-		string __lang;
-		__env = std::getenv("LANG");
-		if (!__env || std::strcmp(__env, "") == 0 
-		    || std::strcmp(__env, "C") == 0 
-		    || std::strcmp(__env, "POSIX") == 0)
-		  __lang = "C";
-		else 
-		  __lang = __env;
-		
-		// Scan the categories looking for the first one
-		// different from LANG.
-		size_t __i = 0;
-		if (__lang == "C")
-		  for (; __i < _S_categories_size; ++__i)
-		    {
-		      __env = std::getenv(_S_categories[__i]);
-		      if (__env && std::strcmp(__env, "") != 0 
-			  && std::strcmp(__env, "C") != 0 
-			  && std::strcmp(__env, "POSIX") != 0)
-			break;
-		    }
-		else
-		  for (; __i < _S_categories_size; ++__i)
-		    {
-		      __env = std::getenv(_S_categories[__i]);
-		      if (__env && std::strcmp(__env, "") != 0
-			  && __lang != __env)
-			break;
-		    }
-	
-		// If one is found, build the complete string of
-		// the form LC_CTYPE=xxx;LC_NUMERIC=yyy; and so on...
-		if (__i < _S_categories_size)
-		  {
-		    string __str;
-		    __str.reserve(128);
-		    for (size_t __j = 0; __j < __i; ++__j)
-		      {
-			__str += _S_categories[__j];
-			__str += '=';
-			__str += __lang;
-			__str += ';';
-		      }
-		    __str += _S_categories[__i];
-		    __str += '=';
-		    __str += __env;
-		    __str += ';';
-		    ++__i;
-		    for (; __i < _S_categories_size; ++__i)
-		      {
-			__env = std::getenv(_S_categories[__i]);
-			__str += _S_categories[__i];
-			if (!__env || std::strcmp(__env, "") == 0)
-			  {
-			    __str += '=';
-			    __str += __lang;
-			    __str += ';';
-			  }
-			else if (std::strcmp(__env, "C") == 0
-				 || std::strcmp(__env, "POSIX") == 0)
-			  __str += "=C;";
-			else
-			  {
-			    __str += '=';
-			    __str += __env;
-			    __str += ';';
-			  }
-		      }
-		    __str.erase(__str.end() - 1);
-		    _M_impl = new _Impl(__str.c_str(), 1);
-		  }
-		// ... otherwise either an additional instance of
-		// the "C" locale or LANG.
-		else if (__lang == "C")
-		  (_M_impl = _S_classic)->_M_add_reference();
-		else
-		  _M_impl = new _Impl(__lang.c_str(), 1);
-	      }
-	  }
-      }
-    else
-      __throw_runtime_error(__N("locale::locale null not valid"));
-  }
-
-  locale::locale(const locale& __base, const char* __s, category __cat)
-  : _M_impl(0)
-  { 
-    // NB: There are complicated, yet more efficient ways to do
-    // this. Building up locales on a per-category way is tedious, so
-    // let's do it this way until people complain.
-    locale __add(__s);
-    _M_coalesce(__base, __add, __cat);
-  }
-
-  locale::locale(const locale& __base, const locale& __add, category __cat)
-  : _M_impl(0)
-  { _M_coalesce(__base, __add, __cat); }
-
-  void
-  locale::_M_coalesce(const locale& __base, const locale& __add, 
-		      category __cat)
-  {
-    __cat = _S_normalize_category(__cat);  
-    _M_impl = new _Impl(*__base._M_impl, 1);  
-
-    __try 
-      { _M_impl->_M_replace_categories(__add._M_impl, __cat); }
-    __catch(...) 
-      { 
-	_M_impl->_M_remove_reference(); 
-	__throw_exception_again;
-      }
-  }
-
-  // Construct named _Impl.
-  locale::_Impl::
-  _Impl(const char* __s, size_t __refs)
-  : _M_refcount(__refs), _M_facets(0), _M_facets_size(_GLIBCXX_NUM_FACETS),
-    _M_caches(0), _M_names(0)
-  {
-    // Initialize the underlying locale model, which also checks to
-    // see if the given name is valid.
-    __c_locale __cloc;
-    locale::facet::_S_create_c_locale(__cloc, __s);
-    __c_locale __clocm = __cloc;
-
-    __try
-      {
-	_M_facets = new const facet*[_M_facets_size];
-	for (size_t __i = 0; __i < _M_facets_size; ++__i)
-	  _M_facets[__i] = 0;
-	_M_caches = new const facet*[_M_facets_size];
-	for (size_t __j = 0; __j < _M_facets_size; ++__j)
-	  _M_caches[__j] = 0;
-	_M_names = new char*[_S_categories_size];
-	for (size_t __k = 0; __k < _S_categories_size; ++__k)
-	  _M_names[__k] = 0;
-
-	// Name the categories.
-	const char* __smon = __s;
-	const size_t __len = std::strlen(__s);
-	if (!std::memchr(__s, ';', __len))
-	  {
-	    _M_names[0] = new char[__len + 1];
-	    std::memcpy(_M_names[0], __s, __len + 1);
-	  }
-	else
-	  {
-	    const char* __end = __s;
-	    bool __found_ctype = false;
-	    bool __found_monetary = false;
-	    size_t __ci = 0, __mi = 0;
-	    for (size_t __i = 0; __i < _S_categories_size; ++__i)
-	      {
-		const char* __beg = std::strchr(__end + 1, '=') + 1;
-		__end = std::strchr(__beg, ';');
-		if (!__end)
-		  __end = __s + __len;
-		_M_names[__i] = new char[__end - __beg + 1];
-		std::memcpy(_M_names[__i], __beg, __end - __beg);
-		_M_names[__i][__end - __beg] = '\0';
-		if (!__found_ctype
-		    && *(__beg - 2) == 'E' && *(__beg - 3) == 'P')
-		  {
-		    __found_ctype = true;
-		    __ci = __i;
-		  }
-		else if (!__found_monetary && *(__beg - 2) == 'Y')
-		  {
-		    __found_monetary = true;
-		    __mi = __i;
-		  }
-	      }
-
-	    if (std::strcmp(_M_names[__ci], _M_names[__mi]))
-	      {
-		__smon = _M_names[__mi];
-		__clocm = locale::facet::_S_lc_ctype_c_locale(__cloc,
-							      __smon);
-	      }
-	  }
- 
-	// Construct all standard facets and add them to _M_facets.
-	_M_init_facet(new std::ctype<char>(__cloc, 0, false));
-	_M_init_facet(new codecvt<char, char, mbstate_t>(__cloc));
-	_M_init_facet(new numpunct<char>(__cloc));
-	_M_init_facet(new num_get<char>);
-	_M_init_facet(new num_put<char>);
-	_M_init_facet(new std::collate<char>(__cloc));
-	_M_init_facet(new moneypunct<char, false>(__cloc, 0));
-	_M_init_facet(new moneypunct<char, true>(__cloc, 0));
-	_M_init_facet(new money_get<char>);
-	_M_init_facet(new money_put<char>);
-	_M_init_facet(new __timepunct<char>(__cloc, __s));
-	_M_init_facet(new time_get<char>);
-	_M_init_facet(new time_put<char>);
-	_M_init_facet(new std::messages<char>(__cloc, __s));
-	
-#ifdef  _GLIBCXX_USE_WCHAR_T
-	_M_init_facet(new std::ctype<wchar_t>(__cloc));
-	_M_init_facet(new codecvt<wchar_t, char, mbstate_t>(__cloc));
-	_M_init_facet(new numpunct<wchar_t>(__cloc));
-	_M_init_facet(new num_get<wchar_t>);
-	_M_init_facet(new num_put<wchar_t>);
-	_M_init_facet(new std::collate<wchar_t>(__cloc));
-	_M_init_facet(new moneypunct<wchar_t, false>(__clocm, __smon));
-	_M_init_facet(new moneypunct<wchar_t, true>(__clocm, __smon));
-	_M_init_facet(new money_get<wchar_t>);
-	_M_init_facet(new money_put<wchar_t>);
-	_M_init_facet(new __timepunct<wchar_t>(__cloc, __s));
-	_M_init_facet(new time_get<wchar_t>);
-	_M_init_facet(new time_put<wchar_t>);
-	_M_init_facet(new std::messages<wchar_t>(__cloc, __s));
-#endif	  
-	locale::facet::_S_destroy_c_locale(__cloc);
-	if (__clocm != __cloc)
-	  locale::facet::_S_destroy_c_locale(__clocm);
-      }
-    __catch(...)
-      {
-	locale::facet::_S_destroy_c_locale(__cloc);
-	if (__clocm != __cloc)
-	  locale::facet::_S_destroy_c_locale(__clocm);
-	this->~_Impl();
-	__throw_exception_again;
-      }	
-  }
-
-  void
-  locale::_Impl::
-  _M_replace_categories(const _Impl* __imp, category __cat)
-  {
-    category __mask = 1;
-    if (!_M_names[0] || !__imp->_M_names[0])
-      {
-	if (_M_names[0])
-	  {
-	    delete [] _M_names[0];
-	    _M_names[0] = 0;   // Unnamed.
-	  }
-
-	for (size_t __ix = 0; __ix < _S_categories_size; ++__ix, __mask <<= 1)
-	  {
-	    if (__mask & __cat)
-	      // Need to replace entry in _M_facets with other locale's info.
-	      _M_replace_category(__imp, _S_facet_categories[__ix]);
-	  }
-      }
-    else
-      {
-	if (!_M_names[1])
-	  {
-	    // A full set of _M_names must be prepared, all identical
-	    // to _M_names[0] to begin with. Then, below, a few will
-	    // be replaced by the corresponding __imp->_M_names. I.e.,
-	    // not a "simple" locale anymore (see locale::operator==).
-	    const size_t __len = std::strlen(_M_names[0]) + 1;
-	    for (size_t __i = 1; __i < _S_categories_size; ++__i)
-	      {
-		_M_names[__i] = new char[__len];
-		std::memcpy(_M_names[__i], _M_names[0], __len);
-	      }
-	  }
-
-	for (size_t __ix = 0; __ix < _S_categories_size; ++__ix, __mask <<= 1)
-	  {
-	    if (__mask & __cat)
-	      {
-		// Need to replace entry in _M_facets with other locale's info.
-		_M_replace_category(__imp, _S_facet_categories[__ix]);
-
-		// FIXME: Hack for libstdc++/29217: the numerical encodings
-		// of the time and collate categories are swapped vs the
-		// order of the names in locale::_S_categories.  We'd like to
-		// adjust the former (the latter is dictated by compatibility
-		// with glibc) but we can't for binary compatibility.
-		size_t __ix_name = __ix;
-		if (__ix == 2 || __ix == 3)
-		  __ix_name = 5 - __ix;
-
-		char* __src = __imp->_M_names[__ix_name] ?
-		              __imp->_M_names[__ix_name] : __imp->_M_names[0];
-		const size_t __len = std::strlen(__src) + 1;
-		char* __new = new char[__len];
-		std::memcpy(__new, __src, __len);
-		delete [] _M_names[__ix_name];
-		_M_names[__ix_name] = __new;
-	      }
-	  }
-      }
-  }
-
-_GLIBCXX_END_NAMESPACE_VERSION
-} // namespace
diff --git a/libstdc++-v3/testsuite/22_locale/codecvt/char32_t/1.cc b/libstdc++-v3/testsuite/22_locale/codecvt/char32_t/1.cc
new file mode 100644
index 0000000..c31a845
--- /dev/null
+++ b/libstdc++-v3/testsuite/22_locale/codecvt/char32_t/1.cc
@@ -0,0 +1,101 @@
+// { dg-options "-std=gnu++11" }
+
+// 2014-04-24 RÃÂdiger Sonderfeld
+
+// Copyright (C) 2014 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 3, or (at your option) any later
+// version.
+
+// This library is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// 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 COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// [locale.codecvt], C++11 22.4.1.4.  specialization.
+
+#include <locale>
+#include <cstring>
+#include <testsuite_hooks.h>
+
+// from 22_locale/codecvt/in/wchar_t/1.cc
+void
+zero_state(std::mbstate_t& state)
+{ std::memset(&state, 0, sizeof(std::mbstate_t)); }
+
+void
+test01()
+{
+  using namespace std;
+  typedef codecvt<char32_t, char, mbstate_t> codecvt_c32;
+  locale loc_c = locale::classic();
+  VERIFY(has_facet<codecvt_c32>(loc_c));
+  const codecvt_c32* const cvt = &use_facet<codecvt_c32>(loc_c);
+
+  VERIFY(not cvt->always_noconv());
+  VERIFY(cvt->max_length() == 4);
+  VERIFY(cvt->encoding() == 0);
+
+  const char u8dat[] = u8"HÃÂllÃÂ ÃÂÂÂ ÃÂÂ ÃÂÂ f(ÃÂ) exp(-2ÃÂÃÂ) dÃÂ ÃÂÂÂ ÃÂÂÂ ÃÂÂÂ ÃÂÃÂÃÂÃÂÃÂÃÂÃÂÃÂÃÂ ÃÂÂ";
+  const char* const u8dat_end = u8dat + sizeof(u8dat);
+
+  const char32_t u32dat[] = U"H\U000000E4ll\U000000F6 \U0001F63F \U000056FD "
+    U"\U0000222B f(\U000003BA) exp(-2\U000003C0\U000003C9) d\U000003BA "
+    U"\U0001F6BF \U0001F6BF \U0001F648 \U00000413\U00000435\U0000043E"
+    U"\U00000433\U00000440\U00000430\U00000444\U00000438\U0000044F \U0000FB05";
+  const char32_t* const u32dat_end = u32dat + sizeof(u32dat)/sizeof(*u32dat);
+
+  {
+    const size_t len = u32dat_end - u32dat + 1;
+    char32_t* const buffer = new char32_t[len];
+    char32_t* const buffer_end = buffer + len;
+
+    const char* from_next;
+    char32_t* to_next;
+
+    codecvt_c32::state_type state01;
+    zero_state(state01);
+    codecvt_base::result res = cvt->in(state01, u8dat, u8dat_end, from_next,
+                                       buffer, buffer_end, to_next);
+
+    VERIFY(res == codecvt_base::ok);
+    VERIFY(from_next == u8dat_end);
+    VERIFY(memcmp((void*)buffer, (void*)u32dat, sizeof(u32dat)) == 0);
+
+    delete[]buffer;
+  }
+
+  {
+    const size_t len = u8dat_end - u8dat + 1;
+    char* const buffer = new char[len];
+    char* const buffer_end = buffer + len;
+
+    const char32_t* from_next;
+    char* to_next;
+
+    codecvt_c32::state_type state01;
+    zero_state(state01);
+    codecvt_base::result res = cvt->out(state01, u32dat, u32dat_end, from_next,
+                                        buffer, buffer_end, to_next);
+
+    VERIFY(res == codecvt_base::ok);
+    VERIFY(from_next == u32dat_end);
+    VERIFY(memcmp((void*)buffer, (void*)u8dat, sizeof(u8dat)) == 0);
+
+    delete[]buffer;
+  }
+}
+
+int
+main()
+{
+  test01();
+  return 0;
+}
-- 
1.9.2


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]