This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
Re: c++0x vs. tr1 type_traits, round 1
On Thu, 2007-04-26 at 17:14 +0200, Benjamin Kosnik wrote:
> > Therefore I would ask you to go ahead with something straighforward, as
> > we discussed above: set-up a separate implementation of type_traits for
> > C++0x by copying the current TR1 one, adjusting the names of those 4
> > traits discussed between yesterday and today, adding the new traits.
>
> Yeah, well.... this doesn't work.
>
> :(
[snip]
> This is striking me more and more as the wrong path. Maybe
> _GLIBCXX_SUPPRESS_TR1 is the way to go after all...
So, let's step back a bit.
TR1 and C++0x have a lot of code in common, so we don't want to maintain
two completely different copies of essentially the same source code.
Now, TR1 has some things that C++0x does not, and C++0x has some things
that TR1 does not, so we need some level of customization for each
library variant. There are two important aspects to this customization:
(1) both variants can occur in the same translation unit, and therefore
must be separated somehow; and (2) this customization has very little to
do with the source language that the compiler is processing, e.g., TR1
bind can use rvalue references if we're in C++0x mode, but not when
we're in C++98 mode.
I think (1) precludes the use of namespace association for sharing code
(because the variants must be distinct) and (2) precludes any scheme
that involves customizing tr1/headers via __GXX_EXPERIMENTAL_CXX0X__.
One solution is to move all of the common code into a separate place,
e.g., include/tr1_impl/type_traits. It would then be included in
different ways from include/std/type_traits and
include/tr1/type_traits.
include/tr1_impl/type_traits might look like this:
namespace std
{
_GLIBCXX_TR1_NAMESPACE_BEGIN
// Bits common to C++0x and TR1
// Where necessary, use _GLIBCXX_INCLUDE_AS_CXX0X or
// _GLIBCXX_INCLUDE_AS_TR1 to handle variations
_GLIBCXX_TR1_NAMESPACE_END
}
Then, include/std/type_traits would look like this:
#if defined(_GLIBCXX_INCLUDE_AS_TR1)
# error C++0x header cannot be included from TR1 header
#endif
#ifndef _GLIBCXX_CXX0X_TYPE_TRAITS_H
#define _GLIBCXX_CXX0X_TYPE_TRAITS_H 1
#if defined(_GLIBCXX_INCLUDE_AS_CXX0X)
# include <tr1_impl/type_traits>
#else
# define _GLIBCXX_INCLUDE_AS_CXX0X
# define _GLIBCXX_TR1_NAMESPACE_BEGIN
# define _GLIBCXX_TR1_NAMESPACE_END
# include <tr1_impl/type_traits>
# undef _GLIBCXX_TR1_NAMESPACE_END
# undef _GLIBCXX_TR1_NAMESPACE_BEGIN
# undef _GLIBCXX_INCLUDE_AS_CXX0X
#endif
namespace std
{
// C++0x-specific bits
}
#endif // _GLIBCXX_CXX0X_TYPE_TRAITS_H
Finally, include/tr1/type_traits would be:
#if defined(_GLIBCXX_INCLUDE_AS_CXX0X)
# error TR1 header cannot be included from C++0x header
#endif
#ifndef _GLIBCXX_TR1_TYPE_TRAITS_H
#define _GLIBCXX_TR1_TYPE_TRAITS_H 1
#if defined(_GLIBCXX_INCLUDE_AS_TR1)
# include <tr1_impl/type_traits>
#else
# define _GLIBCXX_INCLUDE_AS_TR1
# define _GLIBCXX_TR1_NAMESPACE_BEGIN namespace tr1 {
# define _GLIBCXX_TR1_NAMESPACE_END }
# include <tr1_impl/type_traits>
# undef _GLIBCXX_TR1_NAMESPACE_END
# undef _GLIBCXX_TR1_NAMESPACE_BEGIN
# undef _GLIBCXX_INCLUDE_AS_TR1
#endif
namespace std
{
namespace tr1
{
// TR1-specific bits
}
}
#endif // _GLIBCXX_TR1_TYPE_TRAITS_H
Now, this does mean that headers in tr1_impl won't really be able to
include other headers without doing the dance Benjamin was talking
about:
// in include/tr1_impl/functional:
#if defined(_GLIBCXX_INCLUDE_AS_CXX0X)
# include <type_traits>
#else
# include <tr1/type_traits>
#endif
In this case (perhaps in all cases?) we could just put the includes
needed by include/tr1_impl/functional into include/std/functional and
include/tr1/functional. If the tr1_impl headers don't include anything,
it becomes easier to avoid C++0x/TR1 collisions.
Does this approach seem reasonable? It feels like a sledgehammer, but at
this point I think that nothing short of this sledgehammer---or
completely separating the TR1 implementation from the C++0x
implementation---will do.
- Doug
- References:
- c++0x vs. tr1 type_traits, round 1
- Re: c++0x vs. tr1 type_traits, round 1
- Re: c++0x vs. tr1 type_traits, round 1
- Re: c++0x vs. tr1 type_traits, round 1
- Re: c++0x vs. tr1 type_traits, round 1
- Re: c++0x vs. tr1 type_traits, round 1
- Re: c++0x vs. tr1 type_traits, round 1
- Re: c++0x vs. tr1 type_traits, round 1
- Re: c++0x vs. tr1 type_traits, round 1
- Re: c++0x vs. tr1 type_traits, round 1