• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1<html>
2<head>
3<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
4<title>Method 2: provide free-standing functions and specialize metafunctions</title>
5<link rel="stylesheet" href="../../../../../../../doc/src/boostbook.css" type="text/css">
6<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
7<link rel="home" href="../../../index.html" title="Chapter 1. Range 2.0">
8<link rel="up" href="../extending.html" title="Extending the library">
9<link rel="prev" href="method_1.html" title="Method 1: provide member functions and nested types">
10<link rel="next" href="method_3.html" title="Method 3: provide range adaptor implementations">
11</head>
12<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
13<table cellpadding="2" width="100%"><tr>
14<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../boost.png"></td>
15<td align="center"><a href="../../../../../../../index.html">Home</a></td>
16<td align="center"><a href="../../../../../../../libs/libraries.htm">Libraries</a></td>
17<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
18<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
19<td align="center"><a href="../../../../../../../more/index.htm">More</a></td>
20</tr></table>
21<hr>
22<div class="spirit-nav">
23<a accesskey="p" href="method_1.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../extending.html"><img src="../../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="method_3.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a>
24</div>
25<div class="section">
26<div class="titlepage"><div><div><h4 class="title">
27<a name="range.reference.extending.method_2"></a><a class="link" href="method_2.html" title="Method 2: provide free-standing functions and specialize metafunctions">Method 2: provide
28        free-standing functions and specialize metafunctions</a>
29</h4></div></div></div>
30<p>
31          This procedure assumes that you cannot (or do not wish to) change the types
32          that should be made conformant to a Range concept. If this is not true,
33          see <a class="link" href="method_1.html" title="Method 1: provide member functions and nested types">method 1</a>.
34        </p>
35<p>
36          The primary templates in this library are implemented such that certain
37          functions are found via argument-dependent-lookup (ADL). Below is given
38          an overview of which free-standing functions a class must specify to be
39          useable as a certain Range concept. Let <code class="computeroutput"><span class="identifier">x</span></code>
40          be a variable (<code class="computeroutput"><span class="keyword">const</span></code> or <code class="computeroutput"><span class="keyword">mutable</span></code>) of the class in question.
41        </p>
42<div class="informaltable"><table class="table">
43<colgroup>
44<col>
45<col>
46</colgroup>
47<thead><tr>
48<th>
49                  <p>
50                    Function
51                  </p>
52                </th>
53<th>
54                  <p>
55                    Related concept
56                  </p>
57                </th>
58</tr></thead>
59<tbody>
60<tr>
61<td>
62                  <p>
63                    <code class="computeroutput"><span class="identifier">range_begin</span><span class="special">(</span><span class="identifier">x</span><span class="special">)</span></code>
64                  </p>
65                </td>
66<td>
67                  <p>
68                    <a class="link" href="../../concepts/single_pass_range.html" title="Single Pass Range">Single Pass
69                    Range</a>
70                  </p>
71                </td>
72</tr>
73<tr>
74<td>
75                  <p>
76                    <code class="computeroutput"><span class="identifier">range_end</span><span class="special">(</span><span class="identifier">x</span><span class="special">)</span></code>
77                  </p>
78                </td>
79<td>
80                  <p>
81                    <a class="link" href="../../concepts/single_pass_range.html" title="Single Pass Range">Single Pass
82                    Range</a>
83                  </p>
84                </td>
85</tr>
86<tr>
87<td>
88                  <p>
89                    <code class="computeroutput"><span class="identifier">range_calculate_size</span><span class="special">(</span><span class="identifier">x</span><span class="special">)</span></code>
90                  </p>
91                </td>
92<td>
93                  <p>
94                    Optional. This can be used to specify a mechanism for constant-time
95                    computation of the size of a range. The default behaviour is
96                    to return <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">end</span><span class="special">(</span><span class="identifier">x</span><span class="special">)</span> <span class="special">-</span>
97                    <span class="identifier">boost</span><span class="special">::</span><span class="identifier">begin</span><span class="special">(</span><span class="identifier">x</span><span class="special">)</span></code>
98                    for random access ranges, and to return <code class="computeroutput"><span class="identifier">x</span><span class="special">.</span><span class="identifier">size</span><span class="special">()</span></code> for ranges with lesser traversal
99                    capability. This behaviour can be changed by implementing <code class="computeroutput"><span class="identifier">range_calculate_size</span></code> in a manner
100                    that will be found via ADL. The ability to calculate size in
101                    O(1) is often possible even with ranges with traversal categories
102                    less than random access.
103                  </p>
104                </td>
105</tr>
106</tbody>
107</table></div>
108<p>
109          <code class="computeroutput"><span class="identifier">range_begin</span><span class="special">()</span></code>
110          and <code class="computeroutput"><span class="identifier">range_end</span><span class="special">()</span></code>
111          must be overloaded for both <code class="computeroutput"><span class="keyword">const</span></code>
112          and <code class="computeroutput"><span class="keyword">mutable</span></code> reference arguments.
113        </p>
114<p>
115          You must also specialize two metafunctions for your type <code class="computeroutput"><span class="identifier">X</span></code>:
116        </p>
117<div class="informaltable"><table class="table">
118<colgroup>
119<col>
120<col>
121</colgroup>
122<thead><tr>
123<th>
124                  <p>
125                    Metafunction
126                  </p>
127                </th>
128<th>
129                  <p>
130                    Related concept
131                  </p>
132                </th>
133</tr></thead>
134<tbody>
135<tr>
136<td>
137                  <p>
138                    <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">range_mutable_iterator</span></code>
139                  </p>
140                </td>
141<td>
142                  <p>
143                    <a class="link" href="../../concepts/single_pass_range.html" title="Single Pass Range">Single Pass
144                    Range</a>
145                  </p>
146                </td>
147</tr>
148<tr>
149<td>
150                  <p>
151                    <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">range_const_iterator</span></code>
152                  </p>
153                </td>
154<td>
155                  <p>
156                    <a class="link" href="../../concepts/single_pass_range.html" title="Single Pass Range">Single Pass
157                    Range</a>
158                  </p>
159                </td>
160</tr>
161</tbody>
162</table></div>
163<p>
164          A complete example is given here:
165        </p>
166<p>
167</p>
168<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">range</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
169<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">iterator</span><span class="special">&gt;</span>         <span class="comment">// for std::iterator_traits, std::distance()</span>
170
171<span class="keyword">namespace</span> <span class="identifier">Foo</span>
172<span class="special">{</span>
173    <span class="comment">//</span>
174    <span class="comment">// Our sample UDT. A 'Pair'</span>
175    <span class="comment">// will work as a range when the stored</span>
176    <span class="comment">// elements are iterators.</span>
177    <span class="comment">//</span>
178    <span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">class</span> <span class="identifier">T</span> <span class="special">&gt;</span>
179    <span class="keyword">struct</span> <span class="identifier">Pair</span>
180    <span class="special">{</span>
181        <span class="identifier">T</span> <span class="identifier">first</span><span class="special">,</span> <span class="identifier">last</span><span class="special">;</span>
182    <span class="special">};</span>
183
184<span class="special">}</span> <span class="comment">// namespace 'Foo'</span>
185
186<span class="keyword">namespace</span> <span class="identifier">boost</span>
187<span class="special">{</span>
188    <span class="comment">//</span>
189    <span class="comment">// Specialize metafunctions. We must include the range.hpp header.</span>
190    <span class="comment">// We must open the 'boost' namespace.</span>
191    <span class="comment">//</span>
192
193	<span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">class</span> <span class="identifier">T</span> <span class="special">&gt;</span>
194	<span class="keyword">struct</span> <span class="identifier">range_mutable_iterator</span><span class="special">&lt;</span> <span class="identifier">Foo</span><span class="special">::</span><span class="identifier">Pair</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="special">&gt;</span>
195	<span class="special">{</span>
196		<span class="keyword">typedef</span> <span class="identifier">T</span> <span class="identifier">type</span><span class="special">;</span>
197	<span class="special">};</span>
198
199	<span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">class</span> <span class="identifier">T</span> <span class="special">&gt;</span>
200	<span class="keyword">struct</span> <span class="identifier">range_const_iterator</span><span class="special">&lt;</span> <span class="identifier">Foo</span><span class="special">::</span><span class="identifier">Pair</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="special">&gt;</span>
201	<span class="special">{</span>
202		<span class="comment">//</span>
203		<span class="comment">// Remark: this is defined similar to 'range_iterator'</span>
204		<span class="comment">//         because the 'Pair' type does not distinguish</span>
205		<span class="comment">//         between an iterator and a const_iterator.</span>
206		<span class="comment">//</span>
207		<span class="keyword">typedef</span> <span class="identifier">T</span> <span class="identifier">type</span><span class="special">;</span>
208	<span class="special">};</span>
209
210<span class="special">}</span> <span class="comment">// namespace 'boost'</span>
211
212<span class="keyword">namespace</span> <span class="identifier">Foo</span>
213<span class="special">{</span>
214	<span class="comment">//</span>
215	<span class="comment">// The required functions. These should be defined in</span>
216	<span class="comment">// the same namespace as 'Pair', in this case</span>
217	<span class="comment">// in namespace 'Foo'.</span>
218	<span class="comment">//</span>
219
220	<span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">class</span> <span class="identifier">T</span> <span class="special">&gt;</span>
221	<span class="keyword">inline</span> <span class="identifier">T</span> <span class="identifier">range_begin</span><span class="special">(</span> <span class="identifier">Pair</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;&amp;</span> <span class="identifier">x</span> <span class="special">)</span>
222	<span class="special">{</span>
223		<span class="keyword">return</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">first</span><span class="special">;</span>
224	<span class="special">}</span>
225
226	<span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">class</span> <span class="identifier">T</span> <span class="special">&gt;</span>
227	<span class="keyword">inline</span> <span class="identifier">T</span> <span class="identifier">range_begin</span><span class="special">(</span> <span class="keyword">const</span> <span class="identifier">Pair</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;&amp;</span> <span class="identifier">x</span> <span class="special">)</span>
228	<span class="special">{</span>
229		<span class="keyword">return</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">first</span><span class="special">;</span>
230	<span class="special">}</span>
231
232	<span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">class</span> <span class="identifier">T</span> <span class="special">&gt;</span>
233	<span class="keyword">inline</span> <span class="identifier">T</span> <span class="identifier">range_end</span><span class="special">(</span> <span class="identifier">Pair</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;&amp;</span> <span class="identifier">x</span> <span class="special">)</span>
234	<span class="special">{</span>
235		<span class="keyword">return</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">last</span><span class="special">;</span>
236	<span class="special">}</span>
237
238	<span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">class</span> <span class="identifier">T</span> <span class="special">&gt;</span>
239	<span class="keyword">inline</span> <span class="identifier">T</span> <span class="identifier">range_end</span><span class="special">(</span> <span class="keyword">const</span> <span class="identifier">Pair</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;&amp;</span> <span class="identifier">x</span> <span class="special">)</span>
240	<span class="special">{</span>
241		<span class="keyword">return</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">last</span><span class="special">;</span>
242	<span class="special">}</span>
243
244<span class="special">}</span> <span class="comment">// namespace 'Foo'</span>
245
246<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">vector</span><span class="special">&gt;</span>
247
248<span class="keyword">int</span> <span class="identifier">main</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">argc</span><span class="special">,</span> <span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">argv</span><span class="special">[])</span>
249<span class="special">{</span>
250	<span class="keyword">typedef</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;::</span><span class="identifier">iterator</span>  <span class="identifier">iter</span><span class="special">;</span>
251	<span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span>                    <span class="identifier">vec</span><span class="special">;</span>
252	<span class="identifier">Foo</span><span class="special">::</span><span class="identifier">Pair</span><span class="special">&lt;</span><span class="identifier">iter</span><span class="special">&gt;</span>                     <span class="identifier">pair</span> <span class="special">=</span> <span class="special">{</span> <span class="identifier">vec</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">vec</span><span class="special">.</span><span class="identifier">end</span><span class="special">()</span> <span class="special">};</span>
253	<span class="keyword">const</span> <span class="identifier">Foo</span><span class="special">::</span><span class="identifier">Pair</span><span class="special">&lt;</span><span class="identifier">iter</span><span class="special">&gt;&amp;</span>              <span class="identifier">cpair</span> <span class="special">=</span> <span class="identifier">pair</span><span class="special">;</span>
254	<span class="comment">//</span>
255	<span class="comment">// Notice that we call 'begin' etc with qualification.</span>
256	<span class="comment">//</span>
257	<span class="identifier">iter</span> <span class="identifier">i</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">begin</span><span class="special">(</span> <span class="identifier">pair</span> <span class="special">);</span>
258	<span class="identifier">iter</span> <span class="identifier">e</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">end</span><span class="special">(</span> <span class="identifier">pair</span> <span class="special">);</span>
259	<span class="identifier">i</span>      <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">begin</span><span class="special">(</span> <span class="identifier">cpair</span> <span class="special">);</span>
260	<span class="identifier">e</span>      <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">end</span><span class="special">(</span> <span class="identifier">cpair</span> <span class="special">);</span>
261	<span class="identifier">boost</span><span class="special">::</span><span class="identifier">range_difference</span><span class="special">&lt;</span> <span class="identifier">Foo</span><span class="special">::</span><span class="identifier">Pair</span><span class="special">&lt;</span><span class="identifier">iter</span><span class="special">&gt;</span> <span class="special">&gt;::</span><span class="identifier">type</span> <span class="identifier">s</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">size</span><span class="special">(</span> <span class="identifier">pair</span> <span class="special">);</span>
262	<span class="identifier">s</span>      <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">size</span><span class="special">(</span> <span class="identifier">cpair</span> <span class="special">);</span>
263	<span class="identifier">boost</span><span class="special">::</span><span class="identifier">range_reverse_iterator</span><span class="special">&lt;</span> <span class="keyword">const</span> <span class="identifier">Foo</span><span class="special">::</span><span class="identifier">Pair</span><span class="special">&lt;</span><span class="identifier">iter</span><span class="special">&gt;</span> <span class="special">&gt;::</span><span class="identifier">type</span>
264	<span class="identifier">ri</span>     <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">rbegin</span><span class="special">(</span> <span class="identifier">cpair</span> <span class="special">),</span>
265	<span class="identifier">re</span>     <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">rend</span><span class="special">(</span> <span class="identifier">cpair</span> <span class="special">);</span>
266
267	<span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
268<span class="special">}</span>
269</pre>
270<p>
271        </p>
272</div>
273<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
274<td align="left"></td>
275<td align="right"><div class="copyright-footer">Copyright © 2003-2010 Thorsten Ottosen,
276      Neil Groves<p>
277        Distributed under the Boost Software License, Version 1.0. (See accompanying
278        file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
279      </p>
280</div></td>
281</tr></table>
282<hr>
283<div class="spirit-nav">
284<a accesskey="p" href="method_1.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../extending.html"><img src="../../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="method_3.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a>
285</div>
286</body>
287</html>
288