Chris@16
|
1 // (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000.
|
Chris@16
|
2 // Use, modification and distribution are subject to the Boost Software License,
|
Chris@16
|
3 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
Chris@16
|
4 // http://www.boost.org/LICENSE_1_0.txt).
|
Chris@16
|
5 //
|
Chris@16
|
6 // See http://www.boost.org/libs/utility for most recent version including documentation.
|
Chris@16
|
7 // see libs/utility/compressed_pair.hpp
|
Chris@16
|
8 //
|
Chris@16
|
9 /* Release notes:
|
Chris@16
|
10 20 Jan 2001:
|
Chris@16
|
11 Fixed obvious bugs (David Abrahams)
|
Chris@16
|
12 07 Oct 2000:
|
Chris@16
|
13 Added better single argument constructor support.
|
Chris@16
|
14 03 Oct 2000:
|
Chris@16
|
15 Added VC6 support (JM).
|
Chris@16
|
16 23rd July 2000:
|
Chris@16
|
17 Additional comments added. (JM)
|
Chris@16
|
18 Jan 2000:
|
Chris@16
|
19 Original version: this version crippled for use with crippled compilers
|
Chris@16
|
20 - John Maddock Jan 2000.
|
Chris@16
|
21 */
|
Chris@16
|
22
|
Chris@16
|
23
|
Chris@16
|
24 #ifndef BOOST_OB_COMPRESSED_PAIR_HPP
|
Chris@16
|
25 #define BOOST_OB_COMPRESSED_PAIR_HPP
|
Chris@16
|
26
|
Chris@16
|
27 #include <algorithm>
|
Chris@16
|
28 #ifndef BOOST_OBJECT_TYPE_TRAITS_HPP
|
Chris@16
|
29 #include <boost/type_traits/object_traits.hpp>
|
Chris@16
|
30 #endif
|
Chris@16
|
31 #ifndef BOOST_SAME_TRAITS_HPP
|
Chris@16
|
32 #include <boost/type_traits/same_traits.hpp>
|
Chris@16
|
33 #endif
|
Chris@16
|
34 #ifndef BOOST_CALL_TRAITS_HPP
|
Chris@16
|
35 #include <boost/call_traits.hpp>
|
Chris@16
|
36 #endif
|
Chris@16
|
37
|
Chris@16
|
38 namespace boost
|
Chris@16
|
39 {
|
Chris@16
|
40 #ifdef BOOST_MSVC6_MEMBER_TEMPLATES
|
Chris@16
|
41 //
|
Chris@16
|
42 // use member templates to emulate
|
Chris@16
|
43 // partial specialisation. Note that due to
|
Chris@16
|
44 // problems with overload resolution with VC6
|
Chris@16
|
45 // each of the compressed_pair versions that follow
|
Chris@16
|
46 // have one template single-argument constructor
|
Chris@16
|
47 // in place of two specific constructors:
|
Chris@16
|
48 //
|
Chris@16
|
49
|
Chris@16
|
50 template <class T1, class T2>
|
Chris@16
|
51 class compressed_pair;
|
Chris@16
|
52
|
Chris@16
|
53 namespace detail{
|
Chris@16
|
54
|
Chris@16
|
55 template <class A, class T1, class T2>
|
Chris@16
|
56 struct best_conversion_traits
|
Chris@16
|
57 {
|
Chris@16
|
58 typedef char one;
|
Chris@16
|
59 typedef char (&two)[2];
|
Chris@16
|
60 static A a;
|
Chris@16
|
61 static one test(T1);
|
Chris@16
|
62 static two test(T2);
|
Chris@16
|
63
|
Chris@16
|
64 enum { value = sizeof(test(a)) };
|
Chris@16
|
65 };
|
Chris@16
|
66
|
Chris@16
|
67 template <int>
|
Chris@16
|
68 struct init_one;
|
Chris@16
|
69
|
Chris@16
|
70 template <>
|
Chris@16
|
71 struct init_one<1>
|
Chris@16
|
72 {
|
Chris@16
|
73 template <class A, class T1, class T2>
|
Chris@16
|
74 static void init(const A& a, T1* p1, T2*)
|
Chris@16
|
75 {
|
Chris@16
|
76 *p1 = a;
|
Chris@16
|
77 }
|
Chris@16
|
78 };
|
Chris@16
|
79
|
Chris@16
|
80 template <>
|
Chris@16
|
81 struct init_one<2>
|
Chris@16
|
82 {
|
Chris@16
|
83 template <class A, class T1, class T2>
|
Chris@16
|
84 static void init(const A& a, T1*, T2* p2)
|
Chris@16
|
85 {
|
Chris@16
|
86 *p2 = a;
|
Chris@16
|
87 }
|
Chris@16
|
88 };
|
Chris@16
|
89
|
Chris@16
|
90
|
Chris@16
|
91 // T1 != T2, both non-empty
|
Chris@16
|
92 template <class T1, class T2>
|
Chris@16
|
93 class compressed_pair_0
|
Chris@16
|
94 {
|
Chris@16
|
95 private:
|
Chris@16
|
96 T1 _first;
|
Chris@16
|
97 T2 _second;
|
Chris@16
|
98 public:
|
Chris@16
|
99 typedef T1 first_type;
|
Chris@16
|
100 typedef T2 second_type;
|
Chris@16
|
101 typedef typename call_traits<first_type>::param_type first_param_type;
|
Chris@16
|
102 typedef typename call_traits<second_type>::param_type second_param_type;
|
Chris@16
|
103 typedef typename call_traits<first_type>::reference first_reference;
|
Chris@16
|
104 typedef typename call_traits<second_type>::reference second_reference;
|
Chris@16
|
105 typedef typename call_traits<first_type>::const_reference first_const_reference;
|
Chris@16
|
106 typedef typename call_traits<second_type>::const_reference second_const_reference;
|
Chris@16
|
107
|
Chris@16
|
108 compressed_pair_0() : _first(), _second() {}
|
Chris@16
|
109 compressed_pair_0(first_param_type x, second_param_type y) : _first(x), _second(y) {}
|
Chris@16
|
110 template <class A>
|
Chris@16
|
111 explicit compressed_pair_0(const A& val)
|
Chris@16
|
112 {
|
Chris@16
|
113 init_one<best_conversion_traits<A, T1, T2>::value>::init(val, &_first, &_second);
|
Chris@16
|
114 }
|
Chris@16
|
115 compressed_pair_0(const ::boost::compressed_pair<T1,T2>& x)
|
Chris@16
|
116 : _first(x.first()), _second(x.second()) {}
|
Chris@16
|
117
|
Chris@16
|
118 #if 0
|
Chris@16
|
119 compressed_pair_0& operator=(const compressed_pair_0& x) {
|
Chris@16
|
120 cout << "assigning compressed pair 0" << endl;
|
Chris@16
|
121 _first = x._first;
|
Chris@16
|
122 _second = x._second;
|
Chris@16
|
123 cout << "finished assigning compressed pair 0" << endl;
|
Chris@16
|
124 return *this;
|
Chris@16
|
125 }
|
Chris@16
|
126 #endif
|
Chris@16
|
127
|
Chris@16
|
128 first_reference first() { return _first; }
|
Chris@16
|
129 first_const_reference first() const { return _first; }
|
Chris@16
|
130
|
Chris@16
|
131 second_reference second() { return _second; }
|
Chris@16
|
132 second_const_reference second() const { return _second; }
|
Chris@16
|
133
|
Chris@16
|
134 void swap(compressed_pair_0& y)
|
Chris@16
|
135 {
|
Chris@16
|
136 using std::swap;
|
Chris@16
|
137 swap(_first, y._first);
|
Chris@16
|
138 swap(_second, y._second);
|
Chris@16
|
139 }
|
Chris@16
|
140 };
|
Chris@16
|
141
|
Chris@16
|
142 // T1 != T2, T2 empty
|
Chris@16
|
143 template <class T1, class T2>
|
Chris@16
|
144 class compressed_pair_1 : T2
|
Chris@16
|
145 {
|
Chris@16
|
146 private:
|
Chris@16
|
147 T1 _first;
|
Chris@16
|
148 public:
|
Chris@16
|
149 typedef T1 first_type;
|
Chris@16
|
150 typedef T2 second_type;
|
Chris@16
|
151 typedef typename call_traits<first_type>::param_type first_param_type;
|
Chris@16
|
152 typedef typename call_traits<second_type>::param_type second_param_type;
|
Chris@16
|
153 typedef typename call_traits<first_type>::reference first_reference;
|
Chris@16
|
154 typedef typename call_traits<second_type>::reference second_reference;
|
Chris@16
|
155 typedef typename call_traits<first_type>::const_reference first_const_reference;
|
Chris@16
|
156 typedef typename call_traits<second_type>::const_reference second_const_reference;
|
Chris@16
|
157
|
Chris@16
|
158 compressed_pair_1() : T2(), _first() {}
|
Chris@16
|
159 compressed_pair_1(first_param_type x, second_param_type y) : T2(y), _first(x) {}
|
Chris@16
|
160
|
Chris@16
|
161 template <class A>
|
Chris@16
|
162 explicit compressed_pair_1(const A& val)
|
Chris@16
|
163 {
|
Chris@16
|
164 init_one<best_conversion_traits<A, T1, T2>::value>::init(val, &_first, static_cast<T2*>(this));
|
Chris@16
|
165 }
|
Chris@16
|
166
|
Chris@16
|
167 compressed_pair_1(const ::boost::compressed_pair<T1,T2>& x)
|
Chris@16
|
168 : T2(x.second()), _first(x.first()) {}
|
Chris@16
|
169
|
Chris@16
|
170 first_reference first() { return _first; }
|
Chris@16
|
171 first_const_reference first() const { return _first; }
|
Chris@16
|
172
|
Chris@16
|
173 second_reference second() { return *this; }
|
Chris@16
|
174 second_const_reference second() const { return *this; }
|
Chris@16
|
175
|
Chris@16
|
176 void swap(compressed_pair_1& y)
|
Chris@16
|
177 {
|
Chris@16
|
178 // no need to swap empty base class:
|
Chris@16
|
179 using std::swap;
|
Chris@16
|
180 swap(_first, y._first);
|
Chris@16
|
181 }
|
Chris@16
|
182 };
|
Chris@16
|
183
|
Chris@16
|
184 // T1 != T2, T1 empty
|
Chris@16
|
185 template <class T1, class T2>
|
Chris@16
|
186 class compressed_pair_2 : T1
|
Chris@16
|
187 {
|
Chris@16
|
188 private:
|
Chris@16
|
189 T2 _second;
|
Chris@16
|
190 public:
|
Chris@16
|
191 typedef T1 first_type;
|
Chris@16
|
192 typedef T2 second_type;
|
Chris@16
|
193 typedef typename call_traits<first_type>::param_type first_param_type;
|
Chris@16
|
194 typedef typename call_traits<second_type>::param_type second_param_type;
|
Chris@16
|
195 typedef typename call_traits<first_type>::reference first_reference;
|
Chris@16
|
196 typedef typename call_traits<second_type>::reference second_reference;
|
Chris@16
|
197 typedef typename call_traits<first_type>::const_reference first_const_reference;
|
Chris@16
|
198 typedef typename call_traits<second_type>::const_reference second_const_reference;
|
Chris@16
|
199
|
Chris@16
|
200 compressed_pair_2() : T1(), _second() {}
|
Chris@16
|
201 compressed_pair_2(first_param_type x, second_param_type y) : T1(x), _second(y) {}
|
Chris@16
|
202 template <class A>
|
Chris@16
|
203 explicit compressed_pair_2(const A& val)
|
Chris@16
|
204 {
|
Chris@16
|
205 init_one<best_conversion_traits<A, T1, T2>::value>::init(val, static_cast<T1*>(this), &_second);
|
Chris@16
|
206 }
|
Chris@16
|
207 compressed_pair_2(const ::boost::compressed_pair<T1,T2>& x)
|
Chris@16
|
208 : T1(x.first()), _second(x.second()) {}
|
Chris@16
|
209
|
Chris@16
|
210 #if 0
|
Chris@16
|
211 compressed_pair_2& operator=(const compressed_pair_2& x) {
|
Chris@16
|
212 cout << "assigning compressed pair 2" << endl;
|
Chris@16
|
213 T1::operator=(x);
|
Chris@16
|
214 _second = x._second;
|
Chris@16
|
215 cout << "finished assigning compressed pair 2" << endl;
|
Chris@16
|
216 return *this;
|
Chris@16
|
217 }
|
Chris@16
|
218 #endif
|
Chris@16
|
219 first_reference first() { return *this; }
|
Chris@16
|
220 first_const_reference first() const { return *this; }
|
Chris@16
|
221
|
Chris@16
|
222 second_reference second() { return _second; }
|
Chris@16
|
223 second_const_reference second() const { return _second; }
|
Chris@16
|
224
|
Chris@16
|
225 void swap(compressed_pair_2& y)
|
Chris@16
|
226 {
|
Chris@16
|
227 // no need to swap empty base class:
|
Chris@16
|
228 using std::swap;
|
Chris@16
|
229 swap(_second, y._second);
|
Chris@16
|
230 }
|
Chris@16
|
231 };
|
Chris@16
|
232
|
Chris@16
|
233 // T1 != T2, both empty
|
Chris@16
|
234 template <class T1, class T2>
|
Chris@16
|
235 class compressed_pair_3 : T1, T2
|
Chris@16
|
236 {
|
Chris@16
|
237 public:
|
Chris@16
|
238 typedef T1 first_type;
|
Chris@16
|
239 typedef T2 second_type;
|
Chris@16
|
240 typedef typename call_traits<first_type>::param_type first_param_type;
|
Chris@16
|
241 typedef typename call_traits<second_type>::param_type second_param_type;
|
Chris@16
|
242 typedef typename call_traits<first_type>::reference first_reference;
|
Chris@16
|
243 typedef typename call_traits<second_type>::reference second_reference;
|
Chris@16
|
244 typedef typename call_traits<first_type>::const_reference first_const_reference;
|
Chris@16
|
245 typedef typename call_traits<second_type>::const_reference second_const_reference;
|
Chris@16
|
246
|
Chris@16
|
247 compressed_pair_3() : T1(), T2() {}
|
Chris@16
|
248 compressed_pair_3(first_param_type x, second_param_type y) : T1(x), T2(y) {}
|
Chris@16
|
249 template <class A>
|
Chris@16
|
250 explicit compressed_pair_3(const A& val)
|
Chris@16
|
251 {
|
Chris@16
|
252 init_one<best_conversion_traits<A, T1, T2>::value>::init(val, static_cast<T1*>(this), static_cast<T2*>(this));
|
Chris@16
|
253 }
|
Chris@16
|
254 compressed_pair_3(const ::boost::compressed_pair<T1,T2>& x)
|
Chris@16
|
255 : T1(x.first()), T2(x.second()) {}
|
Chris@16
|
256
|
Chris@16
|
257 first_reference first() { return *this; }
|
Chris@16
|
258 first_const_reference first() const { return *this; }
|
Chris@16
|
259
|
Chris@16
|
260 second_reference second() { return *this; }
|
Chris@16
|
261 second_const_reference second() const { return *this; }
|
Chris@16
|
262
|
Chris@16
|
263 void swap(compressed_pair_3& y)
|
Chris@16
|
264 {
|
Chris@16
|
265 // no need to swap empty base classes:
|
Chris@16
|
266 }
|
Chris@16
|
267 };
|
Chris@16
|
268
|
Chris@16
|
269 // T1 == T2, and empty
|
Chris@16
|
270 template <class T1, class T2>
|
Chris@16
|
271 class compressed_pair_4 : T1
|
Chris@16
|
272 {
|
Chris@16
|
273 public:
|
Chris@16
|
274 typedef T1 first_type;
|
Chris@16
|
275 typedef T2 second_type;
|
Chris@16
|
276 typedef typename call_traits<first_type>::param_type first_param_type;
|
Chris@16
|
277 typedef typename call_traits<second_type>::param_type second_param_type;
|
Chris@16
|
278 typedef typename call_traits<first_type>::reference first_reference;
|
Chris@16
|
279 typedef typename call_traits<second_type>::reference second_reference;
|
Chris@16
|
280 typedef typename call_traits<first_type>::const_reference first_const_reference;
|
Chris@16
|
281 typedef typename call_traits<second_type>::const_reference second_const_reference;
|
Chris@16
|
282
|
Chris@16
|
283 compressed_pair_4() : T1() {}
|
Chris@16
|
284 compressed_pair_4(first_param_type x, second_param_type y) : T1(x), m_second(y) {}
|
Chris@16
|
285 // only one single argument constructor since T1 == T2
|
Chris@16
|
286 explicit compressed_pair_4(first_param_type x) : T1(x), m_second(x) {}
|
Chris@16
|
287 compressed_pair_4(const ::boost::compressed_pair<T1,T2>& x)
|
Chris@16
|
288 : T1(x.first()), m_second(x.second()) {}
|
Chris@16
|
289
|
Chris@16
|
290 first_reference first() { return *this; }
|
Chris@16
|
291 first_const_reference first() const { return *this; }
|
Chris@16
|
292
|
Chris@16
|
293 second_reference second() { return m_second; }
|
Chris@16
|
294 second_const_reference second() const { return m_second; }
|
Chris@16
|
295
|
Chris@16
|
296 void swap(compressed_pair_4& y)
|
Chris@16
|
297 {
|
Chris@16
|
298 // no need to swap empty base classes:
|
Chris@16
|
299 }
|
Chris@16
|
300 private:
|
Chris@16
|
301 T2 m_second;
|
Chris@16
|
302 };
|
Chris@16
|
303
|
Chris@16
|
304 // T1 == T2, not empty
|
Chris@16
|
305 template <class T1, class T2>
|
Chris@16
|
306 class compressed_pair_5
|
Chris@16
|
307 {
|
Chris@16
|
308 private:
|
Chris@16
|
309 T1 _first;
|
Chris@16
|
310 T2 _second;
|
Chris@16
|
311 public:
|
Chris@16
|
312 typedef T1 first_type;
|
Chris@16
|
313 typedef T2 second_type;
|
Chris@16
|
314 typedef typename call_traits<first_type>::param_type first_param_type;
|
Chris@16
|
315 typedef typename call_traits<second_type>::param_type second_param_type;
|
Chris@16
|
316 typedef typename call_traits<first_type>::reference first_reference;
|
Chris@16
|
317 typedef typename call_traits<second_type>::reference second_reference;
|
Chris@16
|
318 typedef typename call_traits<first_type>::const_reference first_const_reference;
|
Chris@16
|
319 typedef typename call_traits<second_type>::const_reference second_const_reference;
|
Chris@16
|
320
|
Chris@16
|
321 compressed_pair_5() : _first(), _second() {}
|
Chris@16
|
322 compressed_pair_5(first_param_type x, second_param_type y) : _first(x), _second(y) {}
|
Chris@16
|
323 // only one single argument constructor since T1 == T2
|
Chris@16
|
324 explicit compressed_pair_5(first_param_type x) : _first(x), _second(x) {}
|
Chris@16
|
325 compressed_pair_5(const ::boost::compressed_pair<T1,T2>& c)
|
Chris@16
|
326 : _first(c.first()), _second(c.second()) {}
|
Chris@16
|
327
|
Chris@16
|
328 first_reference first() { return _first; }
|
Chris@16
|
329 first_const_reference first() const { return _first; }
|
Chris@16
|
330
|
Chris@16
|
331 second_reference second() { return _second; }
|
Chris@16
|
332 second_const_reference second() const { return _second; }
|
Chris@16
|
333
|
Chris@16
|
334 void swap(compressed_pair_5& y)
|
Chris@16
|
335 {
|
Chris@16
|
336 using std::swap;
|
Chris@16
|
337 swap(_first, y._first);
|
Chris@16
|
338 swap(_second, y._second);
|
Chris@16
|
339 }
|
Chris@16
|
340 };
|
Chris@16
|
341
|
Chris@16
|
342 template <bool e1, bool e2, bool same>
|
Chris@16
|
343 struct compressed_pair_chooser
|
Chris@16
|
344 {
|
Chris@16
|
345 template <class T1, class T2>
|
Chris@16
|
346 struct rebind
|
Chris@16
|
347 {
|
Chris@16
|
348 typedef compressed_pair_0<T1, T2> type;
|
Chris@16
|
349 };
|
Chris@16
|
350 };
|
Chris@16
|
351
|
Chris@16
|
352 template <>
|
Chris@16
|
353 struct compressed_pair_chooser<false, true, false>
|
Chris@16
|
354 {
|
Chris@16
|
355 template <class T1, class T2>
|
Chris@16
|
356 struct rebind
|
Chris@16
|
357 {
|
Chris@16
|
358 typedef compressed_pair_1<T1, T2> type;
|
Chris@16
|
359 };
|
Chris@16
|
360 };
|
Chris@16
|
361
|
Chris@16
|
362 template <>
|
Chris@16
|
363 struct compressed_pair_chooser<true, false, false>
|
Chris@16
|
364 {
|
Chris@16
|
365 template <class T1, class T2>
|
Chris@16
|
366 struct rebind
|
Chris@16
|
367 {
|
Chris@16
|
368 typedef compressed_pair_2<T1, T2> type;
|
Chris@16
|
369 };
|
Chris@16
|
370 };
|
Chris@16
|
371
|
Chris@16
|
372 template <>
|
Chris@16
|
373 struct compressed_pair_chooser<true, true, false>
|
Chris@16
|
374 {
|
Chris@16
|
375 template <class T1, class T2>
|
Chris@16
|
376 struct rebind
|
Chris@16
|
377 {
|
Chris@16
|
378 typedef compressed_pair_3<T1, T2> type;
|
Chris@16
|
379 };
|
Chris@16
|
380 };
|
Chris@16
|
381
|
Chris@16
|
382 template <>
|
Chris@16
|
383 struct compressed_pair_chooser<true, true, true>
|
Chris@16
|
384 {
|
Chris@16
|
385 template <class T1, class T2>
|
Chris@16
|
386 struct rebind
|
Chris@16
|
387 {
|
Chris@16
|
388 typedef compressed_pair_4<T1, T2> type;
|
Chris@16
|
389 };
|
Chris@16
|
390 };
|
Chris@16
|
391
|
Chris@16
|
392 template <>
|
Chris@16
|
393 struct compressed_pair_chooser<false, false, true>
|
Chris@16
|
394 {
|
Chris@16
|
395 template <class T1, class T2>
|
Chris@16
|
396 struct rebind
|
Chris@16
|
397 {
|
Chris@16
|
398 typedef compressed_pair_5<T1, T2> type;
|
Chris@16
|
399 };
|
Chris@16
|
400 };
|
Chris@16
|
401
|
Chris@16
|
402 template <class T1, class T2>
|
Chris@16
|
403 struct compressed_pair_traits
|
Chris@16
|
404 {
|
Chris@16
|
405 private:
|
Chris@16
|
406 typedef compressed_pair_chooser<is_empty<T1>::value, is_empty<T2>::value, is_same<T1,T2>::value> chooser;
|
Chris@16
|
407 typedef typename chooser::template rebind<T1, T2> bound_type;
|
Chris@16
|
408 public:
|
Chris@16
|
409 typedef typename bound_type::type type;
|
Chris@16
|
410 };
|
Chris@16
|
411
|
Chris@16
|
412 } // namespace detail
|
Chris@16
|
413
|
Chris@16
|
414 template <class T1, class T2>
|
Chris@16
|
415 class compressed_pair : public detail::compressed_pair_traits<T1, T2>::type
|
Chris@16
|
416 {
|
Chris@16
|
417 private:
|
Chris@16
|
418 typedef typename detail::compressed_pair_traits<T1, T2>::type base_type;
|
Chris@16
|
419 public:
|
Chris@16
|
420 typedef T1 first_type;
|
Chris@16
|
421 typedef T2 second_type;
|
Chris@16
|
422 typedef typename call_traits<first_type>::param_type first_param_type;
|
Chris@16
|
423 typedef typename call_traits<second_type>::param_type second_param_type;
|
Chris@16
|
424 typedef typename call_traits<first_type>::reference first_reference;
|
Chris@16
|
425 typedef typename call_traits<second_type>::reference second_reference;
|
Chris@16
|
426 typedef typename call_traits<first_type>::const_reference first_const_reference;
|
Chris@16
|
427 typedef typename call_traits<second_type>::const_reference second_const_reference;
|
Chris@16
|
428
|
Chris@16
|
429 compressed_pair() : base_type() {}
|
Chris@16
|
430 compressed_pair(first_param_type x, second_param_type y) : base_type(x, y) {}
|
Chris@16
|
431 template <class A>
|
Chris@16
|
432 explicit compressed_pair(const A& x) : base_type(x){}
|
Chris@16
|
433
|
Chris@16
|
434 first_reference first() { return base_type::first(); }
|
Chris@16
|
435 first_const_reference first() const { return base_type::first(); }
|
Chris@16
|
436
|
Chris@16
|
437 second_reference second() { return base_type::second(); }
|
Chris@16
|
438 second_const_reference second() const { return base_type::second(); }
|
Chris@16
|
439 };
|
Chris@16
|
440
|
Chris@16
|
441 template <class T1, class T2>
|
Chris@16
|
442 inline void swap(compressed_pair<T1, T2>& x, compressed_pair<T1, T2>& y)
|
Chris@16
|
443 {
|
Chris@16
|
444 x.swap(y);
|
Chris@16
|
445 }
|
Chris@16
|
446
|
Chris@16
|
447 #else
|
Chris@16
|
448 // no partial specialisation, no member templates:
|
Chris@16
|
449
|
Chris@16
|
450 template <class T1, class T2>
|
Chris@16
|
451 class compressed_pair
|
Chris@16
|
452 {
|
Chris@16
|
453 private:
|
Chris@16
|
454 T1 _first;
|
Chris@16
|
455 T2 _second;
|
Chris@16
|
456 public:
|
Chris@16
|
457 typedef T1 first_type;
|
Chris@16
|
458 typedef T2 second_type;
|
Chris@16
|
459 typedef typename call_traits<first_type>::param_type first_param_type;
|
Chris@16
|
460 typedef typename call_traits<second_type>::param_type second_param_type;
|
Chris@16
|
461 typedef typename call_traits<first_type>::reference first_reference;
|
Chris@16
|
462 typedef typename call_traits<second_type>::reference second_reference;
|
Chris@16
|
463 typedef typename call_traits<first_type>::const_reference first_const_reference;
|
Chris@16
|
464 typedef typename call_traits<second_type>::const_reference second_const_reference;
|
Chris@16
|
465
|
Chris@16
|
466 compressed_pair() : _first(), _second() {}
|
Chris@16
|
467 compressed_pair(first_param_type x, second_param_type y) : _first(x), _second(y) {}
|
Chris@16
|
468 explicit compressed_pair(first_param_type x) : _first(x), _second() {}
|
Chris@16
|
469 // can't define this in case T1 == T2:
|
Chris@16
|
470 // explicit compressed_pair(second_param_type y) : _first(), _second(y) {}
|
Chris@16
|
471
|
Chris@16
|
472 first_reference first() { return _first; }
|
Chris@16
|
473 first_const_reference first() const { return _first; }
|
Chris@16
|
474
|
Chris@16
|
475 second_reference second() { return _second; }
|
Chris@16
|
476 second_const_reference second() const { return _second; }
|
Chris@16
|
477
|
Chris@16
|
478 void swap(compressed_pair& y)
|
Chris@16
|
479 {
|
Chris@16
|
480 using std::swap;
|
Chris@16
|
481 swap(_first, y._first);
|
Chris@16
|
482 swap(_second, y._second);
|
Chris@16
|
483 }
|
Chris@16
|
484 };
|
Chris@16
|
485
|
Chris@16
|
486 template <class T1, class T2>
|
Chris@16
|
487 inline void swap(compressed_pair<T1, T2>& x, compressed_pair<T1, T2>& y)
|
Chris@16
|
488 {
|
Chris@16
|
489 x.swap(y);
|
Chris@16
|
490 }
|
Chris@16
|
491
|
Chris@16
|
492 #endif
|
Chris@16
|
493
|
Chris@16
|
494 } // boost
|
Chris@16
|
495
|
Chris@16
|
496 #endif // BOOST_OB_COMPRESSED_PAIR_HPP
|
Chris@16
|
497
|
Chris@16
|
498
|
Chris@16
|
499
|