xref: /aosp_15_r20/external/cronet/base/containers/to_value_list.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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_VALUE_LIST_H_
6 #define BASE_CONTAINERS_TO_VALUE_LIST_H_
7 
8 #include <concepts>
9 #include <functional>
10 #include <iterator>
11 #include <type_traits>
12 #include <utility>
13 
14 #include "base/ranges/algorithm.h"
15 #include "base/ranges/ranges.h"
16 #include "base/values.h"
17 
18 namespace base {
19 
20 namespace internal {
21 template <typename T>
22 concept AppendableToValueList =
requires(T && value)23     requires(T&& value) { Value::List().Append(std::forward<T>(value)); };
24 }  // namespace internal
25 
26 // Maps a container to a Value::List with respect to the provided projection.
27 //
28 // Complexity: Exactly `size(range)` applications of `proj`.
29 template <typename Range, typename Proj = std::identity>
30   requires requires { typename internal::range_category_t<Range>; } &&
31            std::indirectly_unary_invocable<Proj, ranges::iterator_t<Range>> &&
32            internal::AppendableToValueList<
33                std::indirect_result_t<Proj, ranges::iterator_t<Range>>>
34 Value::List ToValueList(Range&& range, Proj proj = {}) {
35   auto container = Value::List::with_capacity(std::size(range));
36   ranges::for_each(
37       std::forward<Range>(range),
38       [&]<typename T>(T&& value) { container.Append(std::forward<T>(value)); },
39       std::move(proj));
40   return container;
41 }
42 
43 }  // namespace base
44 
45 #endif  // BASE_CONTAINERS_TO_VALUE_LIST_H_
46