Barry debian version 0.18.5-1
[barry.git] / desktop / src / optout.h
blob7e7a2ddf3b658d6cd0ab5b1f509cdededbb4fb3e
1 ///
2 /// \file OptOut.h
3 /// A set of container classes and element base class that support
4 /// smart elements that can remove themselves from the container
5 /// upon deletion.
6 ///
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.
12 ///
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__
33 #include <vector>
35 namespace OptOut {
37 class ContainerBase;
39 class Element
41 friend class ContainerBase;
43 ContainerBase *m_container;
45 protected:
46 virtual void OptIn(ContainerBase *container)
48 OptOut();
49 m_container = container;
52 virtual void OptOut();
54 public:
55 Element() : m_container(0) {}
56 virtual ~Element()
58 OptOut();
62 class ContainerBase
64 friend class Element;
66 protected:
67 virtual void NotifyElement(Element *element)
69 element->OptIn(this);
72 virtual void OptOut(Element *element) = 0;
74 public:
75 virtual ~ContainerBase()
80 inline void Element::OptOut()
82 if( m_container ) {
83 m_container->OptOut(this);
84 m_container = 0;
88 template <class TypeT>
89 class Vector : public ContainerBase
91 public:
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;
97 private:
98 container_type m_con;
100 protected:
101 virtual void OptOut(Element *element)
103 for( iterator i = m_con.begin(); i != m_con.end(); ++i ) {
104 if( (*i) == element ) {
105 m_con.erase(i);
106 return;
111 public:
112 ~Vector()
114 iterator i;
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
118 delete (*i);
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
151 #endif