library of assembled shared sources

http://lass.cocamware.com

type_traits.h

Go to the documentation of this file.
00001 /** @file
00002  *  @author Bram de Greve (bramz@users.sourceforge.net)
00003  *  @author Tom De Muer (tomdemuer@users.sourceforge.net)
00004  *
00005  *  *** BEGIN LICENSE INFORMATION ***
00006  *  
00007  *  The contents of this file are subject to the Common Public Attribution License 
00008  *  Version 1.0 (the "License"); you may not use this file except in compliance with 
00009  *  the License. You may obtain a copy of the License at 
00010  *  http://lass.sourceforge.net/cpal-license. The License is based on the 
00011  *  Mozilla Public License Version 1.1 but Sections 14 and 15 have been added to cover 
00012  *  use of software over a computer network and provide for limited attribution for 
00013  *  the Original Developer. In addition, Exhibit A has been modified to be consistent 
00014  *  with Exhibit B.
00015  *  
00016  *  Software distributed under the License is distributed on an "AS IS" basis, WITHOUT 
00017  *  WARRANTY OF ANY KIND, either express or implied. See the License for the specific 
00018  *  language governing rights and limitations under the License.
00019  *  
00020  *  The Original Code is LASS - Library of Assembled Shared Sources.
00021  *  
00022  *  The Initial Developer of the Original Code is Bram de Greve and Tom De Muer.
00023  *  The Original Developer is the Initial Developer.
00024  *  
00025  *  All portions of the code written by the Initial Developer are:
00026  *  Copyright (C) 2004-2007 the Initial Developer.
00027  *  All Rights Reserved.
00028  *  
00029  *  Contributor(s):
00030  *
00031  *  Alternatively, the contents of this file may be used under the terms of the 
00032  *  GNU General Public License Version 2 or later (the GPL), in which case the 
00033  *  provisions of GPL are applicable instead of those above.  If you wish to allow use
00034  *  of your version of this file only under the terms of the GPL and not to allow 
00035  *  others to use your version of this file under the CPAL, indicate your decision by 
00036  *  deleting the provisions above and replace them with the notice and other 
00037  *  provisions required by the GPL License. If you do not delete the provisions above,
00038  *  a recipient may use your version of this file under either the CPAL or the GPL.
00039  *  
00040  *  *** END LICENSE INFORMATION ***
00041  */
00042 
00043 
00044 
00045 /** @class lass::meta::TypeTraits
00046  *  @brief Interesting goodies on types
00047  *  @author Bram de Greve [BdG]
00048  *
00049  *  @section overview
00050  *
00051  *  TypeTraits gives you compile-time information on a type @a T.  It will tell you if
00052  *  @a T is
00053  *  constant type, a pointer, a reference ...  It will also able you to derive related types
00054  *  at compile time, such as non-const version of a constant type.
00055  *
00056  *  In contrary to the type traits in boost[1] or loki[2], our TypeTraits tries to be smarter
00057  *  concerning reference.  i.e. if @a T is a reference, TypeTraits will also report
00058  *  properties of the referred type.  And if you request a related type, it will modify
00059  *  the referred type instead.  All this should make sure you get exactly what you intend.
00060  *  (this is still to be proven in practice [BdG]).
00061  *
00062  *  Here's a list of the different fields (we suppose @a T is the template parameter):
00063  *
00064  *  @par Type
00065  *  a typedef to the template paramter.  i.e. this is the same as @a T.
00066  *
00067  *  @par isConst
00068  *  is @c true if @a T is a constant type or a reference to a constant type, is @c false otherwise.
00069  *  Notice that this will yield @c false for non-const pointers to const types (<tt>const int*</tt>)
00070  *  but @c true for const pointers to non-const types (<tt>int* const</tt>).
00071  *
00072  *  @par TNonConst
00073  *  a typedef to the non-const version of @a T if @a T is const, otherwise it's @a T itself.  You
00074  *  can use this to get rid of the @c const qualifier of a type, e.g. <tt>const int</tt> becomes
00075  *  <tt>int</tt> but <tt>const int*</tt> remains <tt>const int*</tt>.  For references, the @c const
00076  *  qualifier is stripped of the referred type, e.g. <tt>const int&</tt> becomes <tt>int&</tt>.
00077  *
00078  *  @par TConst
00079  *  This is the opposite of @b TNonConst.  It appends a @c const qualifier to the (reffered) type,
00080  *  <tt>const int*</tt> becomes <tt>const int* const</tt>, <tt>int&</tt> becomes <tt>const int&</tt>
00081  *
00082  *  @par isPointer
00083  *  is @c true if @a T is a pointer or a reference to a pointer, is @c false otherwise.
00084  *  Notice that <tt>int*&</tt> will yield true.
00085  *
00086  *  @par TPointee
00087  *  if @b isPointer is @c true then @b TPointee is a typedef to the (referred) type points to,
00088  *  otherwise it will be equal to lass::meta::NullType.  both <tt>int* const</tt> and <tt>int*&</tt>
00089  *  will yield <tt>int</tt>, but <tt>int</tt> and <tt>int&</tt> will yield lass::meta::NullType.
00090  *
00091  *  @par isReference
00092  *  is @c true if @a T is a reference, is @c false otherwise.  both <tt>const int&</tt> and
00093  *  <tt>int*&</tt> are references, <tt>const int</tt> and <tt>int*</tt> are not.
00094  *
00095  *  @par TReferred
00096  *  if @b isReference is @c true then strips the @e ampersand to get type @a T is refering to,
00097  *  otherwise it's @a T itself.  both <tt>const int&</tt> and <tt>const int</tt> become
00098  *  <tt>const int</tt>, <tt>int*&</tt> and <tt>int*</tt> become <tt>int*</tt>.
00099  *
00100  *  @par TReference
00101  *  if @b isReference is @c false then adds the @e ampersand to get a type refering to a @a T,
00102  *  otherwise it's @a T itself.  This solves the ill-formed @e reference-to-reference-to-type
00103  *  problem by keeping it a @e reference-to-type (what is exactly what you want).  i.e. <tt>int</tt>
00104  *  becomes <tt>int&</tt>, but <tt>int&</tt> remains <tt>int&</tt>.
00105  *
00106  *  @par TStorage
00107  *  yields in a type that can be used to store temporary objects.  To store temporary objects,
00108  *  we must get rid of the reference and the @c const qualifier of the referred type.  e.g. if a
00109  *  <tt>const std::string&</tt> is the type of a function parameter, you would like to @e store
00110  *  tempories as <tt>std::string</tt>.  This @b TStorage will give you this <tt>std::string</tt>
00111  *  type.
00112  *
00113  *  Here we list all possible results of TypeTraits in a table.  We show it for a base type
00114  *  int, but it is of course valid for any other type.
00115  *
00116  *  <table><tr>
00117  *  <td><b>T</b></td>                   <td><b>isConst</b></td> <td><b>TNonConst</b></td>   <td><b>TConst</b></td>      <td><b>isPointer</b></td>   <td><b>TPointee</b></td>    <td><b>isReference</b></td> <td><b>TReferred</b></td>   <td><b>TReference</b></td>  <td><b>TStorage</b></td>
00118  *  </tr><tr>
00119  *  <td><b>int</b></td>                 <td>false</td>          <td>int</td>                <td>const int</td>          <td>false</td>              <td>NullType</td>           <td>false</td>              <td>int</td>                <td>int&</td>               <td>int</td>
00120  *  </tr><tr>
00121  *  <td><b>int*</b></td>                <td>false</td>          <td>int*</td>               <td>int* const</td>         <td>true</td>               <td>int</td>                <td>false</td>              <td>int*</td>               <td>int*&</td>              <td>int*</td>
00122  *  </tr><tr>
00123  *  <td><b>int* const</b></td>          <td>true</td>           <td>int*</td>               <td>int* const</td>         <td>true</td>               <td>int</td>                 <td>false</td>              <td>int* const</td>         <td>int* const&</td>        <td>int*</td>
00124  *  </tr><tr>
00125  *  <td><b>int&</b></td>                <td>false</td>          <td>int&</td>               <td>const int&</td>         <td>false</td>              <td>NullType</td>           <td>true</td>               <td>int</td>                <td>int&</td>               <td>int</td>
00126  *  </tr><tr>
00127  *  <td><b>int*&</b></td>               <td>false</td>          <td>int*&</td>              <td>int* const&</td>        <td>true</td>               <td>int</td>                <td>true</td>               <td>int*</td>               <td>int*&</td>              <td>int*</td>
00128  *  </tr><tr>
00129  *  <td><b>int* const&</b></td>         <td>true</td>           <td>int*&</td>              <td>int* const&</td>        <td>true</td>               <td>int</td>                <td>true</td>               <td>int* const</td>         <td>int* const&</td>        <td>int*</td>
00130  *  </tr><tr>
00131  *  <td><b>const int</b></td>           <td>true</td>           <td>int</td>                <td>const int</td>          <td>false</td>              <td>NullType</td>           <td>false</td>              <td>const int</td>          <td>const int&</td>         <td>int</td>
00132  *  </tr><tr>
00133  *  <td><b>const int*</b></td>          <td>false</td>          <td>const int*</td>         <td>const int* const</td>   <td>true</td>               <td>const int</td>          <td>false</td>              <td>const int*</td>         <td>const int*&</td>        <td>const int*</td>
00134  *  </tr><tr>
00135  *  <td><b>const int* const</b></td>    <td>true</td>           <td>const int*</td>         <td>const int* const</td>   <td>true</td>               <td>const int</td>          <td>false</td>              <td>const int* const</td>   <td>const int* const&</td>  <td>const int*</td>
00136  *  </tr><tr>
00137  *  <td><b>const int&</b></td>          <td>true</td>           <td>int&</td>               <td>const int&</td>         <td>false</td>              <td>NullType</td>           <td>true</td>               <td>const int</td>          <td>const int&</td>         <td>int</td>
00138  *  </tr><tr>
00139  *  <td><b>const int*&</b></td>         <td>false</td>          <td>const int*&</td>        <td>const int* const&</td>  <td>true</td>               <td>const int</td>          <td>true</td>               <td>const int*</td>         <td>const int*&</td>        <td>const int*</td>
00140  *  </tr><tr>
00141  *  <td><b>const int* const&</b></td>   <td>true</td>           <td>const int*&</td>        <td>const int* const&</td>  <td>true</td>               <td>const int</td>          <td>true</td>               <td>const int* const</td>   <td>const int* const&</td>  <td>const int*</td>
00142  *  </tr></table>
00143  *
00144  *  @note You can see that references behave much the same as the refered type.  e.g.
00145  *  <tt>TypeTraits<U>::TPointee</tt> will be the same as
00146  *  <tt>TypeTraits<typename TypeTraits<U>::TReferred>::TPointee</tt>, no matter what the type of @c U is.
00147  *  The same is valid for @c isConst and @c isPointer.  @c TConst and @c TNonConst are a bit
00148  *  different, for these the @e ampersand will again be added if @c U is a reference.
00149  *
00150  *  @section broken broken compilers workaround
00151  *
00152  *  Unfortunately, the have a neat implementation of TypeTraits, we need partial template
00153  *  specialisation, a feature not supported by MSVC6x and MSVC70.  However, TypeTraits @e can be a
00154  *  crucial tool to implement algorithms that would be impossible to implement if TypeTraits fail.
00155  *  Thus we, @e do need a way to get this TypeTraits up and running in environments without this
00156  *  partial specialisation, and we need to get it to the @e right thing!
00157  *
00158  *  There's really only one way to solve this, and that's exhaustive full specialisation of all
00159  *  possible parameters @a T.  This means we should specialise it for <tt>int</tt>,
00160  *  <tt>const int</tt>, <tt>const int*</tt>, ... (for each base type @c int, you have to specialise
00161  *  for the twelve cases as in the table above).
00162  *
00163  *  Of course, it is impossible for a library to do this, because we can never know all types
00164  *  that will ever be needed.  Therefore we have a twofolded solution:
00165  *
00166  *  - we have provided full specialisations for all twelve cases of all @e fundamental types and
00167  *    some more.  This types are: bool, char, wchar_t, signed char, signed short, signed int,
00168  *    signed long, (signed __int64), unsigned char, unsigned short, unsigned int, unsigned long,
00169  *    (unsigned __int64), float, double, long double, std::string, std::complex<float>,
00170  *    std::complex<double> and std::complex<long double>
00171  *  - we have provided a macro LASS_META_BROKEN_TYPE_TRAITS_SPECIALISATION you can use to provide
00172  *    full specialisation of all twelve cases of any other type:
00173  *
00174  *  @code
00175  *  namespace foo
00176  *  {
00177  *      struct Bar {};
00178  *  }
00179  *  LASS_META_BROKEN_TYPE_TRAITS_SPECIALISATION(foo::Bar)
00180  *  @endcode
00181  *
00182  *  @note you can safely use this macro regardless if the compiler supports partial specialisation.
00183  *        If your compiler supports it, the macro will be expanded to @e nothing.
00184  *
00185  *  @warning you have to call this macro @e outside any namespaces.
00186  *
00187  *  @warning this exhaustive full specialisation @e might lead to an overflow of the compiler's
00188  *  internal heap while building.  You're warned!
00189  */
00190 
00191 #ifndef LASS_GUARDIAN_OF_INCLUSION_META_TYPE_TRAITS_H
00192 #define LASS_GUARDIAN_OF_INCLUSION_META_TYPE_TRAITS_H
00193 
00194 #include "meta_common.h"
00195 #include "null_type.h"
00196 #include "meta_assert.h"
00197 
00198 namespace lass
00199 {
00200 namespace meta
00201 {
00202 
00203 #if !defined(LASS_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
00204 
00205 template <typename T>
00206 struct TypeTraits
00207 {
00208 private:
00209 
00210     template <typename U> struct ConstTraits
00211     {
00212         enum { isConst = false };
00213         typedef U TNonConst;
00214         typedef const U TConst;
00215     };
00216     template <typename U> struct ConstTraits<const U>
00217     {
00218         enum { isConst = true };
00219         typedef U TNonConst;
00220         typedef const U TConst;
00221     };
00222     template <typename U> struct ConstTraits<U&>
00223     {
00224         enum { isConst = false };
00225         typedef U& TNonConst;
00226         typedef const U& TConst;
00227     };
00228     template <typename U> struct ConstTraits<const U&>
00229     {
00230         enum { isConst = true };
00231         typedef U& TNonConst;
00232         typedef const U& TConst;
00233     };
00234 
00235     template <typename U> struct PointerTraits
00236     {
00237         enum { isPointer = false };
00238         typedef NullType TPointee;
00239     };
00240     template <typename U> struct PointerTraits<U*>
00241     {
00242         enum { isPointer = true };
00243         typedef U TPointee;
00244     };
00245     template <typename U> struct PointerTraits<U&>
00246     {
00247         enum { isPointer = false };
00248         typedef NullType TPointee;
00249     };
00250     template <typename U> struct PointerTraits<U*&>
00251     {
00252         enum { isPointer = true };
00253         typedef U TPointee;
00254     };
00255 
00256     template <typename U> struct ReferenceTraits
00257     {
00258         enum { isReference = false };
00259         typedef U TReferred;
00260         typedef U& TReference;
00261     };
00262     template <typename U> struct ReferenceTraits<U&>
00263     {
00264         enum { isReference = true };
00265         typedef U TReferred;
00266         typedef U& TReference;
00267     };
00268 
00269     typedef typename ConstTraits<T>::TNonConst TStripped;
00270 
00271 public:
00272 
00273     /** type of @a T itself
00274      */
00275     typedef T Type;
00276 
00277     /** is @c true if referred type of @a T is constant. */
00278     enum { isConst = ConstTraits<T>::isConst };
00279     /** strips @c const qualifier of refered type of @a T (but keeps reference if any). */
00280     typedef typename ConstTraits<T>::TNonConst TNonConst;
00281     /** add @c const qualifier to referred type of @a T (but keeps reference if any). */
00282     typedef typename ConstTraits<T>::TConst TConst;
00283 
00284     /** is @c true if referred type of @a T is a pointer */
00285     enum { isPointer = PointerTraits<TNonConst>::isPointer };
00286     /** is type pointed to by referred type of @a T, NullType if not applyable. */
00287     typedef typename PointerTraits<TNonConst>::TPointee TPointee;
00288 
00289     /** is @c true if @a T is a reference*/
00290     enum { isReference = ReferenceTraits<T>::isReference };
00291     /** is type @a T refers to if @a T is a reference, is @a T otherwise*/
00292     typedef typename ReferenceTraits<T>::TReferred TReferred;
00293     /** is a reference to @a T if @a T is @e not a reference, is @a T otherwise*/
00294     typedef typename ReferenceTraits<T>::TReference TReference;
00295 
00296     /** strips @c const qualifier of refered type of @a T but without keeping reference if any. */
00297     typedef typename ConstTraits<typename ReferenceTraits<T>::TReferred>::TNonConst TStorage;
00298 };
00299 
00300 #define LASS_META_BROKEN_TYPE_TRAITS_SPECIALISATION(type) /**/
00301 
00302 #else
00303 
00304 template <typename T>
00305 struct TypeTraits
00306 {
00307     LASS_META_ASSERT(false, lass_meta_TypeTraits_is_not_specialized_for_type);
00308 };
00309 
00310 #define LASS_META_BROKEN_TYPE_TRAITS_SPECIALISATION(type)\
00311     namespace lass\
00312     {\
00313     namespace meta\
00314     {\
00315     template <>\
00316     struct TypeTraits<type >\
00317     {\
00318         typedef type Type;\
00319         enum { isConst = false };\
00320         typedef type TNonConst;\
00321         typedef const type TConst;\
00322         enum { isPointer = false };\
00323         typedef NullType TPointee;\
00324         enum { isReference = false };\
00325         typedef type TReferred;\
00326         typedef type& TReference;\
00327         typedef type TStorage;\
00328     };\
00329     template <>\
00330     struct TypeTraits<const type >\
00331     {\
00332         typedef const type Type;\
00333         enum { isConst = true };\
00334         typedef type TNonConst;\
00335         typedef const type TConst;\
00336         enum { isPointer = false };\
00337         typedef NullType TPointee;\
00338         enum { isReference = false };\
00339         typedef const type TReferred;\
00340         typedef const type& TReference;\
00341         typedef type TStorage;\
00342     };\
00343     template <>\
00344     struct TypeTraits<type*>\
00345     {\
00346         typedef type* Type;\
00347         enum { isConst = false };\
00348         typedef type* TNonConst;\
00349         typedef type* const TConst;\
00350         enum { isPointer = true };\
00351         typedef type TPointee;\
00352         enum { isReference = false };\
00353         typedef type* TReferred;\
00354         typedef type*& TReference;\
00355         typedef type* TStorage;\
00356     };\
00357     template <>\
00358     struct TypeTraits<const type*>\
00359     {\
00360         typedef const type* Type;\
00361         enum { isConst = false };\
00362         typedef const type* TNonConst;\
00363         typedef const type* const TConst;\
00364         enum { isPointer = true };\
00365         typedef const type TPointee;\
00366         enum { isReference = false };\
00367         typedef const type* TReferred;\
00368         typedef const type*& TReference;\
00369         typedef const type* TStorage;\
00370     };\
00371     template <>\
00372     struct TypeTraits<type* const>\
00373     {\
00374         typedef type* const Type;\
00375         enum { isConst = true };\
00376         typedef type* TNonConst;\
00377         typedef type* const TConst;\
00378         enum { isPointer = true };\
00379         typedef type TPointee;\
00380         enum { isReference = false };\
00381         typedef type* const TReferred;\
00382         typedef type* const& TReference;\
00383         typedef type* TStorage;\
00384     };\
00385     template <>\
00386     struct TypeTraits<const type* const>\
00387     {\
00388         typedef const type* const Type;\
00389         enum { isConst = true };\
00390         typedef const type* TNonConst;\
00391         typedef const type* const TConst;\
00392         enum { isPointer = true };\
00393         typedef const type TPointee;\
00394         enum { isReference = false };\
00395         typedef const type* const TReferred;\
00396         typedef const type* const& TReference;\
00397         typedef const type* TStorage;\
00398     };\
00399     template <>\
00400     struct TypeTraits<type&>\
00401     {\
00402         typedef type& Type;\
00403         enum { isConst = false };\
00404         typedef type& TNonConst;\
00405         typedef const type& TConst;\
00406         enum { isPointer = false };\
00407         typedef NullType TPointee;\
00408         enum { isReference = true };\
00409         typedef type TReferred;\
00410         typedef type& TReference;\
00411         typedef type TStorage;\
00412     };\
00413     template <>\
00414     struct TypeTraits<const type&>\
00415     {\
00416         typedef const type& Type;\
00417         enum { isConst = true };\
00418         typedef type& TNonConst;\
00419         typedef const type& TConst;\
00420         enum { isPointer = false };\
00421         typedef NullType TPointee;\
00422         enum { isReference = true };\
00423         typedef const type TReferred;\
00424         typedef const type& TReference;\
00425         typedef type TStorage;\
00426     };\
00427     template <>\
00428     struct TypeTraits<type*&>\
00429     {\
00430         typedef type*& Type;\
00431         enum { isConst = false };\
00432         typedef type*& TNonConst;\
00433         typedef type* const& TConst;\
00434         enum { isPointer = true };\
00435         typedef type TPointee;\
00436         enum { isReference = true };\
00437         typedef type* TReferred;\
00438         typedef type*& TReference;\
00439         typedef type* TStorage;\
00440     };\
00441     template <>\
00442     struct TypeTraits<const type*&>\
00443     {\
00444         typedef const type*& Type;\
00445         enum { isConst = false };\
00446         typedef const type*& TNonConst;\
00447         typedef const type* const& TConst;\
00448         enum { isPointer = true };\
00449         typedef const type TPointee;\
00450         enum { isReference = true };\
00451         typedef const type* TReferred;\
00452         typedef const type*& TReference;\
00453         typedef const type* TStorage;\
00454     };\
00455     template <>\
00456     struct TypeTraits<type* const&>\
00457     {\
00458         typedef type* const& Type;\
00459         enum { isConst = true };\
00460         typedef type*& TNonConst;\
00461         typedef type* const& TConst;\
00462         enum { isPointer = true };\
00463         typedef type TPointee;\
00464         enum { isReference = true };\
00465         typedef type* const TReferred;\
00466         typedef type* const& TReference;\
00467         typedef type* TStorage;\
00468     };\
00469     template <>\
00470     struct TypeTraits<const type* const&>\
00471     {\
00472         typedef const type* const& Type;\
00473         enum { isConst = true };\
00474         typedef const type*& TNonConst;\
00475         typedef const type* const& TConst;\
00476         enum { isPointer = true };\
00477         typedef const type TPointee;\
00478         enum { isReference = true };\
00479         typedef const type* const TReferred;\
00480         typedef const type* const& TReference;\
00481         typedef const type* TStorage;\
00482     };\
00483     }\
00484     }
00485 
00486 #endif
00487 
00488 }
00489 
00490 }
00491 
00492 LASS_META_BROKEN_TYPE_TRAITS_SPECIALISATION(bool)
00493 LASS_META_BROKEN_TYPE_TRAITS_SPECIALISATION(char)
00494 LASS_META_BROKEN_TYPE_TRAITS_SPECIALISATION(wchar_t)
00495 LASS_META_BROKEN_TYPE_TRAITS_SPECIALISATION(signed char)
00496 LASS_META_BROKEN_TYPE_TRAITS_SPECIALISATION(signed short)
00497 LASS_META_BROKEN_TYPE_TRAITS_SPECIALISATION(signed int)
00498 LASS_META_BROKEN_TYPE_TRAITS_SPECIALISATION(signed long)
00499 LASS_META_BROKEN_TYPE_TRAITS_SPECIALISATION(signed __int64)
00500 LASS_META_BROKEN_TYPE_TRAITS_SPECIALISATION(unsigned char)
00501 LASS_META_BROKEN_TYPE_TRAITS_SPECIALISATION(unsigned short)
00502 LASS_META_BROKEN_TYPE_TRAITS_SPECIALISATION(unsigned int)
00503 LASS_META_BROKEN_TYPE_TRAITS_SPECIALISATION(unsigned long)
00504 LASS_META_BROKEN_TYPE_TRAITS_SPECIALISATION(unsigned __int64)
00505 LASS_META_BROKEN_TYPE_TRAITS_SPECIALISATION(float)
00506 LASS_META_BROKEN_TYPE_TRAITS_SPECIALISATION(double)
00507 LASS_META_BROKEN_TYPE_TRAITS_SPECIALISATION(long double)
00508 LASS_META_BROKEN_TYPE_TRAITS_SPECIALISATION(std::string)
00509 LASS_META_BROKEN_TYPE_TRAITS_SPECIALISATION(std::complex<float>)
00510 LASS_META_BROKEN_TYPE_TRAITS_SPECIALISATION(std::complex<double>)
00511 LASS_META_BROKEN_TYPE_TRAITS_SPECIALISATION(std::complex<long double>)
00512 
00513 #endif
00514 
00515 // EOF

Generated on Mon Nov 10 14:22:01 2008 for Library of Assembled Shared Sources by doxygen 1.5.7.1
SourceForge.net Logo