blob: 4eac598324f7dfedde847fd7182e6603f9ebf18b [file] [log] [blame]
/***************************************************************************
*
* _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$
*
***************************************************************************
*
* 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