OCILIB (C and C++ Driver for Oracle)  4.7.6
Open source and cross platform Oracle Driver delivering efficient access to Oracle databases.
HandleHolder.hpp
1 /*
2  * OCILIB - C Driver for Oracle (C Wrapper for Oracle OCI)
3  *
4  * Website: http://www.ocilib.net
5  *
6  * Copyright (c) 2007-2023 Vincent ROGIER <vince.rogier@ocilib.net>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  */
20 
21 #pragma once
22 
23 #include "ocilibcpp/core.hpp"
24 
25 // ReSharper disable CppClangTidyBugproneUnhandledSelfAssignment
26 
27 namespace ocilib
28 {
29  namespace core
30  {
31  template<class T>
32  HandleHolder<T>::HandleHolder() : _smartHandle(nullptr)
33  {
34  }
35 
36  template<class T>
37  HandleHolder<T>::HandleHolder(const HandleHolder& other) : _smartHandle(nullptr)
38  {
39  AcquireTransient(other, other._smartHandle ? other._smartHandle->GetParent() : nullptr);
40  }
41 
42  template<class T>
43  HandleHolder<T>::~HandleHolder() noexcept
44  {
45  SILENT_CATCH(Release())
46  }
47 
48  template<class T>
49  HandleHolder<T>& HandleHolder<T>::operator= (const HandleHolder<T>& other) noexcept
50  {
51  if (this != &other)
52  {
53  Handle* parent = other._smartHandle ? other._smartHandle->GetParent() : nullptr;
54  SILENT_CATCH(AcquireTransient(other, parent))
55  }
56  return *this;
57  }
58 
59  template<class T>
60  bool HandleHolder<T>::IsNull() const
61  {
62  return (static_cast<T>(*this) == 0);
63  }
64 
65  template<class T>
66  HandleHolder<T>::operator T()
67  {
68  return _smartHandle ? _smartHandle->GetHandle() : nullptr;
69  }
70 
71  template<class T>
72  HandleHolder<T>::operator T() const
73  {
74  return _smartHandle ? _smartHandle->GetHandle() : nullptr;
75  }
76 
77  template<class T>
78  HandleHolder<T>::operator bool()
79  {
80  return !IsNull();
81  }
82 
83  template<class T>
84  HandleHolder<T>::operator bool() const
85  {
86  return !IsNull();
87  }
88 
89  template<class T>
90  Handle* HandleHolder<T>::GetHandle() const
91  {
92  return static_cast<Handle*>(_smartHandle);
93  }
94 
95  template<class T>
96  void HandleHolder<T>::AcquireAllocated(T handle, Handle* parent)
97  {
98  Acquire(handle, true, nullptr, parent);
99  }
100 
101  template<class T>
102  void HandleHolder<T>::AcquireTransient(T handle, Handle* parent)
103  {
104  Acquire(handle, false, nullptr, parent);
105  }
106 
107  template<class T>
108  void HandleHolder<T>::AcquireAllocatedWithNotification(T handle, Handle* parent, SmartHandleFreeNotifyFunc freeNotifyFunc)
109  {
110  Acquire(handle, true, freeNotifyFunc, parent);
111  }
112 
113  template<class T>
114  void HandleHolder<T>::Acquire(T handle, bool allocated, SmartHandleFreeNotifyFunc freeNotifyFunc, Handle* parent)
115  {
116  if (_smartHandle && _smartHandle->GetHandle() == handle)
117  {
118  return;
119  }
120 
121  Release();
122 
123  if (handle)
124  {
125  _smartHandle = HandleStore::GetStoreForHandle(parent).Get<SmartHandle*>(handle);
126 
127  if (!_smartHandle)
128  {
129  _smartHandle = OnAllocate(new SmartHandle(this, handle, allocated, freeNotifyFunc, parent));
130  }
131  else
132  {
133  _smartHandle->Acquire(this);
134  }
135  }
136  }
137 
138  template<class T>
139  void HandleHolder<T>::Acquire(HandleHolder<T>& other)
140  {
141  if (&other != this && _smartHandle != other._smartHandle)
142  {
143  Release();
144 
145  if (other._smartHandle)
146  {
147  other._smartHandle->Acquire(this);
148  _smartHandle = other._smartHandle;
149  }
150  }
151  }
152 
153  template<class T>
154  void HandleHolder<T>::Release()
155  {
156  if (_smartHandle)
157  {
158  _smartHandle->Release(this);
159  }
160 
161  _smartHandle = nullptr;
162  }
163  }
164 }
OCILIB ++ Namespace.