Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #ifndef ABSL_CONTAINER_INTERNAL_INLINED_VECTOR_INTERNAL_H_
00016 #define ABSL_CONTAINER_INTERNAL_INLINED_VECTOR_INTERNAL_H_
00017
00018 #include <cstddef>
00019 #include <cstring>
00020 #include <iterator>
00021 #include <memory>
00022 #include <utility>
00023
00024 #include "absl/container/internal/compressed_tuple.h"
00025 #include "absl/meta/type_traits.h"
00026
00027 namespace absl {
00028 namespace inlined_vector_internal {
00029
00030 template <typename Iterator>
00031 using IsAtLeastForwardIterator = std::is_convertible<
00032 typename std::iterator_traits<Iterator>::iterator_category,
00033 std::forward_iterator_tag>;
00034
00035 template <typename AllocatorType, typename ValueType, typename SizeType>
00036 void DestroyElements(AllocatorType* alloc_ptr, ValueType* destroy_first,
00037 SizeType destroy_size) {
00038 using AllocatorTraits = std::allocator_traits<AllocatorType>;
00039
00040
00041
00042
00043
00044
00045
00046
00047 for (SizeType i = 0; i < destroy_size; ++i) {
00048 AllocatorTraits::destroy(*alloc_ptr, destroy_first + i);
00049 }
00050
00051 #ifndef NDEBUG
00052
00053
00054
00055
00056 void* memory = reinterpret_cast<void*>(destroy_first);
00057 size_t memory_size = sizeof(ValueType) * destroy_size;
00058 std::memset(memory, 0xab, memory_size);
00059 #endif // NDEBUG
00060 }
00061
00062 template <typename T, size_t N, typename A>
00063 class Storage {
00064 public:
00065 using allocator_type = A;
00066 using value_type = typename allocator_type::value_type;
00067 using pointer = typename allocator_type::pointer;
00068 using const_pointer = typename allocator_type::const_pointer;
00069 using reference = typename allocator_type::reference;
00070 using const_reference = typename allocator_type::const_reference;
00071 using rvalue_reference = typename allocator_type::value_type&&;
00072 using size_type = typename allocator_type::size_type;
00073 using difference_type = typename allocator_type::difference_type;
00074 using iterator = pointer;
00075 using const_iterator = const_pointer;
00076 using reverse_iterator = std::reverse_iterator<iterator>;
00077 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
00078 using AllocatorTraits = std::allocator_traits<allocator_type>;
00079
00080 explicit Storage(const allocator_type& alloc)
00081 : metadata_(alloc, 0) {}
00082
00083 size_type GetSize() const { return GetSizeAndIsAllocated() >> 1; }
00084
00085 bool GetIsAllocated() const { return GetSizeAndIsAllocated() & 1; }
00086
00087 pointer GetInlinedData() {
00088 return reinterpret_cast<pointer>(
00089 std::addressof(data_.inlined.inlined_data[0]));
00090 }
00091
00092 const_pointer GetInlinedData() const {
00093 return reinterpret_cast<const_pointer>(
00094 std::addressof(data_.inlined.inlined_data[0]));
00095 }
00096
00097 pointer GetAllocatedData() { return data_.allocated.allocated_data; }
00098
00099 const_pointer GetAllocatedData() const {
00100 return data_.allocated.allocated_data;
00101 }
00102
00103 size_type GetAllocatedCapacity() const {
00104 return data_.allocated.allocated_capacity;
00105 }
00106
00107 allocator_type* GetAllocPtr() {
00108 return std::addressof(metadata_.template get<0>());
00109 }
00110
00111 const allocator_type* GetAllocPtr() const {
00112 return std::addressof(metadata_.template get<0>());
00113 }
00114
00115 void SetAllocatedSize(size_type size) {
00116 GetSizeAndIsAllocated() = (size << 1) | static_cast<size_type>(1);
00117 }
00118
00119 void SetInlinedSize(size_type size) { GetSizeAndIsAllocated() = size << 1; }
00120
00121 void AddSize(size_type count) { GetSizeAndIsAllocated() += count << 1; }
00122
00123 void SetAllocatedData(pointer data) { data_.allocated.allocated_data = data; }
00124
00125 void SetAllocatedCapacity(size_type capacity) {
00126 data_.allocated.allocated_capacity = capacity;
00127 }
00128
00129 void SwapSizeAndIsAllocated(Storage* other) {
00130 using std::swap;
00131 swap(GetSizeAndIsAllocated(), other->GetSizeAndIsAllocated());
00132 }
00133
00134 void SwapAllocatedSizeAndCapacity(Storage* other) {
00135 using std::swap;
00136 swap(data_.allocated, other->data_.allocated);
00137 }
00138
00139 private:
00140 size_type& GetSizeAndIsAllocated() { return metadata_.template get<1>(); }
00141
00142 const size_type& GetSizeAndIsAllocated() const {
00143 return metadata_.template get<1>();
00144 }
00145
00146 using Metadata =
00147 container_internal::CompressedTuple<allocator_type, size_type>;
00148
00149 struct Allocated {
00150 pointer allocated_data;
00151 size_type allocated_capacity;
00152 };
00153
00154 struct Inlined {
00155 using InlinedDataElement =
00156 absl::aligned_storage_t<sizeof(value_type), alignof(value_type)>;
00157 InlinedDataElement inlined_data[N];
00158 };
00159
00160 union Data {
00161 Allocated allocated;
00162 Inlined inlined;
00163 };
00164
00165 Metadata metadata_;
00166 Data data_;
00167 };
00168
00169 }
00170 }
00171
00172 #endif // ABSL_CONTAINER_INTERNAL_INLINED_VECTOR_INTERNAL_H_