vrshoot

view libs/assimp/boost/tuple/tuple.hpp @ 0:b2f14e535253

initial commit
author John Tsiombikas <nuclear@member.fsf.org>
date Sat, 01 Feb 2014 19:58:19 +0200
parents
children
line source
1 // A very small replacement for boost::tuple
2 // (c) Alexander Gessler, 2008 [alexander.gessler@gmx.net]
4 #ifndef BOOST_TUPLE_INCLUDED
5 #define BOOST_TUPLE_INCLUDED
7 namespace boost {
8 namespace detail {
10 // Represents an empty tuple slot (up to 5 supported)
11 struct nulltype {};
13 // For readable error messages
14 struct tuple_component_idx_out_of_bounds;
16 // To share some code for the const/nonconst versions of the getters
17 template <bool b, typename T>
18 struct ConstIf {
19 typedef T t;
20 };
22 template <typename T>
23 struct ConstIf<true,T> {
24 typedef const T t;
25 };
27 // Predeclare some stuff
28 template <typename, unsigned, typename, bool, unsigned> struct value_getter;
30 // Helper to obtain the type of a tuple element
31 template <typename T, unsigned NIDX, typename TNEXT, unsigned N /*= 0*/>
32 struct type_getter {
33 typedef type_getter<typename TNEXT::type,NIDX+1,typename TNEXT::next_type,N> next_elem_getter;
34 typedef typename next_elem_getter::type type;
35 };
37 template <typename T, unsigned NIDX, typename TNEXT >
38 struct type_getter <T,NIDX,TNEXT,NIDX> {
39 typedef T type;
40 };
42 // Base class for all explicit specializations of list_elem
43 template <typename T, unsigned NIDX, typename TNEXT >
44 struct list_elem_base {
46 // Store template parameters
47 typedef TNEXT next_type;
48 typedef T type;
50 static const unsigned nidx = NIDX;
51 };
53 // Represents an element in the tuple component list
54 template <typename T, unsigned NIDX, typename TNEXT >
55 struct list_elem : list_elem_base<T,NIDX,TNEXT>{
57 // Real members
58 T me;
59 TNEXT next;
61 // Get the value of a specific tuple element
62 template <unsigned N>
63 typename type_getter<T,NIDX,TNEXT,N>::type& get () {
64 value_getter <T,NIDX,TNEXT,false,N> s;
65 return s(*this);
66 }
68 // Get the value of a specific tuple element
69 template <unsigned N>
70 const typename type_getter<T,NIDX,TNEXT,N>::type& get () const {
71 value_getter <T,NIDX,TNEXT,true,N> s;
72 return s(*this);
73 }
75 // Explicit cast
76 template <typename T2, typename TNEXT2 >
77 operator list_elem<T2,NIDX,TNEXT2> () const {
78 list_elem<T2,NIDX,TNEXT2> ret;
79 ret.me = (T2)me;
80 ret.next = next;
81 return ret;
82 }
84 // Recursively compare two elements (last element returns always true)
85 bool operator == (const list_elem& s) const {
86 return (me == s.me && next == s.next);
87 }
88 };
90 // Represents a non-used tuple element - the very last element processed
91 template <typename TNEXT, unsigned NIDX >
92 struct list_elem<nulltype,NIDX,TNEXT> : list_elem_base<nulltype,NIDX,TNEXT> {
93 template <unsigned N, bool IS_CONST = true> struct value_getter {
94 /* just dummy members to produce readable error messages */
95 tuple_component_idx_out_of_bounds operator () (typename ConstIf<IS_CONST,list_elem>::t& me);
96 };
97 template <unsigned N> struct type_getter {
98 /* just dummy members to produce readable error messages */
99 typedef tuple_component_idx_out_of_bounds type;
100 };
102 // dummy
103 list_elem& operator = (const list_elem& other) {
104 return *this;
105 }
107 // dummy
108 bool operator == (const list_elem& other) {
109 return true;
110 }
111 };
113 // Represents the absolute end of the list
114 typedef list_elem<nulltype,0,int> list_end;
116 // Helper obtain to query the value of a tuple element
117 // NOTE: This can't be a nested class as the compiler won't accept a full or
118 // partial specialization of a nested class of a non-specialized template
119 template <typename T, unsigned NIDX, typename TNEXT, bool IS_CONST, unsigned N>
120 struct value_getter {
122 // calling list_elem
123 typedef list_elem<T,NIDX,TNEXT> outer_elem;
125 // typedef for the getter for next element
126 typedef value_getter<typename TNEXT::type,NIDX+1,typename TNEXT::next_type,
127 IS_CONST, N> next_value_getter;
129 typename ConstIf<IS_CONST,typename type_getter<T,NIDX,TNEXT,N>::type>::t&
130 operator () (typename ConstIf<IS_CONST,outer_elem >::t& me) {
132 next_value_getter s;
133 return s(me.next);
134 }
135 };
137 template <typename T, unsigned NIDX, typename TNEXT, bool IS_CONST>
138 struct value_getter <T,NIDX,TNEXT,IS_CONST,NIDX> {
139 typedef list_elem<T,NIDX,TNEXT> outer_elem;
141 typename ConstIf<IS_CONST,T>::t& operator () (typename ConstIf<IS_CONST,outer_elem >::t& me) {
142 return me.me;
143 }
144 };
145 };
147 // A very minimal implementation for up to 5 elements
148 template <typename T0 = detail::nulltype,
149 typename T1 = detail::nulltype,
150 typename T2 = detail::nulltype,
151 typename T3 = detail::nulltype,
152 typename T4 = detail::nulltype>
153 class tuple {
155 template <typename T0b,
156 typename T1b,
157 typename T2b,
158 typename T3b,
159 typename T4b >
160 friend class tuple;
162 private:
164 typedef detail::list_elem<T0,0,
165 detail::list_elem<T1,1,
166 detail::list_elem<T2,2,
167 detail::list_elem<T3,3,
168 detail::list_elem<T4,4,
169 detail::list_end > > > > > very_long;
171 very_long m;
173 public:
175 // Get a specific tuple element
176 template <unsigned N>
177 typename detail::type_getter<T0,0,typename very_long::next_type, N>::type& get () {
178 return m.template get<N>();
179 }
181 // ... and the const version
182 template <unsigned N>
183 const typename detail::type_getter<T0,0,typename very_long::next_type, N>::type& get () const {
184 return m.template get<N>();
185 }
188 // comparison operators
189 bool operator== (const tuple& other) const {
190 return m == other.m;
191 }
193 // ... and the other way round
194 bool operator!= (const tuple& other) const {
195 return !(m == other.m);
196 }
198 // cast to another tuple - all single elements must be convertible
199 template <typename T0b, typename T1b,typename T2b,typename T3b, typename T4b>
200 operator tuple <T0b,T1b,T2b,T3b,T4b> () const {
201 tuple <T0b,T1b,T2b,T3b,T4b> s;
202 s.m = (typename tuple <T0b,T1b,T2b,T3b,T4b>::very_long)m;
203 return s;
204 }
205 };
207 // Another way to access an element ...
208 template <unsigned N,typename T0,typename T1,typename T2,typename T3,typename T4>
209 inline typename tuple<T0,T1,T2,T3,T4>::very_long::template type_getter<N>::type& get (
210 tuple<T0,T1,T2,T3,T4>& m) {
211 return m.template get<N>();
212 }
214 // ... and the const version
215 template <unsigned N,typename T0,typename T1,typename T2,typename T3,typename T4>
216 inline const typename tuple<T0,T1,T2,T3,T4>::very_long::template type_getter<N>::type& get (
217 const tuple<T0,T1,T2,T3,T4>& m) {
218 return m.template get<N>();
219 }
221 // Constructs a tuple with 5 elements
222 template <typename T0,typename T1,typename T2,typename T3,typename T4>
223 inline tuple <T0,T1,T2,T3,T4> make_tuple (const T0& t0,
224 const T1& t1,const T2& t2,const T3& t3,const T4& t4) {
226 tuple <T0,T1,T2,T3,T4> t;
227 t.template get<0>() = t0;
228 t.template get<1>() = t1;
229 t.template get<2>() = t2;
230 t.template get<3>() = t3;
231 t.template get<4>() = t4;
232 return t;
233 }
235 // Constructs a tuple with 4 elements
236 template <typename T0,typename T1,typename T2,typename T3>
237 inline tuple <T0,T1,T2,T3> make_tuple (const T0& t0,
238 const T1& t1,const T2& t2,const T3& t3) {
239 tuple <T0,T1,T2,T3> t;
240 t.template get<0>() = t0;
241 t.template get<1>() = t1;
242 t.template get<2>() = t2;
243 t.template get<3>() = t3;
244 return t;
245 }
247 // Constructs a tuple with 3 elements
248 template <typename T0,typename T1,typename T2>
249 inline tuple <T0,T1,T2> make_tuple (const T0& t0,
250 const T1& t1,const T2& t2) {
251 tuple <T0,T1,T2> t;
252 t.template get<0>() = t0;
253 t.template get<1>() = t1;
254 t.template get<2>() = t2;
255 return t;
256 }
258 // Constructs a tuple with 2 elements
259 template <typename T0,typename T1>
260 inline tuple <T0,T1> make_tuple (const T0& t0,
261 const T1& t1) {
262 tuple <T0,T1> t;
263 t.template get<0>() = t0;
264 t.template get<1>() = t1;
265 return t;
266 }
268 // Constructs a tuple with 1 elements (well ...)
269 template <typename T0>
270 inline tuple <T0> make_tuple (const T0& t0) {
271 tuple <T0> t;
272 t.template get<0>() = t0;
273 return t;
274 }
276 // Constructs a tuple with 0 elements (well ...)
277 inline tuple <> make_tuple () {
278 tuple <> t;
279 return t;
280 }
281 };
283 #endif // !! BOOST_TUPLE_INCLUDED