github.com/ckxng/wakeup@v0.0.0-20190105202853-90356a5f5a15/include/internal/cef_ptr.h (about)

     1  // Copyright (c) 2008 Marshall A. Greenblatt. Portions Copyright (c)
     2  // 2006-2008 Google Inc. All rights reserved.
     3  //
     4  // Redistribution and use in source and binary forms, with or without
     5  // modification, are permitted provided that the following conditions are
     6  // met:
     7  //
     8  //    * Redistributions of source code must retain the above copyright
     9  // notice, this list of conditions and the following disclaimer.
    10  //    * Redistributions in binary form must reproduce the above
    11  // copyright notice, this list of conditions and the following disclaimer
    12  // in the documentation and/or other materials provided with the
    13  // distribution.
    14  //    * Neither the name of Google Inc. nor the name Chromium Embedded
    15  // Framework nor the names of its contributors may be used to endorse
    16  // or promote products derived from this software without specific prior
    17  // written permission.
    18  //
    19  // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    20  // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    21  // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    22  // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    23  // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    24  // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    25  // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    26  // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    27  // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    28  // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    29  // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    30  
    31  
    32  #ifndef CEF_INCLUDE_INTERNAL_CEF_PTR_H_
    33  #define CEF_INCLUDE_INTERNAL_CEF_PTR_H_
    34  #pragma once
    35  
    36  #include <stddef.h>
    37  
    38  ///
    39  // Smart pointer implementation borrowed from base/ref_counted.h
    40  // <p>
    41  // A smart pointer class for reference counted objects.  Use this class instead
    42  // of calling AddRef and Release manually on a reference counted object to
    43  // avoid common memory leaks caused by forgetting to Release an object
    44  // reference.  Sample usage:
    45  // <pre>
    46  //   class MyFoo : public CefBase {
    47  //    ...
    48  //   };
    49  //
    50  //   void some_function() {
    51  //     // The MyFoo object that |foo| represents starts with a single
    52  //     // reference.
    53  //     CefRefPtr&lt;MyFoo&gt; foo = new MyFoo();
    54  //     foo-&gt;Method(param);
    55  //     // |foo| is released when this function returns
    56  //   }
    57  //
    58  //   void some_other_function() {
    59  //     CefRefPtr&lt;MyFoo&gt; foo = new MyFoo();
    60  //     ...
    61  //     foo = NULL;  // explicitly releases |foo|
    62  //     ...
    63  //     if (foo)
    64  //       foo-&gt;Method(param);
    65  //   }
    66  // </pre>
    67  // The above examples show how CefRefPtr&lt;T&gt; acts like a pointer to T.
    68  // Given two CefRefPtr&lt;T&gt; classes, it is also possible to exchange
    69  // references between the two objects, like so:
    70  // <pre>
    71  //   {
    72  //     CefRefPtr&lt;MyFoo&gt; a = new MyFoo();
    73  //     CefRefPtr&lt;MyFoo&gt; b;
    74  //
    75  //     b.swap(a);
    76  //     // now, |b| references the MyFoo object, and |a| references NULL.
    77  //   }
    78  // </pre>
    79  // To make both |a| and |b| in the above example reference the same MyFoo
    80  // object, simply use the assignment operator:
    81  // <pre>
    82  //   {
    83  //     CefRefPtr&lt;MyFoo&gt; a = new MyFoo();
    84  //     CefRefPtr&lt;MyFoo&gt; b;
    85  //
    86  //     b = a;
    87  //     // now, |a| and |b| each own a reference to the same MyFoo object.
    88  //     // the reference count of the underlying MyFoo object will be 2.
    89  //   }
    90  // </pre>
    91  // Reference counted objects can also be passed as function parameters and
    92  // used as function return values:
    93  // <pre>
    94  //   void some_func_with_param(CefRefPtr&lt;MyFoo&gt; param) {
    95  //     // A reference is added to the MyFoo object that |param| represents
    96  //     // during the scope of some_func_with_param() and released when
    97  //     // some_func_with_param() goes out of scope.
    98  //   }
    99  //
   100  //   CefRefPtr&lt;MyFoo&gt; some_func_with_retval() {
   101  //     // The MyFoo object that |foox| represents starts with a single
   102  //     // reference.
   103  //     CefRefPtr&lt;MyFoo&gt; foox = new MyFoo();
   104  //
   105  //     // Creating the return value adds an additional reference.
   106  //     return foox;
   107  //
   108  //     // When some_func_with_retval() goes out of scope the original |foox|
   109  //     // reference is released.
   110  //   }
   111  //
   112  //   void and_another_function() {
   113  //     CefRefPtr&lt;MyFoo&gt; foo = new MyFoo();
   114  //
   115  //     // pass |foo| as a parameter.
   116  //     some_function(foo);
   117  //
   118  //     CefRefPtr&lt;MyFoo&gt; foo2 = some_func_with_retval();
   119  //     // Now, since we kept a reference to the some_func_with_retval() return
   120  //     // value, |foo2| is the only class pointing to the MyFoo object created
   121  //     in some_func_with_retval(), and it has a reference count of 1.
   122  //
   123  //     some_func_with_retval();
   124  //     // Now, since we didn't keep a reference to the some_func_with_retval()
   125  //     // return value, the MyFoo object created in some_func_with_retval()
   126  //     // will automatically be released.
   127  //   }
   128  // </pre>
   129  // And in standard containers:
   130  // <pre>
   131  //   {
   132  //      // Create a vector that holds MyFoo objects.
   133  //      std::vector&lt;CefRefPtr&lt;MyFoo&gt; &gt; MyFooVec;
   134  //
   135  //     // The MyFoo object that |foo| represents starts with a single
   136  //     // reference.
   137  //     CefRefPtr&lt;MyFoo&gt; foo = new MyFoo();
   138  //
   139  //     // When the MyFoo object is added to |MyFooVec| the reference count
   140  //     // is increased to 2.
   141  //     MyFooVec.push_back(foo);
   142  //   }
   143  // </pre>
   144  // </p>
   145  ///
   146  template <class T>
   147  class CefRefPtr {
   148   public:
   149    CefRefPtr() : ptr_(NULL) {
   150    }
   151  
   152    CefRefPtr(T* p) : ptr_(p) {  // NOLINT(runtime/explicit)
   153      if (ptr_)
   154        ptr_->AddRef();
   155    }
   156  
   157    CefRefPtr(const CefRefPtr<T>& r) : ptr_(r.ptr_) {
   158      if (ptr_)
   159        ptr_->AddRef();
   160    }
   161  
   162    ~CefRefPtr() {
   163      if (ptr_)
   164        ptr_->Release();
   165    }
   166  
   167    T* get() const { return ptr_; }
   168    operator T*() const { return ptr_; }
   169    T* operator->() const { return ptr_; }
   170  
   171    CefRefPtr<T>& operator=(T* p) {
   172      // AddRef first so that self assignment should work
   173      if (p)
   174        p->AddRef();
   175      if (ptr_ )
   176        ptr_ ->Release();
   177      ptr_ = p;
   178      return *this;
   179    }
   180  
   181    CefRefPtr<T>& operator=(const CefRefPtr<T>& r) {
   182      return *this = r.ptr_;
   183    }
   184  
   185    void swap(T** pp) {
   186      T* p = ptr_;
   187      ptr_ = *pp;
   188      *pp = p;
   189    }
   190  
   191    void swap(CefRefPtr<T>& r) {
   192      swap(&r.ptr_);  // NOLINT(build/include_what_you_use)
   193    }
   194  
   195   private:
   196    T* ptr_;
   197  };
   198  
   199  #endif  // CEF_INCLUDE_INTERNAL_CEF_PTR_H_