abseil-cpp/absl/container/internal/container_memory_test.cc
Go to the documentation of this file.
1 // Copyright 2018 The Abseil Authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "absl/container/internal/container_memory.h"
16 
17 #include <cstdint>
18 #include <tuple>
19 #include <typeindex>
20 #include <typeinfo>
21 #include <utility>
22 
23 #include "gmock/gmock.h"
24 #include "gtest/gtest.h"
25 #include "absl/container/internal/test_instance_tracker.h"
26 #include "absl/strings/string_view.h"
27 
28 namespace absl {
30 namespace container_internal {
31 namespace {
32 
33 using ::absl::test_internal::CopyableMovableInstance;
34 using ::absl::test_internal::InstanceTracker;
39 
40 TEST(Memory, AlignmentLargerThanBase) {
41  std::allocator<int8_t> alloc;
42  void* mem = Allocate<2>(&alloc, 3);
43  EXPECT_EQ(0, reinterpret_cast<uintptr_t>(mem) % 2);
44  memcpy(mem, "abc", 3);
45  Deallocate<2>(&alloc, mem, 3);
46 }
47 
48 TEST(Memory, AlignmentSmallerThanBase) {
49  std::allocator<int64_t> alloc;
50  void* mem = Allocate<2>(&alloc, 3);
51  EXPECT_EQ(0, reinterpret_cast<uintptr_t>(mem) % 2);
52  memcpy(mem, "abc", 3);
53  Deallocate<2>(&alloc, mem, 3);
54 }
55 
56 std::map<std::type_index, int>& AllocationMap() {
57  static auto* map = new std::map<std::type_index, int>;
58  return *map;
59 }
60 
61 template <typename T>
62 struct TypeCountingAllocator {
63  TypeCountingAllocator() = default;
64  template <typename U>
65  TypeCountingAllocator(const TypeCountingAllocator<U>&) {} // NOLINT
66 
67  using value_type = T;
68 
69  T* allocate(size_t n, const void* = nullptr) {
70  AllocationMap()[typeid(T)] += n;
71  return std::allocator<T>().allocate(n);
72  }
73  void deallocate(T* p, std::size_t n) {
74  AllocationMap()[typeid(T)] -= n;
75  return std::allocator<T>().deallocate(p, n);
76  }
77 };
78 
79 TEST(Memory, AllocateDeallocateMatchType) {
80  TypeCountingAllocator<int> alloc;
81  void* mem = Allocate<1>(&alloc, 1);
82  // Verify that it was allocated
83  EXPECT_THAT(AllocationMap(), ElementsAre(Pair(_, Gt(0))));
84  Deallocate<1>(&alloc, mem, 1);
85  // Verify that the deallocation matched.
86  EXPECT_THAT(AllocationMap(), ElementsAre(Pair(_, 0)));
87 }
88 
89 class Fixture : public ::testing::Test {
90  using Alloc = std::allocator<std::string>;
91 
92  public:
93  Fixture() { ptr_ = std::allocator_traits<Alloc>::allocate(*alloc(), 1); }
94  ~Fixture() override {
96  std::allocator_traits<Alloc>::deallocate(*alloc(), ptr_, 1);
97  }
98  std::string* ptr() { return ptr_; }
99  Alloc* alloc() { return &alloc_; }
100 
101  private:
104 };
105 
106 TEST_F(Fixture, ConstructNoArgs) {
107  ConstructFromTuple(alloc(), ptr(), std::forward_as_tuple());
108  EXPECT_EQ(*ptr(), "");
109 }
110 
111 TEST_F(Fixture, ConstructOneArg) {
112  ConstructFromTuple(alloc(), ptr(), std::forward_as_tuple("abcde"));
113  EXPECT_EQ(*ptr(), "abcde");
114 }
115 
116 TEST_F(Fixture, ConstructTwoArg) {
117  ConstructFromTuple(alloc(), ptr(), std::forward_as_tuple(5, 'a'));
118  EXPECT_EQ(*ptr(), "aaaaa");
119 }
120 
121 TEST(PairArgs, NoArgs) {
123  Pair(std::forward_as_tuple(), std::forward_as_tuple()));
124 }
125 
126 TEST(PairArgs, TwoArgs) {
127  EXPECT_EQ(
128  std::make_pair(std::forward_as_tuple(1), std::forward_as_tuple('A')),
129  PairArgs(1, 'A'));
130 }
131 
132 TEST(PairArgs, Pair) {
133  EXPECT_EQ(
134  std::make_pair(std::forward_as_tuple(1), std::forward_as_tuple('A')),
135  PairArgs(std::make_pair(1, 'A')));
136 }
137 
138 TEST(PairArgs, Piecewise) {
139  EXPECT_EQ(
140  std::make_pair(std::forward_as_tuple(1), std::forward_as_tuple('A')),
141  PairArgs(std::piecewise_construct, std::forward_as_tuple(1),
142  std::forward_as_tuple('A')));
143 }
144 
145 TEST(WithConstructed, Simple) {
146  EXPECT_EQ(1, WithConstructed<absl::string_view>(
148  [](absl::string_view str) { return str.size(); }));
149 }
150 
151 template <class F, class Arg>
152 decltype(DecomposeValue(std::declval<F>(), std::declval<Arg>()))
153 DecomposeValueImpl(int, F&& f, Arg&& arg) {
154  return DecomposeValue(std::forward<F>(f), std::forward<Arg>(arg));
155 }
156 
157 template <class F, class Arg>
158 const char* DecomposeValueImpl(char, F&& f, Arg&& arg) {
159  return "not decomposable";
160 }
161 
162 template <class F, class Arg>
163 decltype(DecomposeValueImpl(0, std::declval<F>(), std::declval<Arg>()))
164 TryDecomposeValue(F&& f, Arg&& arg) {
165  return DecomposeValueImpl(0, std::forward<F>(f), std::forward<Arg>(arg));
166 }
167 
168 TEST(DecomposeValue, Decomposable) {
169  auto f = [](const int& x, int&& y) { // NOLINT
170  EXPECT_EQ(&x, &y);
171  EXPECT_EQ(42, x);
172  return 'A';
173  };
174  EXPECT_EQ('A', TryDecomposeValue(f, 42));
175 }
176 
177 TEST(DecomposeValue, NotDecomposable) {
178  auto f = [](void*) {
179  ADD_FAILURE() << "Must not be called";
180  return 'A';
181  };
182  EXPECT_STREQ("not decomposable", TryDecomposeValue(f, 42));
183 }
184 
185 template <class F, class... Args>
186 decltype(DecomposePair(std::declval<F>(), std::declval<Args>()...))
187 DecomposePairImpl(int, F&& f, Args&&... args) {
188  return DecomposePair(std::forward<F>(f), std::forward<Args>(args)...);
189 }
190 
191 template <class F, class... Args>
192 const char* DecomposePairImpl(char, F&& f, Args&&... args) {
193  return "not decomposable";
194 }
195 
196 template <class F, class... Args>
197 decltype(DecomposePairImpl(0, std::declval<F>(), std::declval<Args>()...))
198 TryDecomposePair(F&& f, Args&&... args) {
199  return DecomposePairImpl(0, std::forward<F>(f), std::forward<Args>(args)...);
200 }
201 
202 TEST(DecomposePair, Decomposable) {
203  auto f = [](const int& x, // NOLINT
204  std::piecewise_construct_t, std::tuple<int&&> k,
205  std::tuple<double>&& v) {
206  EXPECT_EQ(&x, &std::get<0>(k));
207  EXPECT_EQ(42, x);
208  EXPECT_EQ(0.5, std::get<0>(v));
209  return 'A';
210  };
211  EXPECT_EQ('A', TryDecomposePair(f, 42, 0.5));
212  EXPECT_EQ('A', TryDecomposePair(f, std::make_pair(42, 0.5)));
213  EXPECT_EQ('A', TryDecomposePair(f, std::piecewise_construct,
214  std::make_tuple(42), std::make_tuple(0.5)));
215 }
216 
217 TEST(DecomposePair, NotDecomposable) {
218  auto f = [](...) {
219  ADD_FAILURE() << "Must not be called";
220  return 'A';
221  };
222  EXPECT_STREQ("not decomposable",
223  TryDecomposePair(f));
224  EXPECT_STREQ("not decomposable",
225  TryDecomposePair(f, std::piecewise_construct, std::make_tuple(),
226  std::make_tuple(0.5)));
227 }
228 
229 TEST(MapSlotPolicy, ConstKeyAndValue) {
230  using slot_policy = map_slot_policy<const CopyableMovableInstance,
231  const CopyableMovableInstance>;
232  using slot_type = typename slot_policy::slot_type;
233 
234  union Slots {
235  Slots() {}
236  ~Slots() {}
237  slot_type slots[100];
238  } slots;
239 
240  std::allocator<
241  std::pair<const CopyableMovableInstance, const CopyableMovableInstance>>
242  alloc;
243  InstanceTracker tracker;
244  slot_policy::construct(&alloc, &slots.slots[0], CopyableMovableInstance(1),
245  CopyableMovableInstance(1));
246  for (int i = 0; i < 99; ++i) {
247  slot_policy::transfer(&alloc, &slots.slots[i + 1], &slots.slots[i]);
248  }
249  slot_policy::destroy(&alloc, &slots.slots[99]);
250 
251  EXPECT_EQ(tracker.copies(), 0);
252 }
253 
254 } // namespace
255 } // namespace container_internal
257 } // namespace absl
xds_interop_client.str
str
Definition: xds_interop_client.py:487
ptr
char * ptr
Definition: abseil-cpp/absl/base/internal/low_level_alloc_test.cc:45
Fixture
Definition: bm_call_create.cc:359
testing::Gt
internal::GtMatcher< Rhs > Gt(Rhs x)
Definition: cares/cares/test/gmock-1.8.0/gmock/gmock.h:8591
EXPECT_THAT
#define EXPECT_THAT(value, matcher)
std::tr1::make_tuple
tuple make_tuple()
Definition: cares/cares/test/gmock-1.8.0/gtest/gtest.h:1619
absl::container_internal::DecomposeValue
decltype(std::declval< F >()(std::declval< const Arg & >(), std::declval< Arg >())) DecomposeValue(F &&f, Arg &&arg)
Definition: abseil-cpp/absl/container/internal/container_memory.h:213
y
const double y
Definition: bloaty/third_party/googletest/googlemock/test/gmock-matchers_test.cc:3611
absl::string_view
Definition: abseil-cpp/absl/strings/string_view.h:167
testing::internal::string
::std::string string
Definition: bloaty/third_party/protobuf/third_party/googletest/googletest/include/gtest/internal/gtest-port.h:881
absl::container_internal::DecomposePair
auto DecomposePair(F &&f, Args &&... args) -> decltype(memory_internal::DecomposePairImpl(std::forward< F >(f), PairArgs(std::forward< Args >(args)...)))
Definition: abseil-cpp/absl/container/internal/container_memory.h:203
absl::container_internal::ConstructFromTuple
void ConstructFromTuple(Alloc *alloc, T *ptr, Tuple &&t)
Definition: abseil-cpp/absl/container/internal/container_memory.h:148
absl::TEST
TEST(NotificationTest, SanityTest)
Definition: abseil-cpp/absl/synchronization/notification_test.cc:126
ABSL_NAMESPACE_END
#define ABSL_NAMESPACE_END
Definition: third_party/abseil-cpp/absl/base/config.h:171
Arg
Arg(64) -> Arg(128) ->Arg(256) ->Arg(512) ->Arg(1024) ->Arg(1536) ->Arg(2048) ->Arg(3072) ->Arg(4096) ->Arg(5120) ->Arg(6144) ->Arg(7168)
ptr_
std::string * ptr_
Definition: abseil-cpp/absl/container/internal/container_memory_test.cc:103
setup.k
k
Definition: third_party/bloaty/third_party/capstone/bindings/python/setup.py:42
map
zval * map
Definition: php/ext/google/protobuf/encode_decode.c:480
T
#define T(upbtypeconst, upbtype, ctype, default_value)
testing::Test
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:402
EXPECT_EQ
#define EXPECT_EQ(a, b)
Definition: iomgr/time_averaged_stats_test.cc:27
testing::ElementsAre
internal::ElementsAreMatcher< ::testing::tuple<> > ElementsAre()
Definition: cares/cares/test/gmock-1.8.0/gmock/gmock.h:13040
memcpy
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
ABSL_NAMESPACE_BEGIN
#define ABSL_NAMESPACE_BEGIN
Definition: third_party/abseil-cpp/absl/base/config.h:170
autogen_x86imm.f
f
Definition: autogen_x86imm.py:9
asyncio_get_stats.args
args
Definition: asyncio_get_stats.py:40
absl::container_internal::PairArgs
std::pair< std::tuple<>, std::tuple<> > PairArgs()
Definition: abseil-cpp/absl/container/internal/container_memory.h:178
hpack_encoder_fixtures::Args
Args({0, 16384})
setup.v
v
Definition: third_party/bloaty/third_party/capstone/bindings/python/setup.py:42
gmock_output_test._
_
Definition: bloaty/third_party/googletest/googlemock/test/gmock_output_test.py:175
arg
Definition: cmdline.cc:40
absl::compare_internal::value_type
int8_t value_type
Definition: abseil-cpp/absl/types/compare.h:45
alloc_
Alloc alloc_
Definition: abseil-cpp/absl/container/internal/container_memory_test.cc:102
x
int x
Definition: bloaty/third_party/googletest/googlemock/test/gmock-matchers_test.cc:3610
absl::flags_internal::Alloc
void * Alloc(FlagOpFn op)
Definition: abseil-cpp/absl/flags/internal/flag.h:102
uintptr_t
_W64 unsigned int uintptr_t
Definition: stdint-msvc2008.h:119
transfer
static std::function< void(void *, Slot *, Slot *)> transfer
Definition: abseil-cpp/absl/container/internal/hash_policy_traits_test.cc:58
ADD_FAILURE
#define ADD_FAILURE()
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:1911
F
#define F(b, c, d)
Definition: md4.c:112
testing::Pair
internal::PairMatcher< FirstMatcher, SecondMatcher > Pair(FirstMatcher first_matcher, SecondMatcher second_matcher)
Definition: cares/cares/test/gmock-1.8.0/gmock/gmock.h:9152
mem
void * mem
Definition: libc.cpp:91
EXPECT_STREQ
#define EXPECT_STREQ(s1, s2)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:2095
construct
static std::function< void(void *, Slot *, Slot)> construct
Definition: abseil-cpp/absl/container/internal/hash_policy_traits_test.cc:41
absl::container_internal::WithConstructed
decltype(std::declval< F >()(std::declval< T >())) WithConstructed(Tuple &&t, F &&f)
Definition: abseil-cpp/absl/container/internal/container_memory.h:158
absl::container_internal::memory_internal::DecomposePairImpl
decltype(std::declval< F >()(std::declval< const K & >(), std::piecewise_construct, std::declval< std::tuple< K >>(), std::declval< V >())) DecomposePairImpl(F &&f, std::pair< std::tuple< K >, V > p)
Definition: abseil-cpp/absl/container/internal/container_memory.h:137
tracker
SessionTracker * tracker
Definition: ssl_session_cache_test.cc:38
absl
Definition: abseil-cpp/absl/algorithm/algorithm.h:31
alloc
std::allocator< int > alloc
Definition: abseil-cpp/absl/container/internal/hash_policy_traits_test.cc:87
destroy
static std::function< void(void *, Slot *)> destroy
Definition: abseil-cpp/absl/container/internal/hash_policy_traits_test.cc:42
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230
TEST_F
#define TEST_F(test_fixture, test_name)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:2367


grpc
Author(s):
autogenerated on Fri May 16 2025 02:58:02