#ifndef VENEERS_H #define VENEERS_H /////////////////////////////////////////////////////////////// // veneers.h - Add behavior without changing size // // // // Jim Fawcett, CSE687 - Object Oriented Design, Spring 2005 // /////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////// // VENEERS were described in detail in: // // "Imperfect C++", Matthew Wilson, Addison-Wesley, 2005 // /////////////////////////////////////////////////////////////// /* * VENEERS are template classes that: * 1. derive publicly from their first template parameter * 2. may override base virtual methods if the base class is * polymorphic, but adds none of its own * 3. may not define any non-static member data * As a consequence, veneers do not increase the size of their * base and can be passed to C-style functions that expect their * base type. */ #ifdef TEST_VENEERS #include #endif #include "../Constraints/constraints.h" ///////////////////////////////////////////////// // POD_veneer // ========== // Goal: // Add RAII to POD type without changing instance // size. This allows objects to be passed to // C-Style interfaces, e.g. Win32, without casting. ///////////////////////////////////////////////// template class pod_veener : public T { typedef pod_veener class_type; public: pod_veener() { CF()(static_cast(this)); } ~pod_veener() { Is_POD(T); Is_Same_Size(class_type, T); DF()(static_cast(this)); } }; // ///////////////////////////////////////////////// // HandleType is the base for Handle_VENEERS // cast operator returns h as HANDLE struct HandleType { HANDLE h; operator HANDLE () { return h; } }; ///////////////////////////////////////////////// // HandleType destruction functor struct HDtor { void operator()(HandleType* pHE) { CloseHandle(pHE->h); #ifdef TEST_VENEERS std::cout << "\n closing handle"; #endif } }; ///////////////////////////////////////////////// // Event construction functor struct HEvCtor { void operator()(HandleType* pHE) { pHE->h = (HANDLE)CreateEvent(0,true,false,0); } }; typedef pod_veener Event; ///////////////////////////////////////////////// // Mutex construction functor struct HMtxCtor { /////////////////////////////////////////////// // all declarers get a handle to the same // "named" mutex void operator()(HandleType* pHM) { pHM->h = (HANDLE)CreateMutex(0,false,"veener"); } }; typedef pod_veener Mutex; // ///////////////////////////////////////////////// // Thread processing function void _cdecl thrdProc(void *pVoid) { Mutex mtx; WaitForSingleObject(mtx,INFINITE); ::Sleep(2000); ReleaseMutex(mtx); } ///////////////////////////////////////////////// // Thread construction functor struct HThdCtor { void operator() (HandleType* pTH) { pTH->h = (HANDLE)_beginthread(thrdProc,0,0); } }; typedef pod_veener Thread; #endif