stl_util.h 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877
  1. // Copyright (c) 2011 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. // Derived from google3/util/gtl/stl_util.h
  5. #ifndef BASE_STL_UTIL_H_
  6. #define BASE_STL_UTIL_H_
  7. #include <algorithm>
  8. #include <deque>
  9. #include <forward_list>
  10. #include <functional>
  11. #include <initializer_list>
  12. #include <iterator>
  13. #include <list>
  14. #include <map>
  15. #include <set>
  16. #include <string>
  17. #include <type_traits>
  18. #include <unordered_map>
  19. #include <unordered_set>
  20. #include <utility>
  21. #include <vector>
  22. #include "base/check.h"
  23. #include "base/optional.h"
  24. #include "base/template_util.h"
  25. namespace base {
  26. namespace internal {
  27. // Calls erase on iterators of matching elements and returns the number of
  28. // removed elements.
  29. template <typename Container, typename Predicate>
  30. size_t IterateAndEraseIf(Container& container, Predicate pred) {
  31. size_t old_size = container.size();
  32. for (auto it = container.begin(), last = container.end(); it != last;) {
  33. if (pred(*it))
  34. it = container.erase(it);
  35. else
  36. ++it;
  37. }
  38. return old_size - container.size();
  39. }
  40. template <typename Iter>
  41. constexpr bool IsRandomAccessIter =
  42. std::is_same<typename std::iterator_traits<Iter>::iterator_category,
  43. std::random_access_iterator_tag>::value;
  44. // Utility type traits used for specializing base::Contains() below.
  45. template <typename Container, typename Element, typename = void>
  46. struct HasFindWithNpos : std::false_type {};
  47. template <typename Container, typename Element>
  48. struct HasFindWithNpos<
  49. Container,
  50. Element,
  51. void_t<decltype(std::declval<const Container&>().find(
  52. std::declval<const Element&>()) != Container::npos)>>
  53. : std::true_type {};
  54. template <typename Container, typename Element, typename = void>
  55. struct HasFindWithEnd : std::false_type {};
  56. template <typename Container, typename Element>
  57. struct HasFindWithEnd<Container,
  58. Element,
  59. void_t<decltype(std::declval<const Container&>().find(
  60. std::declval<const Element&>()) !=
  61. std::declval<const Container&>().end())>>
  62. : std::true_type {};
  63. template <typename Container, typename Element, typename = void>
  64. struct HasContains : std::false_type {};
  65. template <typename Container, typename Element>
  66. struct HasContains<Container,
  67. Element,
  68. void_t<decltype(std::declval<const Container&>().contains(
  69. std::declval<const Element&>()))>> : std::true_type {};
  70. } // namespace internal
  71. // C++14 implementation of C++17's std::size():
  72. // http://en.cppreference.com/w/cpp/iterator/size
  73. template <typename Container>
  74. constexpr auto size(const Container& c) -> decltype(c.size()) {
  75. return c.size();
  76. }
  77. template <typename T, size_t N>
  78. constexpr size_t size(const T (&array)[N]) noexcept {
  79. return N;
  80. }
  81. // C++14 implementation of C++17's std::empty():
  82. // http://en.cppreference.com/w/cpp/iterator/empty
  83. template <typename Container>
  84. constexpr auto empty(const Container& c) -> decltype(c.empty()) {
  85. return c.empty();
  86. }
  87. template <typename T, size_t N>
  88. constexpr bool empty(const T (&array)[N]) noexcept {
  89. return false;
  90. }
  91. template <typename T>
  92. constexpr bool empty(std::initializer_list<T> il) noexcept {
  93. return il.size() == 0;
  94. }
  95. // C++14 implementation of C++17's std::data():
  96. // http://en.cppreference.com/w/cpp/iterator/data
  97. template <typename Container>
  98. constexpr auto data(Container& c) -> decltype(c.data()) {
  99. return c.data();
  100. }
  101. // std::basic_string::data() had no mutable overload prior to C++17 [1].
  102. // Hence this overload is provided.
  103. // Note: str[0] is safe even for empty strings, as they are guaranteed to be
  104. // null-terminated [2].
  105. //
  106. // [1] http://en.cppreference.com/w/cpp/string/basic_string/data
  107. // [2] http://en.cppreference.com/w/cpp/string/basic_string/operator_at
  108. template <typename CharT, typename Traits, typename Allocator>
  109. CharT* data(std::basic_string<CharT, Traits, Allocator>& str) {
  110. return std::addressof(str[0]);
  111. }
  112. template <typename Container>
  113. constexpr auto data(const Container& c) -> decltype(c.data()) {
  114. return c.data();
  115. }
  116. template <typename T, size_t N>
  117. constexpr T* data(T (&array)[N]) noexcept {
  118. return array;
  119. }
  120. template <typename T>
  121. constexpr const T* data(std::initializer_list<T> il) noexcept {
  122. return il.begin();
  123. }
  124. // std::array::data() was not constexpr prior to C++17 [1].
  125. // Hence these overloads are provided.
  126. //
  127. // [1] https://en.cppreference.com/w/cpp/container/array/data
  128. template <typename T, size_t N>
  129. constexpr T* data(std::array<T, N>& array) noexcept {
  130. return !array.empty() ? &array[0] : nullptr;
  131. }
  132. template <typename T, size_t N>
  133. constexpr const T* data(const std::array<T, N>& array) noexcept {
  134. return !array.empty() ? &array[0] : nullptr;
  135. }
  136. // C++14 implementation of C++17's std::as_const():
  137. // https://en.cppreference.com/w/cpp/utility/as_const
  138. template <typename T>
  139. constexpr std::add_const_t<T>& as_const(T& t) noexcept {
  140. return t;
  141. }
  142. template <typename T>
  143. void as_const(const T&& t) = delete;
  144. namespace internal {
  145. // Helper struct and alias to deduce the class type from a member function
  146. // pointer or member object pointer.
  147. template <typename DecayedF>
  148. struct member_pointer_class {};
  149. template <typename ReturnT, typename ClassT>
  150. struct member_pointer_class<ReturnT ClassT::*> {
  151. using type = ClassT;
  152. };
  153. template <typename DecayedF>
  154. using member_pointer_class_t = typename member_pointer_class<DecayedF>::type;
  155. // Utility struct to detect specializations of std::reference_wrapper.
  156. template <typename T>
  157. struct is_reference_wrapper : std::false_type {};
  158. template <typename T>
  159. struct is_reference_wrapper<std::reference_wrapper<T>> : std::true_type {};
  160. // Small helpers used below in internal::invoke to make the SFINAE more concise.
  161. template <typename F>
  162. const bool& IsMemFunPtr =
  163. std::is_member_function_pointer<std::decay_t<F>>::value;
  164. template <typename F>
  165. const bool& IsMemObjPtr = std::is_member_object_pointer<std::decay_t<F>>::value;
  166. template <typename F,
  167. typename T,
  168. typename MemPtrClass = member_pointer_class_t<std::decay_t<F>>>
  169. const bool& IsMemPtrToBaseOf =
  170. std::is_base_of<MemPtrClass, std::decay_t<T>>::value;
  171. template <typename T>
  172. const bool& IsRefWrapper = is_reference_wrapper<std::decay_t<T>>::value;
  173. template <bool B>
  174. using EnableIf = std::enable_if_t<B, bool>;
  175. // Invokes a member function pointer on a reference to an object of a suitable
  176. // type. Covers bullet 1 of the INVOKE definition.
  177. //
  178. // Reference: https://wg21.link/func.require#1.1
  179. template <typename F,
  180. typename T1,
  181. typename... Args,
  182. EnableIf<IsMemFunPtr<F> && IsMemPtrToBaseOf<F, T1>> = true>
  183. constexpr decltype(auto) invoke(F&& f, T1&& t1, Args&&... args) {
  184. return (std::forward<T1>(t1).*f)(std::forward<Args>(args)...);
  185. }
  186. // Invokes a member function pointer on a std::reference_wrapper to an object of
  187. // a suitable type. Covers bullet 2 of the INVOKE definition.
  188. //
  189. // Reference: https://wg21.link/func.require#1.2
  190. template <typename F,
  191. typename T1,
  192. typename... Args,
  193. EnableIf<IsMemFunPtr<F> && IsRefWrapper<T1>> = true>
  194. constexpr decltype(auto) invoke(F&& f, T1&& t1, Args&&... args) {
  195. return (t1.get().*f)(std::forward<Args>(args)...);
  196. }
  197. // Invokes a member function pointer on a pointer-like type to an object of a
  198. // suitable type. Covers bullet 3 of the INVOKE definition.
  199. //
  200. // Reference: https://wg21.link/func.require#1.3
  201. template <typename F,
  202. typename T1,
  203. typename... Args,
  204. EnableIf<IsMemFunPtr<F> && !IsMemPtrToBaseOf<F, T1> &&
  205. !IsRefWrapper<T1>> = true>
  206. constexpr decltype(auto) invoke(F&& f, T1&& t1, Args&&... args) {
  207. return ((*std::forward<T1>(t1)).*f)(std::forward<Args>(args)...);
  208. }
  209. // Invokes a member object pointer on a reference to an object of a suitable
  210. // type. Covers bullet 4 of the INVOKE definition.
  211. //
  212. // Reference: https://wg21.link/func.require#1.4
  213. template <typename F,
  214. typename T1,
  215. EnableIf<IsMemObjPtr<F> && IsMemPtrToBaseOf<F, T1>> = true>
  216. constexpr decltype(auto) invoke(F&& f, T1&& t1) {
  217. return std::forward<T1>(t1).*f;
  218. }
  219. // Invokes a member object pointer on a std::reference_wrapper to an object of
  220. // a suitable type. Covers bullet 5 of the INVOKE definition.
  221. //
  222. // Reference: https://wg21.link/func.require#1.5
  223. template <typename F,
  224. typename T1,
  225. EnableIf<IsMemObjPtr<F> && IsRefWrapper<T1>> = true>
  226. constexpr decltype(auto) invoke(F&& f, T1&& t1) {
  227. return t1.get().*f;
  228. }
  229. // Invokes a member object pointer on a pointer-like type to an object of a
  230. // suitable type. Covers bullet 6 of the INVOKE definition.
  231. //
  232. // Reference: https://wg21.link/func.require#1.6
  233. template <typename F,
  234. typename T1,
  235. EnableIf<IsMemObjPtr<F> && !IsMemPtrToBaseOf<F, T1> &&
  236. !IsRefWrapper<T1>> = true>
  237. constexpr decltype(auto) invoke(F&& f, T1&& t1) {
  238. return (*std::forward<T1>(t1)).*f;
  239. }
  240. // Invokes a regular function or function object. Covers bullet 7 of the INVOKE
  241. // definition.
  242. //
  243. // Reference: https://wg21.link/func.require#1.7
  244. template <typename F, typename... Args>
  245. constexpr decltype(auto) invoke(F&& f, Args&&... args) {
  246. return std::forward<F>(f)(std::forward<Args>(args)...);
  247. }
  248. } // namespace internal
  249. // Implementation of C++17's std::invoke. This is not based on implementation
  250. // referenced in original std::invoke proposal, but rather a manual
  251. // implementation, so that it can be constexpr.
  252. //
  253. // References:
  254. // - https://wg21.link/n4169#implementability
  255. // - https://en.cppreference.com/w/cpp/utility/functional/invoke
  256. // - https://wg21.link/func.invoke
  257. template <typename F, typename... Args>
  258. constexpr decltype(auto) invoke(F&& f, Args&&... args) {
  259. return internal::invoke(std::forward<F>(f), std::forward<Args>(args)...);
  260. }
  261. // Implementation of C++20's std::identity.
  262. //
  263. // Reference:
  264. // - https://en.cppreference.com/w/cpp/utility/functional/identity
  265. // - https://wg21.link/func.identity
  266. struct identity {
  267. template <typename T>
  268. constexpr T&& operator()(T&& t) const noexcept {
  269. return std::forward<T>(t);
  270. }
  271. using is_transparent = void;
  272. };
  273. // Returns a const reference to the underlying container of a container adapter.
  274. // Works for std::priority_queue, std::queue, and std::stack.
  275. template <class A>
  276. const typename A::container_type& GetUnderlyingContainer(const A& adapter) {
  277. struct ExposedAdapter : A {
  278. using A::c;
  279. };
  280. return adapter.*&ExposedAdapter::c;
  281. }
  282. // Clears internal memory of an STL object.
  283. // STL clear()/reserve(0) does not always free internal memory allocated
  284. // This function uses swap/destructor to ensure the internal memory is freed.
  285. template<class T>
  286. void STLClearObject(T* obj) {
  287. T tmp;
  288. tmp.swap(*obj);
  289. // Sometimes "T tmp" allocates objects with memory (arena implementation?).
  290. // Hence using additional reserve(0) even if it doesn't always work.
  291. obj->reserve(0);
  292. }
  293. // Counts the number of instances of val in a container.
  294. template <typename Container, typename T>
  295. typename std::iterator_traits<
  296. typename Container::const_iterator>::difference_type
  297. STLCount(const Container& container, const T& val) {
  298. return std::count(container.begin(), container.end(), val);
  299. }
  300. // General purpose implementation to check if |container| contains |value|.
  301. template <typename Container,
  302. typename Value,
  303. std::enable_if_t<
  304. !internal::HasFindWithNpos<Container, Value>::value &&
  305. !internal::HasFindWithEnd<Container, Value>::value &&
  306. !internal::HasContains<Container, Value>::value>* = nullptr>
  307. bool Contains(const Container& container, const Value& value) {
  308. using std::begin;
  309. using std::end;
  310. return std::find(begin(container), end(container), value) != end(container);
  311. }
  312. // Specialized Contains() implementation for when |container| has a find()
  313. // member function and a static npos member, but no contains() member function.
  314. template <typename Container,
  315. typename Value,
  316. std::enable_if_t<internal::HasFindWithNpos<Container, Value>::value &&
  317. !internal::HasContains<Container, Value>::value>* =
  318. nullptr>
  319. bool Contains(const Container& container, const Value& value) {
  320. return container.find(value) != Container::npos;
  321. }
  322. // Specialized Contains() implementation for when |container| has a find()
  323. // and end() member function, but no contains() member function.
  324. template <typename Container,
  325. typename Value,
  326. std::enable_if_t<internal::HasFindWithEnd<Container, Value>::value &&
  327. !internal::HasContains<Container, Value>::value>* =
  328. nullptr>
  329. bool Contains(const Container& container, const Value& value) {
  330. return container.find(value) != container.end();
  331. }
  332. // Specialized Contains() implementation for when |container| has a contains()
  333. // member function.
  334. template <
  335. typename Container,
  336. typename Value,
  337. std::enable_if_t<internal::HasContains<Container, Value>::value>* = nullptr>
  338. bool Contains(const Container& container, const Value& value) {
  339. return container.contains(value);
  340. }
  341. // O(1) implementation of const casting an iterator for any sequence,
  342. // associative or unordered associative container in the STL.
  343. //
  344. // Reference: https://stackoverflow.com/a/10669041
  345. template <typename Container,
  346. typename ConstIter,
  347. std::enable_if_t<!internal::IsRandomAccessIter<ConstIter>>* = nullptr>
  348. constexpr auto ConstCastIterator(Container& c, ConstIter it) {
  349. return c.erase(it, it);
  350. }
  351. // Explicit overload for std::forward_list where erase() is named erase_after().
  352. template <typename T, typename Allocator>
  353. constexpr auto ConstCastIterator(
  354. std::forward_list<T, Allocator>& c,
  355. typename std::forward_list<T, Allocator>::const_iterator it) {
  356. // The erase_after(it, it) trick used below does not work for libstdc++ [1],
  357. // thus we need a different way.
  358. // TODO(crbug.com/972541): Remove this workaround once libstdc++ is fixed on all
  359. // platforms.
  360. //
  361. // [1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90857
  362. #if defined(__GLIBCXX__)
  363. return c.insert_after(it, {});
  364. #else
  365. return c.erase_after(it, it);
  366. #endif
  367. }
  368. // Specialized O(1) const casting for random access iterators. This is
  369. // necessary, because erase() is either not available (e.g. array-like
  370. // containers), or has O(n) complexity (e.g. std::deque or std::vector).
  371. template <typename Container,
  372. typename ConstIter,
  373. std::enable_if_t<internal::IsRandomAccessIter<ConstIter>>* = nullptr>
  374. constexpr auto ConstCastIterator(Container& c, ConstIter it) {
  375. using std::begin;
  376. using std::cbegin;
  377. return begin(c) + (it - cbegin(c));
  378. }
  379. namespace internal {
  380. template <typename Map, typename Key, typename Value>
  381. std::pair<typename Map::iterator, bool> InsertOrAssignImpl(Map& map,
  382. Key&& key,
  383. Value&& value) {
  384. auto lower = map.lower_bound(key);
  385. if (lower != map.end() && !map.key_comp()(key, lower->first)) {
  386. // key already exists, perform assignment.
  387. lower->second = std::forward<Value>(value);
  388. return {lower, false};
  389. }
  390. // key did not yet exist, insert it.
  391. return {map.emplace_hint(lower, std::forward<Key>(key),
  392. std::forward<Value>(value)),
  393. true};
  394. }
  395. template <typename Map, typename Key, typename Value>
  396. typename Map::iterator InsertOrAssignImpl(Map& map,
  397. typename Map::const_iterator hint,
  398. Key&& key,
  399. Value&& value) {
  400. auto&& key_comp = map.key_comp();
  401. if ((hint == map.begin() || key_comp(std::prev(hint)->first, key))) {
  402. if (hint == map.end() || key_comp(key, hint->first)) {
  403. // *(hint - 1) < key < *hint => key did not exist and hint is correct.
  404. return map.emplace_hint(hint, std::forward<Key>(key),
  405. std::forward<Value>(value));
  406. }
  407. if (!key_comp(hint->first, key)) {
  408. // key == *hint => key already exists and hint is correct.
  409. auto mutable_hint = ConstCastIterator(map, hint);
  410. mutable_hint->second = std::forward<Value>(value);
  411. return mutable_hint;
  412. }
  413. }
  414. // hint was not helpful, dispatch to hintless version.
  415. return InsertOrAssignImpl(map, std::forward<Key>(key),
  416. std::forward<Value>(value))
  417. .first;
  418. }
  419. template <typename Map, typename Key, typename... Args>
  420. std::pair<typename Map::iterator, bool> TryEmplaceImpl(Map& map,
  421. Key&& key,
  422. Args&&... args) {
  423. auto lower = map.lower_bound(key);
  424. if (lower != map.end() && !map.key_comp()(key, lower->first)) {
  425. // key already exists, do nothing.
  426. return {lower, false};
  427. }
  428. // key did not yet exist, insert it.
  429. return {map.emplace_hint(lower, std::piecewise_construct,
  430. std::forward_as_tuple(std::forward<Key>(key)),
  431. std::forward_as_tuple(std::forward<Args>(args)...)),
  432. true};
  433. }
  434. template <typename Map, typename Key, typename... Args>
  435. typename Map::iterator TryEmplaceImpl(Map& map,
  436. typename Map::const_iterator hint,
  437. Key&& key,
  438. Args&&... args) {
  439. auto&& key_comp = map.key_comp();
  440. if ((hint == map.begin() || key_comp(std::prev(hint)->first, key))) {
  441. if (hint == map.end() || key_comp(key, hint->first)) {
  442. // *(hint - 1) < key < *hint => key did not exist and hint is correct.
  443. return map.emplace_hint(
  444. hint, std::piecewise_construct,
  445. std::forward_as_tuple(std::forward<Key>(key)),
  446. std::forward_as_tuple(std::forward<Args>(args)...));
  447. }
  448. if (!key_comp(hint->first, key)) {
  449. // key == *hint => no-op, return correct hint.
  450. return ConstCastIterator(map, hint);
  451. }
  452. }
  453. // hint was not helpful, dispatch to hintless version.
  454. return TryEmplaceImpl(map, std::forward<Key>(key),
  455. std::forward<Args>(args)...)
  456. .first;
  457. }
  458. } // namespace internal
  459. // Implementation of C++17's std::map::insert_or_assign as a free function.
  460. template <typename Map, typename Value>
  461. std::pair<typename Map::iterator, bool>
  462. InsertOrAssign(Map& map, const typename Map::key_type& key, Value&& value) {
  463. return internal::InsertOrAssignImpl(map, key, std::forward<Value>(value));
  464. }
  465. template <typename Map, typename Value>
  466. std::pair<typename Map::iterator, bool>
  467. InsertOrAssign(Map& map, typename Map::key_type&& key, Value&& value) {
  468. return internal::InsertOrAssignImpl(map, std::move(key),
  469. std::forward<Value>(value));
  470. }
  471. // Implementation of C++17's std::map::insert_or_assign with hint as a free
  472. // function.
  473. template <typename Map, typename Value>
  474. typename Map::iterator InsertOrAssign(Map& map,
  475. typename Map::const_iterator hint,
  476. const typename Map::key_type& key,
  477. Value&& value) {
  478. return internal::InsertOrAssignImpl(map, hint, key,
  479. std::forward<Value>(value));
  480. }
  481. template <typename Map, typename Value>
  482. typename Map::iterator InsertOrAssign(Map& map,
  483. typename Map::const_iterator hint,
  484. typename Map::key_type&& key,
  485. Value&& value) {
  486. return internal::InsertOrAssignImpl(map, hint, std::move(key),
  487. std::forward<Value>(value));
  488. }
  489. // Implementation of C++17's std::map::try_emplace as a free function.
  490. template <typename Map, typename... Args>
  491. std::pair<typename Map::iterator, bool>
  492. TryEmplace(Map& map, const typename Map::key_type& key, Args&&... args) {
  493. return internal::TryEmplaceImpl(map, key, std::forward<Args>(args)...);
  494. }
  495. template <typename Map, typename... Args>
  496. std::pair<typename Map::iterator, bool> TryEmplace(Map& map,
  497. typename Map::key_type&& key,
  498. Args&&... args) {
  499. return internal::TryEmplaceImpl(map, std::move(key),
  500. std::forward<Args>(args)...);
  501. }
  502. // Implementation of C++17's std::map::try_emplace with hint as a free
  503. // function.
  504. template <typename Map, typename... Args>
  505. typename Map::iterator TryEmplace(Map& map,
  506. typename Map::const_iterator hint,
  507. const typename Map::key_type& key,
  508. Args&&... args) {
  509. return internal::TryEmplaceImpl(map, hint, key, std::forward<Args>(args)...);
  510. }
  511. template <typename Map, typename... Args>
  512. typename Map::iterator TryEmplace(Map& map,
  513. typename Map::const_iterator hint,
  514. typename Map::key_type&& key,
  515. Args&&... args) {
  516. return internal::TryEmplaceImpl(map, hint, std::move(key),
  517. std::forward<Args>(args)...);
  518. }
  519. // Returns true if the container is sorted. Requires constexpr std::begin/end,
  520. // which exists for arrays in C++14.
  521. // Note that std::is_sorted is constexpr beginning C++20 and this should be
  522. // switched to use it when C++20 is supported.
  523. template <typename Container>
  524. constexpr bool STLIsSorted(const Container& cont) {
  525. auto it = std::begin(cont);
  526. const auto end = std::end(cont);
  527. if (it == end)
  528. return true;
  529. for (auto prev = it++; it != end; prev = it++) {
  530. if (*it < *prev)
  531. return false;
  532. }
  533. return true;
  534. }
  535. // Returns a new ResultType containing the difference of two sorted containers.
  536. template <typename ResultType, typename Arg1, typename Arg2>
  537. ResultType STLSetDifference(const Arg1& a1, const Arg2& a2) {
  538. DCHECK(STLIsSorted(a1));
  539. DCHECK(STLIsSorted(a2));
  540. ResultType difference;
  541. std::set_difference(a1.begin(), a1.end(),
  542. a2.begin(), a2.end(),
  543. std::inserter(difference, difference.end()));
  544. return difference;
  545. }
  546. // Returns a new ResultType containing the union of two sorted containers.
  547. template <typename ResultType, typename Arg1, typename Arg2>
  548. ResultType STLSetUnion(const Arg1& a1, const Arg2& a2) {
  549. DCHECK(STLIsSorted(a1));
  550. DCHECK(STLIsSorted(a2));
  551. ResultType result;
  552. std::set_union(a1.begin(), a1.end(),
  553. a2.begin(), a2.end(),
  554. std::inserter(result, result.end()));
  555. return result;
  556. }
  557. // Returns a new ResultType containing the intersection of two sorted
  558. // containers.
  559. template <typename ResultType, typename Arg1, typename Arg2>
  560. ResultType STLSetIntersection(const Arg1& a1, const Arg2& a2) {
  561. DCHECK(STLIsSorted(a1));
  562. DCHECK(STLIsSorted(a2));
  563. ResultType result;
  564. std::set_intersection(a1.begin(), a1.end(),
  565. a2.begin(), a2.end(),
  566. std::inserter(result, result.end()));
  567. return result;
  568. }
  569. // Returns true if the sorted container |a1| contains all elements of the sorted
  570. // container |a2|.
  571. template <typename Arg1, typename Arg2>
  572. bool STLIncludes(const Arg1& a1, const Arg2& a2) {
  573. DCHECK(STLIsSorted(a1));
  574. DCHECK(STLIsSorted(a2));
  575. return std::includes(a1.begin(), a1.end(),
  576. a2.begin(), a2.end());
  577. }
  578. // Erase/EraseIf are based on C++20's uniform container erasure API:
  579. // - https://eel.is/c++draft/libraryindex#:erase
  580. // - https://eel.is/c++draft/libraryindex#:erase_if
  581. // They provide a generic way to erase elements from a container.
  582. // The functions here implement these for the standard containers until those
  583. // functions are available in the C++ standard.
  584. // For Chromium containers overloads should be defined in their own headers
  585. // (like standard containers).
  586. // Note: there is no std::erase for standard associative containers so we don't
  587. // have it either.
  588. template <typename CharT, typename Traits, typename Allocator, typename Value>
  589. size_t Erase(std::basic_string<CharT, Traits, Allocator>& container,
  590. const Value& value) {
  591. auto it = std::remove(container.begin(), container.end(), value);
  592. size_t removed = std::distance(it, container.end());
  593. container.erase(it, container.end());
  594. return removed;
  595. }
  596. template <typename CharT, typename Traits, typename Allocator, class Predicate>
  597. size_t EraseIf(std::basic_string<CharT, Traits, Allocator>& container,
  598. Predicate pred) {
  599. auto it = std::remove_if(container.begin(), container.end(), pred);
  600. size_t removed = std::distance(it, container.end());
  601. container.erase(it, container.end());
  602. return removed;
  603. }
  604. template <class T, class Allocator, class Value>
  605. size_t Erase(std::deque<T, Allocator>& container, const Value& value) {
  606. auto it = std::remove(container.begin(), container.end(), value);
  607. size_t removed = std::distance(it, container.end());
  608. container.erase(it, container.end());
  609. return removed;
  610. }
  611. template <class T, class Allocator, class Predicate>
  612. size_t EraseIf(std::deque<T, Allocator>& container, Predicate pred) {
  613. auto it = std::remove_if(container.begin(), container.end(), pred);
  614. size_t removed = std::distance(it, container.end());
  615. container.erase(it, container.end());
  616. return removed;
  617. }
  618. template <class T, class Allocator, class Value>
  619. size_t Erase(std::vector<T, Allocator>& container, const Value& value) {
  620. auto it = std::remove(container.begin(), container.end(), value);
  621. size_t removed = std::distance(it, container.end());
  622. container.erase(it, container.end());
  623. return removed;
  624. }
  625. template <class T, class Allocator, class Predicate>
  626. size_t EraseIf(std::vector<T, Allocator>& container, Predicate pred) {
  627. auto it = std::remove_if(container.begin(), container.end(), pred);
  628. size_t removed = std::distance(it, container.end());
  629. container.erase(it, container.end());
  630. return removed;
  631. }
  632. template <class T, class Allocator, class Predicate>
  633. size_t EraseIf(std::forward_list<T, Allocator>& container, Predicate pred) {
  634. // Note: std::forward_list does not have a size() API, thus we need to use the
  635. // O(n) std::distance work-around. However, given that EraseIf is O(n)
  636. // already, this should not make a big difference.
  637. size_t old_size = std::distance(container.begin(), container.end());
  638. container.remove_if(pred);
  639. return old_size - std::distance(container.begin(), container.end());
  640. }
  641. template <class T, class Allocator, class Predicate>
  642. size_t EraseIf(std::list<T, Allocator>& container, Predicate pred) {
  643. size_t old_size = container.size();
  644. container.remove_if(pred);
  645. return old_size - container.size();
  646. }
  647. template <class Key, class T, class Compare, class Allocator, class Predicate>
  648. size_t EraseIf(std::map<Key, T, Compare, Allocator>& container,
  649. Predicate pred) {
  650. return internal::IterateAndEraseIf(container, pred);
  651. }
  652. template <class Key, class T, class Compare, class Allocator, class Predicate>
  653. size_t EraseIf(std::multimap<Key, T, Compare, Allocator>& container,
  654. Predicate pred) {
  655. return internal::IterateAndEraseIf(container, pred);
  656. }
  657. template <class Key, class Compare, class Allocator, class Predicate>
  658. size_t EraseIf(std::set<Key, Compare, Allocator>& container, Predicate pred) {
  659. return internal::IterateAndEraseIf(container, pred);
  660. }
  661. template <class Key, class Compare, class Allocator, class Predicate>
  662. size_t EraseIf(std::multiset<Key, Compare, Allocator>& container,
  663. Predicate pred) {
  664. return internal::IterateAndEraseIf(container, pred);
  665. }
  666. template <class Key,
  667. class T,
  668. class Hash,
  669. class KeyEqual,
  670. class Allocator,
  671. class Predicate>
  672. size_t EraseIf(std::unordered_map<Key, T, Hash, KeyEqual, Allocator>& container,
  673. Predicate pred) {
  674. return internal::IterateAndEraseIf(container, pred);
  675. }
  676. template <class Key,
  677. class T,
  678. class Hash,
  679. class KeyEqual,
  680. class Allocator,
  681. class Predicate>
  682. size_t EraseIf(
  683. std::unordered_multimap<Key, T, Hash, KeyEqual, Allocator>& container,
  684. Predicate pred) {
  685. return internal::IterateAndEraseIf(container, pred);
  686. }
  687. template <class Key,
  688. class Hash,
  689. class KeyEqual,
  690. class Allocator,
  691. class Predicate>
  692. size_t EraseIf(std::unordered_set<Key, Hash, KeyEqual, Allocator>& container,
  693. Predicate pred) {
  694. return internal::IterateAndEraseIf(container, pred);
  695. }
  696. template <class Key,
  697. class Hash,
  698. class KeyEqual,
  699. class Allocator,
  700. class Predicate>
  701. size_t EraseIf(
  702. std::unordered_multiset<Key, Hash, KeyEqual, Allocator>& container,
  703. Predicate pred) {
  704. return internal::IterateAndEraseIf(container, pred);
  705. }
  706. template <class T, class Allocator, class Value>
  707. size_t Erase(std::forward_list<T, Allocator>& container, const Value& value) {
  708. // Unlike std::forward_list::remove, this function template accepts
  709. // heterogeneous types and does not force a conversion to the container's
  710. // value type before invoking the == operator.
  711. return EraseIf(container, [&](const T& cur) { return cur == value; });
  712. }
  713. template <class T, class Allocator, class Value>
  714. size_t Erase(std::list<T, Allocator>& container, const Value& value) {
  715. // Unlike std::list::remove, this function template accepts heterogeneous
  716. // types and does not force a conversion to the container's value type before
  717. // invoking the == operator.
  718. return EraseIf(container, [&](const T& cur) { return cur == value; });
  719. }
  720. // A helper class to be used as the predicate with |EraseIf| to implement
  721. // in-place set intersection. Helps implement the algorithm of going through
  722. // each container an element at a time, erasing elements from the first
  723. // container if they aren't in the second container. Requires each container be
  724. // sorted. Note that the logic below appears inverted since it is returning
  725. // whether an element should be erased.
  726. template <class Collection>
  727. class IsNotIn {
  728. public:
  729. explicit IsNotIn(const Collection& collection)
  730. : i_(collection.begin()), end_(collection.end()) {}
  731. bool operator()(const typename Collection::value_type& x) {
  732. while (i_ != end_ && *i_ < x)
  733. ++i_;
  734. if (i_ == end_)
  735. return true;
  736. if (*i_ == x) {
  737. ++i_;
  738. return false;
  739. }
  740. return true;
  741. }
  742. private:
  743. typename Collection::const_iterator i_;
  744. const typename Collection::const_iterator end_;
  745. };
  746. // Helper for returning the optional value's address, or nullptr.
  747. template <class T>
  748. T* OptionalOrNullptr(base::Optional<T>& optional) {
  749. return optional.has_value() ? &optional.value() : nullptr;
  750. }
  751. template <class T>
  752. const T* OptionalOrNullptr(const base::Optional<T>& optional) {
  753. return optional.has_value() ? &optional.value() : nullptr;
  754. }
  755. // Helper for creating an Optional<T> from a potentially nullptr T*.
  756. template <class T>
  757. base::Optional<T> OptionalFromPtr(const T* value) {
  758. if (value)
  759. return base::Optional<T>(*value);
  760. return base::nullopt;
  761. }
  762. } // namespace base
  763. #endif // BASE_STL_UTIL_H_