00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef __ALIAS_HPP
00014 #define __ALIAS_HPP
00015 #include <basix/vector.hpp>
00016 #include <basix/wrap.hpp>
00017
00019
00020 namespace mmx {
00021 #define TMPL template<typename C>
00022 #define Alias alias<C>
00023 #define Alias_rep alias_rep<C>
00024 #define Generic_alias generic_alias<C>
00025 class routine;
00026 TMPL class alias;
00027
00028
00029
00030
00031
00032 TMPL
00033 class alias_rep REP_STRUCT {
00034 protected:
00035 inline alias_rep () {}
00036 inline virtual ~alias_rep () {}
00037
00038 public:
00039 virtual C get () const = 0;
00040 virtual C& open () const = 0;
00041 virtual void close () const = 0;
00042 friend class Alias;
00043 };
00044
00045 TMPL
00046 class alias {
00047 INDIRECT_PROTO_1 (alias, alias_rep, C)
00048 public:
00049 inline const Alias_rep* operator * () const { return rep; }
00050 alias (const C& x);
00051 };
00052 INDIRECT_IMPL_1 (alias, alias_rep, typename C, C)
00053
00054 TMPL inline syntactic flatten (const Alias& a) { return flatten (a->get ()); }
00055 TMPL inline alias<C> new_alias (const C& c) { return alias<C> (c); }
00056 TMPL inline C get_alias (const Alias& a) { return a->get (); }
00057 TMPL inline C& open_alias (const Alias& a) { return a->open (); }
00058 TMPL inline void close_alias (const Alias& a) { a->close (); }
00059 TMPL inline C set_alias (const Alias& a, const C& c) {
00060 a->open ()= c; a->close (); return c; }
00061
00062 WRAP_INDIRECT_IMPL(TMPL inline,Alias)
00063
00064 TMPL
00065 struct binary_helper<Alias >: public void_binary_helper<Alias > {
00066 static inline string short_type_name () {
00067 return "Al" * Short_type_name (C); }
00068 static inline generic full_type_name () {
00069 return gen ("Alias", Full_type_name (C)); }
00070 };
00071
00072
00073
00074
00075
00076 TMPL
00077 class global_alias_rep: public Alias_rep {
00078 C& val;
00079 public:
00080 inline global_alias_rep (C& val2): val (val2) {}
00081 inline C get () const { return val; }
00082 inline C& open () const { return val; }
00083 inline void close () const {}
00084 };
00085
00086 TMPL Alias
00087 global_alias (C& c) {
00088 return new global_alias_rep<C> (c);
00089 }
00090
00091
00092
00093
00094
00095 TMPL
00096 class basic_alias_rep: public Alias_rep {
00097 C val;
00098 public:
00099 inline basic_alias_rep (const C& val2): val (val2) {}
00100 inline C get () const { return val; }
00101 inline C& open () const { return *(const_cast<C*> (&val)); }
00102 inline void close () const {}
00103 };
00104
00105 TMPL
00106 Alias::alias (const C& c) {
00107 rep= new basic_alias_rep<C> (c);
00108 }
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119 template<typename C>
00120 class generic_alias {
00121 MMX_ALLOCATORS
00122 alias<generic> rep;
00123 public:
00124 inline alias<generic> operator * () const { return rep; }
00125 inline generic_alias (const alias<generic>& a): rep (a) {}
00126 inline generic_alias (const Generic_alias& a): rep (a.rep) {}
00127 };
00128
00129 TMPL inline syntactic flatten (const Generic_alias& a) { return flatten (*a); }
00130 TMPL inline generic_alias<C> new_genalias (const alias<generic>& a) {
00131 return generic_alias<C> (a); }
00132 TMPL inline alias<generic> generalize_genalias (const Generic_alias& a) {
00133 return *a; }
00134 TMPL inline C get_genalias (const Generic_alias& a) {
00135 return as<C> ((*a)->get ()); }
00136 TMPL inline generic set_genalias (const Generic_alias& a, const generic& c) {
00137 return set_alias (*a, c); }
00138
00139 WRAP_WRAPPED_IMPL(TMPL inline,Generic_alias)
00140
00141
00142
00143
00144
00145 TMPL
00146 class incarnate_alias_rep: public Alias_rep {
00147 generic_alias<C> a;
00148 C* temp;
00149 public:
00150 inline incarnate_alias_rep (const generic_alias<C>& a2):
00151 a (a2), temp (NULL) {}
00152 inline ~incarnate_alias_rep () {
00153 ASSERT (temp == NULL, "destruction while accessing alias"); }
00154 inline C get () const { return get_genalias (a); }
00155 inline C& open () const {
00156 incarnate_alias_rep<C>* me= const_cast<incarnate_alias_rep<C>*> (this);
00157 me->temp= mmx_new_one<C> (as<C> (get_genalias (a)));
00158 return *me->temp; }
00159 inline void close () const {
00160 incarnate_alias_rep<C>* me= const_cast<incarnate_alias_rep<C>*> (this);
00161 set_genalias (a, as<generic> (*temp));
00162 mmx_delete_one<C> (me->temp);
00163 me->temp= NULL; }
00164 };
00165
00166 TMPL inline alias<C> incarnate_genalias (const generic_alias<C>& a) {
00167 return new incarnate_alias_rep<C> (a); }
00168
00169
00170
00171
00172
00173 void alias_type_info (nat& id, int& mode);
00174 void alias_specializer (nat id, routine& r);
00175 void alias_getter (nat id, routine& r);
00176 void alias_setter (nat id, routine& r);
00177 generic specialize_alias (const generic& a);
00178 generic get_alias (const generic& a);
00179 generic set_alias (const generic& a, const generic& val);
00180
00181 inline bool
00182 is_alias_type (nat id) {
00183 int mode= 0;
00184 alias_type_info (id, mode);
00185 return mode == 1;
00186 }
00187
00188 inline nat
00189 alias_to_scalar (nat id) {
00190 int mode= 0;
00191 alias_type_info (id, mode);
00192 return id;
00193 }
00194
00195 inline nat
00196 scalar_to_alias (nat id) {
00197 int mode= 1;
00198 alias_type_info (id, mode);
00199 return id;
00200 }
00201
00202 inline nat
00203 new_alias_type_id (nat id) {
00204 int mode= 2;
00205 alias_type_info (id, mode);
00206 return id;
00207 }
00208
00209 inline nat
00210 new_generic_alias_type_id (nat id) {
00211 int mode= 3;
00212 alias_type_info (id, mode);
00213 return id;
00214 }
00215
00216 TMPL struct type_information<Alias > { static nat id; };
00217 TMPL nat type_information<Alias >::id=
00218 new_alias_type_id (type_information<C>::id);
00219
00220 TMPL struct type_information<Generic_alias > { static nat id; };
00221 TMPL nat type_information<Generic_alias >::id=
00222 new_generic_alias_type_id (type_information<C>::id);
00223
00224
00225
00226
00227
00228 template<typename C, typename R, typename A>
00229 class alias_unary_access_rep: public alias_rep<C> {
00230 alias<R> r;
00231 A a;
00232 public:
00233 inline alias_unary_access_rep (const alias<R>& rr, const A& aa):
00234 r (rr), a (aa) {}
00235 C get () const { return read (get_alias (r), a); }
00236 C& open () const { return open_alias (r) [a]; }
00237 void close () const { close_alias (r); }
00238 };
00239
00240 template<typename C, typename R, typename A> inline alias<C>
00241 alias_access (const alias<R>& r, const A& a) {
00242 return new alias_unary_access_rep<C,R,A> (r, a);
00243 }
00244
00245 template<typename C, typename R, typename A, typename B>
00246 class alias_binary_access_rep: public alias_rep<C> {
00247 alias<R> r;
00248 A a;
00249 B b;
00250 public:
00251 inline alias_binary_access_rep
00252 (const alias<R>& rr, const A& aa, const B& bb):
00253 r (rr), a (aa), b (bb) {}
00254 C get () const { return read (get_alias (r), a, b); }
00255 C& open () const { return open_alias (r) (a, b); }
00256 void close () const { close_alias (r); }
00257 };
00258
00259 template<typename C, typename R, typename A, typename B> inline alias<C>
00260 alias_access (const alias<R>& r, const A& a, const B& b) {
00261 return new alias_binary_access_rep<C,R,A,B> (r, a, b);
00262 }
00263
00264 template<typename R, typename A> inline void
00265 alias_reset (const alias<R>& r, const A& a) {
00266 reset (r->open (), a);
00267 r->close ();
00268 }
00269
00270 template<typename R, typename A> inline alias<R>
00271 alias_write (const alias<R>& r, const A& a) {
00272 r->open () << a;
00273 r->close ();
00274 return r;
00275 }
00276
00277 template<typename R, typename A, typename B> inline void
00278 alias_glue (const alias<R>& r, const A& a, const B& b) {
00279 glue (r->open (), a, b);
00280 r->close ();
00281 }
00282
00283 template<typename X, typename R, typename A, typename B, typename C>
00284 inline alias<X>
00285 alias_tuple_access (const alias<R>& r, const A& a, const B& b, const C& c) {
00286 return alias_access<X> (r, cons (a, (cons (b, c))));
00287 }
00288
00289 template<typename R, typename A, typename B, typename C>
00290 inline void
00291 alias_tuple_reset (const alias<R>& r, const A& a, const B& b, const C& c) {
00292 alias_reset (r, cons (a, cons (b, c)));
00293 }
00294
00295 #undef TMPL
00296 #undef Alias
00297 #undef Alias_rep
00298 #undef Generic_alias
00299 }
00300 #endif // __ALIAS_HPP