File: array_traits.html

package info (click to toggle)
boost 1.27.0-3
  • links: PTS
  • area: main
  • in suites: woody
  • size: 19,908 kB
  • ctags: 26,546
  • sloc: cpp: 122,225; ansic: 10,956; python: 4,412; sh: 855; yacc: 803; makefile: 257; perl: 165; lex: 90; csh: 6
file content (187 lines) | stat: -rw-r--r-- 8,574 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
<html>

<head>
<!!---------------------------------------------------------------------->
<!! Copyright (C) 1998 Dietmar Kuehl, Claas Solutions GmbH >
<!!>
<!! Permission to use, copy, modify, distribute and sell this >
<!! software for any purpose is hereby granted without fee, provided >
<!! that the above copyright notice appears in all copies and that >
<!! both that copyright notice and this permission notice appear in >
<!! supporting documentation. Dietmar Kuehl and Claas Solutions make no >
<!! representations about the suitability of this software for any >
<!! purpose. It is provided "as is" without express or implied warranty. >
<!!---------------------------------------------------------------------->
<title>array_traits.3</title>
<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
<meta name="ProgId" content="FrontPage.Editor.Document">
</head>

<body bgcolor="white" link="0000FF" vlink="800080">

<h1><img src="../../c++boost.gif" alt="c++boost.gif (8819 bytes)" align="center" width="277" height="86"><a href="../../boost/array_traits.hpp">array_traits.hpp</a></h1>
<h1>Abstract</h1>
Although STL somewhat supports built-in arrays, the standard library provides no
support for getting iterators to built-in arrays. While getting an iterator to
the beginning of an array is trivial, getting a past-the-end iterator is much
harder, if not impossible (at least portably). However, it is possible to get a
past-the-end iterator for statically sized built-in arrays. This component
provides functions for better support of built-in arrays.<a name="Synopsis">
<h1>Synopsis</h1>
</a>
<table border="0" cellspacing="0" cellpadding="0" cols="2">
  <tr>
    <td width="30" valign="TOP"></td>
    <td>
      <pre>
#include &quot;boost/array_traits.hpp&quot;

namespace boost
{
  template &lt;typename Container&gt;
    struct array_traits
    {
      typedef ... iterator;
      typedef ... size_type;

      static iterator  begin();
      static iterator  end();
      static size_type size();
    };

  template &lt;typename Container&gt;
    array_traits&lt;Container&gt;::iterator  begin(Container &amp;c);
  template &lt;typename Container&gt;
    array_traits&lt;Container&gt;::iterator  end(Container &amp;c);
  template &lt;typename Container&gt;
    array_traits&lt;Container&gt;::size_type size(Container &amp;c);

  template &lt;typename T, unsigned long sz&gt;
  char (&amp;sizer(T (&amp;)[sz]))[sz];
}
  </pre>
    </td>
</table>
<a name="Description">
<h1>Description</h1>
</a>The header <nobr><tt>boost/array_traits.hpp</tt></nobr> declares one
template class and a set of functions which can be used for better support of
statically sized built-in arrays. See the <a href="array-article.html">article</a>
about built-in arrays for a rationale why and under which constraints built-in
arrays are still useful (for most applications, container classes, whether from
the standard library, some third party, or self-written, are superior than
built-in arrays but there are a few exceptions to this rule).
<p>The template class <nobr><tt>array_traits</tt></nobr> is mainly an auxiliary
class used by the functions to get a consistent interface. It is specialized for
statically sized arrays and constant containers. The former does not explicitly
define an iterator type and the methods to access the beginning, the end, and
the size of this container is very different from the approach taken for STL
containers. It is necessary to specialize for constant containers because the
iterator type is a different one than for non-constant containers (<nobr><tt>const_iterator</tt></nobr>
instead of <nobr><tt>iterator</tt></nobr>).
<p>The functions <nobr><tt>begin()</tt></nobr>, <nobr><tt>end()</tt></nobr>, and
<nobr><tt>size()</tt></nobr> can be used to replace the corresponding container
member functions: For STL conformant containers, these functions simply call the
corresponding container member functions. However, for statically sized built-in
arrays, they behave different. In this case, <nobr><tt>begin()</tt></nobr>
simply returns a pointer to the array (the type passed to the function <nobr><tt>begin()</tt></nobr>
is <nobr><tt>T (&amp;)[size]</tt></nobr>, not <nobr><tt>T*</tt></nobr>), <nobr><tt>end()</tt></nobr>
converts the argument to a pointer and adds the size of the array, and <nobr><tt>size()</tt></nobr>
returns the size.
<p>Here is a sample program using these functions:
<p>&nbsp;
<table border="0" cellspacing="0" cellpadding="0" cols="2">
  <tr>
    <td width="30" valign="TOP"></td>
    <td>
      <pre>
#include &quot;boost/array_traits.hpp&quot;
#include &lt;vector&gt;
#include &lt;iostream&gt;
#include &lt;iterator&gt;
#include &lt;algorithm&gt;

int main()
{
  int              arr[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
  std::vector&lt;int&gt; vec(boost::begin(arr), boost::end(arr));

  std::ostream_iterator&lt;int&gt; oit(std::cout, &quot; &quot;);

  std::cout &lt;&lt; &quot;size:  &quot; &lt;&lt; boost::size(arr) &lt;&lt; &quot;\n&quot;;
  std::copy(boost::begin(arr), boost::end(arr), oit);
  std::cout &lt;&lt; &quot;\n&quot;;

  std::cout &lt;&lt; &quot;size:  &quot; &lt;&lt; boost::size(vec) &lt;&lt; &quot;\n&quot;;
  std::copy(boost::begin(vec), boost::end(vec), oit);
  std::cout &lt;&lt; &quot;\n&quot;;

  return 0;
}
    </pre>
    </td>
</table>
Note that this example uses absolutely identical code to print the array and the
vector. Using the same code is essential when writing templates. However, using <nobr><tt>end(array)</tt></nobr>
instead of either hardcoding the size of the array or using some macro is also
convenient in other contexts when a statically size array is used (using a macro
for this is as convenient as using the function <nobr><tt>end()</tt></nobr> but
it is not safe: the macro could be called on a pointer, too, yielding false
results).
<p>Actually, this example should use a template function which gets the
container as argument. This is not used because none of the compilers used to
test this code could compile it...<a name="Bugs">
<h1>Bugs</h1>
</a>Currently, this code needs (b)leading edge compilers. Thus, only few
compilers compile this code successfully. I was able to get the code working for
egcs-2.92.23 (that is, the snapshot from 1998-11-22) and EDG-2.39 but I needed
some extra code for both compilers to make it work. Although this code should
not be harmful to standard conforming compilers, it should be remove once it is
no longer necessary. The only other compiler I tested was MSVC++ 6.0 but this
failed with no hope to make things work... (this compiler already flagged errors
when only the array version of the three functions were used; I gave up before
coming around to test whether partial specialization needed for <nobr><tt>array_traits</tt></nobr>
works).
<p>The result of the <nobr><tt>size()</tt></nobr> function cannot be used as an
integral constant. This is the major flaw with this code. It is possible to
write a macro which is an integral constant... However, in a discussion in
comp.lang.c++.moderated a safe method for getting the size of an array as
integral constant was proposed. The basic idea is to use the <nobr><tt>sizeof</tt></nobr>
operator to a function returning a reference to an appropriately sized array of <nobr><tt>char</tt></nobr>s:
The result of the <nobr><tt>sizeof</tt></nobr> operator applied to this function
can be used as an integral constant. To do this, the function <nobr><tt>sizer()</tt></nobr>
is declared (it is not necessary to define this function since the argument to
the <nobr><tt>sizeof</tt></nobr> operator is never evaluated) is declared in <nobr><tt>boost/array_traits.hpp</tt></nobr>.
Here is an example:
<p>&nbsp;
<table border="0" cellspacing="0" cellpadding="0" cols="2">
  <tr>
    <td width="30" valign="TOP"></td>
    <td>
      <pre>
#include &quot;boost/array_traits.hpp&quot;
#include &lt;algorithm&gt;

int main()
{
  int source[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
  int destination[sizeof(boost::sizer(source))];

  std::copy(boost::begin(source), boost::end(source), boost::begin(destination));
}
    </pre>
    </td>
</table>
<a name="See Also">
<h1>See Also</h1>
</a><a href="array-article.html">array-article(3)</a>
<h1>History</h1>
<p>The header was previously named <code>array.hpp</code></p>
<hr>
Copyright  1998 <a href="http://www.claas-solutions.de/kuehl">Dietmar Khl</a>
(<a href="mailto:dietmar.kuehl@claas-solutions.de">dietmar.kuehl@claas-solutions.de</a>)<br>
<a href="http://www.claas-solutions.de/">Claas Solutions GmbH</a>

</body>

</html>