Update files in ortools/base and add more tests
This commit is contained in:
committed by
Mizux Seiha
parent
29a74e7547
commit
cb2fae32ed
@@ -19,7 +19,6 @@ package(default_visibility = ["//visibility:public"])
|
||||
filegroup(
|
||||
name = "base_swig",
|
||||
srcs = ["base.i"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
@@ -33,7 +32,6 @@ cc_library(
|
||||
"adjustable_priority_queue.h",
|
||||
"adjustable_priority_queue-inl.h",
|
||||
],
|
||||
deps = [":base"],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
@@ -64,21 +62,13 @@ cc_library(
|
||||
":commandlineflags",
|
||||
":logging",
|
||||
":types",
|
||||
"@abseil-cpp//absl/base",
|
||||
"@abseil-cpp//absl/container:flat_hash_map",
|
||||
"@abseil-cpp//absl/container:flat_hash_set",
|
||||
"@abseil-cpp//absl/container:node_hash_map",
|
||||
"@abseil-cpp//absl/container:node_hash_set",
|
||||
"@abseil-cpp//absl/flags:flag",
|
||||
"@abseil-cpp//absl/flags:parse",
|
||||
"@abseil-cpp//absl/flags:usage",
|
||||
"@abseil-cpp//absl/log",
|
||||
"@abseil-cpp//absl/log:check",
|
||||
"@abseil-cpp//absl/log:die_if_null",
|
||||
"@abseil-cpp//absl/log:globals",
|
||||
"@abseil-cpp//absl/log:initialize",
|
||||
"@abseil-cpp//absl/strings",
|
||||
"@abseil-cpp//absl/synchronization",
|
||||
"@abseil-cpp//absl/strings:string_view",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -108,7 +98,6 @@ cc_library(
|
||||
name = "constant_divisor",
|
||||
srcs = ["constant_divisor.cc"],
|
||||
hdrs = ["constant_divisor.h"],
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"@abseil-cpp//absl/log:check",
|
||||
"@abseil-cpp//absl/numeric:int128",
|
||||
@@ -120,19 +109,18 @@ cc_test(
|
||||
srcs = ["constant_divisor_test.cc"],
|
||||
deps = [
|
||||
":constant_divisor",
|
||||
"//ortools/base:gmock_main",
|
||||
"@abseil-cpp//absl/flags:flag",
|
||||
"@abseil-cpp//absl/random",
|
||||
"@abseil-cpp//absl/random:bit_gen_ref",
|
||||
"@abseil-cpp//absl/random:distributions",
|
||||
"@google_benchmark//:benchmark",
|
||||
"@googletest//:gtest_main",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "container_logging",
|
||||
hdrs = ["container_logging.h"],
|
||||
deps = [":base"],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
@@ -143,7 +131,6 @@ cc_library(
|
||||
"//conditions:default": [],
|
||||
}),
|
||||
deps = [
|
||||
":strong_int",
|
||||
":strong_vector",
|
||||
"@abseil-cpp//absl/container:inlined_vector",
|
||||
],
|
||||
@@ -161,17 +148,10 @@ cc_test(
|
||||
":dump_vars",
|
||||
":strong_int",
|
||||
":strong_vector",
|
||||
"@abseil-cpp//absl/strings",
|
||||
"@googletest//:gtest_main",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "flags",
|
||||
hdrs = ["flags.h"],
|
||||
deps = ["@abseil-cpp//absl/flags:flag"],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "file",
|
||||
srcs = [
|
||||
@@ -189,6 +169,7 @@ cc_library(
|
||||
"@abseil-cpp//absl/log",
|
||||
"@abseil-cpp//absl/log:check",
|
||||
"@abseil-cpp//absl/status",
|
||||
"@abseil-cpp//absl/status:statusor",
|
||||
"@abseil-cpp//absl/strings",
|
||||
"@bzip2//:bz2",
|
||||
"@protobuf",
|
||||
@@ -221,10 +202,9 @@ cc_library(
|
||||
srcs = ["gzipfile.cc"],
|
||||
hdrs = ["gzipfile.h"],
|
||||
deps = [
|
||||
":base",
|
||||
":file",
|
||||
":path",
|
||||
"@abseil-cpp//absl/strings",
|
||||
":logging",
|
||||
"@abseil-cpp//absl/strings:string_view",
|
||||
"@zlib",
|
||||
],
|
||||
)
|
||||
@@ -233,7 +213,9 @@ cc_library(
|
||||
name = "gzipstring",
|
||||
hdrs = ["gzipstring.h"],
|
||||
deps = [
|
||||
":base",
|
||||
":logging",
|
||||
"@abseil-cpp//absl/log",
|
||||
"@abseil-cpp//absl/strings:string_view",
|
||||
"@zlib",
|
||||
],
|
||||
)
|
||||
@@ -242,41 +224,40 @@ cc_library(
|
||||
name = "hash",
|
||||
srcs = ["hash.cc"],
|
||||
hdrs = ["hash.h"],
|
||||
deps = ["@abseil-cpp//absl/strings"],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "int_type",
|
||||
hdrs = ["int_type.h"],
|
||||
deps = [":base"],
|
||||
deps = [
|
||||
"@abseil-cpp//absl/base:core_headers",
|
||||
"@abseil-cpp//absl/strings:string_view",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "intops",
|
||||
hdrs = ["strong_int.h"],
|
||||
deps = [
|
||||
":int_type",
|
||||
"@abseil-cpp//absl/log:absl_log",
|
||||
"@abseil-cpp//absl/numeric:int128",
|
||||
"@abseil-cpp//absl/meta:type_traits",
|
||||
"@abseil-cpp//absl/strings",
|
||||
"@abseil-cpp//absl/strings:str_format",
|
||||
"@abseil-cpp//absl/strings:string_view",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "iterator_adaptors",
|
||||
hdrs = ["iterator_adaptors.h"],
|
||||
deps = [":base"],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "linked_hash_map",
|
||||
hdrs = ["linked_hash_map.h"],
|
||||
deps = [
|
||||
":base",
|
||||
":logging",
|
||||
"//ortools/base",
|
||||
"@abseil-cpp//absl/container:common",
|
||||
"@abseil-cpp//absl/container:flat_hash_map",
|
||||
"@abseil-cpp//absl/container:flat_hash_set",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -286,32 +267,38 @@ cc_library(
|
||||
hdrs = ["logging.h"],
|
||||
deps = [
|
||||
":base_export",
|
||||
"@abseil-cpp//absl/base:core_headers",
|
||||
"@abseil-cpp//absl/base:log_severity",
|
||||
"@abseil-cpp//absl/flags:flag",
|
||||
"@abseil-cpp//absl/flags:usage",
|
||||
"@abseil-cpp//absl/log",
|
||||
"@abseil-cpp//absl/log:check",
|
||||
"@abseil-cpp//absl/log:die_if_null",
|
||||
"@abseil-cpp//absl/log:flags",
|
||||
"@abseil-cpp//absl/log:globals",
|
||||
"@abseil-cpp//absl/log:initialize",
|
||||
"@abseil-cpp//absl/log:vlog_is_on",
|
||||
"@abseil-cpp//absl/memory",
|
||||
"@abseil-cpp//absl/status",
|
||||
"@abseil-cpp//absl/strings",
|
||||
"@abseil-cpp//absl/strings:string_view",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "map_util",
|
||||
hdrs = ["map_util.h"],
|
||||
deps = [":base"],
|
||||
deps = ["//ortools/base:logging"],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "mathutil",
|
||||
srcs = ["mathutil.cc"],
|
||||
hdrs = ["mathutil.h"],
|
||||
deps = [":base"],
|
||||
deps = [
|
||||
"//ortools/base:logging",
|
||||
"@abseil-cpp//absl/base",
|
||||
"@abseil-cpp//absl/log:check",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
@@ -322,17 +309,12 @@ cc_library(
|
||||
cc_library(
|
||||
name = "memutil",
|
||||
hdrs = ["memutil.h"],
|
||||
deps = ["@abseil-cpp//absl/strings"],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "murmur",
|
||||
hdrs = ["murmur.h"],
|
||||
deps = [
|
||||
":base",
|
||||
":hash",
|
||||
"@abseil-cpp//absl/strings",
|
||||
],
|
||||
deps = ["//ortools/base:hash"],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
@@ -356,6 +338,8 @@ cc_library(
|
||||
deps = [
|
||||
"//ortools/base:status_macros",
|
||||
"@abseil-cpp//absl/log:check",
|
||||
"@abseil-cpp//absl/status",
|
||||
"@abseil-cpp//absl/strings:string_view",
|
||||
"@protobuf",
|
||||
],
|
||||
)
|
||||
@@ -365,8 +349,7 @@ cc_library(
|
||||
testonly = True,
|
||||
hdrs = ["parse_test_proto.h"],
|
||||
deps = [
|
||||
":gmock",
|
||||
"@abseil-cpp//absl/log:check",
|
||||
"//ortools/base:gmock",
|
||||
"@protobuf",
|
||||
],
|
||||
)
|
||||
@@ -376,18 +359,23 @@ cc_library(
|
||||
srcs = ["path.cc"],
|
||||
hdrs = ["path.h"],
|
||||
deps = [
|
||||
":base",
|
||||
"@abseil-cpp//absl/strings",
|
||||
"@abseil-cpp//absl/strings:string_view",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "protobuf_util",
|
||||
hdrs = ["protobuf_util.h"],
|
||||
deps = [
|
||||
"@abseil-cpp//absl/log:check",
|
||||
"@protobuf",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "protocol-buffer-matchers",
|
||||
testonly = True,
|
||||
srcs = ["protocol-buffer-matchers.cc"],
|
||||
hdrs = ["protocol-buffer-matchers.h"],
|
||||
deps = [
|
||||
@@ -402,9 +390,9 @@ cc_library(
|
||||
name = "protoutil",
|
||||
hdrs = ["protoutil.h"],
|
||||
deps = [
|
||||
":timer",
|
||||
"@abseil-cpp//absl/status",
|
||||
"@abseil-cpp//absl/status:statusor",
|
||||
"@abseil-cpp//absl/time",
|
||||
"@protobuf",
|
||||
],
|
||||
)
|
||||
@@ -412,10 +400,7 @@ cc_library(
|
||||
cc_library(
|
||||
name = "proto_enum_utils",
|
||||
hdrs = ["proto_enum_utils.h"],
|
||||
deps = [
|
||||
"@abseil-cpp//absl/types:span",
|
||||
"@protobuf",
|
||||
],
|
||||
deps = ["@protobuf"],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
@@ -423,12 +408,9 @@ cc_library(
|
||||
srcs = ["recordio.cc"],
|
||||
hdrs = ["recordio.h"],
|
||||
deps = [
|
||||
":base",
|
||||
":file",
|
||||
":logging",
|
||||
"@abseil-cpp//absl/status:statusor",
|
||||
"@abseil-cpp//absl/strings",
|
||||
"@protobuf",
|
||||
"@abseil-cpp//absl/log",
|
||||
"@abseil-cpp//absl/log:check",
|
||||
"@zlib",
|
||||
],
|
||||
)
|
||||
@@ -443,7 +425,6 @@ cc_library(
|
||||
name = "status_builder",
|
||||
hdrs = ["status_builder.h"],
|
||||
deps = [
|
||||
":base",
|
||||
"@abseil-cpp//absl/status",
|
||||
"@abseil-cpp//absl/strings",
|
||||
],
|
||||
@@ -453,7 +434,6 @@ cc_library(
|
||||
name = "status_macros",
|
||||
hdrs = ["status_macros.h"],
|
||||
deps = [
|
||||
":base",
|
||||
":status_builder",
|
||||
"@abseil-cpp//absl/status",
|
||||
"@abseil-cpp//absl/status:statusor",
|
||||
@@ -463,7 +443,10 @@ cc_library(
|
||||
cc_library(
|
||||
name = "stl_util",
|
||||
hdrs = ["stl_util.h"],
|
||||
deps = [":base"],
|
||||
deps = [
|
||||
"@abseil-cpp//absl/base:core_headers",
|
||||
"@abseil-cpp//absl/meta:type_traits",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
@@ -489,16 +472,15 @@ cc_test(
|
||||
timeout = "long",
|
||||
srcs = ["strong_int_test.cc"],
|
||||
deps = [
|
||||
":gmock",
|
||||
":logging",
|
||||
":strong_int",
|
||||
"//ortools/base:gmock_main",
|
||||
"@abseil-cpp//absl/container:node_hash_map",
|
||||
"@abseil-cpp//absl/flags:marshalling",
|
||||
"@abseil-cpp//absl/hash:hash_testing",
|
||||
"@abseil-cpp//absl/numeric:int128",
|
||||
"@abseil-cpp//absl/strings",
|
||||
"@abseil-cpp//absl/strings:str_format",
|
||||
"@googletest//:gtest_main",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -506,8 +488,8 @@ cc_library(
|
||||
name = "strong_vector",
|
||||
hdrs = ["strong_vector.h"],
|
||||
deps = [
|
||||
":base",
|
||||
":intops",
|
||||
"//ortools/base:logging",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -516,16 +498,27 @@ cc_library(
|
||||
srcs = ["strtoint.cc"],
|
||||
hdrs = ["strtoint.h"],
|
||||
deps = [
|
||||
"@abseil-cpp//absl/base:core_headers",
|
||||
"@abseil-cpp//absl/log:check",
|
||||
"@abseil-cpp//absl/strings",
|
||||
],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "strtoint_test",
|
||||
size = "small",
|
||||
srcs = ["strtoint_test.cc"],
|
||||
deps = [
|
||||
":strtoint",
|
||||
"//ortools/base:gmock_main",
|
||||
"//ortools/base:types",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "sysinfo",
|
||||
srcs = ["sysinfo.cc"],
|
||||
hdrs = ["sysinfo.h"],
|
||||
deps = ["@abseil-cpp//absl/strings"],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
@@ -533,10 +526,10 @@ cc_library(
|
||||
srcs = ["temp_file.cc"],
|
||||
hdrs = ["temp_file.h"],
|
||||
deps = [
|
||||
":base",
|
||||
":file",
|
||||
"@abseil-cpp//absl/status",
|
||||
"//ortools/base:logging",
|
||||
"@abseil-cpp//absl/status:statusor",
|
||||
"@abseil-cpp//absl/strings",
|
||||
"@abseil-cpp//absl/strings:str_format",
|
||||
"@abseil-cpp//absl/time",
|
||||
],
|
||||
)
|
||||
@@ -551,6 +544,7 @@ cc_library(
|
||||
"@abseil-cpp//absl/log:check",
|
||||
"@abseil-cpp//absl/status",
|
||||
"@abseil-cpp//absl/strings",
|
||||
"@abseil-cpp//absl/strings:string_view",
|
||||
"@abseil-cpp//absl/time",
|
||||
],
|
||||
)
|
||||
@@ -561,7 +555,7 @@ cc_library(
|
||||
hdrs = ["threadpool.h"],
|
||||
deps = [
|
||||
"@abseil-cpp//absl/log:check",
|
||||
"@abseil-cpp//absl/synchronization",
|
||||
"@abseil-cpp//absl/strings",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -578,6 +572,7 @@ cc_library(
|
||||
cc_library(
|
||||
name = "top_n",
|
||||
hdrs = ["top_n.h"],
|
||||
deps = [":logging"],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
@@ -591,9 +586,8 @@ cc_library(
|
||||
hdrs = ["zipfile.h"],
|
||||
deps = [
|
||||
":file",
|
||||
":path",
|
||||
":stl_util",
|
||||
"@abseil-cpp//absl/strings",
|
||||
":logging",
|
||||
"@abseil-cpp//absl/strings:string_view",
|
||||
"@zlib",
|
||||
],
|
||||
)
|
||||
|
||||
51
ortools/base/accurate_sum_test.cc
Normal file
51
ortools/base/accurate_sum_test.cc
Normal file
@@ -0,0 +1,51 @@
|
||||
// Copyright 2010-2025 Google LLC
|
||||
// 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.
|
||||
|
||||
#include "ortools/base/accurate_sum.h"
|
||||
|
||||
#include <cmath>
|
||||
#include <random>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/random/random.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "ortools/base/accurate_sum.h"
|
||||
|
||||
namespace {
|
||||
|
||||
TEST(AccurateSumTest, ExactConsistencyWithUtilMath) {
|
||||
std::vector<double> data;
|
||||
{
|
||||
std::mt19937 random(12345);
|
||||
const int kNumNumbers = 1000000;
|
||||
data.assign(kNumNumbers, 0.0);
|
||||
for (int i = 0; i < kNumNumbers; ++i) {
|
||||
const double abs_value = exp2(absl::Uniform<double>(random, -100, 100.0));
|
||||
data[i] = absl::Bernoulli(random, 1.0 / 2) ? abs_value : -abs_value;
|
||||
}
|
||||
}
|
||||
operations_research::AccurateSum<double> forked_sum;
|
||||
AccurateSum<double> reference_sum;
|
||||
// Runtime: August 2013, fastbuild, forge: 4 seconds.
|
||||
const int kNumPasses = 100;
|
||||
for (int i = 0; i < kNumPasses; ++i) {
|
||||
for (const double v : data) {
|
||||
forked_sum.Add(v);
|
||||
reference_sum.Add(v);
|
||||
}
|
||||
}
|
||||
// We *do* mean to expect a rigorous floating-point equality.
|
||||
EXPECT_EQ(reference_sum.Value(), forked_sum.Value());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
@@ -41,8 +41,6 @@
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
|
||||
#include "absl/base/port.h"
|
||||
|
||||
namespace gtl {
|
||||
|
||||
// Several policy classes below determine how LogRangeToStream will
|
||||
|
||||
@@ -14,9 +14,9 @@
|
||||
#include "ortools/base/dump_vars.h"
|
||||
|
||||
#include <optional>
|
||||
#include <ostream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
|
||||
@@ -13,11 +13,18 @@
|
||||
|
||||
#include "ortools/base/filesystem.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <exception> // IWYU pragma: keep
|
||||
#include <filesystem> // NOLINT(build/c++17)
|
||||
#include <regex> // NOLINT
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <system_error> // NOLINT
|
||||
#include <vector>
|
||||
|
||||
#include "absl/status/status.h"
|
||||
#include "absl/strings/str_replace.h"
|
||||
#include "ortools/base/file.h"
|
||||
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
|
||||
732
ortools/base/linked_hash_map_test.cc
Normal file
732
ortools/base/linked_hash_map_test.cc
Normal file
@@ -0,0 +1,732 @@
|
||||
// Copyright 2010-2025 Google LLC
|
||||
// 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.
|
||||
|
||||
// Tests linked_hash_map.
|
||||
//
|
||||
// This test was forked from ortools/base/linked_hash_map_test.cc on Feb 25,
|
||||
// 2021. Some tests were deleted as they depended on code not visible from here.
|
||||
|
||||
#include "ortools/base/linked_hash_map.h"
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/container/internal/unordered_map_constructor_test.h"
|
||||
#include "absl/container/internal/unordered_map_lookup_test.h"
|
||||
#include "absl/container/internal/unordered_map_members_test.h"
|
||||
#include "absl/container/internal/unordered_map_modifiers_test.h"
|
||||
#include "absl/memory/memory.h"
|
||||
#include "absl/types/any.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "ortools/base/gmock.h"
|
||||
#include "util/gtl/map_util_test.h"
|
||||
|
||||
namespace gtl {
|
||||
namespace {
|
||||
|
||||
// Need to import the namespace to bring the names generated by GoogleTest for
|
||||
// the typed test suite.
|
||||
using namespace absl::container_internal; // NOLINT
|
||||
|
||||
using ::absl::container_internal::hash_internal::Enum;
|
||||
using ::absl::container_internal::hash_internal::EnumClass;
|
||||
|
||||
template <class K, class V>
|
||||
using Map = linked_hash_map<K, V, StatefulTestingHash, StatefulTestingEqual,
|
||||
Alloc<std::pair<const K, V>>>;
|
||||
|
||||
static_assert(!std::is_standard_layout<NonStandardLayout>(), "");
|
||||
|
||||
using MapTypes =
|
||||
::testing::Types<Map<int, int>, Map<std::string, int>,
|
||||
Map<Enum, std::string>, Map<EnumClass, int>,
|
||||
Map<int, NonStandardLayout>, Map<NonStandardLayout, int>>;
|
||||
|
||||
INSTANTIATE_TYPED_TEST_SUITE_P(LinkedHashMap, ConstructorTest, MapTypes);
|
||||
INSTANTIATE_TYPED_TEST_SUITE_P(LinkedHashMap, LookupTest, MapTypes);
|
||||
INSTANTIATE_TYPED_TEST_SUITE_P(LinkedHashMap, MembersTest, MapTypes);
|
||||
INSTANTIATE_TYPED_TEST_SUITE_P(LinkedHashMap, ModifiersTest, MapTypes);
|
||||
|
||||
using ::testing::ElementsAre;
|
||||
using ::testing::Pair;
|
||||
using ::testing::Pointee;
|
||||
|
||||
// Tests that the range constructor works.
|
||||
TEST(LinkedHashMapTest, RangeConstruct) {
|
||||
const std::pair<int, int> items[] = {{1, 2}, {2, 3}, {3, 4}};
|
||||
EXPECT_THAT((linked_hash_map<int, int>(std::begin(items), std::end(items))),
|
||||
ElementsAre(Pair(1, 2), Pair(2, 3), Pair(3, 4)));
|
||||
}
|
||||
|
||||
// Tests that copying works.
|
||||
TEST(LinkedHashMapTest, Copy) {
|
||||
linked_hash_map<int, int> m{{2, 12}, {3, 13}};
|
||||
// NOLINTNEXTLINE(performance-unnecessary-copy-initialization)
|
||||
auto copy = m;
|
||||
|
||||
EXPECT_TRUE(copy.contains(2));
|
||||
auto found = copy.find(2);
|
||||
ASSERT_TRUE(found != copy.end());
|
||||
for (auto iter = copy.begin(); iter != copy.end(); ++iter) {
|
||||
if (iter == found) return;
|
||||
}
|
||||
FAIL() << "Copied map's find method returned an invalid iterator.";
|
||||
}
|
||||
|
||||
// Tests that assignment works.
|
||||
TEST(LinkedHashMapTest, Assign) {
|
||||
linked_hash_map<int, int> m{{2, 12}, {3, 13}};
|
||||
linked_hash_map<int, int> n{{4, 14}};
|
||||
|
||||
n = m;
|
||||
EXPECT_TRUE(n.contains(2));
|
||||
auto found = n.find(2);
|
||||
ASSERT_TRUE(found != n.end());
|
||||
for (auto iter = n.begin(); iter != n.end(); ++iter) {
|
||||
if (iter == found) return;
|
||||
}
|
||||
FAIL() << "Assigned map's find method returned an invalid iterator.";
|
||||
}
|
||||
|
||||
// Tests that move constructor works.
|
||||
TEST(LinkedHashMapTest, Move) {
|
||||
// Use unique_ptr as an example of a non-copyable type.
|
||||
linked_hash_map<int, std::unique_ptr<int>> m;
|
||||
m[2] = std::make_unique<int>(12);
|
||||
m[3] = std::make_unique<int>(13);
|
||||
linked_hash_map<int, std::unique_ptr<int>> n = std::move(m);
|
||||
EXPECT_THAT(n, ElementsAre(Pair(2, Pointee(12)), Pair(3, Pointee(13))));
|
||||
}
|
||||
|
||||
TEST(LinkedHashMapTest, CanInsertMoveOnly) {
|
||||
linked_hash_map<int, std::unique_ptr<int>> m;
|
||||
struct Data {
|
||||
int k, v;
|
||||
};
|
||||
const Data data[] = {{1, 123}, {3, 345}, {2, 234}, {4, 456}};
|
||||
for (const auto& kv : data)
|
||||
m.insert({kv.k, std::make_unique<int>(int{kv.v})});
|
||||
EXPECT_TRUE(m.contains(2));
|
||||
auto found = m.find(2);
|
||||
ASSERT_TRUE(found != m.end());
|
||||
EXPECT_EQ(234, *found->second);
|
||||
}
|
||||
|
||||
TEST(LinkedHashMapTest, CanEmplaceMoveOnly) {
|
||||
linked_hash_map<int, std::unique_ptr<int>> m;
|
||||
struct Data {
|
||||
int k, v;
|
||||
};
|
||||
const Data data[] = {{1, 123}, {3, 345}, {2, 234}, {4, 456}};
|
||||
for (const auto& kv : data) {
|
||||
m.emplace(std::piecewise_construct, std::make_tuple(kv.k),
|
||||
std::make_tuple(new int{kv.v}));
|
||||
}
|
||||
EXPECT_TRUE(m.contains(2));
|
||||
auto found = m.find(2);
|
||||
ASSERT_TRUE(found != m.end());
|
||||
EXPECT_EQ(234, *found->second);
|
||||
}
|
||||
|
||||
struct NoCopy {
|
||||
explicit NoCopy(int x) : x(x) {}
|
||||
NoCopy(const NoCopy&) = delete;
|
||||
NoCopy& operator=(const NoCopy&) = delete;
|
||||
NoCopy(NoCopy&&) = delete;
|
||||
NoCopy& operator=(NoCopy&&) = delete;
|
||||
int x;
|
||||
};
|
||||
|
||||
TEST(LinkedHashMapTest, CanEmplaceNoMoveNoCopy) {
|
||||
linked_hash_map<int, NoCopy> m;
|
||||
struct Data {
|
||||
int k, v;
|
||||
};
|
||||
const Data data[] = {{1, 123}, {3, 345}, {2, 234}, {4, 456}};
|
||||
for (const auto& kv : data) {
|
||||
m.emplace(std::piecewise_construct, std::make_tuple(kv.k),
|
||||
std::make_tuple(kv.v));
|
||||
}
|
||||
EXPECT_TRUE(m.contains(2));
|
||||
auto found = m.find(2);
|
||||
ASSERT_TRUE(found != m.end());
|
||||
EXPECT_EQ(234, found->second.x);
|
||||
}
|
||||
|
||||
TEST(LinkedHashMapTest, ConstKeys) {
|
||||
linked_hash_map<int, int> m;
|
||||
m.insert(std::make_pair(1, 2));
|
||||
// Test that keys are const in iteration.
|
||||
std::pair<const int, int>& p = *m.begin();
|
||||
EXPECT_EQ(1, p.first);
|
||||
}
|
||||
|
||||
// Tests that iteration from begin() to end() works
|
||||
TEST(LinkedHashMapTest, Iteration) {
|
||||
linked_hash_map<int, int> m;
|
||||
EXPECT_TRUE(m.begin() == m.end());
|
||||
|
||||
m.insert(std::make_pair(2, 12));
|
||||
m.insert(std::make_pair(1, 11));
|
||||
m.insert(std::make_pair(3, 13));
|
||||
|
||||
linked_hash_map<int, int>::iterator i = m.begin();
|
||||
ASSERT_TRUE(m.begin() == i);
|
||||
ASSERT_TRUE(m.end() != i);
|
||||
EXPECT_EQ(2, i->first);
|
||||
EXPECT_EQ(12, i->second);
|
||||
|
||||
++i;
|
||||
ASSERT_TRUE(m.end() != i);
|
||||
EXPECT_EQ(1, i->first);
|
||||
EXPECT_EQ(11, i->second);
|
||||
|
||||
++i;
|
||||
ASSERT_TRUE(m.end() != i);
|
||||
EXPECT_EQ(3, i->first);
|
||||
EXPECT_EQ(13, i->second);
|
||||
|
||||
++i; // Should be the end of the line.
|
||||
ASSERT_TRUE(m.end() == i);
|
||||
}
|
||||
|
||||
// Tests that reverse iteration from rbegin() to rend() works
|
||||
TEST(LinkedHashMapTest, ReverseIteration) {
|
||||
linked_hash_map<int, int> m;
|
||||
EXPECT_TRUE(m.rbegin() == m.rend());
|
||||
|
||||
m.insert(std::make_pair(2, 12));
|
||||
m.insert(std::make_pair(1, 11));
|
||||
m.insert(std::make_pair(3, 13));
|
||||
|
||||
linked_hash_map<int, int>::reverse_iterator i = m.rbegin();
|
||||
ASSERT_TRUE(m.rbegin() == i);
|
||||
ASSERT_TRUE(m.rend() != i);
|
||||
EXPECT_EQ(3, i->first);
|
||||
EXPECT_EQ(13, i->second);
|
||||
|
||||
++i;
|
||||
ASSERT_TRUE(m.rend() != i);
|
||||
EXPECT_EQ(1, i->first);
|
||||
EXPECT_EQ(11, i->second);
|
||||
|
||||
++i;
|
||||
ASSERT_TRUE(m.rend() != i);
|
||||
EXPECT_EQ(2, i->first);
|
||||
EXPECT_EQ(12, i->second);
|
||||
|
||||
++i; // Should be the end of the line.
|
||||
ASSERT_TRUE(m.rend() == i);
|
||||
}
|
||||
|
||||
// Tests that clear() works
|
||||
TEST(LinkedHashMapTest, Clear) {
|
||||
linked_hash_map<int, int> m;
|
||||
m.insert(std::make_pair(2, 12));
|
||||
m.insert(std::make_pair(1, 11));
|
||||
m.insert(std::make_pair(3, 13));
|
||||
|
||||
ASSERT_EQ(3, m.size());
|
||||
|
||||
m.clear();
|
||||
|
||||
EXPECT_EQ(0, m.size());
|
||||
|
||||
m.clear(); // Make sure we can call it on an empty map.
|
||||
|
||||
EXPECT_EQ(0, m.size());
|
||||
}
|
||||
|
||||
// Tests that size() works.
|
||||
TEST(LinkedHashMapTest, Size) {
|
||||
linked_hash_map<int, int> m;
|
||||
EXPECT_EQ(0, m.size());
|
||||
m.insert(std::make_pair(2, 12));
|
||||
EXPECT_EQ(1, m.size());
|
||||
m.insert(std::make_pair(1, 11));
|
||||
EXPECT_EQ(2, m.size());
|
||||
m.insert(std::make_pair(3, 13));
|
||||
EXPECT_EQ(3, m.size());
|
||||
m.clear();
|
||||
EXPECT_EQ(0, m.size());
|
||||
}
|
||||
|
||||
// Tests empty()
|
||||
TEST(LinkedHashMapTest, Empty) {
|
||||
linked_hash_map<int, int> m;
|
||||
ASSERT_TRUE(m.empty());
|
||||
m.insert(std::make_pair(2, 12));
|
||||
ASSERT_FALSE(m.empty());
|
||||
m.clear();
|
||||
ASSERT_TRUE(m.empty());
|
||||
}
|
||||
|
||||
TEST(LinkedHashMapTest, Erase) {
|
||||
linked_hash_map<int, int> m;
|
||||
ASSERT_EQ(0, m.size());
|
||||
EXPECT_EQ(0, m.erase(2)); // Nothing to erase yet
|
||||
|
||||
m.insert(std::make_pair(2, 12));
|
||||
ASSERT_EQ(1, m.size());
|
||||
EXPECT_EQ(1, m.erase(2));
|
||||
EXPECT_EQ(0, m.size());
|
||||
|
||||
EXPECT_EQ(0, m.erase(2)); // Make sure nothing bad happens if we repeat.
|
||||
EXPECT_EQ(0, m.size());
|
||||
}
|
||||
|
||||
TEST(LinkedHashMapTest, Erase2) {
|
||||
linked_hash_map<int, int> m;
|
||||
ASSERT_EQ(0, m.size());
|
||||
EXPECT_EQ(0, m.erase(2)); // Nothing to erase yet
|
||||
|
||||
m.insert(std::make_pair(2, 12));
|
||||
m.insert(std::make_pair(1, 11));
|
||||
m.insert(std::make_pair(3, 13));
|
||||
m.insert(std::make_pair(4, 14));
|
||||
ASSERT_EQ(4, m.size());
|
||||
|
||||
// Erase middle two
|
||||
EXPECT_EQ(1, m.erase(1));
|
||||
EXPECT_EQ(1, m.erase(3));
|
||||
|
||||
EXPECT_EQ(2, m.size());
|
||||
|
||||
// Make sure we can still iterate over everything that's left.
|
||||
linked_hash_map<int, int>::iterator it = m.begin();
|
||||
ASSERT_TRUE(it != m.end());
|
||||
EXPECT_EQ(12, it->second);
|
||||
++it;
|
||||
ASSERT_TRUE(it != m.end());
|
||||
EXPECT_EQ(14, it->second);
|
||||
++it;
|
||||
ASSERT_TRUE(it == m.end());
|
||||
|
||||
EXPECT_EQ(0, m.erase(1)); // Make sure nothing bad happens if we repeat.
|
||||
ASSERT_EQ(2, m.size());
|
||||
|
||||
EXPECT_EQ(1, m.erase(2));
|
||||
EXPECT_EQ(1, m.erase(4));
|
||||
ASSERT_EQ(0, m.size());
|
||||
|
||||
EXPECT_EQ(0, m.erase(1)); // Make sure nothing bad happens if we repeat.
|
||||
ASSERT_EQ(0, m.size());
|
||||
}
|
||||
|
||||
// Test that erase(iter,iter) and erase(iter) compile and work.
|
||||
TEST(LinkedHashMapTest, Erase3) {
|
||||
linked_hash_map<int, int> m;
|
||||
|
||||
m.insert(std::make_pair(1, 11));
|
||||
m.insert(std::make_pair(2, 12));
|
||||
m.insert(std::make_pair(3, 13));
|
||||
m.insert(std::make_pair(4, 14));
|
||||
|
||||
// Erase middle two
|
||||
linked_hash_map<int, int>::iterator it2 = m.find(2);
|
||||
linked_hash_map<int, int>::iterator it4 = m.find(4);
|
||||
EXPECT_EQ(m.erase(it2, it4), m.find(4));
|
||||
EXPECT_EQ(2, m.size());
|
||||
|
||||
// Make sure we can still iterate over everything that's left.
|
||||
linked_hash_map<int, int>::iterator it = m.begin();
|
||||
ASSERT_TRUE(it != m.end());
|
||||
EXPECT_EQ(11, it->second);
|
||||
++it;
|
||||
ASSERT_TRUE(it != m.end());
|
||||
EXPECT_EQ(14, it->second);
|
||||
++it;
|
||||
ASSERT_TRUE(it == m.end());
|
||||
|
||||
// Erase first one using an iterator.
|
||||
EXPECT_EQ(m.erase(m.begin()), m.find(4));
|
||||
|
||||
// Only the last element should be left.
|
||||
it = m.begin();
|
||||
ASSERT_TRUE(it != m.end());
|
||||
EXPECT_EQ(14, it->second);
|
||||
++it;
|
||||
ASSERT_TRUE(it == m.end());
|
||||
}
|
||||
|
||||
// Test all types of insertion
|
||||
TEST(LinkedHashMapTest, Insertion) {
|
||||
linked_hash_map<int, int> m;
|
||||
ASSERT_EQ(0, m.size());
|
||||
std::pair<linked_hash_map<int, int>::iterator, bool> result;
|
||||
|
||||
result = m.insert(std::make_pair(2, 12));
|
||||
ASSERT_EQ(1, m.size());
|
||||
EXPECT_TRUE(result.second);
|
||||
EXPECT_EQ(2, result.first->first);
|
||||
EXPECT_EQ(12, result.first->second);
|
||||
|
||||
result = m.insert(std::make_pair(1, 11));
|
||||
ASSERT_EQ(2, m.size());
|
||||
EXPECT_TRUE(result.second);
|
||||
EXPECT_EQ(1, result.first->first);
|
||||
EXPECT_EQ(11, result.first->second);
|
||||
|
||||
result = m.insert(std::make_pair(3, 13));
|
||||
linked_hash_map<int, int>::iterator result_iterator = result.first;
|
||||
ASSERT_EQ(3, m.size());
|
||||
EXPECT_TRUE(result.second);
|
||||
EXPECT_EQ(3, result.first->first);
|
||||
EXPECT_EQ(13, result.first->second);
|
||||
|
||||
result = m.insert(std::make_pair(3, 13));
|
||||
EXPECT_EQ(3, m.size());
|
||||
EXPECT_FALSE(result.second) << "No insertion should have occurred.";
|
||||
EXPECT_TRUE(result_iterator == result.first)
|
||||
<< "Duplicate insertion should have given us the original iterator.";
|
||||
|
||||
std::vector<std::pair<int, int>> v = {{3, 13}, {4, 14}, {5, 15}};
|
||||
m.insert(v.begin(), v.end());
|
||||
// Expect 4 and 5 inserted, 3 not inserted.
|
||||
EXPECT_EQ(5, m.size());
|
||||
EXPECT_EQ(14, m.at(4));
|
||||
EXPECT_EQ(15, m.at(5));
|
||||
}
|
||||
|
||||
static std::pair<const int, int> Pair(int i, int j) { return {i, j}; }
|
||||
|
||||
// Test front accessors.
|
||||
TEST(LinkedHashMapTest, Front) {
|
||||
linked_hash_map<int, int> m;
|
||||
|
||||
m.insert(std::make_pair(2, 12));
|
||||
m.insert(std::make_pair(1, 11));
|
||||
m.insert(std::make_pair(3, 13));
|
||||
|
||||
EXPECT_EQ(3, m.size());
|
||||
EXPECT_EQ(Pair(2, 12), m.front());
|
||||
m.pop_front();
|
||||
EXPECT_EQ(2, m.size());
|
||||
EXPECT_EQ(Pair(1, 11), m.front());
|
||||
m.pop_front();
|
||||
EXPECT_EQ(1, m.size());
|
||||
EXPECT_EQ(Pair(3, 13), m.front());
|
||||
m.pop_front();
|
||||
EXPECT_TRUE(m.empty());
|
||||
}
|
||||
|
||||
// Test back accessors.
|
||||
TEST(LinkedHashMapTest, Back) {
|
||||
linked_hash_map<int, int> m;
|
||||
|
||||
m.insert(std::make_pair(2, 12));
|
||||
m.insert(std::make_pair(1, 11));
|
||||
m.insert(std::make_pair(3, 13));
|
||||
|
||||
EXPECT_EQ(3, m.size());
|
||||
EXPECT_EQ(Pair(3, 13), m.back());
|
||||
m.pop_back();
|
||||
EXPECT_EQ(2, m.size());
|
||||
EXPECT_EQ(Pair(1, 11), m.back());
|
||||
m.pop_back();
|
||||
EXPECT_EQ(1, m.size());
|
||||
EXPECT_EQ(Pair(2, 12), m.back());
|
||||
m.pop_back();
|
||||
EXPECT_TRUE(m.empty());
|
||||
}
|
||||
|
||||
TEST(LinkedHashMapTest, Find) {
|
||||
linked_hash_map<int, int> m;
|
||||
|
||||
EXPECT_TRUE(m.end() == m.find(1))
|
||||
<< "We shouldn't find anything in an empty map.";
|
||||
|
||||
m.insert(std::make_pair(2, 12));
|
||||
EXPECT_TRUE(m.end() == m.find(1))
|
||||
<< "We shouldn't find an element that doesn't exist in the map.";
|
||||
|
||||
std::pair<linked_hash_map<int, int>::iterator, bool> result =
|
||||
m.insert(std::make_pair(1, 11));
|
||||
ASSERT_TRUE(result.second);
|
||||
ASSERT_TRUE(m.end() != result.first);
|
||||
EXPECT_TRUE(result.first == m.find(1))
|
||||
<< "We should have found an element we know exists in the map.";
|
||||
EXPECT_EQ(11, result.first->second);
|
||||
|
||||
// Check that a follow-up insertion doesn't affect our original
|
||||
m.insert(std::make_pair(3, 13));
|
||||
linked_hash_map<int, int>::iterator it = m.find(1);
|
||||
ASSERT_TRUE(m.end() != it);
|
||||
EXPECT_EQ(11, it->second);
|
||||
|
||||
m.clear();
|
||||
EXPECT_TRUE(m.end() == m.find(1))
|
||||
<< "We shouldn't find anything in a map that we've cleared.";
|
||||
}
|
||||
|
||||
TEST(LinkedHashMapTest, Contains) {
|
||||
linked_hash_map<int, int> m;
|
||||
|
||||
EXPECT_FALSE(m.contains(1)) << "An empty map shouldn't contain anything.";
|
||||
|
||||
m.insert(std::make_pair(2, 12));
|
||||
EXPECT_FALSE(m.contains(1))
|
||||
<< "The map shouldn't contain an element that doesn't exist.";
|
||||
|
||||
m.insert(std::make_pair(1, 11));
|
||||
EXPECT_TRUE(m.contains(1))
|
||||
<< "The map should contain an element that we know exists.";
|
||||
|
||||
m.clear();
|
||||
EXPECT_FALSE(m.contains(1))
|
||||
<< "A map that we've cleared shouldn't contain anything.";
|
||||
}
|
||||
|
||||
TEST(LinkedHashMapTest, At) {
|
||||
linked_hash_map<int, int> m = {{1, 2}};
|
||||
EXPECT_EQ(2, m.at(1));
|
||||
EXPECT_DEATH(m.at(3), ".*linked_hash_map::at.*");
|
||||
|
||||
const linked_hash_map<int, int> cm = {{1, 2}};
|
||||
EXPECT_EQ(2, cm.at(1));
|
||||
EXPECT_DEATH(cm.at(3), ".*linked_hash_map::at.*");
|
||||
}
|
||||
|
||||
TEST(LinkedHashMapTest, Swap) {
|
||||
linked_hash_map<int, int> m1;
|
||||
linked_hash_map<int, int> m2;
|
||||
m1.insert(std::make_pair(1, 1));
|
||||
m1.insert(std::make_pair(2, 2));
|
||||
m2.insert(std::make_pair(3, 3));
|
||||
ASSERT_EQ(2, m1.size());
|
||||
ASSERT_EQ(1, m2.size());
|
||||
m1.swap(m2);
|
||||
ASSERT_EQ(1, m1.size());
|
||||
ASSERT_EQ(2, m2.size());
|
||||
}
|
||||
|
||||
TEST(LinkedHashMapTest, InitializerList) {
|
||||
linked_hash_map<int, int> m{{1, 2}, {3, 4}};
|
||||
ASSERT_EQ(2, m.size());
|
||||
EXPECT_TRUE(m.contains(1));
|
||||
linked_hash_map<int, int>::iterator it = m.find(1);
|
||||
ASSERT_TRUE(m.end() != it);
|
||||
EXPECT_EQ(2, it->second);
|
||||
EXPECT_TRUE(m.contains(3));
|
||||
it = m.find(3);
|
||||
ASSERT_TRUE(m.end() != it);
|
||||
EXPECT_EQ(4, it->second);
|
||||
}
|
||||
|
||||
TEST(LinkedHashMapTest, CustomHashAndEquality) {
|
||||
struct CustomIntHash {
|
||||
size_t operator()(int x) const { return x; }
|
||||
};
|
||||
struct CustomIntEq {
|
||||
bool operator()(int x, int y) const { return x == y; }
|
||||
};
|
||||
linked_hash_map<int, int, CustomIntHash, CustomIntEq> m;
|
||||
m.insert(std::make_pair(1, 1));
|
||||
EXPECT_TRUE(m.contains(1));
|
||||
EXPECT_EQ(1, m[1]);
|
||||
}
|
||||
|
||||
TEST(LinkedHashMapTest, EqualRange) {
|
||||
linked_hash_map<int, int> m{{3, 11}, {1, 13}};
|
||||
const auto& const_m = m;
|
||||
|
||||
EXPECT_THAT(m.equal_range(2), testing::Pair(m.end(), m.end()));
|
||||
EXPECT_THAT(const_m.equal_range(2),
|
||||
testing::Pair(const_m.end(), const_m.end()));
|
||||
|
||||
EXPECT_THAT(m.equal_range(1), testing::Pair(m.find(1), ++m.find(1)));
|
||||
EXPECT_THAT(const_m.equal_range(1),
|
||||
testing::Pair(const_m.find(1), ++const_m.find(1)));
|
||||
}
|
||||
|
||||
TEST(LinkedHashMapTest, ReserveWorks) {
|
||||
linked_hash_map<int, int> m;
|
||||
EXPECT_GE(10000, m.capacity());
|
||||
EXPECT_EQ(0, m.size());
|
||||
EXPECT_EQ(0.0, m.load_factor());
|
||||
m.reserve(100'000);
|
||||
const int capacity_before_insert = m.capacity();
|
||||
EXPECT_LE(100'000, capacity_before_insert);
|
||||
EXPECT_EQ(0, m.size());
|
||||
EXPECT_EQ(0.0, m.load_factor());
|
||||
m.emplace(1, 1);
|
||||
m.emplace(2, 2);
|
||||
EXPECT_EQ(capacity_before_insert, m.capacity());
|
||||
EXPECT_EQ(2, m.size());
|
||||
EXPECT_LT(0.0, m.load_factor());
|
||||
}
|
||||
|
||||
TEST(LinkedHashMapTest, HeterogeneousStringViewLookup) {
|
||||
linked_hash_map<std::string, int> map;
|
||||
map["foo"] = 1;
|
||||
map["bar"] = 2;
|
||||
map["blah"] = 3;
|
||||
|
||||
{
|
||||
absl::string_view lookup("foo");
|
||||
auto itr = map.find(lookup);
|
||||
ASSERT_NE(itr, map.end());
|
||||
EXPECT_EQ(1, itr->second);
|
||||
}
|
||||
|
||||
// Not found.
|
||||
{
|
||||
absl::string_view lookup("foobar");
|
||||
EXPECT_EQ(map.end(), map.find(lookup));
|
||||
}
|
||||
|
||||
{
|
||||
absl::string_view lookup("blah");
|
||||
auto itr = map.find(lookup);
|
||||
ASSERT_NE(itr, map.end());
|
||||
EXPECT_EQ(3, itr->second);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(LinkedHashMapTest, UniversalReferenceWorks) {
|
||||
linked_hash_map<std::string, int> map;
|
||||
std::string s = "very very very very very long string";
|
||||
map[s] = 1;
|
||||
EXPECT_EQ(s, "very very very very very long string");
|
||||
}
|
||||
|
||||
TEST(LinkedHashMap, ExtractInsert) {
|
||||
linked_hash_map<int, int> m = {{1, 7}, {2, 9}};
|
||||
auto node = m.extract(1);
|
||||
EXPECT_TRUE(node);
|
||||
EXPECT_EQ(node.key(), 1);
|
||||
EXPECT_EQ(node.mapped(), 7);
|
||||
EXPECT_THAT(m, ElementsAre(Pair(2, 9)));
|
||||
EXPECT_FALSE(m.contains(1));
|
||||
EXPECT_TRUE(m.contains(2));
|
||||
|
||||
node.mapped() = 17;
|
||||
m.insert(std::move(node));
|
||||
EXPECT_FALSE(node);
|
||||
EXPECT_THAT(m, ElementsAre(Pair(2, 9), Pair(1, 17)));
|
||||
EXPECT_TRUE(m.contains(2));
|
||||
EXPECT_TRUE(m.contains(1));
|
||||
|
||||
node = m.extract(m.find(1));
|
||||
EXPECT_TRUE(node);
|
||||
EXPECT_EQ(node.key(), 1);
|
||||
EXPECT_EQ(node.mapped(), 17);
|
||||
EXPECT_THAT(m, ElementsAre(Pair(2, 9)));
|
||||
}
|
||||
|
||||
TEST(LinkedHashMap, Merge) {
|
||||
linked_hash_map<int, int> m = {{1, 7}, {3, 6}};
|
||||
linked_hash_map<int, int> src = {{1, 10}, {2, 9}, {4, 16}};
|
||||
|
||||
m.merge(src);
|
||||
|
||||
EXPECT_THAT(m, ElementsAre(Pair(1, 7), Pair(3, 6), Pair(2, 9), Pair(4, 16)));
|
||||
EXPECT_THAT(src, ElementsAre(Pair(1, 10)));
|
||||
for (int i : {2, 9, 4}) {
|
||||
EXPECT_FALSE(src.contains(i));
|
||||
}
|
||||
}
|
||||
|
||||
TEST(LinkedHashMap, EraseRange) {
|
||||
linked_hash_map<int, int> map = {{1, 1}, {2, 4}, {3, 9}, {4, 16}, {5, 25},
|
||||
{6, 36}, {7, 49}, {8, 64}, {9, 81}};
|
||||
auto start = map.find(3);
|
||||
auto end = map.find(8);
|
||||
auto itr = map.erase(start, end);
|
||||
ASSERT_NE(itr, map.end());
|
||||
EXPECT_THAT(*itr, Pair(8, 64));
|
||||
EXPECT_THAT(map,
|
||||
ElementsAre(Pair(1, 1), Pair(2, 4), Pair(8, 64), Pair(9, 81)));
|
||||
for (int i : {1, 2, 8, 9}) {
|
||||
EXPECT_TRUE(map.contains(i));
|
||||
}
|
||||
for (int i : {3, 4, 5, 6, 7}) {
|
||||
EXPECT_FALSE(map.contains(i));
|
||||
}
|
||||
}
|
||||
|
||||
TEST(LinkedHashMap, InsertInitializerList) {
|
||||
linked_hash_map<int, int> m;
|
||||
m.insert({{1, 7}, {2, 9}, {3, 29}});
|
||||
EXPECT_THAT(m, ElementsAre(Pair(1, 7), Pair(2, 9), Pair(3, 29)));
|
||||
}
|
||||
|
||||
TEST(LinkedHashMap, InsertOrAssign) {
|
||||
linked_hash_map<int, int> m;
|
||||
{
|
||||
auto [itr, elem_inserted] = m.insert_or_assign(10, 20);
|
||||
EXPECT_THAT(*itr, Pair(10, 20));
|
||||
EXPECT_EQ(elem_inserted, true);
|
||||
}
|
||||
{
|
||||
auto [itr, elem_inserted] = m.insert_or_assign(10, 30);
|
||||
EXPECT_THAT(*itr, Pair(10, 30));
|
||||
EXPECT_EQ(elem_inserted, false);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(LinkedHashMap, TryEmplace) {
|
||||
linked_hash_map<int, std::pair<int, std::string>> m;
|
||||
{
|
||||
auto [itr, elem_inserted] = m.try_emplace(10, 20, "string");
|
||||
EXPECT_THAT(*itr, Pair(10, Pair(20, "string")));
|
||||
EXPECT_EQ(elem_inserted, true);
|
||||
}
|
||||
{
|
||||
std::string s = "some string";
|
||||
auto [itr, elem_inserted] = m.try_emplace(10, 2, std::move(s));
|
||||
EXPECT_THAT(*itr, Pair(10, Pair(20, "string")));
|
||||
EXPECT_EQ(elem_inserted, false);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(LinkedHashMapTest, TryEmplace) {
|
||||
linked_hash_map<int, std::tuple<int, std::string, std::unique_ptr<float>>>
|
||||
map;
|
||||
auto result = map.try_emplace(3, 2, "foo", new float(1.0));
|
||||
EXPECT_TRUE(result.second);
|
||||
EXPECT_EQ(std::get<0>(result.first->second), 2);
|
||||
EXPECT_EQ(std::get<1>(result.first->second), "foo");
|
||||
EXPECT_EQ(*std::get<2>(result.first->second), 1.0);
|
||||
|
||||
// Ptr should not be moved.
|
||||
auto ptr = std::make_unique<float>(3.0);
|
||||
auto result2 = map.try_emplace(3, 22, "foo-bar", std::move(ptr));
|
||||
EXPECT_FALSE(result2.second);
|
||||
EXPECT_EQ(std::get<0>(result.first->second), 2);
|
||||
EXPECT_EQ(std::get<1>(result.first->second), "foo");
|
||||
EXPECT_EQ(*std::get<2>(result.first->second), 1.0);
|
||||
EXPECT_NE(ptr.get(), nullptr);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace gtl
|
||||
|
||||
REGISTER_TYPED_TEST_SUITE_P(MapUtilIntIntTest, ValueMapTests,
|
||||
UpdateReturnCopyTest, InsertOrReturnExistingTest,
|
||||
FindOrDieTest, InsertOrDieTest, InsertKeyOrDieTest);
|
||||
typedef ::testing::Types<ortools_gtl::linked_hash_map<int, int>>
|
||||
LinkedHashMapIntIntTypes;
|
||||
INSTANTIATE_TYPED_TEST_SUITE_P(LinkedHashMapUtilTest, MapUtilIntIntTest,
|
||||
LinkedHashMapIntIntTypes);
|
||||
|
||||
REGISTER_TYPED_TEST_SUITE_P(MapUtilIntIntPtrTest, LookupOrInsertNewTest,
|
||||
InsertAndDeleteExistingTest, FindPtrOrNullTest,
|
||||
EraseKeyReturnValuePtrTest);
|
||||
typedef ::testing::Types<ortools_gtl::linked_hash_map<int, int*>>
|
||||
LinkedHashMapIntIntPtrTypes;
|
||||
INSTANTIATE_TYPED_TEST_SUITE_P(LinkedHashMapUtilTest, MapUtilIntIntPtrTest,
|
||||
LinkedHashMapIntIntPtrTypes);
|
||||
59
ortools/base/strtoint_test.cc
Normal file
59
ortools/base/strtoint_test.cc
Normal file
@@ -0,0 +1,59 @@
|
||||
// Copyright 2010-2025 Google LLC
|
||||
// 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.
|
||||
|
||||
#include "ortools/base/strtoint.h"
|
||||
|
||||
#include <limits>
|
||||
#include <string>
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "ortools/base/types.h"
|
||||
|
||||
namespace operations_research {
|
||||
|
||||
TEST(StrutilTest, StrtoFunctions) {
|
||||
// 64-bit conversions are pass-through on all current platforms
|
||||
EXPECT_EQ(0, strtoint64("0"));
|
||||
|
||||
EXPECT_EQ(std::numeric_limits<int64_t>::max(),
|
||||
strtoint64("9223372036854775807"));
|
||||
|
||||
EXPECT_EQ(std::numeric_limits<int64_t>::min(),
|
||||
strtoint64("-9223372036854775808"));
|
||||
|
||||
// safe signed 32-bit conversions within 32-bit range
|
||||
EXPECT_EQ(0, strtoint32("0"));
|
||||
|
||||
EXPECT_EQ(std::numeric_limits<int32_t>::max(), strtoint32("2147483647"));
|
||||
|
||||
EXPECT_EQ(std::numeric_limits<int32_t>::min(), strtoint32("-2147483648"));
|
||||
}
|
||||
|
||||
TEST(StrutilTest, AtoiFunctions) {
|
||||
// basic atoi32/64 functions, including checks for overflow equivalency
|
||||
// even in invalid conversions
|
||||
EXPECT_EQ(0, atoi64("0"));
|
||||
EXPECT_EQ(12345, atoi64("12345"));
|
||||
EXPECT_EQ(-12345, atoi64("-12345"));
|
||||
EXPECT_EQ(std::numeric_limits<int64_t>::max(), atoi64("9223372036854775807"));
|
||||
EXPECT_EQ(std::numeric_limits<int64_t>::min(),
|
||||
atoi64("-9223372036854775808"));
|
||||
|
||||
EXPECT_EQ(0, atoi32("0"));
|
||||
EXPECT_EQ(12345, atoi32("12345"));
|
||||
EXPECT_EQ(-12345, atoi32("-12345"));
|
||||
EXPECT_EQ(std::numeric_limits<int32_t>::max(), atoi32("2147483647"));
|
||||
EXPECT_EQ(std::numeric_limits<int32_t>::min(), atoi32("-2147483648"));
|
||||
}
|
||||
|
||||
} // namespace operations_research
|
||||
Reference in New Issue
Block a user