basix_doc 0.1
|
00001 00002 /****************************************************************************** 00003 * MODULE : alias.hpp 00004 * DESCRIPTION: Alias type (for references) 00005 * COPYRIGHT : (C) 2006 Joris van der Hoeven 00006 ******************************************************************************* 00007 * This software falls under the GNU general public license and comes WITHOUT 00008 * ANY WARRANTY WHATSOEVER. See the file $TEXMACS_PATH/LICENSE for more details. 00009 * If you don't have this file, write to the Free Software Foundation, Inc., 00010 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 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 * The alias class 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 * Global aliases 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 * Basic aliases 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 * The generic_alias class. At a first sight, this class may seem superfluous. 00112 * However, we need it for a correct implementation of the Alias (Generic) type. 00113 * Indeed, if x : Alias (Generic) and x refers to an element of type T, 00114 * then x is transformed into an element of type Generic_alias (T) during 00115 * function applications. This enables us to apply converters which depend 00116 * on T, such as the basic converter Generic_alias (T) -> T. 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 * Incarnate generic aliases as ordinary aliases 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 * Type information for alias types 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 * Further utilities for the creation of common aliases 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 #undef TMPL 00284 #undef Alias 00285 #undef Alias_rep 00286 #undef Generic_alias 00287 } // namespace mmx 00288 #endif // __ALIAS_HPP