562 lines
14 KiB
C
562 lines
14 KiB
C
|
#ifndef __TRAITS_H
|
|||
|
#define __TRAITS_H
|
|||
|
#pragma option push -b -a8 -pc -Vx- -Ve- -w-inl -w-aus -w-sig
|
|||
|
// -*- C++ -*-
|
|||
|
#ifndef __RW_TRAITS
|
|||
|
#define __RW_TRAITS
|
|||
|
/***************************************************************************
|
|||
|
*
|
|||
|
* traits - Declarations for char_traits
|
|||
|
*
|
|||
|
*
|
|||
|
***************************************************************************
|
|||
|
*
|
|||
|
* Copyright (c) 1994-1999 Rogue Wave Software, Inc. All Rights Reserved.
|
|||
|
*
|
|||
|
* This computer software is owned by Rogue Wave Software, Inc. and is
|
|||
|
* protected by U.S. copyright laws and other laws and by international
|
|||
|
* treaties. This computer software is furnished by Rogue Wave Software,
|
|||
|
* Inc. pursuant to a written license agreement and may be used, copied,
|
|||
|
* transmitted, and stored only in accordance with the terms of such
|
|||
|
* license and with the inclusion of the above copyright notice. This
|
|||
|
* computer software or any other copies thereof may not be provided or
|
|||
|
* otherwise made available to any other person.
|
|||
|
*
|
|||
|
* U.S. Government Restricted Rights. This computer software is provided
|
|||
|
* with Restricted Rights. Use, duplication, or disclosure by the
|
|||
|
* Government is subject to restrictions as set forth in subparagraph (c)
|
|||
|
* (1) (ii) of The Rights in Technical Data and Computer Software clause
|
|||
|
* at DFARS 252.227-7013 or subparagraphs (c) (1) and (2) of the
|
|||
|
* Commercial Computer Software <EFBFBD> Restricted Rights at 48 CFR 52.227-19,
|
|||
|
* as applicable. Manufacturer is Rogue Wave Software, Inc., 5500
|
|||
|
* Flatiron Parkway, Boulder, Colorado 80301 USA.
|
|||
|
*
|
|||
|
**************************************************************************/
|
|||
|
|
|||
|
#ifndef _RWSTD_NO_NEW_HEADER
|
|||
|
#include <cstdio>
|
|||
|
#include <cstring>
|
|||
|
#else
|
|||
|
#include <stdio.h>
|
|||
|
#include <string.h>
|
|||
|
#endif
|
|||
|
|
|||
|
//
|
|||
|
// Temporarily turn off the warnings under the Borland compiler that
|
|||
|
// say 'Functions containing ... cannot be inlined'
|
|||
|
//
|
|||
|
#if defined(__BORLANDC__)
|
|||
|
#pragma option -w-inl
|
|||
|
#endif
|
|||
|
|
|||
|
/*
|
|||
|
* this are all necessary for the "traits" class
|
|||
|
*/
|
|||
|
#ifdef _RW_STD_IOSTREAM
|
|||
|
#include <rw/iotraits>
|
|||
|
#endif
|
|||
|
|
|||
|
#ifndef _RWSTD_NO_NAMESPACE
|
|||
|
namespace std {
|
|||
|
#endif
|
|||
|
|
|||
|
/*
|
|||
|
* STRUCT CHAR_TRAITS
|
|||
|
*/
|
|||
|
|
|||
|
template <class charT>
|
|||
|
struct _RWSTDExportTemplate char_traits
|
|||
|
{
|
|||
|
typedef charT char_type;
|
|||
|
typedef long int_type;
|
|||
|
|
|||
|
#ifdef _RW_STD_IOSTREAM
|
|||
|
typedef wstreamoff off_type;
|
|||
|
typedef mbstate_t state_type;
|
|||
|
typedef fpos<state_type> pos_type;
|
|||
|
#endif /* _RW_STD_IOSTREAM */
|
|||
|
|
|||
|
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, size_t n)
|
|||
|
{
|
|||
|
size_t i=0;
|
|||
|
|
|||
|
while ( i < n )
|
|||
|
{
|
|||
|
if ( !eq( s1[i], s2[i] ) )
|
|||
|
{
|
|||
|
if ( lt( s1[i], s2[i]) )
|
|||
|
return -1;
|
|||
|
else
|
|||
|
return 1;
|
|||
|
}
|
|||
|
i++;
|
|||
|
}
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
static size_t length(const char_type *s)
|
|||
|
{
|
|||
|
size_t l = 0;
|
|||
|
while ( !eq(*s++, char_type(0) ) ) ++l;
|
|||
|
return l;
|
|||
|
}
|
|||
|
|
|||
|
static const char_type*
|
|||
|
find (const char_type* s, size_t n, const char_type& a)
|
|||
|
{
|
|||
|
while (n-- > 0 && *s != a)
|
|||
|
++s;
|
|||
|
return *s == a ? s : 0;
|
|||
|
}
|
|||
|
|
|||
|
static char_type* move (char_type* s1, const char_type* s2, size_t n)
|
|||
|
{
|
|||
|
char_type * s = s1;
|
|||
|
if (s1 < s2)
|
|||
|
copy(s1, s2, n);
|
|||
|
else if (s1 > s2)
|
|||
|
{
|
|||
|
s1 += n;
|
|||
|
s2 += n;
|
|||
|
for(size_t i = 0; i < n; ++i)
|
|||
|
assign(*--s1, *--s2);
|
|||
|
}
|
|||
|
return s1;
|
|||
|
}
|
|||
|
|
|||
|
static char_type * copy(char_type *dst,const char_type *src, size_t n)
|
|||
|
{
|
|||
|
memcpy((char *)dst,(char *)src,n*sizeof(char_type));
|
|||
|
return dst;
|
|||
|
}
|
|||
|
|
|||
|
static char_type* assign (char_type* s, size_t n, char_type a)
|
|||
|
{
|
|||
|
char_type* tmp = s;
|
|||
|
while (n-- > 0)
|
|||
|
*tmp++ = a;
|
|||
|
return s;
|
|||
|
}
|
|||
|
|
|||
|
static int_type not_eof(const int_type& c)
|
|||
|
{
|
|||
|
if(c == EOF)
|
|||
|
return 0;
|
|||
|
else
|
|||
|
return 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; }
|
|||
|
|
|||
|
static bool eq_int_type(const int_type& c1,const int_type& c2)
|
|||
|
{ return (c1 == c2); }
|
|||
|
|
|||
|
#ifdef _RW_STD_IOSTREAM
|
|||
|
static state_type get_state(pos_type pos)
|
|||
|
{ return pos.state(); }
|
|||
|
#endif
|
|||
|
|
|||
|
static int_type eof()
|
|||
|
{ return EOF; }
|
|||
|
};
|
|||
|
/*
|
|||
|
*
|
|||
|
* STRUCT CHAR_TRAITS SPECIALIZED FOR CHAR
|
|||
|
*
|
|||
|
*/
|
|||
|
|
|||
|
_RWSTD_TEMPLATE
|
|||
|
struct _RWSTDExport char_traits<char>
|
|||
|
{
|
|||
|
|
|||
|
typedef char char_type;
|
|||
|
typedef int int_type;
|
|||
|
|
|||
|
#ifdef _RW_STD_IOSTREAM
|
|||
|
typedef streamoff off_type;
|
|||
|
typedef streampos pos_type;
|
|||
|
typedef mbstate_t state_type;
|
|||
|
#endif
|
|||
|
|
|||
|
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, size_t n)
|
|||
|
{ return memcmp(s1, s2, n); }
|
|||
|
|
|||
|
static const char_type* find (const char_type* s,
|
|||
|
size_t n, const char_type& a)
|
|||
|
{ return (char_type*) memchr(s,a,n); }
|
|||
|
|
|||
|
static size_t length(const char_type *s)
|
|||
|
{ return strlen(s); }
|
|||
|
|
|||
|
static char_type * move (char_type* s1, const char_type* s2, size_t n)
|
|||
|
{
|
|||
|
#ifndef _RWSTD_NO_MEMMOVE
|
|||
|
memmove(s1, s2, n);
|
|||
|
#else
|
|||
|
char_type * s = s1;
|
|||
|
if (s1 < s2)
|
|||
|
copy(s1, s2, n);
|
|||
|
else if (s1 > s2)
|
|||
|
{
|
|||
|
s1 += n;
|
|||
|
s2 += n;
|
|||
|
for(size_t i = 0; i < n; ++i)
|
|||
|
assign(*--s1, *--s2);
|
|||
|
}
|
|||
|
#endif
|
|||
|
return s1;
|
|||
|
}
|
|||
|
|
|||
|
static char_type *copy(char_type *dst,const char_type *src, size_t n)
|
|||
|
{
|
|||
|
memcpy(dst, src, n);
|
|||
|
return dst;
|
|||
|
}
|
|||
|
|
|||
|
static char_type* assign (char_type* s, size_t n, char_type a)
|
|||
|
{
|
|||
|
memset(s,a,n);
|
|||
|
return s;
|
|||
|
}
|
|||
|
|
|||
|
static int_type not_eof(const int_type& c)
|
|||
|
{
|
|||
|
if ( c == EOF )
|
|||
|
return 0;
|
|||
|
else
|
|||
|
return c;
|
|||
|
}
|
|||
|
|
|||
|
static char_type to_char_type(const int_type& c)
|
|||
|
{ return (char)c; }
|
|||
|
static int_type to_int_type(const char_type& c)
|
|||
|
{ return (unsigned char)c; }
|
|||
|
|
|||
|
static bool eq_int_type(const int_type& c1,const int_type& c2)
|
|||
|
{ return (c1 == c2); }
|
|||
|
|
|||
|
#ifdef _RW_STD_IOSTREAM
|
|||
|
static state_type get_state(pos_type pos)
|
|||
|
{ return pos.state(); }
|
|||
|
#endif
|
|||
|
|
|||
|
static int_type eof()
|
|||
|
{ return EOF; }
|
|||
|
};
|
|||
|
/*
|
|||
|
*
|
|||
|
* STRUCT CHAR_TRAITS SPECIALIZED FOR WCHAR_T
|
|||
|
*
|
|||
|
*/
|
|||
|
#ifndef _RWSTD_NO_WIDE_CHAR
|
|||
|
|
|||
|
_RWSTD_TEMPLATE
|
|||
|
struct _RWSTDExport char_traits<wchar_t>
|
|||
|
{
|
|||
|
typedef wchar_t char_type;
|
|||
|
|
|||
|
#ifndef _RWSTD_NO_WINT_TYPE
|
|||
|
typedef wint_t int_type;
|
|||
|
#else
|
|||
|
typedef long int_type;
|
|||
|
#endif
|
|||
|
|
|||
|
#ifndef WEOF
|
|||
|
#define WEOF (-1)
|
|||
|
#endif
|
|||
|
|
|||
|
#ifdef _RW_STD_IOSTREAM
|
|||
|
typedef wstreamoff off_type;
|
|||
|
typedef wstreampos pos_type;
|
|||
|
typedef mbstate_t state_type;
|
|||
|
#endif /* _RW_STD_IOSTREAM */
|
|||
|
|
|||
|
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, size_t n)
|
|||
|
{
|
|||
|
#ifndef _RWSTD_NO_WSTR
|
|||
|
return memcmp(s1, s2, n*sizeof(char_type));
|
|||
|
#else
|
|||
|
size_t i=0;
|
|||
|
|
|||
|
while ( i < n )
|
|||
|
{
|
|||
|
if ( !eq( s1[i], s2[i] ) )
|
|||
|
{
|
|||
|
if ( lt( s1[i], s2[i]) )
|
|||
|
return -1;
|
|||
|
else
|
|||
|
return 1;
|
|||
|
}
|
|||
|
i++;
|
|||
|
}
|
|||
|
return 0;
|
|||
|
#endif
|
|||
|
}
|
|||
|
static size_t length(const char_type *s)
|
|||
|
{
|
|||
|
#ifndef _RWSTD_NO_WSTR
|
|||
|
return wcslen(s);
|
|||
|
#else
|
|||
|
size_t l = 0;
|
|||
|
while ( !eq(*s++, char_type(0) ) ) ++l;
|
|||
|
return l;
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
static const char_type* find (const char_type* s, size_t n,
|
|||
|
const char_type& a)
|
|||
|
{
|
|||
|
#ifndef _RWSTD_NOT_ALL_WSTR_CFUNCTIONS
|
|||
|
return (char_type*) wmemchr(s,a,n);
|
|||
|
#else
|
|||
|
while (n-- > 0 && *s != a)
|
|||
|
++s;
|
|||
|
return *s == a ? s : 0;
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
static char_type * move (char_type* s1, const char_type* s2, size_t n)
|
|||
|
{
|
|||
|
#ifndef _RWSTD_NO_MEMMOVE
|
|||
|
memmove(s1, s2, n*sizeof(char_type));
|
|||
|
#else
|
|||
|
char_type * s = s1;
|
|||
|
if (s1 < s2)
|
|||
|
copy(s1, s2, n);
|
|||
|
else if (s1 > s2)
|
|||
|
{
|
|||
|
s1 += n;
|
|||
|
s2 += n;
|
|||
|
for(size_t i = 0; i < n; ++i) assign(*--s1, *--s2);
|
|||
|
}
|
|||
|
#endif
|
|||
|
return s1;
|
|||
|
}
|
|||
|
|
|||
|
static char_type * copy(char_type *dst,const char_type *src, size_t n)
|
|||
|
{
|
|||
|
memcpy((char *)dst,(char *)src, n*sizeof(char_type));
|
|||
|
return dst;
|
|||
|
}
|
|||
|
|
|||
|
static char_type* assign (char_type* s, size_t n, char_type a)
|
|||
|
{
|
|||
|
#ifndef _RWSTD_NOT_ALL_WSTR_CFUNCTIONS
|
|||
|
wmemset(s,a,n);
|
|||
|
#else
|
|||
|
char_type* tmp = s;
|
|||
|
while (n-- > 0)
|
|||
|
*tmp++ = a;
|
|||
|
#endif
|
|||
|
return s;
|
|||
|
}
|
|||
|
|
|||
|
static int_type not_eof(const int_type& c)
|
|||
|
{
|
|||
|
if(c == WEOF)
|
|||
|
return 0;
|
|||
|
else
|
|||
|
return 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; }
|
|||
|
|
|||
|
static bool eq_int_type(const int_type& c1,const int_type& c2)
|
|||
|
{ return (c1 == c2); }
|
|||
|
|
|||
|
#ifdef _RW_STD_IOSTREAM
|
|||
|
static state_type get_state(pos_type pos)
|
|||
|
{ return pos.state(); }
|
|||
|
#endif
|
|||
|
|
|||
|
static int_type eof()
|
|||
|
{ return WEOF; }
|
|||
|
};
|
|||
|
|
|||
|
#endif
|
|||
|
#ifndef _RWSTD_NO_NAMESPACE
|
|||
|
} namespace __rwstd {
|
|||
|
#endif
|
|||
|
//
|
|||
|
// Implementation traits class, rw_traits, provides specialized
|
|||
|
// algorithms to speed up find operations on char and wchar_t strings
|
|||
|
//
|
|||
|
|
|||
|
template <class charT, class traits>
|
|||
|
struct _RWSTDExportTemplate rw_traits
|
|||
|
{
|
|||
|
static const charT* find(const charT* s, const charT* v)
|
|||
|
{
|
|||
|
size_t slen = traits::length(s);
|
|||
|
size_t vlen = traits::length(v);
|
|||
|
for (size_t xpos = 0; (xpos + vlen) <= slen ; xpos++)
|
|||
|
{
|
|||
|
bool found = true;
|
|||
|
for (size_t i = 0; i < vlen ; i++)
|
|||
|
{
|
|||
|
if (!traits::eq(s[xpos + i], v[i]))
|
|||
|
{
|
|||
|
found = false;
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
if (found)
|
|||
|
return &s[xpos];
|
|||
|
}
|
|||
|
return NULL;
|
|||
|
}
|
|||
|
|
|||
|
static const charT* rfind(const charT* s, charT v, size_t pos)
|
|||
|
{
|
|||
|
const charT* p = s + pos;
|
|||
|
while (p >= s)
|
|||
|
{
|
|||
|
if (traits::eq(*p,v))
|
|||
|
return p;
|
|||
|
p--;
|
|||
|
}
|
|||
|
return NULL;
|
|||
|
}
|
|||
|
|
|||
|
static size_t find_first_of(const charT* s, const charT* v)
|
|||
|
{
|
|||
|
const charT* p = s;
|
|||
|
for (; *p; p++)
|
|||
|
{
|
|||
|
for (const charT* q = v; *q; q++)
|
|||
|
if (traits::eq(*p, *q))
|
|||
|
return p-s;
|
|||
|
}
|
|||
|
return p-s;
|
|||
|
}
|
|||
|
|
|||
|
static size_t find_first_not_of(const charT* s, const charT* v)
|
|||
|
{
|
|||
|
const charT* p = s;
|
|||
|
for (; *p; p++)
|
|||
|
{
|
|||
|
for (const charT* q = v; *q; q++)
|
|||
|
if (!traits::eq(*p, *q))
|
|||
|
return p-s;
|
|||
|
}
|
|||
|
return p-s;
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
_RWSTD_TEMPLATE
|
|||
|
struct _RWSTDExport rw_traits<char,_RW_STD::char_traits<char> >
|
|||
|
{
|
|||
|
static const char* find(const char* s, const char* v)
|
|||
|
#if !defined(_RWSTD_NO_NEW_HEADER) && !defined(_RWSTD_NO_NAMESPACE)
|
|||
|
{ return std::strstr(s,v); }
|
|||
|
#else
|
|||
|
{ return strstr(s,v); }
|
|||
|
#endif
|
|||
|
static const char* rfind(const char* s, char v, size_t pos)
|
|||
|
{
|
|||
|
const char* p = s + pos;
|
|||
|
while (p >= s)
|
|||
|
{
|
|||
|
if (_RW_STD::char_traits<char>::eq(*p,v))
|
|||
|
return p;
|
|||
|
p--;
|
|||
|
}
|
|||
|
return NULL;
|
|||
|
}
|
|||
|
static size_t find_first_of(const char* s, const char* v)
|
|||
|
#if !defined(_RWSTD_NO_NEW_HEADER) && !defined(_RWSTD_NO_NAMESPACE)
|
|||
|
{ return std::strcspn(s,v); }
|
|||
|
#else
|
|||
|
{ return strcspn(s,v); }
|
|||
|
#endif
|
|||
|
static size_t find_first_not_of(const char* s, const char* v)
|
|||
|
#if !defined(_RWSTD_NO_NEW_HEADER) && !defined(_RWSTD_NO_NAMESPACE)
|
|||
|
{ return std::strspn(s,v); }
|
|||
|
#else
|
|||
|
{ return strspn(s,v); }
|
|||
|
#endif
|
|||
|
};
|
|||
|
|
|||
|
#ifndef _RWSTD_NO_WSTR
|
|||
|
_RWSTD_TEMPLATE
|
|||
|
struct _RWSTDExport rw_traits<wchar_t,_RW_STD::char_traits<wchar_t> >
|
|||
|
{
|
|||
|
static const wchar_t* find(const wchar_t* s, const wchar_t* v)
|
|||
|
#ifndef _HPACC_
|
|||
|
#if !defined(_RWSTD_NO_NEW_HEADER) && !defined(_RWSTD_NO_NAMESPACE)
|
|||
|
{ return std::wcsstr(s,v); }
|
|||
|
#else
|
|||
|
{ return wcsstr(s,v); }
|
|||
|
#endif
|
|||
|
#else
|
|||
|
// Having _HPACC_ defined sufficiently indicates both function name
|
|||
|
// and that said function is not in namespace std.
|
|||
|
{ return wcswcs(s,v); }
|
|||
|
#endif //_HPACC_
|
|||
|
static const wchar_t* rfind(const wchar_t* s, wchar_t v, size_t pos)
|
|||
|
{
|
|||
|
const wchar_t* p = s + pos;
|
|||
|
while (p >= s)
|
|||
|
{
|
|||
|
if (_RW_STD::char_traits<wchar_t>::eq(*p,v))
|
|||
|
return p;
|
|||
|
p--;
|
|||
|
}
|
|||
|
return NULL;
|
|||
|
}
|
|||
|
static size_t find_first_of(const wchar_t* s, const wchar_t* v)
|
|||
|
#if !defined(_RWSTD_NO_NEW_HEADER) && !defined(_RWSTD_NO_NAMESPACE) && !defined(_HPACC_)
|
|||
|
{ return std::wcscspn(s,v); }
|
|||
|
#else
|
|||
|
{ return wcscspn(s,v); }
|
|||
|
#endif
|
|||
|
static size_t find_first_not_of(const wchar_t* s, const wchar_t* v)
|
|||
|
#if !defined(_RWSTD_NO_NEW_HEADER) && !defined(_RWSTD_NO_NAMESPACE) && !defined(_HPACC_)
|
|||
|
{ return std::wcsspn(s,v); }
|
|||
|
#else
|
|||
|
{ return wcsspn(s,v); }
|
|||
|
#endif
|
|||
|
};
|
|||
|
#endif // _RWSTD_NO_WSTR
|
|||
|
|
|||
|
#ifndef _RWSTD_NO_NAMESPACE
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
#endif // __RW_TRAITS
|
|||
|
#pragma option pop
|
|||
|
#endif /* __TRAITS_H */
|