3 /// A set of container classes and element base class that support
4 /// smart elements that can remove themselves from the container
7 /// To use it, derive your element from OptOut::Element, and
8 /// then add new-ly allocated pointers to the Vector. The
9 /// Vector will delete any remaining elements, and each
10 /// element can be deleted early, either with a delete this
11 /// by themselves, or deleted manually outside of the Vector.
15 Copyright (C) 2010-2013, Chris Frey <cdfrey@foursquare.net>
17 This program is free software; you can redistribute it and/or modify
18 it under the terms of the GNU General Public License as published by
19 the Free Software Foundation; either version 2 of the License, or
20 (at your option) any later version.
22 This program is distributed in the hope that it will be useful,
23 but WITHOUT ANY WARRANTY; without even the implied warranty of
24 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
26 See the GNU General Public License in the COPYING file at the
27 root directory of this project for more details.
30 #ifndef __UTIL_OPTOUT_H__
31 #define __UTIL_OPTOUT_H__
41 friend class ContainerBase
;
43 ContainerBase
*m_container
;
46 virtual void OptIn(ContainerBase
*container
)
49 m_container
= container
;
52 virtual void OptOut();
55 Element() : m_container(0) {}
67 virtual void NotifyElement(Element
*element
)
72 virtual void OptOut(Element
*element
) = 0;
75 virtual ~ContainerBase()
80 inline void Element::OptOut()
83 m_container
->OptOut(this);
88 template <class TypeT
>
89 class Vector
: public ContainerBase
92 typedef std::vector
<Element
*> container_type
;
93 typedef container_type::iterator iterator
;
94 typedef container_type::const_iterator const_iterator
;
95 typedef container_type::size_type size_type
;
101 virtual void OptOut(Element
*element
)
103 for( iterator i
= m_con
.begin(); i
!= m_con
.end(); ++i
) {
104 if( (*i
) == element
) {
115 while( (i
= m_con
.begin()) != m_con
.end() ) {
116 // this will remove the element from the array,
117 // hence the while, starting over each time
122 // std::vector<> compatible functions
123 size_type
size() { return m_con
.size(); }
124 void push_back(Element
*element
)
126 NotifyElement(element
);
127 m_con
.push_back(element
);
129 TypeT
* operator[] (size_type n
)
131 return dynamic_cast<TypeT
*> (m_con
[n
]);
133 iterator
begin() { return m_con
.begin(); }
134 const_iterator
begin() const { return m_con
.begin(); }
135 iterator
end() { return m_con
.end(); }
136 const_iterator
end() const { return m_con
.end(); }
137 iterator
rbegin() { return m_con
.rbegin(); }
138 const_iterator
rbegin() const { return m_con
.rbegin(); }
139 iterator
rend() { return m_con
.rend(); }
140 const_iterator
rend() const { return m_con
.rend(); }
142 // since iterators hold Element* pointers, these functions
143 // are just a helpful dynamic cast aid
144 TypeT
* GetType(iterator i
) { return dynamic_cast<TypeT
*> (*i
); }
145 const TypeT
* GetType(const_iterator i
) { return dynamic_cast<const TypeT
*> (*i
); }
149 } // namespace OptOut