Phoenix
Object-oriented orthogonally persistent operating system
|
00001 /* 00002 * /phoenix/include/triton/tuple.h 00003 * 00004 * This file is a part of Phoenix operating system. 00005 * Copyright (c) 2011-2012, Artyom Lebedev <artyom.lebedev@gmail.com> 00006 * All rights reserved. 00007 * See COPYING file for copyright details. 00008 */ 00009 00014 #ifndef TUPLE_H_ 00015 #define TUPLE_H_ 00016 00017 namespace triton { 00018 00020 namespace triton_internal { 00021 00027 template <int idx, typename T, typename... components> 00028 struct TupleTypeImpl { 00029 typedef typename TupleTypeImpl<idx - 1, components...>::Type Type; 00030 }; 00031 00032 template <typename T, typename... components> 00033 struct TupleTypeImpl<0, T, components...> { 00034 typedef T Type; 00035 }; 00036 00042 template <int idx, typename... components> 00043 using TupleType = typename TupleTypeImpl<idx, components...>::Type; 00044 00046 template <typename... components> 00047 class TupleStorage; 00048 00049 template <> class TupleStorage<> { }; 00050 00051 template <typename T, typename... components> 00052 class TupleStorage<T, components...>: public TupleStorage<components...> { 00053 public: 00055 T value; 00057 typedef TupleStorage<components...> BaseType; 00058 00060 inline 00061 TupleStorage(add_const_reference<T> firstValue, 00062 add_const_reference<components>... restValues) : 00063 BaseType(restValues...), value(firstValue) {} 00064 00065 TupleStorage(const TupleStorage<T, components...> &src) : 00066 BaseType(static_cast<const BaseType &>(src)), value(src.value) {} 00067 }; 00068 00070 template <int idx, typename T, typename... components> 00071 class TupleGetter { 00072 public: 00073 static inline TupleType<idx, T, components...> & 00074 Get(TupleStorage<T, components...> &stg) 00075 { 00076 return TupleGetter<idx - 1, components...>::Get(stg); 00077 } 00078 00079 static inline Object::hash_t 00080 __hash__(const TupleStorage<T, components...> &stg) 00081 { 00082 u32 h1 = TupleGetter<idx - 1, components...>::__hash__(stg); 00083 u32 h2 = hash(stg.value); 00084 u32 h3 = idx; 00085 Hash::Mix(h1, h2, h3); 00086 return static_cast<Object::hash_t>(h2) << 32 | h3; 00087 } 00088 }; 00089 00090 template <typename T, typename... components> 00091 class TupleGetter<0, T, components...> { 00092 public: 00093 static inline T & 00094 Get(TupleStorage<T, components...> &stg) 00095 { 00096 return stg.value; 00097 } 00098 00099 static inline Object::hash_t 00100 __hash__(const TupleStorage<T, components...> &stg) 00101 { 00102 return hash(stg.value); 00103 } 00104 }; 00105 00106 }; /* namespace triton_internal */ 00107 00109 template <class... components> 00110 class Tuple: public Container { 00111 private: 00112 triton_internal::TupleStorage<components...> _values; 00113 public: 00121 template <int idx> 00122 using Type = triton_internal::TupleType<idx, components...>; 00123 00124 inline 00125 Tuple(components... values) : _values(values...) {} 00126 00127 inline 00128 Tuple(const Tuple<components...> &t) : _values(t._values) {} 00129 00130 virtual const char * 00131 __name__() const 00132 { 00133 return "Tuple"; 00134 } 00135 00140 virtual size_t 00141 __len__() 00142 { 00143 return sizeof...(components); 00144 } 00145 00152 template <int idx> 00153 inline triton_internal::TupleType<idx, components...> & 00154 get() 00155 { 00156 return triton_internal::TupleGetter<idx, components...>::Get(_values); 00157 } 00158 00160 virtual Object::hash_t 00161 __hash__() const 00162 { 00163 return triton_internal:: 00164 TupleGetter<sizeof...(components) - 1, components...>:: 00165 __hash__(_values); 00166 } 00167 }; 00168 00169 } /* namespace triton */ 00170 00171 #endif /* TUPLE_H_ */