Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

more/lang/ct_type.h

Go to the documentation of this file.
00001 //  Copyright (C) 2001--2002  Petter Urkedal (petter.urkedal@matfys.lth.se)
00002 //
00003 //  This file is free software; you can redistribute it and/or modify
00004 //  it under the terms of the GNU General Public License as published by
00005 //  the Free Software Foundation; either version 2 of the License, or
00006 //  (at your option) any later version.
00007 //
00008 //  This file is distributed in the hope that it will be useful,
00009 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00011 //  GNU General Public License for more details.
00012 //
00013 //  You should have received a copy of the GNU General Public License
00014 //  along with this program; if not, write to the Free Software
00015 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00016 //
00017 //  As a special exception, you may use this file as part of a free
00018 //  software library without restriction.  Specifically, if other files
00019 //  instantiate templates or use macros or inline functions from this
00020 //  file, or you compile this file and link it with other files to
00021 //  produce an executable, this file does not by itself cause the
00022 //  resulting executable to be covered by the GNU General Public
00023 //  License.  This exception does not however invalidate any other
00024 //  reasons why the executable file might be covered by the GNU General
00025 //  Public License.
00026 //
00027 //  $Id: ct_type.h,v 1.1 2002/05/30 18:01:37 petter_urkedal Exp $
00028 
00029 
00030 #ifndef MORE_LANG_CT_TYPE_H
00031 #define MORE_LANG_CT_TYPE_H
00032 
00033 #include <more/bits/config.h>
00034 
00035 #ifdef HAVE_LIBFFI
00036 #  include <ffi.h>
00037 
00038 // If defined, ct_type::ffi_type_of() will be defined.
00039 #  define MORE_LANG_PROVIDE_FFI
00040 
00041 // If defined, use libffi for type properties and function calls.
00042 // Requires that MORE_LANG_PROVIDE_FFI is defined.
00043 //# define MORE_LANG_USE_FFI
00044 
00045 #endif
00046 
00047 #ifdef HAVE_BDWGC
00048 #  define MORE_LANG_USE_GC
00049 #  include <bdwgc/gc_cpp.h>
00050 #  include <more/gen/memory.h>
00051 #  include <more/gen/gc_string.h>
00052 #endif
00053 
00054 #include <iosfwd>
00055 #include <cstdlib>
00056 #include <cstring>
00057 #include <more/lang/fwd.h>
00058 #include <more/io/fwd.h>
00059 #include <more/gen/string.h>
00060 #include <more/gen/identifier.h>
00061 #include <more/math/hash.h>
00062 #include <typeinfo>
00063 
00064 
00065 namespace more {
00066 namespace lang {
00067 
00068   using std::size_t;
00069 #ifdef MORE_LANG_USE_GC
00070   using gen::gc_string;
00071   using gen::gc_wstring;
00072 #endif
00073   using gen::identifier;
00074 
00075   /** Type used for function pointers with unknown prototype. */
00076   typedef void (*fn_ptr_t)();
00077 
00078   /** \class ct_type ct_type.h more/lang/ct_type.h
00079       Abstract base class for runtime type representation. */
00080   struct ct_type
00081 #ifdef MORE_LANG_USE_GC
00082       : gc
00083 #endif
00084   {
00085       typedef std::size_t       size_type;
00086       typedef short             alignment_type; // as used in ffi_type
00087       typedef math::hash<192>   hash_type;
00088 
00089       typedef unsigned short    printopt_type;
00090       static printopt_type const printopt_low_precedence        = 1;
00091       static printopt_type const printopt_space_before_name     = 2;
00092       static printopt_type const printopt_space_after_name      = 4;
00093       static printopt_type const printopt_function_args         = 8;
00094       static printopt_type const printopt_lang_cxx              = 16;
00095 
00096       /** Construct a type with CV qualified variants.  This
00097           constructor give tho non-const and non-volatile variant.
00098           The other variants can be obtained with to_cv. */
00099       ct_type();
00100 
00101 #ifdef MORE_LANG_USE_FFI
00102       /** Construct a type with fixed CV qualifiers.  The only case
00103           for this ctor is ct_proto which is always const and
00104           non-volatile. */
00105       ct_type(bool const_p, bool volatile_p);
00106 #else
00107       ct_type(size_type, alignment_type);
00108       ct_type(size_type, alignment_type, bool const_p, bool volatile_p);
00109 #endif
00110 
00111       virtual ~ct_type();
00112 
00113       /** Return an ct_type identical to this. */
00114       virtual ct_type*  clone() const = 0;
00115 
00116       /** Return the ffi_type of this type (cf libffi). */
00117 #ifdef MORE_LANG_PROVIDE_FFI
00118       virtual ffi_type* ffi_type_of() const = 0;
00119 #endif
00120 #if 0
00121       virtual void      construct(void* p) const = 0;
00122 #endif
00123       /** Constructor the object at \a p as a copy of \a src. */
00124       virtual void      construct_copy(void* p, void* src) const = 0;
00125 
00126       /** Destruct the object at \a p. */
00127       virtual void      destruct(void* p) const = 0;
00128 
00129       /** True iff the objects at \a p0 and \a p1 are equal. */
00130       virtual bool      equal(void* p0, void* p1) const = 0;
00131 
00132       /** Print the object in human readable form.
00133           It is not very important to reimplement this. */
00134       virtual void      print_object(std::ostream&, void*) const;
00135 
00136       /** Print a declaration of \a var with the type described by \c
00137           this.  If var = 0, just print the type.  No semicolon is
00138           added. */
00139       void      print_declaration(std::ostream&, printopt_type,
00140                                   char const* var = 0) const;
00141 
00142       /** Print the part of the declaration which precedes the
00143           variable or function name. */
00144       virtual void      print_declaration_pre(std::ostream&,
00145                                               printopt_type) const = 0;
00146       /** Print the part of the declaration which succeeds the
00147           variable or function name. */
00148       virtual void      print_declaration_post(std::ostream&,
00149                                                printopt_type) const = 0;
00150     protected:
00151       /** Print only the const and volatile keywords. This is helper
00152           mostly for internal use. */
00153       void              print_declaration_cv(std::ostream&,
00154                                              printopt_type) const;
00155     public:
00156       virtual void      hash(hash_type&) const = 0;
00157       virtual bool      equal_to(ct_type const*) const = 0;
00158 
00159       bool              is_const() const        { return m_is_const; }
00160       bool              is_volatile() const     { return m_is_volatile; }
00161 
00162       /** Return an clone of \a rtt with different CV equalifiers. */
00163       friend ct_type const*
00164       to_cv(ct_type const* rtt, bool const_p, bool volatile_p);
00165 
00166       virtual bool      is_builtin() const;
00167       virtual bool      is_number() const;
00168 
00169       // Properties according to numeric_limits
00170       // XXX rt_value* min() const
00171       // XXX rt_value* max() const
00172       virtual int       digits() const;
00173       virtual int       digits10() const;
00174       virtual bool      is_integer() const;
00175       virtual bool      is_exact() const;
00176       virtual int       radix() const;
00177       // rt_value* epsilon() const
00178       // rt_value* round_error() const
00179       virtual int       min_exponent() const;
00180       virtual int       min_exponent10() const;
00181       virtual int       max_exponent() const;
00182       virtual int       max_exponent10() const;
00183       virtual bool      has_infinity() const;
00184       virtual bool      has_quiet_NaN() const;
00185       virtual bool      has_signaling_NaN() const;
00186       virtual std::float_denorm_style has_denorm() const;
00187       virtual bool      has_denorm_loss() const;
00188       // T infinity() const
00189       // T quiet_NaN() const
00190       // T signaling_NaN() const
00191       // T denorm_min() const
00192       virtual bool      is_iec559() const;
00193       virtual bool      is_bounded() const;
00194       virtual bool      is_modulo() const;
00195       virtual bool      traps() const;
00196       virtual bool      tinyness_before() const;
00197       virtual std::float_round_style round_style() const;
00198 
00199       virtual ct_type const* promoted() const;
00200 
00201 #if 0 // c_name
00202       identifier        c_name() const          { return m_c_name; }
00203       void              set_c_name(char const* str) { m_c_name = str; }
00204 #endif
00205 
00206       char const*       c_error_value() const   { return 0; }
00207 
00208 #ifdef MORE_LANG_USE_FFI
00209       size_type         size()      const { return ffi_type_of()->size; }
00210       alignment_type    alignment() const { return ffi_type_of()->alignment; }
00211 #else
00212       size_type         size()      const { req_fin(); return m_size; }
00213       alignment_type    alignment() const { req_fin(); return m_alignment; }
00214 #endif
00215 
00216     private:
00217 #ifndef MORE_LANG_USE_FFI
00218       void req_fin() const
00219       {
00220           if (m_size == size_type(-1))
00221               throw std::logic_error("more::lang::ct_type: "
00222                                      "Access of unfinished type description.");
00223       }
00224     protected:
00225       void set_size_and_alignment(size_type size, alignment_type alignment)
00226       {
00227           if (m_size != size_type(-1))
00228               throw std::logic_error("more::lang::ct_type: "
00229                                      "Tried to redefine size and alignment.");
00230           m_size = size;
00231           m_alignment = alignment;
00232       }
00233     private:
00234       size_type         m_size;
00235       alignment_type    m_alignment;
00236 #endif
00237 
00238       unsigned int      m_is_const      : 1;
00239       unsigned int      m_is_volatile   : 1;
00240       ct_type**         m_cv_array;
00241     protected:
00242       static char const* s_private_pfx;
00243   };
00244 
00245   /** Return true if \a t0 and \a t1 are equal, taking into account CV
00246       qualifiers. */
00247   inline bool
00248   equal(ct_type const* t0, ct_type const* t1)
00249   {
00250       return t0->equal_to(t1);
00251   }
00252 
00253   /** \class ct_pointer ct_type.h more/lang/ct_type.h
00254       The runtime representation of a pointer type. */
00255   struct ct_pointer : ct_type
00256   {
00257       explicit ct_pointer(ct_type const* t);
00258       virtual ~ct_pointer();
00259       virtual ct_pointer* clone() const;
00260 
00261 #ifdef MORE_LANG_PROVIDE_FFI
00262       virtual ffi_type* ffi_type_of()                   const;
00263 #endif
00264       virtual void      construct_copy(void*, void*)    const;
00265       virtual void      destruct(void*)                 const;
00266       virtual bool      equal(void*, void*)             const;
00267       virtual void      print_object(std::ostream&, void*) const;
00268       virtual void      print_declaration_pre(std::ostream&,
00269                                               printopt_type) const;
00270       virtual void      print_declaration_post(std::ostream&,
00271                                                printopt_type) const;
00272       virtual void      hash(hash_type&) const;
00273       virtual bool      equal_to(ct_type const*) const;
00274 
00275       ct_type const*    deref_type() const { return m_deref_type; }
00276       void*             deref(void* p) { return *(void**)p; }
00277 
00278     private:
00279       ct_type const* m_deref_type;
00280   };
00281 
00282 
00283   /** \class ct_array ct_type.h more/lang/ct_type.h
00284       The runtime representation of an array type. */
00285   struct ct_array : ct_type
00286   {
00287       ct_array(ct_type const* t, std::size_t);
00288       virtual ~ct_array();
00289       virtual ct_array* clone() const;
00290 
00291 #ifdef MORE_LANG_PROVIDE_FFI
00292       virtual ffi_type* ffi_type_of()                   const;
00293 #endif
00294       virtual void      construct_copy(void*, void*)    const;
00295       virtual void      destruct(void*)                 const;
00296       virtual bool      equal(void*, void*)             const;
00297       virtual void      print_object(std::ostream&, void*) const;
00298       virtual void      print_declaration_pre(std::ostream&,
00299                                               printopt_type) const;
00300       virtual void      print_declaration_post(std::ostream&,
00301                                                printopt_type) const;
00302       virtual void      hash(hash_type&) const;
00303       virtual bool      equal_to(ct_type const*) const;
00304 
00305       ct_type const*    element_type() const { return m_element_type; }
00306       void*             element(void*, std::size_t) const;
00307 
00308     private:
00309       ct_type const*    m_element_type;
00310       size_t            m_count;
00311 #ifdef MORE_LANG_PROVIDE_FFI
00312       mutable ffi_type  m_ffi_type;
00313 #endif
00314   };
00315 
00316 
00317 
00318 
00319   //--------------------------------------------------------------------
00320   //                          ct_type_of
00321   //--------------------------------------------------------------------
00322 
00323   ///\if bits
00324   template<typename T>
00325     struct _ct_type
00326     {
00327         static ct_type const* get() { return s_value; }
00328         static void set(ct_type const* s) { s_value = s; }
00329         static ct_type const* s_value;
00330     };
00331   template<typename T>
00332     ct_type const* _ct_type<T>::s_value = 0;
00333 
00334   template<typename T>
00335     struct _ct_type<T const>
00336     {
00337         static ct_type const*
00338         get()
00339         {
00340             static ct_type const* t = 0;
00341             if (!t)
00342                 t = to_cv(_ct_type<T>::get(), true, false);
00343             return t;
00344         }
00345     };
00346 
00347   template<typename T>
00348     struct _ct_type<T volatile>
00349     {
00350         static ct_type const*
00351         get()
00352         {
00353             static ct_type const* t = 0;
00354             if (!t)
00355                 t = to_cv(_ct_type<T>::get(), false, true);
00356             return t;
00357         }
00358     };
00359 
00360   template<typename T>
00361     struct _ct_type<T const volatile>
00362     {
00363         static ct_type const*
00364         get()
00365         {
00366             static ct_type const* t = 0;
00367             if (!t)
00368                 t = to_cv(_ct_type<T>::get(), true, true);
00369             return t;
00370         }
00371     };
00372 
00373   template<typename T>
00374     struct _ct_type<T*>
00375     {
00376         static ct_type const*
00377         get()
00378         {
00379             static ct_pointer* t = 0;
00380             if (!t) {
00381 #ifdef MORE_LANG_USE_GC
00382                 t = new(UseGC) ct_pointer(_ct_type<T>::get());
00383 #else
00384                 t = new ct_pointer(_ct_type<T>::get());
00385 #endif
00386             }
00387             return t;
00388         }
00389     };
00390 
00391   template<typename T, std::size_t N>
00392     struct _ct_type<T[N]>
00393     {
00394         static ct_type const*
00395         get()
00396         {
00397             static ct_array* t = 0;
00398             if (!t) {
00399 #ifdef MORE_LANG_USE_GC
00400                 t = new(UseGC) ct_array(_ct_type<T>::get(), N);
00401 #else
00402                 t = new ct_array(_ct_type<T>::get(), N);
00403 #endif
00404             }
00405             return t;
00406         }
00407     };
00408 
00409   template<typename T, std::size_t N>
00410     struct _ct_type<T const[N]>
00411     {
00412         static ct_type const*
00413         get()
00414         {
00415             static ct_type const* t = 0;
00416             if (!t)
00417                 t = to_cv(_ct_type<T[N]>::get(), true, false);
00418             return t;
00419         }
00420     };
00421 
00422   template<typename T, std::size_t N>
00423     struct _ct_type<T volatile[N]>
00424     {
00425         static ct_type const*
00426         get()
00427         {
00428             static ct_type const* t = 0;
00429             if (!t)
00430                 t = to_cv(_ct_type<T[N]>::get(), false, true);
00431             return t;
00432         }
00433     };
00434 
00435   template<typename T, std::size_t N>
00436     struct _ct_type<T const volatile[N]>
00437     {
00438         static ct_type const*
00439         get()
00440         {
00441             static ct_type const* t = 0;
00442             if (!t)
00443                 t = to_cv(_ct_type<T[N]>::get(), true, true);
00444             return t;
00445         }
00446     };
00447 
00448 
00449   template<> struct _ct_type<void>              { static ct_type* get(); };
00450 //   template<> struct _ct_type<bool>           { static ct_type* get(); };
00451   template<> struct _ct_type<char>              { static ct_type* get(); };
00452   template<> struct _ct_type<signed char>       { static ct_type* get(); };
00453   template<> struct _ct_type<unsigned char>     { static ct_type* get(); };
00454   template<> struct _ct_type<short>             { static ct_type* get(); };
00455   template<> struct _ct_type<unsigned short>    { static ct_type* get(); };
00456   template<> struct _ct_type<int>               { static ct_type* get(); };
00457   template<> struct _ct_type<unsigned int>      { static ct_type* get(); };
00458   template<> struct _ct_type<long>              { static ct_type* get(); };
00459   template<> struct _ct_type<unsigned long>     { static ct_type* get(); };
00460 #ifdef CXX_HAVE_LONG_LONG
00461   template<> struct _ct_type<long long>         { static ct_type* get(); };
00462   template<> struct _ct_type<unsigned long long>{ static ct_type* get(); };
00463 #endif
00464   template<> struct _ct_type<float>             { static ct_type* get(); };
00465   template<> struct _ct_type<double>            { static ct_type* get(); };
00466   template<> struct _ct_type<long double>       { static ct_type* get(); };
00467 
00468 #ifdef MORE_LANG_USE_GC
00469   template<> struct _ct_type<gc_wstring>        { static ct_type* get(); };
00470   template<> struct _ct_type<gc_string>         { static ct_type* get(); };
00471   template<> struct _ct_type<identifier>        { static ct_type* get(); };
00472   template<> struct _ct_type<io::sourceref>     { static ct_type* get(); };
00473 #endif
00474   ///\endif
00475 
00476   /** Returns the ct_type descriptor of \a T.  If T is not a builtin
00477       type, or a pointer to or array of such, \c register_ct_type_of
00478       must be called once first with the same type argument to
00479       register the type descriptor. */
00480   template<typename T>
00481     inline ct_type const*
00482     ct_type_of()
00483     {
00484         if (ct_type const* t = _ct_type<T>::get())
00485             return t;
00486         else
00487             throw std::logic_error("more::lang::ct_type_of<\""
00488                                    + std::string(typeid(T).name())
00489                                    + "\">: Type is not registered.");
00490     }
00491 
00492   /** Return type \c ct_type descriptor of \a T. */
00493   template<typename T>
00494     inline ct_type const*
00495     ct_type_of(T x)
00496     {
00497         return _ct_type<T>::get();
00498     }
00499 
00500   /** Provide a type descriptor \a t for the type \a T. */
00501   template<typename T>
00502     inline void
00503     register_ct_type_of(ct_type const* t)
00504     {
00505         if (_ct_type<T>::get())
00506             throw std::logic_error("more::lang::register_ct_type_of: "
00507                                    "Multiple definitions of type "
00508                                    "description.");
00509         _ct_type<T>::set(t);
00510     }
00511 
00512   /** Return result type of a binary arithmetic operation on \a x and
00513       \a y, or 0 if invalid.  The result is detemined by type
00514       promotion and coversion rule. */
00515   ct_type const* arithmetic_result_type(ct_type const* x, ct_type const* y);
00516 
00517 }}
00518 #endif

Generated on Sat Sep 7 19:11:17 2002 for more with Doxygen 1.2.13.1. Doxygen 1.2.13.1 is written and copyright 1997-2002 by Dimitri van Heesch.