00001 #ifndef X3DTK_TYPELIST_H 00002 #define X3DTK_TYPELIST_H 00003 00004 namespace X3DTK { 00005 00008 00015 class nil {}; 00016 00023 template<class H, class T = nil> 00024 struct tlist 00025 { 00027 typedef H head_type; 00029 typedef T tail_type; 00030 }; 00031 00032 #ifndef DOXYGEN 00033 00036 00037 template<class TL, class F> struct findIn; 00038 00039 template<class H, class T, class F> 00040 struct findIn<tlist<H, T>, F> 00041 { 00042 enum {result = findIn<T, F>::result}; 00043 }; 00044 00045 template<class T, class F> 00046 struct findIn<tlist<F, T>, F> 00047 { 00048 enum {result = true}; 00049 }; 00050 00051 template<class T> 00052 struct findIn<nil, T> 00053 { 00054 enum {result = false}; 00055 }; 00056 00057 #endif 00058 00061 00062 template<class TL> class clist; 00063 00070 template<class H, class T> 00071 class clist<tlist<H, T> > : public H, public clist<T> 00072 { 00073 public: 00074 template<class F, bool optional> 00075 F &get(); 00076 00077 template<class F, bool optional> 00078 const F &get() const; 00079 00080 template<class F> 00081 inline static bool find(); 00082 }; 00083 00084 #ifndef DOXYGEN 00085 00086 template<class H> 00087 class clist<tlist<H, nil> > : public H 00088 { 00089 public: 00090 template<class F, bool optional> 00091 F &get(); 00092 00093 template<class F, bool optional> 00094 const F &get() const; 00095 00096 template<class F> 00097 inline static bool find(); 00098 }; 00099 00100 template<class T, class F, bool present, bool optional> struct Get; 00101 00102 template<class T, class F, bool optional> 00103 struct Get<T, F, true, optional> 00104 { 00105 inline static F &apply(clist<T> &t) 00106 { 00107 return t; 00108 }; 00109 }; 00110 00111 template<class T, class F> 00112 struct Get<T, F, false, true> 00113 { 00114 static F &apply(clist<T> &t) 00115 { 00116 static F f; 00117 return f; 00118 }; 00119 }; 00120 00121 template<class H, class T> 00122 template<class F> 00123 bool clist<tlist<H, T> >::find() 00124 { 00125 return findIn<tlist<H, T>, F>::result; 00126 } 00127 00128 template<class H, class T> 00129 template<class F, bool optional> 00130 F &clist<tlist<H, T> >::get() 00131 { 00132 return Get<tlist<H, T>, F, findIn<tlist<H, T>, F>::result, optional>::apply(*this); 00133 } 00134 00135 template<class H, class T> 00136 template<class F, bool optional> 00137 const F &clist<tlist<H, T> >::get() const 00138 { 00139 return Get<tlist<H, T>, F, findIn<tlist<H, T>, F>::result, optional>::apply(*this); 00140 } 00141 00142 00143 template<class H> 00144 template<class F> 00145 bool clist<tlist<H, nil> >::find() 00146 { 00147 return findIn<tlist<H, nil>, F>::result; 00148 } 00149 00150 template<class H> 00151 template<class F, bool optional> 00152 F &clist<tlist<H, nil> >::get() 00153 { 00154 return Get<tlist<H, nil>, F, findIn<tlist<H, nil>, F>::result, optional>::apply(*this); 00155 } 00156 00157 template<class H> 00158 template<class F, bool optional> 00159 const F &clist<tlist<H, nil> >::get() const 00160 { 00161 return Get<tlist<H, nil>, F, findIn<tlist<H, nil>, F>::result, optional>::apply(*this); 00162 } 00163 00164 #endif 00165 00166 } 00167 00168 #endif