1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
#ifndef MANAGED_PTR_VECTOR
#define MANAGED_PTR_VECTOR

#include <vector>
#include <memory>
#include <cstddef>

//! A vector of pointers to objects that are automatically deleted when the container itself is deleted.
/*! Loosely
modeled after the boost ptr containers.
*/
template <typename X>
class ManagedPtrVector
{
public:
  typedef X value_type;
  typedef X& reference_type;
  typedef size_t size_type;
  typedef std::vector<X*> container_type;
  
  class iterator
  {
  public:
    typedef iterator this_type;
    typedef X& reference;
    typedef size_t size_type;
    typedef size_t difference_type;
    
    iterator()
      {}
    iterator(const this_type& rhs)
        :mIter(rhs.mIter)
      {}
    iterator(const typename ManagedPtrVector<X>::container_type::iterator& rhs)
        : mIter(rhs)
      {}
    ~iterator()
      {}
    
    X* operator->()
      { return *mIter; }
    reference operator*() const
      { return **mIter; }
    
    bool operator==(const this_type& rhs) const
      { return this->mIter == rhs.mIter; }
    bool operator!=(const this_type& rhs) const
      { return this->mIter != rhs.mIter; }
    
    this_type& operator++()
      {
        ++mIter;
        return *this;
      }
    
    this_type operator++(int)
      {
        this_type rv = *this;
        ++mIter;
        return rv;
      }
    
    this_type& operator--()
      {
        --mIter;
        return *this;
      }
    
    this_type operator--(int)
      {
        this_type rv = *this;
        --mIter;
        return rv;
      }

    this_type operator+(difference_type n)
    {
      this_type rv = *this;
      rv += n;
      return rv;
    }
    
    this_type& operator+=(difference_type n)
      {
        mIter += n;
        return *this;
      }
    
    this_type& operator-=(difference_type n)
      {
        mIter -= n;
        return *this;
      }
    
    reference operator[](difference_type i) const
      {
        return reference(*(mIter+i));
      }
    
  private:
    typename ManagedPtrVector<X>::container_type::iterator mIter;
  };
  
  
  ManagedPtrVector()
  {}
  ~ManagedPtrVector()
  { clear(); }
  
  // Add an object to the container.
  // The container becomes "owned" by the container.
  void push_back(X* obj)
  { mContainer.push_back(obj); }

  iterator begin()
  { return iterator(mContainer.begin()); }
  iterator end()
  { return iterator(mContainer.end()); }

  //! Refer by index
  reference_type operator[](size_type i)
  { return *(mContainer[i]); }

  //! Remove an item from the list without deleting it.
  /*! The returned auto_ptr now owns the pointer.*/
  std::auto_ptr<X> release(iterator to_release)
  {
    // save a raw pointer.
    X* rv = to_release.operator->();
    // find the iterator in the container.  We don't have access
    // to the internal iterator, so we have to loop through to find it.
    // This could probably be optimized.
    typename container_type::iterator i = mContainer.begin();
    for (;
      i != mContainer.end() && iterator(i) != to_release;
      ++i)
    {}
    // we either found the iterator, or the end.  erase it.
    mContainer.erase(i);
    return std::auto_ptr<X>(rv);
  }

  //! Replace one object with another.
  /*! The returned auto_ptr now owns the pointer removed from
      the container, and the container owns the object pointed to
      by \a new_val.
  */
  std::auto_ptr<X> replace(iterator to_replace, std::auto_ptr<X> new_val)
  {
    // save a raw pointer.
    X* rv = to_replace.operator->();<--- Variable 'rv' is assigned a value that is never used.
    // find the iterator in the container.  We don't have access
    // to the internal iterator, so we have to loop through to find it.
    // This could probably be optimized.
    typename container_type::iterator i = mContainer.begin();
    for (;
      i != mContainer.end();
      ++i)
    {
      if (iterator(i) == to_replace)
      {
        *i = new_val;<--- Copying 'auto_ptr' pointer to another does not create two equal objects since one has lost its ownership of the pointer.
      }
    }
    return std::auto_ptr<X>(NULL);
  }

  // Delete all objects contained in this container.
  void clear()
  {
    // delete all the pointers
    for (typename container_type::iterator i = mContainer.begin();
      i != mContainer.end();
      i++)<--- Prefer prefix ++/-- operators for non-primitive types.
    {
      delete *i;
    }
    mContainer.clear();
  }

  size_type size() const
  { return mContainer.size(); }

private:
  // Make both of these illegal
  ManagedPtrVector(const ManagedPtrVector<X>&);
  ManagedPtrVector& operator=(const ManagedPtrVector<X>&);

  container_type mContainer;
};



#endif