1 // Copyright 2024 The Chromium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef BASE_CONTAINERS_TO_VECTOR_H_ 6 #define BASE_CONTAINERS_TO_VECTOR_H_ 7 8 #include <functional> 9 #include <iterator> 10 #include <type_traits> 11 #include <utility> 12 #include <vector> 13 14 #include "base/ranges/algorithm.h" 15 #include "base/ranges/ranges.h" 16 17 namespace base { 18 19 // Maps a container to a std::vector<> with respect to the provided projection. 20 // The deduced vector element type is equal to the projection's return type with 21 // cv-qualifiers removed. 22 // 23 // In C++20 this is roughly equal to: 24 // auto vec = range | std::views:transform(proj) | 25 // std::ranges::to<std::vector>; 26 // 27 // Complexity: Exactly `size(range)` applications of `proj`. 28 template <typename Range, typename Proj = std::identity> 29 requires requires { typename internal::range_category_t<Range>; } && 30 std::indirectly_unary_invocable<Proj, ranges::iterator_t<Range>> 31 auto ToVector(Range&& range, Proj proj = {}) { 32 using ProjectedType = 33 std::projected<ranges::iterator_t<Range>, Proj>::value_type; 34 std::vector<ProjectedType> container; 35 container.reserve(std::size(range)); 36 ranges::transform(std::forward<Range>(range), std::back_inserter(container), 37 std::move(proj)); 38 return container; 39 } 40 41 } // namespace base 42 43 #endif // BASE_CONTAINERS_TO_VECTOR_H_ 44