#ifndef VALUE_PTR_H #define VALUE_PTR_H // ---------------------------------------------------------------------- // // ValuePtr.h - Smart pointer permitting copying of pointed-to object // // Purpose: // Declaration and definition of the class template zmt::ValuePtr. // Full documentation available in Sutter: More Exceptional C++, // Addison-Wesley, 2002; Items 30 and 31. // // History: // 08-May-2000 WEB Original version by Herb Sutter, GOTW #62, // http://www.gotw.ca/gotw/062.htm; edit for comformance with Zoom // and ISOcxx // 06-Apr-2001 WEB Fix syntax for declaring class template friendship // 31-May-2002 WEB Add swap() free function // 03-Jun-2002 WEB Separate from ZMtools into its own package; change // name from HolderPtr to ValuePtr per Sutter; change namespace name; // update internal documentation // 11-Jun-2002 JBK Remove friendship for gcc 2.95.2 and use the // operator-> to get at the pointer instead of private member access // 12-Jun-2002 WEB Entirely remove no-longer-needed friendship; // remove last vestiges of ISOcxx // // ---------------------------------------------------------------------- #include // for std::swap() namespace zoom { // -------------------------------------------------------------------- // // Auxiliary traits class template providing default clone() // Users should specialize this template for types that have their // own self-copy operations; failure to do so may lead to slicing! // // -------------------------------------------------------------------- template< class T > struct VPTraits { static T * clone( T const * p ) { return new T( *p ); } }; // VPTraits // -------------------------------------------------------------------- // // Copyable smart pointer class template // // -------------------------------------------------------------------- template< class T > class ValuePtr { public: // -------------------------------------------------- // Default constructor/destructor: // -------------------------------------------------- explicit ValuePtr( T * p = 0 ) : myP( p ) { ; } ~ValuePtr() { delete myP; myP = 0; } // -------------------------------------------------- // Copy constructor/copy assignment: // -------------------------------------------------- ValuePtr( ValuePtr const & orig ) : myP( createFrom( orig.myP ) ) {} ValuePtr & operator = ( ValuePtr const & orig ) { ValuePtr temp( orig ); swap( temp ); return *this; } // -------------------------------------------------- // Access mechanisms: // -------------------------------------------------- T & operator * () const { return *myP; } T * operator -> () const { return myP; } // -------------------------------------------------- // Manipulation: // -------------------------------------------------- void swap( ValuePtr & orig ) { std::swap( myP, orig.myP ); } // -------------------------------------------------- // Copy-like construct/assign from compatible ValuePtr<>: // -------------------------------------------------- template< class U > ValuePtr( ValuePtr const & orig ) : myP( createFrom( orig.operator->() ) ) {} template< class U > ValuePtr & operator = ( ValuePtr const & orig ) { ValuePtr temp( orig ); swap( temp ); return *this; } private: // -------------------------------------------------- // Implementation aid: // -------------------------------------------------- template< class U > T * createFrom( U const * p ) const { return p ? VPTraits::clone( p ) : 0; } // -------------------------------------------------- // Member data: // -------------------------------------------------- T * myP; }; // ValuePtr // -------------------------------------------------------------------- // // Free-standing swap() // // -------------------------------------------------------------------- template< class T > inline void swap( ValuePtr & vp1, ValuePtr & vp2 ) { vp1.swap( vp2 ); } } // namespace zoom #endif // VALUE_PTR_H