So-Bogus
A c++ sparse block matrix library aimed at Second Order cone problems
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Pages
NaiveSharedPtr.hpp
1 /*
2  * This file is part of bogus, a C++ sparse block matrix library.
3  *
4  * Copyright 2013 Gilles Daviet <gdaviet@gmail.com>
5  *
6  * This Source Code Form is subject to the terms of the Mozilla Public
7  * License, v. 2.0. If a copy of the MPL was not distributed with this
8  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 */
10 
11 #include "CppTools.hpp"
12 
13 #if BOGUS_HAS_CPP11 && !defined(BOGUS_SHARED_PTR_NS)
14 #define BOGUS_SHARED_PTR_NS std
15 #endif
16 
17 // Standard shared_ptr -- BOGUS_SHARED_PTR_NS should be set to std, std::tr1 or boost
18 #ifdef BOGUS_SHARED_PTR_NS
19 #ifndef BOGUS_SHARED_PTR
20 #include <memory>
21 #define BOGUS_SHARED_PTR( Type, Name ) BOGUS_SHARED_PTR_NS::shared_ptr< Type > Name
22 #endif
23 #endif
24 
25 #ifndef BOGUS_NAIVE_SHARED_PTR_HPP
26 #define BOGUS_NAIVE_SHARED_PTR_HPP
27 
28 #ifndef BOGUS_SHARED_PTR
29 #define BOGUS_SHARED_PTR( Type, Name ) NaiveSharedPtr< Type > Name
30 #endif
31 
32 #if defined( _MSC_VER ) && !defined( BOGUS_DONT_USE_BUILTIN_ATOMICS )
33  #define BOGUS_DONT_USE_BUILTIN_ATOMICS
34 #endif
35 
36 namespace bogus {
37 
39 
46 template < typename T >
48 {
49 private:
50 
51  T* m_instance ;
52  int* m_refCount ;
53 
54 public:
55 
56  explicit NaiveSharedPtr( T * instance = BOGUS_NULL_PTR(T) )
57  {
58  acquire( instance ) ;
59  }
60 
62  {
63  add_ref( rhs ) ;
64  }
65 
66  const NaiveSharedPtr& operator=( const NaiveSharedPtr< T >& rhs )
67  {
68  if( this != &rhs )
69  {
70  release() ;
71  add_ref( rhs ) ;
72  }
73  return *this ;
74  }
75 
77  {
78  release() ;
79  }
80 
81  void reset( T * instance = BOGUS_NULL_PTR(T) )
82  {
83  release() ;
84  acquire( instance ) ;
85  }
86 
87  void release()
88  {
89  T* instance = BOGUS_NULL_PTR(T) ;
90  std::swap( m_instance, instance ) ;
91 
92 
93  if( instance && 0 == sync_add< -1 > () )
94  {
95  delete instance ;
96  delete m_refCount ;
97  }
98  }
99 
100  T& operator * ( ) {
101  return *m_instance;
102  }
103  T const& operator * ( ) const {
104  return *m_instance;
105  }
106  T* operator -> ( ) {
107  return m_instance;
108  }
109  T const* operator -> ( ) const {
110  return m_instance;
111  }
112  T* get() {
113  return m_instance ;
114  }
115  const T* get() const {
116  return m_instance ;
117  }
118 
119  operator bool() const {
120  return BOGUS_NULL_PTR(T) != m_instance ;
121  }
122 
123 private:
124 
125  T* add_ref() const
126  {
127  T* instance = m_instance ;
128 
129  if( instance && sync_add< 1 >() <= 1 )
130  {
131  // Here m_refCount may already been deleted if another thread is simultaneously releasing
132  // this object. We hope that the memory location is still accessible and check for destruction
133  // But as I said previously, this class is *NOT* thread-safe
134  instance = BOGUS_NULL_PTR(T) ;
135  }
136 
137  return instance ;
138  }
139 
140  void add_ref( const NaiveSharedPtr< T >& rhs )
141  {
142  m_refCount = rhs.m_refCount ;
143  m_instance = rhs.add_ref() ;
144  }
145 
146  void acquire( T* instance )
147  {
148  if( instance ) {
149  m_refCount = new int ;
150  *m_refCount = 1 ;
151  }
152  m_instance = instance ;
153  }
154 
155 
156  template< int val >
157  inline int sync_add() const
158  {
159 
160 #ifndef BOGUS_DONT_USE_BUILTIN_ATOMICS
161  return __sync_add_and_fetch( m_refCount, val );
162 #else
163  int t;
164 
165 #ifdef OPENMP_3_1
166 #pragma omp atomic capture
167 #else
168 #ifndef BOGUS_DONT_PARALLELIZE
169 #pragma omp critical (BogusNaiveSharedPtr)
170 #endif
171 #endif
172  { *m_refCount += val ; t = *m_refCount ; }
173  return t;
174 #endif
175  }
176 
177 } ;
178 
179 } //naemspace bogus
180 
181 #endif
Naive reference-counting Shared Pointer.
Definition: NaiveSharedPtr.hpp:47