log4cplus
1.1.0
|
00001 // -*- C++ -*- 00002 // Module: Log4CPLUS 00003 // File: pointer.h 00004 // Created: 6/2001 00005 // Author: Tad E. Smith 00006 // 00007 // 00008 // Copyright 2001-2010 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 && defined (LOG4CPLUS_HAVE_CXX11_ATOMICS) 00043 #include <atomic> 00044 #endif 00045 00046 00047 namespace log4cplus { 00048 namespace helpers { 00049 00050 /****************************************************************************** 00051 * Class SharedObject (from pp. 204-205) * 00052 ******************************************************************************/ 00053 00054 class LOG4CPLUS_EXPORT SharedObject 00055 { 00056 public: 00057 void addReference() const; 00058 void removeReference() const; 00059 00060 protected: 00061 // Ctor 00062 SharedObject() 00063 : access_mutex() 00064 , count(0) 00065 { } 00066 00067 SharedObject(const SharedObject&) 00068 : access_mutex() 00069 , count(0) 00070 { } 00071 00072 // Dtor 00073 virtual ~SharedObject(); 00074 00075 // Operators 00076 SharedObject& operator=(const SharedObject&) { return *this; } 00077 00078 public: 00079 thread::Mutex access_mutex; 00080 00081 private: 00082 #if defined (LOG4CPLUS_SINGLE_THREADED) 00083 typedef unsigned count_type; 00084 #elif defined (LOG4CPLUS_HAVE_CXX11_ATOMICS) 00085 typedef std::atomic<unsigned> count_type; 00086 #elif defined (_WIN32) || defined (__CYGWIN__) 00087 typedef long count_type; 00088 #else 00089 typedef unsigned count_type; 00090 #endif 00091 mutable count_type count; 00092 }; 00093 00094 00095 /****************************************************************************** 00096 * Template Class SharedObjectPtr (from pp. 203, 206) * 00097 ******************************************************************************/ 00098 template<class T> 00099 class SharedObjectPtr 00100 { 00101 public: 00102 // Ctor 00103 explicit 00104 SharedObjectPtr(T* realPtr = 0) 00105 : pointee(realPtr) 00106 { 00107 addref (); 00108 } 00109 00110 SharedObjectPtr(const SharedObjectPtr& rhs) 00111 : pointee(rhs.pointee) 00112 { 00113 addref (); 00114 } 00115 00116 #if defined (LOG4CPLUS_HAVE_RVALUE_REFS) 00117 SharedObjectPtr(SharedObjectPtr && rhs) 00118 : pointee (std::move (rhs.pointee)) 00119 { 00120 rhs.pointee = 0; 00121 } 00122 00123 SharedObjectPtr & operator = (SharedObjectPtr && rhs) 00124 { 00125 rhs.swap (*this); 00126 return *this; 00127 } 00128 #endif 00129 00130 // Dtor 00131 ~SharedObjectPtr() 00132 { 00133 if (pointee) 00134 pointee->removeReference(); 00135 } 00136 00137 // Operators 00138 bool operator==(const SharedObjectPtr& rhs) const { return (pointee == rhs.pointee); } 00139 bool operator!=(const SharedObjectPtr& rhs) const { return (pointee != rhs.pointee); } 00140 bool operator==(const T* rhs) const { return (pointee == rhs); } 00141 bool operator!=(const T* rhs) const { return (pointee != rhs); } 00142 T* operator->() const {assert (pointee); return pointee; } 00143 T& operator*() const {assert (pointee); return *pointee; } 00144 00145 SharedObjectPtr& operator=(const SharedObjectPtr& rhs) 00146 { 00147 return this->operator = (rhs.pointee); 00148 } 00149 00150 SharedObjectPtr& operator=(T* rhs) 00151 { 00152 SharedObjectPtr<T> (rhs).swap (*this); 00153 return *this; 00154 } 00155 00156 // Methods 00157 T* get() const { return pointee; } 00158 00159 void swap (SharedObjectPtr & other) throw () 00160 { 00161 std::swap (pointee, other.pointee); 00162 } 00163 00164 typedef T * (SharedObjectPtr:: * unspec_bool_type) () const; 00165 operator unspec_bool_type () const 00166 { 00167 return pointee ? &SharedObjectPtr::get : 0; 00168 } 00169 00170 bool operator ! () const 00171 { 00172 return ! pointee; 00173 } 00174 00175 private: 00176 // Methods 00177 void addref() const 00178 { 00179 if (pointee) 00180 pointee->addReference(); 00181 } 00182 00183 // Data 00184 T* pointee; 00185 }; 00186 00187 } // end namespace helpers 00188 } // end namespace log4cplus 00189 00190 00191 #endif // LOG4CPLUS_HELPERS_POINTERS_HEADER_