basix_doc 0.1
/Users/mourrain/Devel/mmx/basix/include/basix/alias.hpp
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines