From 671a80a70be60ccad1c0176556487c09be810489 Mon Sep 17 00:00:00 2001 From: Attila Molnar Date: Mon, 24 Mar 2014 16:33:09 +0100 Subject: Create the stdalgo namespace for container-related algorithms, add stdalgo::vector::swaperase() --- include/inspircd.h | 1 + include/stdalgo.h | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+) create mode 100644 include/stdalgo.h (limited to 'include') diff --git a/include/inspircd.h b/include/inspircd.h index a707eec73..bf3cb06b0 100644 --- a/include/inspircd.h +++ b/include/inspircd.h @@ -46,6 +46,7 @@ #include "intrusive_list.h" #include "compat.h" #include "typedefs.h" +#include "stdalgo.h" CoreExport extern InspIRCd* ServerInstance; diff --git a/include/stdalgo.h b/include/stdalgo.h new file mode 100644 index 000000000..758845312 --- /dev/null +++ b/include/stdalgo.h @@ -0,0 +1,66 @@ +/* + * InspIRCd -- Internet Relay Chat Daemon + * + * Copyright (C) 2014 Attila Molnar + * + * This file is part of InspIRCd. InspIRCd is free software: you can + * redistribute it and/or modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation, version 2. + * + * 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 General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#pragma once + +namespace stdalgo +{ + namespace vector + { + /** + * Erase a single element from a vector by overwriting it with a copy of the last element, + * which is then removed. This, in contrast to vector::erase(), does not result in all + * elements after the erased element being moved. + * @param vect Vector to remove the element from + * @param it Iterator to the element to remove + * @return Nothing, but all iterators, references and pointers to the erased element and the + * last element are invalidated + */ + template + inline void swaperase(typename std::vector& vect, const typename std::vector::iterator& it) + { + *it = vect.back(); + vect.pop_back(); + } + + /** + * Find and if exists, erase a single element from a vector by overwriting it with a + * copy of the last element, which is then removed. This, in contrast to vector::erase(), + * does not result in all elements after the erased element being moved. + * If the given value occurs multiple times, the one with the lowest index is removed. + * Individual elements are compared to the given value using operator==(). + * @param vect Vector to remove the element from + * @param val Value of the element to look for and remove + * @return True if the element was found and removed, false if it wasn't found. + * If true, all iterators, references and pointers pointing to either the first element that + * is equal to val or to the last element are invalidated. + */ + template + inline bool swaperase(typename std::vector& vect, const T& val) + { + const typename std::vector::iterator it = std::find(vect.begin(), vect.end(), val); + if (it != vect.end()) + { + swaperase(vect, it); + return true; + } + return false; + } + } +} -- cgit v1.2.3