Main Page   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   Related Pages  

private.h

00001 //
00002 // OpenVRML
00003 //
00004 // Copyright (C) 2001  Braden McDaniel
00005 // 
00006 // This library is free software; you can redistribute it and/or
00007 // modify it under the terms of the GNU Lesser General Public
00008 // License as published by the Free Software Foundation; either
00009 // version 2.1 of the License, or (at your option) any later version.
00010 // 
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 // Lesser General Public License for more details.
00015 // 
00016 // You should have received a copy of the GNU Lesser General Public
00017 // License along with this library; if not, write to the Free Software
00018 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019 // 
00020 
00021 # ifndef OPENVRML_PRIVATE_H
00022 #   define OPENVRML_PRIVATE_H
00023 
00024 #   ifndef NDEBUG
00025 #     include <iostream>
00026 #   endif
00027 
00028 #   ifdef NDEBUG
00029 #     define OPENVRML_VERIFY_(condition_)
00030 #   else
00031 #     define OPENVRML_VERIFY_(condition_) \
00032             do { \
00033                 if (!(condition_)) { \
00034                     std::cerr << __FILE__ << ":" << __LINE__ \
00035                               << ": verification (" #condition_ ") failed" \
00036                               << std::endl; \
00037                 } \
00038             } while (false)
00039 #   endif
00040 
00041 #   ifdef NDEBUG
00042 #     define OPENVRML_PRINT_EXCEPTION_(ex_)
00043 #   else
00044 #     define OPENVRML_PRINT_EXCEPTION_(ex_) \
00045             std::cerr << __FILE__ << ":" << __LINE__ << ": " \
00046                       << ex_.what() << std::endl
00047 #   endif
00048 
00049 #   ifdef NDEBUG
00050 #     define OPENVRML_PRINT_MESSAGE_(message_)
00051 #   else
00052 #     define OPENVRML_PRINT_MESSAGE_(message_) \
00053             std::cerr << __FILE__ << ":" << __LINE__ << ": " \
00054                       << message_ << std::endl
00055 #   endif
00056             
00057 #   include <assert.h>
00058 #   include <math.h>
00059 #   include <stddef.h>
00060 
00061 namespace {
00062     namespace OpenVRML_ {
00063         
00064         const float fptolerance = 1.0e-6;
00065 
00066         inline bool fpzero(const float f) { return (fabs(f) <= fptolerance); }
00067 
00068         inline bool fpequal(const float a, const float b) {
00069             return fpzero(a - b);
00070         }
00071 
00072         inline double length(const float vec[3]) {
00073             return sqrt(vec[0] * vec[0] + vec[1] * vec[1] + vec[2] * vec[2]);
00074         }
00075 
00076         inline void normalize(float vec[3]) {
00077             const float len = float(length(vec));
00078             if (!fpzero(len)) {
00079                 vec[0] /= len;
00080                 vec[1] /= len;
00081                 vec[2] /= len;
00082             }
00083         }
00084         
00085         
00086         template <typename T>
00087             class SharedPtr {
00088                 T * data;
00089                 size_t * count;
00090 
00091             public:
00092                 explicit SharedPtr(T * data = 0);
00093                 SharedPtr(const SharedPtr<T> & sharedPtr);
00094                 ~SharedPtr();
00095 
00096                 SharedPtr<T> & operator=(const SharedPtr<T> & sharedPtr);
00097 
00098                 T & operator*() const;
00099                 T * operator->() const;
00100                 T * get() const;
00101 
00102                 void reset(T * data = 0);
00103 
00104             private:
00105                 void dispose();
00106                 void share(T * data, size_t * count);
00107             };
00108 
00109         template <typename T>
00110             SharedPtr<T>::SharedPtr(T * data): data(data) {
00111                 try {
00112                     this->count = new size_t(1);
00113                 } catch (...) {
00114                     delete data;
00115                     throw;
00116                 }
00117             }
00118 
00119         template <typename T>
00120             SharedPtr<T>::SharedPtr(const SharedPtr<T> & sharedPtr):
00121                     data(sharedPtr.data) {
00122                 ++*(this->count = sharedPtr.count);
00123             }
00124 
00125         template <typename T>
00126             SharedPtr<T>::~SharedPtr() { this->dispose(); }
00127         
00128         template <typename T>
00129             SharedPtr<T> &
00130                     SharedPtr<T>::operator=(const SharedPtr<T> & sharedPtr) {
00131                 this->share(sharedPtr.data, sharedPtr.count);
00132                 return *this;
00133             }
00134 
00135         template <typename T>
00136             T & SharedPtr<T>::operator*() const { return *this->data; }
00137 
00138         template <typename T>
00139             T * SharedPtr<T>::operator->() const { return this->data; }
00140 
00141         template <typename T>
00142             T * SharedPtr<T>::get() const { return this->data; }
00143 
00144         template <typename T>
00145             void SharedPtr<T>::reset(T * data) {
00146                 assert(data != this->data); // fail on self-assignment
00147                 if (--*this->count == 0) {
00148                     delete this->data;
00149                 } else {
00150                     try {
00151                         this->data = new size_t;
00152                     } catch (...) {
00153                         ++*this->count;
00154                         delete data;
00155                         throw;
00156                     }
00157                 }
00158                 *this->count = 1;
00159                 this->data = data;
00160             }
00161         
00162         template <typename T>
00163             void SharedPtr<T>::dispose() {
00164                 if (--*this->count == 0) {
00165                     delete this->data;
00166                     delete this->count;
00167                 }
00168             }
00169         
00170         template <typename T>
00171             void SharedPtr<T>::share(T * data, size_t * count) {
00172                 if (this->count != count) {
00173                     ++*count;
00174                     this->dispose();
00175                     this->data = data;
00176                     this->count = count;
00177                 }
00178             }
00179         
00180         template <typename T, typename U>
00181             inline bool operator==(const SharedPtr<T> & a,
00182                                    const SharedPtr<U> & b) {
00183                 return a.get() == b.get();
00184             }
00185     }
00186 }
00187 
00188 # endif