00001 00002 00003 00004 00005 #ifndef TYPELIST_H 00006 #define TYPELIST_H 00007 00009 00010 namespace X3DTK { 00011 00014 00015 class nil {}; 00016 00017 template<class H, class T = nil> 00018 struct tlist 00019 { 00020 typedef H head_type; 00021 typedef T tail_type; 00022 }; 00023 00026 00027 template<class TL, class F> struct findIn; 00028 00029 template<class H, class T, class F> 00030 struct findIn<tlist<H, T>, F> 00031 { 00032 enum {result = findIn<T, F>::result}; 00033 }; 00034 00035 template<class T, class F> 00036 struct findIn<tlist<F, T>, F> 00037 { 00038 enum {result = true}; 00039 }; 00040 00041 template<class T> 00042 struct findIn<nil, T> 00043 { 00044 enum {result = false}; 00045 }; 00046 00049 00050 template<class TL> class clist; 00051 00052 template<class H, class T> 00053 class clist<tlist<H, T> > : public H, public clist<T> 00054 { 00055 public: 00056 template<class F, bool optional> 00057 F &get(); 00058 00059 template<class F, bool optional> 00060 const F &get() const; 00061 00062 template<class F> 00063 inline static bool find(); 00064 }; 00065 00066 template<class H> 00067 class clist<tlist<H, nil> > : public H 00068 { 00069 public: 00070 template<class F, bool optional> 00071 F &get(); 00072 00073 template<class F, bool optional> 00074 const F &get() const; 00075 00076 template<class F> 00077 inline static bool find(); 00078 }; 00079 00080 template<class T, class F, bool present, bool optional> struct Get; 00081 00082 template<class T, class F, bool optional> 00083 struct Get<T, F, true, optional> 00084 { 00085 inline static F &apply(clist<T> &t) 00086 { 00087 return t; 00088 }; 00089 }; 00090 00091 template<class T, class F> 00092 struct Get<T, F, false, true> 00093 { 00094 static F &apply(clist<T> &t) 00095 { 00096 static F f; 00097 return f; 00098 }; 00099 }; 00100 00101 template<class H, class T> 00102 template<class F> 00103 bool clist<tlist<H, T> >::find() 00104 { 00105 return findIn<tlist<H, T>, F>::result; 00106 } 00107 00108 template<class H, class T> 00109 template<class F, bool optional> 00110 F &clist<tlist<H, T> >::get() 00111 { 00112 return Get<tlist<H, T>, F, findIn<tlist<H, T>, F>::result, optional>::apply(*this); 00113 } 00114 00115 template<class H, class T> 00116 template<class F, bool optional> 00117 const F &clist<tlist<H, T> >::get() const 00118 { 00119 return Get<tlist<H, T>, F, findIn<tlist<H, T>, F>::result, optional>::apply(*this); 00120 } 00121 00122 00123 template<class H> 00124 template<class F> 00125 bool clist<tlist<H, nil> >::find() 00126 { 00127 return findIn<tlist<H, nil>, F>::result; 00128 } 00129 00130 template<class H> 00131 template<class F, bool optional> 00132 F &clist<tlist<H, nil> >::get() 00133 { 00134 return Get<tlist<H, nil>, F, findIn<tlist<H, nil>, F>::result, optional>::apply(*this); 00135 } 00136 00137 template<class H> 00138 template<class F, bool optional> 00139 const F &clist<tlist<H, nil> >::get() const 00140 { 00141 return Get<tlist<H, nil>, F, findIn<tlist<H, nil>, F>::result, optional>::apply(*this); 00142 } 00143 00144 } 00145 00146 #endif