From fbe76102e941b9f1edaf236788e42678f05fdf9a Mon Sep 17 00:00:00 2001 From: Daniel Wilhelm Date: Fri, 18 Apr 2014 17:08:06 +0200 Subject: 3.9 --- shared/com_ptr.h | 186 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 186 insertions(+) create mode 100644 shared/com_ptr.h (limited to 'shared/com_ptr.h') diff --git a/shared/com_ptr.h b/shared/com_ptr.h new file mode 100644 index 00000000..1ce7eae6 --- /dev/null +++ b/shared/com_ptr.h @@ -0,0 +1,186 @@ +// ************************************************************************** +// * This file is part of the FreeFileSync project. It is distributed under * +// * GNU General Public License: http://www.gnu.org/licenses/gpl.html * +// * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) * +// ************************************************************************** +// +#ifndef SMART_COM_PTR_H +#define SMART_COM_PTR_H + +#include +#include + +namespace util +{ +/* +ComPtr: RAII class handling COM objects + +Example: + -------- + ComPtr devFinder; + if (FAILED(::CoCreateInstance(CLSID_UPnPDeviceFinder, + NULL, + CLSCTX_ALL, + IID_PPV_ARGS(devFinder.init())))) + return -1; + + ComPtr devEnum = com_dynamic_cast(devColl); + if (!devEnum) + return -1; +*/ + +template +class ComPtr +{ +public: + ComPtr(); + ComPtr(const ComPtr& rhs); + ComPtr& operator=(const ComPtr& rhs); + ~ComPtr(); + T** init(); //get pointer for use with ::CoCreateInstance() + T* get() const; + T* release(); + void swap(ComPtr& rhs); //throw() + T* operator->() const; + operator bool() const; + +private: + T* ptr; +}; + + +template +ComPtr com_dynamic_cast(const ComPtr& other); //throw() + + + + + + + + + + + + + + + + + + + + + + + + + +//################# Inline Implementation ############################# + +template +inline +ComPtr::ComPtr() : ptr(NULL) {} + + +template +inline +ComPtr::ComPtr(const ComPtr& rhs) : ptr(rhs.ptr) +{ + if (ptr) + ptr->AddRef(); +} + + +template +inline +ComPtr& ComPtr::operator=(const ComPtr& rhs) +{ + ComPtr(rhs).swap(*this); + return *this; +} + + +template +inline +ComPtr::~ComPtr() +{ + if (ptr) + ptr->Release(); +} + + +template +inline +T** ComPtr::init() //get pointer for use with ::CoCreateInstance() +{ + ComPtr().swap(*this); + return &ptr; +} + + +template +inline +T* ComPtr::get() const +{ + return ptr; +} + + +template +inline +T* ComPtr::release() //throw() +{ + T* tmp = ptr; + ptr = NULL; + return tmp; +} + + +template +inline +void ComPtr::swap(ComPtr& rhs) //throw() +{ + std::swap(ptr, rhs.ptr); +} + + +//we cannot specialize std::swap() for a class template and are not allowed to overload it => offer swap in own namespace +template +inline +void swap(util::ComPtr& lhs, util::ComPtr& rhs) +{ + lhs.swap(rhs); +} + + +template +inline +T* ComPtr::operator->() const +{ + return ptr; +} + + +template +inline +ComPtr::operator bool() const +{ + return ptr != NULL; +} + + +template +inline +ComPtr com_dynamic_cast(const ComPtr& other) //throw() +{ + ComPtr outPtr; + if (other) + other->QueryInterface(IID_PPV_ARGS(outPtr.init())); + return outPtr; +} + +} + + +#endif //SMART_COM_PTR_H \ No newline at end of file -- cgit