diff options
author | 2022-08-03 12:58:28 -0700 | |
---|---|---|
committer | 2022-09-01 08:52:57 -0700 | |
commit | e6c5e6e6c7b387a487cf9088bd4f86cd6f5dc644 (patch) | |
tree | 79c6148e1103ad527fe8283e3d9d9c3be18f8563 /include/ftl | |
parent | cc7f1ece12e6b982ccb0d46a07a04af43dee6144 (diff) |
FTL: Add find_if
Bug: 185536303
Test: ftl_test
Change-Id: I16b63d63da181c7f79d62af9d7a91639342d8c95
Diffstat (limited to 'include/ftl')
-rw-r--r-- | include/ftl/algorithm.h | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/include/ftl/algorithm.h b/include/ftl/algorithm.h new file mode 100644 index 0000000000..c5ff03b80d --- /dev/null +++ b/include/ftl/algorithm.h @@ -0,0 +1,71 @@ +/* + * Copyright 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include <algorithm> +#include <functional> +#include <utility> + +#include <ftl/optional.h> + +namespace android::ftl { + +// Adapter for std::find_if that converts the return value from iterator to optional. +// +// const ftl::StaticVector vector = {"upside"sv, "down"sv, "cake"sv}; +// assert(ftl::find_if(vector, [](const auto& str) { return str.front() == 'c'; }) == "cake"sv); +// +template <typename Container, typename Predicate, typename V = typename Container::value_type> +constexpr auto find_if(const Container& container, Predicate&& predicate) + -> Optional<std::reference_wrapper<const V>> { + const auto it = std::find_if(std::cbegin(container), std::cend(container), + std::forward<Predicate>(predicate)); + if (it == std::cend(container)) return {}; + return std::cref(*it); +} + +// Transformers for ftl::find_if on a map-like `Container` that contains key-value pairs. +// +// const ftl::SmallMap map = ftl::init::map<int, ftl::StaticVector<std::string_view, 3>>( +// 12, "snow"sv, "cone"sv)(13, "tiramisu"sv)(14, "upside"sv, "down"sv, "cake"sv); +// +// using Map = decltype(map); +// +// assert(14 == ftl::find_if(map, [](const auto& pair) { +// return pair.second.size() == 3; +// }).transform(ftl::to_key<Map>)); +// +// const auto opt = ftl::find_if(map, [](const auto& pair) { +// return pair.second.size() == 1; +// }).transform(ftl::to_mapped_ref<Map>); +// +// assert(opt); +// assert(opt->get() == ftl::StaticVector("tiramisu"sv)); +// +template <typename Map, typename Pair = typename Map::value_type, + typename Key = typename Map::key_type> +constexpr auto to_key(const Pair& pair) -> Key { + return pair.first; +} + +template <typename Map, typename Pair = typename Map::value_type, + typename Mapped = typename Map::mapped_type> +constexpr auto to_mapped_ref(const Pair& pair) -> std::reference_wrapper<const Mapped> { + return std::cref(pair.second); +} + +} // namespace android::ftl |