Warning: This file is not a C or C++ file. It does not have highlighting.
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 | int references() const { return references_; } |
23 | void TakeReference() { ++references_; } |
24 | void DropReference() { |
25 | if (--references_ == 0) { |
26 | delete static_cast<A *>(this); |
27 | } |
28 | } |
29 | |
30 | private: |
31 | int references_{0}; |
32 | }; |
33 | |
34 | // A reference to a reference-counted object. |
35 | template <typename A> class CountedReference { |
36 | public: |
37 | using type = A; |
38 | CountedReference() {} |
39 | CountedReference(type *m) : p_{m} { Take(); } |
40 | CountedReference(const CountedReference &c) : p_{c.p_} { Take(); } |
41 | CountedReference(CountedReference &&c) : p_{c.p_} { c.p_ = nullptr; } |
42 | CountedReference &operator=(const CountedReference &c) { |
43 | c.Take(); |
44 | Drop(); |
45 | p_ = c.p_; |
46 | return *this; |
47 | } |
48 | CountedReference &operator=(CountedReference &&c) { |
49 | A *p{c.p_}; |
50 | c.p_ = nullptr; |
51 | Drop(); |
52 | p_ = p; |
53 | return *this; |
54 | } |
55 | ~CountedReference() { Drop(); } |
56 | operator bool() const { return p_ != nullptr; } |
57 | type *get() const { return p_; } |
58 | type &operator*() const { return *p_; } |
59 | type *operator->() const { return p_; } |
60 | |
61 | private: |
62 | void Take() const { |
63 | if (p_) { |
64 | p_->TakeReference(); |
65 | } |
66 | } |
67 | void Drop() { |
68 | if (p_) { |
69 | p_->DropReference(); |
70 | p_ = nullptr; |
71 | } |
72 | } |
73 | |
74 | type *p_{nullptr}; |
75 | }; |
76 | } // namespace Fortran::common |
77 | #endif // FORTRAN_COMMON_REFERENCE_COUNTED_H_ |
78 |
Warning: This file is not a C or C++ file. It does not have highlighting.