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

more/gen/utility.h

Go to the documentation of this file.
00001 //  more/utility.h -- various utilities
00002 //  Copyright (C) 1998--2002  Petter Urkedal
00003 
00004 //  This file is free software; you can redistribute it and/or modify
00005 //  it under the terms of the GNU General Public License as published by
00006 //  the Free Software Foundation; either version 2 of the License, or
00007 //  (at your option) any later version.
00008 
00009 //  This file is distributed in the hope that it will be useful,
00010 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 //  GNU General Public License for more details.
00013 
00014 //  You should have received a copy of the GNU General Public License
00015 //  along with this program; if not, write to the Free Software
00016 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00017 
00018 //  As a special exception, you may use this file as part of a free
00019 //  software library without restriction.  Specifically, if other files
00020 //  instantiate templates or use macros or inline functions from this
00021 //  file, or you compile this file and link it with other files to
00022 //  produce an executable, this file does not by itself cause the
00023 //  resulting executable to be covered by the GNU General Public
00024 //  License.  This exception does not however invalidate any other
00025 //  reasons why the executable file might be covered by the GNU General
00026 //  Public License.
00027 
00028 //  $Id: utility.h,v 1.4 2002/08/24 13:59:27 petter_urkedal Exp $
00029 
00030 
00031 #ifndef MORE_GEN_UTILITY_H
00032 #define MORE_GEN_UTILITY_H
00033 
00034 #include <utility>
00035 #include <functional>
00036 #include <string>
00037 #include <typeinfo>
00038 #include <stdexcept>
00039 #include <cassert>
00040 #include <more/bits/config.h>
00041 
00042 
00043 namespace more {
00044 namespace gen {
00045 
00046   struct instance_counter
00047   {
00048       instance_counter()
00049           : ic(new int)
00050       {
00051           *ic = 0;
00052       }
00053 
00054       instance_counter(const instance_counter& x)
00055           : ic(x.ic)
00056       {
00057           ++*ic;
00058       }
00059 
00060       ~instance_counter()
00061       {
00062           if (!*ic)
00063               delete ic;
00064           else
00065               --*ic;
00066       }
00067 
00068       instance_counter& operator=(const instance_counter& x)
00069       {
00070           if (!*ic)
00071               delete ic;
00072           ic = x.ic;
00073           ++*ic;
00074           return *this;
00075       }
00076 
00077       bool is_unique() const { return !*ic; }
00078 
00079   private:
00080       mutable int* ic;
00081   };
00082 
00083   //  --- handle ---
00084   //
00085 
00086   template<typename T> class handle;
00087 
00088   /** \class handle_base utility.h more/gen/utility.h
00089    ** Base class for the template argument of a \c handle. */
00090   struct handle_data
00091   {
00092       handle_data() : m_refcnt(1) {}
00093       void              ref()   const { ++m_refcnt; }
00094       unsigned int      unref() const { return --m_refcnt; }
00095 
00096   private:
00097       template<typename T> friend class handle;
00098       mutable int m_refcnt;
00099   };
00100 
00101   /** \class handle utility.h more/gen/utility.h
00102    ** Utility class to deal with reference counting.  This class can
00103    ** be used as a base class for the user-visible class, whereas the
00104    ** data members are placed in a separate type, given as the
00105    ** template argument \a T.  The handle can also be a data-member.
00106    ** In any case, the copy constructor, the assigment operator and
00107    ** the destructor shall be invoked when the superclass or containing
00108    ** class is copied, assigned to ar destructed, respectively.
00109    **
00110    ** A const handle is treated as a constant object referring to
00111    ** <i>mutable</i> data, since constness of the data is anyway violated
00112    ** when a non-constant handle to the same data also exists.  But
00113    ** the member functions of the object derived from the handle
00114    ** should nevertheless reflect the constness of the data.  The
00115    ** important consequence of this semanic, is that the
00116    ** copy-constructor can be declared `const&', and thus the classes
00117    ** will interact more normally with STL headers, and in particular
00118    ** the extensions in `more/lambda.h'. */
00119   template<typename T>
00120   struct handle
00121   {
00122       handle() : m_ptr(0) {}
00123 
00124       explicit handle(T* p) : m_ptr(p) {}
00125 
00126       handle(handle const& x)
00127           : m_ptr(x.m_ptr)
00128       {
00129           if (m_ptr)
00130               ++m_ptr->m_refcnt;
00131       }
00132 
00133       handle& operator=(handle const& x)
00134       {
00135           if (m_ptr && !--m_ptr->m_refcnt)
00136               delete m_ptr;
00137           m_ptr = x.m_ptr;
00138           if (m_ptr)
00139               ++m_ptr->m_refcnt;
00140           return *this;
00141       }
00142 
00143       ~handle()
00144       {
00145           if (m_ptr && !--m_ptr->m_refcnt)
00146               delete m_ptr;
00147       }
00148 
00149       operator bool() const { return m_ptr; }
00150 
00151       bool is_owner() const { return m_ptr->m_refcnt == 1; }
00152 
00153       void check_data() const
00154       {
00155 #ifndef MORE_DEBUG
00156           if (!m_ptr)
00157               throw std::logic_error(
00158                   std::string("more::gen::handle: "
00159                               "Accessing invalid object, typeid = ")
00160                   + typeid(*this).name());
00161 #endif
00162       }
00163 
00164       T* datachk() const
00165       {
00166           check_data();
00167           return m_ptr;
00168       }
00169 
00170       T* data() const { return m_ptr; }
00171 
00172       T* data_ref() const { m_ptr->ref(); return m_ptr; }
00173 
00174 //       T* operator()() const { return m_ptr; }
00175 
00176       /** Set the handle to point to \a ptr.  The caller looses
00177        ** ownership of \a ptr. */
00178       void set_data(T* ptr)
00179       {
00180           if (m_ptr && !--m_ptr->m_refcnt)
00181               delete m_ptr;
00182           m_ptr = ptr;
00183       }
00184 
00185     private:
00186       mutable T *m_ptr;
00187   };
00188 
00189   /** \class noncopyable utility.h more/utility.h
00190    **
00191    ** Classes derived from this can not be copied or assigned.  Since
00192    ** C++ provies a default copy constructor and copy assignment
00193    ** operator for classes which does not define them, it is necessary
00194    ** to explicitely state that copying is not allow; which is done
00195    ** with this common ideom.  */
00196   struct noncopyable
00197   {
00198       noncopyable() {}
00199     private:
00200       noncopyable(noncopyable const&) {}
00201       noncopyable const& operator=(noncopyable const&) { return *this; }
00202   };
00203 
00204   /** \class refpair utility.h more/gen/utility.h
00205    **
00206    ** Like a pair, but contains references which can be assigned to. */
00207   template<typename T, typename U>
00208     struct refpair
00209     {
00210         /** The type of the first component. */
00211         typedef T first_type;
00212         /** The type of the second component. */
00213         typedef U second_type;
00214         /** Construct a pair of references to \c x and \c y. */
00215         refpair(T& x, U& y) : first(x), second(y) {}
00216         /** Construct a copy. */
00217         refpair(refpair const& rp) : first(rp.first), second(rp.second) {}
00218         /** Assign the values of \c p to the references in this pair. */
00219         refpair& operator=(std::pair<T, U> const& p)
00220         {
00221             first = p.first;
00222             second = p.second;
00223             return *this;
00224         }
00225         /** The first member of the pair. */
00226         T& first;
00227         /** The second member of the pair. */
00228         U& second;
00229     };
00230 
00231   /** Creates a refpair. */
00232   template<typename T, typename U>
00233     inline refpair<T, U> tie(T& x, U& y) { return refpair<T, U>(x, y); }
00234 
00235 
00236   /** \class select1st utility.h more/gen/utility.h
00237    **
00238    ** A functional which returns a reference to the first component of
00239    ** a pair-like type.  */
00240   template<typename Pair>
00241     struct select1st : std::unary_function<Pair, typename Pair::first_type>
00242     {
00243         typename Pair::first_type&
00244         operator()(Pair& x) const
00245         {
00246             return x.first;
00247         }
00248     };
00249 
00250   /** \class select2nd utility.h more/gen/utility.h
00251    **
00252    ** A functional which returns a reference to the second component
00253    ** of a pair-like type.  */
00254   template<typename Pair>
00255     struct select2nd : std::unary_function<Pair, typename Pair::second_type>
00256     {
00257         typename Pair::second_type&
00258         operator()(Pair& x) const
00259         {
00260             return x.second;
00261         }
00262     };
00263 
00264 }} // more::gen
00265 
00266 #endif

Generated on Sat Sep 7 19:11:14 2002 for more with Doxygen 1.2.13.1. Doxygen 1.2.13.1 is written and copyright 1997-2002 by Dimitri van Heesch.