1 /*========================== begin_copyright_notice ============================
2 
3 Copyright (C) 2017-2021 Intel Corporation
4 
5 SPDX-License-Identifier: MIT
6 
7 ============================= end_copyright_notice ===========================*/
8 
9 /*========================== begin_copyright_notice ============================
10 
11 This file is distributed under the University of Illinois Open Source License.
12 See LICENSE.TXT for details.
13 
14 ============================= end_copyright_notice ===========================*/
15 
16 #ifndef __REF_COUNT_H__
17 #define __REF_COUNT_H__
18 
19 #include "Probe/Assertion.h"
20 
21 namespace igc_SPIR {
22 
23 template <typename T>
24 class RefCount{
25 public:
RefCount()26   RefCount(): m_refCount(0), m_ptr(0) {
27   }
28 
RefCount(T * ptr)29   RefCount(T* ptr): m_ptr(ptr) {
30     m_refCount = new int(1);
31   }
32 
RefCount(const RefCount<T> & other)33   RefCount(const RefCount<T>& other) {
34     cpy(other);
35   }
36 
~RefCount()37   ~RefCount() {
38     if (m_refCount)
39       dispose();
40   }
41 
42   RefCount& operator=(const RefCount<T>& other) {
43     if(this == &other)
44       return *this;
45     if (m_refCount)
46       dispose();
47     cpy(other);
48     return *this;
49   }
50 
init(T * ptr)51   void init(T* ptr) {
52     IGC_ASSERT_MESSAGE(!m_ptr, "overrunning non NULL pointer");
53     IGC_ASSERT_MESSAGE(!m_refCount, "overrunning non NULL pointer");
54     m_refCount = new int(1);
55     m_ptr = ptr;
56   }
57 
isNull()58   bool isNull() const {
59     return (!m_ptr);
60   }
61 
62 // Pointer access
63   const T& operator*() const{
64     sanity();
65     return *m_ptr;
66   }
67 
68   T& operator*() {
69     sanity();
70     return *m_ptr;
71   }
72 
73   operator T*() {
74     return m_ptr;
75   }
76 
77   operator const T*() const{
78     return m_ptr;
79   }
80 
81   T* operator->() {
82     return m_ptr;
83   }
84 
85   const T* operator->() const{
86     return m_ptr;
87   }
88 private:
sanity()89   void sanity() const{
90     IGC_ASSERT_MESSAGE(m_ptr, "NULL pointer");
91     IGC_ASSERT_MESSAGE(m_refCount, "NULL ref counter");
92     IGC_ASSERT_MESSAGE(*m_refCount, "zero ref counter");
93   }
94 
cpy(const RefCount<T> & other)95   void cpy(const RefCount<T>& other) {
96     m_refCount = other.m_refCount;
97     m_ptr = other.m_ptr;
98     if (m_refCount) ++*m_refCount;
99   }
100 
dispose()101   void dispose() {
102     sanity();
103     if (0 == --*m_refCount) {
104       delete m_refCount;
105       delete m_ptr;
106       m_ptr = 0;
107       m_refCount = 0;
108     }
109   }
110 
111   int* m_refCount;
112   T* m_ptr;
113 };// End RefCount
114 
115 } // End SPIR namespace
116 
117 #endif//__REF_COUNT_H__
118