Value_Ptr.h

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00003 //==========================================================================
00004 /**
00005  *  @file Value_Ptr.h
00006  *
00007  *  Value_Ptr.h,v 4.9 2005/11/27 12:11:35 ossama Exp
00008  *
00009  *  Value_Ptr implementation based on code in Herb Sutter's book "More
00010  *  Exceptional C++".
00011  *
00012  *  @author Ossama Othman <ossama@dre.vanderbilt.edu>
00013  */
00014 //==========================================================================
00015 
00016 #ifndef ACE_VALUE_PTR_H
00017 #define ACE_VALUE_PTR_H
00018 
00019 #include "ace/config-lite.h"
00020 
00021 #include <algorithm>
00022 
00023 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00024 
00025 namespace ACE
00026 {
00027   /**
00028    * @struct VP_traits
00029    *
00030    * @brief @c Value_Ptr traits template structure.
00031    *
00032    * The @c Value_Ptr template class delegates some operations to this
00033    * template traits structure.
00034    *
00035    * Specialize this trait template if cloning through copy
00036    * construction is not sufficient.  For example, to avoid slicing
00037    * when copying an object through a base class pointer, one can
00038    * implement a virtual "clone" method that can be used to
00039    * polymorphically invoke the appropriate cloning operation(s).
00040    * That virtual method would then be invoked by the @c VP_traits<>
00041    * specialization.
00042    */
00043   template <typename T>
00044   struct VP_traits
00045   {
00046     /// Copy the given object.
00047     static T * clone (T const * p) { return new T (*p); }
00048   };
00049 
00050   /**
00051    * @class Value_Ptr
00052    *
00053    * @brief Smart pointer implementation designed for use as a class
00054    *        member.
00055    *
00056    * Using a @c std::auto_ptr<> as a class member is sometimes
00057    * problematic since ownership of memory is transferred when copying
00058    * such members.  This @c Value_Ptr class is explicitly designed to
00059    * avoid such problems by performing copies of the underlying object
00060    * rather than transfer ownership.  This, for example, allows it to
00061    * be readily used as a member in classes placed inside STL
00062    * containers.
00063    *
00064    * @see Item 31 in "More Exceptional C++" by Herb Sutter.
00065    */
00066   template <typename T>
00067   class Value_Ptr
00068   {
00069   public:
00070 
00071     /// Constructor.
00072     explicit Value_Ptr (T * p = 0) : p_ (p) { }
00073 
00074     /// Destructor.
00075     ~Value_Ptr (void) { delete this->p_; }
00076 
00077     /// Deference operator.
00078     T & operator* (void) const { return *this->p_; }
00079 
00080     /// Pointer operator.
00081     T * operator-> (void) const { return this->p_; }
00082 
00083     /// Non-throwing swap operation used to make assignment strongly
00084     /// exception-safe.
00085     /**
00086      * @note As implemented, the swap operation may not work correctly
00087      *       for @c auto_ptr<>s, but why would one use an @c
00088      *       auto_ptr<> as the template argument for this particular
00089      *       template class!?
00090      */
00091     void swap (Value_Ptr & other) { std::swap (this->p_, other.p_); }
00092 
00093     /// Copy constructor.
00094     Value_Ptr (Value_Ptr const & other)
00095       : p_ (create_from (other.p_)) { }
00096 
00097     /// Assignment operator.
00098     Value_Ptr & operator= (Value_Ptr const & other)
00099     {
00100       // Strongly exception-safe.
00101       Value_Ptr temp (other);
00102       this->swap (temp);
00103       return *this;
00104     }
00105 
00106 #ifndef ACE_LACKS_MEMBER_TEMPLATES
00107 
00108     // Compiler can't handle member templates so we lose converting
00109     // copy operations.
00110 
00111     /// Converting copy constructor.
00112     template <typename U>
00113     Value_Ptr (Value_Ptr<U> const & other)
00114       : p_ (create_from (other.p_)) { }
00115 
00116     /// Converting assignment operator.
00117     template <typename U>
00118     Value_Ptr & operator= (Value_Ptr<U> const & other)
00119     {
00120       // Strongly exception-safe.
00121       Value_Ptr temp (other);
00122       this->swap (temp);
00123       return *this;
00124     }
00125 
00126 #endif  /* !ACE_LACKS_MEMBER_TEMPLATES */
00127 
00128   private:
00129 
00130 #ifndef ACE_LACKS_MEMBER_TEMPLATES
00131 
00132     /// Copying method invoked when copy constructing.
00133     template <typename U>
00134     T * create_from (U const * p) const
00135     {
00136       return p ? VP_traits<U>::clone (p) : 0;
00137     }
00138 
00139 #else
00140 
00141     // Compiler can't handle member templates so we lose converting
00142     // copy operations.
00143 
00144     /// Copying method invoked when copy constructing.
00145     T * create_from (T const * p) const
00146     {
00147       return p ? VP_traits<T>::clone (p) : 0;
00148     }
00149 
00150 #endif  /* !ACE_LACKS_MEMBER_TEMPLATES */
00151 
00152   private:
00153 
00154 #ifndef ACE_LACKS_MEMBER_TEMPLATES
00155     template <typename U> friend class Value_Ptr;
00156 #endif  /* !ACE_LACKS_MEMBER_TEMPLATES */
00157 
00158     /// Object owned by this @c Value_Ptr.
00159     T * p_;
00160 
00161   };
00162 
00163 }
00164 
00165 ACE_END_VERSIONED_NAMESPACE_DECL
00166 
00167 #endif  /* ACE_VALUE_PTR_H */

Generated on Thu Nov 9 09:42:09 2006 for ACE by doxygen 1.3.6