Benjamin Kosnik - user-defined types and basic_string (original) (raw)

This is the mail archive of the libstdc++@gcc.gnu.orgmailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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 #include

// 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 { 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 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 typedef basic_string 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; }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]