blob: 3c2d97c7b17fb0691524bece86f78703868d534f [file] [log] [blame]
Avi Drissmane4622aa2022-09-08 20:36:061// Copyright 2011 The Chromium Authors
[email protected]7286e3fc2011-07-19 22:13:242// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5// Derived from google3/util/gtl/stl_util.h
6
7#ifndef BASE_STL_UTIL_H_
8#define BASE_STL_UTIL_H_
[email protected]7286e3fc2011-07-19 22:13:249
[email protected]1dea7572012-12-05 21:40:2710#include <algorithm>
[email protected]c014f2b32013-09-03 23:29:1211#include <iterator>
[email protected]7286e3fc2011-07-19 22:13:2412
Hans Wennborg7b533712020-06-22 20:52:2713#include "base/check.h"
[email protected]1dea7572012-12-05 21:40:2714
skyostil68be7152016-08-09 22:18:0015namespace base {
16
Dan Sanders97c13742018-05-17 23:12:3217// Returns a const reference to the underlying container of a container adapter.
18// Works for std::priority_queue, std::queue, and std::stack.
19template <class A>
20const typename A::container_type& GetUnderlyingContainer(const A& adapter) {
21 struct ExposedAdapter : A {
22 using A::c;
23 };
24 return adapter.*&ExposedAdapter::c;
25}
26
[email protected]6ee951a2012-06-26 17:24:0527// Clears internal memory of an STL object.
[email protected]7286e3fc2011-07-19 22:13:2428// STL clear()/reserve(0) does not always free internal memory allocated
29// This function uses swap/destructor to ensure the internal memory is freed.
Peter Kasting134ef9af2024-12-28 02:30:0930template <class T>
[email protected]6ee951a2012-06-26 17:24:0531void STLClearObject(T* obj) {
[email protected]7286e3fc2011-07-19 22:13:2432 T tmp;
33 tmp.swap(*obj);
34 // Sometimes "T tmp" allocates objects with memory (arena implementation?).
35 // Hence using additional reserve(0) even if it doesn't always work.
36 obj->reserve(0);
37}
38
[email protected]1dea7572012-12-05 21:40:2739// Returns a new ResultType containing the difference of two sorted containers.
40template <typename ResultType, typename Arg1, typename Arg2>
41ResultType STLSetDifference(const Arg1& a1, const Arg2& a2) {
Peter Kasting025a94252025-01-29 21:28:3742 DCHECK(std::ranges::is_sorted(a1));
43 DCHECK(std::ranges::is_sorted(a2));
[email protected]1dea7572012-12-05 21:40:2744 ResultType difference;
Peter Kasting134ef9af2024-12-28 02:30:0945 std::set_difference(a1.begin(), a1.end(), a2.begin(), a2.end(),
[email protected]1dea7572012-12-05 21:40:2746 std::inserter(difference, difference.end()));
47 return difference;
48}
49
[email protected]9a53ade2014-01-29 17:13:2750// Returns a new ResultType containing the union of two sorted containers.
51template <typename ResultType, typename Arg1, typename Arg2>
52ResultType STLSetUnion(const Arg1& a1, const Arg2& a2) {
Peter Kasting025a94252025-01-29 21:28:3753 DCHECK(std::ranges::is_sorted(a1));
54 DCHECK(std::ranges::is_sorted(a2));
[email protected]9a53ade2014-01-29 17:13:2755 ResultType result;
Peter Kasting134ef9af2024-12-28 02:30:0956 std::set_union(a1.begin(), a1.end(), a2.begin(), a2.end(),
[email protected]9a53ade2014-01-29 17:13:2757 std::inserter(result, result.end()));
58 return result;
59}
60
61// Returns a new ResultType containing the intersection of two sorted
62// containers.
63template <typename ResultType, typename Arg1, typename Arg2>
64ResultType STLSetIntersection(const Arg1& a1, const Arg2& a2) {
Peter Kasting025a94252025-01-29 21:28:3765 DCHECK(std::ranges::is_sorted(a1));
66 DCHECK(std::ranges::is_sorted(a2));
[email protected]9a53ade2014-01-29 17:13:2767 ResultType result;
Peter Kasting134ef9af2024-12-28 02:30:0968 std::set_intersection(a1.begin(), a1.end(), a2.begin(), a2.end(),
[email protected]9a53ade2014-01-29 17:13:2769 std::inserter(result, result.end()));
70 return result;
71}
72
Kevin Bailey156ff6d2017-10-26 17:36:0073// A helper class to be used as the predicate with |EraseIf| to implement
74// in-place set intersection. Helps implement the algorithm of going through
75// each container an element at a time, erasing elements from the first
76// container if they aren't in the second container. Requires each container be
77// sorted. Note that the logic below appears inverted since it is returning
78// whether an element should be erased.
79template <class Collection>
80class IsNotIn {
81 public:
82 explicit IsNotIn(const Collection& collection)
Lei Zhang56887e22024-11-21 18:48:0683 : it_(collection.begin()), end_(collection.end()) {}
Kevin Bailey156ff6d2017-10-26 17:36:0084
85 bool operator()(const typename Collection::value_type& x) {
Lei Zhang56887e22024-11-21 18:48:0686 while (it_ != end_ && *it_ < x) {
87 ++it_;
Kevin Bailey156ff6d2017-10-26 17:36:0088 }
Lei Zhang56887e22024-11-21 18:48:0689 if (it_ == end_ || *it_ != x) {
90 return true;
91 }
92 ++it_;
93 return false;
Kevin Bailey156ff6d2017-10-26 17:36:0094 }
95
96 private:
Lei Zhang56887e22024-11-21 18:48:0697 typename Collection::const_iterator it_;
Kevin Bailey156ff6d2017-10-26 17:36:0098 const typename Collection::const_iterator end_;
99};
100
[email protected]1dea7572012-12-05 21:40:27101} // namespace base
102
[email protected]7286e3fc2011-07-19 22:13:24103#endif // BASE_STL_UTIL_H_