562 lines
16 KiB
C++
562 lines
16 KiB
C++
/***************************************************************************
|
|
*
|
|
* _traits.h - definition of the char_traits class template
|
|
*
|
|
* This is an internal header file used to implement the C++ Standard
|
|
* Library. It should never be #included directly by a program.
|
|
*
|
|
* $Id: _traits.h 648752 2008-04-16 17:01:56Z faridz $
|
|
*
|
|
***************************************************************************
|
|
*
|
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
* contributor license agreements. See the NOTICE file distributed
|
|
* with this work for additional information regarding copyright
|
|
* ownership. The ASF licenses this file to you under the Apache
|
|
* License, Version 2.0 (the "License"); you may not use this file
|
|
* except in compliance with the License. You may obtain a copy of
|
|
* the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
* implied. See the License for the specific language governing
|
|
* permissions and limitations under the License.
|
|
*
|
|
* Copyright 1994-2008 Rogue Wave Software, Inc.
|
|
*
|
|
**************************************************************************/
|
|
|
|
#ifndef _RWSTD_RW_TRAITS_H_INCLUDED
|
|
#define _RWSTD_RW_TRAITS_H_INCLUDED
|
|
|
|
#ifndef _RWSTD_RW_IOSFWD_H_INCLUDED
|
|
# include <rw/_iosfwd.h>
|
|
#endif // _RWSTD_RW_IOSFWD_H_INCLUDED
|
|
|
|
#ifndef _RWSTD_RW_MBSTATE_H_INCLUDED
|
|
# include <rw/_mbstate.h> // for _RWSTD_MBSTATE_T
|
|
#endif // _RWSTD_RW_MBSTATE_H_INCLUDED
|
|
|
|
|
|
#if defined (_RWSTDDEBUG) || defined (_RWSTD_EDG_ECCP)
|
|
|
|
// avoid including <cstring> and <cwchar> in debug mode or when using
|
|
// the vanilla EDG eccp (i.e., in strict conformance mode) to prevent
|
|
// namespace pollutiuon
|
|
|
|
_RWSTD_NAMESPACE (__rw) {
|
|
|
|
_RWSTD_EXPORT void* __rw_memcpy (void*, const void*, _RWSTD_SIZE_T);
|
|
_RWSTD_EXPORT void* __rw_memmove (void*, const void*, _RWSTD_SIZE_T);
|
|
_RWSTD_EXPORT const void* __rw_memchr (const void*, int, _RWSTD_SIZE_T);
|
|
_RWSTD_EXPORT void* __rw_memset (void*, int, _RWSTD_SIZE_T);
|
|
_RWSTD_EXPORT int __rw_memcmp (const void*, const void*, _RWSTD_SIZE_T);
|
|
_RWSTD_EXPORT _RWSTD_SIZE_T __rw_strlen (const char*);
|
|
|
|
# ifndef _RWSTD_NO_WCHAR_T
|
|
|
|
_RWSTD_EXPORT wchar_t* __rw_wmemcpy (wchar_t*, const wchar_t*, _RWSTD_SIZE_T);
|
|
_RWSTD_EXPORT wchar_t* __rw_wmemmove (wchar_t*, const wchar_t*, _RWSTD_SIZE_T);
|
|
_RWSTD_EXPORT const wchar_t*
|
|
__rw_wmemchr (const wchar_t*, wchar_t, _RWSTD_SIZE_T);
|
|
_RWSTD_EXPORT wchar_t* __rw_wmemset (wchar_t*, wchar_t, _RWSTD_SIZE_T);
|
|
_RWSTD_EXPORT int __rw_wmemcmp (const wchar_t*, const wchar_t*, _RWSTD_SIZE_T);
|
|
_RWSTD_EXPORT _RWSTD_SIZE_T __rw_wcslen (const wchar_t*);
|
|
|
|
# endif // _RWSTD_NO_WCHAR_T
|
|
|
|
} // namespace __rw
|
|
|
|
# define _RWSTD_MEMCPY _RW::__rw_memcpy
|
|
# define _RWSTD_MEMCMP _RW::__rw_memcmp
|
|
# define _RWSTD_MEMCHR _RW::__rw_memchr
|
|
# define _RWSTD_MEMMOVE _RW::__rw_memmove
|
|
# define _RWSTD_MEMSET _RW::__rw_memset
|
|
# define _RWSTD_STRLEN _RW::__rw_strlen
|
|
|
|
# define _RWSTD_WMEMCPY _RW::__rw_wmemcpy
|
|
# define _RWSTD_WMEMCMP _RW::__rw_wmemcmp
|
|
# define _RWSTD_WMEMCHR _RW::__rw_wmemchr
|
|
# define _RWSTD_WMEMMOVE _RW::__rw_wmemmove
|
|
# define _RWSTD_WMEMSET _RW::__rw_wmemset
|
|
# define _RWSTD_WCSLEN _RW::__rw_wcslen
|
|
#else // if !defined (_RWSTDDEBUG) && !defined (_RWSTD_EDG_ECCP)
|
|
|
|
# if 4 <= __GNUG__ && !defined (__INTEL_COMPILER)
|
|
// use gcc 4.x intrinsic functions
|
|
# define _RWSTD_MEMCPY __builtin_memcpy
|
|
# define _RWSTD_MEMCMP __builtin_memcmp
|
|
# define _RWSTD_MEMMOVE __builtin_memmove
|
|
# define _RWSTD_MEMSET __builtin_memset
|
|
# define _RWSTD_STRLEN __builtin_strlen
|
|
|
|
# if 4 < __GNUG__ || 3 <= __GNUC_MINOR__
|
|
// __builtin_memchr() is only available in gcc 4.3 and beyond
|
|
# define _RWSTD_MEMCHR __builtin_memchr
|
|
# else // gcc < 4.3
|
|
# include _RWSTD_CSTRING // for memchr()
|
|
# define _RWSTD_MEMCHR _RWSTD_C::memchr
|
|
# endif // gcc 4.3
|
|
# else // gcc < 4.0
|
|
# include _RWSTD_CSTRING // for memcmp(), ...
|
|
|
|
# define _RWSTD_MEMCPY _RWSTD_C::memcpy
|
|
# define _RWSTD_MEMCMP _RWSTD_C::memcmp
|
|
# define _RWSTD_MEMMOVE _RWSTD_C::memmove
|
|
# define _RWSTD_MEMSET _RWSTD_C::memset
|
|
# define _RWSTD_STRLEN _RWSTD_C::strlen
|
|
# define _RWSTD_MEMCHR _RWSTD_C::memchr
|
|
# endif // gcc 4.0
|
|
|
|
# include _RWSTD_CWCHAR // wmemcmp(), ...
|
|
|
|
# ifndef _RWSTD_NO_WMEMCPY
|
|
# define _RWSTD_WMEMCPY _RWSTD_C::wmemcpy
|
|
# elif !defined (_RWSTD_NO_WCHAR_T)
|
|
|
|
_RWSTD_NAMESPACE (__rw) {
|
|
|
|
_RWSTD_EXPORT wchar_t*
|
|
__rw_wmemcpy (wchar_t*, const wchar_t*, _RWSTD_SIZE_T);
|
|
|
|
|
|
} // namespace __rw
|
|
|
|
# define _RWSTD_WMEMCPY _RW::__rw_wmemcpy
|
|
# endif // _RWSTD_NO_WMEMCPY
|
|
|
|
# ifndef _RWSTD_NO_WMEMCMP
|
|
# define _RWSTD_WMEMCMP wmemcmp
|
|
# elif !defined (_RWSTD_NO_WCHAR_T)
|
|
|
|
_RWSTD_NAMESPACE (__rw) {
|
|
|
|
_RWSTD_EXPORT int
|
|
__rw_wmemcmp (const wchar_t*, const wchar_t*, _RWSTD_SIZE_T);
|
|
|
|
|
|
} // namespace __rw
|
|
|
|
# define _RWSTD_WMEMCMP _RW::__rw_wmemcmp
|
|
# endif // _RWSTD_NO_WMEMCMP
|
|
|
|
# ifndef _RWSTD_NO_WMEMMOVE
|
|
# define _RWSTD_WMEMMOVE _RWSTD_C::wmemmove
|
|
# elif !defined (_RWSTD_NO_WCHAR_T)
|
|
|
|
_RWSTD_NAMESPACE (__rw) {
|
|
|
|
_RWSTD_EXPORT wchar_t*
|
|
__rw_wmemmove (wchar_t*, const wchar_t*, _RWSTD_SIZE_T);
|
|
|
|
|
|
} // namespace __rw
|
|
|
|
# define _RWSTD_WMEMMOVE _RW::__rw_wmemmove
|
|
# endif // _RWSTD_NO_WMEMMOVE
|
|
|
|
# ifndef _RWSTD_NO_WMEMSET
|
|
# define _RWSTD_WMEMSET _RWSTD_C::wmemset
|
|
# elif !defined (_RWSTD_NO_WCHAR_T)
|
|
|
|
_RWSTD_NAMESPACE (__rw) {
|
|
|
|
_RWSTD_EXPORT wchar_t*
|
|
__rw_wmemset (wchar_t*, wchar_t, _RWSTD_SIZE_T);
|
|
|
|
|
|
} // namespace __rw
|
|
|
|
# define _RWSTD_WMEMSET _RW::__rw_wmemset
|
|
# endif // _RWSTD_NO_WMEMSET
|
|
|
|
# ifndef _RWSTD_NO_WCSLEN
|
|
# define _RWSTD_WCSLEN _RWSTD_C::wcslen
|
|
# elif !defined (_RWSTD_NO_WCHAR_T)
|
|
|
|
_RWSTD_NAMESPACE (__rw) {
|
|
|
|
_RWSTD_EXPORT _RWSTD_SIZE_T
|
|
__rw_wcslen (const wchar_t*);
|
|
|
|
|
|
} // namespace __rw
|
|
|
|
# define _RWSTD_WCSLEN _RW::__rw_wcslen
|
|
# endif // _RWSTD_NO_WCSLEN
|
|
|
|
# ifndef _RWSTD_NO_WMEMCHR
|
|
# define _RWSTD_WMEMCHR _RWSTD_C::wmemchr
|
|
# elif !defined (_RWSTD_NO_WCHAR_T)
|
|
|
|
_RWSTD_NAMESPACE (__rw) {
|
|
|
|
_RWSTD_EXPORT const wchar_t*
|
|
__rw_wmemchr (const wchar_t*, wchar_t, _RWSTD_SIZE_T);
|
|
|
|
|
|
} // namespace __rw
|
|
|
|
# define _RWSTD_WMEMCHR _RW::__rw_wmemchr
|
|
# endif // _RWSTD_NO_WMEMCHR
|
|
|
|
#endif // !_RWSTDDEBUG && !(vanilla EDG eccp demo)
|
|
|
|
|
|
_RWSTD_NAMESPACE (std) {
|
|
|
|
|
|
// 27.4.1, p2
|
|
// the C++ type ptrdiff_t is the same as the POSIX ssize_t suggested
|
|
// to be used here in 27.4.2, Footnote 266, except for Win64 where
|
|
// the former is 64 bits while the latter is only 32 bits wide
|
|
typedef _RWSTD_PTRDIFF_T streamsize;
|
|
|
|
|
|
// 27.4.3
|
|
template <class _StateT>
|
|
class fpos
|
|
{
|
|
public:
|
|
|
|
typedef _StateT state_type;
|
|
|
|
#ifndef _RWSTD_NO_POD_ZERO_INIT
|
|
|
|
fpos (_RWSTD_STREAMOFF __off = 0,
|
|
const state_type &__state = state_type ())
|
|
: _C_pos (__off),
|
|
_C_state (__state)
|
|
{ }
|
|
|
|
#else // if defined (_RWSTD_NO_POD_ZERO_INIT)
|
|
|
|
fpos (_RWSTD_STREAMOFF __off = 0)
|
|
: _C_pos (__off) {
|
|
_RWSTD_MEMSET (&_C_state, 0, sizeof _C_state);
|
|
}
|
|
|
|
fpos (_RWSTD_STREAMOFF __off, const state_type &__state)
|
|
: _C_pos (__off),
|
|
_C_state (__state)
|
|
{ }
|
|
|
|
#endif // _RWSTD_NO_POD_ZERO_INIT
|
|
|
|
operator _RWSTD_STREAMOFF () const {
|
|
return _C_pos;
|
|
}
|
|
|
|
// 27.4.3.1, p1
|
|
void state (state_type __state) {
|
|
_C_state = __state;
|
|
}
|
|
|
|
// 27.4.3.1, p2
|
|
state_type state () const {
|
|
return _C_state;
|
|
}
|
|
|
|
// 27.4.3.2, p1: Table 88
|
|
fpos& operator-= (_RWSTD_STREAMOFF __off) {
|
|
return _C_pos -= __off, *this;
|
|
}
|
|
|
|
fpos& operator+= (_RWSTD_STREAMOFF __off) {
|
|
return _C_pos += __off, *this;
|
|
}
|
|
|
|
fpos operator- (_RWSTD_STREAMOFF __off) const {
|
|
return fpos (*this) -= __off;
|
|
}
|
|
|
|
fpos operator+ (_RWSTD_STREAMOFF __off) const {
|
|
return fpos (*this) += __off;
|
|
}
|
|
|
|
// equality and relational operators provided
|
|
// via the conversion operator to streamoff
|
|
|
|
private:
|
|
|
|
_RWSTD_STREAMOFF _C_pos; // signed displacement
|
|
state_type _C_state; // conversion state
|
|
};
|
|
|
|
|
|
template <class _CharT>
|
|
struct char_traits;
|
|
|
|
|
|
#ifndef _RWSTD_NO_EXT_CHAR_TRAITS_PRIMARY
|
|
|
|
template <class _CharT>
|
|
struct char_traits
|
|
{
|
|
typedef _CharT char_type;
|
|
typedef int int_type;
|
|
typedef _RWSTD_STREAMOFF off_type;
|
|
typedef _RWSTD_MBSTATE_T state_type;
|
|
typedef fpos<state_type> pos_type;
|
|
|
|
static int_type eof () {
|
|
return -1;
|
|
}
|
|
|
|
static void assign (char_type& __c1, const char_type& __c2) {
|
|
__c1 = __c2;
|
|
}
|
|
|
|
static bool eq (const char_type& __c1, const char_type& __c2) {
|
|
return __c1 == __c2;
|
|
}
|
|
|
|
static bool lt (const char_type& __c1, const char_type& __c2) {
|
|
return __c1 < __c2;
|
|
}
|
|
|
|
static int
|
|
compare (const char_type* __s1, const char_type* __s2, _RWSTD_SIZE_T __n) {
|
|
for (_RWSTD_SIZE_T __i = 0; __i != __n; ++__i) {
|
|
if (!eq (__s1[__i], __s2[__i])) {
|
|
return lt (__s1[__i], __s2[__i]) ? -1 : 1;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static _RWSTD_SIZE_T length (const char_type *__s) {
|
|
_RWSTD_SIZE_T __len = 0;
|
|
while (!eq (*__s++, char_type ()))
|
|
++__len;
|
|
return __len;
|
|
}
|
|
|
|
static const char_type*
|
|
find (const char_type* __s, _RWSTD_SIZE_T __n, const char_type& __c) {
|
|
while (__n-- > 0 && !eq (*__s, __c) )
|
|
++__s;
|
|
return eq (*__s, __c) ? __s : 0;
|
|
}
|
|
|
|
static char_type*
|
|
move (char_type* __s1, const char_type* __s2, _RWSTD_SIZE_T __n) {
|
|
_RWSTD_MEMMOVE (__s1, __s2, __n * sizeof (char_type));
|
|
return __s1;
|
|
}
|
|
|
|
static char_type*
|
|
copy (char_type *__dst, const char_type *__src, _RWSTD_SIZE_T __n) {
|
|
_RWSTD_MEMCPY (_RWSTD_STATIC_CAST (void*, __dst),
|
|
_RWSTD_STATIC_CAST (const void*, __src),
|
|
__n * sizeof (char_type));
|
|
return __dst;
|
|
}
|
|
|
|
static char_type*
|
|
assign (char_type* __s, _RWSTD_SIZE_T __n, char_type __c) {
|
|
char_type* __tmp = __s;
|
|
while (__n-- > 0)
|
|
assign (*__tmp++, __c);
|
|
return __s;
|
|
}
|
|
|
|
static bool eq_int_type (const int_type& __c1, const int_type& __c2) {
|
|
return __c1 == __c2;
|
|
}
|
|
|
|
static int_type not_eof (const int_type& __c) {
|
|
return eq_int_type (eof (), __c) ? 0 : __c;
|
|
}
|
|
|
|
static char_type to_char_type (const int_type& __c) {
|
|
// cast to prevent warnings for unusual types
|
|
return _RWSTD_STATIC_CAST (char_type, __c);
|
|
}
|
|
|
|
static int_type to_int_type (const char_type& __c) {
|
|
// cast to prevent warnings for unusual types
|
|
return _RWSTD_STATIC_CAST (int_type, __c);
|
|
}
|
|
};
|
|
|
|
#endif // _RWSTD_NO_EXT_CHAR_TRAITS_PRIMARY
|
|
|
|
|
|
// 21.1.3.1
|
|
_RWSTD_SPECIALIZED_CLASS
|
|
struct char_traits<char>
|
|
{
|
|
typedef char char_type;
|
|
typedef _RWSTD_INT_T int_type;
|
|
typedef _RWSTD_STREAMOFF off_type;
|
|
typedef _RWSTD_MBSTATE_T state_type;
|
|
typedef fpos<state_type> pos_type;
|
|
|
|
static int_type eof () {
|
|
return int_type (_RWSTD_EOF);
|
|
}
|
|
|
|
static void assign (char_type& __c1, const char_type& __c2){
|
|
__c1 = __c2;
|
|
}
|
|
|
|
static bool eq (const char_type& __c1, const char_type& __c2) {
|
|
return __c1 == __c2;
|
|
}
|
|
|
|
static bool lt (const char_type& __c1, const char_type& __c2) {
|
|
// lwg issue 467: cast arguments to unsigned char
|
|
// to get the same result as memcmp(&c1, &c2) < 0
|
|
return _RWSTD_STATIC_CAST (unsigned char, __c1)
|
|
< _RWSTD_STATIC_CAST (unsigned char, __c2);
|
|
}
|
|
|
|
static int
|
|
compare (const char_type* __s1, const char_type* __s2, _RWSTD_SIZE_T __n) {
|
|
return _RWSTD_MEMCMP (__s1, __s2, __n);
|
|
}
|
|
|
|
static const char_type*
|
|
find (const char_type* __s, _RWSTD_SIZE_T __n, const char_type& __c) {
|
|
// cast to const void* used to get around a gcc 2.95 bug
|
|
// that prevents a static_cast from void* --> const T*
|
|
// (only occurs if memchr() isn't overloaded on const)
|
|
return _RWSTD_STATIC_CAST (
|
|
const char_type*, (const void*)_RWSTD_MEMCHR (
|
|
__s, _RWSTD_STATIC_CAST (unsigned char, __c), __n));
|
|
}
|
|
|
|
static _RWSTD_SIZE_T length (const char_type *__s) {
|
|
return _RWSTD_STRLEN (__s);
|
|
}
|
|
|
|
static char_type*
|
|
move (char_type* __s1, const char_type* __s2, _RWSTD_SIZE_T __n) {
|
|
_RWSTD_MEMMOVE (__s1, __s2, __n);
|
|
return __s1;
|
|
}
|
|
|
|
static char_type*
|
|
copy (char_type *__dst, const char_type *__src, _RWSTD_SIZE_T __n) {
|
|
_RWSTD_MEMCPY (__dst, __src, __n);
|
|
return __dst;
|
|
}
|
|
|
|
static char_type*
|
|
assign (char_type* __s, _RWSTD_SIZE_T __n, char_type __c) {
|
|
_RWSTD_MEMSET (__s, __c, __n);
|
|
return __s;
|
|
}
|
|
|
|
static bool eq_int_type (const int_type& __c1, const int_type& __c2) {
|
|
return __c1 == __c2;
|
|
}
|
|
|
|
static int_type not_eof (const int_type& __c) {
|
|
return eq_int_type (eof (), __c) ? 0 : __c;
|
|
}
|
|
|
|
static char_type to_char_type (const int_type& __c) {
|
|
return _RWSTD_STATIC_CAST (char_type, __c);
|
|
}
|
|
|
|
static int_type to_int_type (const char_type& __c) {
|
|
// make sure (signed char)'\xff' converts to 255 and not -1
|
|
return _RWSTD_STATIC_CAST (unsigned char, __c);
|
|
}
|
|
};
|
|
|
|
|
|
#ifndef _RWSTD_NO_WCHAR_T
|
|
|
|
// 21.1.3.2
|
|
_RWSTD_SPECIALIZED_CLASS
|
|
struct char_traits<wchar_t>
|
|
{
|
|
typedef wchar_t char_type;
|
|
typedef _RWSTD_WINT_T int_type;
|
|
typedef _RWSTD_STREAMOFF off_type;
|
|
typedef _RWSTD_MBSTATE_T state_type;
|
|
typedef fpos<state_type> pos_type;
|
|
|
|
static int_type eof () {
|
|
return int_type (_RWSTD_WEOF);
|
|
}
|
|
|
|
static void assign (char_type& __c1, const char_type& __c2) {
|
|
__c1 = __c2;
|
|
}
|
|
|
|
static bool eq (const char_type& __c1, const char_type& __c2) {
|
|
return __c1 == __c2;
|
|
}
|
|
|
|
static bool lt (const char_type& __c1, const char_type& __c2) {
|
|
return __c1 < __c2;
|
|
}
|
|
|
|
static int
|
|
compare (const char_type* __s1, const char_type* __s2, _RWSTD_SIZE_T __n) {
|
|
return _RWSTD_WMEMCMP (__s1, __s2, __n);
|
|
}
|
|
|
|
static _RWSTD_SIZE_T length (const char_type *__s) {
|
|
// [harmless] cast necessary on CygWin
|
|
return _RWSTD_WCSLEN (_RWSTD_CONST_CAST (char_type*, __s));
|
|
}
|
|
|
|
static const char_type*
|
|
find (const char_type* __s, _RWSTD_SIZE_T __n, const char_type& __c) {
|
|
// const cast in case of a const-incorrect wmemchr()
|
|
return _RWSTD_STATIC_CAST (const char_type*,
|
|
_RWSTD_WMEMCHR (_RWSTD_CONST_CAST (char_type*, __s),
|
|
__c, __n));
|
|
}
|
|
|
|
static char_type*
|
|
copy (char_type *__dst, const char_type *__src, _RWSTD_SIZE_T __n) {
|
|
_RWSTD_WMEMCPY (__dst, __src, __n);
|
|
return __dst;
|
|
}
|
|
|
|
static char_type*
|
|
move (char_type* __s1, const char_type* __s2, _RWSTD_SIZE_T __n) {
|
|
_RWSTD_WMEMMOVE (__s1, __s2, __n);
|
|
return __s1;
|
|
}
|
|
|
|
static char_type*
|
|
assign (char_type* __s, _RWSTD_SIZE_T __n, char_type __c) {
|
|
_RWSTD_WMEMSET (__s, __c, __n);
|
|
return __s;
|
|
}
|
|
|
|
static bool eq_int_type (const int_type& __c1, const int_type& __c2) {
|
|
return __c1 == __c2;
|
|
}
|
|
|
|
static int_type not_eof (const int_type& __c) {
|
|
return eq_int_type (eof (), __c) ? 0 : __c;
|
|
}
|
|
|
|
static char_type to_char_type (const int_type& __c) {
|
|
return __c;
|
|
}
|
|
|
|
static int_type to_int_type (const char_type& __c) {
|
|
return __c;
|
|
}
|
|
};
|
|
|
|
#endif // _RWSTD_NO_WCHAR_T
|
|
|
|
|
|
} // namespace std
|
|
|
|
|
|
#endif // _RWSTD_RW_TRAITS_H_INCLUDED
|