00001 #ifndef X3DTK_TYPELIST_H 00002 #define X3DTK_TYPELIST_H 00003 00004 #include "X3DBaseTypes.h" 00005 00006 namespace X3DTK { 00007 00008 #ifdef TEMPLATE_SPECIALIZATION_SUPPORTED 00009 00012 00019 template<class H, class T = nil> 00020 struct tlist 00021 { 00023 typedef H head_type; 00025 typedef T tail_type; 00026 }; 00027 00028 #ifndef DOXYGEN 00029 00032 00033 template<class TL, class F> struct findIn; 00034 00035 template<class H, class T, class F> 00036 struct findIn<tlist<H, T>, F> 00037 { 00038 enum {result = findIn<T, F>::result}; 00039 }; 00040 00041 template<class T, class F> 00042 struct findIn<tlist<F, T>, F> 00043 { 00044 enum {result = true}; 00045 }; 00046 00047 template<class T> 00048 struct findIn<nil, T> 00049 { 00050 enum {result = false}; 00051 }; 00052 00053 #endif 00054 00057 00058 template<class TL> class clist; 00059 00066 template<class H, class T> 00067 class clist<tlist<H, T> > : public H, public clist<T> 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 #ifndef DOXYGEN 00081 00082 template<class H> 00083 class clist<tlist<H, nil> > : public H 00084 { 00085 public: 00086 template<class F, bool optional> 00087 F &get(); 00088 00089 template<class F, bool optional> 00090 const F &get() const; 00091 00092 template<class F> 00093 inline static bool find(); 00094 }; 00095 00096 template<class T, class F, bool present, bool optional> struct Get; 00097 00098 template<class T, class F, bool optional> 00099 struct Get<T, F, true, optional> 00100 { 00101 inline static F &apply(clist<T> &t) 00102 { 00103 return t; 00104 }; 00105 }; 00106 00107 template<class T, class F> 00108 struct Get<T, F, false, true> 00109 { 00110 static F &apply(clist<T> &t) 00111 { 00112 static F f; 00113 return f; 00114 }; 00115 }; 00116 00117 template<class H, class T> 00118 template<class F> 00119 bool clist<tlist<H, T> >::find() 00120 { 00121 return findIn<tlist<H, T>, F>::result; 00122 } 00123 00124 template<class H, class T> 00125 template<class F, bool optional> 00126 F &clist<tlist<H, T> >::get() 00127 { 00128 return Get<tlist<H, T>, F, findIn<tlist<H, T>, F>::result, optional>::apply(*this); 00129 } 00130 00131 template<class H, class T> 00132 template<class F, bool optional> 00133 const F &clist<tlist<H, T> >::get() const 00134 { 00135 return Get<tlist<H, T>, F, findIn<tlist<H, T>, F>::result, optional>::apply(*this); 00136 } 00137 00138 00139 template<class H> 00140 template<class F> 00141 bool clist<tlist<H, nil> >::find() 00142 { 00143 return findIn<tlist<H, nil>, F>::result; 00144 } 00145 00146 template<class H> 00147 template<class F, bool optional> 00148 F &clist<tlist<H, nil> >::get() 00149 { 00150 return Get<tlist<H, nil>, F, findIn<tlist<H, nil>, F>::result, optional>::apply(*this); 00151 } 00152 00153 template<class H> 00154 template<class F, bool optional> 00155 const F &clist<tlist<H, nil> >::get() const 00156 { 00157 return Get<tlist<H, nil>, F, findIn<tlist<H, nil>, F>::result, optional>::apply(*this); 00158 } 00159 00160 #endif 00161 #endif 00162 00163 } 00164 00165 #endif