]> git.sesse.net Git - casparcg/blob - tbb/include/tbb/compat/tuple
2.0. Updated tbb library.
[casparcg] / tbb / include / tbb / compat / tuple
1 /*
2     Copyright 2005-2011 Intel Corporation.  All Rights Reserved.
3
4     This file is part of Threading Building Blocks.
5
6     Threading Building Blocks is free software; you can redistribute it
7     and/or modify it under the terms of the GNU General Public License
8     version 2 as published by the Free Software Foundation.
9
10     Threading Building Blocks is distributed in the hope that it will be
11     useful, but WITHOUT ANY WARRANTY; without even the implied warranty
12     of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14
15     You should have received a copy of the GNU General Public License
16     along with Threading Building Blocks; if not, write to the Free Software
17     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18
19     As a special exception, you may use this file as part of a free software
20     library without restriction.  Specifically, if other files instantiate
21     templates or use macros or inline functions from this file, or you compile
22     this file and link it with other files to produce an executable, this
23     file does not by itself cause the resulting executable to be covered by
24     the GNU General Public License.  This exception does not however
25     invalidate any other reasons why the executable file might be covered by
26     the GNU General Public License.
27 */
28
29 #ifndef __TBB_tuple_H
30 #define __TBB_tuple_H
31
32 #if !TBB_PREVIEW_TUPLE
33 #error Set TBB_PREVIEW_TUPLE to include compat/tuple
34 #endif
35
36 #include <utility>
37 #include "../tbb_stddef.h"
38
39 namespace tbb {
40 namespace interface5 {
41 namespace internal {
42 struct null_type { };
43 }
44 using internal::null_type;
45
46 // tuple forward declaration
47 template <class T0=null_type, class T1=null_type, class T2=null_type, class T3=null_type, class T4=null_type, class T5=null_type, class T6=null_type, class T7=null_type, class T8=null_type, class T9=null_type>
48 class tuple;
49
50 namespace internal {
51
52 // const null_type temp
53 inline const null_type cnull() { return null_type(); }
54
55 // cons forward declaration
56 template <class HT, class TT> struct cons;
57
58 // type of a component of the cons
59 template<int N, class T>
60 struct component {
61     typedef typename T::tail_type next;
62     typedef typename component<N-1,next>::type type;
63 };
64
65 template<class T>
66 struct component<0,T> {
67     typedef typename T::head_type type;
68 };
69
70 template<>
71 struct component<0,null_type> {
72     typedef null_type type;
73 };
74
75 // const version of component
76
77 template<int N, class T>
78 struct component<N, const T>
79 {
80     typedef typename T::tail_type next;
81     typedef typename component<N-1,next>::type type;
82 };
83
84 template<class T>
85 struct component<0, const T>
86 {
87     typedef const typename T::head_type type;
88 };
89
90
91 // helper class for getting components of cons
92 template< int N>
93 struct get_helper {
94 template<class HT, class TT>
95 inline static typename component<N, cons<HT,TT> >::type& get(cons<HT,TT>& ti) {
96     return get_helper<N-1>::get(ti.tail);
97 }
98 };
99
100 template<>
101 struct get_helper<0> {
102 template<class HT, class TT>
103 inline static typename component<0, cons<HT,TT> >::type& get(cons<HT,TT>& ti) {
104     return ti.head;
105 }
106 };
107
108 // traits adaptor
109 template <class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9>
110 struct tuple_traits {
111     typedef cons <T0, typename tuple_traits<T1, T2, T3, T4, T5, T6, T7, T8, T9, null_type>::U > U;
112 };
113
114 template <>
115 struct tuple_traits<class T0, null_type, null_type, null_type, null_type, null_type, null_type, null_type, null_type, null_type> {
116     typedef cons<T0, null_type> U;
117 };
118
119 template<>
120 struct tuple_traits<null_type, null_type, null_type, null_type, null_type, null_type, null_type, null_type, null_type, null_type> {
121     typedef null_type U;
122 };
123
124
125 // core cons defs
126 template <class HT, class TT>
127 struct cons{
128
129     typedef HT head_type;
130     typedef TT tail_type;
131
132     HT head; 
133     TT tail;
134
135     static const int length = 1 + tail_type::length;
136
137     // default constructors
138     explicit cons() : head(), tail() { }
139
140     // non-default constructors
141     cons(head_type& h, const tail_type& t) : head(h), tail(t) { }
142
143     template <class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9>
144     cons(const T0& t0, const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5, const T6& t6, const T7& t7, const T8& t8, const T9& t9) :
145         head(t0), tail(t1, t2, t3, t4, t5, t6, t7, t8, t9, cnull()) { }
146
147     template <class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9>
148     cons(T0& t0, T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6, T7& t7, T8& t8, T9& t9) :
149         head(t0), tail(t1, t2, t3, t4, t5, t6, t7, t8, t9, cnull()) { }
150
151     template <class HT1, class TT1>
152     cons(const cons<HT1,TT1>& other) : head(other.head), tail(other.tail) { }
153
154     cons& operator=(const cons& other) { head = other.head; tail = other.tail; return *this; }
155
156     friend bool operator==(const cons& me, const cons& other) {
157         return me.head == other.head && me.tail == other.tail;
158     }
159     friend bool operator<(const cons& me, const cons& other)  {
160         return me.head < other.head || (!(other.head < me.head) && me.tail < other.tail);
161     }
162     friend bool operator>(const cons& me, const cons& other)  { return other<me; }
163     friend bool operator!=(const cons& me, const cons& other) { return !(me==other); }
164     friend bool operator>=(const cons& me, const cons& other) { return !(me<other); }
165     friend bool operator<=(const cons& me, const cons& other) { return !(me>other); }
166
167     template<class HT1, class TT1>
168     friend bool operator==(const cons<HT,TT>& me, const cons<HT1,TT1>& other) {
169         return me.head == other.head && me.tail == other.tail;
170     }
171
172     template<class HT1, class TT1>
173     friend bool operator<(const cons<HT,TT>& me, const cons<HT1,TT1>& other) {
174         return me.head < other.head || (!(other.head < me.head) && me.tail < other.tail);
175     }
176
177     template<class HT1, class TT1>
178     friend bool operator>(const cons<HT,TT>& me, const cons<HT1,TT1>& other) { return other<me; }
179
180     template<class HT1, class TT1>
181     friend bool operator!=(const cons<HT,TT>& me, const cons<HT1,TT1>& other) { return !(me==other); }
182
183     template<class HT1, class TT1>
184     friend bool operator>=(const cons<HT,TT>& me, const cons<HT1,TT1>& other) { return !(me<other); }
185
186     template<class HT1, class TT1>
187     friend bool operator<=(const cons<HT,TT>& me, const cons<HT1,TT1>& other) { return !(me>other); }
188
189
190 };  // cons
191
192
193 template <class HT>
194 struct cons<HT,null_type> { 
195
196     typedef HT head_type;
197     typedef null_type tail_type;
198     static const int length = 1;
199     head_type head; 
200
201     // default constructor
202     cons() : head() { /*std::cout << "default constructor 1\n";*/ }
203
204     cons(const null_type&, const null_type&, const null_type&, const null_type&, const null_type&, const null_type&, const null_type&, const null_type&, const null_type&, const null_type&) : head() { /*std::cout << "default constructor 2\n";*/ }
205
206     // non-default constructor
207     template<class T1>
208     cons(T1& t1, const null_type&, const null_type&, const null_type&, const null_type&, const null_type&, const null_type&, const null_type&, const null_type&, const null_type& ) : head(t1) { /*std::cout << "non-default a1, t1== " << t1 << "\n";*/}
209
210     cons(head_type& h, const null_type& = null_type() ) : head(h) { }
211     cons(const head_type& t0, const null_type&, const null_type&, const null_type&, const null_type&, const null_type&, const null_type&, const null_type&, const null_type&, const null_type&) : head(t0) { }
212
213     // converting constructor
214     template<class HT1>
215     cons(HT1 h1, const null_type&, const null_type&, const null_type&, const null_type&, const null_type&, const null_type&, const null_type&, const null_type&, const null_type&) : head(h1) { }
216
217     // copy constructor
218     template<class HT1>
219     cons( const cons<HT1, null_type>& other) : head(other.head) { }
220
221     // assignment operator
222     cons& operator=(const cons& other) { head = other.head; return *this; }
223
224     friend bool operator==(const cons& me, const cons& other) { return me.head == other.head; }
225     friend bool operator<(const cons& me, const cons& other) { return me.head < other.head; }
226     friend bool operator>(const cons& me, const cons& other) { return other<me; }
227     friend bool operator!=(const cons& me, const cons& other) {return !(me==other); }
228     friend bool operator<=(const cons& me, const cons& other) {return !(me>other); }
229     friend bool operator>=(const cons& me, const cons& other) {return !(me<other); }
230
231     template<class HT1>
232     friend bool operator==(const cons<HT,null_type>& me, const cons<HT1,null_type>& other) {
233         return me.head == other.head;
234     }
235
236     template<class HT1>
237     friend bool operator<(const cons<HT,null_type>& me, const cons<HT1,null_type>& other) {
238         return me.head < other.head;
239     }
240
241     template<class HT1>
242     friend bool operator>(const cons<HT,null_type>& me, const cons<HT1,null_type>& other) { return other<me; }
243
244     template<class HT1>
245     friend bool operator!=(const cons<HT,null_type>& me, const cons<HT1,null_type>& other) { return !(me==other); }
246
247     template<class HT1>
248     friend bool operator<=(const cons<HT,null_type>& me, const cons<HT1,null_type>& other) { return !(me>other); }
249
250     template<class HT1>
251     friend bool operator>=(const cons<HT,null_type>& me, const cons<HT1,null_type>& other) { return !(me<other); }
252
253 };  // cons
254
255 template <>
256 struct cons<null_type,null_type> { typedef null_type tail_type; static const int length = 0; };
257
258 // wrapper for default constructor
259 template<class T>
260 inline const T wrap_dcons(T*) { return T(); }
261 } // namespace internal
262
263 // tuple definition
264 template<class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9>
265 class tuple : public internal::tuple_traits<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>::U {
266     // friends
267     template <class T> friend class tuple_size;
268     template<int N, class T> friend struct tuple_element;
269
270     // stl components
271     typedef tuple<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9> value_type;
272     typedef value_type *pointer;
273     typedef const value_type *const_pointer;
274     typedef value_type &reference;
275     typedef const value_type &const_reference;
276     typedef size_t size_type;
277
278     typedef typename internal::tuple_traits<T0,T1,T2,T3, T4, T5, T6, T7, T8, T9>::U my_cons;
279 public:
280
281     tuple(const T0& t0=internal::wrap_dcons((T0*)NULL),
282           const T1& t1=internal::wrap_dcons((T1*)NULL),
283           const T2& t2=internal::wrap_dcons((T2*)NULL),
284           const T3& t3=internal::wrap_dcons((T3*)NULL),
285           const T4& t4=internal::wrap_dcons((T4*)NULL),
286           const T5& t5=internal::wrap_dcons((T5*)NULL),
287           const T6& t6=internal::wrap_dcons((T6*)NULL),
288           const T7& t7=internal::wrap_dcons((T7*)NULL),
289           const T8& t8=internal::wrap_dcons((T8*)NULL),
290           const T9& t9=internal::wrap_dcons((T9*)NULL)
291           ) :
292         internal::tuple_traits<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9>::U(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9) { }
293
294     template<int N>
295     struct internal_tuple_element {
296         typedef typename internal::component<N,my_cons>::type type;
297     };
298
299     template<int N>
300     typename internal_tuple_element<N>::type& get() { return internal::get_helper<N>::get(*this); }
301
302     template<class U1, class U2>
303     tuple& operator=(const internal::cons<U1,U2>& other) {
304         my_cons::operator=(other);
305         return *this;
306     }
307
308     template<class U1, class U2>
309     tuple& operator=(const std::pair<U1,U2>& other) {
310         // __TBB_ASSERT(tuple_size<value_type>::value == 2, "Invalid size for pair to tuple assignment");
311         this->head = other.first;
312         this->tail.head = other.second;
313         return *this;
314     }
315
316     friend bool operator==(const tuple& me, const tuple& other) {return static_cast<const my_cons &>(me)==(other);}
317     friend bool operator<(const tuple& me,  const tuple& other) {return static_cast<const my_cons &>(me)<(other);}
318     friend bool operator>(const tuple& me,  const tuple& other) {return static_cast<const my_cons &>(me)>(other);}
319     friend bool operator!=(const tuple& me, const tuple& other) {return static_cast<const my_cons &>(me)!=(other);}
320     friend bool operator>=(const tuple& me, const tuple& other) {return static_cast<const my_cons &>(me)>=(other);}
321     friend bool operator<=(const tuple& me, const tuple& other) {return static_cast<const my_cons &>(me)<=(other);}
322
323     template<class U0, class U1, class U2, class U3, class U4, class U5, class U6, class U7, class U8, class U9>
324     friend bool operator==(const tuple& me, const tuple<U0,U1,U2,U3,U4,U5,U6,U7,U8,U9>& other) {
325         return static_cast<const my_cons &>(me)==(other);
326     }
327
328     template<class U0, class U1, class U2, class U3, class U4, class U5, class U6, class U7, class U8, class U9>
329     friend bool operator<(const tuple& me, const tuple<U0,U1,U2,U3,U4,U5,U6,U7,U8,U9>& other) {
330         return static_cast<const my_cons &>(me)<(other);
331     }
332
333     template<class U0, class U1, class U2, class U3, class U4, class U5, class U6, class U7, class U8, class U9>
334     friend bool operator>(const tuple& me, const tuple<U0,U1,U2,U3,U4,U5,U6,U7,U8,U9>& other) {
335         return static_cast<const my_cons &>(me)>(other);
336     }
337
338     template<class U0, class U1, class U2, class U3, class U4, class U5, class U6, class U7, class U8, class U9>
339     friend bool operator!=(const tuple& me, const tuple<U0,U1,U2,U3,U4,U5,U6,U7,U8,U9>& other) {
340         return static_cast<const my_cons &>(me)!=(other);
341     }
342
343     template<class U0, class U1, class U2, class U3, class U4, class U5, class U6, class U7, class U8, class U9>
344     friend bool operator>=(const tuple& me, const tuple<U0,U1,U2,U3,U4,U5,U6,U7,U8,U9>& other) {
345         return static_cast<const my_cons &>(me)>=(other);
346     }
347
348     template<class U0, class U1, class U2, class U3, class U4, class U5, class U6, class U7, class U8, class U9>
349     friend bool operator<=(const tuple& me, const tuple<U0,U1,U2,U3,U4,U5,U6,U7,U8,U9>& other) {
350         return static_cast<const my_cons &>(me)<=(other);
351     }
352
353 };  // tuple
354
355 // empty tuple
356 template<>
357 class tuple<null_type, null_type, null_type, null_type, null_type, null_type, null_type, null_type, null_type, null_type> : public null_type {
358     typedef null_type inherited;
359 };
360
361 // helper classes
362
363 template < class T>
364 class tuple_size {
365 public:
366     static const size_t value = 1 + tuple_size<typename T::tail_type>::value;
367 };
368
369 template <>
370 class tuple_size<tuple<> > { 
371 public:
372     static const size_t value = 0;
373 };
374
375 template <>
376 class tuple_size<null_type> {
377 public:
378     static const size_t value = 0;
379 };
380
381 template<int N, class T>
382 struct tuple_element {
383     typedef typename internal::component<N, typename T::my_cons>::type type;
384 };
385
386 template<int N, class T>
387 inline static typename tuple_element<N,T>::type& get(T &t) { return t.get<N>(); }
388
389 template<int N, class T>
390 inline static typename tuple_element<N,T>::type const& get(T const &t) { return 
391     const_cast<typename tuple_element<N,T>::type const &>
392         (const_cast<T &>(t).get<N>()); }
393
394 }  // interface5
395 } // tbb
396
397 #if TBB_IMPLEMENT_CPP0X
398 namespace std {
399 using tbb::interface5::tuple;
400 using tbb::interface5::tuple_size;
401 using tbb::interface5::tuple_element;
402 using tbb::interface5::get;
403 }
404 #endif
405  
406 #endif /* __TBB_tuple_H */