internal/inlined_vector.h
Go to the documentation of this file.
1 // Copyright 2019 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 #ifndef ABSL_CONTAINER_INTERNAL_INLINED_VECTOR_INTERNAL_H_
16 #define ABSL_CONTAINER_INTERNAL_INLINED_VECTOR_INTERNAL_H_
17 
18 #include <cstddef>
19 #include <cstring>
20 #include <iterator>
21 #include <memory>
22 #include <utility>
23 
25 #include "absl/meta/type_traits.h"
26 
27 namespace absl {
28 namespace inlined_vector_internal {
29 
30 template <typename Iterator>
31 using IsAtLeastForwardIterator = std::is_convertible<
32  typename std::iterator_traits<Iterator>::iterator_category,
33  std::forward_iterator_tag>;
34 
35 template <typename AllocatorType, typename ValueType, typename SizeType>
36 void DestroyElements(AllocatorType* alloc_ptr, ValueType* destroy_first,
37  SizeType destroy_size) {
38  using AllocatorTraits = std::allocator_traits<AllocatorType>;
39 
40  // Destroys `destroy_size` elements from `destroy_first`.
41  //
42  // Destroys the range
43  // [`destroy_first`, `destroy_first + destroy_size`).
44  //
45  // NOTE: We assume destructors do not throw and thus make no attempt to roll
46  // back.
47  for (SizeType i = 0; i < destroy_size; ++i) {
48  AllocatorTraits::destroy(*alloc_ptr, destroy_first + i);
49  }
50 
51 #ifndef NDEBUG
52  // Overwrite unused memory with `0xab` so we can catch uninitialized usage.
53  //
54  // Cast to `void*` to tell the compiler that we don't care that we might be
55  // scribbling on a vtable pointer.
56  void* memory = reinterpret_cast<void*>(destroy_first);
57  size_t memory_size = sizeof(ValueType) * destroy_size;
58  std::memset(memory, 0xab, memory_size);
59 #endif // NDEBUG
60 }
61 
62 template <typename T, size_t N, typename A>
63 class Storage {
64  public:
65  using allocator_type = A;
67  using pointer = typename allocator_type::pointer;
68  using const_pointer = typename allocator_type::const_pointer;
69  using reference = typename allocator_type::reference;
70  using const_reference = typename allocator_type::const_reference;
72  using size_type = typename allocator_type::size_type;
73  using difference_type = typename allocator_type::difference_type;
74  using iterator = pointer;
76  using reverse_iterator = std::reverse_iterator<iterator>;
77  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
78  using AllocatorTraits = std::allocator_traits<allocator_type>;
79 
80  explicit Storage(const allocator_type& alloc)
81  : metadata_(alloc, /* empty and inlined */ 0) {}
82 
83  size_type GetSize() const { return GetSizeAndIsAllocated() >> 1; }
84 
85  bool GetIsAllocated() const { return GetSizeAndIsAllocated() & 1; }
86 
88  return reinterpret_cast<pointer>(
89  std::addressof(data_.inlined.inlined_data[0]));
90  }
91 
93  return reinterpret_cast<const_pointer>(
94  std::addressof(data_.inlined.inlined_data[0]));
95  }
96 
98 
101  }
102 
105  }
106 
108  return std::addressof(metadata_.template get<0>());
109  }
110 
111  const allocator_type* GetAllocPtr() const {
112  return std::addressof(metadata_.template get<0>());
113  }
114 
116  GetSizeAndIsAllocated() = (size << 1) | static_cast<size_type>(1);
117  }
118 
120 
121  void AddSize(size_type count) { GetSizeAndIsAllocated() += count << 1; }
122 
124 
127  }
128 
130  using std::swap;
132  }
133 
135  using std::swap;
137  }
138 
139  private:
140  size_type& GetSizeAndIsAllocated() { return metadata_.template get<1>(); }
141 
143  return metadata_.template get<1>();
144  }
145 
146  using Metadata =
148 
149  struct Allocated {
152  };
153 
154  struct Inlined {
155  using InlinedDataElement =
157  InlinedDataElement inlined_data[N];
158  };
159 
160  union Data {
163  };
164 
165  Metadata metadata_;
166  Data data_;
167 };
168 
169 } // namespace inlined_vector_internal
170 } // namespace absl
171 
172 #endif // ABSL_CONTAINER_INTERNAL_INLINED_VECTOR_INTERNAL_H_
absl::aligned_storage_t< sizeof(value_type), alignof(value_type)> InlinedDataElement
typename std::aligned_storage< Len, Align >::type aligned_storage_t
Definition: type_traits.h:541
Definition: algorithm.h:29
static std::function< void(void *, Slot *)> destroy
std::is_convertible< typename std::iterator_traits< Iterator >::iterator_category, std::forward_iterator_tag > IsAtLeastForwardIterator
static char data[kDataSize]
Definition: city_test.cc:31
void swap(absl::InlinedVector< T, N, A > &a, absl::InlinedVector< T, N, A > &b) noexcept(noexcept(a.swap(b)))
uintptr_t size
void DestroyElements(AllocatorType *alloc_ptr, ValueType *destroy_first, SizeType destroy_size)
const allocator_type * GetAllocPtr() const
std::allocator< int > alloc
const size_type & GetSizeAndIsAllocated() const


abseil_cpp
Author(s):
autogenerated on Wed Jun 19 2019 19:19:56