00001 /******************************************************************************* 00002 * Copyright (C) 2004 Vintela, Inc. All rights reserved. 00003 * Copyright (C) 2005 Novell, Inc. All rights reserved. 00004 * 00005 * Redistribution and use in source and binary forms, with or without 00006 * modification, are permitted provided that the following conditions are met: 00007 * 00008 * - Redistributions of source code must retain the above copyright notice, 00009 * this list of conditions and the following disclaimer. 00010 * 00011 * - Redistributions in binary form must reproduce the above copyright notice, 00012 * this list of conditions and the following disclaimer in the documentation 00013 * and/or other materials provided with the distribution. 00014 * 00015 * - Neither the name of Vintela, Inc., Novell, Inc., nor the names of its 00016 * contributors may be used to endorse or promote products derived from this 00017 * software without specific prior written permission. 00018 * 00019 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' 00020 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00021 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00022 * ARE DISCLAIMED. IN NO EVENT SHALL Vintela, Inc., Novell, Inc., OR THE 00023 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 00024 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00025 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 00026 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 00027 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 00028 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 00029 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00030 *******************************************************************************/ 00031 00032 00037 #ifndef BLOCXX_SHARED_LIBRARY_REFERENCE_HPP_ 00038 #define BLOCXX_SHARED_LIBRARY_REFERENCE_HPP_ 00039 #include "blocxx/BLOCXX_config.h" 00040 #include "blocxx/SharedLibrary.hpp" 00041 00042 namespace BLOCXX_NAMESPACE 00043 { 00044 00045 template <class T> 00046 class SharedLibraryReference 00047 { 00048 public: 00049 typedef T element_type; 00050 00051 SharedLibraryReference(const SharedLibraryRef& lib, const T& obj) 00052 : m_sharedLib(lib), m_obj(obj) 00053 {} 00054 SharedLibraryReference(const SharedLibraryRef& lib, typename T::element_type* obj) 00055 : m_sharedLib(lib), m_obj(T(obj)) 00056 {} 00057 SharedLibraryReference(const SharedLibraryReference<T>& arg) 00058 : m_sharedLib(arg.m_sharedLib), m_obj(arg.m_obj) 00059 { 00060 } 00061 /* construct out of a reference to a derived type. U should be 00062 derived from T */ 00063 template <class U> 00064 SharedLibraryReference(const SharedLibraryReference<U>& arg) 00065 : m_sharedLib(arg.m_sharedLib), m_obj(arg.m_obj) 00066 { 00067 } 00068 SharedLibraryReference() 00069 : m_sharedLib(), m_obj() 00070 {} 00071 SharedLibraryReference<T>& operator=(const SharedLibraryReference<T>& arg) 00072 { 00073 m_obj = arg.m_obj; 00074 m_sharedLib = arg.m_sharedLib; 00075 return *this; 00076 } 00077 ~SharedLibraryReference() 00078 { 00079 try 00080 { 00081 m_obj = 0; 00082 m_sharedLib = 0; 00083 } 00084 catch (...) 00085 { 00086 // don't let exceptions escape 00087 } 00088 } 00089 SharedLibraryRef getLibRef() const 00090 { 00091 return m_sharedLib; 00092 } 00093 typename T::element_type* operator->() const 00094 { 00095 return &*m_obj; 00096 } 00097 T get() const 00098 { 00099 return m_obj; 00100 } 00101 00102 typedef T SharedLibraryReference::*safe_bool; 00103 operator safe_bool () const 00104 { return (m_obj) ? &SharedLibraryReference::m_obj : 0; } 00105 bool operator!() const 00106 { return !m_obj; } 00107 void setNull() 00108 { 00109 m_obj = 0; 00110 m_sharedLib = 0; 00111 } 00112 00113 template <class U> 00114 SharedLibraryReference<U> cast_to() const 00115 { 00116 SharedLibraryReference<U> rval; 00117 rval.m_sharedLib = m_sharedLib; 00118 rval.m_obj = m_obj.cast_to<U>(); 00119 return rval; 00120 } 00121 00122 #if !defined(__GNUC__) || __GNUC__ > 2 // causes gcc 2.95 to ICE 00123 /* This is so cast_to will work */ 00124 template <class U> friend class SharedLibraryReference; 00125 00126 private: 00127 #endif 00128 00129 SharedLibraryRef m_sharedLib; 00130 T m_obj; 00131 }; 00132 00133 } // end namespace BLOCXX_NAMESPACE 00134 00135 #endif