Boost logo

Boost :

From: Kevin Atkinson (kevinatk_at_[hidden])
Date: 2000-03-08 05:05:09


Here is a better copy of ClonePtr and CopyPtr. In the process of making
clone and copy pointer have a uniform interface and semantics I realized
that there is very little difference in them except for how a copy is
made. Thus, I decided to break of the commonality into a new class
classed GenericCopyPtr which is suitable for any type of copy function
and memory allocation.

Rather than having a different template parameter for each operation
(new copy, assignment, and delete) I decided to group them all together
in one structure. In my on code I find that this greatly increases the
readability of types because
   GenericCopyPtr<Type, CopyPtrParms>
is for more readable in error messages and the like than
  GenericCopyPtr<Type, NewWCopy, DerefAssign, StandardDelete>
Also if any of these functions have some sort of state in them they are
likely to need to share the same state. For example GenericCopyPtr can
easily be used with new[] and delete[] but in order make copies both the
"clone" method and the "assignment" method would need access to the
length of the array.

Hopefully now that you finally understand the point of these classes you
can understand the more generic code.

Both the CopyPtr and ClonePtr have way too much code. Ideally I would
like to do something like

template <class T>
class CopyPtr : public GenericCopyPtr<T, CopyPtrParms<T> {
  ... (constructors)
}

However egcs 1.1 and gcc 2.95 where having all sort of problems with
undefined references because durien explicit instantiation none of the
base methods were getting instantiation. So I just decided to use the
"contains a" relation.

If you think it should go in boost let me know and I will change the
namespace, the naming to all lower case if you insist, and add it to the
vault.

However the modified copy will need testing as it won't be the one that
I use as I believe strongly that all classes should be mixed case with
the first letter upper and which the C++ standards committee felt the
same way.

-- 
Kevin Atkinson
kevinatk_at_[hidden]
http://metalab.unc.edu/kevina/

// Copyright (c) 2000
// Kevin Atkinson
//
// Permission to use, copy, modify, distribute and sell this software
// and its documentation for any purpose is hereby granted without
// fee, provided that the above copyright notice appear in all copies
// and that both that copyright notice and this permission notice
// appear in supporting documentation. Kevin Atkinson makes no
// representations about the suitability of this software for any
// purpose. It is provided "as is" without express or implied
// warranty.

#ifndef autil__generic_copy_ptr
#define autil__generic_copy_ptr

namespace autil {

  // Parms is expected to have the following members
  // T * Parms::clone(const T *);
  // void Parms::assign(T * &, const T *);
  // void Parms::del(T *);
  // All members can assume that all pointers are not null

  template <typename T, typename Parms>
  class GenericCopyPtr {

    T * ptr_;
    Parms parms_;

  public:

    explicit GenericCopyPtr(T * p = 0, const Parms & parms = Parms())
      : ptr_(p), parms_(parms) {}

    GenericCopyPtr(const GenericCopyPtr & other);
    GenericCopyPtr & operator= (const GenericCopyPtr & other) {
      assign(other.ptr_, parms_);
      return *this;
    }

    // assign makes a copy of other
    void assign(const T * other, const Parms & parms = Parms());

    // reset takes ownership of other
    void reset(T * other = 0, const Parms & parms = Parms());

    T & operator* () const {return *ptr_;}
    T * operator-> () const {return ptr_;}
    T * get() const {return ptr_;}
    operator T * () const {return ptr_;}
    
    T * release() {T * tmp = ptr_; ptr_ = 0; return tmp;}

    const Parms & parms() {return parms_;}
    const Parms & parms() const {return parms_;}

    ~GenericCopyPtr();
  };

}

#endif


// Copyright (c) 2000
// Kevin Atkinson
//
// Permission to use, copy, modify, distribute and sell this software
// and its documentation for any purpose is hereby granted without
// fee, provided that the above copyright notice appear in all copies
// and that both that copyright notice and this permission notice
// appear in supporting documentation. Kevin Atkinson makes no
// representations about the suitability of this software for any
// purpose. It is provided "as is" without express or implied
// warranty.

#ifndef autil__generic_copy_ptr_t
#define autil__generic_copy_ptr_t

#include "generic_copy_ptr.hh"

namespace autil {

  template <typename T, typename Parms>
  GenericCopyPtr<T,Parms>::GenericCopyPtr(const GenericCopyPtr & other)
  {
    if (other.ptr_ != 0)
      ptr_ = parms_.clone(other.ptr_);
    else
      ptr_ = 0;
    parms_ = other.parms_;
  }
  
  template <typename T, typename Parms>
  void GenericCopyPtr<T,Parms>::assign(const T * other_ptr,
                                       const Parms & other_parms)
  {
    if (other_ptr == 0) {
      if (ptr_ != 0) parms_.del(ptr_);
      ptr_ = 0;
    } else if (ptr_ == 0) {
      ptr_ = parms_.clone(other_ptr);
    } else {
      parms_.assign(ptr_, other_ptr);
    }
    parms_ = other_parms;
  }

  template <typename T, typename Parms>
  void GenericCopyPtr<T,Parms>::reset (T * other, const Parms & other_parms)
  {
    if (ptr_ != 0)
      parms_.del(ptr_);
    ptr_ = other;
    parms_ = other_parms;
  }

  template <typename T, typename Parms>
  GenericCopyPtr<T,Parms>::~GenericCopyPtr()
  {
    if (ptr_ != 0)
      parms_.del(ptr_);
  }
  
}

#endif


// Copyright (c) 2000
// Kevin Atkinson
//
// Permission to use, copy, modify, distribute and sell this software
// and its documentation for any purpose is hereby granted without
// fee, provided that the above copyright notice appear in all copies
// and that both that copyright notice and this permission notice
// appear in supporting documentation. Kevin Atkinson makes no
// representations about the suitability of this software for any
// purpose. It is provided "as is" without express or implied
// warranty.

#ifndef autil__copy_ptr
#define autil__copy_ptr

#include "generic_copy_ptr.hh"

namespace autil {

  template <typename T>
  class CopyPtr
  {
    struct Parms {
      T * clone(const T * ptr) const;
      void assign(T * & rhs, const T * lhs) const;
      void del(T * ptr);
    };
    GenericCopyPtr<T, Parms> impl;

  public:

    explicit CopyPtr(T * p = 0) : impl(p) {}
    CopyPtr(const CopyPtr & other) : impl(other.impl) {}

    CopyPtr & operator=(const CopyPtr & other) {
      impl = other.impl;
      return *this;
    }

    void assign(const T * other) {impl.assign(other);}
    void reset(T * other = 0) {impl.reset(other);}
    
    T & operator* () const {return *impl;}
    T * operator-> () const {return impl;}
    T * get() const {return impl;}
    operator T * () const {return impl;}

    T * release() {return impl.release();}
  };
  
}

#endif


// Copyright (c) 2000
// Kevin Atkinson
//
// Permission to use, copy, modify, distribute and sell this software
// and its documentation for any purpose is hereby granted without
// fee, provided that the above copyright notice appear in all copies
// and that both that copyright notice and this permission notice
// appear in supporting documentation. Kevin Atkinson makes no
// representations about the suitability of this software for any
// purpose. It is provided "as is" without express or implied
// warranty.

#ifndef autil__copy_ptr_t
#define autil__copy_ptr_t

#include "copy_ptr.hh"
#include "generic_copy_ptr-t.hh"

namespace autil {

  template <typename T>
  inline T * CopyPtr<T>::Parms::clone(const T * ptr) const {
    return new T(*ptr);
  }

  template <typename T>
  inline void CopyPtr<T>::Parms::assign(T * & rhs, const T * lhs) const {
    *rhs = *lhs;
  }

  template <typename T>
  inline void CopyPtr<T>::Parms::del(T * ptr) {
    delete ptr;
  }
}

#endif


// Copyright (c) 2000
// Kevin Atkinson
//
// Permission to use, copy, modify, distribute and sell this software
// and its documentation for any purpose is hereby granted without
// fee, provided that the above copyright notice appear in all copies
// and that both that copyright notice and this permission notice
// appear in supporting documentation. Kevin Atkinson makes no
// representations about the suitability of this software for any
// purpose. It is provided "as is" without express or implied
// warranty.

#ifndef autil__clone_ptr
#define autil__clone_ptr

#include "generic_copy_ptr.hh"

namespace autil {

  template <typename T>
  class ClonePtr
  {
    struct Parms {
      T * clone(const T * ptr) const;
      void assign(T * & rhs, const T * lhs) const;
      void del(T * ptr);
    };
    GenericCopyPtr<T, Parms> impl;

  public:

    explicit ClonePtr(T * p = 0) : impl(p) {}
    ClonePtr(const ClonePtr & other) : impl(other.impl) {}

    ClonePtr & operator=(const ClonePtr & other) {
      impl = other.impl;
      return *this;
    }

    void assign(const T * other) {impl.assign(other);}
    void reset(T * other = 0) {impl.reset(other);}
    
    T & operator* () const {return *impl;}
    T * operator-> () const {return impl;}
    T * get() const {return impl;}
    operator T * () const {return impl;}

    T * release() {return impl.release();}
  };
  
}

#endif


// Copyright (c) 2000
// Kevin Atkinson
//
// Permission to use, copy, modify, distribute and sell this software
// and its documentation for any purpose is hereby granted without
// fee, provided that the above copyright notice appear in all copies
// and that both that copyright notice and this permission notice
// appear in supporting documentation. Kevin Atkinson makes no
// representations about the suitability of this software for any
// purpose. It is provided "as is" without express or implied
// warranty.

#ifndef autil__clone_ptr_t
#define autil__clone_ptr_t

#include "clone_ptr.hh"
#include <typeinfo>
#include "generic_copy_ptr-t.hh"

namespace autil {

  template <typename T>
  inline T * ClonePtr<T>::Parms::clone(const T * ptr) const {
    return ptr->clone();
  }

  template <typename T>
  void ClonePtr<T>::Parms::assign(T * & rhs, const T * lhs) const {
    if (typeid(*rhs) == typeid(*lhs)) {
      rhs->assign(lhs);
    } else {
      delete rhs;
      rhs = lhs->clone();
    }
  }

  template <typename T>
  inline void ClonePtr<T>::Parms::del(T * ptr) {
    delete ptr;
  }

}

#endif


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk