mirror of
https://github.com/mii443/mozc.git
synced 2025-08-22 16:15:46 +00:00
Introduce constexpr flat containers.
These containers offer `constexpr` construction, by creating a sorted array at compile time, and provide read-only lookup of values. They have a very minimal API surface, sufficient for Mozc's use, and deliberately diverge from the standard STL API for simplicity. * `FlatSet` has `bool contains(K)`: The standard C++ interface for sets. * `FlatMap` has `const T* FindOrNull(K)`, not `iterator find(K)`: No iterator involved. * `FlatMultiMap` has `absl::Span<const Entry<K, V>> EqualSpan(K)`, not `pair<iterator, iterator> equal_range(K)`: No iterator, or no `std::pair` that lacks necessary `constexpr` support (yet). These are meant for replacing patterns like `const auto *map = new std::map<...>(...)` in the codebase, reducing runtime startup work and eliminating leaked heap allocations, which is particularly important when linked in the Windows DLL. PiperOrigin-RevId: 729741608
This commit is contained in:
committed by
Hiroyuki Komatsu
parent
f215eaf71a
commit
992b1f49f1
@ -53,6 +53,80 @@ mozc_cc_test(
|
|||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
mozc_cc_library(
|
||||||
|
name = "entry",
|
||||||
|
hdrs = ["entry.h"],
|
||||||
|
)
|
||||||
|
|
||||||
|
mozc_cc_library(
|
||||||
|
name = "flat_internal",
|
||||||
|
hdrs = ["flat_internal.h"],
|
||||||
|
deps = [
|
||||||
|
"@com_google_absl//absl/log",
|
||||||
|
"@com_google_absl//absl/types:span",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
mozc_cc_library(
|
||||||
|
name = "flat_map",
|
||||||
|
hdrs = ["flat_map.h"],
|
||||||
|
deps = [
|
||||||
|
":entry",
|
||||||
|
":flat_internal",
|
||||||
|
"@com_google_absl//absl/base:nullability",
|
||||||
|
"@com_google_absl//absl/types:span",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
mozc_cc_test(
|
||||||
|
name = "flat_map_test",
|
||||||
|
srcs = ["flat_map_test.cc"],
|
||||||
|
deps = [
|
||||||
|
":flat_map",
|
||||||
|
"//testing:gunit_main",
|
||||||
|
"@com_google_absl//absl/strings",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
mozc_cc_library(
|
||||||
|
name = "flat_multimap",
|
||||||
|
hdrs = ["flat_multimap.h"],
|
||||||
|
deps = [
|
||||||
|
":entry",
|
||||||
|
":flat_internal",
|
||||||
|
"@com_google_absl//absl/types:span",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
mozc_cc_test(
|
||||||
|
name = "flat_multimap_test",
|
||||||
|
srcs = ["flat_multimap_test.cc"],
|
||||||
|
deps = [
|
||||||
|
":flat_multimap",
|
||||||
|
"//testing:gunit_main",
|
||||||
|
"@com_google_absl//absl/strings",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
mozc_cc_library(
|
||||||
|
name = "flat_set",
|
||||||
|
hdrs = ["flat_set.h"],
|
||||||
|
deps = [
|
||||||
|
":flat_internal",
|
||||||
|
"@com_google_absl//absl/types:span",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
mozc_cc_test(
|
||||||
|
name = "flat_set_test",
|
||||||
|
srcs = ["flat_set_test.cc"],
|
||||||
|
deps = [
|
||||||
|
":flat_set",
|
||||||
|
"//testing:gunit_main",
|
||||||
|
"@com_google_absl//absl/strings",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
mozc_cc_library(
|
mozc_cc_library(
|
||||||
name = "freelist",
|
name = "freelist",
|
||||||
hdrs = ["freelist.h"],
|
hdrs = ["freelist.h"],
|
||||||
|
46
src/base/container/entry.h
Normal file
46
src/base/container/entry.h
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
// Copyright 2010-2021, Google Inc.
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
#ifndef MOZC_BASE_CONTAINER_ENTRY_H_
|
||||||
|
#define MOZC_BASE_CONTAINER_ENTRY_H_
|
||||||
|
|
||||||
|
namespace mozc {
|
||||||
|
|
||||||
|
// Represents an entry in a map.
|
||||||
|
//
|
||||||
|
// We need constexpr copy/move, which `std::pair` doesn't get until C++20.
|
||||||
|
template <class K, class V>
|
||||||
|
struct Entry {
|
||||||
|
K key;
|
||||||
|
V value;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace mozc
|
||||||
|
|
||||||
|
#endif // MOZC_BASE_CONTAINER_ENTRY_H_
|
128
src/base/container/flat_internal.h
Normal file
128
src/base/container/flat_internal.h
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
// Copyright 2010-2021, Google Inc.
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
#ifndef MOZC_BASE_CONTAINER_FLAT_INTERNAL_H_
|
||||||
|
#define MOZC_BASE_CONTAINER_FLAT_INTERNAL_H_
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <array>
|
||||||
|
#include <functional>
|
||||||
|
#include <type_traits>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
#include "absl/log/log.h"
|
||||||
|
#include "absl/types/span.h"
|
||||||
|
|
||||||
|
namespace mozc::internal {
|
||||||
|
|
||||||
|
// Sorts the given span in place.
|
||||||
|
// C++17 backport of constexpr `std::sort` from C++20.
|
||||||
|
template <class T, class Compare = std::less<>>
|
||||||
|
constexpr void Sort(absl::Span<T> span, const Compare &cmp = {}) {
|
||||||
|
// Since we're dealing with compile-time constants, expected to be small,
|
||||||
|
// we use insertion sort. It's faster for small inputs, and easier to
|
||||||
|
// implement :)
|
||||||
|
for (int i = 1; i < span.size(); ++i) {
|
||||||
|
if (!cmp(span[i], span[i - 1])) continue;
|
||||||
|
|
||||||
|
T tmp = std::move(span[i]);
|
||||||
|
int j = i;
|
||||||
|
do {
|
||||||
|
span[j] = std::move(span[j - 1]);
|
||||||
|
--j;
|
||||||
|
} while (j > 0 && cmp(tmp, span[j - 1]));
|
||||||
|
span[j] = std::move(tmp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T, size_t N, size_t... I>
|
||||||
|
constexpr std::array<std::remove_cv_t<T>, N> ToArrayImpl(
|
||||||
|
T (&&a)[N], std::index_sequence<I...>) {
|
||||||
|
return {std::move(a[I])...};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Converts a C-style array to a `std::array`.
|
||||||
|
// C++17 backport of `std::to_array` from C++20.
|
||||||
|
template <class T, size_t N>
|
||||||
|
constexpr std::array<std::remove_cv_t<T>, N> ToArray(T (&&a)[N]) {
|
||||||
|
return ToArrayImpl(std::move(a), std::make_index_sequence<N>());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finds the first element satisfying the given predicate, or `span.end()` if
|
||||||
|
// none exists.
|
||||||
|
//
|
||||||
|
// `pred` must be non-decreasing in `span`: if `l <= r`, then
|
||||||
|
// `pred(span[l]) <= pred(span[r])`, where `false < true`.
|
||||||
|
//
|
||||||
|
// NOTE: To use `std::lower_bound`, we'd need an iterator adapter that extracts
|
||||||
|
// the first element of each pair, which would be more code than a custom binary
|
||||||
|
// search.
|
||||||
|
template <class T, class Predicate>
|
||||||
|
constexpr typename absl::Span<const T>::iterator FindFirst(
|
||||||
|
absl::Span<const T> span, Predicate pred) {
|
||||||
|
if (span.empty()) return span.end();
|
||||||
|
if (pred(span.front())) return span.begin();
|
||||||
|
|
||||||
|
// Invariant: `pred(span[l])` is false and `pred(span[r])` is true (virtually
|
||||||
|
// assuming `pred(span[span.size()])` is true). Note that `mid` will never be
|
||||||
|
// `span.size()` (which would be out-of-bound access), because the largest
|
||||||
|
// possible `mid` occurs when `(l, r) = (span.size() - 2, span.size())`,
|
||||||
|
// resulting in `mid = span.size() - 1`.
|
||||||
|
int l = 0;
|
||||||
|
int r = span.size();
|
||||||
|
while (r - l > 1) {
|
||||||
|
int mid = l + (r - l) / 2;
|
||||||
|
(pred(span[mid]) ? r : l) = mid;
|
||||||
|
}
|
||||||
|
|
||||||
|
return span.begin() + r;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Non-constexpr function to be called when a duplicate entry is found, causing
|
||||||
|
// a compile-time error.
|
||||||
|
inline void DuplicateEntryFound() { LOG(FATAL) << "Duplicate entry found"; }
|
||||||
|
|
||||||
|
// Sorts the given span in place, and verifies that the elements are unique
|
||||||
|
// according to `cmp`.
|
||||||
|
template <class T, class Compare = std::less<>>
|
||||||
|
constexpr void SortAndVerifyUnique(absl::Span<T> span,
|
||||||
|
const Compare &cmp = {}) {
|
||||||
|
Sort(span, cmp);
|
||||||
|
for (int i = 0; i + i < span.size(); ++i) {
|
||||||
|
if (!cmp(span[i], span[i + 1]) && !cmp(span[i + 1], span[i])) {
|
||||||
|
DuplicateEntryFound();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace mozc::internal
|
||||||
|
|
||||||
|
#endif // MOZC_BASE_CONTAINER_FLAT_INTERNAL_H_
|
98
src/base/container/flat_map.h
Normal file
98
src/base/container/flat_map.h
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
// Copyright 2010-2021, Google Inc.
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
#ifndef MOZC_BASE_CONTAINER_FLAT_MAP_H_
|
||||||
|
#define MOZC_BASE_CONTAINER_FLAT_MAP_H_
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <array>
|
||||||
|
#include <functional>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
#include "absl/base/nullability.h"
|
||||||
|
#include "absl/types/span.h"
|
||||||
|
#include "base/container/entry.h"
|
||||||
|
#include "base/container/flat_internal.h"
|
||||||
|
|
||||||
|
namespace mozc {
|
||||||
|
|
||||||
|
// Read-only map that is backed by `constexpr`-sorted array.
|
||||||
|
template <class K, class V, class CompareKey, size_t N>
|
||||||
|
class FlatMap {
|
||||||
|
public:
|
||||||
|
// Consider calling `CreateFlatMap` instead, so you don't have to manually
|
||||||
|
// specify the number of entries, `N`.
|
||||||
|
constexpr FlatMap(std::array<Entry<K, V>, N> entries,
|
||||||
|
const CompareKey &cmp_key = {})
|
||||||
|
: entries_(std::move(entries)), cmp_key_(cmp_key) {
|
||||||
|
internal::SortAndVerifyUnique(
|
||||||
|
absl::MakeSpan(entries_),
|
||||||
|
[&](const Entry<K, V> &a, const Entry<K, V> &b) {
|
||||||
|
return cmp_key_(a.key, b.key);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finds the value associated with the given key, or `nullptr` if not found.
|
||||||
|
constexpr absl::Nullable<const V *> FindOrNull(const K &key) const {
|
||||||
|
auto lb = internal::FindFirst(
|
||||||
|
absl::MakeSpan(entries_),
|
||||||
|
[&](const Entry<K, V> &e) { return !cmp_key_(e.key, key); });
|
||||||
|
return lb == entries_.end() || cmp_key_(key, lb->key) ? nullptr
|
||||||
|
: &lb->value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::array<Entry<K, V>, N> entries_;
|
||||||
|
CompareKey cmp_key_;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Creates a `FlatMap` from a C-style array of `Entry`s.
|
||||||
|
//
|
||||||
|
// Example:
|
||||||
|
//
|
||||||
|
// constexpr auto kMap = CreateFlatMap<int, absl::string_view>({
|
||||||
|
// {1, "one"},
|
||||||
|
// {2, "two"},
|
||||||
|
// {3, "three"},
|
||||||
|
// });
|
||||||
|
//
|
||||||
|
// Declare the variable as auto and use `CreateFlatMap`. The actual type is
|
||||||
|
// complex and explicitly declaring it would leak the number of entries, `N`.
|
||||||
|
template <class K, class V, class CompareKey = std::less<>, size_t N>
|
||||||
|
constexpr auto CreateFlatMap(Entry<K, V> (&&entries)[N],
|
||||||
|
const CompareKey &cmp_key = {}) {
|
||||||
|
return FlatMap<K, V, CompareKey, N>(internal::ToArray(std::move(entries)),
|
||||||
|
cmp_key);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace mozc
|
||||||
|
|
||||||
|
#endif // MOZC_BASE_CONTAINER_FLAT_MAP_H_
|
78
src/base/container/flat_map_test.cc
Normal file
78
src/base/container/flat_map_test.cc
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
// Copyright 2010-2021, Google Inc.
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
#include "base/container/flat_map.h"
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
#include "absl/strings/string_view.h"
|
||||||
|
#include "testing/gmock.h"
|
||||||
|
#include "testing/gunit.h"
|
||||||
|
|
||||||
|
namespace mozc {
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
using ::testing::Eq;
|
||||||
|
using ::testing::IsNull;
|
||||||
|
using ::testing::Pointee;
|
||||||
|
|
||||||
|
TEST(FlatMapTest, FindOrNull) {
|
||||||
|
constexpr auto kMap = CreateFlatMap<int, absl::string_view>({
|
||||||
|
{1, "one"},
|
||||||
|
{3, "three"},
|
||||||
|
{5, "five"},
|
||||||
|
});
|
||||||
|
|
||||||
|
EXPECT_THAT(kMap.FindOrNull(0), IsNull());
|
||||||
|
EXPECT_THAT(kMap.FindOrNull(1), Pointee(Eq("one")));
|
||||||
|
EXPECT_THAT(kMap.FindOrNull(2), IsNull());
|
||||||
|
EXPECT_THAT(kMap.FindOrNull(3), Pointee(Eq("three")));
|
||||||
|
EXPECT_THAT(kMap.FindOrNull(4), IsNull());
|
||||||
|
EXPECT_THAT(kMap.FindOrNull(5), Pointee(Eq("five")));
|
||||||
|
EXPECT_THAT(kMap.FindOrNull(6), IsNull());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(FlatMapTest, CustomerCompare) {
|
||||||
|
constexpr auto kMap = CreateFlatMap<int, absl::string_view, std::greater<>>({
|
||||||
|
{1, "one"},
|
||||||
|
{3, "three"},
|
||||||
|
{5, "five"},
|
||||||
|
});
|
||||||
|
|
||||||
|
EXPECT_THAT(kMap.FindOrNull(0), IsNull());
|
||||||
|
EXPECT_THAT(kMap.FindOrNull(1), Pointee(Eq("one")));
|
||||||
|
EXPECT_THAT(kMap.FindOrNull(2), IsNull());
|
||||||
|
EXPECT_THAT(kMap.FindOrNull(3), Pointee(Eq("three")));
|
||||||
|
EXPECT_THAT(kMap.FindOrNull(4), IsNull());
|
||||||
|
EXPECT_THAT(kMap.FindOrNull(5), Pointee(Eq("five")));
|
||||||
|
EXPECT_THAT(kMap.FindOrNull(6), IsNull());
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
} // namespace mozc
|
107
src/base/container/flat_multimap.h
Normal file
107
src/base/container/flat_multimap.h
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
// Copyright 2010-2021, Google Inc.
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
#ifndef MOZC_BASE_CONTAINER_FLAT_MULTIMAP_H_
|
||||||
|
#define MOZC_BASE_CONTAINER_FLAT_MULTIMAP_H_
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <array>
|
||||||
|
#include <functional>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
#include "absl/types/span.h"
|
||||||
|
#include "base/container/entry.h"
|
||||||
|
#include "base/container/flat_internal.h"
|
||||||
|
|
||||||
|
namespace mozc {
|
||||||
|
|
||||||
|
// Read-only multimap that is backed by `constexpr`-sorted array.
|
||||||
|
template <class K, class V, class CompareKey, size_t N>
|
||||||
|
class FlatMultimap {
|
||||||
|
public:
|
||||||
|
// Consider calling `CreateFlatMultimap` instead, so you don't have to
|
||||||
|
// manually specify the number of entries, `N`.
|
||||||
|
constexpr FlatMultimap(std::array<Entry<K, V>, N> entries,
|
||||||
|
const CompareKey &cmp_key = {})
|
||||||
|
: entries_(std::move(entries)), cmp_key_(cmp_key) {
|
||||||
|
internal::Sort(absl::MakeSpan(entries_),
|
||||||
|
[&](const Entry<K, V> &a, const Entry<K, V> &b) {
|
||||||
|
return cmp_key_(a.key, b.key);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns a span of entries with the given key.
|
||||||
|
//
|
||||||
|
// IMPORTANT: The order of the returned span is not guaranteed to be the
|
||||||
|
// same as the order of the entries given when the map was created.
|
||||||
|
//
|
||||||
|
// NOTE: The current implementation actually preserves the order, but this
|
||||||
|
// will change once we switch to `std::sort`, which is not stable (and
|
||||||
|
// `std::stable_sort` is not planned to receive constexpr support).
|
||||||
|
constexpr absl::Span<const Entry<K, V>> EqualSpan(const K &key) const {
|
||||||
|
auto lb = internal::FindFirst(
|
||||||
|
absl::MakeSpan(entries_),
|
||||||
|
[&](const Entry<K, V> &e) { return !cmp_key_(e.key, key); });
|
||||||
|
auto ub = internal::FindFirst(
|
||||||
|
absl::MakeSpan(entries_),
|
||||||
|
[&](const Entry<K, V> &e) { return cmp_key_(key, e.key); });
|
||||||
|
return absl::MakeConstSpan(lb, ub);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::array<Entry<K, V>, N> entries_;
|
||||||
|
CompareKey cmp_key_;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Creates a `FlatMultimap` from a C-style array of `Entry`s.
|
||||||
|
//
|
||||||
|
// Example:
|
||||||
|
//
|
||||||
|
// constexpr auto kMultimap = CreateFlatMultimap<int, absl::string_view>({
|
||||||
|
// {1, "one"},
|
||||||
|
// {1, "ichi"},
|
||||||
|
// {2, "two"},
|
||||||
|
// {2, "ni"},
|
||||||
|
// {3, "three"},
|
||||||
|
// {3, "san"},
|
||||||
|
// });
|
||||||
|
// Declare the variable as auto and use `CreateFlatMultimap`. The actual type is
|
||||||
|
// complex and explicitly declaring it would leak the number of entries, `N`.
|
||||||
|
template <class K, class V, class CompareKey = std::less<>, size_t N>
|
||||||
|
constexpr auto CreateFlatMultimap(Entry<K, V> (&&entries)[N],
|
||||||
|
const CompareKey &cmp_key = {}) {
|
||||||
|
return FlatMultimap<K, V, CompareKey, N>(
|
||||||
|
internal::ToArray(std::move(entries)), cmp_key);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace mozc
|
||||||
|
|
||||||
|
#endif // MOZC_BASE_CONTAINER_FLAT_MULTIMAP_H_
|
98
src/base/container/flat_multimap_test.cc
Normal file
98
src/base/container/flat_multimap_test.cc
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
// Copyright 2010-2021, Google Inc.
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
#include "base/container/flat_multimap.h"
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
#include "absl/strings/string_view.h"
|
||||||
|
#include "testing/gmock.h"
|
||||||
|
#include "testing/gunit.h"
|
||||||
|
|
||||||
|
namespace mozc {
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
using ::testing::Eq;
|
||||||
|
using ::testing::FieldsAre;
|
||||||
|
using ::testing::IsEmpty;
|
||||||
|
using ::testing::UnorderedElementsAre;
|
||||||
|
|
||||||
|
TEST(FlatMultimapTest, EqualSpan) {
|
||||||
|
constexpr auto kMultimap = CreateFlatMultimap<int, absl::string_view>({
|
||||||
|
{1, "one"},
|
||||||
|
{3, "three"},
|
||||||
|
{5, "five"},
|
||||||
|
{1, "ichi"},
|
||||||
|
{3, "san"},
|
||||||
|
{5, "go"},
|
||||||
|
});
|
||||||
|
|
||||||
|
EXPECT_THAT(kMultimap.EqualSpan(0), IsEmpty());
|
||||||
|
EXPECT_THAT(kMultimap.EqualSpan(1),
|
||||||
|
UnorderedElementsAre(FieldsAre(Eq(1), Eq("one")),
|
||||||
|
FieldsAre(Eq(1), Eq("ichi"))));
|
||||||
|
EXPECT_THAT(kMultimap.EqualSpan(2), IsEmpty());
|
||||||
|
EXPECT_THAT(kMultimap.EqualSpan(3),
|
||||||
|
UnorderedElementsAre(FieldsAre(Eq(3), Eq("three")),
|
||||||
|
FieldsAre(Eq(3), Eq("san"))));
|
||||||
|
EXPECT_THAT(kMultimap.EqualSpan(4), IsEmpty());
|
||||||
|
EXPECT_THAT(kMultimap.EqualSpan(5),
|
||||||
|
UnorderedElementsAre(FieldsAre(Eq(5), Eq("five")),
|
||||||
|
FieldsAre(Eq(5), Eq("go"))));
|
||||||
|
EXPECT_THAT(kMultimap.EqualSpan(6), IsEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(FlatMultimapTest, CustomerCompare) {
|
||||||
|
constexpr auto kMultimap =
|
||||||
|
CreateFlatMultimap<int, absl::string_view, std::greater<>>({
|
||||||
|
{1, "one"},
|
||||||
|
{3, "three"},
|
||||||
|
{5, "five"},
|
||||||
|
{1, "ichi"},
|
||||||
|
{3, "san"},
|
||||||
|
{5, "go"},
|
||||||
|
});
|
||||||
|
|
||||||
|
EXPECT_THAT(kMultimap.EqualSpan(0), IsEmpty());
|
||||||
|
EXPECT_THAT(kMultimap.EqualSpan(1),
|
||||||
|
UnorderedElementsAre(FieldsAre(Eq(1), Eq("one")),
|
||||||
|
FieldsAre(Eq(1), Eq("ichi"))));
|
||||||
|
EXPECT_THAT(kMultimap.EqualSpan(2), IsEmpty());
|
||||||
|
EXPECT_THAT(kMultimap.EqualSpan(3),
|
||||||
|
UnorderedElementsAre(FieldsAre(Eq(3), Eq("three")),
|
||||||
|
FieldsAre(Eq(3), Eq("san"))));
|
||||||
|
EXPECT_THAT(kMultimap.EqualSpan(4), IsEmpty());
|
||||||
|
EXPECT_THAT(kMultimap.EqualSpan(5),
|
||||||
|
UnorderedElementsAre(FieldsAre(Eq(5), Eq("five")),
|
||||||
|
FieldsAre(Eq(5), Eq("go"))));
|
||||||
|
EXPECT_THAT(kMultimap.EqualSpan(6), IsEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
} // namespace mozc
|
86
src/base/container/flat_set.h
Normal file
86
src/base/container/flat_set.h
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
// Copyright 2010-2021, Google Inc.
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
#ifndef MOZC_BASE_CONTAINER_FLAT_SET_H_
|
||||||
|
#define MOZC_BASE_CONTAINER_FLAT_SET_H_
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <array>
|
||||||
|
#include <functional>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
#include "absl/types/span.h"
|
||||||
|
#include "base/container/flat_internal.h"
|
||||||
|
|
||||||
|
namespace mozc {
|
||||||
|
|
||||||
|
// Read-only set that is backed by `constexpr`-sorted array.
|
||||||
|
template <class T, class Compare, size_t N>
|
||||||
|
class FlatSet {
|
||||||
|
public:
|
||||||
|
// Consider calling `CreateFlatSet` instead, so you don't have to manually
|
||||||
|
// specify the number of elements, `N`.
|
||||||
|
constexpr FlatSet(std::array<T, N> elements, const Compare &cmp = {})
|
||||||
|
: elements_(std::move(elements)), cmp_(cmp) {
|
||||||
|
internal::SortAndVerifyUnique(absl::MakeSpan(elements_), cmp_);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns if the given element is in the set.
|
||||||
|
constexpr bool contains(const T &x) const {
|
||||||
|
auto lb = internal::FindFirst(absl::MakeSpan(elements_),
|
||||||
|
[&](const T &e) { return !cmp_(e, x); });
|
||||||
|
return lb != elements_.end() && !cmp_(x, *lb);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::array<T, N> elements_;
|
||||||
|
Compare cmp_;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Creates a `FlatSet` from a C-style array of `Entry`s.
|
||||||
|
//
|
||||||
|
// Example:
|
||||||
|
//
|
||||||
|
// constexpr auto kSet = CreateFlatSet<absl::string_view>({
|
||||||
|
// "one",
|
||||||
|
// "two",
|
||||||
|
// "three",
|
||||||
|
// });
|
||||||
|
// Declare the variable as auto and use `CreateFlatSet`. The actual type is
|
||||||
|
// complex and explicitly declaring it would leak the number of elements, `N`.
|
||||||
|
template <class T, class Compare = std::less<>, size_t N>
|
||||||
|
constexpr auto CreateFlatSet(T (&&elements)[N], const Compare &cmp = {}) {
|
||||||
|
return FlatSet<T, Compare, N>(internal::ToArray(std::move(elements)), cmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace mozc
|
||||||
|
|
||||||
|
#endif // MOZC_BASE_CONTAINER_FLAT_SET_H_
|
73
src/base/container/flat_set_test.cc
Normal file
73
src/base/container/flat_set_test.cc
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
// Copyright 2010-2021, Google Inc.
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
#include "base/container/flat_set.h"
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
#include "absl/strings/string_view.h"
|
||||||
|
#include "testing/gunit.h"
|
||||||
|
|
||||||
|
namespace mozc {
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
TEST(FlatSetTest, Contains) {
|
||||||
|
constexpr auto kSet = CreateFlatSet<absl::string_view>({
|
||||||
|
"one",
|
||||||
|
"three",
|
||||||
|
"five",
|
||||||
|
});
|
||||||
|
|
||||||
|
EXPECT_FALSE(kSet.contains("zero"));
|
||||||
|
EXPECT_TRUE(kSet.contains("one"));
|
||||||
|
EXPECT_FALSE(kSet.contains("two"));
|
||||||
|
EXPECT_TRUE(kSet.contains("three"));
|
||||||
|
EXPECT_FALSE(kSet.contains("four"));
|
||||||
|
EXPECT_TRUE(kSet.contains("five"));
|
||||||
|
EXPECT_FALSE(kSet.contains("six"));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(FlatSetTest, CustomerCompare) {
|
||||||
|
constexpr auto kSet = CreateFlatSet<absl::string_view, std::greater<>>({
|
||||||
|
"one",
|
||||||
|
"three",
|
||||||
|
"five",
|
||||||
|
});
|
||||||
|
|
||||||
|
EXPECT_FALSE(kSet.contains("zero"));
|
||||||
|
EXPECT_TRUE(kSet.contains("one"));
|
||||||
|
EXPECT_FALSE(kSet.contains("two"));
|
||||||
|
EXPECT_TRUE(kSet.contains("three"));
|
||||||
|
EXPECT_FALSE(kSet.contains("four"));
|
||||||
|
EXPECT_TRUE(kSet.contains("five"));
|
||||||
|
EXPECT_FALSE(kSet.contains("six"));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
} // namespace mozc
|
@ -28,6 +28,34 @@
|
|||||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
# Redistribution and use in source and binary forms, with or without
|
||||||
|
# modification, are permitted provided that the following conditions are
|
||||||
|
# met:
|
||||||
|
#
|
||||||
|
# * Redistributions of source code must retain the above copyright
|
||||||
|
# notice, this list of conditions and the following disclaimer.
|
||||||
|
# * Redistributions in binary form must reproduce the above
|
||||||
|
# copyright notice, this list of conditions and the following disclaimer
|
||||||
|
# in the documentation and/or other materials provided with the
|
||||||
|
# distribution.
|
||||||
|
# * Neither the name of Google Inc. nor the names of its
|
||||||
|
# contributors may be used to endorse or promote products derived from
|
||||||
|
# this software without specific prior written permission.
|
||||||
|
#
|
||||||
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
"""A console utility to show progress."""
|
"""A console utility to show progress."""
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
Reference in New Issue
Block a user