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