vrshoot

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