// // Copyright (c) 2002 by Stephen C. Dewhurst // Permission to use, copy, modify, distribute and sell this software for any purpose is // hereby granted without fee, provided that the above copyright notice appears in all copies // and that both that copyright notice and this permission notice appear in supporting documentation. // The author or makes no representations about the suitability of this software for any purpose. // It is provided "as is" without express or implied warranty. // // "typeof" operator implementation // // Described in CUJ 20(8, 10, and 12), August, October, and December 2002: "A Bit-Wise Typeof" // #ifndef GENTYPE_H #define GENTYPE_H #include "multishift.h" // // Regenerating a type from a Godel number. // template struct GenType; template struct ModSwitch; template struct ModSwitch { // * typedef typename GenType::GTR *MSR; }; template struct ModSwitch { // * const typedef typename GenType::GTR * const MSR; }; template struct ModSwitch { // * volatile typedef typename GenType::GTR * volatile MSR; }; template struct ModSwitch { // * const volatile typedef typename GenType::GTR * const volatile MSR; }; template struct ModSwitch { // & typedef typename GenType::GTR &MSR; }; template struct ModSwitch { // [N] typedef ShiftRight SR; enum { bound = code1 & ArrayboundMask, c1 = SR::code1, c2 = SR::code2, c3 = SR::code3, c4 = SR::code4 }; typedef typename GenType::GTR MSR[bound]; }; template struct ModSwitch { // C::* // Note: BaseLen, not QualBaseLen! typedef ShiftRight SR; enum { classtype = code1 & BaseMask, c1 = SR::code1, c2 = SR::code2, c3 = SR::code3, c4 = SR::code4 }; typedef typename GenType::GTR MemType; typedef typename DeCode::R ClassType; typedef MemType ClassType::*MSR; }; template struct ModSwitch { // C::*const typedef const typename ModSwitch::MSR MSR; }; template struct ModSwitch { // C::*volatile typedef volatile typename ModSwitch::MSR MSR; }; template struct ModSwitch { // C::*const volatile typedef const volatile typename ModSwitch::MSR MSR; }; template struct FunSwitch; template struct FunSwitch<0,code4,code3,code2,code1> { typedef typename GenType::GTR RetType; typedef RetType FSR(void); }; template struct FunSwitch<1,code4,code3,code2,code1> { enum { arglen = code1 & ((1< SRR; enum { rc1 = SRR::code1, rc2 = SRR::code2, rc3 = SRR::code3, rc4 = SRR::code4 }; enum { argshiftlen = (CodeLen*NumCodes)-(arglen+ArglenLen) }; typedef ShiftLeft SL; enum { t1 = SL::code1, t2 = SL::code2, t3 = SL::code3, t4 = SL::code4 }; typedef ShiftRight SRA; enum { ac1 = SRA::code1, ac2 = SRA::code2, ac3 = SRA::code3, ac4 = SRA::code4 }; typedef typename GenType::GTR RetType; typedef typename GenType::GTR ArgType; typedef RetType FSR( ArgType ); }; template struct ModSwitch { // () typedef ShiftRight SR; enum { argcount = code1 & ((1<::FSR MSR; }; template struct ModSwitch { // R (C::*)(void) // Note: BaseLen, not QualBaseLen! enum { classtype = code1 & BaseMask, shiftamt = BaseLen+ArgcountLen+ModLen // pop off class code, 0 (arg count), and Fun mod }; typedef ShiftRight SR; enum { c1 = SR::code1, c2 = SR::code2, c3 = SR::code3, c4 = SR::code4 }; typedef typename FunSwitch<0,c4,c3,c2,c1>::RetType RetType; typedef typename DeCode::R ClassType; typedef RetType (ClassType::*MSR)(); }; template struct ModSwitch { // R (C::*)(void) const // Note: BaseLen, not QualBaseLen! enum { classtype = code1 & BaseMask, shiftamt = BaseLen+ArgcountLen+ModLen // pop off class code, 0 (arg count), and Fun mod }; typedef ShiftRight SR; enum { c1 = SR::code1, c2 = SR::code2, c3 = SR::code3, c4 = SR::code4 }; typedef typename FunSwitch<0,c4,c3,c2,c1>::RetType RetType; typedef typename DeCode::R ClassType; typedef RetType (ClassType::*MSR)() const; }; template struct ModSwitch { // R (C::*)(void) volatile // Note: BaseLen, not QualBaseLen! enum { classtype = code1 & BaseMask, shiftamt = BaseLen+ArgcountLen+ModLen // pop off class code, 0 (arg count), and Fun mod }; typedef ShiftRight SR; enum { c1 = SR::code1, c2 = SR::code2, c3 = SR::code3, c4 = SR::code4 }; typedef typename FunSwitch<0,c4,c3,c2,c1>::RetType RetType; typedef typename DeCode::R ClassType; typedef RetType (ClassType::*MSR)() volatile; }; template struct ModSwitch { // R (C::*)(void) const volatile // Note: BaseLen, not QualBaseLen! enum { classtype = code1 & BaseMask, shiftamt = BaseLen+ArgcountLen+ModLen // pop off class code, 0 (arg count), and Fun mod }; typedef ShiftRight SR; enum { c1 = SR::code1, c2 = SR::code2, c3 = SR::code3, c4 = SR::code4 }; typedef typename FunSwitch<0,c4,c3,c2,c1>::RetType RetType; typedef typename DeCode::R ClassType; typedef RetType (ClassType::*MSR)() const volatile; }; template struct ModSwitch { // R (C::*)(A) // Note: BaseLen, not QualBaseLen! enum { classtype = code1 & BaseMask, shiftamt = BaseLen+ArgcountLen+ModLen // pop off class code, 1 (arg count), and Fun mod }; typedef ShiftRight SR; enum { c1 = SR::code1, c2 = SR::code2, c3 = SR::code3, c4 = SR::code4 }; typedef FunSwitch<1,c4,c3,c2,c1> Fun; typedef typename Fun::RetType RetType; typedef typename Fun::ArgType ArgType; typedef typename DeCode::R ClassType; typedef RetType (ClassType::*MSR)(ArgType); }; template struct ModSwitch { // R (C::*)(A) const // Note: BaseLen, not QualBaseLen! enum { classtype = code1 & BaseMask, shiftamt = BaseLen+ArgcountLen+ModLen // pop off class code, 1 (arg count), and Fun mod }; typedef ShiftRight SR; enum { c1 = SR::code1, c2 = SR::code2, c3 = SR::code3, c4 = SR::code4 }; typedef FunSwitch<1,c4,c3,c2,c1> Fun; typedef typename Fun::RetType RetType; typedef typename Fun::ArgType ArgType; typedef typename DeCode::R ClassType; typedef RetType (ClassType::*MSR)(ArgType) const; }; template struct ModSwitch { // R (C::*)(A) volatile // Note: BaseLen, not QualBaseLen! enum { classtype = code1 & BaseMask, shiftamt = BaseLen+ArgcountLen+ModLen // pop off class code, 1 (arg count), and Fun mod }; typedef ShiftRight SR; enum { c1 = SR::code1, c2 = SR::code2, c3 = SR::code3, c4 = SR::code4 }; typedef FunSwitch<1,c4,c3,c2,c1> Fun; typedef typename Fun::RetType RetType; typedef typename Fun::ArgType ArgType; typedef typename DeCode::R ClassType; typedef RetType (ClassType::*MSR)(ArgType) volatile; }; template struct ModSwitch { // R (C::*)(A) const volatile // Note: BaseLen, not QualBaseLen! enum { classtype = code1 & BaseMask, shiftamt = BaseLen+ArgcountLen+ModLen // pop off class code, 1 (arg count), and Fun mod }; typedef ShiftRight SR; enum { c1 = SR::code1, c2 = SR::code2, c3 = SR::code3, c4 = SR::code4 }; typedef FunSwitch<1,c4,c3,c2,c1> Fun; typedef typename Fun::RetType RetType; typedef typename Fun::ArgType ArgType; typedef typename DeCode::R ClassType; typedef RetType (ClassType::*MSR)(ArgType) const volatile; }; template struct GenModType { typedef ShiftRight SR; enum { mod = code1 & ModMask, c1 = SR::code1, c2 = SR::code2, c3 = SR::code3, c4 = SR::code4 }; typedef typename ModSwitch::MSR MR; }; template struct GenBaseType { enum { base = code & BaseMask, isconst = code & ConstBaseQual, isvol = code & VolBaseQual }; typedef typename DeCode::R B; typedef typename Select::Result CB; typedef typename Select::Result VCB; typedef VCB R; }; template struct GenTypeImpl { typedef typename GenBaseType::R Result; }; template struct GenTypeImpl { typedef typename GenModType::MR Result; }; template struct GenType { // Indirection necessary to avoid instantiating both possibilities. typedef typename GenTypeImpl::Result GTR; }; #endif