File Index Symbol Index

// xlocale internal header (from <locale>)
#pragma once
#ifndef _XLOCALE_
#define _XLOCALE_
#ifndef RC_INVOKED
#include <climits>
#include <cstring>
#include <stdexcept> #include <typeinfo> #include <xlocinfo> #include <memory>
#include <xfacet>
_STL_DISABLE_CLANG_WARNINGS
#pragma push_macro("new")
#undef new
// CLASS TEMPLATE _Locbase
template
<
class
_Dummy
>
class
_Locbase
{
// define templatized category constants, instantiate on demand
public
: };
template
<
class
_Dummy
>
const
int
_Locbase
<
_Dummy
>::
collate
;
template
<
class
_Dummy
>
const
int
_Locbase
<
_Dummy
>::
ctype
;
template
<
class
_Dummy
>
const
int
_Locbase
<
_Dummy
>::
monetary
;
template
<
class
_Dummy
>
const
int
_Locbase
<
_Dummy
>::
numeric
;
template
<
class
_Dummy
>
const
int
_Locbase
<
_Dummy
>::
time
;
template
<
class
_Dummy
>
const
int
_Locbase
<
_Dummy
>::
messages
;
template
<
class
_Dummy
>
const
int
_Locbase
<
_Dummy
>::
all
;
template
<
class
_Dummy
>
const
int
_Locbase
<
_Dummy
>::
none
;
// CLASS locale
class
locale
;
template
<
class
_Facet
>
template
<
class
_Elem
>
class
collate
; {
// base class for marking allocations as CRT blocks
#ifdef _DEBUG
{
// replace operator new
void
*
_Ptr
=
operator
new
(
_Size
,
nothrow
);
if
(!
_Ptr
)
_Xbad_alloc
();
return
(
_Ptr
); } {
// replace nothrow operator new
} {
// replace operator delete
} {
// replace nothrow operator delete
operator
delete
(
_Ptr
); } {
// imitate True Placement New
return
(
_Ptr
); } {
// imitate True Placement Delete
}
#endif /* _DEBUG */
};
class
locale
:
public
_Locbase
<
int
>,
public
_Crt_new_delete
{
// nonmutable collection of facets that describe a locale
public
:
typedef
int
category
;
// CLASS id
{
// identifier stamp, unique for each distinct kind of facet
public
: : _Id(
_Val
) {
// construct with specified stamp value
} {
// get stamp, with lazy allocation
if
(
_Id
=
=
0
) {
// still zero, allocate stamp
if
(
_Id
=
=
0
) {
_Id
=
static_cast
<
size_t
>(++
_Id_cnt
); } }
return
(
_Id
); }
private
:
size_t
_Id
;
// the identifier stamp
public
: };
class
_Locimp
;
// CLASS facet
:
public
_Facet_base
,
public
_Crt_new_delete
{
// base class for all locale facets, performs reference counting
public
:
const
locale
* =
nullptr
) {
// get category value, or -1 if no corresponding C category
return
(
static_cast
<
size_t
>(-
1
)); } {
// increment use count
} {
// decrement use count
{
return
(
this
); }
return
(
nullptr
); }
private
:
_Atomic_counter_t
_Myrefs
;
// the reference count
protected
: : _Myrefs(
static_cast
<
_Atomic_integral_t
>(
_Initrefs
))
// non-atomic initialization
{
// construct with initial reference count
} {
// ensure that derived classes can be destroyed properly
}
public
: };
// CLASS _Locimp
:
public
facet
{
// reference-counted actual implementation of a locale
protected
: {
// destroy the object
_Locimp_dtor
(
this
); }
private
:
_New_Locimp
(
bool
_Transparent
=
false
);
_New_Locimp
(
const
_Locimp
&
_Right
);
_Locimp_dtor
(
_Locimp
*);
_Locimp_Addfac
(
_Locimp
*,
facet
*,
size_t
);
// add a facet
_Locimp_ctor
(
_Locimp
*,
const
_Locimp
&);
friend
locale; :
locale
::
facet
(
1
), _Facetvec(
nullptr
), _Facetcount(
0
), _Catmask(
none
), _Xparent(
_Transparent
), _Name(
"*"
) {
// construct an empty _Locimp
} :
locale
::
facet
(
1
), _Facetvec(
nullptr
), _Facetcount(
_Right
.
_Facetcount
), _Catmask(
_Right
.
_Catmask
), _Xparent(
_Right
.
_Xparent
), _Name(
_Right
.
_Name
.
c_str
()) {
// construct by copying
_Locimp_ctor
(
this
,
_Right
); } {
// add a facet
_Locimp_Addfac
(
this
,
_Pfacet
,
_Id
); }
category
,
_Locimp
*,
const
locale
*);
// make essential facets
category
,
_Locimp
*,
const
locale
*);
// make wchar_t facets
#ifdef _NATIVE_WCHAR_T_DEFINED
category
,
_Locimp
*,
const
locale
*);
// make ushort facets
#endif /* _NATIVE_WCHAR_T_DEFINED */
category
,
_Locimp
*,
const
locale
*);
// make remaining facets
facet
**
_Facetvec
;
// pointer to vector of facets
size_t
_Facetcount
;
// size of vector of facets
category
_Catmask
;
// mask describing implemented categories
bool
_Xparent
;
// true if locale is transparent
_Yarn
<
char
>
_Name
;
// locale name, or "*" if not known
public
: };
template
<
class
_Elem
,
class
_Traits
,
class
_Alloc
>
bool
operator
(
)
(
const
basic_string
<
_Elem
,
_Traits
,
_Alloc
>&
_Left
,
const
basic_string
<
_Elem
,
_Traits
,
_Alloc
>&
_Right
)
const
{
// compare _Left and _Right strings using collate facet in locale
return
(
_Coll_fac
.
compare
(
_Left
.
c_str
(),
_Left
.
c_str
() +
_Left
.
size
(),
_Right
.
c_str
(),
_Right
.
c_str
() +
_Right
.
size
())
<
0
); }
template
<
class
_Facet
>
locale
combine
(
const
locale
&
_Loc
)
const
{
// combine two locales
_Facet
*
_Facptr
;
_Facptr
= (
_Facet
*)&
use_facet
<
_Facet
>(
_Loc
);
_Xruntime_error
(
"locale::combine facet missing"
);
_Locimp
*
_Newimp
=
_Locimp
::
_New_Locimp
(*
_Ptr
);
_Newimp
->
_Addfac
(
_Facptr
,
_Facet
::id);
_Newimp
->
_Catmask
=
none
;
_Newimp
->
_Name
=
"*"
;
return
(
locale
(
_Newimp
)); }
template
<
class
_Facet
>
locale
(
const
locale
&
_Loc
,
const
_Facet
*
_Facptr
) : _Ptr(
_Locimp
::
_New_Locimp
(*
_Loc
.
_Ptr
)) {
// construct from _Loc, replacing facet with *_Facptr
if
(
_Facptr
!=
nullptr
) {
// replace facet
_Ptr
->
_Addfac
((
_Facet
*)
_Facptr
,
_Facet
::id);
_Ptr
->
_Catmask
=
none
;
_Ptr
->
_Name
=
"*"
; } }
locale
(
_Uninitialized
) {
// defer construction
}
locale
(
const
locale
&
_Right
)
noexcept
: _Ptr(
_Right
.
_Ptr
) {
// construct by copying
_Ptr
->
_Incref
(); }
locale
()
noexcept
: _Ptr(
_Init
(
true
)) {
// construct from current locale
}
#if !defined(MRTDLL) || !defined(_CRTBLD)
locale
(
const
locale
&
_Loc
,
const
locale
&
_Other
,
category
_Cat
) : _Ptr(
_Locimp
::
_New_Locimp
(*
_Loc
.
_Ptr
)) {
// construct a locale by copying named facets
if
(
_Cat
!
=
none
) {
// worth adding, do it
_Locimp
::
_Makeloc
(
_Lobj
,
_Cat
,
_Ptr
, &
_Other
);
_Lobj
.
_Addcats
(
_Loc
.
_Ptr
->
_Catmask
,
_Loc
.
name
().
c_str
());
_Lobj
.
_Addcats
(
_Other
.
_Ptr
->
_Catmask
,
_Other
.
name
().
c_str
());
_Ptr
->
_Catmask
=
_Loc
.
_Ptr
->
_Catmask
|
_Other
.
_Ptr
->
_Catmask
;
_Ptr
->
_Name
=
_Lobj
.
_Getname
();
delete
_Ptr
->
_Decref
(); } }
private
:
void
_Construct
(
const
string
&
_Str
,
category
_Cat
) {
// construct a locale with named facets
bool
_Bad
=
false
;
_Init
();
if
(
_Cat
!
=
none
) {
// worth adding, do it
if
(
_Badname
(
_Lobj
))
_Bad
=
true
;
else
{
// name okay, build the locale
_Locimp
::
_Makeloc
(
_Lobj
,
_Cat
,
_Ptr
,
nullptr
);
_Ptr
->
_Catmask
=
_Cat
;
_Ptr
->
_Name
=
_Str
.
c_str
(); }
delete
_Ptr
->
_Decref
(); }
if
(
_Bad
) {
// Don't throw within _BEGIN_LOCINFO if we can avoid it
delete
_Ptr
->
_Decref
();
_Xruntime_error
(
"bad locale name"
); } }
public
:
explicit
locale
(
const
char
*
_Locname
,
category
_Cat
=
all
) : _Ptr(
_Locimp
::
_New_Locimp
()) {
// construct a locale with named facets
// _Locname might have been returned from setlocale().
// Therefore, _Construct() takes const string&.
if
(
_Locname
==
nullptr
)
_Xruntime_error
(
"bad locale name"
);
_Construct
(
_Locname
,
_Cat
); }
locale
(
const
locale
&
_Loc
,
const
char
*
_Locname
,
category
_Cat
) : _Ptr(
_Locimp
::
_New_Locimp
(*
_Loc
.
_Ptr
)) {
// construct a locale by copying, replacing named facets
// _Locname might have been returned from setlocale().
// Therefore, _Construct() takes const string&.
if
(
_Locname
==
nullptr
)
_Xruntime_error
(
"bad locale name"
);
_Construct
(
_Locname
,
_Cat
); }
explicit
locale
(
const
string
&
_Str
,
category
_Cat
=
all
) : _Ptr(
_Locimp
::
_New_Locimp
()) {
// construct a locale with named facets
_Construct
(
_Str
,
_Cat
); }
locale
(
const
locale
&
_Loc
,
const
string
&
_Str
,
category
_Cat
) : _Ptr(
_Locimp
::
_New_Locimp
(*
_Loc
.
_Ptr
)) {
// construct a locale by copying, replacing named facets
_Construct
(
_Str
,
_Cat
); }
#endif /* !MRTDLL || !_CRTBLD */
~
locale
()
noexcept
{
// destroy the object
if
(
_Ptr
!=
nullptr
)
delete
_Ptr
->
_Decref
(); }
locale
&
operator
=
(
const
locale
&
_Right
)
noexcept
{
// assign a locale
if
(
_Ptr
!
=
_Right
.
_Ptr
) {
// different implementation, point at new one
delete
_Ptr
->
_Decref
();
_Ptr
=
_Right
.
_Ptr
;
_Ptr
->
_Incref
(); }
return
(*
this
); }
string
name
()
const
{
// return locale name
return
(
_Ptr
==
nullptr
?
string
() :
_Ptr
->
_Name
.
c_str
()); } {
// return locale name as NTBS
return
(
_Ptr
==
nullptr
?
""
:
_Ptr
->
_Name
.
c_str
()); }
const
facet
*
_Getfacet
(
size_t
_Id
)
const
{
// look up a facet in locale object
const
facet
*
_Facptr
=
_Id
<
_Ptr
->
_Facetcount
?
_Ptr
->
_Facetvec
[
_Id
] :
nullptr
;
// null if id off end
if
(
_Facptr
!=
nullptr
|| !
_Ptr
->
_Xparent
)
return
(
_Facptr
);
// found facet or not transparent
else
{
// look in current locale
locale
::
_Locimp
*
_Ptr0
=
_Getgloballocale
();
return
(
_Id
<
_Ptr0
->
_Facetcount
?
_Ptr0
->
_Facetvec
[
_Id
]
// get from current locale
:
nullptr
);
// no entry in current locale
} } {
// compare locales for equality
return
(
_Ptr
=
=
_Loc
.
_Ptr
|| (
name
().
compare
(
"*"
)
!
=
0
&&
name
().
compare
(
_Loc
.
name
())
=
=
0
)); } {
// test for locale inequality
return
(!(*
this
=
=
_Right
)); }
classic
();
// classic "C" locale
global
(
const
locale
&);
// current locale
empty
();
// empty (transparent) locale
private
:
locale
(
_Locimp
*
_Ptrimp
) : _Ptr(
_Ptrimp
) {
// construct from _Locimp pointer
}
_Init
(
bool
_Do_incref
=
false
);
// initialize locale
_Getgloballocale
();
_Setgloballocale
(
void
*);
bool
_Badname
(
const
_Locinfo
&
_Lobj
) {
// test if name is "*"
}
_Locimp
*
_Ptr
;
// pointer to locale implementation object
};
// SUPPORT TEMPLATES
template
<
class
_Facet
>
struct
_Facetptr
{
// store pointer to lazy facet for use_facet
};
template
<
class
_Facet
>
_Psave
=
nullptr
;
template
<
class
_Facet
>
inline
{
// get facet reference from locale
const
locale
::
facet
*
_Psave
=
_Facetptr
<
_Facet
>::
_Psave
;
// static pointer to lazy facet
const
size_t
_Id
=
_Facet
::id;
const
locale
::
facet
*
_Pf
=
_Loc
.
_Getfacet
(
_Id
);
if
(
_Pf
==
nullptr
) {
if
(
_Psave
!=
nullptr
) {
_Pf
=
_Psave
;
// lazy facet already allocated
}
else
if
(
_Facet
::_Getcat(&
_Psave
, &
_Loc
) ==
static_cast
<
size_t
>(-
1
)) {
#if _HAS_EXCEPTIONS
#else /* _HAS_EXCEPTIONS */
abort(); // lazy disallowed #endif /* _HAS_EXCEPTIONS */
}
else
{
// queue up lazy facet for destruction
auto
_Pfmod
=
const_cast
<
locale
::
facet
*>(
_Psave
);
unique_ptr
<
_Facet_base
>
_Psave_guard
(
static_cast
<
_Facet_base
*>(
_Pfmod
));
#if defined(_M_CEE)
_Facet_Register_m(_Pfmod); #else /* defined(_M_CEE) */
_Facet_Register
(
_Pfmod
);
#endif /* defined(_M_CEE) */
_Pfmod
->
_Incref
();
_Facetptr
<
_Facet
>::
_Psave
=
_Psave
;
_Pf
=
_Psave
; (
void
)
_Psave_guard
.
release
(); } }
return
(
static_cast
<
const
_Facet
&>(*
_Pf
));
// should be dynamic_cast
}
// end of use_facet body
// FUNCTION TEMPLATE _Getloctxt
template
<
class
_Elem
,
class
_InIt
>
inline
const
_Elem
*
_Ptr
) {
// find field at _Ptr that matches longest in [_First, _Last)
for
(
size_t
_Off
=
0
;
_Ptr
[
_Off
] != (
_Elem
)
0
; ++
_Off
)
if
(
_Ptr
[
_Off
] ==
_Ptr
[
0
]) ++
_Numfields
;
// add fields with leading mark to initial count
string
_Str
(
_Numfields
,
'\0'
);
// one column counter for each field
int
_Ans
= -
2
;
// no candidates so far
for
(
size_t
_Column
=
1
; ; ++
_Column
, (
void
)++
_First
,
_Ans
= -
1
) {
// test each element against all viable fields
bool
_Prefix
=
false
;
// seen at least one valid prefix
size_t
_Off
=
0
;
// offset into fields
size_t
_Field
=
0
;
// current field number
for
(;
_Field
<
_Numfields
; ++
_Field
) {
// test element at _Column in field _Field
while
(
_Ptr
[
_Off
] != (
_Elem
)
0
&&
_Ptr
[
_Off
] !=
_Ptr
[
0
]) {
// find beginning of field
++
_Off
; }
if
(
_Str
[
_Field
]
!
=
'\0'
) {
_Off
+=
_Str
[
_Field
];
// skip tested columns in field
}
else
if
(
_Ptr
[
_Off
+=
_Column
] ==
_Ptr
[
0
] ||
_Ptr
[
_Off
] == (
_Elem
)
0
) {
// matched all of field, save as possible answer
_Str
[
_Field
] = (
char
)(
_Column
<
127
?
_Column
:
127
);
// save skip count if small enough
_Ans
= (
int
)
_Field
;
// save answer
}
else
if
(
_First
==
_Last
||
_Ptr
[
_Off
] != *
_First
) {
_Str
[
_Field
] = (
char
)(
_Column
<
127
?
_Column
:
127
);
// no match, just save skip count
}
else
{
_Prefix
=
true
;
// still a valid prefix
} }
if
(!
_Prefix
||
_First
==
_Last
)
break
;
// no pending prefixes or no input, give up
}
return
(
_Ans
);
// return field number or negative value on failure
}
// FUNCTION TEMPLATE _Maklocbyte
template
<
class
_Elem
>
inline
const
_Locinfo
::
_Cvtvec
&) {
// convert _Elem to char using _Cvtvec
return
((
char
)(
unsigned
char
)
_Char
); }
template
<>
inline
const
_Locinfo
::
_Cvtvec
&
_Cvt
) {
// convert wchar_t to char using _Cvtvec
char
_Byte
=
'\0'
;
mbstate_t
_Mbst1
= {};
_Wcrtomb
(&
_Byte
,
_Char
, &
_Mbst1
, &
_Cvt
);
return
(
_Byte
); }
#ifdef _NATIVE_WCHAR_T_DEFINED
template
<>
inline
const
_Locinfo
::
_Cvtvec
&
_Cvt
) {
// convert unsigned short to char using _Cvtvec
char
_Byte
=
'\0'
;
mbstate_t
_Mbst1
= {};
_Wcrtomb
(&
_Byte
, (
wchar_t
)
_Char
, &
_Mbst1
, &
_Cvt
);
return
(
_Byte
); }
#endif /* _NATIVE_WCHAR_T_DEFINED */
// FUNCTION TEMPLATE _Maklocchr
template
<
class
_Elem
>
inline
const
_Locinfo
::
_Cvtvec
&) {
// convert char to _Elem using _Cvtvec
return
((
_Elem
)(
unsigned
char
)
_Byte
); }
template
<>
inline
const
_Locinfo
::
_Cvtvec
&
_Cvt
) {
// convert char to wchar_t using _Cvtvec
wchar_t
_Wc
=
L'\0'
;
mbstate_t
_Mbst1
= {};
_Mbrtowc
(&
_Wc
, &
_Byte
,
1
, &
_Mbst1
, &
_Cvt
);
return
(
_Wc
); }
#ifdef _NATIVE_WCHAR_T_DEFINED
template
<>
inline
const
_Locinfo
::
_Cvtvec
&
_Cvt
) {
// convert char to unsigned short using _Cvtvec
unsigned
short
_Wc
= (
unsigned
short
)
0
;
mbstate_t
_Mbst1
= {};
_Mbrtowc
((
wchar_t
*)&
_Wc
, &
_Byte
,
1
, &
_Mbst1
, &
_Cvt
);
return
(
_Wc
); }
#endif /* _NATIVE_WCHAR_T_DEFINED */
// FUNCTION TEMPLATE _Maklocstr
template
<
class
_Elem
>
inline
const
_Locinfo
::
_Cvtvec
&) {
// convert C string to _Elem sequence using _Cvtvec
_Elem
*
_Ptrdest
= (
_Elem
*)
_calloc_dbg
(
_Count
,
sizeof
(
_Elem
),
if
(!
_Ptrdest
)
_Xbad_alloc
();
for
(
_Elem
*
_Ptrnext
=
_Ptrdest
;
0
<
_Count
; --
_Count
, ++
_Ptrnext
, ++
_Ptr
) *
_Ptrnext
= (
_Elem
)(
unsigned
char
)*
_Ptr
;
return
(
_Ptrdest
); }
template
<>
inline
const
_Locinfo
::
_Cvtvec
&
_Cvt
) {
// convert C string to wchar_t sequence using _Cvtvec
size_t
_Count
,
_Count1
;
size_t
_Wchars
;
const
char
*
_Ptr1
;
int
_Bytes
;
wchar_t
_Wc
;
mbstate_t
_Mbst1
= {};
for
(
_Count
=
_Count1
,
_Wchars
=
0
,
_Ptr1
=
_Ptr
;
0
<
_Count
;
_Count
-=
_Bytes
,
_Ptr1
+=
_Bytes
, ++
_Wchars
)
if
((
_Bytes
=
_Mbrtowc
(&
_Wc
,
_Ptr1
,
_Count
, &
_Mbst1
, &
_Cvt
)) <=
0
)
break
; ++
_Wchars
;
// count terminating nul
wchar_t
*
_Ptrdest
= (
wchar_t
*)
_calloc_dbg
(
_Wchars
,
sizeof
(
wchar_t
),
if
(!
_Ptrdest
)
_Xbad_alloc
();
wchar_t
*
_Ptrnext
=
_Ptrdest
;
mbstate_t
_Mbst2
= {};
for
(;
0
<
_Wchars
;
_Count
-=
_Bytes
,
_Ptr
+=
_Bytes
, --
_Wchars
, ++
_Ptrnext
)
if
((
_Bytes
=
_Mbrtowc
(
_Ptrnext
,
_Ptr
,
_Count1
, &
_Mbst2
, &
_Cvt
)) <=
0
)
break
; *
_Ptrnext
=
L'\0'
;
return
(
_Ptrdest
); }
#ifdef _NATIVE_WCHAR_T_DEFINED
template
<>
inline
const
_Locinfo
::
_Cvtvec
&
_Cvt
) {
// convert C string to unsigned short sequence using _Cvtvec
size_t
_Count
,
_Count1
;
size_t
_Wchars
;
const
char
*
_Ptr1
;
int
_Bytes
;
unsigned
short
_Wc
;
mbstate_t
_Mbst1
= {};
for
(
_Count
=
_Count1
,
_Wchars
=
0
,
_Ptr1
=
_Ptr
;
0
<
_Count
;
_Count
-=
_Bytes
,
_Ptr1
+=
_Bytes
, ++
_Wchars
) {
if
((
_Bytes
=
_Mbrtowc
((
wchar_t
*)&
_Wc
,
_Ptr1
,
_Count
, &
_Mbst1
, &
_Cvt
)) <=
0
) {
break
; } } ++
_Wchars
;
// count terminating nul
wchar_t
*
_Ptrdest
= (
wchar_t
*)
_calloc_dbg
(
_Wchars
,
sizeof
(
wchar_t
),
if
(!
_Ptrdest
) {
_Xbad_alloc
(); }
wchar_t
*
_Ptrnext
=
_Ptrdest
;
mbstate_t
_Mbst2
= {};
for
(;
0
<
_Wchars
;
_Count
-=
_Bytes
,
_Ptr
+=
_Bytes
, --
_Wchars
, ++
_Ptrnext
) {
if
((
_Bytes
=
_Mbrtowc
(
_Ptrnext
,
_Ptr
,
_Count1
, &
_Mbst2
, &
_Cvt
)) <=
0
) {
break
; } } *
_Ptrnext
=
L'\0'
;
return
((
unsigned
short
*)
_Ptrdest
); }
#endif /* _NATIVE_WCHAR_T_DEFINED */
// STRUCT codecvt_base
:
public
locale
::
facet
{
// base class for codecvt
public
:
enum
{
// constants for different parse states
ok
,
partial
,
error
,
noconv
};
typedef
int
result
; :
locale
::
facet
(
_Refs
) {
// default constructor
} {
// return true if conversions never change input (from codecvt)
return
(
do_always_noconv
()); } {
// return maximum length required for a conversion (from codecvt)
return
(
do_max_length
()); } {
// return length of code sequence (from codecvt)
return
(
do_encoding
()); } {
// destroy the object
}
protected
: {
// return true if conversions never change input (from codecvt)
return
(
false
); } {
// return maximum length required for a conversion (from codecvt)
return
(
1
); } {
// return length of code sequence (from codecvt)
return
(
1
);
// -1 ==> state dependent, 0 ==> varying length
} };
// CLASS TEMPLATE codecvt
template
<
class
_Elem
,
class
_Byte
,
class
_Statype
>
class
codecvt
:
public
codecvt_base
{
// facet for converting between _Elem and char (_Byte) sequences
public
:
typedef
_Elem
intern_type
;
typedef
_Byte
extern_type
;
typedef
_Statype
state_type
;
const
_Byte
*
_First1
,
const
_Byte
*
_Last1
,
const
_Byte
*&
_Mid1
,
_Elem
*
_First2
,
_Elem
*
_Last2
,
_Elem
*&
_Mid2
)
const
{
// convert bytes [_First1, _Last1) to [_First2, _Last)
return
(
do_in
(
_State
,
_First1
,
_Last1
,
_Mid1
,
_First2
,
_Last2
,
_Mid2
)); }
const
_Elem
*
_First1
,
const
_Elem
*
_Last1
,
const
_Elem
*&
_Mid1
,
_Byte
*
_First2
,
_Byte
*
_Last2
,
_Byte
*&
_Mid2
)
const
{
// convert [_First1, _Last1) to bytes [_First2, _Last2)
return
(
do_out
(
_State
,
_First1
,
_Last1
,
_Mid1
,
_First2
,
_Last2
,
_Mid2
)); }
_Byte
*
_First2
,
_Byte
*
_Last2
,
_Byte
*&
_Mid2
)
const
{
// generate bytes to return to default shift state
return
(
do_unshift
(
_State
,
_First2
,
_Last2
,
_Mid2
)); }
const
_Byte
*
_Last1
,
size_t
_Count
)
const
{
// return min(_Count, converted length of bytes [_First1, _Last1))
return
(
do_length
(
_State
,
_First1
,
_Last1
,
_Count
)); } :
codecvt_base
(
_Refs
) {
// construct from current locale
_Init
(
_Locinfo
()); } :
codecvt_base
(
_Refs
) {
// construct from specified locale
_Init
(
_Lobj
); }
const
locale
*
_Ploc
=
nullptr
) {
// return locale category mask and construct standard facet
if
(
_Ppf
!=
nullptr
&& *
_Ppf
==
nullptr
) *
_Ppf
=
new
codecvt
<
_Elem
,
_Byte
,
_Statype
>(
_Locinfo
(
_Ploc
->
c_str
())); }
protected
: {
// destroy the object
} {
// initialize from _Locinfo object
} {
// return true if conversions never change input (from codecvt)
return
(
is_same_v
<
_Byte
,
_Elem
>); }
const
_Byte
*
_First1
,
const
_Byte
*
_Last1
,
const
_Byte
*&
_Mid1
,
_Elem
*
_First2
,
_Elem
*
_Last2
,
_Elem
*&
_Mid2
)
const
{
// convert bytes [_First1, _Last1) to [_First2, _Last)
_Mid1
=
_First1
;
_Mid2
=
_First2
;
if
(
is_same_v
<
_Byte
,
_Elem
>) {
return
(
noconv
);
// convert nothing
}
// types differ, copy one for one
for
(;
_Mid1
!
=
_Last1
&&
_Mid2
!
=
_Last2
; ++
_Mid1
, ++
_Mid2
) { *
_Mid2
= (
_Elem
)*
_Mid1
; }
return
(
ok
); }
const
_Elem
*
_First1
,
const
_Elem
*
_Last1
,
const
_Elem
*&
_Mid1
,
_Byte
*
_First2
,
_Byte
*
_Last2
,
_Byte
*&
_Mid2
)
const
{
// convert [_First1, _Last1) to bytes [_First2, _Last)
_Mid1
=
_First1
;
_Mid2
=
_First2
;
if
(
is_same_v
<
_Byte
,
_Elem
>) {
return
(
noconv
);
// convert nothing
}
// types differ, copy one for one
for
(;
_Mid1
!
=
_Last1
&&
_Mid2
!
=
_Last2
; ++
_Mid1
, ++
_Mid2
) { *
_Mid2
= (
_Byte
)*
_Mid1
; }
return
(
ok
); }
_Byte
*
_First2
,
_Byte
*,
_Byte
*&
_Mid2
)
const
{
// generate bytes to return to default shift state
_Mid2
=
_First2
;
return
(
ok
);
// convert nothing
}
const
_Byte
*
_Last1
,
size_t
_Count
)
const
{
// return min(_Count, converted length of bytes [_First1, _Last1))
return
(
static_cast
<
int
>(
_Min_value
(
_Count
,
static_cast
<
size_t
>(
_Last1
-
_First1
))));
// assumes 1:1 conversion
} };
// STATIC codecvt::id OBJECT
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdllimport-static-field-def"
#endif /* __clang__ */
template
<
class
_Elem
,
class
_Byte
,
class
_Statype
>
#ifdef __clang__
#pragma clang diagnostic pop
#endif /* __clang__ */
// ENUM _Codecvt_mode
enum
_Codecvt_mode
{
_Consume_header
=
4
,
_Generate_header
=
2
};
// CLASS codecvt<char16_t, char, _Mbstatet>
template
<> :
public
codecvt_base
{
// facet for converting between char16_t and UTF-8 byte sequences
public
:
typedef
codecvt
<
char16_t
,
char
,
_Mbstatet
>
_Mybase
;
typedef
char16_t
_Elem
;
typedef
char
_Byte
;
typedef
_Mbstatet
_Statype
;
typedef
_Elem
intern_type
;
typedef
_Byte
extern_type
;
typedef
_Statype
state_type
;
const
_Byte
*
_First1
,
const
_Byte
*
_Last1
,
const
_Byte
*&
_Mid1
,
_Elem
*
_First2
,
_Elem
*
_Last2
,
_Elem
*&
_Mid2
)
const
{
// convert bytes [_First1, _Last1) to [_First2, _Last)
return
(
do_in
(
_State
,
_First1
,
_Last1
,
_Mid1
,
_First2
,
_Last2
,
_Mid2
)); }
const
_Elem
*
_First1
,
const
_Elem
*
_Last1
,
const
_Elem
*&
_Mid1
,
_Byte
*
_First2
,
_Byte
*
_Last2
,
_Byte
*&
_Mid2
)
const
{
// convert [_First1, _Last1) to bytes [_First2, _Last)
return
(
do_out
(
_State
,
_First1
,
_Last1
,
_Mid1
,
_First2
,
_Last2
,
_Mid2
)); }
_Byte
*
_First2
,
_Byte
*
_Last2
,
_Byte
*&
_Mid2
)
const
{
// generate bytes to return to default shift state
return
(
do_unshift
(
_State
,
_First2
,
_Last2
,
_Mid2
)); }
const
_Byte
*
_Last1
,
size_t
_Count
)
const
{
// return min(_Count, converted length of bytes [_First1, _Last1))
return
(
do_length
(
_State
,
_First1
,
_Last1
,
_Count
)); } :
codecvt_base
(
_Refs
), _Maxcode(
0x10ffff
), _Mode(
_Consume_header
) {
// construct from current locale
_Init
(
_Lobj
); } :
codecvt_base
(
_Refs
), _Maxcode(
0x10ffff
), _Mode(
_Consume_header
) {
// construct from specified locale
_Init
(
_Lobj
); }
_Codecvt_mode
_Mode_arg
,
size_t
_Refs
=
0
) :
codecvt_base
(
_Refs
), _Maxcode(
_Maxcode_arg
), _Mode(
_Mode_arg
) {
// construct from specified locale and parameters
_Init
(
_Lobj
); }
const
locale
*
_Ploc
=
nullptr
) {
// return locale category mask and construct standard facet
if
(
_Ppf
!=
nullptr
&& *
_Ppf
==
nullptr
) { *
_Ppf
=
new
codecvt
<
_Elem
,
_Byte
,
_Statype
>(
_Locinfo
(
_Ploc
->
c_str
())); } }
protected
: {
// destroy the object
} {
// initialize
}
const
_Byte
*
_First1
,
const
_Byte
*
_Last1
,
const
_Byte
*&
_Mid1
,
_Elem
*
_First2
,
_Elem
*
_Last2
,
_Elem
*&
_Mid2
)
const
{
// convert bytes [_First1, _Last1) to [_First2, _Last2)
unsigned
short
*
_Pstate
= (
unsigned
short
*)&
_State
;
_Mid1
=
_First1
;
_Mid2
=
_First2
;
while
(
_Mid1
!
=
_Last1
&&
_Mid2
!
=
_Last2
) {
// convert a multibyte sequence
unsigned
char
_By
= (
unsigned
char
)*
_Mid1
;
unsigned
long
_Ch
;
int
_Nextra
,
_Nskip
;
if
(*
_Pstate
>
1
) {
if
(
_By
<
0x80
||
0xc0
<=
_By
) {
return
(
_Mybase
::
error
);
// not continuation byte
}
// deliver second half of two-word value
++
_Mid1
; *
_Mid2
++ = (
_Elem
)(*
_Pstate
| (
_By
&
0x3f
)); *
_Pstate
=
1
;
continue
; }
if
(
_By
<
0x80
) {
_Ch
=
_By
;
_Nextra
=
0
; }
else
if
(
_By
<
0xc0
) {
// 0x80-0xdf not first byte
++
_Mid1
;
return
(
_Mybase
::
error
); }
else
if
(
_By
<
0xe0
) {
_Ch
=
static_cast
<
unsigned
long
>(
_By
&
0x1f
);
_Nextra
=
1
; }
else
if
(
_By
<
0xf0
) {
_Ch
=
static_cast
<
unsigned
long
>(
_By
&
0x0f
);
_Nextra
=
2
; }
else
if
(
_By
<
0xf8
) {
_Ch
=
static_cast
<
unsigned
long
>(
_By
&
0x07
);
_Nextra
=
3
; }
else
{
_Ch
=
static_cast
<
unsigned
long
>(
_By
&
0x03
);
_Nextra
=
_By
<
0xfc
?
4
:
5
; }
_Nskip
=
_Nextra
<
3
?
0
:
1
;
// leave a byte for 2nd word
_First1
=
_Mid1
;
// roll back point
if
(
_Nextra
=
=
0
) { ++
_Mid1
; }
else
if
(
_Last1
-
_Mid1
<
_Nextra
+
1
-
_Nskip
) {
break
;
// not enough input
}
else
{
for
(++
_Mid1
;
_Nskip
<
_Nextra
; --
_Nextra
, ++
_Mid1
) {
if
((
_By
= (
unsigned
char
)*
_Mid1
)
<
0x80
||
0xc0
<=
_By
) {
return
(
_Mybase
::
error
);
// not continuation byte
}
else
{
_Ch
=
_Ch
<<
6
| (
_By
&
0x3f
); } } }
if
(
0
<
_Nskip
) {
_Ch
<<=
6
;
// get last byte on next call
}
if
((
_Maxcode
<
0x10ffff
?
_Maxcode
:
0x10ffff
)
<
_Ch
) {
return
(
_Mybase
::
error
);
// value too large
}
if
(
0xffff
<
_Ch
) {
// deliver first half of two-word value, save second word
unsigned
short
_Ch0
= (
unsigned
short
)(
0xd800
| (
_Ch
>>
10
) -
0x0040
); *
_Mid2
++ = (
_Elem
)
_Ch0
; *
_Pstate
= (
unsigned
short
)(
0xdc00
| (
_Ch
&
0x03ff
));
continue
; }
if
(
_Nskip
!
=
0
) {
if
(
_Mid1
=
=
_Last1
) {
// not enough bytes, noncanonical value
_Mid1
=
_First1
;
break
; }
if
((
_By
= (
unsigned
char
)*
_Mid1
++)
<
0x80
||
0xc0
<=
_By
) {
return
(
_Mybase
::
error
);
// not continuation byte
}
_Ch
|=
_By
&
0x3f
;
// complete noncanonical value
}
if
(*
_Pstate
=
=
0
) {
// first time, maybe look for and consume header
*
_Pstate
=
1
;
if
((
_Mode
&
_Consume_header
) !=
0
&&
_Ch
==
0xfeff
) {
// drop header and retry
const
result
_Ans
=
do_in
(
_State
,
_Mid1
,
_Last1
,
_Mid1
,
_First2
,
_Last2
,
_Mid2
);
if
(
_Ans
=
=
_Mybase
::
partial
) {
// roll back header determination
*
_Pstate
=
0
;
_Mid1
=
_First1
; }
return
(
_Ans
); } } *
_Mid2
++ = (
_Elem
)
_Ch
; }
return
(
_First1
=
=
_Mid1
?
_Mybase
::
partial
:
_Mybase
::
ok
); }
const
_Elem
*
_First1
,
const
_Elem
*
_Last1
,
const
_Elem
*&
_Mid1
,
_Byte
*
_First2
,
_Byte
*
_Last2
,
_Byte
*&
_Mid2
)
const
{
// convert [_First1, _Last1) to bytes [_First2, _Last)
unsigned
short
*
_Pstate
= (
unsigned
short
*)&
_State
;
_Mid1
=
_First1
;
_Mid2
=
_First2
;
while
(
_Mid1
!
=
_Last1
&&
_Mid2
!
=
_Last2
) {
// convert and put a wide char
unsigned
long
_Ch
;
const
unsigned
short
_Ch1
= (
unsigned
short
)*
_Mid1
;
bool
_Save
=
false
;
if
(
1
<
*
_Pstate
) {
// get saved MS 11 bits from *_Pstate
if
(
_Ch1
<
0xdc00
||
0xe000
<=
_Ch1
)
return
(
_Mybase
::
error
);
// bad second word
_Ch
=
static_cast
<
unsigned
long
>((*
_Pstate
<<
10
) | (
_Ch1
-
0xdc00
)); }
else
if
(
0xd800
<=
_Ch1
&&
_Ch1
<
0xdc00
) {
// get new first word
_Ch
=
static_cast
<
unsigned
long
>((
_Ch1
-
0xd800
+
0x0040
) <<
10
);
_Save
=
true
;
// put only first byte, rest with second word
}
else
_Ch
=
_Ch1
;
// not first word, just put it
_Byte
_By
;
int
_Nextra
;
if
(
_Ch
<
0x0080
) {
_By
= (
_Byte
)
_Ch
;
_Nextra
=
0
; }
else
if
(
_Ch
<
0x0800
) {
_By
= (
_Byte
)(
0xc0
|
_Ch
>>
6
);
_Nextra
=
1
; }
else
if
(
_Ch
<
0x10000
) {
_By
= (
_Byte
)(
0xe0
|
_Ch
>>
12
);
_Nextra
=
2
; }
else
{
_By
= (
_Byte
)(
0xf0
|
_Ch
>>
18
);
_Nextra
=
3
; }
int
_Nput
=
_Nextra
<
3
?
_Nextra
+
1
:
_Save
?
1
:
3
;
if
(
_Last2
-
_Mid2
<
_Nput
) {
break
;
// not enough room, even without header
}
if
(*
_Pstate
=
=
0
&& (
_Mode
&
_Generate_header
) !=
0
) {
if
(
_Last2
-
_Mid2
<
3
+
_Nput
) {
break
;
// not enough room for header + output
}
// prepend header
*
_Mid2
++ = (
_Byte
)(
unsigned
char
)
0xef
; *
_Mid2
++ = (
_Byte
)(
unsigned
char
)
0xbb
; *
_Mid2
++ = (
_Byte
)(
unsigned
char
)
0xbf
; } ++
_Mid1
;
if
(
_Save
||
_Nextra
<
3
) {
// put first byte of sequence, if not already put
*
_Mid2
++ =
_By
; --
_Nput
; }
for
(;
0
<
_Nput
; --
_Nput
) { *
_Mid2
++ = (
_Byte
)((
_Ch
>>
6
* --
_Nextra
&
0x3f
) |
0x80
); } *
_Pstate
= (
unsigned
short
)(
_Save
?
_Ch
>>
10
:
1
); }
return
(
_First1
=
=
_Mid1
?
_Mybase
::
partial
:
_Mybase
::
ok
); }
_Byte
*
_First2
,
_Byte
*,
_Byte
*&
_Mid2
)
const
{
// generate bytes to return to default shift state
unsigned
short
*
_Pstate
= (
unsigned
short
*)&
_State
;
_Mid2
=
_First2
;
return
(
1
<
*
_Pstate
?
_Mybase
::
error
:
_Mybase
::
ok
);
// fail if trailing first word
}
const
_Byte
*
_Last1
,
size_t
_Count
)
const
{
// return min(_Count, converted length of bytes [_First1, _Last1))
size_t
_Wchars
=
0
;
_Statype
_Mystate
=
_State
;
while
(
_Wchars
<
_Count
&&
_First1
!
=
_Last1
) {
// convert another wide character
const
_Byte
*
_Mid1
;
_Elem
*
_Mid2
;
_Elem
_Ch
;
const
auto
_Result
=
do_in
(
_Mystate
,
_First1
,
_Last1
,
_Mid1
, &
_Ch
, &
_Ch
+
1
,
_Mid2
);
if
(
_Result
=
=
_Mybase
::
noconv
) {
_Wchars
+=
static_cast
<
size_t
>(
_Last1
-
_First1
);
break
; }
if
(
_Result
=
=
_Mybase
::
ok
) {
if
(
_Mid2
=
=
&
_Ch
+
1
) { ++
_Wchars
;
// replacement do_in might not convert one
}
_First1
=
_Mid1
;
continue
; }
break
;
// error or partial
} } {
// return true if conversions never change input
return
(
false
); } {
// return maximum length required for a conversion
return
((
_Mode
&
_Consume_header
) !=
0
?
9
// header + max input
: (
_Mode
&
_Generate_header
) !=
0
?
7
// header + max output
:
6
);
// 6-byte max input sequence, no 3-byte header
}
virtual
int
do_encoding
()
const
noexcept
override
{
// return length of code sequence (from codecvt)
return
(
0
);
// 0 => varying length
}
private
:
unsigned
long
_Maxcode
;
// default: 0x10ffff
_Codecvt_mode
_Mode
;
// default: _Consume_header
};
// CLASS codecvt<char32_t, char, _Mbstatet>
template
<> :
public
codecvt_base
{
// facet for converting between char32_t and UTF-8 byte sequences
public
:
typedef
codecvt
<
char32_t
,
char
,
_Mbstatet
>
_Mybase
;
typedef
char32_t
_Elem
;
typedef
char
_Byte
;
typedef
_Mbstatet
_Statype
;
typedef
_Elem
intern_type
;
typedef
_Byte
extern_type
;
typedef
_Statype
state_type
;
const
_Byte
*
_First1
,
const
_Byte
*
_Last1
,
const
_Byte
*&
_Mid1
,
_Elem
*
_First2
,
_Elem
*
_Last2
,
_Elem
*&
_Mid2
)
const
{
// convert bytes [_First1, _Last1) to [_First2, _Last)
return
(
do_in
(
_State
,
_First1
,
_Last1
,
_Mid1
,
_First2
,
_Last2
,
_Mid2
)); }
const
_Elem
*
_First1
,
const
_Elem
*
_Last1
,
const
_Elem
*&
_Mid1
,
_Byte
*
_First2
,
_Byte
*
_Last2
,
_Byte
*&
_Mid2
)
const
{
// convert [_First1, _Last1) to bytes [_First2, _Last)
return
(
do_out
(
_State
,
_First1
,
_Last1
,
_Mid1
,
_First2
,
_Last2
,
_Mid2
)); }
_Byte
*
_First2
,
_Byte
*
_Last2
,
_Byte
*&
_Mid2
)
const
{
// generate bytes to return to default shift state
return
(
do_unshift
(
_State
,
_First2
,
_Last2
,
_Mid2
)); }
const
_Byte
*
_Last1
,
size_t
_Count
)
const
{
// return min(_Count, converted length of bytes [_First1, _Last1))
return
(
do_length
(
_State
,
_First1
,
_Last1
,
_Count
)); } :
codecvt_base
(
_Refs
), _Maxcode(
0xffffffff
), _Mode(
_Consume_header
) {
// construct from current locale
_Init
(
_Lobj
); } :
codecvt_base
(
_Refs
), _Maxcode(
0xffffffff
), _Mode(
_Consume_header
) {
// construct from specified locale
_Init
(
_Lobj
); }
_Codecvt_mode
_Mode_arg
,
size_t
_Refs
=
0
) :
codecvt_base
(
_Refs
), _Maxcode(
_Maxcode_arg
), _Mode(
_Mode_arg
) {
// construct from specified locale and parameters
_Init
(
_Lobj
); }
const
locale
*
_Ploc
=
nullptr
) {
// return locale category mask and construct standard facet
if
(
_Ppf
!=
nullptr
&& *
_Ppf
==
nullptr
) *
_Ppf
=
new
codecvt
<
_Elem
,
_Byte
,
_Statype
>(
_Locinfo
(
_Ploc
->
c_str
())); }
protected
: {
// destroy the object
} {
// initialize
}
const
_Byte
*
_First1
,
const
_Byte
*
_Last1
,
const
_Byte
*&
_Mid1
,
_Elem
*
_First2
,
_Elem
*
_Last2
,
_Elem
*&
_Mid2
)
const
{
// convert bytes [_First1, _Last1) to [_First2, _Last)
char
*
_Pstate
= (
char
*)&
_State
;
_Mid1
=
_First1
;
_Mid2
=
_First2
;
while
(
_Mid1
!
=
_Last1
&&
_Mid2
!
=
_Last2
) {
// convert a multibyte sequence
unsigned
char
_By
= (
unsigned
char
)*
_Mid1
;
unsigned
long
_Ch
;
int
_Nextra
;
if
(
_By
<
0x80
) {
_Ch
=
_By
;
_Nextra
=
0
; }
else
if
(
_By
<
0xc0
) {
// 0x80-0xdf not first byte
++
_Mid1
;
return
(
_Mybase
::
error
); }
else
if
(
_By
<
0xe0
) {
_Ch
=
static_cast
<
unsigned
long
>(
_By
&
0x1f
);
_Nextra
=
1
; }
else
if
(
_By
<
0xf0
) {
_Ch
=
static_cast
<
unsigned
long
>(
_By
&
0x0f
);
_Nextra
=
2
; }
else
if
(
_By
<
0xf8
) {
_Ch
=
static_cast
<
unsigned
long
>(
_By
&
0x07
);
_Nextra
=
3
; }
else
{
_Ch
=
static_cast
<
unsigned
long
>(
_By
&
0x03
);
_Nextra
=
_By
<
0xfc
?
4
:
5
; }
if
(
_Nextra
=
=
0
) { ++
_Mid1
; }
else
if
(
_Last1
-
_Mid1
<
_Nextra
+
1
) {
break
;
// not enough input
}
else
{
for
(++
_Mid1
;
0
<
_Nextra
; --
_Nextra
, ++
_Mid1
) {
if
((
_By
= (
unsigned
char
)*
_Mid1
)
<
0x80
||
0xc0
<=
_By
) {
return
(
_Mybase
::
error
);
// not continuation byte
}
else
{
_Ch
=
_Ch
<<
6
| (
_By
&
0x3f
); } } }
if
(*
_Pstate
=
=
0
) {
// first time, maybe look for and consume header
*
_Pstate
=
1
;
if
((
_Mode
&
_Consume_header
) !=
0
&&
_Ch
==
0xfeff
) {
// drop header and retry
const
result
_Ans
=
do_in
(
_State
,
_Mid1
,
_Last1
,
_Mid1
,
_First2
,
_Last2
,
_Mid2
);
if
(
_Ans
=
=
_Mybase
::
partial
) {
// roll back header determination
*
_Pstate
=
0
;
_Mid1
=
_First1
; }
return
(
_Ans
); } }
if
(
_Maxcode
<
_Ch
) {
return
(
_Mybase
::
error
);
// code too large
} *
_Mid2
++ = (
_Elem
)
_Ch
; }
return
(
_First1
=
=
_Mid1
?
_Mybase
::
partial
:
_Mybase
::
ok
); }
const
_Elem
*
_First1
,
const
_Elem
*
_Last1
,
const
_Elem
*&
_Mid1
,
_Byte
*
_First2
,
_Byte
*
_Last2
,
_Byte
*&
_Mid2
)
const
{
// convert [_First1, _Last1) to bytes [_First2, _Last)
char
*
_Pstate
= (
char
*)&
_State
;
_Mid1
=
_First1
;
_Mid2
=
_First2
;
while
(
_Mid1
!
=
_Last1
&&
_Mid2
!
=
_Last2
) {
// convert and put a wide char
_Byte
_By
;
int
_Nextra
;
unsigned
long
_Ch
= (
unsigned
long
)*
_Mid1
;
if
(
_Maxcode
<
_Ch
)
return
(
_Mybase
::
error
);
if
(
_Ch
<
0x0080
) {
_By
= (
_Byte
)
_Ch
;
_Nextra
=
0
; }
else
if
(
_Ch
<
0x0800
) {
_By
= (
_Byte
)(
0xc0
|
_Ch
>>
6
);
_Nextra
=
1
; }
else
if
(
_Ch
<
0x00010000
) {
_By
= (
_Byte
)(
0xe0
|
_Ch
>>
12
);
_Nextra
=
2
; }
else
if
(
_Ch
<
0x00200000
) {
_By
= (
_Byte
)(
0xf0
|
_Ch
>>
18
);
_Nextra
=
3
; }
else
if
(
_Ch
<
0x04000000
) {
_By
= (
_Byte
)(
0xf8
|
_Ch
>>
24
);
_Nextra
=
4
; }
else
{
_By
= (
_Byte
)(
0xfc
| (
_Ch
>>
30
&
0x03
));
_Nextra
=
5
; }
if
(*
_Pstate
=
=
0
) {
// first time, maybe generate header
*
_Pstate
=
1
;
if
((
_Mode
&
_Generate_header
) !=
0
) {
if
(
_Last2
-
_Mid2
<
3
+
1
+
_Nextra
) {
return
(
_Mybase
::
partial
);
// not enough room for both
}
// prepend header
*
_Mid2
++ = (
_Byte
)(
unsigned
char
)
0xef
; *
_Mid2
++ = (
_Byte
)(
unsigned
char
)
0xbb
; *
_Mid2
++ = (
_Byte
)(
unsigned
char
)
0xbf
; } }
if
(
_Last2
-
_Mid2
<
1
+
_Nextra
) {
break
;
// not enough room for output
} ++
_Mid1
;
for
(*
_Mid2
++ =
_By
;
0
<
_Nextra
; ) { *
_Mid2
++ = (
_Byte
)((
_Ch
>>
6
* --
_Nextra
&
0x3f
) |
0x80
); } }
return
(
_First1
=
=
_Mid1
?
_Mybase
::
partial
:
_Mybase
::
ok
); }
_Byte
*
_First2
,
_Byte
*,
_Byte
*&
_Mid2
)
const
{
// generate bytes to return to default shift state
_Mid2
=
_First2
;
return
(
_Mybase
::
ok
); }
const
_Byte
*
_Last1
,
size_t
_Count
)
const
{
// return min(_Count, converted length of bytes [_First1, _Last1))
size_t
_Wchars
=
0
;
_Statype
_Mystate
=
_State
;
while
(
_Wchars
<
_Count
&&
_First1
!
=
_Last1
) {
// convert another wide character
const
_Byte
*
_Mid1
;
_Elem
*
_Mid2
;
_Elem
_Ch
;
const
auto
_Result
=
do_in
(
_Mystate
,
_First1
,
_Last1
,
_Mid1
, &
_Ch
, &
_Ch
+
1
,
_Mid2
);
if
(
_Result
=
=
_Mybase
::
noconv
) {
_Wchars
+=
static_cast
<
size_t
>(
_Last1
-
_First1
);
break
; }
if
(
_Result
=
=
_Mybase
::
ok
) {
if
(
_Mid2
=
=
&
_Ch
+
1
) { ++
_Wchars
;
// replacement do_in might not convert one
}
_First1
=
_Mid1
;
continue
; }
break
;
// error or partial
} } {
// return true if conversions never change input
return
(
false
); } {
// return maximum length required for a conversion
return
((
_Mode
& (
_Consume_header
|
_Generate_header
)) !=
0
?
9
:
6
); } {
// return length of code sequence (from codecvt)
return
((
_Mode
& (
_Consume_header
|
_Generate_header
)) !=
0
? -
1
:
0
);
// -1 => state dependent, 0 => varying length
}
private
:
unsigned
long
_Maxcode
;
// default: 0xffffffff
_Codecvt_mode
_Mode
;
// default: _Consume_header
};
// CLASS codecvt<wchar_t, char, _Mbstatet>
template
<> :
public
codecvt_base
{
// facet for converting between wchar_t and char (_Byte) sequences
public
:
typedef
wchar_t
_Elem
;
typedef
char
_Byte
;
typedef
_Mbstatet
_Statype
;
typedef
_Elem
intern_type
;
typedef
_Byte
extern_type
;
typedef
_Statype
state_type
;
const
_Byte
*
_First1
,
const
_Byte
*
_Last1
,
const
_Byte
*&
_Mid1
,
_Elem
*
_First2
,
_Elem
*
_Last2
,
_Elem
*&
_Mid2
)
const
{
// convert bytes [_First1, _Last1) to [_First2, _Last)
return
(
do_in
(
_State
,
_First1
,
_Last1
,
_Mid1
,
_First2
,
_Last2
,
_Mid2
)); }
const
_Elem
*
_First1
,
const
_Elem
*
_Last1
,
const
_Elem
*&
_Mid1
,
_Byte
*
_First2
,
_Byte
*
_Last2
,
_Byte
*&
_Mid2
)
const
{
// convert [_First1, _Last1) to bytes [_First2, _Last)
return
(
do_out
(
_State
,
_First1
,
_Last1
,
_Mid1
,
_First2
,
_Last2
,
_Mid2
)); }
_Byte
*
_First2
,
_Byte
*
_Last2
,
_Byte
*&
_Mid2
)
const
{
// generate bytes to return to default shift state
return
(
do_unshift
(
_State
,
_First2
,
_Last2
,
_Mid2
)); }
const
_Byte
*
_Last1
,
size_t
_Count
)
const
{
// return min(_Count, converted length of bytes [_First1, _Last1))
return
(
do_length
(
_State
,
_First1
,
_Last1
,
_Count
)); } :
codecvt_base
(
_Refs
) {
// construct from current locale
_Init
(
_Lobj
); } :
codecvt_base
(
_Refs
) {
// construct from specified locale
_Init
(
_Lobj
); }
const
locale
*
_Ploc
=
nullptr
) {
// return locale category mask and construct standard facet
if
(
_Ppf
!=
nullptr
&& *
_Ppf
==
nullptr
) *
_Ppf
=
new
codecvt
<
_Elem
,
_Byte
,
_Statype
>(
_Locinfo
(
_Ploc
->
c_str
())); }
protected
: {
// destroy the object
} {
// initialize from _Lobj
_Cvt
=
_Lobj
.
_Getcvt
(); }
const
_Byte
*
_First1
,
const
_Byte
*
_Last1
,
const
_Byte
*&
_Mid1
,
_Elem
*
_First2
,
_Elem
*
_Last2
,
_Elem
*&
_Mid2
)
const
{
// convert bytes [_First1, _Last1) to [_First2, _Last)
_Statype
_Mystate
{};
_Adl_verify_range
(
_First1
,
_Last1
);
_Adl_verify_range
(
_First2
,
_Last2
);
_Mid1
=
_First1
;
_Mid2
=
_First2
;
for
(;;) {
if
(
_Mid1
=
=
_Last1
) {
return
(
ok
); }
if
(
_Mid2
=
=
_Last2
) {
return
(
partial
); }
int
_Bytes
=
_Mbrtowc
(
_Mid2
,
_Mid1
,
static_cast
<
size_t
>(
_Last1
-
_Mid1
), &
_Mystate
, &
_Cvt
);
switch
(
_Bytes
) {
case
-
2
:
// partial conversion
return
(
partial
);
case
-
1
:
// failed conversion
return
(
error
);
case
0
:
// converted NULL character, TRANSITION, VSO#654347
_Bytes
=
1
;
// [[fallthrough]];
default
:
// converted some other character
_Mid1
+=
_Bytes
; ++
_Mid2
;
break
; } } }
const
_Elem
*
_First1
,
const
_Elem
*
_Last1
,
const
_Elem
*&
_Mid1
,
_Byte
*
_First2
,
_Byte
*
_Last2
,
_Byte
*&
_Mid2
)
const
{
// convert [_First1, _Last1) to bytes [_First2, _Last)
_Adl_verify_range
(
_First1
,
_Last1
);
_Adl_verify_range
(
_First2
,
_Last2
);
_Mid1
=
_First1
;
_Mid2
=
_First2
;
int
_Bytes
;
while
(
_Mid1
!
=
_Last1
&&
_Mid2
!
=
_Last2
) { {
if
((
_Bytes
=
_Wcrtomb
(
_Mid2
, *
_Mid1
, &
_State
, &
_Cvt
))
<
0
) {
return
(
error
);
// locale-specific wcrtomb failed
}
else
{ ++
_Mid1
;
_Mid2
+=
_Bytes
; } }
else
{
// destination too small, convert into buffer
_Statype
_Stsave
=
_State
;
if
((
_Bytes
=
_Wcrtomb
(
_Buf
, *
_Mid1
, &
_State
, &
_Cvt
))
<
0
) {
return
(
error
);
// locale-specific wcrtomb failed
}
else
if
(
_Last2
-
_Mid2
<
_Bytes
) {
// converted too many, roll back and return previous
_State
=
_Stsave
;
break
; }
else
{
// copy converted bytes from buffer
++
_Mid1
;
_Mid2
+=
_Bytes
; } } }
return
(
_Mid1
=
=
_Last1
?
ok
:
partial
); }
_Byte
*
_First2
,
_Byte
*
_Last2
,
_Byte
*&
_Mid2
)
const
{
// generate bytes to return to default shift state
_Adl_verify_range
(
_First2
,
_Last2
);
_Mid2
=
_First2
;
result
_Ans
=
ok
;
int
_Bytes
;
_Statype
_Stsave
=
_State
;
if
((
_Bytes
=
_Wcrtomb
(
_Buf
,
L'\0'
, &
_State
, &
_Cvt
)) <=
0
)
_Ans
=
error
;
// locale-specific wcrtomb failed
else
if
(
_Last2
-
_Mid2
<
--
_Bytes
) {
// converted too many, roll back and return
_State
=
_Stsave
;
_Ans
=
partial
; }
else
if
(
0
<
_Bytes
) {
// copy converted bytes from buffer
_Mid2
+=
_Bytes
; }
return
(
_Ans
); }
const
_Byte
*
_Last1
,
size_t
_Count
)
const
{
// return min(_Count, converted length of bytes [_First1, _Last1))
_Adl_verify_range
(
_First1
,
_Last1
);
size_t
_Wchars
=
0
;
_Statype
_Mystate
{};
while
(
_Wchars
<
_Count
&&
_First1
!
=
_Last1
) {
_Elem
_Ch
;
int
_Bytes
=
_Mbrtowc
(&
_Ch
,
_First1
,
static_cast
<
size_t
>(
_Last1
-
_First1
), &
_Mystate
, &
_Cvt
);
if
(
_Bytes
<
0
) {
// partial or failed conversion
break
; }
if
(
_Bytes
=
=
0
) {
// converted NULL character, TRANSITION, VSO#654347
_Bytes
=
1
; }
// converted _Bytes bytes to a wchar_t:
_First1
+=
_Bytes
; ++
_Wchars
; } } {
// return true if conversions never change input
return
(
false
); } {
// return maximum length required for a conversion (from codecvt)
} {
// return length of code sequence (from codecvt)
return
(
0
);
// 0 => varying length
}
private
:
_Locinfo
::
_Cvtvec
_Cvt
;
// locale info passed to _Mbrtowc, _Wcrtomb
};
#ifdef _NATIVE_WCHAR_T_DEFINED
// CLASS codecvt<unsigned short, char, _Mbstatet>
template
<> :
public
codecvt_base
{
// facet for converting between unsigned short and char sequences
public
:
typedef
unsigned
short
_Elem
;
typedef
char
_Byte
;
typedef
_Mbstatet
_Statype
;
typedef
_Elem
intern_type
;
typedef
_Byte
extern_type
;
typedef
_Statype
state_type
;
const
_Byte
*
_First1
,
const
_Byte
*
_Last1
,
const
_Byte
*&
_Mid1
,
_Elem
*
_First2
,
_Elem
*
_Last2
,
_Elem
*&
_Mid2
)
const
{
// convert bytes [_First1, _Last1) to [_First2, _Last)
return
(
do_in
(
_State
,
_First1
,
_Last1
,
_Mid1
,
_First2
,
_Last2
,
_Mid2
)); }
const
_Elem
*
_First1
,
const
_Elem
*
_Last1
,
const
_Elem
*&
_Mid1
,
_Byte
*
_First2
,
_Byte
*
_Last2
,
_Byte
*&
_Mid2
)
const
{
// convert [_First1, _Last1) to bytes [_First2, _Last)
return
(
do_out
(
_State
,
_First1
,
_Last1
,
_Mid1
,
_First2
,
_Last2
,
_Mid2
)); }
_Byte
*
_First2
,
_Byte
*
_Last2
,
_Byte
*&
_Mid2
)
const
{
// generate bytes to return to default shift state
return
(
do_unshift
(
_State
,
_First2
,
_Last2
,
_Mid2
)); }
const
_Byte
*
_Last1
,
size_t
_Count
)
const
{
// return min(_Count, converted length of bytes [_First1, _Last1))
return
(
do_length
(
_State
,
_First1
,
_Last1
,
_Count
)); } :
codecvt_base
(
_Refs
) {
// construct from current locale
_Init
(
_Lobj
); } :
codecvt_base
(
_Refs
) {
// construct from specified locale
_Init
(
_Lobj
); }
const
locale
*
_Ploc
=
nullptr
) {
// return locale category mask and construct standard facet
if
(
_Ppf
!=
nullptr
&& *
_Ppf
==
nullptr
) *
_Ppf
=
new
codecvt
<
_Elem
,
_Byte
,
_Statype
>(
_Locinfo
(
_Ploc
->
c_str
())); }
protected
: {
// destroy the object
} {
// initialize from _Lobj
_Cvt
=
_Lobj
.
_Getcvt
(); }
const
_Byte
*
_First1
,
const
_Byte
*
_Last1
,
const
_Byte
*&
_Mid1
,
_Elem
*
_First2
,
_Elem
*
_Last2
,
_Elem
*&
_Mid2
)
const
{
// convert bytes [_First1, _Last1) to [_First2, _Last)
_Statype
_Mystate
{};
_Adl_verify_range
(
_First1
,
_Last1
);
_Adl_verify_range
(
_First2
,
_Last2
);
_Mid1
=
_First1
;
_Mid2
=
_First2
;
for
(;;) {
if
(
_Mid1
=
=
_Last1
) {
return
(
ok
); }
if
(
_Mid2
=
=
_Last2
) {
return
(
partial
); }
int
_Bytes
=
_Mbrtowc
(
reinterpret_cast
<
wchar_t
*>(
_Mid2
),
_Mid1
,
static_cast
<
size_t
>(
_Last1
-
_Mid1
), &
_Mystate
, &
_Cvt
);
switch
(
_Bytes
) {
case
-
2
:
// partial conversion
return
(
partial
);
case
-
1
:
// failed conversion
return
(
error
);
case
0
:
// converted NULL character, TRANSITION, VSO#654347
_Bytes
=
1
;
// [[fallthrough]];
default
:
// converted some other character
_Mid1
+=
_Bytes
; ++
_Mid2
;
break
; } } }
const
_Elem
*
_First1
,
const
_Elem
*
_Last1
,
const
_Elem
*&
_Mid1
,
_Byte
*
_First2
,
_Byte
*
_Last2
,
_Byte
*&
_Mid2
)
const
{
// convert [_First1, _Last1) to bytes [_First2, _Last)
_Adl_verify_range
(
_First1
,
_Last1
);
_Adl_verify_range
(
_First2
,
_Last2
);
_Mid1
=
_First1
;
_Mid2
=
_First2
;
int
_Bytes
;
while
(
_Mid1
!
=
_Last1
&&
_Mid2
!
=
_Last2
) { {
if
((
_Bytes
=
_Wcrtomb
(
_Mid2
, *
_Mid1
, &
_State
, &
_Cvt
))
<
0
) {
return
(
error
);
// locale-specific wcrtomb failed
}
else
{ ++
_Mid1
;
_Mid2
+=
_Bytes
; } }
else
{
// destination too small, convert into buffer
_Statype
_Stsave
=
_State
;
if
((
_Bytes
=
_Wcrtomb
(
_Buf
, *
_Mid1
, &
_State
, &
_Cvt
))
<
0
) {
return
(
error
);
// locale-specific wcrtomb failed
}
else
if
(
_Last2
-
_Mid2
<
_Bytes
) {
// converted too many, roll back and return previous
_State
=
_Stsave
;
break
; }
else
{
// copy converted bytes from buffer
++
_Mid1
;
_Mid2
+=
_Bytes
; } } }
return
(
_Mid1
=
=
_Last1
?
ok
:
partial
); }
_Byte
*
_First2
,
_Byte
*
_Last2
,
_Byte
*&
_Mid2
)
const
{
// generate bytes to return to default shift state
_Adl_verify_range
(
_First2
,
_Last2
);
_Mid2
=
_First2
;
result
_Ans
=
ok
;
int
_Bytes
;
_Statype
_Stsave
=
_State
;
if
((
_Bytes
=
_Wcrtomb
(
_Buf
,
L'\0'
, &
_State
, &
_Cvt
)) <=
0
) {
_Ans
=
error
;
// locale-specific wcrtomb failed
}
else
if
(
_Last2
-
_Mid2
<
--
_Bytes
) {
// converted too many, roll back and return
_State
=
_Stsave
;
_Ans
=
partial
; }
else
if
(
0
<
_Bytes
) {
// copy converted bytes from buffer
_Mid2
+=
_Bytes
; }
return
(
_Ans
); }
const
_Byte
*
_Last1
,
size_t
_Count
)
const
{
// return min(_Count, converted length of bytes [_First1, _Last1))
_Adl_verify_range
(
_First1
,
_Last1
);
size_t
_Wchars
=
0
;
_Statype
_Mystate
{};
while
(
_Wchars
<
_Count
&&
_First1
!
=
_Last1
) {
wchar_t
_Ch
;
int
_Bytes
=
_Mbrtowc
(&
_Ch
,
_First1
,
static_cast
<
size_t
>(
_Last1
-
_First1
), &
_Mystate
, &
_Cvt
);
if
(
_Bytes
<
0
) {
// partial or failed conversion
break
; }
if
(
_Bytes
=
=
0
) {
// converted NULL character, TRANSITION, VSO#654347
_Bytes
=
1
; }
// converted _Bytes bytes to a wchar_t:
_First1
+=
_Bytes
; ++
_Wchars
; } } {
// return true if conversions never change input
return
(
false
); } {
// return maximum length required for a conversion (from codecvt)
} {
// return length of code sequence (from codecvt)
return
(
0
);
// 0 => varying length
}
private
:
_Locinfo
::
_Cvtvec
_Cvt
;
// locale info passed to _Mbrtowc, _Wcrtomb
};
#endif /* _NATIVE_WCHAR_T_DEFINED */
// CLASS TEMPLATE codecvt_byname
template
<
class
_Elem
,
class
_Byte
,
class
_Statype
>
class
codecvt_byname
:
public
codecvt
<
_Elem
,
_Byte
,
_Statype
> {
// codecvt for named locale
public
: :
codecvt
<
_Elem
,
_Byte
,
_Statype
>(
_Locinfo
(
_Locname
),
_Refs
) {
// construct for named locale
} :
codecvt
<
_Elem
,
_Byte
,
_Statype
>(
_Locinfo
(
_Str
.
c_str
()),
_Refs
) {
// construct for named locale
}
protected
: {
// destroy the object
} };
// STRUCT ctype_base
:
public
locale
::
facet
{
// base for ctype
enum
{
// constants for character classifications
typedef
short
mask
;
// to match <ctype.h>
:
locale
::
facet
(
_Refs
) {
// default constructor
} {
// destroy the object
} };
// CLASS TEMPLATE ctype
template
<
class
_Elem
>
class
ctype
:
public
ctype_base
{
// facet for classifying elements, converting cases
public
:
typedef
_Elem
char_type
; {
// test if element fits any mask classifications
return
(
do_is
(
_Maskval
,
_Ch
)); }
mask
*
_Dest
)
const
{
// get mask sequence for elements in [_First, _Last)
return
(
do_is
(
_First
,
_Last
,
_Dest
)); }
const
_Elem
*
_Last
)
const
{
// find first in [_First, _Last) that fits mask classification
return
(
do_scan_is
(
_Maskval
,
_First
,
_Last
)); }
const
_Elem
*
_Last
)
const
{
// find first in [_First, _Last) not fitting mask classification
return
(
do_scan_not
(
_Maskval
,
_First
,
_Last
)); } {
// convert element to lower case
return
(
do_tolower
(
_Ch
)); } {
// convert [_First, _Last) in place to lower case
return
(
do_tolower
(
_First
,
_Last
)); } {
// convert element to upper case
return
(
do_toupper
(
_Ch
)); } {
// convert [_First, _Last) in place to upper case
return
(
do_toupper
(
_First
,
_Last
)); } {
// widen char
return
(
do_widen
(
_Byte
)); }
_Elem
*
_Dest
)
const
{
// widen chars in [_First, _Last)
return
(
do_widen
(
_First
,
_Last
,
_Dest
)); } {
// narrow element to char
return
(
do_narrow
(
_Ch
,
_Dflt
)); }
char
_Dflt
,
char
*
_Dest
)
const
{
// narrow elements in [_First, _Last) to chars
return
(
do_narrow
(
_First
,
_Last
,
_Dflt
,
_Dest
)); } :
ctype_base
(
_Refs
) {
// construct from current locale
_Init
(
_Lobj
); } :
ctype_base
(
_Refs
) {
// construct from specified locale
_Init
(
_Lobj
); }
const
locale
*
_Ploc
=
nullptr
) {
// return locale category mask and construct standard facet
if
(
_Ppf
!=
nullptr
&& *
_Ppf
==
nullptr
) *
_Ppf
=
new
ctype
<
_Elem
>(
_Locinfo
(
_Ploc
->
c_str
())); }
protected
: {
// destroy the object
if
(
_Ctype
.
_Delfl
) } {
// initialize from _Lobj
_Ctype
=
_Lobj
.
_Getctype
();
_Cvt
=
_Lobj
.
_Getcvt
(); } {
// test if element fits any mask classifications
return
((
_Ctype
.
_Table
[(
unsigned
char
)
narrow
(
_Ch
)] &
_Maskval
)
!
=
0
); }
mask
*
_Dest
)
const
{
// get mask sequence for elements in [_First, _Last)
_Adl_verify_range
(
_First
,
_Last
);
for
(;
_First
!
=
_Last
; ++
_First
, ++
_Dest
) { *
_Dest
=
_Ctype
.
_Table
[(
unsigned
char
)
narrow
(*
_First
)]; }
return
(
_First
); }
const
_Elem
*
_First
,
const
_Elem
*
_Last
)
const
{
// find first in [_First, _Last) that fits mask classification
_Adl_verify_range
(
_First
,
_Last
);
while
(
_First
!
=
_Last
&& !
is
(
_Maskval
, *
_First
)) { ++
_First
; }
return
(
_First
); }
const
_Elem
*
_First
,
const
_Elem
*
_Last
)
const
{
// find first in [_First, _Last) not fitting mask classification
_Adl_verify_range
(
_First
,
_Last
);
while
(
_First
!
=
_Last
&&
is
(
_Maskval
, *
_First
)) { ++
_First
; }
return
(
_First
); } {
// convert element to lower case
unsigned
char
_Byte
= (
unsigned
char
)
narrow
(
_Ch
,
'\0'
);
if
(
_Byte
=
=
'\0'
) {
return
(
_Ch
); }
return
(
widen
((
char
)
_Tolower
(
_Byte
, &
_Ctype
))); }
const
_Elem
*
_Last
)
const
{
// convert [_First, _Last) in place to lower case
_Adl_verify_range
((
const
_Elem
*)
_First
,
_Last
);
for
(;
_First
!
=
_Last
; ++
_First
) {
// convert *_First to lower case
unsigned
char
_Byte
= (
unsigned
char
)
narrow
(*
_First
,
'\0'
);
if
(
_Byte
!
=
'\0'
) { *
_First
= (
widen
((
char
)
_Tolower
(
_Byte
, &
_Ctype
))); } }
return
((
const
_Elem
*)
_First
); } {
// convert element to upper case
unsigned
char
_Byte
= (
unsigned
char
)
narrow
(
_Ch
,
'\0'
);
if
(
_Byte
=
=
'\0'
) {
return
(
_Ch
); }
return
(
widen
((
char
)
_Toupper
(
_Byte
, &
_Ctype
))); }
const
_Elem
*
_Last
)
const
{
// convert [_First, _Last) in place to upper case
_Adl_verify_range
((
const
_Elem
*)
_First
,
_Last
);
for
(;
_First
!
=
_Last
; ++
_First
) {
// convert *_First to upper case
unsigned
char
_Byte
= (
unsigned
char
)
narrow
(*
_First
,
'\0'
);
if
(
_Byte
!
=
'\0'
) { *
_First
= (
widen
((
char
)
_Toupper
(
_Byte
, &
_Ctype
))); } }
return
((
const
_Elem
*)
_First
); } {
// widen char
return
(
_Maklocchr
(
_Byte
,
static_cast
<
_Elem
*>(
nullptr
),
_Cvt
)); }
const
char
*
_Last
,
_Elem
*
_Dest
)
const
{
// widen chars in [_First, _Last)
_Adl_verify_range
(
_First
,
_Last
);
for
(;
_First
!
=
_Last
; ++
_First
, ++
_Dest
) { *
_Dest
=
_Maklocchr
(*
_First
,
static_cast
<
_Elem
*>(
nullptr
),
_Cvt
); }
return
(
_First
); } {
// narrow element to char
char
_Byte
;
if
(
_Ch
== (
_Elem
)
0
) {
return
(
'\0'
); }
if
((
_Byte
=
_Maklocbyte
(
_Ch
,
_Cvt
))
=
=
'\0'
) {
return
(
_Dflt
); }
return
(
_Byte
); } {
// narrow element to char
return
(
_Donarrow
(
_Ch
,
_Dflt
)); }
const
_Elem
*
_Last
,
char
_Dflt
,
char
*
_Dest
)
const
{
// narrow elements in [_First, _Last) to chars
_Adl_verify_range
(
_First
,
_Last
);
for
(;
_First
!
=
_Last
; ++
_First
, ++
_Dest
) { *
_Dest
=
_Donarrow
(*
_First
,
_Dflt
); }
return
(
_First
); }
private
:
_Locinfo
::
_Ctypevec
_Ctype
;
// locale info passed to _Tolower, etc.
_Locinfo
::
_Cvtvec
_Cvt
;
// conversion information
};
// STATIC ctype::id OBJECT
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdllimport-static-field-def"
#endif /* __clang__ */
template
<
class
_Elem
>
locale
::
id
ctype
<
_Elem
>::
id
;
#ifdef __clang__
#pragma clang diagnostic pop
#endif /* __clang__ */
// CLASS ctype<char>
template
<> :
public
ctype_base
{
// facet for classifying char elements, converting cases
public
:
typedef
char
_Elem
;
typedef
_Elem
char_type
; {
// test if element fits any mask classifications
return
((
_Ctype
.
_Table
[(
unsigned
char
)
_Ch
] &
_Maskval
)
!
=
0
); }
const
_Elem
*
_Last
,
mask
*
_Dest
)
const
{
// get mask sequence for elements in [_First, _Last)
_Adl_verify_range
(
_First
,
_Last
);
for
(;
_First
!
=
_Last
; ++
_First
, ++
_Dest
) *
_Dest
=
_Ctype
.
_Table
[(
unsigned
char
)*
_First
];
return
(
_First
); }
const
_Elem
*
_First
,
const
_Elem
*
_Last
)
const
{
// find first in [_First, _Last) that fits mask classification
_Adl_verify_range
(
_First
,
_Last
);
while
(
_First
!
=
_Last
&& !
is
(
_Maskval
, *
_First
)) { ++
_First
; }
return
(
_First
); }
const
_Elem
*
_First
,
const
_Elem
*
_Last
)
const
{
// find first in [_First, _Last) not fitting mask classification
_Adl_verify_range
(
_First
,
_Last
);
while
(
_First
!
=
_Last
&&
is
(
_Maskval
, *
_First
)) { ++
_First
; }
return
(
_First
); } {
// convert element to lower case
return
(
do_tolower
(
_Ch
)); } {
// convert [_First, _Last) in place to lower case
return
(
do_tolower
(
_First
,
_Last
)); } {
// convert element to upper case
return
(
do_toupper
(
_Ch
)); } {
// convert [_First, _Last) in place to upper case
return
(
do_toupper
(
_First
,
_Last
)); } {
// widen char
return
(
do_widen
(
_Byte
)); }
_Elem
*
_Dest
)
const
{
// widen chars in [_First, _Last)
return
(
do_widen
(
_First
,
_Last
,
_Dest
)); } {
// narrow element to char
return
(
do_narrow
(
_Ch
,
_Dflt
)); }
char
_Dflt
,
char
*
_Dest
)
const
{
// narrow elements in [_First, _Last) to chars
return
(
do_narrow
(
_First
,
_Last
,
_Dflt
,
_Dest
)); }
bool
_Deletetable
=
false
,
size_t
_Refs
=
0
) :
ctype_base
(
_Refs
) {
// construct with specified table and delete flag for table
_Init
(
_Lobj
);
_Tidy
();
// free existing table, as needed
if
(
_Table
!=
nullptr
) {
// replace existing char to mask table
_Ctype
.
_Table
=
_Table
;
_Ctype
.
_Delfl
=
_Deletetable
? -
1
:
0
; }
else
{
// use classic table
_Ctype
.
_Table
=
classic_table
();
_Ctype
.
_Delfl
=
0
; } } :
ctype_base
(
_Refs
) {
// construct from current locale
_Init
(
_Lobj
); }
const
locale
*
_Ploc
=
nullptr
) {
// return locale category mask and construct standard facet
if
(
_Ppf
!=
nullptr
&& *
_Ppf
==
nullptr
) *
_Ppf
=
new
ctype
<
_Elem
>(
_Locinfo
(
_Ploc
->
c_str
())); } {
// return address of char to mask table
return
(
_Ctype
.
_Table
); } {
// return address of char to mask table for "C" locale
}
protected
: {
// destroy the object
_Tidy
(); } {
// initialize from _Lobj
_Ctype
=
_Lobj
.
_Getctype
(); } {
// free any allocated storage
if
(
0
<
_Ctype
.
_Delfl
)
else
if
(
_Ctype
.
_Delfl
<
0
)
delete
[]
_Ctype
.
_Table
; } {
// convert element to lower case
return
((
_Elem
)
_Tolower
((
unsigned
char
)
_Ch
, &
_Ctype
)); }
const
_Elem
*
_Last
)
const
{
// convert [_First, _Last) in place to lower case
_Adl_verify_range
((
const
_Elem
*)
_First
,
_Last
);
for
(;
_First
!
=
_Last
; ++
_First
) { *
_First
= (
_Elem
)
_Tolower
((
unsigned
char
)*
_First
, &
_Ctype
); }
return
((
const
_Elem
*)
_First
); } {
// convert element to upper case
return
((
_Elem
)
_Toupper
((
unsigned
char
)
_Ch
, &
_Ctype
)); }
const
_Elem
*
_Last
)
const
{
// convert [_First, _Last) in place to upper case
_Adl_verify_range
((
const
_Elem
*)
_First
,
_Last
);
for
(;
_First
!
=
_Last
; ++
_First
) { *
_First
= (
_Elem
)
_Toupper
((
unsigned
char
)*
_First
, &
_Ctype
); }
return
((
const
_Elem
*)
_First
); } {
// widen char
return
(
_Byte
); }
const
char
*
_Last
,
_Elem
*
_Dest
)
const
{
// widen chars in [_First, _Last)
_Adl_verify_range
(
_First
,
_Last
);
return
(
_Last
); } {
// narrow char
return
(
_Ch
); }
const
_Elem
*
_Last
,
char
,
char
*
_Dest
)
const
{
// narrow elements in [_First, _Last) to chars
_Adl_verify_range
(
_First
,
_Last
);
return
(
_Last
); }
private
:
_Locinfo
::
_Ctypevec
_Ctype
;
// information
};
// CLASS ctype<wchar_t>
template
<> :
public
ctype_base
{
// facet for classifying wchar_t elements, converting cases
public
:
typedef
wchar_t
_Elem
;
typedef
_Elem
char_type
; {
// test if element fits any mask classifications
return
(
do_is
(
_Maskval
,
_Ch
)); }
mask
*
_Dest
)
const
{
// get mask sequence for elements in [_First, _Last)
return
(
do_is
(
_First
,
_Last
,
_Dest
)); }
const
_Elem
*
_Last
)
const
{
// find first in [_First, _Last) that fits mask classification
return
(
do_scan_is
(
_Maskval
,
_First
,
_Last
)); }
const
_Elem
*
_Last
)
const
{
// find first in [_First, _Last) not fitting mask classification
return
(
do_scan_not
(
_Maskval
,
_First
,
_Last
)); } {
// convert element to lower case
return
(
do_tolower
(
_Ch
)); } {
// convert [_First, _Last) in place to lower case
return
(
do_tolower
(
_First
,
_Last
)); } {
// convert element to upper case
return
(
do_toupper
(
_Ch
)); } {
// convert [_First, _Last) in place to upper case
return
(
do_toupper
(
_First
,
_Last
)); } {
// widen char
return
(
do_widen
(
_Byte
)); }
_Elem
*
_Dest
)
const
{
// widen chars in [_First, _Last)
return
(
do_widen
(
_First
,
_Last
,
_Dest
)); } {
// narrow element to char
return
(
do_narrow
(
_Ch
,
_Dflt
)); }
char
_Dflt
,
char
*
_Dest
)
const
{
// narrow elements in [_First, _Last) to chars
return
(
do_narrow
(
_First
,
_Last
,
_Dflt
,
_Dest
)); } :
ctype_base
(
_Refs
) {
// construct from current locale
_Init
(
_Lobj
); } :
ctype_base
(
_Refs
) {
// construct from specified locale
_Init
(
_Lobj
); }
const
locale
*
_Ploc
=
nullptr
) {
// return locale category mask and construct standard facet
if
(
_Ppf
!=
nullptr
&& *
_Ppf
==
nullptr
) { *
_Ppf
=
new
ctype
<
_Elem
>(
_Locinfo
(
_Ploc
->
c_str
())); } }
protected
: {
// destroy the object
if
(
_Ctype
.
_Delfl
) } {
// initialize from _Lobj
_Ctype
=
_Lobj
.
_Getctype
();
_Cvt
=
_Lobj
.
_Getcvt
(); } {
// test if element fits any mask classifications
}
const
_Elem
*
_Last
,
mask
*
_Dest
)
const
{
// get mask sequence for elements in [_First, _Last)
_Adl_verify_range
(
_First
,
_Last
); }
const
_Elem
*
_First
,
const
_Elem
*
_Last
)
const
{
// find first in [_First, _Last) that fits mask classification
_Adl_verify_range
(
_First
,
_Last
);
while
(
_First
!
=
_Last
&& !
is
(
_Maskval
, *
_First
)) { ++
_First
; }
return
(
_First
); }
const
_Elem
*
_First
,
const
_Elem
*
_Last
)
const
{
// find first in [_First, _Last) not fitting mask classification
_Adl_verify_range
(
_First
,
_Last
);
while
(
_First
!
=
_Last
&&
is
(
_Maskval
, *
_First
)) { ++
_First
; }
return
(
_First
); } {
// convert element to lower case
return
(
_Towlower
(
_Ch
, &
_Ctype
)); }
const
_Elem
*
_Last
)
const
{
// convert [_First, _Last) in place to lower case
_Adl_verify_range
((
const
_Elem
*)
_First
,
_Last
);
for
(;
_First
!
=
_Last
; ++
_First
) { *
_First
=
_Towlower
(*
_First
, &
_Ctype
); }
return
((
const
_Elem
*)
_First
); } {
// convert element to upper case
return
(
_Towupper
(
_Ch
, &
_Ctype
)); }
const
_Elem
*
_Last
)
const
{
// convert [_First, _Last) in place to upper case
_Adl_verify_range
((
const
_Elem
*)
_First
,
_Last
);
for
(;
_First
!
=
_Last
; ++
_First
) { *
_First
=
_Towupper
(*
_First
, &
_Ctype
); }
return
((
const
_Elem
*)
_First
); } {
// widen char
mbstate_t
_Mbst
= {};
wchar_t
_Wc
;
return
(
_Mbrtowc
(&
_Wc
, &
_Byte
,
1
, &
_Mbst
, &
_Cvt
)
<
0
} {
// widen char
return
(
_Dowiden
(
_Byte
)); }
const
char
*
_Last
,
_Elem
*
_Dest
)
const
{
// widen chars in [_First, _Last)
_Adl_verify_range
(
_First
,
_Last
);
for
(;
_First
!
=
_Last
; ++
_First
, ++
_Dest
) { *
_Dest
=
_Dowiden
(*
_First
); }
return
(
_First
); } {
// narrow element to char
mbstate_t
_Mbst
= {};
return
(
_Wcrtomb
(
_Buf
,
_Ch
, &
_Mbst
, &
_Cvt
)
!
=
1
?
_Dflt
:
_Buf
[
0
]); } {
// narrow element to char
return
(
_Donarrow
(
_Ch
,
_Dflt
)); }
const
_Elem
*
_Last
,
char
_Dflt
,
char
*
_Dest
)
const
{
// narrow elements in [_First, _Last) to chars
_Adl_verify_range
(
_First
,
_Last
);
for
(;
_First
!
=
_Last
; ++
_First
, ++
_Dest
) { *
_Dest
=
_Donarrow
(*
_First
,
_Dflt
); }
return
(
_First
); }
private
:
_Locinfo
::
_Ctypevec
_Ctype
;
// locale info passed to _Tolower, etc.
_Locinfo
::
_Cvtvec
_Cvt
;
// conversion information
};
#ifdef _NATIVE_WCHAR_T_DEFINED
// CLASS ctype<unsigned short>
template
<> :
public
ctype_base
{
// facet for classifying unsigned short elements, converting cases
public
:
typedef
unsigned
short
_Elem
;
typedef
_Elem
char_type
; {
// test if element fits any mask classifications
return
(
do_is
(
_Maskval
,
_Ch
)); }
mask
*
_Dest
)
const
{
// get mask sequence for elements in [_First, _Last)
return
(
do_is
(
_First
,
_Last
,
_Dest
)); }
const
_Elem
*
_Last
)
const
{
// find first in [_First, _Last) that fits mask classification
return
(
do_scan_is
(
_Maskval
,
_First
,
_Last
)); }
const
_Elem
*
_Last
)
const
{
// find first in [_First, _Last) not fitting mask classification
return
(
do_scan_not
(
_Maskval
,
_First
,
_Last
)); } {
// convert element to lower case
return
(
do_tolower
(
_Ch
)); } {
// convert [_First, _Last) in place to lower case
return
(
do_tolower
(
_First
,
_Last
)); } {
// convert element to upper case
return
(
do_toupper
(
_Ch
)); } {
// convert [_First, _Last) in place to upper case
return
(
do_toupper
(
_First
,
_Last
)); } {
// widen char
return
(
do_widen
(
_Byte
)); }
_Elem
*
_Dest
)
const
{
// widen chars in [_First, _Last)
return
(
do_widen
(
_First
,
_Last
,
_Dest
)); } {
// narrow element to char
return
(
do_narrow
(
_Ch
,
_Dflt
)); }
char
_Dflt
,
char
*
_Dest
)
const
{
// narrow elements in [_First, _Last) to chars
return
(
do_narrow
(
_First
,
_Last
,
_Dflt
,
_Dest
)); } :
ctype_base
(
_Refs
) {
// construct from current locale
_Init
(
_Lobj
); } :
ctype_base
(
_Refs
) {
// construct from specified locale
_Init
(
_Lobj
); }
const
locale
*
_Ploc
=
nullptr
) {
// return locale category mask and construct standard facet
if
(
_Ppf
!=
nullptr
&& *
_Ppf
==
nullptr
) { *
_Ppf
=
new
ctype
<
_Elem
>(
_Locinfo
(
_Ploc
->
c_str
())); } }
protected
: {
// destroy the object
if
(
_Ctype
.
_Delfl
) } {
// initialize from _Lobj
_Ctype
=
_Lobj
.
_Getctype
();
_Cvt
=
_Lobj
.
_Getcvt
(); } {
// test if element fits any mask classifications
}
const
_Elem
*
_Last
,
mask
*
_Dest
)
const
{
// get mask sequence for elements in [_First, _Last)
_Adl_verify_range
(
_First
,
_Last
); (
const
wchar_t
*)
_Last
,
_Dest
, &
_Ctype
)); }
const
_Elem
*
_First
,
const
_Elem
*
_Last
)
const
{
// find first in [_First, _Last) that fits mask classification
_Adl_verify_range
(
_First
,
_Last
);
while
(
_First
!
=
_Last
&& !
is
(
_Maskval
, *
_First
)) { ++
_First
; }
return
(
_First
); }
const
_Elem
*
_First
,
const
_Elem
*
_Last
)
const
{
// find first in [_First, _Last) not fitting mask classification
_Adl_verify_range
(
_First
,
_Last
);
while
(
_First
!
=
_Last
&&
is
(
_Maskval
, *
_First
)) { ++
_First
; }
return
(
_First
); } {
// convert element to lower case
return
(
_Towlower
(
_Ch
, &
_Ctype
)); }
const
_Elem
*
_Last
)
const
{
// convert [_First, _Last) in place to lower case
_Adl_verify_range
((
const
_Elem
*)
_First
,
_Last
);
for
(;
_First
!
=
_Last
; ++
_First
) { *
_First
=
_Towlower
(*
_First
, &
_Ctype
); }
return
((
const
_Elem
*)
_First
); } {
// convert element to upper case
return
(
_Towupper
(
_Ch
, &
_Ctype
)); }
const
_Elem
*
_Last
)
const
{
// convert [_First, _Last) in place to upper case
_Adl_verify_range
((
const
_Elem
*)
_First
,
_Last
);
for
(;
_First
!
=
_Last
; ++
_First
) { *
_First
=
_Towupper
(*
_First
, &
_Ctype
); }
return
((
const
_Elem
*)
_First
); } {
// widen char
mbstate_t
_Mbst
= {};
unsigned
short
_Wc
;
return
(
_Mbrtowc
((
wchar_t
*)&
_Wc
, &
_Byte
,
1
, &
_Mbst
, &
_Cvt
)
<
0
} {
// widen char
return
(
_Dowiden
(
_Byte
)); }
const
char
*
_Last
,
_Elem
*
_Dest
)
const
{
// widen chars in [_First, _Last)
_Adl_verify_range
(
_First
,
_Last
);
for
(;
_First
!
=
_Last
; ++
_First
, ++
_Dest
) { *
_Dest
=
_Dowiden
(*
_First
); }
return
(
_First
); } {
// narrow element to char
mbstate_t
_Mbst
= {};
return
(
_Wcrtomb
(
_Buf
,
_Ch
, &
_Mbst
, &
_Cvt
)
!
=
1
?
_Dflt
:
_Buf
[
0
]); } {
// narrow element to char
return
(
_Donarrow
(
_Ch
,
_Dflt
)); }
const
_Elem
*
_Last
,
char
_Dflt
,
char
*
_Dest
)
const
{
// narrow elements in [_First, _Last) to chars
_Adl_verify_range
(
_First
,
_Last
);
for
(;
_First
!
=
_Last
; ++
_First
, ++
_Dest
) { *
_Dest
=
_Donarrow
(*
_First
,
_Dflt
); }
return
(
_First
); }
private
:
_Locinfo
::
_Ctypevec
_Ctype
;
// locale info passed to _Tolower, etc.
_Locinfo
::
_Cvtvec
_Cvt
;
// conversion information
};
#endif /* _NATIVE_WCHAR_T_DEFINED */
// CLASS TEMPLATE ctype_byname
template
<
class
_Elem
>
class
ctype_byname
:
public
ctype
<
_Elem
> {
// ctype for named locale
public
: :
ctype
<
_Elem
>(
_Locinfo
(
_Locname
),
_Refs
) {
// construct for named locale
} :
ctype
<
_Elem
>(
_Locinfo
(
_Str
.
c_str
()),
_Refs
) {
// construct for named locale
}
protected
: {
// destroy the object
} };
// CLASS TEMPLATE ctype_byname<char>
template
<>
class
ctype_byname
<
char
> :
public
ctype
<
char
> {
// ctype_byname<char> for named locale
public
: :
ctype
<
char
>(
_Locinfo
(
_Locname
),
_Refs
) {
// construct for named locale
} :
ctype
<
char
>(
_Locinfo
(
_Str
.
c_str
()),
_Refs
) {
// construct for named locale
}
protected
: {
// destroy the object
} };
#if defined(_DLL_CPPLIB)
#if !defined(_CRTBLD) || defined(__FORCE_INSTANCE)
#pragma pop_macro("new")
_STL_RESTORE_CLANG_WARNINGS
/* * Copyright (c) by P.J. Plauger. All rights reserved. * Consult your license regarding permissions and restrictions. V6.50:0009 */