📄 facets_byname.cpp
字号:
/*
* Copyright (c) 1999
* Silicon Graphics Computer Systems, Inc.
*
* Copyright (c) 1999
* Boris Fomitchev
*
* This material is provided "as is", with absolutely no warranty expressed
* or implied. Any use is at your own risk.
*
* Permission to use or copy this software for any purpose is hereby granted
* without fee, provided the above notices are retained on all copies.
* Permission to modify the code and to distribute modified code is granted,
* provided the above notices are retained, and a notice that the code was
* modified is included with the above copyright notice.
*
*/
#include "stlport_prefix.h"
#include <hash_map>
#include <vector>
#include <locale>
#include <istream>
#include <algorithm>
#include <functional>
#include "c_locale.h"
#include "locale_impl.h"
#include "acquire_release.h"
_STLP_BEGIN_NAMESPACE
//----------------------------------------------------------------------
// ctype_byname<char>
ctype_byname<char>::ctype_byname(const char* name, size_t refs, _Locale_name_hint* hint) :
ctype<char>( 0, false, refs),
_M_ctype(_STLP_PRIV __acquire_ctype(name, hint)) {
ctype<char>::_M_ctype_table = _M_byname_table;
if (!_M_ctype)
locale::_M_throw_runtime_error();
// We have to do this, instead of just pointer twiddling, because
// ctype_base::mask isn't the same type as _Locale_mask_t.
const _Locale_mask_t* p = _Locale_ctype_table(_M_ctype);
if (!p)
locale::_M_throw_runtime_error();
for (size_t i = 0; i < table_size; ++i) {
_Locale_mask_t __m = p[i];
if (__m & (upper | lower))
__m |= alpha;
_M_byname_table[i] = ctype_base::mask(__m);
}
}
ctype_byname<char>::~ctype_byname()
{ _STLP_PRIV __release_ctype(_M_ctype); }
char ctype_byname<char>::do_toupper(char c) const
{ return (char)_Locale_toupper(_M_ctype, c); }
char ctype_byname<char>::do_tolower(char c) const
{ return (char)_Locale_tolower(_M_ctype, c); }
const char*
ctype_byname<char>::do_toupper(char* first, const char* last) const {
for ( ; first != last ; ++first)
*first = (char)_Locale_toupper(_M_ctype, *first);
return last;
}
const char*
ctype_byname<char>::do_tolower(char* first, const char* last) const {
for ( ; first != last ; ++first)
*first = (char)_Locale_tolower(_M_ctype, *first);
return last;
}
// Some helper functions used in ctype<>::scan_is and scan_is_not.
#if !defined (_STLP_NO_WCHAR_T)
_STLP_MOVE_TO_PRIV_NAMESPACE
// ctype_byname<wchar_t>
struct _Ctype_byname_w_is_mask {
typedef wchar_t argument_type;
typedef bool result_type;
/* ctype_base::mask*/ int M;
_Locale_ctype* M_ctp;
_Ctype_byname_w_is_mask(/* ctype_base::mask */ int m, _Locale_ctype* c) : M((int)m), M_ctp(c) {}
bool operator()(wchar_t c) const
{ return (M & _Locale_wchar_ctype(M_ctp, c, M)) != 0; }
};
_STLP_MOVE_TO_STD_NAMESPACE
ctype_byname<wchar_t>::ctype_byname(const char* name, size_t refs, _Locale_name_hint* hint)
: ctype<wchar_t>(refs),
_M_ctype(_STLP_PRIV __acquire_ctype(name, hint)) {
if (!_M_ctype)
locale::_M_throw_runtime_error();
}
ctype_byname<wchar_t>::~ctype_byname()
{ _STLP_PRIV __release_ctype(_M_ctype); }
bool ctype_byname<wchar_t>::do_is(ctype_base::mask m, wchar_t c) const
{ return (m & _Locale_wchar_ctype(_M_ctype, c, m)) != 0; }
const wchar_t*
ctype_byname<wchar_t>::do_is(const wchar_t* low, const wchar_t* high,
ctype_base::mask * m) const {
ctype_base::mask all_bits = ctype_base::mask(
ctype_base::space |
ctype_base::print |
ctype_base::cntrl |
ctype_base::upper |
ctype_base::lower |
ctype_base::alpha |
ctype_base::digit |
ctype_base::punct |
ctype_base::xdigit);
for ( ; low < high; ++low, ++m)
*m = ctype_base::mask (_Locale_wchar_ctype(_M_ctype, *low, all_bits));
return high;
}
const wchar_t*
ctype_byname<wchar_t>
::do_scan_is(ctype_base::mask m, const wchar_t* low, const wchar_t* high) const
{ return find_if(low, high, _STLP_PRIV _Ctype_byname_w_is_mask(m, _M_ctype)); }
const wchar_t*
ctype_byname<wchar_t>
::do_scan_not(ctype_base::mask m, const wchar_t* low, const wchar_t* high) const
{ return find_if(low, high, not1(_STLP_PRIV _Ctype_byname_w_is_mask(m, _M_ctype))); }
wchar_t ctype_byname<wchar_t>::do_toupper(wchar_t c) const
{ return _Locale_wchar_toupper(_M_ctype, c); }
const wchar_t*
ctype_byname<wchar_t>::do_toupper(wchar_t* low, const wchar_t* high) const {
for ( ; low < high; ++low)
*low = _Locale_wchar_toupper(_M_ctype, *low);
return high;
}
wchar_t ctype_byname<wchar_t>::do_tolower(wchar_t c) const
{ return _Locale_wchar_tolower(_M_ctype, c); }
const wchar_t*
ctype_byname<wchar_t>::do_tolower(wchar_t* low, const wchar_t* high) const {
for ( ; low < high; ++low)
*low = _Locale_wchar_tolower(_M_ctype, *low);
return high;
}
#endif /* WCHAR_T */
// collate_byname<char>
collate_byname<char>::collate_byname(const char* name, size_t refs, _Locale_name_hint* hint)
: collate<char>(refs),
_M_collate(_STLP_PRIV __acquire_collate(name, hint)) {
if (!_M_collate)
locale::_M_throw_runtime_error();
}
collate_byname<char>::~collate_byname()
{ _STLP_PRIV __release_collate(_M_collate); }
int collate_byname<char>::do_compare(const char* __low1,
const char* __high1,
const char* __low2,
const char* __high2) const {
return _Locale_strcmp(_M_collate,
__low1, __high1 - __low1,
__low2, __high2 - __low2);
}
collate_byname<char>::string_type
collate_byname<char>::do_transform(const char* low, const char* high) const {
if (low == high)
return string_type();
size_t n = _Locale_strxfrm(_M_collate, NULL, 0, low, high - low);
// NOT PORTABLE. What we're doing relies on internal details of the
// string implementation. (Contiguity of string elements and presence
// of trailing zero.)
string_type buf(n, 0);
_Locale_strxfrm(_M_collate, &(*buf.begin()), n + 1, low, high - low);
return buf;
}
#if !defined (_STLP_NO_WCHAR_T)
// collate_byname<wchar_t>
collate_byname<wchar_t>::collate_byname(const char* name, size_t refs, _Locale_name_hint* hint)
: collate<wchar_t>(refs),
_M_collate(_STLP_PRIV __acquire_collate(name, hint)) {
if (!_M_collate)
locale::_M_throw_runtime_error();
}
collate_byname<wchar_t>::~collate_byname()
{ _STLP_PRIV __release_collate(_M_collate); }
int collate_byname<wchar_t>::do_compare(const wchar_t* low1,
const wchar_t* high1,
const wchar_t* low2,
const wchar_t* high2) const {
return _Locale_strwcmp(_M_collate,
low1, high1 - low1,
low2, high2 - low2);
}
collate_byname<wchar_t>::string_type
collate_byname<wchar_t>::do_transform(const wchar_t* low,
const wchar_t* high) const {
if (low == high)
return string_type();
size_t n = _Locale_strwxfrm(_M_collate, NULL, 0, low, high - low);
// NOT PORTABLE. What we're doing relies on internal details of the
// string implementation. (Contiguity of string elements and presence
// of trailing zero.)
string_type buf(n, 0);
_Locale_strwxfrm(_M_collate, &(*buf.begin()), n + 1, low, high - low);
return buf;
}
#endif /* _STLP_NO_WCHAR_T */
_STLP_END_NAMESPACE
#if !defined (_STLP_NO_MBSTATE_T)
_STLP_BEGIN_NAMESPACE
//----------------------------------------------------------------------
// codecvt_byname<char>
codecvt_byname<char, char, mbstate_t>
::codecvt_byname(const char* /* name */, size_t refs)
: codecvt<char, char, mbstate_t>(refs) {}
codecvt_byname<char, char, mbstate_t>::~codecvt_byname() {}
# if !defined (_STLP_NO_WCHAR_T)
//----------------------------------------------------------------------
// codecvt_byname<wchar_t>
codecvt_byname<wchar_t, char, mbstate_t>
::codecvt_byname(const char* name, size_t refs, _Locale_name_hint* hint)
: codecvt<wchar_t, char, mbstate_t>(refs),
_M_ctype(_STLP_PRIV __acquire_ctype(name, hint)) {
if (!_M_ctype)
locale::_M_throw_runtime_error();
}
codecvt_byname<wchar_t, char, mbstate_t>::~codecvt_byname()
{ _STLP_PRIV __release_ctype(_M_ctype); }
codecvt<wchar_t, char, mbstate_t>::result
codecvt_byname<wchar_t, char, mbstate_t>
::do_out(state_type& state,
const wchar_t* from,
const wchar_t* from_end,
const wchar_t*& from_next,
char* to,
char* to_limit,
char*& to_next) const {
while (from != from_end) {
size_t chars_stored = _Locale_wctomb(_M_ctype,
to, to_limit - to, *from,
&state);
if (chars_stored == (size_t) -1) {
from_next = from;
to_next = to;
return error;
}
else if (chars_stored == (size_t) -2) {
from_next = from;
to_next = to;
return partial;
}
++from;
to += chars_stored;
}
from_next = from;
to_next = to;
return ok;
}
codecvt<wchar_t, char, mbstate_t>::result
codecvt_byname<wchar_t, char, mbstate_t>
::do_in(state_type& state,
const extern_type* from,
const extern_type* from_end,
const extern_type*& from_next,
intern_type* to,
intern_type* ,
intern_type*& to_next) const {
while (from != from_end) {
size_t chars_read = _Locale_mbtowc(_M_ctype,
to, from, from_end - from,
&state);
if (chars_read == (size_t) -1) {
from_next = from;
to_next = to;
return error;
}
if (chars_read == (size_t) -2) {
from_next = from;
to_next = to;
return partial;
}
from += chars_read;
to++;
}
from_next = from;
to_next = to;
return ok;
}
codecvt<wchar_t, char, mbstate_t>::result
codecvt_byname<wchar_t, char, mbstate_t>
::do_unshift(state_type& state,
extern_type* to,
extern_type* to_limit,
extern_type*& to_next) const {
to_next = to;
size_t result = _Locale_unshift(_M_ctype, &state,
to, to_limit - to, &to_next);
if (result == (size_t) -1)
return error;
else if (result == (size_t) -2)
return partial;
else
# if defined (__ISCPP__)
return /*to_next == to ? noconv :*/ ok;
# else
return to_next == to ? noconv : ok;
# endif
}
int
codecvt_byname<wchar_t, char, mbstate_t>::do_encoding() const _STLP_NOTHROW {
if (_Locale_is_stateless(_M_ctype)) {
int max_width = _Locale_mb_cur_max(_M_ctype);
int min_width = _Locale_mb_cur_min(_M_ctype);
return min_width == max_width ? min_width : 0;
}
else
return -1;
}
bool codecvt_byname<wchar_t, char, mbstate_t>
::do_always_noconv() const _STLP_NOTHROW {
return false;
}
int
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -