1 | //===----------------------------------------------------------------------===// |
2 | // DuckDB |
3 | // |
4 | // duckdb/common/optional_ptr.hpp |
5 | // |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #pragma once |
10 | |
11 | #include "duckdb/common/exception.hpp" |
12 | #include "duckdb/common/unique_ptr.hpp" |
13 | |
14 | namespace duckdb { |
15 | |
16 | template <class T> |
17 | class optional_ptr { |
18 | public: |
19 | optional_ptr() : ptr(nullptr) { |
20 | } |
21 | optional_ptr(T *ptr_p) : ptr(ptr_p) { // NOLINT: allow implicit creation from pointer |
22 | } |
23 | optional_ptr(const unique_ptr<T> &ptr_p) : ptr(ptr_p.get()) { // NOLINT: allow implicit creation from unique pointer |
24 | } |
25 | |
26 | void CheckValid() const { |
27 | if (!ptr) { |
28 | throw InternalException("Attempting to dereference an optional pointer that is not set" ); |
29 | } |
30 | } |
31 | |
32 | operator bool() const { |
33 | return ptr; |
34 | } |
35 | T &operator*() { |
36 | CheckValid(); |
37 | return *ptr; |
38 | } |
39 | const T &operator*() const { |
40 | CheckValid(); |
41 | return *ptr; |
42 | } |
43 | T *operator->() { |
44 | CheckValid(); |
45 | return ptr; |
46 | } |
47 | const T *operator->() const { |
48 | CheckValid(); |
49 | return ptr; |
50 | } |
51 | T *get() { |
52 | // CheckValid(); |
53 | return ptr; |
54 | } |
55 | const T *get() const { |
56 | // CheckValid(); |
57 | return ptr; |
58 | } |
59 | // this looks dirty - but this is the default behavior of raw pointers |
60 | T *get_mutable() const { |
61 | // CheckValid(); |
62 | return ptr; |
63 | } |
64 | |
65 | bool operator==(const optional_ptr<T> &rhs) const { |
66 | return ptr == rhs.ptr; |
67 | } |
68 | |
69 | bool operator!=(const optional_ptr<T> &rhs) const { |
70 | return ptr != rhs.ptr; |
71 | } |
72 | |
73 | private: |
74 | T *ptr; |
75 | }; |
76 | |
77 | } // namespace duckdb |
78 | |