Roll leveldb from r73 to r75.
[chromium-blink-merge.git] / skia / ext / refptr.h
bloba3900f61ba4502c0d59c3b8664cf6bb4dd3c4aa1
1 // Copyright 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef SKIA_EXT_REFPTR_H_
6 #define SKIA_EXT_REFPTR_H_
8 #include "third_party/skia/include/core/SkRefCnt.h"
10 namespace skia {
12 // When creating/receiving a ref-counted pointer from Skia, wrap that pointer in
13 // this class to avoid dealing with the ref-counting and prevent leaks/crashes
14 // due to ref-counting bugs.
16 // Example of creating a new SkShader* and setting it on a SkPaint:
17 // skia::RefPtr<SkShader> shader = skia::AdoptRef(SkGradientShader::Create());
18 // paint.setShader(shader.get());
20 // When passing around a ref-counted pointer to methods outside of Skia, always
21 // pass around the skia::RefPtr instead of the raw pointer. An example method
22 // that takes a SkShader* parameter and saves the SkShader* in the class.
23 // void AMethodThatSavesAShader(const skia::RefPtr<SkShader>& shader) {
24 // member_refptr_ = shader;
25 // }
26 // skia::RefPtr<SkShader> member_refptr_;
28 // When returning a ref-counted pointer, also return the skia::RefPtr instead.
29 // An example method that creates an SkShader* and returns it:
30 // skia::RefPtr<SkShader> MakeAShader() {
31 // return skia::AdoptRef(SkGradientShader::Create());
32 // }
34 // To take a scoped reference to an object whose references are all owned
35 // by other objects (i.e. does not have one that needs to be adopted) use the
36 // skia::SharePtr helper:
38 // skia::RefPtr<SkShader> shader = skia::SharePtr(paint.getShader());
40 // Never call ref() or unref() on the underlying ref-counted pointer. If you
41 // AdoptRef() the raw pointer immediately into a skia::RefPtr and always work
42 // with skia::RefPtr instances instead, the ref-counting will be taken care of
43 // for you.
44 template<typename T>
45 class RefPtr {
46 public:
47 RefPtr() : ptr_(NULL) {}
49 RefPtr(const RefPtr& other)
50 : ptr_(other.get()) {
51 SkSafeRef(ptr_);
54 template<typename U>
55 RefPtr(const RefPtr<U>& other)
56 : ptr_(other.get()) {
57 SkSafeRef(ptr_);
60 ~RefPtr() {
61 clear();
64 RefPtr& operator=(const RefPtr& other) {
65 SkRefCnt_SafeAssign(ptr_, other.get());
66 return *this;
69 template<typename U>
70 RefPtr& operator=(const RefPtr<U>& other) {
71 SkRefCnt_SafeAssign(ptr_, other.get());
72 return *this;
75 void clear() {
76 T* to_unref = ptr_;
77 ptr_ = NULL;
78 SkSafeUnref(to_unref);
81 T* get() const { return ptr_; }
82 T& operator*() const { return *ptr_; }
83 T* operator->() const { return ptr_; }
85 typedef T* RefPtr::*unspecified_bool_type;
86 operator unspecified_bool_type() const {
87 return ptr_ ? &RefPtr::ptr_ : NULL;
90 private:
91 T* ptr_;
93 // This function cannot be public because Skia starts its ref-counted
94 // objects at refcnt=1. This makes it impossible to differentiate
95 // between a newly created object (that doesn't need to be ref'd) or an
96 // already existing object with one owner (that does need to be ref'd so that
97 // this RefPtr can also manage its lifetime).
98 explicit RefPtr(T* ptr) : ptr_(ptr) {}
100 template<typename U>
101 friend RefPtr<U> AdoptRef(U* ptr);
103 template<typename U>
104 friend RefPtr<U> SharePtr(U* ptr);
107 // For objects that have an unowned reference (such as newly created objects).
108 template<typename T>
109 RefPtr<T> AdoptRef(T* ptr) { return RefPtr<T>(ptr); }
111 // For objects that are already owned. This doesn't take ownership of existing
112 // references and adds a new one.
113 template<typename T>
114 RefPtr<T> SharePtr(T* ptr) { return RefPtr<T>(SkSafeRef(ptr)); }
116 } // namespace skia
118 #endif // SKIA_EXT_REFPTR_H_