1 /* 2 * This program is free software; you can redistribute it and/or 3 * modify it under the terms of the GNU General Public License 4 * as published by the Free Software Foundation; either version 2 5 * of the License, or (at your option) any later version. 6 * 7 * This program is distributed in the hope that it will be useful, 8 * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 * GNU General Public License for more details. 11 * 12 * You should have received a copy of the GNU General Public License 13 * along with this program; if not, write to the Free Software Foundation, 14 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 15 */ 16 17 #pragma once 18 19 /** \file 20 * \ingroup freestyle 21 * \brief Simple RAII wrappers for std:: sequential containers 22 * 23 * PointerSequence 24 * 25 * Produces a wrapped version of a sequence type (std::vector, std::deque, std::list) that will 26 * take ownership of pointers that it stores. Those pointers will be deleted in its destructor. 27 * 28 * Because the contained pointers are wholly owned by the sequence, you cannot make a copy of the 29 * sequence. Making a copy would result in a double free. 30 * 31 * This is a no-frills class that provides no additional facilities. The user is responsible for 32 * managing any pointers that are removed from the list, and for making sure that any pointers 33 * contained in the class are not deleted elsewhere. Because this class does no reference 34 * counting, the user must also make sure that any pointer appears only once in the sequence. 35 * 36 * If more sophisticated facilities are needed, use tr1::shared_ptr or boost::shared_ptr. 37 * This class is only intended to allow one to eke by in projects where tr1 or boost are not 38 * available. 39 * 40 * Usage: The template takes two parameters, the standard container, and the class held in the 41 * container. This is a limitation of C++ templates, where T::iterator is not a type when T is a 42 * template parameter. If anyone knows a way around this limitation, then the second parameter can 43 * be eliminated. 44 * 45 * Example: 46 * PointerSequence<vector<Widget*>, Widget*> v; 47 * v.push_back(new Widget); 48 * cout << v[0] << endl; // operator[] is provided by std::vector, not by PointerSequence 49 * v.destroy(); // Deletes all pointers in sequence and sets them to NULL. 50 * 51 * The idiom for removing a pointer from a sequence is: 52 * Widget* w = v[3]; 53 * v.erase(v.begin() + 3); // or v[3] = 0; 54 * The user is now responsible for disposing of w properly. 55 */ 56 57 #include <algorithm> 58 59 #ifdef WITH_CXX_GUARDEDALLOC 60 # include "MEM_guardedalloc.h" 61 #endif 62 63 namespace Freestyle { 64 65 template<typename C, typename T> class PointerSequence : public C { 66 PointerSequence(PointerSequence &other); 67 PointerSequence &operator=(PointerSequence &other); 68 destroyer(T t)69 static void destroyer(T t) 70 { 71 delete t; 72 } 73 74 public: PointerSequence()75 PointerSequence(){}; 76 ~PointerSequence()77 ~PointerSequence() 78 { 79 destroy(); 80 } 81 destroy()82 void destroy() 83 { 84 for_each(this->begin(), this->end(), destroyer); 85 } 86 87 #ifdef WITH_CXX_GUARDEDALLOC 88 MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:PointerSequence") 89 #endif 90 }; 91 92 } /* namespace Freestyle */ 93