1 | #pragma once |
2 | |
3 | #include <torch/csrc/python_headers.h> |
4 | |
5 | template <class T> |
6 | class THPPointer { |
7 | public: |
8 | THPPointer() : ptr(nullptr){}; |
9 | explicit THPPointer(T* ptr) noexcept : ptr(ptr){}; |
10 | THPPointer(THPPointer&& p) noexcept { |
11 | free(); |
12 | ptr = p.ptr; |
13 | p.ptr = nullptr; |
14 | }; |
15 | |
16 | ~THPPointer() { |
17 | free(); |
18 | }; |
19 | T* get() { |
20 | return ptr; |
21 | } |
22 | const T* get() const { |
23 | return ptr; |
24 | } |
25 | T* release() { |
26 | T* tmp = ptr; |
27 | ptr = nullptr; |
28 | return tmp; |
29 | } |
30 | operator T*() { |
31 | return ptr; |
32 | } |
33 | THPPointer& operator=(T* new_ptr) noexcept { |
34 | free(); |
35 | ptr = new_ptr; |
36 | return *this; |
37 | } |
38 | THPPointer& operator=(THPPointer&& p) noexcept { |
39 | free(); |
40 | ptr = p.ptr; |
41 | p.ptr = nullptr; |
42 | return *this; |
43 | } |
44 | T* operator->() { |
45 | return ptr; |
46 | } |
47 | explicit operator bool() const { |
48 | return ptr != nullptr; |
49 | } |
50 | |
51 | private: |
52 | void free(); |
53 | T* ptr = nullptr; |
54 | }; |
55 | |
56 | /** |
57 | * An RAII-style, owning pointer to a PyObject. You must protect |
58 | * destruction of this object with the GIL. |
59 | * |
60 | * WARNING: Think twice before putting this as a field in a C++ |
61 | * struct. This class does NOT take out the GIL on destruction, |
62 | * so if you will need to ensure that the destructor of your struct |
63 | * is either (a) always invoked when the GIL is taken or (b) takes |
64 | * out the GIL itself. Easiest way to avoid this problem is to |
65 | * not use THPPointer in this situation. |
66 | */ |
67 | using THPObjectPtr = THPPointer<PyObject>; |
68 | using THPCodeObjectPtr = THPPointer<PyCodeObject>; |
69 | using THPFrameObjectPtr = THPPointer<PyFrameObject>; |
70 | |