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