/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
/* Cairo - a vector graphics library with display and print output
*
* Copyright < A9 > 2010 Mozilla Foundation
*
* This library is free software ; you can redistribute it and / or
* modify it either under the terms of the GNU Lesser General Public
* License version 2 . 1 as published by the Free Software Foundation
* ( the " LGPL " ) or , at your option , under the terms of the Mozilla
* Public License Version 1 . 1 ( the " MPL " ) . If you do not alter this
* notice , a recipient may use your version of this file under either
* the MPL or the LGPL .
*
* You should have received a copy of the LGPL along with this library
* in the file COPYING - LGPL - 2 . 1 ; if not , write to the Free Software
* Foundation , Inc . , 59 Temple Place , Suite 330 , Boston , MA 02111 - 1307 USA
* You should have received a copy of the MPL along with this library
* in the file COPYING - MPL - 1 . 1
*
* The contents of this file are subject to the Mozilla Public License
* Version 1 . 1 ( the " License " ) ; you may not use this file except in
* compliance with the License . You may obtain a copy of the License at
* http : //www.mozilla.org/MPL/
*
* This software is distributed on an " AS IS " basis , WITHOUT WARRANTY
* OF ANY KIND , either express or implied . See the LGPL or the MPL for
* the specific language governing rights and limitations .
*
* The Original Code is the cairo graphics library .
*
* The Initial Developer of the Original Code is the Mozilla Foundation
*
* Contributor ( s ) :
* Bas Schouten < bschouten @ mozilla . com >
*/
#ifndef CAIRO_WIN32_REFPTR_H
#define CAIRO_WIN32_REFPTR_H
template <typename T> class TemporaryRef;
/*
* RefPtr points to a refcounted thing that has AddRef and Release
* methods to increase / decrease the refcount , respectively . After a
* RefPtr < T > is assigned a T * , the T * can be used through the RefPtr
* as if it were a T * .
*
* A RefPtr can forget its underlying T * , which results in the T *
* being wrapped in a temporary object until the T * is either
* re - adopted from or released by the temporary .
*/
template <typename T>
class RefPtr
{
// To allow them to use unref()
friend class TemporaryRef<T>;
struct dontRef {};
public:
RefPtr() : ptr(0 ) { }
RefPtr(const RefPtr& o) : ptr(ref(o.ptr)) {}
RefPtr(const TemporaryRef<T>& o) : ptr(o.drop()) {}
RefPtr(T* t) : ptr(ref(t)) {}
template <typename U>
RefPtr(const RefPtr<U>& o) : ptr(ref(o.get())) {}
~RefPtr() { unref(ptr); }
RefPtr& operator =(const RefPtr& o) {
assign(ref(o.ptr));
return *this;
}
RefPtr& operator =(const TemporaryRef<T>& o) {
assign(o.drop());
return *this;
}
RefPtr& operator =(T* t) {
assign(ref(t));
return *this;
}
template <typename U>
RefPtr& operator =(const RefPtr<U>& o) {
assign(ref(o.get()));
return *this;
}
TemporaryRef<T> forget() {
T* tmp = ptr;
ptr = 0 ;
return TemporaryRef<T>(tmp, dontRef());
}
T* get() const { return ptr; }
operator T*() const { return ptr; }
T* operator ->() const { return ptr; }
T& operator *() const { return *ptr; }
template <typename U>
operator TemporaryRef<U>() { return TemporaryRef<U>(ptr); }
/**
* WARNING for ease of use , passing a reference will release / clear out ptr !
* We null out the ptr before returning its address so people passing byref
* as input will most likely get functions returning errors rather than accessing
* freed memory . Further more accessing it after this point if it hasn ' t
* been set will produce a null pointer dereference .
*/
T** operator &()
{
if (ptr) {
ptr->Release();
ptr = NULL;
}
return &ptr;
}
private :
void assign(T* t) {
unref(ptr);
ptr = t;
}
T* ptr;
static inline T* ref(T* t) {
if (t) {
t->AddRef();
}
return t;
}
static inline void unref(T* t) {
if (t) {
t->Release();
}
}
};
/*
* TemporaryRef < T > represents an object that holds a temporary
* reference to a T . TemporaryRef objects can ' t be manually ref ' d or
* unref ' d ( being temporaries , not lvalues ) , so can only relinquish
* references to other objects , or unref on destruction .
*/
template <typename T>
class TemporaryRef
{
// To allow it to construct TemporaryRef from a bare T*
friend class RefPtr<T>;
typedef typename RefPtr<T>::dontRef dontRef;
public:
TemporaryRef(T* t) : ptr(RefPtr<T>::ref(t)) {}
TemporaryRef(const TemporaryRef& o) : ptr(o.drop()) {}
template <typename U>
TemporaryRef(const TemporaryRef<U>& o) : ptr(o.drop()) {}
~TemporaryRef() { RefPtr<T>::unref(ptr); }
T* drop() const {
T* tmp = ptr;
ptr = 0 ;
return tmp;
}
private :
TemporaryRef(T* t, const dontRef&) : ptr(t) {}
mutable T* ptr;
TemporaryRef();
TemporaryRef& operator =(const TemporaryRef&);
};
#endif
Messung V0.5 in Prozent C=95 H=98 G=96
¤ Dauer der Verarbeitung: 0.7 Sekunden
¤
*© Formatika GbR, Deutschland