about summary refs log tree commit diff
path: root/absl/container/internal/container_memory_test.cc
diff options
context:
space:
mode:
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 000000000000..f1c4058298c1
--- /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