summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/assimp/code/BoostWorkaround/boost/tuple/tuple.hpp
blob: 3c1dd7b33c7bf2a6e783278ef834abf8c302c254 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
// A very small replacement for boost::tuple
// (c) Alexander Gessler, 2008 [alexander.gessler@gmx.net]

#ifndef BOOST_TUPLE_INCLUDED
#define BOOST_TUPLE_INCLUDED

namespace boost	{
	namespace detail	{

		// Represents an empty tuple slot (up to 5 supported)
		struct nulltype {};

		// For readable error messages
		struct tuple_component_idx_out_of_bounds;

		// To share some code for the const/nonconst versions of the getters
		template <bool b, typename T>
		struct ConstIf {
			typedef T t;
		};

		template <typename T>
		struct ConstIf<true,T> {
			typedef const T t;
		};

		// Predeclare some stuff
		template <typename, unsigned, typename, bool, unsigned> struct value_getter;

		// Helper to obtain the type of a tuple element
		template <typename T, unsigned NIDX, typename TNEXT, unsigned N /*= 0*/>
		struct type_getter	{
			typedef type_getter<typename TNEXT::type,NIDX+1,typename TNEXT::next_type,N> next_elem_getter;
			typedef typename next_elem_getter::type type;
		};

		template <typename T, unsigned NIDX, typename TNEXT >
		struct type_getter <T,NIDX,TNEXT,NIDX>	{
			typedef T type;
		};

		// Base class for all explicit specializations of list_elem
		template <typename T, unsigned NIDX, typename TNEXT >
		struct list_elem_base {

			// Store template parameters
			typedef TNEXT next_type;
			typedef T type;

			static const unsigned nidx = NIDX;
		};

		// Represents an element in the tuple component list
		template <typename T, unsigned NIDX, typename TNEXT >
		struct list_elem : list_elem_base<T,NIDX,TNEXT>{

			// Real members
			T me;
			TNEXT next;

			// Get the value of a specific tuple element
			template <unsigned N>
			typename type_getter<T,NIDX,TNEXT,N>::type& get () {
				value_getter <T,NIDX,TNEXT,false,N> s;
				return s(*this);
			}

			// Get the value of a specific tuple element
			template <unsigned N>
			const typename type_getter<T,NIDX,TNEXT,N>::type& get () const {
				value_getter <T,NIDX,TNEXT,true,N> s;
				return s(*this);
			}

			// Explicit cast
			template <typename T2, typename TNEXT2 >
			operator list_elem<T2,NIDX,TNEXT2> () const	{
				list_elem<T2,NIDX,TNEXT2> ret;
				ret.me   = (T2)me;
				ret.next = next;
				return ret;
			}

			// Recursively compare two elements (last element returns always true)
			bool operator == (const list_elem& s) const	{
				return (me == s.me && next == s.next);
			}
		};

		// Represents a non-used tuple element - the very last element processed
		template <typename TNEXT, unsigned NIDX  >
		struct list_elem<nulltype,NIDX,TNEXT> : list_elem_base<nulltype,NIDX,TNEXT> {
			template <unsigned N, bool IS_CONST = true> struct value_getter		{
				/* just dummy members to produce readable error messages */
				tuple_component_idx_out_of_bounds operator () (typename ConstIf<IS_CONST,list_elem>::t& me);
			};
			template <unsigned N> struct type_getter  {
				/* just dummy members to produce readable error messages */
				typedef tuple_component_idx_out_of_bounds type;
			};

			// dummy
			list_elem& operator = (const list_elem& other)	{
				return *this;
			}

			// dummy
			bool operator == (const list_elem& other)	{
				return true;
			}
		};

		// Represents the absolute end of the list
		typedef list_elem<nulltype,0,int> list_end;

		// Helper obtain to query the value of a tuple element
		// NOTE: This can't be a nested class as the compiler won't accept a full or
		// partial specialization of a nested class of a non-specialized template
		template <typename T, unsigned NIDX, typename TNEXT, bool IS_CONST, unsigned N>
		struct value_getter	 {

			// calling list_elem
			typedef list_elem<T,NIDX,TNEXT> outer_elem;

			// typedef for the getter for next element
			typedef value_getter<typename TNEXT::type,NIDX+1,typename TNEXT::next_type,
				IS_CONST, N> next_value_getter;

			typename ConstIf<IS_CONST,typename type_getter<T,NIDX,TNEXT,N>::type>::t&
				operator () (typename ConstIf<IS_CONST,outer_elem >::t& me) {

				next_value_getter s;
				return s(me.next);
			}
		};

		template <typename T, unsigned NIDX, typename TNEXT, bool IS_CONST>
		struct value_getter <T,NIDX,TNEXT,IS_CONST,NIDX>	{
			typedef list_elem<T,NIDX,TNEXT> outer_elem;

			typename ConstIf<IS_CONST,T>::t& operator () (typename ConstIf<IS_CONST,outer_elem >::t& me) {
				return me.me;
			}
		};
	};

	// A very minimal implementation for up to 5 elements
	template <typename T0  = detail::nulltype,
		      typename T1  = detail::nulltype,
			  typename T2  = detail::nulltype,
			  typename T3  = detail::nulltype,
			  typename T4  = detail::nulltype>
	class tuple	{

		template <typename T0b,
		      typename T1b,
			  typename T2b,
			  typename T3b,
			  typename T4b >
		friend class tuple;

	private:

		typedef detail::list_elem<T0,0,
					detail::list_elem<T1,1,
						detail::list_elem<T2,2,
							detail::list_elem<T3,3,
								detail::list_elem<T4,4,
									detail::list_end > > > > > very_long;

		very_long m;

	public:

		// Get a specific tuple element
		template <unsigned N>
		typename detail::type_getter<T0,0,typename very_long::next_type, N>::type& get ()	{
			return m.template get<N>();
		}

		// ... and the const version
		template <unsigned N>
		const typename detail::type_getter<T0,0,typename very_long::next_type, N>::type& get () const	{
			return m.template get<N>();
		}


		// comparison operators
		bool operator== (const tuple& other) const	{
			return m == other.m;
		}

		// ... and the other way round
		bool operator!= (const tuple& other) const	{
			return !(m == other.m);
		}

		// cast to another tuple - all single elements must be convertible
		template <typename T0b, typename T1b,typename T2b,typename T3b, typename T4b>
		operator tuple <T0b,T1b,T2b,T3b,T4b> () const {
			tuple <T0b,T1b,T2b,T3b,T4b> s;
			s.m = (typename tuple <T0b,T1b,T2b,T3b,T4b>::very_long)m;
			return s;
		}
	};

	// Another way to access an element ...
	template <unsigned N,typename T0,typename T1,typename T2,typename T3,typename T4>
	inline typename tuple<T0,T1,T2,T3,T4>::very_long::template type_getter<N>::type& get (
			tuple<T0,T1,T2,T3,T4>& m)	{
			return m.template get<N>();
		}

	// ... and the const version
	template <unsigned N,typename T0,typename T1,typename T2,typename T3,typename T4>
	inline const typename tuple<T0,T1,T2,T3,T4>::very_long::template type_getter<N>::type& get (
			const tuple<T0,T1,T2,T3,T4>& m)	{
			return m.template get<N>();
		}

	// Constructs a tuple with 5 elements
	template <typename T0,typename T1,typename T2,typename T3,typename T4>
	inline tuple <T0,T1,T2,T3,T4> make_tuple (const T0& t0,
		const T1& t1,const T2& t2,const T3& t3,const T4& t4) {

		tuple <T0,T1,T2,T3,T4> t;
		t.template get<0>() = t0;
		t.template get<1>() = t1;
		t.template get<2>() = t2;
		t.template get<3>() = t3;
		t.template get<4>() = t4;
		return t;
	}

	// Constructs a tuple with 4 elements
	template <typename T0,typename T1,typename T2,typename T3>
	inline tuple <T0,T1,T2,T3> make_tuple (const T0& t0,
		const T1& t1,const T2& t2,const T3& t3) {
		tuple <T0,T1,T2,T3> t;
		t.template get<0>() = t0;
		t.template get<1>() = t1;
		t.template get<2>() = t2;
		t.template get<3>() = t3;
		return t;
	}

	// Constructs a tuple with 3 elements
	template <typename T0,typename T1,typename T2>
	inline tuple <T0,T1,T2> make_tuple (const T0& t0,
		const T1& t1,const T2& t2) {
		tuple <T0,T1,T2> t;
		t.template get<0>() = t0;
		t.template get<1>() = t1;
		t.template get<2>() = t2;
		return t;
	}

	// Constructs a tuple with 2 elements 
	template <typename T0,typename T1>
	inline tuple <T0,T1> make_tuple (const T0& t0,
		const T1& t1) {
		tuple <T0,T1> t;
		t.template get<0>() = t0;
		t.template get<1>() = t1;
		return t;
	}

	// Constructs a tuple with 1 elements (well ...)
	template <typename T0>
	inline tuple <T0> make_tuple (const T0& t0) {
		tuple <T0> t;
		t.template get<0>() = t0;
		return t;
	}

	// Constructs a tuple with 0 elements (well ...)
	inline tuple <> make_tuple () {
		tuple <> t = tuple <> ();
		return t;
	}
};

#endif // !! BOOST_TUPLE_INCLUDED