///////////////////////////////////////////////////////////////// // IsType.cpp - some metafunctions to test for specific types // // // // Jim Fawcett, CSE687 - Object Oriented Design, Spring 05 // ///////////////////////////////////////////////////////////////// // // This example illustrates a MetaProgramming that // manipulates types, not values. //----< IsChar >--------------------------------- template struct IsChar { enum { value=false }; }; template <> struct IsChar { enum { value=true }; }; //----< IsArray >-------------------------------- template struct IsArray { enum { value=false }; }; template struct IsArray { enum { value=true }; }; //----< IsPointer >------------------------------ template struct IsPointer { enum { value=false }; }; template struct IsPointer { enum { value=true }; }; template struct IsPointer { enum { value=true }; }; template struct IsPointer { enum { value=true }; }; template struct IsPointer { enum { value=true }; }; //----< IsPointer to member >-------------------- template struct IsPointerToMember { enum { value=false }; }; template struct IsPointerToMember { enum { value=true }; // member data }; template struct IsPointerToMember { enum { value=true }; // member function }; // //----< demonstrations >------------------------- #ifdef TEST_ISTYPE #include class Y {}; class X { public: void fun() {} int i; }; void main() { std::cout << "\n Demonstrating Evaluation of Types at Compile-Time"; std::cout << "\n ===================================================\n"; if(IsChar::value) std::cout << "\n int is a char"; else std::cout << "\n int is not a char"; typedef char charType; if(IsChar::value) std::cout << "\n charType is a char"; else std::cout << "\n charType is not a char"; if(IsArray::value) std::cout << "\n X[3] is an array"; else std::cout << "\n X[3] is not an array"; if(IsArray::value) std::cout << "\n X* is an array"; else std::cout << "\n X* is not an array"; if(IsPointer::value) std::cout << "\n X is a pointer"; else std::cout << "\n X is not a pointer"; if(IsPointer::value) std::cout << "\n X* is a pointer"; else std::cout << "\n X* is not a pointer"; if(IsPointer::value) std::cout << "\n const X* is a pointer"; else std::cout << "\n const X* is not a pointer"; if(IsPointer::value) std::cout << "\n volatile X* is a pointer"; else std::cout << "\n volatile X* is not a pointer"; // // demonstrate use of pointer to members int X::*pXi = &X::i; // declare pointer to member data void (X::*pMf)(void) = &X::fun; // declare pointer to member function X x; x.*pXi = 3; // dereference member data pointer (x.*pMf)(); // invoke member function pointer if(IsPointerToMember::value) // false std::cout << "\n X* is a pointer to member"; else std::cout << "\n X* is not a pointer to member"; if(IsPointerToMember::value) // true std::cout << "\n Y X::* is a pointer to member"; else std::cout << "\n Y X::* is not a pointer to member"; if(IsPointerToMember::value) // true std::cout << "\n X& (X::*)(const X&) is a pointer to member"; else std::cout << "\n X& (X::*)(const X&) is not a pointer to member"; std::cout << "\n\n"; } #endif