summaryrefslogtreecommitdiff
path: root/absl/container/internal/container_memory_test.cc
diff options
context:
space:
mode:
authorGravatar Abseil Team <absl-team@google.com>2018-09-27 12:24:54 -0700
committerGravatar Derek Mauro <dmauro@google.com>2018-09-27 15:28:12 -0400
commit48cd2c3f351ff188bc85684b84a91b6e6d17d896 (patch)
tree6f92b0cbb0f8282b7df1cd567cb66406fbbb6f80 /absl/container/internal/container_memory_test.cc
parente291c279e458761e77a69b09b129d3d1e81f1e80 (diff)
Export of internal Abseil changes.
-- 4eacae3ff1b14b1d309e8092185bc10e8a6203cf by Derek Mauro <dmauro@google.com>: Release SwissTable - a fast, efficient, cache-friendly hash table. https://www.youtube.com/watch?v=ncHmEUmJZf4 PiperOrigin-RevId: 214816527 -- df8c3dfab3cfb2f4365909a84d0683b193cfbb11 by Derek Mauro <dmauro@google.com>: Internal change PiperOrigin-RevId: 214785288 -- 1eabd5266bbcebc33eecc91e5309b751856a75c8 by Abseil Team <absl-team@google.com>: Internal change PiperOrigin-RevId: 214722931 -- 2ebbfac950f83146b46253038e7dd7dcde9f2951 by Derek Mauro <dmauro@google.com>: Internal change PiperOrigin-RevId: 214701684 GitOrigin-RevId: 4eacae3ff1b14b1d309e8092185bc10e8a6203cf Change-Id: I9ba64e395b22ad7863213d157b8019b082adc19d
Diffstat (limited to 'absl/container/internal/container_memory_test.cc')
-rw-r--r--absl/container/internal/container_memory_test.cc188
1 files changed, 188 insertions, 0 deletions
diff --git a/absl/container/internal/container_memory_test.cc b/absl/container/internal/container_memory_test.cc
new file mode 100644
index 00000000..f1c40582
--- /dev/null
+++ b/absl/container/internal/container_memory_test.cc
@@ -0,0 +1,188 @@
+// Copyright 2018 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
+//
+// 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 "absl/container/internal/container_memory.h"
+
+#include <cstdint>
+#include <tuple>
+#include <utility>
+
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+#include "absl/strings/string_view.h"
+
+namespace absl {
+namespace container_internal {
+namespace {
+
+using ::testing::Pair;
+
+TEST(Memory, AlignmentLargerThanBase) {
+ std::allocator<int8_t> alloc;
+ void* mem = Allocate<2>(&alloc, 3);
+ EXPECT_EQ(0, reinterpret_cast<uintptr_t>(mem) % 2);
+ memcpy(mem, "abc", 3);
+ Deallocate<2>(&alloc, mem, 3);
+}
+
+TEST(Memory, AlignmentSmallerThanBase) {
+ std::allocator<int64_t> alloc;
+ void* mem = Allocate<2>(&alloc, 3);
+ EXPECT_EQ(0, reinterpret_cast<uintptr_t>(mem) % 2);
+ memcpy(mem, "abc", 3);
+ Deallocate<2>(&alloc, mem, 3);
+}
+
+class Fixture : public ::testing::Test {
+ using Alloc = std::allocator<std::string>;
+
+ public:
+ Fixture() { ptr_ = std::allocator_traits<Alloc>::allocate(*alloc(), 1); }
+ ~Fixture() override {
+ std::allocator_traits<Alloc>::destroy(*alloc(), ptr_);
+ std::allocator_traits<Alloc>::deallocate(*alloc(), ptr_, 1);
+ }
+ std::string* ptr() { return ptr_; }
+ Alloc* alloc() { return &alloc_; }
+
+ private:
+ Alloc alloc_;
+ std::string* ptr_;
+};
+
+TEST_F(Fixture, ConstructNoArgs) {
+ ConstructFromTuple(alloc(), ptr(), std::forward_as_tuple());
+ EXPECT_EQ(*ptr(), "");
+}
+
+TEST_F(Fixture, ConstructOneArg) {
+ ConstructFromTuple(alloc(), ptr(), std::forward_as_tuple("abcde"));
+ EXPECT_EQ(*ptr(), "abcde");
+}
+
+TEST_F(Fixture, ConstructTwoArg) {
+ ConstructFromTuple(alloc(), ptr(), std::forward_as_tuple(5, 'a'));
+ EXPECT_EQ(*ptr(), "aaaaa");
+}
+
+TEST(PairArgs, NoArgs) {
+ EXPECT_THAT(PairArgs(),
+ Pair(std::forward_as_tuple(), std::forward_as_tuple()));
+}
+
+TEST(PairArgs, TwoArgs) {
+ EXPECT_EQ(
+ std::make_pair(std::forward_as_tuple(1), std::forward_as_tuple('A')),
+ PairArgs(1, 'A'));
+}
+
+TEST(PairArgs, Pair) {
+ EXPECT_EQ(
+ std::make_pair(std::forward_as_tuple(1), std::forward_as_tuple('A')),
+ PairArgs(std::make_pair(1, 'A')));
+}
+
+TEST(PairArgs, Piecewise) {
+ EXPECT_EQ(
+ std::make_pair(std::forward_as_tuple(1), std::forward_as_tuple('A')),
+ PairArgs(std::piecewise_construct, std::forward_as_tuple(1),
+ std::forward_as_tuple('A')));
+}
+
+TEST(WithConstructed, Simple) {
+ EXPECT_EQ(1, WithConstructed<absl::string_view>(
+ std::make_tuple(std::string("a")),
+ [](absl::string_view str) { return str.size(); }));
+}
+
+template <class F, class Arg>
+decltype(DecomposeValue(std::declval<F>(), std::declval<Arg>()))
+DecomposeValueImpl(int, F&& f, Arg&& arg) {
+ return DecomposeValue(std::forward<F>(f), std::forward<Arg>(arg));
+}
+
+template <class F, class Arg>
+const char* DecomposeValueImpl(char, F&& f, Arg&& arg) {
+ return "not decomposable";
+}
+
+template <class F, class Arg>
+decltype(DecomposeValueImpl(0, std::declval<F>(), std::declval<Arg>()))
+TryDecomposeValue(F&& f, Arg&& arg) {
+ return DecomposeValueImpl(0, std::forward<F>(f), std::forward<Arg>(arg));
+}
+
+TEST(DecomposeValue, Decomposable) {
+ auto f = [](const int& x, int&& y) {
+ EXPECT_EQ(&x, &y);
+ EXPECT_EQ(42, x);
+ return 'A';
+ };
+ EXPECT_EQ('A', TryDecomposeValue(f, 42));
+}
+
+TEST(DecomposeValue, NotDecomposable) {
+ auto f = [](void*) {
+ ADD_FAILURE() << "Must not be called";
+ return 'A';
+ };
+ EXPECT_STREQ("not decomposable", TryDecomposeValue(f, 42));
+}
+
+template <class F, class... Args>
+decltype(DecomposePair(std::declval<F>(), std::declval<Args>()...))
+DecomposePairImpl(int, F&& f, Args&&... args) {
+ return DecomposePair(std::forward<F>(f), std::forward<Args>(args)...);
+}
+
+template <class F, class... Args>
+const char* DecomposePairImpl(char, F&& f, Args&&... args) {
+ return "not decomposable";
+}
+
+template <class F, class... Args>
+decltype(DecomposePairImpl(0, std::declval<F>(), std::declval<Args>()...))
+TryDecomposePair(F&& f, Args&&... args) {
+ return DecomposePairImpl(0, std::forward<F>(f), std::forward<Args>(args)...);
+}
+
+TEST(DecomposePair, Decomposable) {
+ auto f = [](const int& x, std::piecewise_construct_t, std::tuple<int&&> k,
+ std::tuple<double>&& v) {
+ EXPECT_EQ(&x, &std::get<0>(k));
+ EXPECT_EQ(42, x);
+ EXPECT_EQ(0.5, std::get<0>(v));
+ return 'A';
+ };
+ EXPECT_EQ('A', TryDecomposePair(f, 42, 0.5));
+ EXPECT_EQ('A', TryDecomposePair(f, std::make_pair(42, 0.5)));
+ EXPECT_EQ('A', TryDecomposePair(f, std::piecewise_construct,
+ std::make_tuple(42), std::make_tuple(0.5)));
+}
+
+TEST(DecomposePair, NotDecomposable) {
+ auto f = [](...) {
+ ADD_FAILURE() << "Must not be called";
+ return 'A';
+ };
+ EXPECT_STREQ("not decomposable",
+ TryDecomposePair(f));
+ EXPECT_STREQ("not decomposable",
+ TryDecomposePair(f, std::piecewise_construct, std::make_tuple(),
+ std::make_tuple(0.5)));
+}
+
+} // namespace
+} // namespace container_internal
+} // namespace absl