• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1[/
2 /  Copyright (c) 2001 Jaakko J�rvi
3 /
4 / Distributed under the Boost Software License, Version 1.0. (See
5 / accompanying file LICENSE_1_0.txt or copy at
6 / http://www.boost.org/LICENSE_1_0.txt)
7 /]
8
9[article Design decisions rationale
10  [quickbook 1.6]
11  [id design_decisions_rationale]
12  [copyright 2001 Jaakko J\u00E4rvi]
13  [license Distributed under the
14    [@http://boost.org/LICENSE_1_0.txt Boost Software License,
15      Version 1.0].
16  ]
17]
18
19[template simplesect[title]
20[block '''<simplesect><title>'''[title]'''</title>''']]
21
22[template endsimplesect[]
23[block '''</simplesect>''']]
24
25[section About namespaces]
26
27There was a discussion about whether tuples should be in a separate namespace
28or directly in the `boost` namespace. The common principle is that domain
29libraries (like /graph/, /python/) should be on a separate subnamespace, while
30utility like libraries directly in the boost namespace. Tuples are somewhere
31in between, as the tuple template is clearly a general utility, but the
32library introduces quite a lot of names in addition to just the tuple template.
33Tuples were originally under a subnamespace. As a result of the discussion,
34tuple definitions were moved directly under the `boost` namespace. As a result
35of a continued discussion, the subnamespace was reintroduced. The final (I
36truly hope so) solution is now to have all definitions in namespace
37`::boost::tuples`, and the most common names in the `::boost` namespace as well.
38This is accomplished with using declarations (suggested by Dave Abrahams):
39
40    namespace boost {
41      namespace tuples {
42          ...
43        // All library code
44          ...
45      }
46      using tuples::tuple;
47      using tuples::make_tuple;
48      using tuples::tie;
49      using tuples::get;
50    }
51
52With this arrangement, tuple creation with direct constructor calls,
53`make_tuple` or `tie` functions do not need the namespace qualifier. Further,
54all functions that manipulate tuples are found with Koenig-lookup. The only
55exceptions are the `get<N>` functions, which are always called with an
56explicitly qualified template argument, and thus Koenig-lookup does not apply.
57Therefore, `get` is lifted to `::boost` namespace with a using declaration.
58Hence, the interface for an application programmer is in practice under the
59namespace `::boost`.
60
61The other names, forming an interface for library writers (cons lists,
62metafunctions manipulating cons lists, ...) remain in the subnamespace
63`::boost::tuples`. Note, that the names `ignore`, `set_open`, `set_close` and
64`set_delimiter` are considered to be part of the application programmer's
65interface, but are still not under `boost` namespace. The reason being the
66danger for name clashes for these common names. Further, the usage of these
67features is probably not very frequent.
68
69[section For those who are really interested in namespaces]
70
71The subnamespace name /tuples/ raised some discussion. The rationale for not
72using the most natural name 'tuple' is to avoid having an identical name with
73the tuple template. Namespace names are, however, not generally in plural form
74in Boost libraries. First, no real trouble was reported for using the same
75name for a namespace and a class and we considered changing the name 'tuples'
76to 'tuple'. But we found some trouble after all. Both gcc and edg compilers
77reject using declarations where the namespace and class names are identical:
78
79    namespace boost {
80      namespace tuple {
81        ... tie(...);
82        class tuple;
83          ...
84      }
85      using tuple::tie; // ok
86      using tuple::tuple; // error
87        ...
88    }
89
90Note, however, that a corresponding using declaration in the global namespace
91seems to be ok:
92
93    using boost::tuple::tuple; // ok;
94
95[endsect]
96
97[endsect]
98
99[section The end mark of the cons list (`nil`, `null_type`, ...)]
100
101Tuples are internally represented as cons lists:
102
103    tuple<int, int>
104
105inherits from
106
107    cons<int, cons<int, null_type> >
108
109`null_type` is the end mark of the list. Original proposition was `nil`, but
110the name is used in MacOS, and might have caused problems, so `null_type` was
111chosen instead. Other names considered were /null_t/ and /unit/ (the empty
112tuple type in SML).
113
114Note that `null_type` is the internal representation of an empty tuple:
115`tuple<>` inherits from `null_type`.
116
117[endsect]
118
119[section Element indexing]
120
121Whether to use `0`- or `1`-based indexing was discussed more than thoroughly,
122and the following observations were made:
123
124* `0`-based indexing is 'the C++ way' and used with arrays etc.
125
126* `1`-based 'name like' indexing exists as well, eg. `bind1st`, `bind2nd`,
127  `pair::first`, etc.
128
129Tuple access with the syntax `get<N>(a)`, or `a.get<N>()` (where `a` is a
130tuple and `N` an index), was considered to be of the first category, hence,
131the index of the first element in a tuple is `0`.
132
133A suggestion to provide `1`-based 'name like' indexing with constants like
134`_1st`, `_2nd`, `_3rd`, ... was made. By suitably chosen constant types, this
135would allow alternative syntaxes:
136
137    a.get<0>() == a.get(_1st) == a[_1st] == a(_1st);
138
139We chose not to provide more than one indexing method for the following
140reasons:
141
142* `0`-based indexing might not please everyone, but once its fixed, it is less
143  confusing than having two different methods (would anyone want such
144  constants for arrays?).
145
146* Adding the other indexing scheme doesn't really provide anything new (like a
147  new feature) to the user of the library.
148
149* C++ variable and constant naming rules don't give many possibilities for
150  defining short and nice index constants (like `_1st`, ...). Let the binding
151  and lambda libraries use these for a better purpose.
152
153* The access syntax a[_1st] (or a(_1st)) is appealing, and almost made us add
154  the index constants after all. However, `0`-based subscripting is so deep in
155  C++, that we had a fear for confusion.
156
157* Such constants are easy to add.
158
159[endsect]
160
161[section Tuple comparison]
162
163The comparison operator implements lexicographical order. Other orderings were
164considered, mainly dominance /(a < b iff for each i a(i) < b(i))/. Our belief
165is, that lexicographical ordering, though not mathematically the most natural
166one, is the most frequently needed ordering in everyday programming.
167
168[endsect]
169
170[section Streaming]
171
172The characters specified with tuple stream manipulators are stored within the
173space allocated by `ios_base::xalloc`, which allocates storage for `long` type
174objects. `static_cast` is used in casting between `long` and the stream's
175character type. Streams that have character types not convertible back and
176forth to long thus fail to compile.
177
178This may be revisited at some point. The two possible solutions are:
179
180* Allow only plain `char` types as the tuple delimiters and use `widen` and
181  `narrow` to convert between the real character type of the stream. This
182  would always compile, but some calls to set manipulators might result in a
183  different character than expected (some default character).
184
185* Allocate enough space to hold the real character type of the stream. This
186  means memory for holding the delimiter characters must be allocated
187  separately, and that pointers to this memory are stored in the space
188  allocated with `ios_base::xalloc`. Any volunteers?
189
190[endsect]
191