user-defined types and basic_string
Benjamin Kosnik
bkoz@redhat.com
Fri Aug 23 10:31:00 GMT 2002
Here's an example of how to do a portable, standards-conformant string
class with underlying type of unsigned short. This also works for
things like unsigned char. Comments welcome.
As Matt pointed out, doing the locale work is a bit tricky. I intend
to do that as well, but thought I'd post this first.
-benjamin
// 2002-08-22 Benjamin Kosnik <bkoz@redhat.com>
#include <string>
#include <locale>
// Assumes pass-by-value is ok, --> simple type, probably builtin.
// If this is not the case, don't have operator and have specific operators.
struct character
{
typedef unsigned short value_type;
value_type value;
explicit character(): value(value_type()) { }
character(const value_type ch): value(ch) { }
operator value_type() const { return this->value; }
};
// Provide std::char_traits specialization.
namespace std
{
template<>
struct char_traits<character>
{
typedef character char_type;
// NB: this type should be bigger than char_type, so as to
// properly hold EOF values in addition to the full range of
// char_type values.
typedef unsigned long int_type;
typedef streampos pos_type;
typedef streamoff off_type;
typedef mbstate_t state_type;
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)
{
for (size_t __i = 0; __i < __n; ++__i)
if (!eq(__s1[__i], __s2[__i]))
return lt(__s1[__i], __s2[__i]) ? -1 : 1;
return 0;
}
static size_t
length(const char_type* __s)
{
const char_type* __p = __s;
while (*__p) ++__p;
return (__p - __s);
}
static const char_type*
find(const char_type* __s, size_t __n, const char_type& __a)
{
for (const char_type* __p = __s; size_t(__p - __s) < __n; ++__p)
if (*__p == __a) return __p;
return 0;
}
static char_type*
move(char_type* __s1, const char_type* __s2, size_t __n)
{ return (char_type*) memmove(__s1, __s2, __n * sizeof(char_type)); }
static char_type*
copy(char_type* __s1, const char_type* __s2, size_t __n)
{ return (char_type*) memcpy(__s1, __s2, __n * sizeof(char_type)); }
static char_type*
assign(char_type* __s, size_t __n, char_type __a)
{
for (char_type* __p = __s; __p < __s + __n; ++__p)
assign(*__p, __a);
return __s;
}
static char_type
to_char_type(const int_type& __c)
{ return char_type(__c); }
static int_type
to_int_type(const char_type& __c) { return int_type(__c); }
static bool
eq_int_type(const int_type& __c1, const int_type& __c2)
{ return __c1 == __c2; }
static int_type
eof() { return static_cast<int_type>(-1); }
static int_type
not_eof(const int_type& __c)
{ return eq_int_type(__c, eof()) ? int_type(0) : __c; }
};
};
int main()
{
using namespace std;
typedef character char_type;
typedef character::value_type value_type;
typedef char_traits<char_type> traits_type;
bool test = true;
// 1 char_type <-> value_type conversions
value_type uc1 = 'c';
value_type uc2 = 'd';
char_type c1(uc1);
char_type c2(uc2);
test = c1 == uc1;
// 2 char_traits
test = traits_type::eq(c1, c2);
// 3 basic_string<char_type>
typedef basic_string<char_type> string_type;
string_type str;
str += char_type('b');
str += char_type('o');
str += char_type('r');
str += char_type('a');
str += char_type('c');
str += char_type('a');
str += char_type('y');
string_type::size_type len = str.size();
const char_type* arr = str.c_str();
return 0;
}
More information about the Libstdc++
mailing list