C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

combining template and non-template iostream

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
John Dill
Guest





PostPosted: Mon Jan 26, 2004 8:27 pm    Post subject: combining template and non-template iostream Reply with quote



I am trying to figure out a way to use one interface for my streams,
but at the same time maintain backwards compatibility. The latest
iostream has a templated version, while the previous ones were not.
How can I combine std::streambuf, and std::basic_streambuf<CharT,
Traits> into one interface? I really want to keep the template
version if I can, but don't know how difficult it would be.

I can't imagine that anyone would use anything other than streambuf,
and the wide character version from the old library. I believe I can
wrap the functionality by doing some template specialization on the
char type and the traits type from basic_streambuf into the old
library std::streambuf and std::wstreambuf counterpart. I am open to
other suggestions.

Thanks,
John

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Samuel Krempp
Guest





PostPosted: Wed Jan 28, 2004 1:37 pm    Post subject: Re: combining template and non-template iostream Reply with quote



le Monday 26 January 2004 21:27, [email]john-dill (AT) uiowa (DOT) edu[/email] écrivit :
Quote:
I can't imagine that anyone would use anything other than streambuf,
and the wide character version from the old library. I believe I can
wrap the functionality by doing some template specialization on the
char type and the traits type from basic_streambuf into the old
library std::streambuf and std::wstreambuf counterpart. I am open to
other suggestions.

I face a similar situation, trying to have my code compile with gcc-2.95.
Wrapping the old lib's non-template std::ostream inside a
template<class Ch, class Tr> basic_ostream;
can help make the code work with the old stream without needing dozens of
#ifndef everywhere
(placing it inside std:: is the easiest, though it is not really allowed by
the standard. but it should probably not cause any trouble - and working
around broken stdlibs is already not in the realm of the standard anyhow)

but then users will need to use these wrappers explicitly (rather than the
native ostream, like "std::cout") since the functions you'll define will
take/return std::basic_ostream<Ch, Tr> 's and std::ostream won't be one of
them (and using implicit conversion wouldnt help for some situations).

I'm investigating using template classes emulating typedef templates to
point to the right stream/char_traits type (so you can put the workaround
code somewhere inside a #ifndef and have the rest of the code be ok)
The big picture of my scheme is :

// for Foo being ostream, char_traits, allocator, streambuf ..
// and other stdlib classes which you have to emulate on
// some of the platforms

template<class T>
class CompatFoo;

#ifdef __GNUC__ < bla bla
#include "workaround_gcc2.95.hpp"
// specialise CompatFoo, point to the equivalent for stdlib
// with close approximations (and approximate names)
// like gcc-2.95's string_char_traits
// or wrap around, or completely redefine..
#ifndef


// **** CompatFoo general definitions :
template class CompatFoo
// general case : just point to the right stuff
public:
typedef Foo platform_type;
typedef Foo std_compatible_type;
};


the workaround can specialize the template as needed (on char / wchar or
whatever) so that
1. platform_type will be the type the user will be handling (eg
std::ostream) like :
template<class Ch, class Tr>
typename CompatOstream<Ch, Tr>::platform_type& operator<<(
typename CompatOstream const OneOfTheAPIClasses & rhs);

which, with proper specialization of the CompatOStream helper, will be found
in invocations like :
std::cout << OneOfTheAPIClasses( ..) ;
even when std::cout is not a std::basic_ostream<..> type.

2. std_compatible_type is for your own use, it will be a wrapper around the
platform_type in which you can add all the stdlib functions you want to be
able to call without needing a #ifndef, practically emulating the expected
stdlib class, so you can write the code targetting the good compiler
rather than being limited all the time by the bad one.

I'm not completely happy with this general concept, the code bloat is non
neglectible, it requires the compiler to support template partial
specialization and proper resolution of calls.. but it's still better than
#ifdefing everything.
In a near future, I'll simply require a sufficiently standard-conforming
stdlib and be done with it..

--
Samuel.Krempp
cout << "@" << "crans." << (is_spam ? "trucs.en.trop." : "" )
<< "ens-cachan.fr" << endl;


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
kanze@gabi-soft.fr
Guest





PostPosted: Thu Jan 29, 2004 6:47 pm    Post subject: Re: combining template and non-template iostream Reply with quote



Samuel Krempp <krempp (AT) crans (DOT) ens-cachan.fr> wrote

Quote:
le Monday 26 January 2004 21:27, [email]john-dill (AT) uiowa (DOT) edu[/email] écrivit :
I can't imagine that anyone would use anything other than
streambuf, and the wide character version from the old library. I
believe I can wrap the functionality by doing some template
specialization on the char type and the traits type from
basic_streambuf into the old library std::streambuf and
std::wstreambuf counterpart. I am open to other suggestions.

I face a similar situation, trying to have my code compile with gcc-2.95.
Wrapping the old lib's non-template std::ostream inside a
template<class Ch, class Tr> basic_ostream;
can help make the code work with the old stream without needing dozens of
#ifndef everywhere
(placing it inside std:: is the easiest, though it is not really allowed by
the standard. but it should probably not cause any trouble - and working
around broken stdlibs is already not in the realm of the standard anyhow)

I'm not sure what the original problem was, but I don't see what problem
your solution solves. If it is one of portability between systems, some
of which support only the old library, and others only the new one
(shame on them), then it is fairly simple to set up a few system
dependant header files with the necessary includes (<iostream.h> vs
<iostream>, <ostream>, etc.) and a few #define's (IOSTD as either std or
nothing, etc.). No point in introducing an obfuscating template.

If the problem is that the compiler supports both, you have some
libraries using one, and others using the other, and you cannot change
the libraries, there is no real solution. You need to support both, and
how you do so will depend on what files the libraries use, etc.
Wrapping the old library in a template with the same name as the new one
just creates violations of the ODR.

--
James Kanze GABI Software mailto:kanze (AT) gabi-soft (DOT) fr
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Samuel Krempp
Guest





PostPosted: Sat Jan 31, 2004 10:51 am    Post subject: Re: combining template and non-template iostream Reply with quote

le Thursday 29 January 2004 19:47, [email]kanze (AT) gabi-soft (DOT) fr[/email] écrivit :
Quote:
I'm not sure what the original problem was, but I don't see what problem
your solution solves. If it is one of portability between systems, some

my problem is writing code aiming for the newer stdlibs, while supporting
the old system as much as possible. I think it's the OP's propblem too, but
I may be mistaken.

Quote:
of which support only the old library, and others only the new one
(shame on them), then it is fairly simple to set up a few system
dependant header files with the necessary includes (<iostream.h> vs
iostream>, <ostream>, etc.) and a few #define's (IOSTD as either std or
nothing, etc.). No point in introducing an obfuscating template.

well, that's all very easy if you plan to support *one* stream class.
you do the dirty things in one header resulting in a typedef, and you're all
set, the other files just use this type.
But for a library, the goal is to work along the stldib's streams or strings
for any template parameters <Ch, Tr, Alloc>. (and only with std::ostream in
case the compiler doesnt have template streams)
With the macro way you'll end up with macros everywhere in all your files.
So I prefer having a template-typedef-emulation kept inside a header file
(and used in the other files) than have dozens of #ifndef lines in all my
files. This system can be flexible enough to use an existing type of the
broken stdlib and augment it with some functions it lacks, and then the
rest of the code can be written with std-conformant classes in mind. That's
what my post was about.

--
Samuel.Krempp
cout << "@" << "crans." << (is_spam ? "trucs.en.trop." : "" )
<< "ens-cachan.fr" << endl;


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
kanze@gabi-soft.fr
Guest





PostPosted: Mon Feb 02, 2004 5:47 pm    Post subject: Re: combining template and non-template iostream Reply with quote

Samuel Krempp <krempp (AT) crans (DOT) ens-cachan.fr> wrote

Quote:
le Thursday 29 January 2004 19:47, [email]kanze (AT) gabi-soft (DOT) fr[/email] écrivit :
I'm not sure what the original problem was, but I don't see what
problem your solution solves. If it is one of portability between
systems, some

my problem is writing code aiming for the newer stdlibs, while
supporting the old system as much as possible. I think it's the OP's
propblem too, but I may be mistaken.

OK. IMHO, that doesn't make much sense, EXCEPT for one very special
context.

Quote:
of which support only the old library, and others only the new one
(shame on them), then it is fairly simple to set up a few system
dependant header files with the necessary includes (<iostream.h> vs
iostream>, <ostream>, etc.) and a few #define's (IOSTD as either
std or nothing, etc.). No point in introducing an obfuscating
template.

well, that's all very easy if you plan to support *one* stream class.
you do the dirty things in one header resulting in a typedef, and
you're all set, the other files just use this type.
But for a library,

That's the special context, I think. I'm an applications programmer, so
I'm not too familiar with all of the constraints, but I can imagine that
if you are developing a third party library, you can expect to have
customers who want it to work with the standard iostreams, AND be fully
templated, and other customers who can't use the new iostreams (because
they are using older compilers, or whatever).

Quote:
From a pratical point of view, you'd probably cover 99.9% of the use by
just providing versions for stream and wstream -- instantiating the

templates for anything else is more work than just writing your streams
from scratch. From a marketing point of view, however, I don't think it
very viable.

Quote:
the goal is to work along the stldib's streams or strings for any
template parameters <Ch, Tr, Alloc>. (and only with std::ostream in
case the compiler doesnt have template streams) With the macro way
you'll end up with macros everywhere in all your files.

From the rest of your explication, I presume you mean
"#if/#ifdef/#ifndef on macros every in all your files." I don't have

too much objection to using a macro instead of a function to mask some
system dependancies. Say using a macro in a derived streambuf to handle
code translation: when using the classic iostream's, you define the
macro to be empty, and when using the new, it invokes whatever is
necessary to use the imbued locale.

Quote:
So I prefer having a template-typedef-emulation kept inside a header
file (and used in the other files) than have dozens of #ifndef lines
in all my files.

I prefer just about anything to #ifdef's. And #ifdef in function body
are simply forbidden, period. So I definitly agree with you.

Quote:
This system can be flexible enough to use an existing type of the
broken stdlib and augment it with some functions it lacks, and then
the rest of the code can be written with std-conformant classes in
mind. That's what my post was about.

OK. Good luck (to the both of you).

--
James Kanze GABI Software mailto:kanze (AT) gabi-soft (DOT) fr
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Allan W
Guest





PostPosted: Fri Feb 06, 2004 8:47 pm    Post subject: Re: combining template and non-template iostream Reply with quote

[email]john-dill (AT) uiowa (DOT) edu[/email] (John Dill) wrote
Quote:
I am trying to figure out a way to use one interface for my streams,
but at the same time maintain backwards compatibility.

If you're already handling multiple basic_streambuf types, then you're
already using templates. I haven't tried this, but it seems to me that
you could just get less specific in your types.

Turn:
template<class CharT, class Traits>
std::basic_stream<CharT,Traits>
operator <<(std::basic_stream { return out<
template std::basic_stream<CharT,Traits>
operator >>(std::basic_stream<CharT,Traits>in, const MyClass&m)
{ return in>>whatever; }

Into:
template<class Stream>
Stream operator <<(Stream out, const MyClass&m)
{ return out<
template Stream operator >>(Stream in, const MyClass&m)
{ return in>>whatever; }

Unless I'm missing the point (and that's certainly possible), this should
work with either pre-standard or standard streams, and even wide-character
streams.

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.