/* Copyright 2012 10gen Inc. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License, version 3, * as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . * * As a special exception, the copyright holders give permission to link the * code of portions of this program with the OpenSSL library under certain * conditions as described in each individual source file and distribute * linked combinations including the program with the OpenSSL library. You * must comply with the GNU Affero General Public License in all respects * for all of the code used other than as permitted herein. If you modify * file(s) with this exception, you may extend this exception to your * version of the file(s), but you are not obligated to do so. If you do not * wish to do so, delete this exception statement from your version. If you * delete this exception statement from all source files in the program, * then also delete it in the license file. */ #pragma once #include #include #include "mongo/base/disallow_copying.h" namespace mongo { /** * An std::vector wrapper that deletes pointers within a vector on destruction. The objects * referenced by the vector's pointers are 'owned' by an object of this class. * NOTE that an OwnedPointerVector wraps an std::vector. */ template class OwnedPointerVector { MONGO_DISALLOW_COPYING(OwnedPointerVector); public: OwnedPointerVector() {} ~OwnedPointerVector() { clear(); } /** * Takes ownership of all pointers contained in 'other'. * NOTE: argument is intentionally taken by value. */ OwnedPointerVector(std::vector other) { _vector.swap(other); } /** * Takes ownership of all pointers contained in 'other'. * NOTE: argument is intentionally taken by value. */ OwnedPointerVector& operator=(std::vector other) { clear(); _vector.swap(other); return *this; } typedef typename std::vector::const_iterator const_iterator; typedef typename std::vector::const_reverse_iterator const_reverse_iterator; /** Access the vector. */ const std::vector& vector() const { return _vector; } std::vector& mutableVector() { return _vector; } std::size_t size() const { return _vector.size(); } bool empty() const { return _vector.empty(); } const_iterator begin() const { return _vector.begin(); } const_reverse_iterator rbegin() const { return _vector.rbegin(); } const_iterator end() const { return _vector.end(); } const_reverse_iterator rend() const { return _vector.rend(); } T* operator[](size_t i) const { return _vector[i]; } T* back() const { return _vector.back(); } T* front() const { return _vector.front(); } void push_back(T* ptr) { _vector.push_back(ptr); } /** * Deletes all pointers in the vector, then sets its size to 0. */ void clear(); /** * Deletes the pointer at 'it', then erases it from the vector. */ void erase(const_iterator it) { delete *it; _vector.erase(toNonConstIter(it)); } void erase(const_iterator begin, const_iterator end) { for (const_iterator it = begin; it != end; ++it) { delete *it; } _vector.erase(toNonConstIter(begin), toNonConstIter(end)); } // // extensions // /** * Releases the entire vector to allow you to transfer ownership. * * Leaves the OwnedPointerVector empty. * Named after the similar method and pattern in std::unique_ptr. */ std::vector release() { std::vector out; out.swap(_vector); return out; } /** * Releases ownership of a single element. * * Sets that element to NULL and does not change size(). */ T* releaseAt(size_t i) { T* out = _vector[i]; _vector[i] = NULL; return out; } T* popAndReleaseBack() { T* out = _vector.back(); _vector.pop_back(); return out; } void popAndDeleteBack() { delete popAndReleaseBack(); } private: typename std::vector::iterator toNonConstIter(const_iterator it) { // This is needed for a few cases where c++03 vectors require non-const iterators that // were relaxed in c++11 to allow const_iterators. It can go away when we require c++11. return _vector.begin() + (it - begin()); } std::vector _vector; }; template inline void OwnedPointerVector::clear() { for (typename std::vector::iterator i = _vector.begin(); i != _vector.end(); ++i) { delete *i; } _vector.clear(); } } // namespace mongo