00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef __MMX_DISPATCHER_HPP
00014 #define __MMX_DISPATCHER_HPP
00015 #include <basix/function.hpp>
00016
00017 namespace mmx {
00018
00019
00020
00021
00022
00023 template<typename R>
00024 struct invalidator_1_rep: public function_0_rep<void> {
00025 typedef function_0<void> INV;
00026 INV prev;
00027 R** tab;
00028 int* old_len;
00029 int* new_len;
00030 inline invalidator_1_rep (const INV& p2, R** t2, int* ol, int* nl):
00031 prev (p2), tab (t2), old_len (ol), new_len (nl) {}
00032 void apply () {
00033 if (!is_nil (prev)) prev ();
00034
00035 mmx_delete<R> (*tab, *old_len);
00036 *tab= mmx_new<R> (*new_len);
00037 *old_len= *new_len; }
00038 };
00039
00040 template<typename R> function_0<void>
00041 invalidator_1 (const function_0<void>& p2, R** t2, int* ol, int* nl) {
00042 return function_0<void> (new invalidator_1_rep<R> (p2, t2, ol, nl));
00043 }
00044
00045 template<typename R>
00046 struct dispatcher_1_rep REP_STRUCT {
00047 typedef function_1<R,const int&> LUP;
00048 typedef function_0<void> INV;
00049 LUP* lookup;
00050 INV* invalidate;
00051 int* len;
00052 bool* refresh;
00053 R* tab;
00054 int n;
00055
00056 inline dispatcher_1_rep (LUP& lup, INV& inv, int& l, bool& r):
00057 lookup (&lup), invalidate (&inv),
00058 len (&l), refresh (&r),
00059 tab (mmx_new<R> (l)), n (l) {
00060 *invalidate= invalidator_1<R> (*invalidate, &tab, &n, len); }
00061 inline ~dispatcher_1_rep () {
00062 mmx_delete<R> (tab, n); }
00063 inline R& dispatch (int i) {
00064
00065 if (*refresh) { (*invalidate) (); *refresh= false; }
00066 R& r= tab[i];
00067 if (is_nil (r)) r= (*lookup) (i);
00068 return r; }
00069 };
00070
00071 template<typename R>
00072 struct dispatcher_1 {
00073 typedef function_1<R,const int&> LUP;
00074 typedef function_0<void> INV;
00075 dispatcher_1_rep<R>* rep;
00076 inline dispatcher_1 (): rep (NULL) {}
00077 inline dispatcher_1 (const dispatcher_1& f):
00078 rep (f.rep) { INC_NULL_COUNT(rep); }
00079 inline dispatcher_1 (LUP& lup, INV& inv, int& l, bool& r):
00080 rep (new dispatcher_1_rep<R> (lup, inv, l, r)) {}
00081 inline ~dispatcher_1 () { DEC_NULL_COUNT (rep); }
00082 inline dispatcher_1& operator = (const dispatcher_1& f) {
00083 INC_NULL_COUNT (f.rep); DEC_NULL_COUNT (rep);
00084 rep= f.rep; return *this; }
00085 };
00086
00087
00088
00089
00090
00091 template<typename R>
00092 struct invalidator_2_rep: public function_0_rep<void> {
00093 typedef function_0<void> INV;
00094 INV prev;
00095 R** tab;
00096 int* old_len_1;
00097 int* old_len_2;
00098 int* new_len_1;
00099 int* new_len_2;
00100 inline invalidator_2_rep (const INV& p2, R** t2,
00101 int* ol1, int* ol2, int* nl1, int* nl2):
00102 prev (p2), tab (t2),
00103 old_len_1 (ol1), old_len_2 (ol2),
00104 new_len_1 (nl1), new_len_2 (nl2) {}
00105 void apply () {
00106 if (!is_nil (prev)) prev ();
00107 mmx_delete<R> (*tab, (*old_len_1) * (*old_len_2));
00108 *tab= mmx_new<R> ((*new_len_1) * (*new_len_2));
00109 *old_len_1= *new_len_1;
00110 *old_len_2= *new_len_2; }
00111 };
00112
00113 template<typename R> function_0<void>
00114 invalidator_2 (const function_0<void>& p2, R** t2,
00115 int* ol1, int* ol2, int* nl1, int* nl2) {
00116 return
00117 function_0<void> (new invalidator_2_rep<R> (p2, t2, ol1, ol2, nl1, nl2));
00118 }
00119
00120 template<typename R>
00121 struct dispatcher_2_rep REP_STRUCT {
00122 typedef function_2<R,const int&,const int&> LUP;
00123 typedef function_0<void> INV;
00124 LUP* lookup;
00125 INV* invalidate_1;
00126 INV* invalidate_2;
00127 int* len_1;
00128 int* len_2;
00129 bool* refresh_1;
00130 bool* refresh_2;
00131 R* tab;
00132 int n_1;
00133 int n_2;
00134
00135 inline dispatcher_2_rep (LUP& lup, INV& inv1, INV& inv2,
00136 int& l1, int& l2, bool& r1, bool& r2):
00137 lookup (&lup),
00138 invalidate_1 (&inv1), invalidate_2 (&inv2),
00139 len_1 (&l1), len_2 (&l2),
00140 refresh_1 (&r1), refresh_2 (&r2),
00141 tab (mmx_new<R> (l1 * l2)),
00142 n_1 (l1), n_2 (l2) {
00143 *invalidate_1= invalidator_2<R> (*invalidate_1, &tab,
00144 &n_1, &n_2, len_1, len_2);
00145 if (refresh_2 != refresh_1)
00146 *invalidate_2= invalidator_2<R> (*invalidate_2, &tab,
00147 &n_1, &n_2, len_1, len_2); }
00148 inline ~dispatcher_2_rep () {
00149 mmx_delete<R> (tab, n_1 * n_2); }
00150 inline R& dispatch (int i1, int i2) {
00151
00152 if (*refresh_1) { (*invalidate_1) (); *refresh_1= false; }
00153 if (*refresh_2) { (*invalidate_2) (); *refresh_2= false; }
00154 R& r= tab[i1 * n_2 + i2];
00155 if (is_nil (r)) r= (*lookup) (i1, i2);
00156 return r; }
00157 };
00158
00159 template<typename R>
00160 struct dispatcher_2 {
00161 typedef function_2<R,const int&,const int&> LUP;
00162 typedef function_0<void> INV;
00163 dispatcher_2_rep<R>* rep;
00164 inline dispatcher_2 (): rep (NULL) {}
00165 inline dispatcher_2 (const dispatcher_2& f):
00166 rep (f.rep) { INC_NULL_COUNT(rep); }
00167 inline dispatcher_2 (LUP& lup, INV& inv1, INV& inv2,
00168 int& l1, int& l2, bool& r1, bool& r2):
00169 rep (new dispatcher_2_rep<R> (lup, inv1, inv2, l1, l2, r1, r2)) {}
00170 inline ~dispatcher_2 () { DEC_NULL_COUNT (rep); }
00171 inline dispatcher_2& operator = (const dispatcher_2& f) {
00172 INC_NULL_COUNT (f.rep); DEC_NULL_COUNT (rep);
00173 rep= f.rep; return *this; }
00174 };
00175
00176 }
00177
00178 using namespace mmx;
00179 #endif // __MMX_DISPATCHER_HPP