tvl-depot/absl/container/fixed_array_test.cc

891 lines
26 KiB
C++
Raw Normal View History

2017-09-19 22:54:40 +02:00
// Copyright 2017 The Abseil Authors.
//
// 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
//
// https://www.apache.org/licenses/LICENSE-2.0
2017-09-19 22:54:40 +02:00
//
// 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 "absl/container/fixed_array.h"
#include <stdio.h>
Export of internal Abseil changes. -- ac7508120c60dfe689c40929e416b6a486f83ee3 by Gennadiy Rozental <rogeeff@google.com>: Internal change PiperOrigin-RevId: 206912089 -- bd709faba88565367b6d337466e6456481b5f3e8 by Matt Calabrese <calabrese@google.com>: Implement `std::experimental::is_detected` in type_traits internals and move `is_detected_convertible` from variant's internals to type_traits internals. This is in preparation of creating workarounds for broken standard traits. PiperOrigin-RevId: 206825598 -- 0dbddea569370eb9b6348cee172d1874f9046eb4 by Jorg Brown <jorg@google.com>: Support users who turn on floating-point conversion warnings PiperOrigin-RevId: 206813209 -- 30991f757c8f0100584619d8a9c41897d029f112 by Jorg Brown <jorg@google.com>: Speed up the absl::Seconds() function for floating-point values, roughly by 4.5x, since we can take advantage of the fact that we're just taking a floating-point number and splitting it into its integral and fractional parts. PiperOrigin-RevId: 206806270 -- 6883837176838aa5a517e7a8cb4c99afd24c0d12 by Jon Cohen <cohenjon@google.com>: Remove the DISABLE_INSTALL from absl_container. It doesn't do anything. PiperOrigin-RevId: 206802544 -- 92ab14fed06e6dd1f01a0284bd7f95d3e2c0c3d8 by Jon Cohen <cohenjon@google.com>: Internal change PiperOrigin-RevId: 206776244 -- 17b76c7f364ac562d9e0faeca0320f63aa3fdb85 by Jorg Brown <jorg@google.com>: Fix absl/strings:numbers_test flakiness due to exceeding the 1-minute timeout PiperOrigin-RevId: 206763175 -- 6637843f2e198b8efd90e5577fbc86bdea43b2cc by Abseil Team <absl-team@google.com>: Adds templated allocator to absl::FixedArray with corresponding tests PiperOrigin-RevId: 206354178 -- bced22f81add828c9b4c60eb45554d36c22e2f96 by Abseil Team <absl-team@google.com>: Adds templated allocator to absl::FixedArray with corresponding tests PiperOrigin-RevId: 206347377 -- 75be14a71d2d5e335812d5b7670120271fb5bd79 by Abseil Team <absl-team@google.com>: Internal change. PiperOrigin-RevId: 206326935 -- 6929e43f4c7898b1f51e441911a19092a06fbf97 by Abseil Team <absl-team@google.com>: Adds templated allocator to absl::FixedArray with corresponding tests PiperOrigin-RevId: 206326368 -- 55ae34b75ff029eb267f9519e577bab8a575b487 by Abseil Team <absl-team@google.com>: Internal change. PiperOrigin-RevId: 206233448 -- 6950a8ccddf35d451eec2d02cd28a797c8b7cf6a by Matt Kulukundis <kfm@google.com>: Internal change PiperOrigin-RevId: 206035613 GitOrigin-RevId: ac7508120c60dfe689c40929e416b6a486f83ee3 Change-Id: I675605abbedab6b3ac9aa82195cbd059ff7c82b1
2018-08-01 13:34:12 +02:00
#include <cstring>
2017-09-19 22:54:40 +02:00
#include <list>
#include <memory>
#include <numeric>
Export of internal Abseil changes. -- ac7508120c60dfe689c40929e416b6a486f83ee3 by Gennadiy Rozental <rogeeff@google.com>: Internal change PiperOrigin-RevId: 206912089 -- bd709faba88565367b6d337466e6456481b5f3e8 by Matt Calabrese <calabrese@google.com>: Implement `std::experimental::is_detected` in type_traits internals and move `is_detected_convertible` from variant's internals to type_traits internals. This is in preparation of creating workarounds for broken standard traits. PiperOrigin-RevId: 206825598 -- 0dbddea569370eb9b6348cee172d1874f9046eb4 by Jorg Brown <jorg@google.com>: Support users who turn on floating-point conversion warnings PiperOrigin-RevId: 206813209 -- 30991f757c8f0100584619d8a9c41897d029f112 by Jorg Brown <jorg@google.com>: Speed up the absl::Seconds() function for floating-point values, roughly by 4.5x, since we can take advantage of the fact that we're just taking a floating-point number and splitting it into its integral and fractional parts. PiperOrigin-RevId: 206806270 -- 6883837176838aa5a517e7a8cb4c99afd24c0d12 by Jon Cohen <cohenjon@google.com>: Remove the DISABLE_INSTALL from absl_container. It doesn't do anything. PiperOrigin-RevId: 206802544 -- 92ab14fed06e6dd1f01a0284bd7f95d3e2c0c3d8 by Jon Cohen <cohenjon@google.com>: Internal change PiperOrigin-RevId: 206776244 -- 17b76c7f364ac562d9e0faeca0320f63aa3fdb85 by Jorg Brown <jorg@google.com>: Fix absl/strings:numbers_test flakiness due to exceeding the 1-minute timeout PiperOrigin-RevId: 206763175 -- 6637843f2e198b8efd90e5577fbc86bdea43b2cc by Abseil Team <absl-team@google.com>: Adds templated allocator to absl::FixedArray with corresponding tests PiperOrigin-RevId: 206354178 -- bced22f81add828c9b4c60eb45554d36c22e2f96 by Abseil Team <absl-team@google.com>: Adds templated allocator to absl::FixedArray with corresponding tests PiperOrigin-RevId: 206347377 -- 75be14a71d2d5e335812d5b7670120271fb5bd79 by Abseil Team <absl-team@google.com>: Internal change. PiperOrigin-RevId: 206326935 -- 6929e43f4c7898b1f51e441911a19092a06fbf97 by Abseil Team <absl-team@google.com>: Adds templated allocator to absl::FixedArray with corresponding tests PiperOrigin-RevId: 206326368 -- 55ae34b75ff029eb267f9519e577bab8a575b487 by Abseil Team <absl-team@google.com>: Internal change. PiperOrigin-RevId: 206233448 -- 6950a8ccddf35d451eec2d02cd28a797c8b7cf6a by Matt Kulukundis <kfm@google.com>: Internal change PiperOrigin-RevId: 206035613 GitOrigin-RevId: ac7508120c60dfe689c40929e416b6a486f83ee3 Change-Id: I675605abbedab6b3ac9aa82195cbd059ff7c82b1
2018-08-01 13:34:12 +02:00
#include <scoped_allocator>
2017-09-19 22:54:40 +02:00
#include <stdexcept>
#include <string>
#include <vector>
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "absl/base/internal/exception_testing.h"
Export of internal Abseil changes. -- 1c1d6e2404dfc6caa022b335df5acdac6da50fe1 by Derek Mauro <dmauro@google.com>: Fix the internal namespacing in unaligned_access.h PiperOrigin-RevId: 215434506 -- 17d4400aebf025a230690fc1c7a968ef8d85bbba by Eric Fiselier <ericwf@google.com>: gtest depends on the GCC extension allowing variadic macros to be passed a empty parameter pack for ..., but LLVM diagnoses this as a GNU extension. This patch suppresses the warning when building the absl tests. PiperOrigin-RevId: 215426161 -- f2c49dde23a9f445b9de963f1bbe840ebb568b30 by Eric Fiselier <ericwf@google.com>: Use EXPECT_DEATH_IF_SUPPORTED instead of EXPECT_DEATH. This avoids breaking the test when gtest doesn't support death tests. PiperOrigin-RevId: 215423849 -- cd687c1e121709603f4fc3726b534f6a9c52cc89 by Eric Fiselier <ericwf@google.com>: Disable LLVM's -Wmissing-variable-declarations in tests. GCC's configuration already disables this via -Wno-missing-declarations, this change makes LLVM do the same. The warning would otherwise flag most tests which use ABSL_FLAG. PiperOrigin-RevId: 215407429 -- d14098824c84e3a8c8f6fb920e0335fb48fe2010 by Eric Fiselier <ericwf@google.com>: Fix local variable shadowing in city hash implementation. PiperOrigin-RevId: 215407249 -- 4b5e140ba743f0d231790a26c49083abb4329e2c by Abseil Team <absl-team@google.com>: Make raw_hash_set::reserve 2X fast when reserve doesn't do any allocation. Make raw_hash_set::reserve ~1% faster when reserve does some (128~4k) allocation. PiperOrigin-RevId: 215348727 -- 461161e65e04b801480aa117af2534c594654ccf by Eric Fiselier <ericwf@google.com>: Internal change PiperOrigin-RevId: 215272283 -- 50413ae31ad3d3a177257416acd8ede47a17bff2 by Eric Fiselier <ericwf@google.com>: Internal Change PiperOrigin-RevId: 215233183 -- 477be54c43d61019a8fe4e190e340eb52737d383 by Abseil Team <absl-team@google.com>: Clarify misleading comment on ABSL_ATTRIBUTE_UNUSED PiperOrigin-RevId: 215185496 -- 2cafa2b5287507d3a946682aee9ab13af6d471c9 by Matt Kulukundis <kfm@google.com>: Add support for absl::Hash to various absl in types. PiperOrigin-RevId: 215039569 -- 082248901991aa3d29be0ea3689c7f213cf0fd83 by Derek Mauro <dmauro@google.com>: Remove an instance of HAS_GLOBAL_STRING from hash_function_defaults.h PiperOrigin-RevId: 214989094 -- b929f61907f0786a6133e3a9d7287e339c0a0acb by Derek Mauro <dmauro@google.com>: Internal import of Github #174 Fix code snippet in comment https://github.com/abseil/abseil-cpp/pull/174 PiperOrigin-RevId: 214958849 -- f2c5e829eca11c352e121f56eefbf87083305023 by Derek Mauro <dmauro@google.com>: Internal import of GitHub #173 Fix CMake build for absl::container. https://github.com/abseil/abseil-cpp/pull/173 PiperOrigin-RevId: 214957796 -- d704f860f9fddafb99e34e6c5032e49f73874e10 by Abseil Team <absl-team@google.com>: Internal change PiperOrigin-RevId: 214828181 GitOrigin-RevId: 1c1d6e2404dfc6caa022b335df5acdac6da50fe1 Change-Id: I551de2b1ba0cbaf6856cd5959358cf6651179dea
2018-10-02 21:09:18 +02:00
#include "absl/hash/hash_testing.h"
2017-09-19 22:54:40 +02:00
#include "absl/memory/memory.h"
using ::testing::ElementsAreArray;
2017-09-19 22:54:40 +02:00
namespace {
// Helper routine to determine if a absl::FixedArray used stack allocation.
template <typename ArrayType>
static bool IsOnStack(const ArrayType& a) {
return a.size() <= ArrayType::inline_elements;
}
class ConstructionTester {
public:
ConstructionTester()
: self_ptr_(this),
value_(0) {
constructions++;
}
~ConstructionTester() {
assert(self_ptr_ == this);
self_ptr_ = nullptr;
destructions++;
}
// These are incremented as elements are constructed and destructed so we can
// be sure all elements are properly cleaned up.
static int constructions;
static int destructions;
void CheckConstructed() {
assert(self_ptr_ == this);
}
void set(int value) { value_ = value; }
int get() { return value_; }
private:
// self_ptr_ should always point to 'this' -- that's how we can be sure the
// constructor has been called.
ConstructionTester* self_ptr_;
int value_;
};
int ConstructionTester::constructions = 0;
int ConstructionTester::destructions = 0;
// ThreeInts will initialize its three ints to the value stored in
// ThreeInts::counter. The constructor increments counter so that each object
// in an array of ThreeInts will have different values.
class ThreeInts {
public:
ThreeInts() {
x_ = counter;
y_ = counter;
z_ = counter;
++counter;
}
static int counter;
int x_, y_, z_;
};
int ThreeInts::counter = 0;
TEST(FixedArrayTest, CopyCtor) {
absl::FixedArray<int, 10> on_stack(5);
std::iota(on_stack.begin(), on_stack.end(), 0);
absl::FixedArray<int, 10> stack_copy = on_stack;
EXPECT_THAT(stack_copy, ElementsAreArray(on_stack));
EXPECT_TRUE(IsOnStack(stack_copy));
absl::FixedArray<int, 10> allocated(15);
std::iota(allocated.begin(), allocated.end(), 0);
absl::FixedArray<int, 10> alloced_copy = allocated;
EXPECT_THAT(alloced_copy, ElementsAreArray(allocated));
EXPECT_FALSE(IsOnStack(alloced_copy));
}
TEST(FixedArrayTest, MoveCtor) {
absl::FixedArray<std::unique_ptr<int>, 10> on_stack(5);
for (int i = 0; i < 5; ++i) {
on_stack[i] = absl::make_unique<int>(i);
}
absl::FixedArray<std::unique_ptr<int>, 10> stack_copy = std::move(on_stack);
for (int i = 0; i < 5; ++i) EXPECT_EQ(*(stack_copy[i]), i);
EXPECT_EQ(stack_copy.size(), on_stack.size());
absl::FixedArray<std::unique_ptr<int>, 10> allocated(15);
for (int i = 0; i < 15; ++i) {
allocated[i] = absl::make_unique<int>(i);
}
absl::FixedArray<std::unique_ptr<int>, 10> alloced_copy =
std::move(allocated);
for (int i = 0; i < 15; ++i) EXPECT_EQ(*(alloced_copy[i]), i);
EXPECT_EQ(allocated.size(), alloced_copy.size());
}
2017-09-19 22:54:40 +02:00
TEST(FixedArrayTest, SmallObjects) {
// Small object arrays
{
// Short arrays should be on the stack
absl::FixedArray<int> array(4);
EXPECT_TRUE(IsOnStack(array));
}
{
// Large arrays should be on the heap
absl::FixedArray<int> array(1048576);
EXPECT_FALSE(IsOnStack(array));
}
{
// Arrays of <= default size should be on the stack
absl::FixedArray<int, 100> array(100);
EXPECT_TRUE(IsOnStack(array));
}
{
// Arrays of > default size should be on the heap
2017-09-19 22:54:40 +02:00
absl::FixedArray<int, 100> array(101);
EXPECT_FALSE(IsOnStack(array));
}
{
// Arrays with different size elements should use approximately
// same amount of stack space
absl::FixedArray<int> array1(0);
absl::FixedArray<char> array2(0);
EXPECT_LE(sizeof(array1), sizeof(array2)+100);
EXPECT_LE(sizeof(array2), sizeof(array1)+100);
}
{
// Ensure that vectors are properly constructed inside a fixed array.
absl::FixedArray<std::vector<int> > array(2);
EXPECT_EQ(0, array[0].size());
EXPECT_EQ(0, array[1].size());
}
{
// Regardless of absl::FixedArray implementation, check that a type with a
// low alignment requirement and a non power-of-two size is initialized
// correctly.
ThreeInts::counter = 1;
absl::FixedArray<ThreeInts> array(2);
EXPECT_EQ(1, array[0].x_);
EXPECT_EQ(1, array[0].y_);
EXPECT_EQ(1, array[0].z_);
EXPECT_EQ(2, array[1].x_);
EXPECT_EQ(2, array[1].y_);
EXPECT_EQ(2, array[1].z_);
}
}
TEST(FixedArrayTest, AtThrows) {
absl::FixedArray<int> a = {1, 2, 3};
EXPECT_EQ(a.at(2), 3);
ABSL_BASE_INTERNAL_EXPECT_FAIL(a.at(3), std::out_of_range,
"failed bounds check");
}
TEST(FixedArrayRelationalsTest, EqualArrays) {
for (int i = 0; i < 10; ++i) {
absl::FixedArray<int, 5> a1(i);
std::iota(a1.begin(), a1.end(), 0);
absl::FixedArray<int, 5> a2(a1.begin(), a1.end());
EXPECT_TRUE(a1 == a2);
EXPECT_FALSE(a1 != a2);
EXPECT_TRUE(a2 == a1);
EXPECT_FALSE(a2 != a1);
EXPECT_FALSE(a1 < a2);
EXPECT_FALSE(a1 > a2);
EXPECT_FALSE(a2 < a1);
EXPECT_FALSE(a2 > a1);
EXPECT_TRUE(a1 <= a2);
EXPECT_TRUE(a1 >= a2);
EXPECT_TRUE(a2 <= a1);
EXPECT_TRUE(a2 >= a1);
}
}
TEST(FixedArrayRelationalsTest, UnequalArrays) {
for (int i = 1; i < 10; ++i) {
absl::FixedArray<int, 5> a1(i);
std::iota(a1.begin(), a1.end(), 0);
absl::FixedArray<int, 5> a2(a1.begin(), a1.end());
--a2[i / 2];
EXPECT_FALSE(a1 == a2);
EXPECT_TRUE(a1 != a2);
EXPECT_FALSE(a2 == a1);
EXPECT_TRUE(a2 != a1);
EXPECT_FALSE(a1 < a2);
EXPECT_TRUE(a1 > a2);
EXPECT_TRUE(a2 < a1);
EXPECT_FALSE(a2 > a1);
EXPECT_FALSE(a1 <= a2);
EXPECT_TRUE(a1 >= a2);
EXPECT_TRUE(a2 <= a1);
EXPECT_FALSE(a2 >= a1);
}
}
template <int stack_elements>
static void TestArray(int n) {
SCOPED_TRACE(n);
SCOPED_TRACE(stack_elements);
ConstructionTester::constructions = 0;
ConstructionTester::destructions = 0;
{
absl::FixedArray<ConstructionTester, stack_elements> array(n);
EXPECT_THAT(array.size(), n);
EXPECT_THAT(array.memsize(), sizeof(ConstructionTester) * n);
EXPECT_THAT(array.begin() + n, array.end());
// Check that all elements were constructed
for (int i = 0; i < n; i++) {
array[i].CheckConstructed();
}
// Check that no other elements were constructed
EXPECT_THAT(ConstructionTester::constructions, n);
// Test operator[]
for (int i = 0; i < n; i++) {
array[i].set(i);
}
for (int i = 0; i < n; i++) {
EXPECT_THAT(array[i].get(), i);
EXPECT_THAT(array.data()[i].get(), i);
}
// Test data()
for (int i = 0; i < n; i++) {
array.data()[i].set(i + 1);
}
for (int i = 0; i < n; i++) {
EXPECT_THAT(array[i].get(), i+1);
EXPECT_THAT(array.data()[i].get(), i+1);
}
} // Close scope containing 'array'.
// Check that all constructed elements were destructed.
EXPECT_EQ(ConstructionTester::constructions,
ConstructionTester::destructions);
}
template <int elements_per_inner_array, int inline_elements>
static void TestArrayOfArrays(int n) {
SCOPED_TRACE(n);
SCOPED_TRACE(inline_elements);
SCOPED_TRACE(elements_per_inner_array);
ConstructionTester::constructions = 0;
ConstructionTester::destructions = 0;
{
using InnerArray = ConstructionTester[elements_per_inner_array];
// Heap-allocate the FixedArray to avoid blowing the stack frame.
auto array_ptr =
absl::make_unique<absl::FixedArray<InnerArray, inline_elements>>(n);
auto& array = *array_ptr;
ASSERT_EQ(array.size(), n);
ASSERT_EQ(array.memsize(),
sizeof(ConstructionTester) * elements_per_inner_array * n);
ASSERT_EQ(array.begin() + n, array.end());
// Check that all elements were constructed
for (int i = 0; i < n; i++) {
for (int j = 0; j < elements_per_inner_array; j++) {
(array[i])[j].CheckConstructed();
}
}
// Check that no other elements were constructed
ASSERT_EQ(ConstructionTester::constructions, n * elements_per_inner_array);
// Test operator[]
for (int i = 0; i < n; i++) {
for (int j = 0; j < elements_per_inner_array; j++) {
(array[i])[j].set(i * elements_per_inner_array + j);
}
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < elements_per_inner_array; j++) {
ASSERT_EQ((array[i])[j].get(), i * elements_per_inner_array + j);
ASSERT_EQ((array.data()[i])[j].get(), i * elements_per_inner_array + j);
}
}
// Test data()
for (int i = 0; i < n; i++) {
for (int j = 0; j < elements_per_inner_array; j++) {
(array.data()[i])[j].set((i + 1) * elements_per_inner_array + j);
}
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < elements_per_inner_array; j++) {
ASSERT_EQ((array[i])[j].get(),
(i + 1) * elements_per_inner_array + j);
ASSERT_EQ((array.data()[i])[j].get(),
(i + 1) * elements_per_inner_array + j);
}
}
} // Close scope containing 'array'.
// Check that all constructed elements were destructed.
EXPECT_EQ(ConstructionTester::constructions,
ConstructionTester::destructions);
}
TEST(IteratorConstructorTest, NonInline) {
int const kInput[] = { 2, 3, 5, 7, 11, 13, 17 };
absl::FixedArray<int, ABSL_ARRAYSIZE(kInput) - 1> const fixed(
kInput, kInput + ABSL_ARRAYSIZE(kInput));
ASSERT_EQ(ABSL_ARRAYSIZE(kInput), fixed.size());
for (size_t i = 0; i < ABSL_ARRAYSIZE(kInput); ++i) {
ASSERT_EQ(kInput[i], fixed[i]);
}
}
TEST(IteratorConstructorTest, Inline) {
int const kInput[] = { 2, 3, 5, 7, 11, 13, 17 };
absl::FixedArray<int, ABSL_ARRAYSIZE(kInput)> const fixed(
kInput, kInput + ABSL_ARRAYSIZE(kInput));
ASSERT_EQ(ABSL_ARRAYSIZE(kInput), fixed.size());
for (size_t i = 0; i < ABSL_ARRAYSIZE(kInput); ++i) {
ASSERT_EQ(kInput[i], fixed[i]);
}
}
TEST(IteratorConstructorTest, NonPod) {
char const* kInput[] =
{ "red", "orange", "yellow", "green", "blue", "indigo", "violet" };
absl::FixedArray<std::string> const fixed(kInput,
kInput + ABSL_ARRAYSIZE(kInput));
2017-09-19 22:54:40 +02:00
ASSERT_EQ(ABSL_ARRAYSIZE(kInput), fixed.size());
for (size_t i = 0; i < ABSL_ARRAYSIZE(kInput); ++i) {
ASSERT_EQ(kInput[i], fixed[i]);
}
}
TEST(IteratorConstructorTest, FromEmptyVector) {
std::vector<int> const empty;
absl::FixedArray<int> const fixed(empty.begin(), empty.end());
EXPECT_EQ(0, fixed.size());
EXPECT_EQ(empty.size(), fixed.size());
}
TEST(IteratorConstructorTest, FromNonEmptyVector) {
int const kInput[] = { 2, 3, 5, 7, 11, 13, 17 };
std::vector<int> const items(kInput, kInput + ABSL_ARRAYSIZE(kInput));
absl::FixedArray<int> const fixed(items.begin(), items.end());
ASSERT_EQ(items.size(), fixed.size());
for (size_t i = 0; i < items.size(); ++i) {
ASSERT_EQ(items[i], fixed[i]);
}
}
TEST(IteratorConstructorTest, FromBidirectionalIteratorRange) {
int const kInput[] = { 2, 3, 5, 7, 11, 13, 17 };
std::list<int> const items(kInput, kInput + ABSL_ARRAYSIZE(kInput));
absl::FixedArray<int> const fixed(items.begin(), items.end());
EXPECT_THAT(fixed, testing::ElementsAreArray(kInput));
}
TEST(InitListConstructorTest, InitListConstruction) {
absl::FixedArray<int> fixed = {1, 2, 3};
EXPECT_THAT(fixed, testing::ElementsAreArray({1, 2, 3}));
}
TEST(FillConstructorTest, NonEmptyArrays) {
absl::FixedArray<int> stack_array(4, 1);
EXPECT_THAT(stack_array, testing::ElementsAreArray({1, 1, 1, 1}));
absl::FixedArray<int, 0> heap_array(4, 1);
EXPECT_THAT(stack_array, testing::ElementsAreArray({1, 1, 1, 1}));
}
TEST(FillConstructorTest, EmptyArray) {
absl::FixedArray<int> empty_fill(0, 1);
absl::FixedArray<int> empty_size(0);
EXPECT_EQ(empty_fill, empty_size);
}
TEST(FillConstructorTest, NotTriviallyCopyable) {
std::string str = "abcd";
absl::FixedArray<std::string> strings = {str, str, str, str};
absl::FixedArray<std::string> array(4, str);
EXPECT_EQ(array, strings);
}
TEST(FillConstructorTest, Disambiguation) {
absl::FixedArray<size_t> a(1, 2);
EXPECT_THAT(a, testing::ElementsAre(2));
}
TEST(FixedArrayTest, ManySizedArrays) {
std::vector<int> sizes;
for (int i = 1; i < 100; i++) sizes.push_back(i);
for (int i = 100; i <= 1000; i += 100) sizes.push_back(i);
for (int n : sizes) {
TestArray<0>(n);
TestArray<1>(n);
TestArray<64>(n);
TestArray<1000>(n);
}
}
TEST(FixedArrayTest, ManySizedArraysOfArraysOf1) {
for (int n = 1; n < 1000; n++) {
ASSERT_NO_FATAL_FAILURE((TestArrayOfArrays<1, 0>(n)));
ASSERT_NO_FATAL_FAILURE((TestArrayOfArrays<1, 1>(n)));
ASSERT_NO_FATAL_FAILURE((TestArrayOfArrays<1, 64>(n)));
ASSERT_NO_FATAL_FAILURE((TestArrayOfArrays<1, 1000>(n)));
}
}
TEST(FixedArrayTest, ManySizedArraysOfArraysOf2) {
for (int n = 1; n < 1000; n++) {
TestArrayOfArrays<2, 0>(n);
TestArrayOfArrays<2, 1>(n);
TestArrayOfArrays<2, 64>(n);
TestArrayOfArrays<2, 1000>(n);
}
}
// If value_type is put inside of a struct container,
// we might evoke this error in a hardened build unless data() is carefully
// written, so check on that.
// error: call to int __builtin___sprintf_chk(etc...)
// will always overflow destination buffer [-Werror]
TEST(FixedArrayTest, AvoidParanoidDiagnostics) {
absl::FixedArray<char, 32> buf(32);
sprintf(buf.data(), "foo"); // NOLINT(runtime/printf)
}
TEST(FixedArrayTest, TooBigInlinedSpace) {
struct TooBig {
char c[1 << 20];
}; // too big for even one on the stack
// Simulate the data members of absl::FixedArray, a pointer and a size_t.
struct Data {
TooBig* p;
size_t size;
};
// Make sure TooBig objects are not inlined for 0 or default size.
static_assert(sizeof(absl::FixedArray<TooBig, 0>) == sizeof(Data),
"0-sized absl::FixedArray should have same size as Data.");
static_assert(alignof(absl::FixedArray<TooBig, 0>) == alignof(Data),
"0-sized absl::FixedArray should have same alignment as Data.");
static_assert(sizeof(absl::FixedArray<TooBig>) == sizeof(Data),
"default-sized absl::FixedArray should have same size as Data");
static_assert(
alignof(absl::FixedArray<TooBig>) == alignof(Data),
"default-sized absl::FixedArray should have same alignment as Data.");
}
// PickyDelete EXPECTs its class-scope deallocation funcs are unused.
struct PickyDelete {
PickyDelete() {}
~PickyDelete() {}
void operator delete(void* p) {
EXPECT_TRUE(false) << __FUNCTION__;
::operator delete(p);
}
void operator delete[](void* p) {
EXPECT_TRUE(false) << __FUNCTION__;
::operator delete[](p);
}
};
TEST(FixedArrayTest, UsesGlobalAlloc) { absl::FixedArray<PickyDelete, 0> a(5); }
2017-09-19 22:54:40 +02:00
TEST(FixedArrayTest, Data) {
static const int kInput[] = { 2, 3, 5, 7, 11, 13, 17 };
absl::FixedArray<int> fa(std::begin(kInput), std::end(kInput));
EXPECT_EQ(fa.data(), &*fa.begin());
EXPECT_EQ(fa.data(), &fa[0]);
const absl::FixedArray<int>& cfa = fa;
EXPECT_EQ(cfa.data(), &*cfa.begin());
EXPECT_EQ(cfa.data(), &cfa[0]);
}
TEST(FixedArrayTest, Empty) {
absl::FixedArray<int> empty(0);
absl::FixedArray<int> inline_filled(1);
absl::FixedArray<int, 0> heap_filled(1);
EXPECT_TRUE(empty.empty());
EXPECT_FALSE(inline_filled.empty());
EXPECT_FALSE(heap_filled.empty());
}
TEST(FixedArrayTest, FrontAndBack) {
absl::FixedArray<int, 3 * sizeof(int)> inlined = {1, 2, 3};
EXPECT_EQ(inlined.front(), 1);
EXPECT_EQ(inlined.back(), 3);
absl::FixedArray<int, 0> allocated = {1, 2, 3};
EXPECT_EQ(allocated.front(), 1);
EXPECT_EQ(allocated.back(), 3);
absl::FixedArray<int> one_element = {1};
EXPECT_EQ(one_element.front(), one_element.back());
}
TEST(FixedArrayTest, ReverseIteratorInlined) {
absl::FixedArray<int, 5 * sizeof(int)> a = {0, 1, 2, 3, 4};
int counter = 5;
for (absl::FixedArray<int>::reverse_iterator iter = a.rbegin();
iter != a.rend(); ++iter) {
counter--;
EXPECT_EQ(counter, *iter);
}
EXPECT_EQ(counter, 0);
counter = 5;
for (absl::FixedArray<int>::const_reverse_iterator iter = a.rbegin();
iter != a.rend(); ++iter) {
counter--;
EXPECT_EQ(counter, *iter);
}
EXPECT_EQ(counter, 0);
counter = 5;
for (auto iter = a.crbegin(); iter != a.crend(); ++iter) {
counter--;
EXPECT_EQ(counter, *iter);
}
EXPECT_EQ(counter, 0);
}
TEST(FixedArrayTest, ReverseIteratorAllocated) {
absl::FixedArray<int, 0> a = {0, 1, 2, 3, 4};
int counter = 5;
for (absl::FixedArray<int>::reverse_iterator iter = a.rbegin();
iter != a.rend(); ++iter) {
counter--;
EXPECT_EQ(counter, *iter);
}
EXPECT_EQ(counter, 0);
counter = 5;
for (absl::FixedArray<int>::const_reverse_iterator iter = a.rbegin();
iter != a.rend(); ++iter) {
counter--;
EXPECT_EQ(counter, *iter);
}
EXPECT_EQ(counter, 0);
counter = 5;
for (auto iter = a.crbegin(); iter != a.crend(); ++iter) {
counter--;
EXPECT_EQ(counter, *iter);
}
EXPECT_EQ(counter, 0);
}
TEST(FixedArrayTest, Fill) {
absl::FixedArray<int, 5 * sizeof(int)> inlined(5);
int fill_val = 42;
inlined.fill(fill_val);
for (int i : inlined) EXPECT_EQ(i, fill_val);
absl::FixedArray<int, 0> allocated(5);
allocated.fill(fill_val);
for (int i : allocated) EXPECT_EQ(i, fill_val);
// It doesn't do anything, just make sure this compiles.
absl::FixedArray<int> empty(0);
empty.fill(fill_val);
}
Export of internal Abseil changes. -- ac7508120c60dfe689c40929e416b6a486f83ee3 by Gennadiy Rozental <rogeeff@google.com>: Internal change PiperOrigin-RevId: 206912089 -- bd709faba88565367b6d337466e6456481b5f3e8 by Matt Calabrese <calabrese@google.com>: Implement `std::experimental::is_detected` in type_traits internals and move `is_detected_convertible` from variant's internals to type_traits internals. This is in preparation of creating workarounds for broken standard traits. PiperOrigin-RevId: 206825598 -- 0dbddea569370eb9b6348cee172d1874f9046eb4 by Jorg Brown <jorg@google.com>: Support users who turn on floating-point conversion warnings PiperOrigin-RevId: 206813209 -- 30991f757c8f0100584619d8a9c41897d029f112 by Jorg Brown <jorg@google.com>: Speed up the absl::Seconds() function for floating-point values, roughly by 4.5x, since we can take advantage of the fact that we're just taking a floating-point number and splitting it into its integral and fractional parts. PiperOrigin-RevId: 206806270 -- 6883837176838aa5a517e7a8cb4c99afd24c0d12 by Jon Cohen <cohenjon@google.com>: Remove the DISABLE_INSTALL from absl_container. It doesn't do anything. PiperOrigin-RevId: 206802544 -- 92ab14fed06e6dd1f01a0284bd7f95d3e2c0c3d8 by Jon Cohen <cohenjon@google.com>: Internal change PiperOrigin-RevId: 206776244 -- 17b76c7f364ac562d9e0faeca0320f63aa3fdb85 by Jorg Brown <jorg@google.com>: Fix absl/strings:numbers_test flakiness due to exceeding the 1-minute timeout PiperOrigin-RevId: 206763175 -- 6637843f2e198b8efd90e5577fbc86bdea43b2cc by Abseil Team <absl-team@google.com>: Adds templated allocator to absl::FixedArray with corresponding tests PiperOrigin-RevId: 206354178 -- bced22f81add828c9b4c60eb45554d36c22e2f96 by Abseil Team <absl-team@google.com>: Adds templated allocator to absl::FixedArray with corresponding tests PiperOrigin-RevId: 206347377 -- 75be14a71d2d5e335812d5b7670120271fb5bd79 by Abseil Team <absl-team@google.com>: Internal change. PiperOrigin-RevId: 206326935 -- 6929e43f4c7898b1f51e441911a19092a06fbf97 by Abseil Team <absl-team@google.com>: Adds templated allocator to absl::FixedArray with corresponding tests PiperOrigin-RevId: 206326368 -- 55ae34b75ff029eb267f9519e577bab8a575b487 by Abseil Team <absl-team@google.com>: Internal change. PiperOrigin-RevId: 206233448 -- 6950a8ccddf35d451eec2d02cd28a797c8b7cf6a by Matt Kulukundis <kfm@google.com>: Internal change PiperOrigin-RevId: 206035613 GitOrigin-RevId: ac7508120c60dfe689c40929e416b6a486f83ee3 Change-Id: I675605abbedab6b3ac9aa82195cbd059ff7c82b1
2018-08-01 13:34:12 +02:00
// TODO(johnsoncj): Investigate InlinedStorage default initialization in GCC 4.x
#ifndef __GNUC__
TEST(FixedArrayTest, DefaultCtorDoesNotValueInit) {
using T = char;
constexpr auto capacity = 10;
using FixedArrType = absl::FixedArray<T, capacity>;
using FixedArrBuffType =
absl::aligned_storage_t<sizeof(FixedArrType), alignof(FixedArrType)>;
constexpr auto scrubbed_bits = 0x95;
constexpr auto length = capacity / 2;
FixedArrBuffType buff;
std::memset(std::addressof(buff), scrubbed_bits, sizeof(FixedArrBuffType));
FixedArrType* arr =
::new (static_cast<void*>(std::addressof(buff))) FixedArrType(length);
EXPECT_THAT(*arr, testing::Each(scrubbed_bits));
arr->~FixedArrType();
}
#endif // __GNUC__
// This is a stateful allocator, but the state lives outside of the
// allocator (in whatever test is using the allocator). This is odd
// but helps in tests where the allocator is propagated into nested
// containers - that chain of allocators uses the same state and is
// thus easier to query for aggregate allocation information.
template <typename T>
class CountingAllocator : public std::allocator<T> {
public:
using Alloc = std::allocator<T>;
using pointer = typename Alloc::pointer;
using size_type = typename Alloc::size_type;
CountingAllocator() : bytes_used_(nullptr), instance_count_(nullptr) {}
explicit CountingAllocator(int64_t* b)
: bytes_used_(b), instance_count_(nullptr) {}
CountingAllocator(int64_t* b, int64_t* a)
: bytes_used_(b), instance_count_(a) {}
template <typename U>
explicit CountingAllocator(const CountingAllocator<U>& x)
: Alloc(x),
bytes_used_(x.bytes_used_),
instance_count_(x.instance_count_) {}
pointer allocate(size_type n, const void* const hint = nullptr) {
assert(bytes_used_ != nullptr);
*bytes_used_ += n * sizeof(T);
return Alloc::allocate(n, hint);
}
void deallocate(pointer p, size_type n) {
Alloc::deallocate(p, n);
assert(bytes_used_ != nullptr);
*bytes_used_ -= n * sizeof(T);
}
template <typename... Args>
void construct(pointer p, Args&&... args) {
Alloc::construct(p, absl::forward<Args>(args)...);
if (instance_count_) {
*instance_count_ += 1;
}
}
void destroy(pointer p) {
Alloc::destroy(p);
if (instance_count_) {
*instance_count_ -= 1;
}
}
template <typename U>
class rebind {
public:
using other = CountingAllocator<U>;
};
int64_t* bytes_used_;
int64_t* instance_count_;
};
TEST(AllocatorSupportTest, CountInlineAllocations) {
constexpr size_t inlined_size = 4;
using Alloc = CountingAllocator<int>;
using AllocFxdArr = absl::FixedArray<int, inlined_size, Alloc>;
int64_t allocated = 0;
int64_t active_instances = 0;
{
const int ia[] = {0, 1, 2, 3, 4, 5, 6, 7};
Alloc alloc(&allocated, &active_instances);
AllocFxdArr arr(ia, ia + inlined_size, alloc);
static_cast<void>(arr);
}
EXPECT_EQ(allocated, 0);
EXPECT_EQ(active_instances, 0);
}
TEST(AllocatorSupportTest, CountOutoflineAllocations) {
constexpr size_t inlined_size = 4;
using Alloc = CountingAllocator<int>;
using AllocFxdArr = absl::FixedArray<int, inlined_size, Alloc>;
int64_t allocated = 0;
int64_t active_instances = 0;
{
const int ia[] = {0, 1, 2, 3, 4, 5, 6, 7};
Alloc alloc(&allocated, &active_instances);
AllocFxdArr arr(ia, ia + ABSL_ARRAYSIZE(ia), alloc);
EXPECT_EQ(allocated, arr.size() * sizeof(int));
static_cast<void>(arr);
}
EXPECT_EQ(active_instances, 0);
}
TEST(AllocatorSupportTest, CountCopyInlineAllocations) {
constexpr size_t inlined_size = 4;
using Alloc = CountingAllocator<int>;
using AllocFxdArr = absl::FixedArray<int, inlined_size, Alloc>;
int64_t allocated1 = 0;
int64_t allocated2 = 0;
int64_t active_instances = 0;
Alloc alloc(&allocated1, &active_instances);
Alloc alloc2(&allocated2, &active_instances);
{
int initial_value = 1;
AllocFxdArr arr1(inlined_size / 2, initial_value, alloc);
EXPECT_EQ(allocated1, 0);
AllocFxdArr arr2(arr1, alloc2);
EXPECT_EQ(allocated2, 0);
static_cast<void>(arr1);
static_cast<void>(arr2);
}
EXPECT_EQ(active_instances, 0);
}
TEST(AllocatorSupportTest, CountCopyOutoflineAllocations) {
constexpr size_t inlined_size = 4;
using Alloc = CountingAllocator<int>;
using AllocFxdArr = absl::FixedArray<int, inlined_size, Alloc>;
int64_t allocated1 = 0;
int64_t allocated2 = 0;
int64_t active_instances = 0;
Alloc alloc(&allocated1, &active_instances);
Alloc alloc2(&allocated2, &active_instances);
{
int initial_value = 1;
AllocFxdArr arr1(inlined_size * 2, initial_value, alloc);
EXPECT_EQ(allocated1, arr1.size() * sizeof(int));
AllocFxdArr arr2(arr1, alloc2);
EXPECT_EQ(allocated2, inlined_size * 2 * sizeof(int));
static_cast<void>(arr1);
static_cast<void>(arr2);
}
EXPECT_EQ(active_instances, 0);
}
TEST(AllocatorSupportTest, SizeValAllocConstructor) {
using testing::AllOf;
using testing::Each;
using testing::SizeIs;
constexpr size_t inlined_size = 4;
using Alloc = CountingAllocator<int>;
using AllocFxdArr = absl::FixedArray<int, inlined_size, Alloc>;
{
auto len = inlined_size / 2;
auto val = 0;
int64_t allocated = 0;
AllocFxdArr arr(len, val, Alloc(&allocated));
EXPECT_EQ(allocated, 0);
EXPECT_THAT(arr, AllOf(SizeIs(len), Each(0)));
}
{
auto len = inlined_size * 2;
auto val = 0;
int64_t allocated = 0;
AllocFxdArr arr(len, val, Alloc(&allocated));
EXPECT_EQ(allocated, len * sizeof(int));
EXPECT_THAT(arr, AllOf(SizeIs(len), Each(0)));
}
}
2017-09-19 22:54:40 +02:00
#ifdef ADDRESS_SANITIZER
TEST(FixedArrayTest, AddressSanitizerAnnotations1) {
absl::FixedArray<int, 32> a(10);
int *raw = a.data();
raw[0] = 0;
raw[9] = 0;
EXPECT_DEATH(raw[-2] = 0, "container-overflow");
EXPECT_DEATH(raw[-1] = 0, "container-overflow");
EXPECT_DEATH(raw[10] = 0, "container-overflow");
EXPECT_DEATH(raw[31] = 0, "container-overflow");
}
TEST(FixedArrayTest, AddressSanitizerAnnotations2) {
absl::FixedArray<char, 17> a(12);
char *raw = a.data();
raw[0] = 0;
raw[11] = 0;
EXPECT_DEATH(raw[-7] = 0, "container-overflow");
EXPECT_DEATH(raw[-1] = 0, "container-overflow");
EXPECT_DEATH(raw[12] = 0, "container-overflow");
EXPECT_DEATH(raw[17] = 0, "container-overflow");
}
TEST(FixedArrayTest, AddressSanitizerAnnotations3) {
absl::FixedArray<uint64_t, 20> a(20);
uint64_t *raw = a.data();
raw[0] = 0;
raw[19] = 0;
EXPECT_DEATH(raw[-1] = 0, "container-overflow");
EXPECT_DEATH(raw[20] = 0, "container-overflow");
}
TEST(FixedArrayTest, AddressSanitizerAnnotations4) {
absl::FixedArray<ThreeInts> a(10);
ThreeInts *raw = a.data();
raw[0] = ThreeInts();
raw[9] = ThreeInts();
// Note: raw[-1] is pointing to 12 bytes before the container range. However,
// there is only a 8-byte red zone before the container range, so we only
// access the last 4 bytes of the struct to make sure it stays within the red
// zone.
EXPECT_DEATH(raw[-1].z_ = 0, "container-overflow");
EXPECT_DEATH(raw[10] = ThreeInts(), "container-overflow");
// The actual size of storage is kDefaultBytes=256, 21*12 = 252,
// so reading raw[21] should still trigger the correct warning.
EXPECT_DEATH(raw[21] = ThreeInts(), "container-overflow");
}
#endif // ADDRESS_SANITIZER
Export of internal Abseil changes. -- 1c1d6e2404dfc6caa022b335df5acdac6da50fe1 by Derek Mauro <dmauro@google.com>: Fix the internal namespacing in unaligned_access.h PiperOrigin-RevId: 215434506 -- 17d4400aebf025a230690fc1c7a968ef8d85bbba by Eric Fiselier <ericwf@google.com>: gtest depends on the GCC extension allowing variadic macros to be passed a empty parameter pack for ..., but LLVM diagnoses this as a GNU extension. This patch suppresses the warning when building the absl tests. PiperOrigin-RevId: 215426161 -- f2c49dde23a9f445b9de963f1bbe840ebb568b30 by Eric Fiselier <ericwf@google.com>: Use EXPECT_DEATH_IF_SUPPORTED instead of EXPECT_DEATH. This avoids breaking the test when gtest doesn't support death tests. PiperOrigin-RevId: 215423849 -- cd687c1e121709603f4fc3726b534f6a9c52cc89 by Eric Fiselier <ericwf@google.com>: Disable LLVM's -Wmissing-variable-declarations in tests. GCC's configuration already disables this via -Wno-missing-declarations, this change makes LLVM do the same. The warning would otherwise flag most tests which use ABSL_FLAG. PiperOrigin-RevId: 215407429 -- d14098824c84e3a8c8f6fb920e0335fb48fe2010 by Eric Fiselier <ericwf@google.com>: Fix local variable shadowing in city hash implementation. PiperOrigin-RevId: 215407249 -- 4b5e140ba743f0d231790a26c49083abb4329e2c by Abseil Team <absl-team@google.com>: Make raw_hash_set::reserve 2X fast when reserve doesn't do any allocation. Make raw_hash_set::reserve ~1% faster when reserve does some (128~4k) allocation. PiperOrigin-RevId: 215348727 -- 461161e65e04b801480aa117af2534c594654ccf by Eric Fiselier <ericwf@google.com>: Internal change PiperOrigin-RevId: 215272283 -- 50413ae31ad3d3a177257416acd8ede47a17bff2 by Eric Fiselier <ericwf@google.com>: Internal Change PiperOrigin-RevId: 215233183 -- 477be54c43d61019a8fe4e190e340eb52737d383 by Abseil Team <absl-team@google.com>: Clarify misleading comment on ABSL_ATTRIBUTE_UNUSED PiperOrigin-RevId: 215185496 -- 2cafa2b5287507d3a946682aee9ab13af6d471c9 by Matt Kulukundis <kfm@google.com>: Add support for absl::Hash to various absl in types. PiperOrigin-RevId: 215039569 -- 082248901991aa3d29be0ea3689c7f213cf0fd83 by Derek Mauro <dmauro@google.com>: Remove an instance of HAS_GLOBAL_STRING from hash_function_defaults.h PiperOrigin-RevId: 214989094 -- b929f61907f0786a6133e3a9d7287e339c0a0acb by Derek Mauro <dmauro@google.com>: Internal import of Github #174 Fix code snippet in comment https://github.com/abseil/abseil-cpp/pull/174 PiperOrigin-RevId: 214958849 -- f2c5e829eca11c352e121f56eefbf87083305023 by Derek Mauro <dmauro@google.com>: Internal import of GitHub #173 Fix CMake build for absl::container. https://github.com/abseil/abseil-cpp/pull/173 PiperOrigin-RevId: 214957796 -- d704f860f9fddafb99e34e6c5032e49f73874e10 by Abseil Team <absl-team@google.com>: Internal change PiperOrigin-RevId: 214828181 GitOrigin-RevId: 1c1d6e2404dfc6caa022b335df5acdac6da50fe1 Change-Id: I551de2b1ba0cbaf6856cd5959358cf6651179dea
2018-10-02 21:09:18 +02:00
Export of internal Abseil changes. -- 5da9755667df37e38ccaf6938c9f408e294110bb by Shaindel Schwartz <shaindel@google.com>: Import of CCTZ from GitHub. PiperOrigin-RevId: 232942734 -- b6fb275769c66fdd2bd92b119198c59e9a7dd737 by Samuel Benzaquen <sbenza@google.com>: Fix integral underflow when from-arg width is INT_MIN. PiperOrigin-RevId: 232888037 -- 4135dbba4a26c4642277fc2a7e2a833d593daa1c by Abseil Team <absl-team@google.com>: Add the insert_return_type alias to raw_hash_set. PiperOrigin-RevId: 232683892 -- 0b120b7d3693800bbb886f6fc607ae54a9338cb1 by Abseil Team <absl-team@google.com>: Macros to detect and disabled SafeStack https://clang.llvm.org/docs/SafeStack.html PiperOrigin-RevId: 232680114 -- a77b3fb533a9e37966d1d6ef5ccd09c73fff2ca1 by Abseil Team <absl-team@google.com>: Avoid potential red zone clobber Pushing on the stack on x86-64 may clobber local variables held below %rsp in the red zone. Avoid this by using lea on x86-64. PiperOrigin-RevId: 232592478 -- bf326a0eefa92f4e704287563df0c5a5b1873b6d by Eric Fiselier <ericwf@google.com>: Add additional tests for AbslHashValue. PiperOrigin-RevId: 232344325 -- 816e4f98fd7632c944c779db87b7dac4e138afcf by Eric Fiselier <ericwf@google.com>: Avoid upcoming GCC 9.0 warnings about base class init. Currently, in trunk, GCC has a new warning under -Wextra that diagnoses when a derived class fails to explicitly initialize the base class in a constructor initializer list. This patch avoids this warning. PiperOrigin-RevId: 232327626 -- 779c0f44b3c2b7a04d4bdf978641eb8180515bf6 by Eric Fiselier <ericwf@google.com>: Guard against C++2a char8_t change. PiperOrigin-RevId: 232326178 -- 41e5395b85bbbfb5bf418cc21b04ad4ccb15a284 by Eric Fiselier <ericwf@google.com>: Avoid Clang Warning PiperOrigin-RevId: 232138866 GitOrigin-RevId: 5da9755667df37e38ccaf6938c9f408e294110bb Change-Id: I49ee4f58db177b81b039d7d949f671c97c5a7933
2019-02-07 23:13:06 +01:00
TEST(FixedArrayTest, AbslHashValueWorks) {
using V = absl::FixedArray<int>;
std::vector<V> cases;
// Generate a variety of vectors some of these are small enough for the inline
// space but are stored out of line.
for (int i = 0; i < 10; ++i) {
V v(i);
for (int j = 0; j < i; ++j) {
v[j] = j;
}
cases.push_back(v);
}
EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly(cases));
}
2017-09-19 22:54:40 +02:00
} // namespace