You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							191 lines
						
					
					
						
							5.3 KiB
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							191 lines
						
					
					
						
							5.3 KiB
						
					
					
				
								// -*- C++ -*-
							 | 
						|
								// Module:  Log4CPLUS
							 | 
						|
								// File:    pointer.h
							 | 
						|
								// Created: 6/2001
							 | 
						|
								// Author:  Tad E. Smith
							 | 
						|
								//
							 | 
						|
								//
							 | 
						|
								// Copyright 2001-2010 Tad E. Smith
							 | 
						|
								//
							 | 
						|
								// Licensed under the Apache License, Version 2.0 (the "License");
							 | 
						|
								// you may not use this file except in compliance with the License.
							 | 
						|
								// You may obtain a copy of the License at
							 | 
						|
								//
							 | 
						|
								//     http://www.apache.org/licenses/LICENSE-2.0
							 | 
						|
								//
							 | 
						|
								// Unless required by applicable law or agreed to in writing, software
							 | 
						|
								// distributed under the License is distributed on an "AS IS" BASIS,
							 | 
						|
								// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
							 | 
						|
								// See the License for the specific language governing permissions and
							 | 
						|
								// limitations under the License.
							 | 
						|
								
							 | 
						|
								//
							 | 
						|
								// Note: Some of this code uses ideas from "More Effective C++" by Scott
							 | 
						|
								// Myers, Addison Wesley Longmain, Inc., (c) 1996, Chapter 29, pp. 183-213
							 | 
						|
								//
							 | 
						|
								
							 | 
						|
								/** @file */
							 | 
						|
								
							 | 
						|
								#ifndef LOG4CPLUS_HELPERS_POINTERS_HEADER_
							 | 
						|
								#define LOG4CPLUS_HELPERS_POINTERS_HEADER_
							 | 
						|
								
							 | 
						|
								#include <log4cplus/config.hxx>
							 | 
						|
								
							 | 
						|
								#if defined (LOG4CPLUS_HAVE_PRAGMA_ONCE)
							 | 
						|
								#pragma once
							 | 
						|
								#endif
							 | 
						|
								
							 | 
						|
								#include <log4cplus/thread/syncprims.h>
							 | 
						|
								#include <algorithm>
							 | 
						|
								#include <cassert>
							 | 
						|
								#if ! defined (LOG4CPLUS_SINGLE_THREADED) \
							 | 
						|
								    && defined (LOG4CPLUS_HAVE_CXX11_ATOMICS)
							 | 
						|
								#include <atomic>
							 | 
						|
								#endif
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								namespace log4cplus {
							 | 
						|
								    namespace helpers {
							 | 
						|
								
							 | 
						|
								        /******************************************************************************
							 | 
						|
								         *                       Class SharedObject (from pp. 204-205)                *
							 | 
						|
								         ******************************************************************************/
							 | 
						|
								
							 | 
						|
								        class LOG4CPLUS_EXPORT SharedObject
							 | 
						|
								        {
							 | 
						|
								        public:
							 | 
						|
								            void addReference() const;
							 | 
						|
								            void removeReference() const;
							 | 
						|
								
							 | 
						|
								        protected:
							 | 
						|
								          // Ctor
							 | 
						|
								            SharedObject()
							 | 
						|
								                : access_mutex()
							 | 
						|
								                , count(0)
							 | 
						|
								            { }
							 | 
						|
								
							 | 
						|
								            SharedObject(const SharedObject&)
							 | 
						|
								                : access_mutex()
							 | 
						|
								                , count(0)
							 | 
						|
								            { }
							 | 
						|
								
							 | 
						|
								          // Dtor
							 | 
						|
								            virtual ~SharedObject();
							 | 
						|
								
							 | 
						|
								          // Operators
							 | 
						|
								            SharedObject& operator=(const SharedObject&) { return *this; }
							 | 
						|
								
							 | 
						|
								        public:
							 | 
						|
								            thread::Mutex access_mutex;
							 | 
						|
								
							 | 
						|
								        private:
							 | 
						|
								#if defined (LOG4CPLUS_SINGLE_THREADED)
							 | 
						|
								            typedef unsigned count_type;
							 | 
						|
								#elif defined (LOG4CPLUS_HAVE_CXX11_ATOMICS)
							 | 
						|
								            typedef std::atomic<unsigned> count_type;
							 | 
						|
								#elif defined (_WIN32) || defined (__CYGWIN__)
							 | 
						|
								            typedef long count_type;
							 | 
						|
								#else
							 | 
						|
								            typedef unsigned count_type;
							 | 
						|
								#endif
							 | 
						|
								            mutable count_type count;
							 | 
						|
								        };
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								        /******************************************************************************
							 | 
						|
								         *           Template Class SharedObjectPtr (from pp. 203, 206)               *
							 | 
						|
								         ******************************************************************************/
							 | 
						|
								        template<class T>
							 | 
						|
								        class SharedObjectPtr
							 | 
						|
								        {
							 | 
						|
								        public:
							 | 
						|
								            // Ctor
							 | 
						|
								            explicit
							 | 
						|
								            SharedObjectPtr(T* realPtr = 0)
							 | 
						|
								                : pointee(realPtr)
							 | 
						|
								            {
							 | 
						|
								                addref ();
							 | 
						|
								            }
							 | 
						|
								
							 | 
						|
								            SharedObjectPtr(const SharedObjectPtr& rhs)
							 | 
						|
								                : pointee(rhs.pointee)
							 | 
						|
								            {
							 | 
						|
								                addref ();
							 | 
						|
								            }
							 | 
						|
								
							 | 
						|
								#if defined (LOG4CPLUS_HAVE_RVALUE_REFS)
							 | 
						|
								            SharedObjectPtr(SharedObjectPtr && rhs)
							 | 
						|
								                : pointee (std::move (rhs.pointee))
							 | 
						|
								            {
							 | 
						|
								                rhs.pointee = 0;
							 | 
						|
								            }
							 | 
						|
								
							 | 
						|
								            SharedObjectPtr & operator = (SharedObjectPtr && rhs)
							 | 
						|
								            {
							 | 
						|
								                rhs.swap (*this);
							 | 
						|
								                return *this;
							 | 
						|
								            }
							 | 
						|
								#endif
							 | 
						|
								
							 | 
						|
								            // Dtor
							 | 
						|
								            ~SharedObjectPtr()
							 | 
						|
								            {
							 | 
						|
								                if (pointee)
							 | 
						|
								                    pointee->removeReference();
							 | 
						|
								            }
							 | 
						|
								
							 | 
						|
								            // Operators
							 | 
						|
								            bool operator==(const SharedObjectPtr& rhs) const { return (pointee == rhs.pointee); }
							 | 
						|
								            bool operator!=(const SharedObjectPtr& rhs) const { return (pointee != rhs.pointee); }
							 | 
						|
								            bool operator==(const T* rhs) const { return (pointee == rhs); }
							 | 
						|
								            bool operator!=(const T* rhs) const { return (pointee != rhs); }
							 | 
						|
								            T* operator->() const {assert (pointee); return pointee; }
							 | 
						|
								            T& operator*() const {assert (pointee); return *pointee; }
							 | 
						|
								
							 | 
						|
								            SharedObjectPtr& operator=(const SharedObjectPtr& rhs)
							 | 
						|
								            {
							 | 
						|
								                return this->operator = (rhs.pointee);
							 | 
						|
								            }
							 | 
						|
								
							 | 
						|
								            SharedObjectPtr& operator=(T* rhs)
							 | 
						|
								            {
							 | 
						|
								                SharedObjectPtr<T> (rhs).swap (*this);
							 | 
						|
								                return *this;
							 | 
						|
								            }
							 | 
						|
								
							 | 
						|
								          // Methods
							 | 
						|
								            T* get() const { return pointee; }
							 | 
						|
								
							 | 
						|
								            void swap (SharedObjectPtr & other) throw ()
							 | 
						|
								            {
							 | 
						|
								                std::swap (pointee, other.pointee);
							 | 
						|
								            }
							 | 
						|
								
							 | 
						|
								            typedef T * (SharedObjectPtr:: * unspec_bool_type) () const;
							 | 
						|
								            operator unspec_bool_type () const
							 | 
						|
								            {
							 | 
						|
								                return pointee ? &SharedObjectPtr::get : 0;
							 | 
						|
								            }
							 | 
						|
								
							 | 
						|
								            bool operator ! () const
							 | 
						|
								            {
							 | 
						|
								                return ! pointee;
							 | 
						|
								            }
							 | 
						|
								
							 | 
						|
								        private:
							 | 
						|
								          // Methods
							 | 
						|
								            void addref() const
							 | 
						|
								            {
							 | 
						|
								                if (pointee)
							 | 
						|
								                    pointee->addReference();
							 | 
						|
								            }
							 | 
						|
								
							 | 
						|
								          // Data
							 | 
						|
								            T* pointee;
							 | 
						|
								        };
							 | 
						|
								
							 | 
						|
								    } // end namespace helpers
							 | 
						|
								} // end namespace log4cplus
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								#endif // LOG4CPLUS_HELPERS_POINTERS_HEADER_
							 |