+ return __ret;
+ }
+
+ int
+ codecvt<wchar_t, char, mbstate_t>::
+ do_encoding() const throw()
+ {
+ // XXX This implementation assumes that the encoding is
+ // stateless and is either single-byte or variable-width.
+ int __ret = 0;
+#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
+ __c_locale __old = __uselocale(_M_c_locale_codecvt);
+#endif
+ if (MB_CUR_MAX == 1)
+ __ret = 1;
+#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
+ __uselocale(__old);
+#endif
+ return __ret;
+ }
+
+ int
+ codecvt<wchar_t, char, mbstate_t>::
+ do_max_length() const throw()
+ {
+#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
+ __c_locale __old = __uselocale(_M_c_locale_codecvt);
+#endif
+ // XXX Probably wrong for stateful encodings.
+ int __ret = MB_CUR_MAX;
+#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
+ __uselocale(__old);
+#endif
+ return __ret;
+ }
+
+ int
+ codecvt<wchar_t, char, mbstate_t>::
+ do_length(state_type& __state, const extern_type* __from,
+ const extern_type* __end, size_t __max) const
+ {
+ int __ret = 0;
+ state_type __tmp_state(__state);
+
+#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
+ __c_locale __old = __uselocale(_M_c_locale_codecvt);
+#endif
+
+ // mbsnrtowcs is *very* fast but stops if encounters NUL characters:
+ // in case we advance past it and then continue, in a loop.
+ // NB: mbsnrtowcs is a GNU extension
+
+ // A dummy internal buffer is needed in order for mbsnrtocws to consider
+ // its fourth parameter (it wouldn't with NULL as first parameter).
+ wchar_t* __to = static_cast<wchar_t*>(__builtin_alloca(sizeof(wchar_t)
+ * __max));
+ while (__from < __end && __max)