log4cplus
2.0.0
|
00001 // -*- C++ -*- 00002 // Module: Log4CPLUS 00003 // File: pointer.h 00004 // Created: 6/2001 00005 // Author: Tad E. Smith 00006 // 00007 // 00008 // Copyright 2001-2015 Tad E. Smith 00009 // 00010 // Licensed under the Apache License, Version 2.0 (the "License"); 00011 // you may not use this file except in compliance with the License. 00012 // You may obtain a copy of the License at 00013 // 00014 // http://www.apache.org/licenses/LICENSE-2.0 00015 // 00016 // Unless required by applicable law or agreed to in writing, software 00017 // distributed under the License is distributed on an "AS IS" BASIS, 00018 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00019 // See the License for the specific language governing permissions and 00020 // limitations under the License. 00021 00022 // 00023 // Note: Some of this code uses ideas from "More Effective C++" by Scott 00024 // Myers, Addison Wesley Longmain, Inc., (c) 1996, Chapter 29, pp. 183-213 00025 // 00026 00029 #ifndef LOG4CPLUS_HELPERS_POINTERS_HEADER_ 00030 #define LOG4CPLUS_HELPERS_POINTERS_HEADER_ 00031 00032 #include <log4cplus/config.hxx> 00033 00034 #if defined (LOG4CPLUS_HAVE_PRAGMA_ONCE) 00035 #pragma once 00036 #endif 00037 00038 #include <log4cplus/thread/syncprims.h> 00039 #include <algorithm> 00040 #include <cassert> 00041 #if ! defined (LOG4CPLUS_SINGLE_THREADED) 00042 #include <atomic> 00043 #endif 00044 00045 00046 namespace log4cplus { 00047 namespace helpers { 00048 00049 /****************************************************************************** 00050 * Class SharedObject (from pp. 204-205) * 00051 ******************************************************************************/ 00052 00053 class LOG4CPLUS_EXPORT SharedObject 00054 { 00055 public: 00056 void addReference() const LOG4CPLUS_NOEXCEPT; 00057 void removeReference() const; 00058 00059 protected: 00060 // Ctor 00061 SharedObject() 00062 : access_mutex() 00063 , count__(0) 00064 { } 00065 00066 SharedObject(const SharedObject&) 00067 : access_mutex() 00068 , count__(0) 00069 { } 00070 00071 SharedObject(SharedObject &&) 00072 : access_mutex() 00073 , count__(0) 00074 { } 00075 00076 // Dtor 00077 virtual ~SharedObject(); 00078 00079 // Operators 00080 SharedObject& operator=(const SharedObject&) LOG4CPLUS_NOEXCEPT { return *this; } 00081 SharedObject& operator=(SharedObject &&) LOG4CPLUS_NOEXCEPT { return *this; } 00082 00083 public: 00084 thread::Mutex access_mutex; 00085 00086 private: 00087 #if defined (LOG4CPLUS_SINGLE_THREADED) 00088 typedef unsigned count_type; 00089 #else 00090 typedef std::atomic<unsigned> count_type; 00091 #endif 00092 mutable count_type count__; 00093 }; 00094 00095 00096 /****************************************************************************** 00097 * Template Class SharedObjectPtr (from pp. 203, 206) * 00098 ******************************************************************************/ 00099 template<class T> 00100 class SharedObjectPtr 00101 { 00102 public: 00103 // Ctor 00104 explicit 00105 SharedObjectPtr(T* realPtr = 0) LOG4CPLUS_NOEXCEPT 00106 : pointee(realPtr) 00107 { 00108 addref (); 00109 } 00110 00111 SharedObjectPtr(const SharedObjectPtr& rhs) LOG4CPLUS_NOEXCEPT 00112 : pointee(rhs.pointee) 00113 { 00114 addref (); 00115 } 00116 00117 SharedObjectPtr(SharedObjectPtr && rhs) LOG4CPLUS_NOEXCEPT 00118 : pointee (std::move (rhs.pointee)) 00119 { 00120 rhs.pointee = 0; 00121 } 00122 00123 SharedObjectPtr & operator = (SharedObjectPtr && rhs) LOG4CPLUS_NOEXCEPT 00124 { 00125 rhs.swap (*this); 00126 return *this; 00127 } 00128 00129 // Dtor 00130 ~SharedObjectPtr() 00131 { 00132 if (pointee) 00133 pointee->removeReference(); 00134 } 00135 00136 // Operators 00137 bool operator==(const SharedObjectPtr& rhs) const 00138 { return (pointee == rhs.pointee); } 00139 bool operator!=(const SharedObjectPtr& rhs) const 00140 { return (pointee != rhs.pointee); } 00141 bool operator==(const T* rhs) const { return (pointee == rhs); } 00142 bool operator!=(const T* rhs) const { return (pointee != rhs); } 00143 T* operator->() const {assert (pointee); return pointee; } 00144 T& operator*() const {assert (pointee); return *pointee; } 00145 00146 SharedObjectPtr& operator=(const SharedObjectPtr& rhs) 00147 { 00148 return this->operator = (rhs.pointee); 00149 } 00150 00151 SharedObjectPtr& operator=(T* rhs) 00152 { 00153 SharedObjectPtr<T> (rhs).swap (*this); 00154 return *this; 00155 } 00156 00157 // Methods 00158 T* get() const { return pointee; } 00159 00160 void swap (SharedObjectPtr & other) LOG4CPLUS_NOEXCEPT 00161 { 00162 std::swap (pointee, other.pointee); 00163 } 00164 00165 typedef T * (SharedObjectPtr:: * unspec_bool_type) () const; 00166 operator unspec_bool_type () const 00167 { 00168 return pointee ? &SharedObjectPtr::get : 0; 00169 } 00170 00171 bool operator ! () const 00172 { 00173 return ! pointee; 00174 } 00175 00176 private: 00177 // Methods 00178 void addref() const LOG4CPLUS_NOEXCEPT 00179 { 00180 if (pointee) 00181 pointee->addReference(); 00182 } 00183 00184 // Data 00185 T* pointee; 00186 }; 00187 00188 00191 inline 00192 void 00193 intrusive_ptr_add_ref (SharedObject const * so) 00194 { 00195 so->addReference(); 00196 } 00197 00198 inline 00199 void 00200 intrusive_ptr_release (SharedObject const * so) 00201 { 00202 so->removeReference(); 00203 } 00205 00206 } // end namespace helpers 00207 } // end namespace log4cplus 00208 00209 00210 #endif // LOG4CPLUS_HELPERS_POINTERS_HEADER_