forked from boostorg/tuple
156 lines
7.6 KiB
HTML
156 lines
7.6 KiB
HTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
|
<html>
|
|
|
|
<title>Design decisions rationale for Boost Tuple Library</title>
|
|
|
|
<body bgcolor="#FFFFFF" text="#000000">
|
|
|
|
<IMG SRC="../../../boost.png"
|
|
ALT="C++ Boost" width="277" height="86">
|
|
|
|
<h1>Tuple Library : design decisions rationale</h1>
|
|
|
|
<h2>About namespaces</h2>
|
|
|
|
<p>
|
|
There was a discussion about whether tuples should be in a separate namespace or directly in the <code>boost</code> namespace.
|
|
The common principle is that domain libraries (like <i>graph</i>, <i>python</i>) should be on a separate
|
|
subnamespace, while utility like libraries directly in the <code>boost</code> namespace.
|
|
Tuples are somewhere in between, as the tuple template is clearly a general utility, but the library introduces quite a lot of names in addition to just the tuple template.
|
|
Tuples were originally under a subnamespace.
|
|
As a result of the discussion, tuple definitions were moved directly under the <code>boost</code> namespace.
|
|
As a result of a continued discussion, the subnamespace was reintroduced.
|
|
The final (I truly hope so) solution is now to have all definitions in namespace <code>::boost::tuples</code>, and the most common names in the <code>::boost</code> namespace as well.
|
|
This is accomplished with using declarations (suggested by Dave Abrahams):</p>
|
|
<pre><code>namespace boost {
|
|
namespace tuples {
|
|
...
|
|
// All library code
|
|
...
|
|
}
|
|
using tuples::tuple;
|
|
using tuples::make_tuple;
|
|
using tuples::tie;
|
|
using tuples::get;
|
|
}
|
|
</code></pre>
|
|
<p>With this arrangement, tuple creation with direct constructor calls, <code>make_tuple</code> or <code>tie</code> functions do not need the namespace qualifier.
|
|
Further, all functions that manipulate tuples are found with Koenig-lookup.
|
|
The only exceptions are the <code>get<N></code> functions, which are always called with an explicitly qualified template argument, and thus Koenig-lookup does not apply.
|
|
Therefore, get is lifted to <code>::boost</code> namespace with a using declaration.
|
|
Hence, the interface for an application programmer is in practice under the namespace <code>::boost</code>.
|
|
</p>
|
|
<p>
|
|
The other names, forming an interface for library writers (cons lists, metafunctions manipulating cons lists, ...) remain in the subnamespace <code>::boost::tuples</code>.
|
|
Note, that the names <code>ignore</code>, <code>set_open</code>, <code>set_close</code> and <code>set_delimiter</code> are considered to be part of the application programmer's interface, but are still not under <code>boost</code> namespace.
|
|
The reason being the danger for name clashes for these common names.
|
|
Further, the usage of these features is probably not very frequent.
|
|
</p>
|
|
|
|
<h4>For those who are really interested in namespaces</h4>
|
|
|
|
<p>
|
|
The subnamespace name <i>tuples</i> raised some discussion.
|
|
The rationale for not using the most natural name 'tuple' is to avoid having an identical name with the tuple template.
|
|
Namespace names are, however, not generally in plural form in boost libraries.
|
|
First, no real trouble was reported for using the same name for a namespace and a class and we considered changing the name 'tuples' to 'tuple'.
|
|
But we found some trouble after all.
|
|
Both gcc and edg compilers reject using declarations where the namespace and class names are identical:</p>
|
|
|
|
<pre><code>namespace boost {
|
|
namespace tuple {
|
|
... tie(...);
|
|
class tuple;
|
|
...
|
|
}
|
|
using tuple::tie; // ok
|
|
using tuple::tuple; // error
|
|
...
|
|
}
|
|
</code></pre>
|
|
|
|
<p>Note, however, that a corresponding using declaration in the global namespace seems to be ok:</p>
|
|
|
|
<pre><code>
|
|
using boost::tuple::tuple; // ok;
|
|
</code></pre>
|
|
|
|
|
|
<h2>The end mark of the cons list (nil, null_type, ...)</h2>
|
|
|
|
<p>
|
|
Tuples are internally represented as <code>cons</code> lists:
|
|
|
|
<pre><code>tuple<int, int>
|
|
</code></pre>
|
|
<p>inherits from</p>
|
|
<pre><code>cons<int, cons<int, null_type> >
|
|
</code></pre>
|
|
|
|
<p>
|
|
<code>null_type</code> is the end mark of the list. Original proposition was <code>nil</code>, but the name is used in MacOS, and might have caused problems, so <code>null_type</code> was chosen instead.
|
|
Other names considered were <i>null_t</i> and <i>unit</i> (the empty tuple type in SML).</p>
|
|
<p>
|
|
Note that <code>null_type</code> is the internal representation of an empty tuple: <code>tuple<></code> inherits from <code>null_type</code>.
|
|
</p>
|
|
|
|
<h2>Element indexing</h2>
|
|
|
|
<p>
|
|
Whether to use 0- or 1-based indexing was discussed more than thoroughly, and the following observations were made:</p>
|
|
|
|
<ul>
|
|
<li> 0-based indexing is 'the C++ way' and used with arrays etc.</li>
|
|
<li> 1-based 'name like' indexing exists as well, eg. <code>bind1st</code>, <code>bind2nd</code>, <code>pair::first</code>, etc.</li>
|
|
</ul>
|
|
<p>Tuple access with the syntax <code>get<N>(a)</code>, or <code>a.get<N>()</code> (where <code>a</code> is a tuple and <code>N</code> an index), was considered to be of the first category, hence, the index of the first element in a tuple is 0.</p>
|
|
|
|
<p>
|
|
A suggestion to provide 1-based 'name like' indexing with constants like <code>_1st</code>, <code>_2nd</code>, <code>_3rd</code>, ... was made.
|
|
By suitably chosen constant types, this would allow alternative syntaxes:
|
|
|
|
<pre><code>a.get<0>() == a.get(_1st) == a[_1st] == a(_1st);
|
|
</code></pre>
|
|
|
|
<p>We chose not to provide more than one indexing method for the following reasons:</p>
|
|
<ul>
|
|
<li>0-based indexing might not please everyone, but once its fixed, it is less confusing than having two different methods (would anyone want such constants for arrays?).</li>
|
|
<li>Adding the other indexing scheme doesn't really provide anything new (like a new feature) to the user of the library.</li>
|
|
<li>C++ variable and constant naming rules don't give many possibilities for defining short and nice index constants (like <code>_1st</code>, ...).
|
|
Let the binding and lambda libraries use these for a better purpose.</li>
|
|
<li>The access syntax <code>a[_1st]</code> (or <code>a(_1st)</code>) is appealing, and almost made us add the index constants after all. However, 0-based subscripting is so deep in C++, that we had a fear for confusion.</li>
|
|
<li>
|
|
Such constants are easy to add.
|
|
</li>
|
|
</ul>
|
|
|
|
|
|
<h2>Tuple comparison</h2>
|
|
|
|
<p>The comparison operator implements lexicographical order.
|
|
Other orderings were considered, mainly dominance (<i>a < b iff for each i a(i) < b(i)</i>).
|
|
Our belief is, that lexicographical ordering, though not mathematically the most natural one, is the most frequently needed ordering in everyday programming.</p>
|
|
|
|
<h2>Streaming</h2>
|
|
|
|
<p>
|
|
The characters specified with tuple stream manipulators are stored within the space allocated by <code>ios_base::xalloc</code>, which allocates storage for <code>long</code> type objects.
|
|
<code>static_cast</code> is used in casting between <code>long</code> and the stream's character type.
|
|
Streams that have character types not convertible back and forth to long thus fail to compile.</p>
|
|
|
|
<p>This may be revisited at some point. The two possible solutions are:</p>
|
|
<ul>
|
|
<li>Allow only plain <code>char</code> types as the tuple delimiters and use <code>widen</code> and <code>narrow</code> to convert between the real character type of the stream.
|
|
This would always compile, but some calls to set manipulators might result in a different
|
|
character than expected (some default character).</li>
|
|
<li>Allocate enough space to hold the real character type of the stream.
|
|
This means memory for holding the delimiter characters must be allocated separately, and that pointers to this memory are stored in the space allocated with <code>ios_base::xalloc</code>.
|
|
Any volunteers?</li>
|
|
</ul>
|
|
|
|
<A href="tuple_users_guide.html">Back to the user's guide</A>
|
|
<hr><p>© Copyright Jaakko Järvi 2001.
|
|
</body>
|
|
</html>
|
|
|