OCILIB (C and C++ Driver for Oracle)  4.7.3
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-2021 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  Acquire(other, nullptr, nullptr, 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(Acquire(other, nullptr, nullptr, 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>::Acquire(T handle, HandleFreeFunc handleFreefunc, SmartHandleFreeNotifyFunc freeNotifyFunc, Handle* parent)
97  {
98  if (_smartHandle && _smartHandle->GetHandle() == handle)
99  {
100  return;
101  }
102 
103  Release();
104 
105  if (handle)
106  {
107  _smartHandle = Environment::GetSmartHandle<SmartHandle*>(handle);
108 
109  if (!_smartHandle)
110  {
111  _smartHandle = OnAllocate(new SmartHandle(this, handle, handleFreefunc, freeNotifyFunc, parent));
112  }
113  else
114  {
115  _smartHandle->Acquire(this);
116  }
117  }
118  }
119 
120  template<class T>
121  void HandleHolder<T>::Acquire(HandleHolder<T>& other)
122  {
123  if (&other != this && _smartHandle != other._smartHandle)
124  {
125  Release();
126 
127  if (other._smartHandle)
128  {
129  other._smartHandle->Acquire(this);
130  _smartHandle = other._smartHandle;
131  }
132  }
133  }
134 
135  template<class T>
136  void HandleHolder<T>::Release()
137  {
138  if (_smartHandle)
139  {
140  _smartHandle->Release(this);
141  }
142 
143  _smartHandle = nullptr;
144  }
145  }
146 }
OCILIB ++ Namespace.