1 /* 2 * TypeTraits.h 3 * Apto 4 * 5 * Created by David on 5/12/11. 6 * Copyright 2011 David Michael Bryson. All rights reserved. 7 * http://programerror.com/software/apto 8 * 9 * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the 10 * following conditions are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the 13 * following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the 15 * following disclaimer in the documentation and/or other materials provided with the distribution. 16 * 3. Neither the name of David Michael Bryson, nor the names of contributors may be used to endorse or promote 17 * products derived from this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY DAVID MICHAEL BRYSON AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 20 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 * DISCLAIMED. IN NO EVENT SHALL DAVID MICHAEL BRYSON OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 25 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 * 27 * Authors: David M. Bryson <david@programerror.com> 28 * 29 * TypeTraits based off of ideas presented in Modern C++ Design (2001) by Andrei Alexandrescu 30 */ 31 32 #ifndef AptoCoreTypeTraits_h 33 #define AptoCoreTypeTraits_h 34 35 #include "apto/core/TypeList.h" 36 37 namespace Apto { 38 39 namespace Types { 40 typedef TL::Create< 41 unsigned char, unsigned short int, unsigned int, unsigned long int, unsigned long long int 42 >::Type StandardUnsignedInts; 43 44 typedef TL::Create< 45 signed char, signed short int, signed int, signed long int, signed long long int 46 >::Type StandardSignedInts; 47 48 typedef TL::Create< 49 bool, char, wchar_t 50 >::Type StandardOtherInts; 51 52 typedef TL::Create< 53 float, double, long double 54 >::Type StandardFloatingPoint; 55 } 56 57 namespace Internal { 58 template <class U> struct MakeParameterType 59 { 60 typedef const U& Result; 61 }; 62 template <class U> struct MakeParameterType<U&> 63 { 64 typedef U& Result; 65 }; 66 template <> struct MakeParameterType<void> 67 { 68 typedef NullType Result; 69 }; 70 } 71 72 template <typename T> class TypeTraits 73 { 74 private: 75 template <class U> struct ReferenceTraits 76 { 77 enum { Result = false }; 78 typedef U ReferredType; 79 }; 80 template <class U> struct ReferenceTraits<U&> 81 { 82 enum { Result = true }; 83 typedef U ReferredType; 84 }; 85 86 87 template <class U> struct PointerTraits 88 { 89 enum { Result = false }; 90 typedef NullType PointeeType; 91 }; 92 template <class U> struct PointerTraits<U*> 93 { 94 enum { Result = true }; 95 typedef U PointeeType; 96 }; 97 template <class U> struct PointerTraits<U*&> 98 { 99 enum { Result = true }; 100 typedef U PointeeType; 101 }; 102 103 104 template <class U> struct PointerToMemberTraits 105 { 106 enum { Result = false }; 107 }; 108 template <class U, class V> struct PointerToMemberTraits<U V::*> 109 { 110 enum { Result = true }; 111 }; 112 template <class U, class V> struct PointerToMemberTraits<U V::*&> 113 { 114 enum { Result = true }; 115 }; 116 117 118 template <class U> struct UnConst 119 { 120 typedef U Result; 121 enum { IsConst = false }; 122 }; 123 template <class U> struct UnConst<const U> 124 { 125 typedef U Result; 126 enum { IsConst = true }; 127 }; 128 template <class U> struct UnConst<const U&> 129 { 130 typedef U Result; 131 enum { IsConst = true }; 132 }; 133 134 135 template <class U> struct UnVolatile 136 { 137 typedef U Result; 138 enum { IsVolatile = false }; 139 }; 140 template <class U> struct UnVolatile<const U> 141 { 142 typedef U Result; 143 enum { IsVolatile = true }; 144 }; 145 template <class U> struct UnVolatile<const U&> 146 { 147 typedef U Result; 148 enum { IsVolatile = true }; 149 }; 150 151 152 public: 153 typedef typename UnConst<T>::Result NonConstType; 154 typedef typename UnVolatile<T>::Result NonVolatileType; 155 typedef typename UnVolatile<typename UnConst<T>::Result >::Result UnqualifiedType; 156 typedef typename PointerTraits<UnqualifiedType>::PointeeType PointeeType; 157 typedef typename ReferenceTraits<T>::ReferredType ReferredType; 158 159 enum { IsConst = UnConst<T>::IsConst }; 160 enum { IsVolatile = UnVolatile<T>::IsVolatile }; 161 enum { IsReference = ReferenceTraits<UnqualifiedType>::Result }; 162 enum { IsPointer = PointerTraits<typename ReferenceTraits<UnqualifiedType>::ReferredType>::Result }; 163 enum { IsMemberPointer = PointerToMemberTraits<typename ReferenceTraits<UnqualifiedType>::ReferredType>::Result }; 164 enum { IsStandardUnsignedInt = TL::IndexOf<Types::StandardUnsignedInts, UnqualifiedType>::Value >= 0 || 165 TL::IndexOf<Types::StandardUnsignedInts, typename ReferenceTraits<UnqualifiedType>::ReferredType>::Value >= 0 }; 166 enum { IsStandardSignedInt = TL::IndexOf<Types::StandardSignedInts, UnqualifiedType>::Value >= 0 || 167 TL::IndexOf<Types::StandardSignedInts, typename ReferenceTraits<UnqualifiedType>::ReferredType>::Value >= 0 }; 168 enum { IsStandardIntegral = IsStandardUnsignedInt || IsStandardSignedInt || 169 TL::IndexOf<Types::StandardOtherInts, UnqualifiedType>::Value >= 0 || 170 TL::IndexOf<Types::StandardOtherInts, typename ReferenceTraits<UnqualifiedType>::ReferredType>::Value >= 0 }; 171 enum { IsStandardFloatingPoint = TL::IndexOf<Types::StandardFloatingPoint, UnqualifiedType>::Value >= 0 || 172 TL::IndexOf<Types::StandardFloatingPoint, typename ReferenceTraits<UnqualifiedType>::ReferredType>::Value >= 0 }; 173 enum { IsStandardArithmetic = IsStandardIntegral || IsStandardFloatingPoint }; 174 enum { IsIntegral = IsStandardIntegral }; 175 enum { IsFloatingPoint = IsStandardFloatingPoint }; 176 enum { IsArithmetic = IsIntegral || IsFloatingPoint }; 177 178 typedef typename TypeSelect< 179 IsArithmetic || IsPointer || IsMemberPointer, 180 T, 181 typename Internal::MakeParameterType<T>::Result 182 >::Result ParameterType; 183 }; 184 }; 185 186 #endif 187