00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043 #ifndef LASS_GUARDIAN_OF_INCLUSION_META_TUPLE_H
00044 #define LASS_GUARDIAN_OF_INCLUSION_META_TUPLE_H
00045
00046 #include "meta_common.h"
00047 #include "type_list.h"
00048 #include "empty_type.h"
00049
00050 namespace lass
00051 {
00052 namespace meta
00053 {
00054
00055 template <typename TList> class Tuple;
00056
00057 template <typename H, typename Ts>
00058 class Tuple< TypeList<H, Ts> >: public Tuple<Ts>
00059 {
00060 public:
00061 typedef H TValue;
00062 typedef Tuple<Ts> TTail;
00063 typedef TypeList<H, Ts> TList;
00064 Tuple(): value_() {}
00065 const H& value() const { return value_; }
00066 H& value() { return value_; }
00067 private:
00068 H value_;
00069 };
00070
00071 template <typename Ts>
00072 class Tuple< TypeList<meta::EmptyType, Ts> >: public Tuple<Ts>
00073 {
00074 public:
00075 typedef meta::EmptyType TValue;
00076 typedef Tuple<Ts> TTail;
00077 typedef TypeList<meta::EmptyType, Ts> TList;
00078 const meta::EmptyType& value() const { return meta::EmptyType::instance(); }
00079 meta::EmptyType& value() { return meta::EmptyType::instance(); }
00080 };
00081
00082 template <>
00083 class Tuple<meta::NullType>
00084 {
00085 public:
00086 typedef meta::NullType TValue;
00087 typedef meta::NullType TTail;
00088 typedef meta::NullType TList;
00089 };
00090
00091
00092
00093 namespace tuple
00094 {
00095
00096 template <typename TupleType, size_t index>
00097 struct Field
00098 {
00099 typedef typename type_list::At<typename TupleType::TList, index>::Type Type;
00100 };
00101
00102 template <typename TupleType, size_t index>
00103 struct Field<const TupleType, index>
00104 {
00105 typedef const typename type_list::At<typename TupleType::TList, index>::Type Type;
00106 };
00107
00108
00109
00110 template <typename TupleType, size_t index> struct SubType;
00111
00112 template <typename H, typename Ts, size_t index>
00113 struct SubType< Tuple< TypeList<H, Ts> >, index >: public SubType< Tuple<Ts>, index - 1 >
00114 {
00115 };
00116
00117 template <typename H, typename Ts>
00118 struct SubType< Tuple< TypeList<H, Ts> >, 0 >
00119 {
00120 typedef Tuple< TypeList<H, Ts> > Type;
00121 };
00122
00123 template <typename H, typename Ts, size_t index>
00124 struct SubType< const Tuple< TypeList<H, Ts> >, index >: public SubType< const Tuple<Ts>, index - 1 >
00125 {
00126 };
00127
00128 template <typename H, typename Ts>
00129 struct SubType< const Tuple< TypeList<H, Ts> >, 0 >
00130 {
00131 typedef const Tuple< TypeList<H, Ts> > Type;
00132 };
00133
00134
00135
00136 template <size_t index, typename TupleType>
00137 typename Field<TupleType, index>::Type& field(TupleType& tuple)
00138 {
00139 typedef typename SubType<TupleType, index>::Type TSubType;
00140 return static_cast<TSubType&>(tuple).value();
00141 }
00142
00143
00144
00145 namespace impl
00146 {
00147 template <typename TupleType> struct ForEach;
00148 template <typename H, typename Ts>
00149 struct ForEach< Tuple< TypeList<H, Ts> > >
00150 {
00151 template <typename Functor> static void call(Tuple< TypeList<H, Ts> >& tuple, Functor& fun)
00152 {
00153 fun(tuple.value());
00154 ForEach< Tuple<Ts> >::call(tuple, fun);
00155 }
00156 };
00157 template <typename Ts>
00158 struct ForEach< Tuple< TypeList<meta::EmptyType, Ts> > >
00159 {
00160 template <typename Functor> static void call(Tuple< TypeList<meta::EmptyType, Ts> >& tuple, Functor& fun)
00161 {
00162 ForEach< Tuple<Ts> >::call(tuple, fun);
00163 }
00164 };
00165 template <>
00166 struct ForEach< Tuple< meta::NullType> >
00167 {
00168 template <typename Functor> static void call(Tuple<meta::NullType>& tuple, Functor& fun)
00169 {
00170 }
00171 };
00172 }
00173
00174 template <typename TupleType, typename Functor>
00175 void forEach(TupleType& tuple, Functor& fun)
00176 {
00177 impl::ForEach<TupleType>::call(tuple, fun);
00178 }
00179
00180
00181
00182 }
00183
00184 }
00185 }
00186
00187 #endif
00188
00189