File Index Symbol Index

// string standard header
#pragma once
#ifndef _STRING_
#define _STRING_
#ifndef RC_INVOKED #include <istream> #include <xstring_insert.h>
#if _HAS_CXX17
#include <xpolymorphic_allocator.h> #endif /* _HAS_CXX17 */
_STL_DISABLE_CLANG_WARNINGS
#pragma push_macro("new")
#undef new
// basic_string INSERTERS AND EXTRACTORS
template
<
class
_Elem
,
class
_Traits
,
class
_Alloc
>
inline
basic_istream
<
_Elem
,
_Traits
>&
operator
>
>
(
basic_istream
<
_Elem
,
_Traits
>&&
_Istr
,
basic_string
<
_Elem
,
_Traits
,
_Alloc
>&
_Str
) {
// extract a string
typedef
ctype
<
_Elem
>
_Ctype
;
typedef
basic_istream
<
_Elem
,
_Traits
>
_Myis
;
typedef
basic_string
<
_Elem
,
_Traits
,
_Alloc
>
_Mystr
;
typedef
typename
_Mystr
::
size_type
_Mysizt
;
ios_base
::
iostate
_State
=
ios_base
::
goodbit
;
bool
_Changed
=
false
;
const
typename
_Myis
::
sentry
_Ok
(
_Istr
);
if
(
_Ok
) {
// state okay, extract characters
_Str
.
erase
();
_Mysizt
_Size
=
0
<
_Istr
.
width
() && (
_Mysizt
)
_Istr
.
width
() <
_Str
.
max_size
() ? (
_Mysizt
)
_Istr
.
width
() :
_Str
.
max_size
();
typename
_Traits
::int_type
_Meta
=
_Istr
.
rdbuf
()->sgetc();
for
(;
0
<
_Size
; --
_Size
,
_Meta
=
_Istr
.
rdbuf
()->snextc())
if
(
_Traits
::eq_int_type(
_Traits
::eof(),
_Meta
)) {
// end of file, quit
_State
|=
ios_base
::
eofbit
;
break
; }
else
if
(
_Ctype_fac
.
is
(
_Ctype
::
space
,
_Traits
::to_char_type(
_Meta
)))
break
;
// whitespace, quit
else
{
// add character to string
_Str
.
push_back
(
_Traits
::to_char_type(
_Meta
));
_Changed
=
true
; } }
_Istr
.
width
(
0
);
if
(!
_Changed
)
_State
|=
ios_base
::
failbit
;
_Istr
.
setstate
(
_State
);
return
(
_Istr
); }
template
<
class
_Elem
,
class
_Traits
,
class
_Alloc
>
inline
basic_istream
<
_Elem
,
_Traits
>&
getline
(
basic_istream
<
_Elem
,
_Traits
>&&
_Istr
,
basic_string
<
_Elem
,
_Traits
,
_Alloc
>&
_Str
,
const
_Elem
_Delim
) {
// get characters into string, discard delimiter
typedef
basic_istream
<
_Elem
,
_Traits
>
_Myis
;
ios_base
::
iostate
_State
=
ios_base
::
goodbit
;
bool
_Changed
=
false
;
const
typename
_Myis
::
sentry
_Ok
(
_Istr
,
true
);
if
(
_Ok
) {
// state okay, extract characters
_Str
.
erase
();
const
typename
_Traits
::int_type
_Metadelim
=
_Traits
::to_int_type(
_Delim
);
typename
_Traits
::int_type
_Meta
=
_Istr
.
rdbuf
()->sgetc();
for
(; ;
_Meta
=
_Istr
.
rdbuf
()->snextc())
if
(
_Traits
::eq_int_type(
_Traits
::eof(),
_Meta
)) {
// end of file, quit
_State
|=
ios_base
::
eofbit
;
break
; }
else
if
(
_Traits
::eq_int_type(
_Meta
,
_Metadelim
)) {
// got a delimiter, discard it and quit
_Changed
=
true
;
_Istr
.
rdbuf
()->sbumpc();
break
; }
else
if
(
_Str
.
max_size
() <=
_Str
.
size
()) {
// string too large, quit
_State
|=
ios_base
::
failbit
;
break
; }
else
{
// got a character, add it to string
_Str
+=
_Traits
::to_char_type(
_Meta
);
_Changed
=
true
; } }
if
(!
_Changed
)
_State
|=
ios_base
::
failbit
;
_Istr
.
setstate
(
_State
);
return
(
_Istr
); }
template
<
class
_Elem
,
class
_Traits
,
class
_Alloc
>
inline
basic_istream
<
_Elem
,
_Traits
>&
getline
(
basic_istream
<
_Elem
,
_Traits
>&&
_Istr
,
basic_string
<
_Elem
,
_Traits
,
_Alloc
>&
_Str
) {
// get characters into string, discard newline
return
(
getline
(
_Istr
,
_Str
,
_Istr
.
widen
(
'\n'
))); }
template
<
class
_Elem
,
class
_Traits
,
class
_Alloc
>
inline
basic_istream
<
_Elem
,
_Traits
>&
operator
>
>
(
basic_istream
<
_Elem
,
_Traits
>&
_Istr
,
basic_string
<
_Elem
,
_Traits
,
_Alloc
>&
_Str
) {
// extract a string
}
template
<
class
_Elem
,
class
_Traits
,
class
_Alloc
>
inline
basic_istream
<
_Elem
,
_Traits
>&
getline
(
basic_istream
<
_Elem
,
_Traits
>&
_Istr
,
basic_string
<
_Elem
,
_Traits
,
_Alloc
>&
_Str
,
const
_Elem
_Delim
) {
// get characters into string, discard delimiter
}
template
<
class
_Elem
,
class
_Traits
,
class
_Alloc
>
inline
basic_istream
<
_Elem
,
_Traits
>&
getline
(
basic_istream
<
_Elem
,
_Traits
>&
_Istr
,
basic_string
<
_Elem
,
_Traits
,
_Alloc
>&
_Str
) {
// get characters into string, discard newline
}
template
<
class
_Elem
,
class
_Traits
,
class
_Alloc
>
inline
basic_ostream
<
_Elem
,
_Traits
>&
operator
<
<
(
basic_ostream
<
_Elem
,
_Traits
>&
_Ostr
,
const
basic_string
<
_Elem
,
_Traits
,
_Alloc
>&
_Str
) {
// insert a string
return
(
_Insert_string
(
_Ostr
,
_Str
.
data
(),
_Str
.
size
())); }
// sto* NARROW CONVERSIONS
inline
int
stoi
(
const
string
&
_Str
,
size_t
*
_Idx
=
nullptr
,
int
_Base
=
10
) {
// convert string to int
const
char
*
_Ptr
=
_Str
.
c_str
();
char
*
_Eptr
;
_Errno_ref
=
0
;
if
(
_Ptr
=
=
_Eptr
)
_Xinvalid_argument
(
"invalid stoi argument"
);
_Xout_of_range
(
"stoi argument out of range"
);
if
(
_Idx
!=
nullptr
) *
_Idx
= (
size_t
)(
_Eptr
-
_Ptr
);
return
((
int
)
_Ans
); }
inline
long
stol
(
const
string
&
_Str
,
size_t
*
_Idx
=
nullptr
,
int
_Base
=
10
) {
// convert string to long
const
char
*
_Ptr
=
_Str
.
c_str
();
char
*
_Eptr
;
_Errno_ref
=
0
;
if
(
_Ptr
=
=
_Eptr
)
_Xinvalid_argument
(
"invalid stol argument"
);
_Xout_of_range
(
"stol argument out of range"
);
if
(
_Idx
!=
nullptr
) *
_Idx
= (
size_t
)(
_Eptr
-
_Ptr
);
return
(
_Ans
); }
inline
unsigned
long
stoul
(
const
string
&
_Str
,
size_t
*
_Idx
=
nullptr
,
int
_Base
=
10
) {
// convert string to unsigned long
const
char
*
_Ptr
=
_Str
.
c_str
();
char
*
_Eptr
;
_Errno_ref
=
0
;
if
(
_Ptr
=
=
_Eptr
)
_Xinvalid_argument
(
"invalid stoul argument"
);
_Xout_of_range
(
"stoul argument out of range"
);
if
(
_Idx
!=
nullptr
) *
_Idx
= (
size_t
)(
_Eptr
-
_Ptr
);
return
(
_Ans
); }
inline
long
long
stoll
(
const
string
&
_Str
,
size_t
*
_Idx
=
nullptr
,
int
_Base
=
10
) {
// convert string to long long
const
char
*
_Ptr
=
_Str
.
c_str
();
char
*
_Eptr
;
_Errno_ref
=
0
;
if
(
_Ptr
=
=
_Eptr
)
_Xinvalid_argument
(
"invalid stoll argument"
);
_Xout_of_range
(
"stoll argument out of range"
);
if
(
_Idx
!=
nullptr
) *
_Idx
= (
size_t
)(
_Eptr
-
_Ptr
);
return
(
_Ans
); }
inline
unsigned
long
long
stoull
(
const
string
&
_Str
,
size_t
*
_Idx
=
nullptr
,
int
_Base
=
10
) {
// convert string to unsigned long long
const
char
*
_Ptr
=
_Str
.
c_str
();
char
*
_Eptr
;
_Errno_ref
=
0
;
if
(
_Ptr
=
=
_Eptr
)
_Xinvalid_argument
(
"invalid stoull argument"
);
_Xout_of_range
(
"stoull argument out of range"
);
if
(
_Idx
!=
nullptr
) *
_Idx
= (
size_t
)(
_Eptr
-
_Ptr
);
return
(
_Ans
); }
inline
float
stof
(
const
string
&
_Str
,
size_t
*
_Idx
=
nullptr
) {
// convert string to float
const
char
*
_Ptr
=
_Str
.
c_str
();
char
*
_Eptr
;
_Errno_ref
=
0
;
if
(
_Ptr
=
=
_Eptr
)
_Xinvalid_argument
(
"invalid stof argument"
);
_Xout_of_range
(
"stof argument out of range"
);
if
(
_Idx
!=
nullptr
) *
_Idx
= (
size_t
)(
_Eptr
-
_Ptr
);
return
(
_Ans
); }
inline
double
stod
(
const
string
&
_Str
,
size_t
*
_Idx
=
nullptr
) {
// convert string to double
const
char
*
_Ptr
=
_Str
.
c_str
();
char
*
_Eptr
;
_Errno_ref
=
0
;
if
(
_Ptr
=
=
_Eptr
)
_Xinvalid_argument
(
"invalid stod argument"
);
_Xout_of_range
(
"stod argument out of range"
);
if
(
_Idx
!=
nullptr
) *
_Idx
= (
size_t
)(
_Eptr
-
_Ptr
);
return
(
_Ans
); }
inline
long
double
stold
(
const
string
&
_Str
,
size_t
*
_Idx
=
nullptr
) {
// convert string to long double
const
char
*
_Ptr
=
_Str
.
c_str
();
char
*
_Eptr
;
_Errno_ref
=
0
;
if
(
_Ptr
=
=
_Eptr
)
_Xinvalid_argument
(
"invalid stold argument"
);
_Xout_of_range
(
"stold argument out of range"
);
if
(
_Idx
!=
nullptr
) *
_Idx
= (
size_t
)(
_Eptr
-
_Ptr
);
return
(
_Ans
); }
// sto* WIDE CONVERSIONS
inline
int
stoi
(
const
wstring
&
_Str
,
size_t
*
_Idx
=
nullptr
,
int
_Base
=
10
) {
// convert wstring to int
const
wchar_t
*
_Ptr
=
_Str
.
c_str
();
wchar_t
*
_Eptr
;
_Errno_ref
=
0
;
if
(
_Ptr
=
=
_Eptr
)
_Xinvalid_argument
(
"invalid stoi argument"
);
_Xout_of_range
(
"stoi argument out of range"
);
if
(
_Idx
!=
nullptr
) *
_Idx
= (
size_t
)(
_Eptr
-
_Ptr
);
return
((
int
)
_Ans
); }
inline
long
stol
(
const
wstring
&
_Str
,
size_t
*
_Idx
=
nullptr
,
int
_Base
=
10
) {
// convert wstring to long
const
wchar_t
*
_Ptr
=
_Str
.
c_str
();
wchar_t
*
_Eptr
;
_Errno_ref
=
0
;
if
(
_Ptr
=
=
_Eptr
)
_Xinvalid_argument
(
"invalid stol argument"
);
_Xout_of_range
(
"stol argument out of range"
);
if
(
_Idx
!=
nullptr
) *
_Idx
= (
size_t
)(
_Eptr
-
_Ptr
);
return
(
_Ans
); }
inline
unsigned
long
stoul
(
const
wstring
&
_Str
,
size_t
*
_Idx
=
nullptr
,
int
_Base
=
10
) {
// convert wstring to unsigned long
const
wchar_t
*
_Ptr
=
_Str
.
c_str
();
wchar_t
*
_Eptr
;
_Errno_ref
=
0
;
if
(
_Ptr
=
=
_Eptr
)
_Xinvalid_argument
(
"invalid stoul argument"
);
_Xout_of_range
(
"stoul argument out of range"
);
if
(
_Idx
!=
nullptr
) *
_Idx
= (
size_t
)(
_Eptr
-
_Ptr
);
return
(
_Ans
); }
inline
long
long
stoll
(
const
wstring
&
_Str
,
size_t
*
_Idx
=
nullptr
,
int
_Base
=
10
) {
// convert wstring to long long
const
wchar_t
*
_Ptr
=
_Str
.
c_str
();
wchar_t
*
_Eptr
;
_Errno_ref
=
0
;
if
(
_Ptr
=
=
_Eptr
)
_Xinvalid_argument
(
"invalid stoll argument"
);
_Xout_of_range
(
"stoll argument out of range"
);
if
(
_Idx
!=
nullptr
) *
_Idx
= (
size_t
)(
_Eptr
-
_Ptr
);
return
(
_Ans
); }
inline
unsigned
long
long
stoull
(
const
wstring
&
_Str
,
size_t
*
_Idx
=
nullptr
,
int
_Base
=
10
) {
// convert wstring to unsigned long long
const
wchar_t
*
_Ptr
=
_Str
.
c_str
();
wchar_t
*
_Eptr
;
_Errno_ref
=
0
;
if
(
_Ptr
=
=
_Eptr
)
_Xinvalid_argument
(
"invalid stoull argument"
);
_Xout_of_range
(
"stoull argument out of range"
);
if
(
_Idx
!=
nullptr
) *
_Idx
= (
size_t
)(
_Eptr
-
_Ptr
);
return
(
_Ans
); }
inline
float
stof
(
const
wstring
&
_Str
,
size_t
*
_Idx
=
nullptr
) {
// convert wstring to float
const
wchar_t
*
_Ptr
=
_Str
.
c_str
();
wchar_t
*
_Eptr
;
_Errno_ref
=
0
;
if
(
_Ptr
=
=
_Eptr
)
_Xinvalid_argument
(
"invalid stof argument"
);
_Xout_of_range
(
"stof argument out of range"
);
if
(
_Idx
!=
nullptr
) *
_Idx
= (
size_t
)(
_Eptr
-
_Ptr
);
return
(
_Ans
); }
inline
double
stod
(
const
wstring
&
_Str
,
size_t
*
_Idx
=
nullptr
) {
// convert wstring to double
const
wchar_t
*
_Ptr
=
_Str
.
c_str
();
wchar_t
*
_Eptr
;
_Errno_ref
=
0
;
if
(
_Ptr
=
=
_Eptr
)
_Xinvalid_argument
(
"invalid stod argument"
);
_Xout_of_range
(
"stod argument out of range"
);
if
(
_Idx
!=
nullptr
) *
_Idx
= (
size_t
)(
_Eptr
-
_Ptr
);
return
(
_Ans
); }
inline
long
double
stold
(
const
wstring
&
_Str
,
size_t
*
_Idx
=
nullptr
) {
// convert wstring to long double
const
wchar_t
*
_Ptr
=
_Str
.
c_str
();
wchar_t
*
_Eptr
;
_Errno_ref
=
0
;
if
(
_Ptr
=
=
_Eptr
)
_Xinvalid_argument
(
"invalid stold argument"
);
_Xout_of_range
(
"stold argument out of range"
);
if
(
_Idx
!=
nullptr
) *
_Idx
= (
size_t
)(
_Eptr
-
_Ptr
);
return
(
_Ans
); }
// HELPERS FOR to_string AND to_wstring
template
<
class
_Elem
,
class
_UTy
>
inline
_Elem
*
_UIntegral_to_buff
(
_Elem
*
_RNext
,
_UTy
_UVal
) {
// format _UVal into buffer *ending at* _RNext
static_assert
(
is_unsigned_v
<
_UTy
>,
"_UTy must be unsigned"
);
#ifdef _WIN64
auto _UVal_trunc = _UVal;
#else /* ^^^ _WIN64 ^^^ // vvv !_WIN64 vvv */
#pragma warning(push)
if
(
sizeof
(
_UTy
) >
4
) {
// For 64-bit numbers, work in chunks to avoid 64-bit divisions.
while
(
_UVal
>
0xFFFFFFFFU
) {
auto
_UVal_chunk
=
static_cast
<
unsigned
long
>(
_UVal
%
1000000000
);
_UVal
/=
1000000000
;
for
(
int
_Idx
=
0
;
_Idx
!
=
9
; ++
_Idx
) { *--
_RNext
=
static_cast
<
_Elem
>(
'0'
+
_UVal_chunk
%
10
);
_UVal_chunk
/=
10
; } } } #pragma warning(pop)
auto
_UVal_trunc
=
static_cast
<
unsigned
long
>(
_UVal
);
#endif /* _WIN64 */
do
{ *--
_RNext
=
static_cast
<
_Elem
>(
'0'
+
_UVal_trunc
%
10
);
_UVal_trunc
/=
10
; }
while
(
_UVal_trunc
!
=
0
);
return
(
_RNext
); }
template
<
class
_Elem
,
class
_Ty
>
inline
basic_string
<
_Elem
>
_Integral_to_string
(
const
_Ty
_Val
) {
// convert _Val to string
static_assert
(
is_integral_v
<
_Ty
>,
"_Ty must be integral"
);
using
_UTy
=
make_unsigned_t
<
_Ty
>;
_Elem
_Buff
[
21
];
// can hold -2^63 and 2^64 - 1, plus NUL
_Elem
*
_RNext
=
_Buff_end
;
const
auto
_UVal
=
static_cast
<
_UTy
>(
_Val
);
if
(
_Val
<
0
) {
_RNext
=
_UIntegral_to_buff
(
_RNext
,
0
-
_UVal
); *--
_RNext
=
'-'
; }
else
_RNext
=
_UIntegral_to_buff
(
_RNext
,
_UVal
);
return
(
basic_string
<
_Elem
>(
_RNext
,
_Buff_end
)); }
template
<
class
_Ty
>
inline
string
_Floating_to_string
(
const
char
*
_Fmt
,
_Ty
_Val
) {
// convert _Val to string
static_assert
(
is_floating_point_v
<
_Ty
>,
"_Ty must be floating point"
);
string
_Str
(
_Len
,
'\0'
);
return
(
_Str
); }
template
<
class
_Ty
>
inline
wstring
_Floating_to_wstring
(
const
wchar_t
*
_Fmt
,
_Ty
_Val
) {
// convert _Val to wstring
static_assert
(
is_floating_point_v
<
_Ty
>,
"_Ty must be floating point"
);
wstring
_Str
(
_Len
,
L'\0'
);
return
(
_Str
); }
#undef _TO_STRING_BUF_SIZE
// to_string NARROW CONVERSIONS
{
// convert int to string
return
(
_Integral_to_string
<
char
>(
_Val
)); } {
// convert unsigned int to string
return
(
_Integral_to_string
<
char
>(
_Val
)); } {
// convert long to string
return
(
_Integral_to_string
<
char
>(
_Val
)); } {
// convert unsigned long to string
return
(
_Integral_to_string
<
char
>(
_Val
)); } {
// convert long long to string
return
(
_Integral_to_string
<
char
>(
_Val
)); } {
// convert unsigned long long to string
return
(
_Integral_to_string
<
char
>(
_Val
)); } {
// convert float to string
return
(
_Floating_to_string
(
"%f"
,
_Val
)); } {
// convert double to string
return
(
_Floating_to_string
(
"%f"
,
_Val
)); } {
// convert long double to string
return
(
_Floating_to_string
(
"%Lf"
,
_Val
)); }
// to_wstring WIDE CONVERSIONS
{
// convert int to wstring
return
(
_Integral_to_string
<
wchar_t
>(
_Val
)); } {
// convert unsigned int to wstring
return
(
_Integral_to_string
<
wchar_t
>(
_Val
)); } {
// convert long to wstring
return
(
_Integral_to_string
<
wchar_t
>(
_Val
)); } {
// convert unsigned long to wstring
return
(
_Integral_to_string
<
wchar_t
>(
_Val
)); } {
// convert long long to wstring
return
(
_Integral_to_string
<
wchar_t
>(
_Val
)); } {
// convert unsigned long long to wstring
return
(
_Integral_to_string
<
wchar_t
>(
_Val
)); } {
// convert float to wstring
return
(
_Floating_to_wstring
(
L"%f"
,
_Val
)); } {
// convert double to wstring
return
(
_Floating_to_wstring
(
L"%f"
,
_Val
)); } {
// convert long double to wstring
return
(
_Floating_to_wstring
(
L"%Lf"
,
_Val
)); }
// basic_string LITERALS
inline
namespace
literals
{
inline
namespace
string_literals
{ {
// construct literal from [_Str, _Str + _Len)
return
(
string
(
_Str
,
_Len
)); } {
// construct literal from [_Str, _Str + _Len)
return
(
wstring
(
_Str
,
_Len
)); } {
// construct literal from [_Str, _Str + _Len)
return
(
u16string
(
_Str
,
_Len
)); } {
// construct literal from [_Str, _Str + _Len)
return
(
u32string
(
_Str
,
_Len
)); } }
// inline namespace string_literals
}
// inline namespace literals
#if _HAS_CXX17
namespace pmr {
template<class _Elem,
class _Traits = char_traits<_Elem>>
using basic_string = _STD basic_string<_Elem, _Traits, polymorphic_allocator<_Elem>>;
using string = basic_string<char>;
using u16string = basic_string<char16_t>;
using u32string = basic_string<char32_t>;
using wstring = basic_string<wchar_t>;
} // namespace pmr #endif /* _HAS_CXX17 */
#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 */