1// Copyright (c) 2017-2023, The Khronos Group Inc.
2// Copyright (c) 2017-2019 Valve Corporation
3// Copyright (c) 2017-2019 LunarG, Inc.
4// Copyright (c) 2019 Collabora, Ltd.
5//
6// SPDX-License-Identifier: Apache-2.0 OR MIT
7//
8// Initial Author: Ryan Pavlik <ryan.pavlik@collabora.com>
9//
10
11/*!
12 * @file
13 *
14 * Additional functions along the lines of the standard library algorithms.
15 */
16
17#pragma once
18
19#include <algorithm>
20#include <vector>
21
22/// Like std::remove_if, except it works on associative containers and it actually removes this.
23///
24/// The iterator stuff in here is subtle - .erase() invalidates only that iterator, but it returns a non-invalidated iterator to the
25/// next valid element which we can use instead of incrementing.
26template <typename T, typename Pred>
27static inline void map_erase_if(T &container, Pred &&predicate) {
28 for (auto it = container.begin(); it != container.end();) {
29 if (predicate(*it)) {
30 it = container.erase(it);
31 } else {
32 ++it;
33 }
34 }
35}
36
37/*!
38 * Moves all elements matching the predicate to the end of the vector then erases them.
39 *
40 * Combines the two parts of the erase-remove idiom to simplify things and avoid accidentally using the wrong erase overload.
41 */
42template <typename T, typename Alloc, typename Pred>
43static inline void vector_remove_if_and_erase(std::vector<T, Alloc> &vec, Pred &&predicate) {
44 auto b = vec.begin();
45 auto e = vec.end();
46 vec.erase(std::remove_if(b, e, std::forward<Pred>(predicate)), e);
47}
48