2 Copyright 2005-2011 Intel Corporation. All Rights Reserved.
4 This file is part of Threading Building Blocks.
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.
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.
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
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.
32 #if !TBB_PREVIEW_TUPLE
33 #error Set TBB_PREVIEW_TUPLE to include compat/tuple
37 #include "../tbb_stddef.h"
40 namespace interface5 {
44 using internal::null_type;
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>
52 // const null_type temp
53 inline const null_type cnull() { return null_type(); }
55 // cons forward declaration
56 template <class HT, class TT> struct cons;
58 // type of a component of the cons
59 template<int N, class T>
61 typedef typename T::tail_type next;
62 typedef typename component<N-1,next>::type type;
66 struct component<0,T> {
67 typedef typename T::head_type type;
71 struct component<0,null_type> {
72 typedef null_type type;
75 // const version of component
77 template<int N, class T>
78 struct component<N, const T>
80 typedef typename T::tail_type next;
81 typedef typename component<N-1,next>::type type;
85 struct component<0, const T>
87 typedef const typename T::head_type type;
91 // helper class for getting components of cons
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);
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) {
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;
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;
120 struct tuple_traits<null_type, null_type, null_type, null_type, null_type, null_type, null_type, null_type, null_type, null_type> {
126 template <class HT, class TT>
129 typedef HT head_type;
130 typedef TT tail_type;
135 static const int length = 1 + tail_type::length;
137 // default constructors
138 explicit cons() : head(), tail() { }
140 // non-default constructors
141 cons(head_type& h, const tail_type& t) : head(h), tail(t) { }
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()) { }
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()) { }
151 template <class HT1, class TT1>
152 cons(const cons<HT1,TT1>& other) : head(other.head), tail(other.tail) { }
154 cons& operator=(const cons& other) { head = other.head; tail = other.tail; return *this; }
156 friend bool operator==(const cons& me, const cons& other) {
157 return me.head == other.head && me.tail == other.tail;
159 friend bool operator<(const cons& me, const cons& other) {
160 return me.head < other.head || (!(other.head < me.head) && me.tail < other.tail);
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); }
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;
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);
177 template<class HT1, class TT1>
178 friend bool operator>(const cons<HT,TT>& me, const cons<HT1,TT1>& other) { return other<me; }
180 template<class HT1, class TT1>
181 friend bool operator!=(const cons<HT,TT>& me, const cons<HT1,TT1>& other) { return !(me==other); }
183 template<class HT1, class TT1>
184 friend bool operator>=(const cons<HT,TT>& me, const cons<HT1,TT1>& other) { return !(me<other); }
186 template<class HT1, class TT1>
187 friend bool operator<=(const cons<HT,TT>& me, const cons<HT1,TT1>& other) { return !(me>other); }
194 struct cons<HT,null_type> {
196 typedef HT head_type;
197 typedef null_type tail_type;
198 static const int length = 1;
201 // default constructor
202 cons() : head() { /*std::cout << "default constructor 1\n";*/ }
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";*/ }
206 // non-default constructor
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";*/}
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) { }
213 // converting constructor
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) { }
219 cons( const cons<HT1, null_type>& other) : head(other.head) { }
221 // assignment operator
222 cons& operator=(const cons& other) { head = other.head; return *this; }
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); }
232 friend bool operator==(const cons<HT,null_type>& me, const cons<HT1,null_type>& other) {
233 return me.head == other.head;
237 friend bool operator<(const cons<HT,null_type>& me, const cons<HT1,null_type>& other) {
238 return me.head < other.head;
242 friend bool operator>(const cons<HT,null_type>& me, const cons<HT1,null_type>& other) { return other<me; }
245 friend bool operator!=(const cons<HT,null_type>& me, const cons<HT1,null_type>& other) { return !(me==other); }
248 friend bool operator<=(const cons<HT,null_type>& me, const cons<HT1,null_type>& other) { return !(me>other); }
251 friend bool operator>=(const cons<HT,null_type>& me, const cons<HT1,null_type>& other) { return !(me<other); }
256 struct cons<null_type,null_type> { typedef null_type tail_type; static const int length = 0; };
258 // wrapper for default constructor
260 inline const T wrap_dcons(T*) { return T(); }
261 } // namespace internal
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 {
267 template <class T> friend class tuple_size;
268 template<int N, class T> friend struct tuple_element;
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;
278 typedef typename internal::tuple_traits<T0,T1,T2,T3, T4, T5, T6, T7, T8, T9>::U my_cons;
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)
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) { }
295 struct internal_tuple_element {
296 typedef typename internal::component<N,my_cons>::type type;
300 typename internal_tuple_element<N>::type& get() { return internal::get_helper<N>::get(*this); }
302 template<class U1, class U2>
303 tuple& operator=(const internal::cons<U1,U2>& other) {
304 my_cons::operator=(other);
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;
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);}
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);
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);
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);
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);
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);
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);
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;
366 static const size_t value = 1 + tuple_size<typename T::tail_type>::value;
370 class tuple_size<tuple<> > {
372 static const size_t value = 0;
376 class tuple_size<null_type> {
378 static const size_t value = 0;
381 template<int N, class T>
382 struct tuple_element {
383 typedef typename internal::component<N, typename T::my_cons>::type type;
386 template<int N, class T>
387 inline static typename tuple_element<N,T>::type& get(T &t) { return t.get<N>(); }
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>()); }
397 #if TBB_IMPLEMENT_CPP0X
399 using tbb::interface5::tuple;
400 using tbb::interface5::tuple_size;
401 using tbb::interface5::tuple_element;
402 using tbb::interface5::get;
406 #endif /* __TBB_tuple_H */