<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
	<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html;charset=iso-8859-1">
	<TITLE>Versioning with Namespaces</TITLE>
	<STYLE>
	<!--
		@page { size: 8.5in 11in }
	-->
	</STYLE>
</HEAD>

<P ALIGN=LEFT>
Document number: J16/06-0083 = WG21 N2013<BR>
Date: 2006-04-19<BR>
Author: Benjamin Kosnik &lt;bkoz@redhat.com&gt; <BR>
Evolution Working Group, Modules and Linkage<BR>

<BODY LANG="en-US" DIR="LTR">
<H2 ALIGN=CENTER>Versioning with Namespaces</H2>

<P><BR><BR>
</P>

<H3>Introduction.</H3>
<p> Elegant transitions between components of the C++ standard as it
evolves are possible without too much work. This paper will outline an
approach using an extension to namespace using directives, and a
careful arrangement of nested namespaces within namespace std. A
careful arrangement is composed by partitioning namespace std into a
collection of nested namespaces named after a specific revision of the
standard, and then placing specific types within one of the unique
nested namespace partitions. The end result is a flexible solution
with options for both binary and source compatibility.
</p>

<p>This was initially presented to the modules working group during the
April, 2006 meeting in Berlin. Ideas for alternate syntax are inspired
by that discussion.
</p>

<H3>Language additions.</H3>
<p> The usual language rules with respect to namespaces are not
sufficient to allow the designs described below. A short study of the
relevant issues can be found in Herb Sutter's paper N1344=02-0002.
</p>

<p>
Therefore, a capability similar to the extension designated "namespace
association" is assumed, and is described by N1526=03-0109. In
addition, a further restriction on this extension is imposed, making
it only applicable to nested namespaces.
</p>

<p> To recap, this extension does the following:
</p>

<p>
     (1) At any time, in a given translation unit, one wants to pretend
	 that a set of names that are defined in a namespace N, are
	 also members of a namespace M, for all purpose but linkage
         (i.e. name mangling).
</p>

<p>
     (2) Furthermore, one wants to retain usual lookup rules, in
	 particular argument dependent lookup, member definition rules,
	 etc.  
</p>

<p> In addition, the syntax is slightly changed for the purpose of
clarity. Instead of logical operators, the keyword "case" is re-used
in combination with the usual namespace directive syntax to identify
an explicit namespace association.
</p>

<pre>
namespace std 
{
  namespace _1998
  {
    template&lt;typename T&gt;
      struct A { };
  }
  using namespace case _1998; // associate _1998 with std

  template&lt;&gt;
    struct A&lt;int&gt; { };  // ok to specialize
}

std::A&lt;float&gt; obj; // ok, fully qualified as std::_1998::A<float>
</pre>

<p> Also, the predefined macro __STDCXX_VERSION__, similar to
__STDC_VERSION__ from ISO C99, is used to distinguish between the
original C++ standard (ISO 14482, referred to as C++98) and a future
standard (referred to as C++0x). This is only one possible mechanism:
the exact mechanism can be left as an implementation detail.
</p>


<H3>Library implementation for source compatibility.</H3>

<p> The following arrangement provides seamless source compatibility,
but changes the actual definitions of elements from C++98 and C++0x to nest
within namespace std as in the following (incomplete) example:
</p>

<pre>
namespace std
{
  namespace _1998
  {
    template&lt;typename _Tp&gt;
      class allocator { };

    template&lt;typename _CharT, typename _Traits, typename _Alloc&gt;
      class basic_string { };
  } 

  namespace _2008
  {
    template&lt;typename _Tp&gt;
      class reference_wrapper { };
  }

#if __STDCXX_VERSION__ >= 199801L
  using namespace case _1998;
#endif

#if __STDCXX_VERSION__ >= 200801L
  using namespace case _2008;
#endif
}
</pre>

<p> This arrangement presumes that types stay compatible, and are not
substantially revised in subsequent versions of the standard. For
instance, it's assumed that std::basic_string would refer to
std::_1998::basic_string only, and similarly for
std::_2008::reference_wrapper and the like.
</p>

<p> If types don't stay compatible between different versions of the
standard, an approach like the above can still be used, but more work
will need to be done. One approach would be to further partition the
nested namespace into compatible and incompatible partitions, and then
only associate the compatible namespace.
</p>

<p> Although this would break binary compatibility, this type of
design is preferred. The added flexibility of allowing incompatible
designs, and the consistent partitioning and placement of all types
would allow older (flawed) elements to be gradually deprecated,
without throwing out all the other elements from that version of the
standard. Throw out the dirty bathwater, but keep the baby.
</p>

<H3>Library implementation for source and binary compatibility.</H3>

<p> The following arrangement provides seamless source and binary
compatibility.
</p>

<pre>
namespace std
{
  template&lt;typename _Tp&gt;
    class allocator { };
  
  template&lt;typename _CharT, typename _Traits, typename _Alloc&gt;
    class basic_string { };

  namespace _2008
  {
    template&lt;typename _Tp&gt;
      class reference_wrapper { };
  }

#if __STDCXX_VERSION__ >= 200801L
  using namespace case _2008;
#endif
}
</pre>

<p> This arrangement allows mangling that is equivalent to that
specified as part of C++98, and presumes that C++0x does not make
changes in C++98 types. If incompatible changes are desired in C++0x,
then the previous design can be used.
</p>


<H3>Implementation notes.</H3>

<p> For the last two years or more, both EDG and GNU compilers
implement the language extension for namespace association, first
presented in Technical Report N1526=03-0109. The syntax used is based
on GNU attribute syntax, and looks like:
</p>

<pre>
using namespace _1998 __attribute__ ((strong));
</pre>

<p>
instead of:
</p>

<pre>
using namespace case _1998;
</pre>

<p> This extension has evolved as usage discovered problems. In
particular, this extension has changed to only be applicable to nested
namespaces.
</p>

<p> In addition, the GNU C++ library (libstdc++) has been modified to
implement versioning much like the designs discussed, and is currently
being tested in experimental linux distributions. Previous to the
modification to support versioning, the language extension was also
used to implement an extended debug version of the library, with
checked iterators and other "safe" STL concepts.
</p>


<H3>References.</H3>
<P>Benjamin Kosnik, Proposal to add namespace references to C++,
Technical Report N1526=03-0109, September 18, 2002.
</P>

<P>Jason Merrill, 6.8 Namespace Association, GCC Manual.
http://gcc.gnu.org/onlinedocs/gcc/Namespace-Association.html#Namespace-Association
</P>

<P>Herb Sutter, Namespaces and Library Versioning, Technical Report
N1344=02-0002, March 1, 2002.
</P>


</BODY>
</HTML>
