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 #if defined(BOOST_MSVC) && BOOST_MSVC <= 1300
|
Chris@16
|
171 // Total weirdness. If the assignment to _first is moved after
|
Chris@16
|
172 // the call to the inherited operator=, then this breaks graph/test/graph.cpp
|
Chris@16
|
173 // by way of iterator_adaptor.
|
Chris@16
|
174 compressed_pair_1& operator=(const compressed_pair_1& x) {
|
Chris@16
|
175 _first = x._first;
|
Chris@16
|
176 T2::operator=(x);
|
Chris@16
|
177 return *this;
|
Chris@16
|
178 }
|
Chris@16
|
179 #endif
|
Chris@16
|
180
|
Chris@16
|
181 first_reference first() { return _first; }
|
Chris@16
|
182 first_const_reference first() const { return _first; }
|
Chris@16
|
183
|
Chris@16
|
184 second_reference second() { return *this; }
|
Chris@16
|
185 second_const_reference second() const { return *this; }
|
Chris@16
|
186
|
Chris@16
|
187 void swap(compressed_pair_1& y)
|
Chris@16
|
188 {
|
Chris@16
|
189 // no need to swap empty base class:
|
Chris@16
|
190 using std::swap;
|
Chris@16
|
191 swap(_first, y._first);
|
Chris@16
|
192 }
|
Chris@16
|
193 };
|
Chris@16
|
194
|
Chris@16
|
195 // T1 != T2, T1 empty
|
Chris@16
|
196 template <class T1, class T2>
|
Chris@16
|
197 class compressed_pair_2 : T1
|
Chris@16
|
198 {
|
Chris@16
|
199 private:
|
Chris@16
|
200 T2 _second;
|
Chris@16
|
201 public:
|
Chris@16
|
202 typedef T1 first_type;
|
Chris@16
|
203 typedef T2 second_type;
|
Chris@16
|
204 typedef typename call_traits<first_type>::param_type first_param_type;
|
Chris@16
|
205 typedef typename call_traits<second_type>::param_type second_param_type;
|
Chris@16
|
206 typedef typename call_traits<first_type>::reference first_reference;
|
Chris@16
|
207 typedef typename call_traits<second_type>::reference second_reference;
|
Chris@16
|
208 typedef typename call_traits<first_type>::const_reference first_const_reference;
|
Chris@16
|
209 typedef typename call_traits<second_type>::const_reference second_const_reference;
|
Chris@16
|
210
|
Chris@16
|
211 compressed_pair_2() : T1(), _second() {}
|
Chris@16
|
212 compressed_pair_2(first_param_type x, second_param_type y) : T1(x), _second(y) {}
|
Chris@16
|
213 template <class A>
|
Chris@16
|
214 explicit compressed_pair_2(const A& val)
|
Chris@16
|
215 {
|
Chris@16
|
216 init_one<best_conversion_traits<A, T1, T2>::value>::init(val, static_cast<T1*>(this), &_second);
|
Chris@16
|
217 }
|
Chris@16
|
218 compressed_pair_2(const ::boost::compressed_pair<T1,T2>& x)
|
Chris@16
|
219 : T1(x.first()), _second(x.second()) {}
|
Chris@16
|
220
|
Chris@16
|
221 #if 0
|
Chris@16
|
222 compressed_pair_2& operator=(const compressed_pair_2& x) {
|
Chris@16
|
223 cout << "assigning compressed pair 2" << endl;
|
Chris@16
|
224 T1::operator=(x);
|
Chris@16
|
225 _second = x._second;
|
Chris@16
|
226 cout << "finished assigning compressed pair 2" << endl;
|
Chris@16
|
227 return *this;
|
Chris@16
|
228 }
|
Chris@16
|
229 #endif
|
Chris@16
|
230 first_reference first() { return *this; }
|
Chris@16
|
231 first_const_reference first() const { return *this; }
|
Chris@16
|
232
|
Chris@16
|
233 second_reference second() { return _second; }
|
Chris@16
|
234 second_const_reference second() const { return _second; }
|
Chris@16
|
235
|
Chris@16
|
236 void swap(compressed_pair_2& y)
|
Chris@16
|
237 {
|
Chris@16
|
238 // no need to swap empty base class:
|
Chris@16
|
239 using std::swap;
|
Chris@16
|
240 swap(_second, y._second);
|
Chris@16
|
241 }
|
Chris@16
|
242 };
|
Chris@16
|
243
|
Chris@16
|
244 // T1 != T2, both empty
|
Chris@16
|
245 template <class T1, class T2>
|
Chris@16
|
246 class compressed_pair_3 : T1, T2
|
Chris@16
|
247 {
|
Chris@16
|
248 public:
|
Chris@16
|
249 typedef T1 first_type;
|
Chris@16
|
250 typedef T2 second_type;
|
Chris@16
|
251 typedef typename call_traits<first_type>::param_type first_param_type;
|
Chris@16
|
252 typedef typename call_traits<second_type>::param_type second_param_type;
|
Chris@16
|
253 typedef typename call_traits<first_type>::reference first_reference;
|
Chris@16
|
254 typedef typename call_traits<second_type>::reference second_reference;
|
Chris@16
|
255 typedef typename call_traits<first_type>::const_reference first_const_reference;
|
Chris@16
|
256 typedef typename call_traits<second_type>::const_reference second_const_reference;
|
Chris@16
|
257
|
Chris@16
|
258 compressed_pair_3() : T1(), T2() {}
|
Chris@16
|
259 compressed_pair_3(first_param_type x, second_param_type y) : T1(x), T2(y) {}
|
Chris@16
|
260 template <class A>
|
Chris@16
|
261 explicit compressed_pair_3(const A& val)
|
Chris@16
|
262 {
|
Chris@16
|
263 init_one<best_conversion_traits<A, T1, T2>::value>::init(val, static_cast<T1*>(this), static_cast<T2*>(this));
|
Chris@16
|
264 }
|
Chris@16
|
265 compressed_pair_3(const ::boost::compressed_pair<T1,T2>& x)
|
Chris@16
|
266 : T1(x.first()), T2(x.second()) {}
|
Chris@16
|
267
|
Chris@16
|
268 first_reference first() { return *this; }
|
Chris@16
|
269 first_const_reference first() const { return *this; }
|
Chris@16
|
270
|
Chris@16
|
271 second_reference second() { return *this; }
|
Chris@16
|
272 second_const_reference second() const { return *this; }
|
Chris@16
|
273
|
Chris@16
|
274 void swap(compressed_pair_3& y)
|
Chris@16
|
275 {
|
Chris@16
|
276 // no need to swap empty base classes:
|
Chris@16
|
277 }
|
Chris@16
|
278 };
|
Chris@16
|
279
|
Chris@16
|
280 // T1 == T2, and empty
|
Chris@16
|
281 template <class T1, class T2>
|
Chris@16
|
282 class compressed_pair_4 : T1
|
Chris@16
|
283 {
|
Chris@16
|
284 public:
|
Chris@16
|
285 typedef T1 first_type;
|
Chris@16
|
286 typedef T2 second_type;
|
Chris@16
|
287 typedef typename call_traits<first_type>::param_type first_param_type;
|
Chris@16
|
288 typedef typename call_traits<second_type>::param_type second_param_type;
|
Chris@16
|
289 typedef typename call_traits<first_type>::reference first_reference;
|
Chris@16
|
290 typedef typename call_traits<second_type>::reference second_reference;
|
Chris@16
|
291 typedef typename call_traits<first_type>::const_reference first_const_reference;
|
Chris@16
|
292 typedef typename call_traits<second_type>::const_reference second_const_reference;
|
Chris@16
|
293
|
Chris@16
|
294 compressed_pair_4() : T1() {}
|
Chris@16
|
295 compressed_pair_4(first_param_type x, second_param_type y) : T1(x), m_second(y) {}
|
Chris@16
|
296 // only one single argument constructor since T1 == T2
|
Chris@16
|
297 explicit compressed_pair_4(first_param_type x) : T1(x), m_second(x) {}
|
Chris@16
|
298 compressed_pair_4(const ::boost::compressed_pair<T1,T2>& x)
|
Chris@16
|
299 : T1(x.first()), m_second(x.second()) {}
|
Chris@16
|
300
|
Chris@16
|
301 first_reference first() { return *this; }
|
Chris@16
|
302 first_const_reference first() const { return *this; }
|
Chris@16
|
303
|
Chris@16
|
304 second_reference second() { return m_second; }
|
Chris@16
|
305 second_const_reference second() const { return m_second; }
|
Chris@16
|
306
|
Chris@16
|
307 void swap(compressed_pair_4& y)
|
Chris@16
|
308 {
|
Chris@16
|
309 // no need to swap empty base classes:
|
Chris@16
|
310 }
|
Chris@16
|
311 private:
|
Chris@16
|
312 T2 m_second;
|
Chris@16
|
313 };
|
Chris@16
|
314
|
Chris@16
|
315 // T1 == T2, not empty
|
Chris@16
|
316 template <class T1, class T2>
|
Chris@16
|
317 class compressed_pair_5
|
Chris@16
|
318 {
|
Chris@16
|
319 private:
|
Chris@16
|
320 T1 _first;
|
Chris@16
|
321 T2 _second;
|
Chris@16
|
322 public:
|
Chris@16
|
323 typedef T1 first_type;
|
Chris@16
|
324 typedef T2 second_type;
|
Chris@16
|
325 typedef typename call_traits<first_type>::param_type first_param_type;
|
Chris@16
|
326 typedef typename call_traits<second_type>::param_type second_param_type;
|
Chris@16
|
327 typedef typename call_traits<first_type>::reference first_reference;
|
Chris@16
|
328 typedef typename call_traits<second_type>::reference second_reference;
|
Chris@16
|
329 typedef typename call_traits<first_type>::const_reference first_const_reference;
|
Chris@16
|
330 typedef typename call_traits<second_type>::const_reference second_const_reference;
|
Chris@16
|
331
|
Chris@16
|
332 compressed_pair_5() : _first(), _second() {}
|
Chris@16
|
333 compressed_pair_5(first_param_type x, second_param_type y) : _first(x), _second(y) {}
|
Chris@16
|
334 // only one single argument constructor since T1 == T2
|
Chris@16
|
335 explicit compressed_pair_5(first_param_type x) : _first(x), _second(x) {}
|
Chris@16
|
336 compressed_pair_5(const ::boost::compressed_pair<T1,T2>& c)
|
Chris@16
|
337 : _first(c.first()), _second(c.second()) {}
|
Chris@16
|
338
|
Chris@16
|
339 first_reference first() { return _first; }
|
Chris@16
|
340 first_const_reference first() const { return _first; }
|
Chris@16
|
341
|
Chris@16
|
342 second_reference second() { return _second; }
|
Chris@16
|
343 second_const_reference second() const { return _second; }
|
Chris@16
|
344
|
Chris@16
|
345 void swap(compressed_pair_5& y)
|
Chris@16
|
346 {
|
Chris@16
|
347 using std::swap;
|
Chris@16
|
348 swap(_first, y._first);
|
Chris@16
|
349 swap(_second, y._second);
|
Chris@16
|
350 }
|
Chris@16
|
351 };
|
Chris@16
|
352
|
Chris@16
|
353 template <bool e1, bool e2, bool same>
|
Chris@16
|
354 struct compressed_pair_chooser
|
Chris@16
|
355 {
|
Chris@16
|
356 template <class T1, class T2>
|
Chris@16
|
357 struct rebind
|
Chris@16
|
358 {
|
Chris@16
|
359 typedef compressed_pair_0<T1, T2> type;
|
Chris@16
|
360 };
|
Chris@16
|
361 };
|
Chris@16
|
362
|
Chris@16
|
363 template <>
|
Chris@16
|
364 struct compressed_pair_chooser<false, true, false>
|
Chris@16
|
365 {
|
Chris@16
|
366 template <class T1, class T2>
|
Chris@16
|
367 struct rebind
|
Chris@16
|
368 {
|
Chris@16
|
369 typedef compressed_pair_1<T1, T2> type;
|
Chris@16
|
370 };
|
Chris@16
|
371 };
|
Chris@16
|
372
|
Chris@16
|
373 template <>
|
Chris@16
|
374 struct compressed_pair_chooser<true, false, false>
|
Chris@16
|
375 {
|
Chris@16
|
376 template <class T1, class T2>
|
Chris@16
|
377 struct rebind
|
Chris@16
|
378 {
|
Chris@16
|
379 typedef compressed_pair_2<T1, T2> type;
|
Chris@16
|
380 };
|
Chris@16
|
381 };
|
Chris@16
|
382
|
Chris@16
|
383 template <>
|
Chris@16
|
384 struct compressed_pair_chooser<true, true, false>
|
Chris@16
|
385 {
|
Chris@16
|
386 template <class T1, class T2>
|
Chris@16
|
387 struct rebind
|
Chris@16
|
388 {
|
Chris@16
|
389 typedef compressed_pair_3<T1, T2> type;
|
Chris@16
|
390 };
|
Chris@16
|
391 };
|
Chris@16
|
392
|
Chris@16
|
393 template <>
|
Chris@16
|
394 struct compressed_pair_chooser<true, true, true>
|
Chris@16
|
395 {
|
Chris@16
|
396 template <class T1, class T2>
|
Chris@16
|
397 struct rebind
|
Chris@16
|
398 {
|
Chris@16
|
399 typedef compressed_pair_4<T1, T2> type;
|
Chris@16
|
400 };
|
Chris@16
|
401 };
|
Chris@16
|
402
|
Chris@16
|
403 template <>
|
Chris@16
|
404 struct compressed_pair_chooser<false, false, true>
|
Chris@16
|
405 {
|
Chris@16
|
406 template <class T1, class T2>
|
Chris@16
|
407 struct rebind
|
Chris@16
|
408 {
|
Chris@16
|
409 typedef compressed_pair_5<T1, T2> type;
|
Chris@16
|
410 };
|
Chris@16
|
411 };
|
Chris@16
|
412
|
Chris@16
|
413 template <class T1, class T2>
|
Chris@16
|
414 struct compressed_pair_traits
|
Chris@16
|
415 {
|
Chris@16
|
416 private:
|
Chris@16
|
417 typedef compressed_pair_chooser<is_empty<T1>::value, is_empty<T2>::value, is_same<T1,T2>::value> chooser;
|
Chris@16
|
418 typedef typename chooser::template rebind<T1, T2> bound_type;
|
Chris@16
|
419 public:
|
Chris@16
|
420 typedef typename bound_type::type type;
|
Chris@16
|
421 };
|
Chris@16
|
422
|
Chris@16
|
423 } // namespace detail
|
Chris@16
|
424
|
Chris@16
|
425 template <class T1, class T2>
|
Chris@16
|
426 class compressed_pair : public detail::compressed_pair_traits<T1, T2>::type
|
Chris@16
|
427 {
|
Chris@16
|
428 private:
|
Chris@16
|
429 typedef typename detail::compressed_pair_traits<T1, T2>::type base_type;
|
Chris@16
|
430 public:
|
Chris@16
|
431 typedef T1 first_type;
|
Chris@16
|
432 typedef T2 second_type;
|
Chris@16
|
433 typedef typename call_traits<first_type>::param_type first_param_type;
|
Chris@16
|
434 typedef typename call_traits<second_type>::param_type second_param_type;
|
Chris@16
|
435 typedef typename call_traits<first_type>::reference first_reference;
|
Chris@16
|
436 typedef typename call_traits<second_type>::reference second_reference;
|
Chris@16
|
437 typedef typename call_traits<first_type>::const_reference first_const_reference;
|
Chris@16
|
438 typedef typename call_traits<second_type>::const_reference second_const_reference;
|
Chris@16
|
439
|
Chris@16
|
440 compressed_pair() : base_type() {}
|
Chris@16
|
441 compressed_pair(first_param_type x, second_param_type y) : base_type(x, y) {}
|
Chris@16
|
442 template <class A>
|
Chris@16
|
443 explicit compressed_pair(const A& x) : base_type(x){}
|
Chris@16
|
444
|
Chris@16
|
445 first_reference first() { return base_type::first(); }
|
Chris@16
|
446 first_const_reference first() const { return base_type::first(); }
|
Chris@16
|
447
|
Chris@16
|
448 second_reference second() { return base_type::second(); }
|
Chris@16
|
449 second_const_reference second() const { return base_type::second(); }
|
Chris@16
|
450 };
|
Chris@16
|
451
|
Chris@16
|
452 template <class T1, class T2>
|
Chris@16
|
453 inline void swap(compressed_pair<T1, T2>& x, compressed_pair<T1, T2>& y)
|
Chris@16
|
454 {
|
Chris@16
|
455 x.swap(y);
|
Chris@16
|
456 }
|
Chris@16
|
457
|
Chris@16
|
458 #else
|
Chris@16
|
459 // no partial specialisation, no member templates:
|
Chris@16
|
460
|
Chris@16
|
461 template <class T1, class T2>
|
Chris@16
|
462 class compressed_pair
|
Chris@16
|
463 {
|
Chris@16
|
464 private:
|
Chris@16
|
465 T1 _first;
|
Chris@16
|
466 T2 _second;
|
Chris@16
|
467 public:
|
Chris@16
|
468 typedef T1 first_type;
|
Chris@16
|
469 typedef T2 second_type;
|
Chris@16
|
470 typedef typename call_traits<first_type>::param_type first_param_type;
|
Chris@16
|
471 typedef typename call_traits<second_type>::param_type second_param_type;
|
Chris@16
|
472 typedef typename call_traits<first_type>::reference first_reference;
|
Chris@16
|
473 typedef typename call_traits<second_type>::reference second_reference;
|
Chris@16
|
474 typedef typename call_traits<first_type>::const_reference first_const_reference;
|
Chris@16
|
475 typedef typename call_traits<second_type>::const_reference second_const_reference;
|
Chris@16
|
476
|
Chris@16
|
477 compressed_pair() : _first(), _second() {}
|
Chris@16
|
478 compressed_pair(first_param_type x, second_param_type y) : _first(x), _second(y) {}
|
Chris@16
|
479 explicit compressed_pair(first_param_type x) : _first(x), _second() {}
|
Chris@16
|
480 // can't define this in case T1 == T2:
|
Chris@16
|
481 // explicit compressed_pair(second_param_type y) : _first(), _second(y) {}
|
Chris@16
|
482
|
Chris@16
|
483 first_reference first() { return _first; }
|
Chris@16
|
484 first_const_reference first() const { return _first; }
|
Chris@16
|
485
|
Chris@16
|
486 second_reference second() { return _second; }
|
Chris@16
|
487 second_const_reference second() const { return _second; }
|
Chris@16
|
488
|
Chris@16
|
489 void swap(compressed_pair& y)
|
Chris@16
|
490 {
|
Chris@16
|
491 using std::swap;
|
Chris@16
|
492 swap(_first, y._first);
|
Chris@16
|
493 swap(_second, y._second);
|
Chris@16
|
494 }
|
Chris@16
|
495 };
|
Chris@16
|
496
|
Chris@16
|
497 template <class T1, class T2>
|
Chris@16
|
498 inline void swap(compressed_pair<T1, T2>& x, compressed_pair<T1, T2>& y)
|
Chris@16
|
499 {
|
Chris@16
|
500 x.swap(y);
|
Chris@16
|
501 }
|
Chris@16
|
502
|
Chris@16
|
503 #endif
|
Chris@16
|
504
|
Chris@16
|
505 } // boost
|
Chris@16
|
506
|
Chris@16
|
507 #endif // BOOST_OB_COMPRESSED_PAIR_HPP
|
Chris@16
|
508
|
Chris@16
|
509
|
Chris@16
|
510
|