FLANG

reference-counted.h
1 //===-- include/flang/Common/reference-counted.h ----------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 #ifndef FORTRAN_COMMON_REFERENCE_COUNTED_H_
10 #define FORTRAN_COMMON_REFERENCE_COUNTED_H_
11
12 // A class template of smart pointers to objects with their own
13 // reference counting object lifetimes that's lighter weight
14 // than std::shared_ptr<>. Not thread-safe.
15
16 namespace Fortran::common {
17
18 // A base class for reference-counted objects. Must be public.
19 template <typename A> class ReferenceCounted {
20 public:
21 ReferenceCounted() {}
22 void TakeReference() { ++references_; }
23 void DropReference() {
24 if (--references_ == 0) {
25 delete static_cast<A *>(this);
26 }
27 }
28
29 private:
30 int references_{0};
31 };
32
33 // A reference to a reference-counted object.
34 template <typename A> class CountedReference {
35 public:
36 using type = A;
37 CountedReference() {}
38 CountedReference(type *m) : p_{m} { Take(); }
39 CountedReference(const CountedReference &c) : p_{c.p_} { Take(); }
40 CountedReference(CountedReference &&c) : p_{c.p_} { c.p_ = nullptr; }
41 CountedReference &operator=(const CountedReference &c) {
42 c.Take();
43 Drop();
44 p_ = c.p_;
45 return *this;
46 }
47 CountedReference &operator=(CountedReference &&c) {
48 A *p{c.p_};
49 c.p_ = nullptr;
50 Drop();
51 p_ = p;
52 return *this;
53 }
54 ~CountedReference() { Drop(); }
55 operator bool() const { return p_ != nullptr; }
56 type *get() const { return p_; }
57 type &operator*() const { return *p_; }
58 type *operator->() const { return p_; }
59
60 private:
61 void Take() const {
62 if (p_) {
63 p_->TakeReference();
64 }
65 }
66 void Drop() {
67 if (p_) {
68 p_->DropReference();
69 p_ = nullptr;
70 }
71 }
72
73 type *p_{nullptr};
74 };
75 } // namespace Fortran::common
76 #endif // FORTRAN_COMMON_REFERENCE_COUNTED_H_
Fortran::common::CountedReference
Definition: reference-counted.h:34
Fortran::common::ReferenceCounted
Definition: reference-counted.h:19