543 lines
16 KiB
Diff
543 lines
16 KiB
Diff
From 6ffe7c46f52d27864c3df3663e16ec9ddee71e8f Mon Sep 17 00:00:00 2001
|
|
From: Khem Raj <raj.khem@gmail.com>
|
|
Date: Fri, 29 Mar 2013 08:46:58 +0400
|
|
Subject: [PATCH 07/35] uclibc-locale-update
|
|
|
|
Signed-off-by: Khem Raj <raj.khem@gmail.com>
|
|
|
|
Upstream-Status: Pending
|
|
---
|
|
.../config/locale/uclibc/c++locale_internal.h | 3 +
|
|
libstdc++-v3/config/locale/uclibc/c_locale.cc | 74 +++++++++-----------
|
|
libstdc++-v3/config/locale/uclibc/c_locale.h | 42 ++++++-----
|
|
libstdc++-v3/config/locale/uclibc/ctype_members.cc | 51 ++++++++++----
|
|
.../config/locale/uclibc/messages_members.h | 12 ++--
|
|
.../config/locale/uclibc/monetary_members.cc | 34 +++++----
|
|
.../config/locale/uclibc/numeric_members.cc | 5 ++
|
|
libstdc++-v3/config/locale/uclibc/time_members.cc | 18 +++--
|
|
libstdc++-v3/config/locale/uclibc/time_members.h | 17 +++--
|
|
9 files changed, 158 insertions(+), 98 deletions(-)
|
|
|
|
diff --git a/libstdc++-v3/config/locale/uclibc/c++locale_internal.h b/libstdc++-v3/config/locale/uclibc/c++locale_internal.h
|
|
index e74fddf..971a6b4 100644
|
|
--- a/libstdc++-v3/config/locale/uclibc/c++locale_internal.h
|
|
+++ b/libstdc++-v3/config/locale/uclibc/c++locale_internal.h
|
|
@@ -31,6 +31,9 @@
|
|
|
|
#include <bits/c++config.h>
|
|
#include <clocale>
|
|
+#include <cstdlib>
|
|
+#include <cstring>
|
|
+#include <cstddef>
|
|
|
|
#ifdef __UCLIBC_MJN3_ONLY__
|
|
#warning clean this up
|
|
diff --git a/libstdc++-v3/config/locale/uclibc/c_locale.cc b/libstdc++-v3/config/locale/uclibc/c_locale.cc
|
|
index 21430d0..1b9d8e1 100644
|
|
--- a/libstdc++-v3/config/locale/uclibc/c_locale.cc
|
|
+++ b/libstdc++-v3/config/locale/uclibc/c_locale.cc
|
|
@@ -39,23 +39,20 @@
|
|
#include <langinfo.h>
|
|
#include <bits/c++locale_internal.h>
|
|
|
|
-namespace std
|
|
-{
|
|
+_GLIBCXX_BEGIN_NAMESPACE(std)
|
|
+
|
|
template<>
|
|
void
|
|
__convert_to_v(const char* __s, float& __v, ios_base::iostate& __err,
|
|
const __c_locale& __cloc)
|
|
{
|
|
- if (!(__err & ios_base::failbit))
|
|
- {
|
|
- char* __sanity;
|
|
- errno = 0;
|
|
- float __f = __strtof_l(__s, &__sanity, __cloc);
|
|
- if (__sanity != __s && errno != ERANGE)
|
|
- __v = __f;
|
|
- else
|
|
- __err |= ios_base::failbit;
|
|
- }
|
|
+ char* __sanity;
|
|
+ errno = 0;
|
|
+ float __f = __strtof_l(__s, &__sanity, __cloc);
|
|
+ if (__sanity != __s && errno != ERANGE)
|
|
+ __v = __f;
|
|
+ else
|
|
+ __err |= ios_base::failbit;
|
|
}
|
|
|
|
template<>
|
|
@@ -63,16 +60,13 @@ namespace std
|
|
__convert_to_v(const char* __s, double& __v, ios_base::iostate& __err,
|
|
const __c_locale& __cloc)
|
|
{
|
|
- if (!(__err & ios_base::failbit))
|
|
- {
|
|
- char* __sanity;
|
|
- errno = 0;
|
|
- double __d = __strtod_l(__s, &__sanity, __cloc);
|
|
- if (__sanity != __s && errno != ERANGE)
|
|
- __v = __d;
|
|
- else
|
|
- __err |= ios_base::failbit;
|
|
- }
|
|
+ char* __sanity;
|
|
+ errno = 0;
|
|
+ double __d = __strtod_l(__s, &__sanity, __cloc);
|
|
+ if (__sanity != __s && errno != ERANGE)
|
|
+ __v = __d;
|
|
+ else
|
|
+ __err |= ios_base::failbit;
|
|
}
|
|
|
|
template<>
|
|
@@ -80,16 +74,13 @@ namespace std
|
|
__convert_to_v(const char* __s, long double& __v, ios_base::iostate& __err,
|
|
const __c_locale& __cloc)
|
|
{
|
|
- if (!(__err & ios_base::failbit))
|
|
- {
|
|
- char* __sanity;
|
|
- errno = 0;
|
|
- long double __ld = __strtold_l(__s, &__sanity, __cloc);
|
|
- if (__sanity != __s && errno != ERANGE)
|
|
- __v = __ld;
|
|
- else
|
|
- __err |= ios_base::failbit;
|
|
- }
|
|
+ char* __sanity;
|
|
+ errno = 0;
|
|
+ long double __ld = __strtold_l(__s, &__sanity, __cloc);
|
|
+ if (__sanity != __s && errno != ERANGE)
|
|
+ __v = __ld;
|
|
+ else
|
|
+ __err |= ios_base::failbit;
|
|
}
|
|
|
|
void
|
|
@@ -110,17 +101,18 @@ namespace std
|
|
void
|
|
locale::facet::_S_destroy_c_locale(__c_locale& __cloc)
|
|
{
|
|
- if (_S_get_c_locale() != __cloc)
|
|
+ if (__cloc && _S_get_c_locale() != __cloc)
|
|
__freelocale(__cloc);
|
|
}
|
|
|
|
__c_locale
|
|
locale::facet::_S_clone_c_locale(__c_locale& __cloc)
|
|
{ return __duplocale(__cloc); }
|
|
-} // namespace std
|
|
|
|
-namespace __gnu_cxx
|
|
-{
|
|
+_GLIBCXX_END_NAMESPACE
|
|
+
|
|
+_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
|
|
+
|
|
const char* const category_names[6 + _GLIBCXX_NUM_CATEGORIES] =
|
|
{
|
|
"LC_CTYPE",
|
|
@@ -138,9 +130,11 @@ namespace __gnu_cxx
|
|
"LC_IDENTIFICATION"
|
|
#endif
|
|
};
|
|
-}
|
|
|
|
-namespace std
|
|
-{
|
|
+_GLIBCXX_END_NAMESPACE
|
|
+
|
|
+_GLIBCXX_BEGIN_NAMESPACE(std)
|
|
+
|
|
const char* const* const locale::_S_categories = __gnu_cxx::category_names;
|
|
-} // namespace std
|
|
+
|
|
+_GLIBCXX_END_NAMESPACE
|
|
diff --git a/libstdc++-v3/config/locale/uclibc/c_locale.h b/libstdc++-v3/config/locale/uclibc/c_locale.h
|
|
index 4bca5f1..64a6d46 100644
|
|
--- a/libstdc++-v3/config/locale/uclibc/c_locale.h
|
|
+++ b/libstdc++-v3/config/locale/uclibc/c_locale.h
|
|
@@ -39,21 +39,23 @@
|
|
#pragma GCC system_header
|
|
|
|
#include <cstring> // get std::strlen
|
|
-#include <cstdio> // get std::snprintf or std::sprintf
|
|
+#include <cstdio> // get std::vsnprintf or std::vsprintf
|
|
#include <clocale>
|
|
#include <langinfo.h> // For codecvt
|
|
#ifdef __UCLIBC_MJN3_ONLY__
|
|
#warning fix this
|
|
#endif
|
|
-#ifdef __UCLIBC_HAS_LOCALE__
|
|
+#ifdef _GLIBCXX_USE_ICONV
|
|
#include <iconv.h> // For codecvt using iconv, iconv_t
|
|
#endif
|
|
-#ifdef __UCLIBC_HAS_GETTEXT_AWARENESS__
|
|
-#include <libintl.h> // For messages
|
|
+#ifdef HAVE_LIBINTL_H
|
|
+#include <libintl.h> // For messages
|
|
#endif
|
|
+#include <cstdarg>
|
|
|
|
#ifdef __UCLIBC_MJN3_ONLY__
|
|
#warning what is _GLIBCXX_C_LOCALE_GNU for
|
|
+// psm: used in os/gnu-linux/ctype_noninline.h
|
|
#endif
|
|
#define _GLIBCXX_C_LOCALE_GNU 1
|
|
|
|
@@ -78,23 +80,25 @@ namespace std
|
|
#else
|
|
typedef int* __c_locale;
|
|
#endif
|
|
-
|
|
- // Convert numeric value of type _Tv to string and return length of
|
|
- // string. If snprintf is available use it, otherwise fall back to
|
|
- // the unsafe sprintf which, in general, can be dangerous and should
|
|
+ // Convert numeric value of type double to string and return length of
|
|
+ // string. If vsnprintf is available use it, otherwise fall back to
|
|
+ // the unsafe vsprintf which, in general, can be dangerous and should
|
|
// be avoided.
|
|
- template<typename _Tv>
|
|
- int
|
|
- __convert_from_v(char* __out,
|
|
- const int __size __attribute__ ((__unused__)),
|
|
- const char* __fmt,
|
|
-#ifdef __UCLIBC_HAS_XCLOCALE__
|
|
- _Tv __v, const __c_locale& __cloc, int __prec)
|
|
+ inline int
|
|
+ __convert_from_v(const __c_locale&
|
|
+#ifndef __UCLIBC_HAS_XCLOCALE__
|
|
+ __cloc __attribute__ ((__unused__))
|
|
+#endif
|
|
+ ,
|
|
+ char* __out,
|
|
+ const int __size,
|
|
+ const char* __fmt, ...)
|
|
{
|
|
+ va_list __args;
|
|
+#ifdef __UCLIBC_HAS_XCLOCALE__
|
|
+
|
|
__c_locale __old = __gnu_cxx::__uselocale(__cloc);
|
|
#else
|
|
- _Tv __v, const __c_locale&, int __prec)
|
|
- {
|
|
# ifdef __UCLIBC_HAS_LOCALE__
|
|
char* __old = std::setlocale(LC_ALL, NULL);
|
|
char* __sav = new char[std::strlen(__old) + 1];
|
|
@@ -103,7 +107,9 @@ namespace std
|
|
# endif
|
|
#endif
|
|
|
|
- const int __ret = std::snprintf(__out, __size, __fmt, __prec, __v);
|
|
+ va_start(__args, __fmt);
|
|
+ const int __ret = std::vsnprintf(__out, __size, __fmt, __args);
|
|
+ va_end(__args);
|
|
|
|
#ifdef __UCLIBC_HAS_XCLOCALE__
|
|
__gnu_cxx::__uselocale(__old);
|
|
diff --git a/libstdc++-v3/config/locale/uclibc/ctype_members.cc b/libstdc++-v3/config/locale/uclibc/ctype_members.cc
|
|
index 7b12861..13e011d 100644
|
|
--- a/libstdc++-v3/config/locale/uclibc/ctype_members.cc
|
|
+++ b/libstdc++-v3/config/locale/uclibc/ctype_members.cc
|
|
@@ -33,16 +33,20 @@
|
|
|
|
// Written by Benjamin Kosnik <bkoz@redhat.com>
|
|
|
|
+#include <features.h>
|
|
+#ifdef __UCLIBC_HAS_LOCALE__
|
|
#define _LIBC
|
|
#include <locale>
|
|
#undef _LIBC
|
|
+#else
|
|
+#include <locale>
|
|
+#endif
|
|
#include <bits/c++locale_internal.h>
|
|
|
|
-namespace std
|
|
-{
|
|
+_GLIBCXX_BEGIN_NAMESPACE(std)
|
|
+
|
|
// NB: The other ctype<char> specializations are in src/locale.cc and
|
|
// various /config/os/* files.
|
|
- template<>
|
|
ctype_byname<char>::ctype_byname(const char* __s, size_t __refs)
|
|
: ctype<char>(0, false, __refs)
|
|
{
|
|
@@ -57,6 +61,8 @@ namespace std
|
|
#endif
|
|
}
|
|
}
|
|
+ ctype_byname<char>::~ctype_byname()
|
|
+ { }
|
|
|
|
#ifdef _GLIBCXX_USE_WCHAR_T
|
|
ctype<wchar_t>::__wmask_type
|
|
@@ -138,17 +144,33 @@ namespace std
|
|
ctype<wchar_t>::
|
|
do_is(mask __m, wchar_t __c) const
|
|
{
|
|
- // Highest bitmask in ctype_base == 10, but extra in "C"
|
|
- // library for blank.
|
|
+ // The case of __m == ctype_base::space is particularly important,
|
|
+ // due to its use in many istream functions. Therefore we deal with
|
|
+ // it first, exploiting the knowledge that on GNU systems _M_bit[5]
|
|
+ // is the mask corresponding to ctype_base::space. NB: an encoding
|
|
+ // change would not affect correctness!
|
|
+
|
|
bool __ret = false;
|
|
- const size_t __bitmasksize = 11;
|
|
- for (size_t __bitcur = 0; __bitcur <= __bitmasksize; ++__bitcur)
|
|
- if (__m & _M_bit[__bitcur]
|
|
- && __iswctype_l(__c, _M_wmask[__bitcur], _M_c_locale_ctype))
|
|
- {
|
|
- __ret = true;
|
|
- break;
|
|
- }
|
|
+ if (__m == _M_bit[5])
|
|
+ __ret = __iswctype_l(__c, _M_wmask[5], _M_c_locale_ctype);
|
|
+ else
|
|
+ {
|
|
+ // Highest bitmask in ctype_base == 10, but extra in "C"
|
|
+ // library for blank.
|
|
+ const size_t __bitmasksize = 11;
|
|
+ for (size_t __bitcur = 0; __bitcur <= __bitmasksize; ++__bitcur)
|
|
+ if (__m & _M_bit[__bitcur])
|
|
+ {
|
|
+ if (__iswctype_l(__c, _M_wmask[__bitcur], _M_c_locale_ctype))
|
|
+ {
|
|
+ __ret = true;
|
|
+ break;
|
|
+ }
|
|
+ else if (__m == _M_bit[__bitcur])
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+
|
|
return __ret;
|
|
}
|
|
|
|
@@ -290,4 +312,5 @@ namespace std
|
|
#endif
|
|
}
|
|
#endif // _GLIBCXX_USE_WCHAR_T
|
|
-}
|
|
+
|
|
+_GLIBCXX_END_NAMESPACE
|
|
diff --git a/libstdc++-v3/config/locale/uclibc/messages_members.h b/libstdc++-v3/config/locale/uclibc/messages_members.h
|
|
index d89da33..067657a 100644
|
|
--- a/libstdc++-v3/config/locale/uclibc/messages_members.h
|
|
+++ b/libstdc++-v3/config/locale/uclibc/messages_members.h
|
|
@@ -53,12 +53,16 @@
|
|
template<typename _CharT>
|
|
messages<_CharT>::messages(__c_locale __cloc, const char* __s,
|
|
size_t __refs)
|
|
- : facet(__refs), _M_c_locale_messages(_S_clone_c_locale(__cloc)),
|
|
- _M_name_messages(__s)
|
|
+ : facet(__refs), _M_c_locale_messages(NULL),
|
|
+ _M_name_messages(NULL)
|
|
{
|
|
- char* __tmp = new char[std::strlen(__s) + 1];
|
|
- std::strcpy(__tmp, __s);
|
|
+ const size_t __len = std::strlen(__s) + 1;
|
|
+ char* __tmp = new char[__len];
|
|
+ std::memcpy(__tmp, __s, __len);
|
|
_M_name_messages = __tmp;
|
|
+
|
|
+ // Last to avoid leaking memory if new throws.
|
|
+ _M_c_locale_messages = _S_clone_c_locale(__cloc);
|
|
}
|
|
|
|
template<typename _CharT>
|
|
diff --git a/libstdc++-v3/config/locale/uclibc/monetary_members.cc b/libstdc++-v3/config/locale/uclibc/monetary_members.cc
|
|
index 31ebb9f..7679b9c 100644
|
|
--- a/libstdc++-v3/config/locale/uclibc/monetary_members.cc
|
|
+++ b/libstdc++-v3/config/locale/uclibc/monetary_members.cc
|
|
@@ -33,9 +33,14 @@
|
|
|
|
// Written by Benjamin Kosnik <bkoz@redhat.com>
|
|
|
|
+#include <features.h>
|
|
+#ifdef __UCLIBC_HAS_LOCALE__
|
|
#define _LIBC
|
|
#include <locale>
|
|
#undef _LIBC
|
|
+#else
|
|
+#include <locale>
|
|
+#endif
|
|
#include <bits/c++locale_internal.h>
|
|
|
|
#ifdef __UCLIBC_MJN3_ONLY__
|
|
@@ -206,7 +211,7 @@ namespace std
|
|
}
|
|
break;
|
|
default:
|
|
- ;
|
|
+ __ret = pattern();
|
|
}
|
|
return __ret;
|
|
}
|
|
@@ -390,7 +395,9 @@ namespace std
|
|
__c_locale __old = __uselocale(__cloc);
|
|
#else
|
|
// Switch to named locale so that mbsrtowcs will work.
|
|
- char* __old = strdup(setlocale(LC_ALL, NULL));
|
|
+ char* __old = setlocale(LC_ALL, NULL);
|
|
+ const size_t __llen = strlen(__old) + 1;
|
|
+ char* __sav = new char[__llen];
|
|
setlocale(LC_ALL, __name);
|
|
#endif
|
|
|
|
@@ -477,8 +484,8 @@ namespace std
|
|
#ifdef __UCLIBC_HAS_XLOCALE__
|
|
__uselocale(__old);
|
|
#else
|
|
- setlocale(LC_ALL, __old);
|
|
- free(__old);
|
|
+ setlocale(LC_ALL, __sav);
|
|
+ delete [] __sav;
|
|
#endif
|
|
__throw_exception_again;
|
|
}
|
|
@@ -498,8 +505,8 @@ namespace std
|
|
#ifdef __UCLIBC_HAS_XLOCALE__
|
|
__uselocale(__old);
|
|
#else
|
|
- setlocale(LC_ALL, __old);
|
|
- free(__old);
|
|
+ setlocale(LC_ALL, __sav);
|
|
+ delete [] __sav;
|
|
#endif
|
|
}
|
|
}
|
|
@@ -545,8 +552,11 @@ namespace std
|
|
__c_locale __old = __uselocale(__cloc);
|
|
#else
|
|
// Switch to named locale so that mbsrtowcs will work.
|
|
- char* __old = strdup(setlocale(LC_ALL, NULL));
|
|
- setlocale(LC_ALL, __name);
|
|
+ char* __old = setlocale(LC_ALL, NULL);
|
|
+ const size_t __llen = strlen(__old) + 1;
|
|
+ char* __sav = new char[__llen];
|
|
+ memcpy(__sav, __old, __llen);
|
|
+ setlocale(LC_ALL, __name);
|
|
#endif
|
|
|
|
#ifdef __UCLIBC_MJN3_ONLY__
|
|
@@ -633,8 +643,8 @@ namespace std
|
|
#ifdef __UCLIBC_HAS_XLOCALE__
|
|
__uselocale(__old);
|
|
#else
|
|
- setlocale(LC_ALL, __old);
|
|
- free(__old);
|
|
+ setlocale(LC_ALL, __sav);
|
|
+ delete [] __sav;
|
|
#endif
|
|
__throw_exception_again;
|
|
}
|
|
@@ -653,8 +663,8 @@ namespace std
|
|
#ifdef __UCLIBC_HAS_XLOCALE__
|
|
__uselocale(__old);
|
|
#else
|
|
- setlocale(LC_ALL, __old);
|
|
- free(__old);
|
|
+ setlocale(LC_ALL, __sav);
|
|
+ delete [] __sav;
|
|
#endif
|
|
}
|
|
}
|
|
diff --git a/libstdc++-v3/config/locale/uclibc/numeric_members.cc b/libstdc++-v3/config/locale/uclibc/numeric_members.cc
|
|
index d5c8961..8ae8969 100644
|
|
--- a/libstdc++-v3/config/locale/uclibc/numeric_members.cc
|
|
+++ b/libstdc++-v3/config/locale/uclibc/numeric_members.cc
|
|
@@ -33,9 +33,14 @@
|
|
|
|
// Written by Benjamin Kosnik <bkoz@redhat.com>
|
|
|
|
+#include <features.h>
|
|
+#ifdef __UCLIBC_HAS_LOCALE__
|
|
#define _LIBC
|
|
#include <locale>
|
|
#undef _LIBC
|
|
+#else
|
|
+#include <locale>
|
|
+#endif
|
|
#include <bits/c++locale_internal.h>
|
|
|
|
#ifdef __UCLIBC_MJN3_ONLY__
|
|
diff --git a/libstdc++-v3/config/locale/uclibc/time_members.cc b/libstdc++-v3/config/locale/uclibc/time_members.cc
|
|
index d848ed5..f24d53e 100644
|
|
--- a/libstdc++-v3/config/locale/uclibc/time_members.cc
|
|
+++ b/libstdc++-v3/config/locale/uclibc/time_members.cc
|
|
@@ -53,11 +53,14 @@ namespace std
|
|
const size_t __len = __strftime_l(__s, __maxlen, __format, __tm,
|
|
_M_c_locale_timepunct);
|
|
#else
|
|
- char* __old = strdup(setlocale(LC_ALL, NULL));
|
|
+ char* __old = setlocale(LC_ALL, NULL);
|
|
+ const size_t __llen = strlen(__old) + 1;
|
|
+ char* __sav = new char[__llen];
|
|
+ memcpy(__sav, __old, __llen);
|
|
setlocale(LC_ALL, _M_name_timepunct);
|
|
const size_t __len = strftime(__s, __maxlen, __format, __tm);
|
|
- setlocale(LC_ALL, __old);
|
|
- free(__old);
|
|
+ setlocale(LC_ALL, __sav);
|
|
+ delete [] __sav;
|
|
#endif
|
|
// Make sure __s is null terminated.
|
|
if (__len == 0)
|
|
@@ -207,11 +210,14 @@ namespace std
|
|
const size_t __len = __wcsftime_l(__s, __maxlen, __format, __tm,
|
|
_M_c_locale_timepunct);
|
|
#else
|
|
- char* __old = strdup(setlocale(LC_ALL, NULL));
|
|
+ char* __old = setlocale(LC_ALL, NULL);
|
|
+ const size_t __llen = strlen(__old) + 1;
|
|
+ char* __sav = new char[__llen];
|
|
+ memcpy(__sav, __old, __llen);
|
|
setlocale(LC_ALL, _M_name_timepunct);
|
|
const size_t __len = wcsftime(__s, __maxlen, __format, __tm);
|
|
- setlocale(LC_ALL, __old);
|
|
- free(__old);
|
|
+ setlocale(LC_ALL, __sav);
|
|
+ delete [] __sav;
|
|
#endif
|
|
// Make sure __s is null terminated.
|
|
if (__len == 0)
|
|
diff --git a/libstdc++-v3/config/locale/uclibc/time_members.h b/libstdc++-v3/config/locale/uclibc/time_members.h
|
|
index ba8e858..1665dde 100644
|
|
--- a/libstdc++-v3/config/locale/uclibc/time_members.h
|
|
+++ b/libstdc++-v3/config/locale/uclibc/time_members.h
|
|
@@ -50,12 +50,21 @@
|
|
__timepunct<_CharT>::__timepunct(__c_locale __cloc, const char* __s,
|
|
size_t __refs)
|
|
: facet(__refs), _M_data(NULL), _M_c_locale_timepunct(NULL),
|
|
- _M_name_timepunct(__s)
|
|
+ _M_name_timepunct(NULL)
|
|
{
|
|
- char* __tmp = new char[std::strlen(__s) + 1];
|
|
- std::strcpy(__tmp, __s);
|
|
+ const size_t __len = std::strlen(__s) + 1;
|
|
+ char* __tmp = new char[__len];
|
|
+ std::memcpy(__tmp, __s, __len);
|
|
_M_name_timepunct = __tmp;
|
|
- _M_initialize_timepunct(__cloc);
|
|
+
|
|
+ try
|
|
+ { _M_initialize_timepunct(__cloc); }
|
|
+ catch(...)
|
|
+ {
|
|
+ delete [] _M_name_timepunct;
|
|
+ __throw_exception_again;
|
|
+ }
|
|
+
|
|
}
|
|
|
|
template<typename _CharT>
|
|
--
|
|
1.7.10.4
|
|
|