This is the mail archive of the libstdc++@gcc.gnu.org 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: Char_traits (part 2+)


> To summarize my interpretation of the Standard:
> 1.	21.1.1/1 is not a definition of template class char_traits<>. It is a 
> statement of requirements – just like numerous similar tables in the 
> Standard.
> 2.	21.1.1/2 requires a declaration of template class char_traits<>. It is 
> not a definition either. It is also all we get.
> 3.	21.1.3.1 and 21.1.3.2 provide complete definitions of the explicit 
> specializations template<> struct char_traits<char> and template<> struct 
> char_traits<wchar_t> respectively. This suggests that the absence of a 
> complete definition in (2) is deliberate.
> 4.	It is not possible to provide a generic implementation of char_traits 
> that meets the requirements of 21.1.1/1 without imposing additional 
> requirements on the character type that are not mandated by the Standard.

Right. It's also not possible to do useful partial specializations for
char_traits due to only one template parameter.

The consensus seems to be that failing to provide a definition for
char_traits<_CharT> is strictly conforming, although not all that
friendly to users.

> Given these points, I consider any definition of template struct 
> char_traits<> to be an implementation defined extension. Since an extension 
> can be and do whatever it wants, we could just draw the line there and let 
> it go at that.

See current sources....

> Nevertheless, I had problems with the original char_traits implementation 
> because they were incorrect for most cases, and because of what I call the 
> “like a duck” problem. This is: if it looks like a ‘character traits’ class, 
> and calls itself a ‘character traits’ class, and is provided by the 
> implementation, then reasonable users can be excused when they think it is a 
> ‘character traits’ class – and for getting annoyed when they discover that 
> it is not correct.

Right. Why should libstdc++ get in the way? Also, it's still not clear
to me that people would be able to specialize if the generic template is
defined before their specializations are declared.

> The changes address only part of this problem – now attempts to use 
> char_traits<MyChar> will compile, but not link unless the user provides the 
> definitions. First, the Standard is clear that adding explicit 
> specializations of templates for built-in types to namespace std results in 
> undefined behavior (17.4.3.1/1), so this doesn’t work for the expected 
> common cases. Additionally, the solution provides no useful functionality 
> for the user-defined types, so I do not see any point. In fact, it seems to 
> promise functionality that is NOT provided, so unless the requirement that 
> the users provide the function definitions is clearly spelled out somewhere, 
> I think it is actually more confusing than just going with only what the 
> Standard requires.

I guess I was thinking more of something like

typedef unsigned short unicode_type;
typedef unsigned char unsigned_type;

then doing

template<> struct std::char_traits<unicode_type>
{
// do the work
}

etc. Isn't this legal? Aren't these user-defined types, and thus allowed
to do the specialization of std::char_traits?

> (2) Let’s face it – the real issue is basic_string<>. Weirdo’s like me who 
> mess with clause 27 are rare and presumably should know what they are doing.

Given the number of bug reports in this area I suspect you'd be
surprised at the number of freaks doing this stuff. I certainly was.

> A.	Provide only what the Standard specifies without extensions. This has the 
> advantage that code will be more likely to be portable. It has the major 
> disadvantage that useful things like basic_string<unsigned char> will not 
> work.
> B.	Provide A plus implementation defined explicit specializations of the 
> other built-in character types. This is my preference. I think it is in 
> keeping with both the letter and the spirit of the Standard. It allows the 
> useful things like declaring a basic_string<unsigned char>, but prevents 
> accidental usage of more esoteric types.

Can "B" be provided as a generic skeletal stubs file that people fill in
for their own types (as above) instead of explicitly instantiated into
the libstdc++.so for all the builtin types? I'd like to do this, and
also provide a similar template (or stubs) for the locale bits that need
to be done in order to work with streams.

If so, I consider this mostly a documentation issue. Here's to patches
that address it!

I'm curious: I don't feel like you addressed the issue of _Traits
ambiguity in some of the locale facets (where _Traits is not a template
parameter, but _Chart and _Iter (which itself has a _Traits param) are.)
This came up in regards to your original email, where you used
MyCharType, instead of a std::char_traits<MyCharType> specialization.
What do you think about this?

Do you agree that analysis was correct? That was the big issue I had
with the second round of char_traits cleanup that I did, actually.

-benjamin


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