1 // Copyright 2016 The Fuchsia 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.
4 
5 #pragma once
6 
7 #include <zircon/assert.h>
8 #include <fbl/macros.h>
9 #include <fbl/ref_counted_internal.h>
10 
11 namespace fbl {
12 
13 // Base class for a reference counted type.  Use as
14 //
15 // class Handle : public RefCounted<Handle> {
16 // };
17 //
18 // This supports intrusive atomic reference counting with adoption. This means
19 // that a new object starts life at a reference count of 1 and has to be adopted
20 // by a type (such as a fbl::RefPtr) that begins manipulation of the reference
21 // count. If the reference count ever reaches zero, the object's lifetime is
22 // over and it should be destroyed (Release() returns true if this is the case).
23 //
24 // You might be wondering about the unused |T| template parameter. It exists so
25 // that the base class of the derived object is a unique type. Without being a
26 // template then you can have many unrelated classes which can be implicitly
27 // upcasted to RefCounted* which is an undesirable situation for a mixin class
28 // like this one. Specially because the destructor is not virtual. The same is
29 // not possible via internal::RefCountedBase since the ctor and dtor are
30 // protected.
31 //
32 template <typename T,
33           bool EnableAdoptionValidator = ZX_DEBUG_ASSERT_IMPLEMENTED>
34 class RefCounted : private internal::RefCountedBase<EnableAdoptionValidator> {
35 public:
RefCounted()36     RefCounted() {}
~RefCounted()37     ~RefCounted() {}
38 
39     using internal::RefCountedBase<EnableAdoptionValidator>::AddRef;
40     using internal::RefCountedBase<EnableAdoptionValidator>::Release;
41     using internal::RefCountedBase<EnableAdoptionValidator>::Adopt;
42     using internal::RefCountedBase<EnableAdoptionValidator>::ref_count_debug;
43 
44     // RefCounted<> instances may not be copied, assigned or moved.
45     DISALLOW_COPY_ASSIGN_AND_MOVE(RefCounted);
46 };
47 
48 }  // namespace fbl
49