This is the mail archive of the mailing 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]

Re: user-defined types and basic_string

Benjamin Kosnik <> writes:

| > |       // 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;
| > 
| > This makes the assumption that range(unsigned long) is a strict
| > superset of range(unsigned short).  If we were going to assume that,
| > why not just use "int" as int_type?
| Could do. (Unsigned int though if value_type == unsigned short, oui?)

With the assumption that sizeof(short) < sizeof (int), all unsigned
short values will be represented by int. And I would go for int
instead of unsigned int since int would be the natural type used in
the usual integral promotions.

| It seems int_type is one of the points where the generic templates start
| to fall down...


| > From your yesterday mail, I thought you were talking of a generic way
| > to define customization points of char_traits for users.
| > 
| > Actually, I'm not convinced that we should make a big deal about
| > defining a specialization for std::char_traits<>.  Defining such a
| > specialization just amonts to define a trait class in one's own
| > namespace, but then there is no need to wrap the fundamental types in
| > a struct.  Thoughts?
| I'm not quite sure I follow you. Can you give examples in C++? 

Here is a minimal list of things where the primary template
char_traits<> breaks down:

  (1) int_type
  (2) less-than comparaison
  (3) equality comparaison
  (4) conversion char_type -> int_type
  (5) conversion int_type -> char_type
  (6) end-of-file mark

(1) has to be supplied by users.  Suppose, it is given by

   namespace __gnu_cxx
      template<typename charT>
        struct __char_traits_int {
          typedef <user-supplied-type> type;

(2) and (3) may be supplied in various ways

   * either by std::less<> and std::equal_to<> (not really a solution)o
   * by function objects

     namespace __gnu_cxx
        template<typename charT>
          struct __char_traits_eq {
            bool operator()(charT a, charT b) const
            { return a == b };

       // similar for char_traits_lt<>

In the same way (4), (5) and (6) can be given by function objects.
Now, equipped with the above, one can give a general definition for 
char_traits<> without having to always define *every* member
function.  That will work for fundamental types as well as
user-defined types.

   template<typename _CharT>
     struct char_traits {

       typedef typename __gnu_cxx::__char_traits_int<_CharT>::type int_type;
       // ...

       lt(const _CharT& __a, const CharT& __b)
       { return __gnu_cxx::__char_traits_eq<_CharT>()(__a, __b); }
       // ...

-- Gaby

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