20130313
[gdash.git] / src / cave / helper / adoptingcontainer.hpp
blobf257fe5e009eb84cf92ab14e69a9cf7b926bf4c6
1 /*
2 * Copyright (c) 2007-2013, Czirkos Zoltan http://code.google.com/p/gdash/
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 #ifndef _GD_ADOPTINGCONTAINER
17 #define _GD_ADOPTINGCONTAINER
19 #include "config.h"
21 #include <algorithm>
22 #include <vector>
24 /**
25 * Class which stores objects' pointers, and adopts them.
27 * The main purpose of this class to create a container for the
28 * objects, which is able to copy them using their clone() methods,
29 * and adopts the pointers given to them to store.
30 * Some functions can be inherited from the base class,
31 * some need to be redefined to delete the pointers as needed.
33 template <class T>
34 class AdoptingContainer: private std::vector<T *> {
35 private:
36 typedef std::vector<T *> _my_base;
37 public:
38 AdoptingContainer();
39 AdoptingContainer(const AdoptingContainer& orig);
40 AdoptingContainer& operator=(const AdoptingContainer& rhs);
41 ~AdoptingContainer();
43 /// Return last element
44 T * const back() const { return _my_base::back(); }
45 /// Return nth element
46 T * const at(unsigned n) const { return _my_base::at(n); }
48 public:
49 using _my_base::empty;
50 using _my_base::size;
51 void clear();
52 void clear_i_own_them() { _my_base::clear(); }
54 /// Store object given in container; adopt it (take care of deleting the pointer).
55 /// @param x The pointer to the object to store.
56 void push_back_adopt(T *x) { this->push_back(x); }
58 typedef typename _my_base::const_iterator const_iterator;
59 using _my_base::begin;
60 using _my_base::end;
62 template <class PRED> void remove_if(PRED p);
65 /// Remove elements from store, if p is true.
66 /// Only needed by the editor, to be able to remove some objects.
67 /// @param p Predicate to decide if a given element should be removed.
68 template <class T>
69 template <class PRED>
70 void AdoptingContainer<T>::remove_if(PRED p) {
71 typename _my_base::iterator bound=std::stable_partition(begin(), end(), p);
72 for (const_iterator it=begin(); it!=bound; ++it) {
73 delete (*it);
75 _my_base::erase(begin(), bound);
78 /// Creates an empty store
79 template <class T>
80 AdoptingContainer<T>::AdoptingContainer() {
83 /// Copy constructor
84 template <class T>
85 AdoptingContainer<T>::AdoptingContainer(const AdoptingContainer<T>& orig) {
86 (*this)=orig;
89 /// Assignment operator
90 template <class T>
91 AdoptingContainer<T>& AdoptingContainer<T>::operator=(const AdoptingContainer<T>& rhs) {
92 if (this==&rhs)
93 return *this;
94 for (unsigned i=0; i<size(); ++i)
95 delete (*this)[i];
96 this->resize(rhs.size());
97 for (unsigned i=0; i<size(); ++i)
98 (*this)[i]=rhs[i]->clone();
99 return *this;
102 /// Destructor
103 template <class T>
104 AdoptingContainer<T>::~AdoptingContainer() {
105 for (unsigned i=0; i<size(); ++i)
106 delete (*this)[i];
109 /// Clear object from list.
110 template <class T>
111 void AdoptingContainer<T>::clear() {
112 for (unsigned i=0; i<size(); ++i)
113 delete _my_base::at(i);
114 _my_base::clear();
118 #endif