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

base/TypeManip

Go to the documentation of this file.
00001 /****************************************************************************
00002   Copyright (C)2001 by Andrei Alexandrescu
00003 
00004   This file is a derivative of a file from the Loki Library written by
00005   Andrei Alexandrescu.  It was distributed by him under the terms
00006   listed below (titled Loki Original Distribution Terms).
00007   In accordance with the terms, this distribution contains the copyright
00008   notice here and the copyright notice and permission notice
00009   in supporting documentation.  The terms do *not* require
00010   redistribution under those same terms.  This code is distributed
00011   to you under the terms of the GNU General Public License (GPL) 
00012   below.  The GPL does not require you to maintain the terms of
00013   the Loki Original Distribution Terms, but you are encouraged to do so.
00014 
00015   This program/file is free software; you can redistribute it and/or modify
00016   it under the terms of the GNU General Public License as published by
00017   the Free Software Foundation; either version 2 of the License, or
00018   (at your option) any later version.
00019   
00020   This program is distributed in the hope that it will be useful,
00021   but WITHOUT ANY WARRANTY; without even the implied warranty of
00022   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00023   GNU General Public License for more details. (http://www.gnu.org)
00024   
00025   You should have received a copy of the GNU General Public License
00026   along with this program; if not, write to the Free Software
00027   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00028   
00029  ****************************************************************************
00030   Loki Original Distribution Terms:
00031 
00032   The Loki Library
00033   Copyright (c) 2001 by Andrei Alexandrescu
00034   This code accompanies the book:
00035   Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design 
00036       Patterns Applied". Copyright (c) 2001. Addison-Wesley.
00037   Permission to use, copy, modify, distribute and sell this software for any 
00038       purpose is hereby granted without fee, provided that the above copyright 
00039       notice appear in all copies and that both that copyright notice and this 
00040       permission notice appear in supporting documentation.
00041   The author or Addison-Welsey Longman make no representations about the 
00042       suitability of this software for any purpose. It is provided "as is" 
00043       without express or implied warranty.
00044  ****************************************************************************
00045 
00046   $Id: TypeManip 1029 2004-02-11 20:45:54Z jungd $
00047   $Revision: 1.1 $
00048   $Date: 2004-02-11 15:45:54 -0500 (Wed, 11 Feb 2004) $
00049   $Author: jungd $
00050  
00051 ****************************************************************************/
00052 
00053 // Last update: June 20, 2001
00054 
00055 #ifndef TYPEMANIP_INC_
00056 #define TYPEMANIP_INC_
00057 
00058 namespace base
00059 {
00060 ////////////////////////////////////////////////////////////////////////////////
00061 // class template Int2Type
00062 // Converts each integral constant into a unique type
00063 // Invocation: Int2Type<v> where v is a compile-time constant integral
00064 // Defines 'value', an enum that evaluates to v
00065 ////////////////////////////////////////////////////////////////////////////////
00066 
00067     template <int v>
00068     struct Int2Type
00069     {
00070         enum { value = v };
00071     };
00072     
00073 ////////////////////////////////////////////////////////////////////////////////
00074 // class template Type2Type
00075 // Converts each type into a unique, insipid type
00076 // Invocation Type2Type<T> where T is a type
00077 // Defines the type OriginalType which maps back to T
00078 ////////////////////////////////////////////////////////////////////////////////
00079 
00080     template <typename T>
00081     struct Type2Type
00082     {
00083         typedef T OriginalType;
00084     };
00085     
00086 ////////////////////////////////////////////////////////////////////////////////
00087 // class template Select
00088 // Selects one of two types based upon a boolean constant
00089 // Invocation: Select<flag, T, U>::Result
00090 // where:
00091 // flag is a compile-time boolean constant
00092 // T and U are types
00093 // Result evaluates to T if flag is true, and to U otherwise.
00094 ////////////////////////////////////////////////////////////////////////////////
00095 
00096     template <bool flag, typename T, typename U>
00097     struct Select
00098     {
00099         typedef T Result;
00100     };
00101     template <typename T, typename U>
00102     struct Select<false, T, U>
00103     {
00104         typedef U Result;
00105     };
00106     
00107 ////////////////////////////////////////////////////////////////////////////////
00108 // Helper types Small and Big - guarantee that sizeof(Small) < sizeof(Big)
00109 ////////////////////////////////////////////////////////////////////////////////
00110 
00111     namespace Private
00112     {
00113         template <class T, class U>
00114         struct ConversionHelper
00115         {
00116             typedef char Small;
00117             struct Big { char dummy[2]; };
00118             static Big   Test(...);
00119             static Small Test(U);
00120             static T MakeT();
00121         };
00122     }
00123 
00124 ////////////////////////////////////////////////////////////////////////////////
00125 // class template Conversion
00126 // Figures out the conversion relationships between two types
00127 // Invocations (T and U are types):
00128 // a) Conversion<T, U>::exists
00129 // returns (at compile time) true if there is an implicit conversion from T
00130 // to U (example: Derived to Base)
00131 // b) Conversion<T, U>::exists2Way
00132 // returns (at compile time) true if there are both conversions from T
00133 // to U and from U to T (example: int to char and back)
00134 // c) Conversion<T, U>::sameType
00135 // returns (at compile time) true if T and U represent the same type
00136 //
00137 // Caveat: might not work if T and U are in a private inheritance hierarchy.
00138 ////////////////////////////////////////////////////////////////////////////////
00139 
00140     template <class T, class U>
00141     struct Conversion
00142     {
00143         typedef Private::ConversionHelper<T, U> H;
00144 #ifndef __MWERKS__
00145         enum { exists = sizeof(typename H::Small) == sizeof(H::Test(H::MakeT())) };
00146 #else
00147         enum { exists = false };
00148 #endif
00149         enum { exists2Way = exists && Conversion<U, T>::exists };
00150         enum { sameType = false };
00151     };
00152     
00153     template <class T>
00154     struct Conversion<T, T>    
00155     {
00156         enum { exists = 1, exists2Way = 1,sameType = 1 };
00157     };
00158     
00159     template <class T>
00160     struct Conversion<void, T>    
00161     {
00162         enum { exists = 1, exists2Way = 0,sameType = 0 };
00163     };
00164     
00165     template <class T>
00166     struct Conversion<T, void>    
00167     {
00168         enum { exists = 1, exists2Way = 0,sameType = 0 };
00169     };
00170     
00171     template <>
00172     class Conversion<void, void>    
00173     {
00174     public:
00175         enum { exists = 1, exists2Way = 1,sameType = 1 };
00176     };    
00177 }
00178 
00179 ////////////////////////////////////////////////////////////////////////////////
00180 // macro SUPERSUBCLASS
00181 // Invocation: SUPERSUBCLASS(B, D) where B and D are types. 
00182 // Returns true if B is a public base of D, or if B and D are aliases of the 
00183 // same type.
00184 //
00185 // Caveat: might not work if T and U are in a private inheritance hierarchy.
00186 ////////////////////////////////////////////////////////////////////////////////
00187 
00188 #define SUPERSUBCLASS(T, U) \
00189     (::base::Conversion<const U*, const T*>::exists && \
00190     !::base::Conversion<const T*, const void*>::sameType)
00191 
00192 ////////////////////////////////////////////////////////////////////////////////
00193 // macro SUPERSUBCLASS
00194 // Invocation: SUPERSUBCLASS(B, D) where B and D are types. 
00195 // Returns true if B is a public base of D.
00196 //
00197 // Caveat: might not work if T and U are in a private inheritance hierarchy.
00198 ////////////////////////////////////////////////////////////////////////////////
00199 
00200 #define SUPERSUBCLASS_STRICT(T, U) \
00201     (SUPERSUBCLASS(T, U) && \
00202     !::base::Conversion<const T, const U>::sameType)
00203 
00204 ////////////////////////////////////////////////////////////////////////////////
00205 // Change log:
00206 // June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!!
00207 ////////////////////////////////////////////////////////////////////////////////
00208 
00209 #endif // TYPEMANIP_INC_

Generated on Thu Jul 29 15:56:16 2004 for OpenSim by doxygen 1.3.6