~ubuntu-branches/debian/sid/boost1.49/sid

« back to all changes in this revision

Viewing changes to libs/tuple/doc/design_decisions_rationale.html

  • Committer: Package Import Robot
  • Author(s): Steve M. Robbins
  • Date: 2012-02-26 00:31:44 UTC
  • Revision ID: package-import@ubuntu.com-20120226003144-eaytp12cbf6ubpms
Tags: upstream-1.49.0
ImportĀ upstreamĀ versionĀ 1.49.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
 
2
<html>
 
3
 
 
4
<title>Design decisions rationale for Boost Tuple Library</title>
 
5
 
 
6
<body bgcolor="#FFFFFF" text="#000000">
 
7
 
 
8
<IMG SRC="../../../boost.png" 
 
9
     ALT="C++ Boost" width="277" height="86">
 
10
 
 
11
<h1>Tuple Library : design decisions rationale</h1>
 
12
 
 
13
<h2>About namespaces</h2>
 
14
 
 
15
<p>
 
16
There was a discussion about whether tuples should be in a separate namespace or directly in the <code>boost</code> namespace.
 
17
The common principle is that domain libraries (like <i>graph</i>, <i>python</i>) should be on a separate
 
18
subnamespace, while utility like libraries directly in the <code>boost</code> namespace.
 
19
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. 
 
20
Tuples were originally under a subnamespace.
 
21
As a result of the discussion, tuple definitions were moved directly under the <code>boost</code> namespace.
 
22
As a result of a continued discussion, the subnamespace was reintroduced.
 
23
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. 
 
24
This is accomplished with using declarations (suggested by Dave Abrahams):</p>
 
25
<pre><code>namespace boost {
 
26
  namespace tuples {
 
27
      ...      
 
28
    // All library code
 
29
      ...
 
30
  }
 
31
  using tuples::tuple; 
 
32
  using tuples::make_tuple;
 
33
  using tuples::tie;
 
34
  using tuples::get;
 
35
}
 
36
</code></pre>
 
37
<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.
 
38
Further, all functions that manipulate tuples are found with Koenig-lookup.
 
39
The only exceptions are the <code>get&lt;N&gt;</code> functions, which are always called with an explicitly qualified template argument, and thus Koenig-lookup does not apply.
 
40
Therefore, get is lifted to <code>::boost</code> namespace with a using declaration.
 
41
Hence, the interface for an application programmer is in practice under the namespace <code>::boost</code>.
 
42
</p>
 
43
<p>
 
44
The other names, forming an interface for library writers (cons lists, metafunctions manipulating cons lists, ...) remain in the subnamespace <code>::boost::tuples</code>.
 
45
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. 
 
46
The reason being the danger for name clashes for these common names.
 
47
Further, the usage of these features is probably not very frequent.
 
48
</p>
 
49
 
 
50
<h4>For those who are really interested in namespaces</h4>
 
51
 
 
52
<p>
 
53
The subnamespace name <i>tuples</i> raised some discussion.
 
54
The rationale for not using the most natural name 'tuple' is to avoid having an identical name with the tuple template. 
 
55
Namespace names are, however, not generally in plural form in boost libraries. 
 
56
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'.
 
57
But we found some trouble after all.
 
58
Both gcc and edg compilers reject using declarations where the namespace and class names are identical:</p>
 
59
 
 
60
<pre><code>namespace boost {
 
61
  namespace tuple {
 
62
    ... tie(...);
 
63
    class tuple; 
 
64
&nbsp;     ...
 
65
  }
 
66
  using tuple::tie; // ok
 
67
  using tuple::tuple; // error
 
68
    ...
 
69
}
 
70
</code></pre>
 
71
 
 
72
<p>Note, however, that a corresponding using declaration in the global namespace seems to be ok:</p>
 
73
 
 
74
<pre><code>
 
75
using boost::tuple::tuple; // ok;
 
76
</code></pre>
 
77
 
 
78
 
 
79
<h2>The end mark of the cons list (nil, null_type, ...)</h2>
 
80
 
 
81
<p>
 
82
Tuples are internally represented as <code>cons</code> lists:
 
83
 
 
84
<pre><code>tuple&lt;int, int&gt;
 
85
</code></pre> 
 
86
<p>inherits from</p>
 
87
<pre><code>cons&lt;int, cons&lt;int, null_type&gt; &gt;
 
88
</code></pre>
 
89
 
 
90
<p>
 
91
<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.
 
92
Other names considered were <i>null_t</i> and <i>unit</i> (the empty tuple type in SML).</p>
 
93
<p>
 
94
Note that <code>null_type</code> is the internal representation of an empty tuple: <code>tuple&lt;&gt;</code> inherits from <code>null_type</code>.
 
95
</p>
 
96
 
 
97
<h2>Element indexing</h2>
 
98
 
 
99
<p>
 
100
Whether to use 0- or 1-based indexing was discussed more than thoroughly, and the following observations were made:</p>
 
101
 
 
102
<ul>
 
103
<li> 0-based indexing is 'the C++ way' and used with arrays etc.</li>
 
104
<li> 1-based 'name like' indexing exists as well, eg. <code>bind1st</code>, <code>bind2nd</code>, <code>pair::first</code>, etc.</li>
 
105
</ul>
 
106
<p>Tuple access with the syntax <code>get&lt;N&gt;(a)</code>, or <code>a.get&lt;N&gt;()</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>
 
107
 
 
108
<p>
 
109
A suggestion to provide 1-based 'name like' indexing with constants like <code>_1st</code>, <code>_2nd</code>, <code>_3rd</code>, ... was made.
 
110
By suitably chosen constant types, this would allow alternative syntaxes:
 
111
 
 
112
<pre><code>a.get&lt;0&gt;() == a.get(_1st) == a[_1st] == a(_1st);
 
113
</code></pre>
 
114
 
 
115
<p>We chose not to provide more than one indexing method for the following reasons:</p>
 
116
<ul>
 
117
<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>
 
118
<li>Adding the other indexing scheme doesn't really provide anything new (like a new feature) to the user of the library.</li>
 
119
<li>C++ variable and constant naming rules don't give many possibilities for defining short and nice index constants (like <code>_1st</code>, ...). 
 
120
Let the binding and lambda libraries use these for a better purpose.</li>
 
121
<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>
 
122
<li>
 
123
Such constants are easy to add.
 
124
</li>
 
125
</ul>
 
126
 
 
127
 
 
128
<h2>Tuple comparison</h2>
 
129
 
 
130
<p>The comparison operator implements lexicographical order. 
 
131
Other orderings were considered, mainly dominance (<i>a &lt; b iff for each i a(i) &lt; b(i)</i>). 
 
132
Our belief is, that lexicographical ordering, though not mathematically the most natural one, is the most frequently needed ordering in everyday programming.</p>
 
133
 
 
134
<h2>Streaming</h2>
 
135
 
 
136
<p>
 
137
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.
 
138
<code>static_cast</code> is used in casting between <code>long</code> and the stream's character type. 
 
139
Streams that have character types not convertible back and forth to long thus fail to compile.</p>
 
140
 
 
141
<p>This may be revisited at some point. The two possible solutions are:</p>
 
142
<ul>
 
143
<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. 
 
144
This would always compile, but some calls to set manipulators might result in a different
 
145
  character than expected (some default character).</li>
 
146
<li>Allocate enough space to hold the real character type of the stream. 
 
147
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>.
 
148
Any volunteers?</li>
 
149
</ul>
 
150
 
 
151
<A href="tuple_users_guide.html">Back to the user's guide</A>
 
152
<hr><p>&copy; Copyright Jaakko J&auml;rvi 2001. 
 
153
</body>
 
154
</html>
 
155