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