1 /*
2 * Copyright 2014 Google Inc. All rights reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #ifndef FRUIT_FIXED_SIZE_VECTOR_DEFN_H
18 #define FRUIT_FIXED_SIZE_VECTOR_DEFN_H
19
20 #include <fruit/impl/data_structures/fixed_size_vector.h>
21
22 #include <fruit/impl/fruit_assert.h>
23
24 #include <cassert>
25 #include <cstring>
26 #include <utility>
27
28 namespace fruit {
29 namespace impl {
30
31 template <typename T, typename Allocator>
FixedSizeVector(std::size_t capacity,Allocator allocator)32 inline FixedSizeVector<T, Allocator>::FixedSizeVector(std::size_t capacity, Allocator allocator)
33 : capacity(capacity), allocator(allocator) {
34 if (capacity == 0) { // LCOV_EXCL_BR_LINE
35 v_begin = 0;
36 } else {
37 v_begin = allocator.allocate(capacity);
38 }
39 v_end = v_begin;
40 }
41
42 template <typename T, typename Allocator>
~FixedSizeVector()43 inline FixedSizeVector<T, Allocator>::~FixedSizeVector() {
44 clear();
45 if (capacity != 0) {
46 allocator.deallocate(v_begin, capacity);
47 }
48 }
49
50 template <typename T, typename Allocator>
FixedSizeVector(FixedSizeVector && other)51 inline FixedSizeVector<T, Allocator>::FixedSizeVector(FixedSizeVector&& other) : FixedSizeVector() {
52 swap(other);
53 }
54
55 template <typename T, typename Allocator>
56 inline FixedSizeVector<T, Allocator>& FixedSizeVector<T, Allocator>::operator=(FixedSizeVector&& other) {
57 swap(other);
58 return *this;
59 }
60
61 template <typename T, typename Allocator>
size()62 inline std::size_t FixedSizeVector<T, Allocator>::size() const {
63 return end() - begin();
64 }
65
66 template <typename T, typename Allocator>
67 inline T& FixedSizeVector<T, Allocator>::operator[](std::size_t i) {
68 FruitAssert(begin() + i < end());
69 return begin()[i];
70 }
71
72 template <typename T, typename Allocator>
73 inline const T& FixedSizeVector<T, Allocator>::operator[](std::size_t i) const {
74 FruitAssert(begin() + i < end());
75 return begin()[i];
76 }
77
78 template <typename T, typename Allocator>
swap(FixedSizeVector & x)79 inline void FixedSizeVector<T, Allocator>::swap(FixedSizeVector& x) {
80 std::swap(v_end, x.v_end);
81 std::swap(v_begin, x.v_begin);
82 std::swap(capacity, x.capacity);
83 }
84
85 template <typename T, typename Allocator>
push_back(T x)86 inline void FixedSizeVector<T, Allocator>::push_back(T x) {
87 #if FRUIT_EXTRA_DEBUG
88 FruitAssert(v_end != v_begin + capacity);
89 #endif
90 new (v_end) T(x); // LCOV_EXCL_BR_LINE
91 ++v_end;
92 #if FRUIT_EXTRA_DEBUG
93 FruitAssert(v_end <= v_begin + capacity);
94 #endif
95 }
96
97 // This method is covered by tests, even though lcov doesn't detect that.
98 template <typename T, typename Allocator>
data()99 inline T* FixedSizeVector<T, Allocator>::data() {
100 return v_begin;
101 }
102
103 template <typename T, typename Allocator>
begin()104 inline T* FixedSizeVector<T, Allocator>::begin() {
105 return v_begin;
106 }
107
108 template <typename T, typename Allocator>
end()109 inline T* FixedSizeVector<T, Allocator>::end() {
110 return v_end;
111 }
112
113 template <typename T, typename Allocator>
data()114 inline const T* FixedSizeVector<T, Allocator>::data() const {
115 return v_begin;
116 }
117
118 template <typename T, typename Allocator>
begin()119 inline const T* FixedSizeVector<T, Allocator>::begin() const {
120 return v_begin;
121 }
122
123 template <typename T, typename Allocator>
end()124 inline const T* FixedSizeVector<T, Allocator>::end() const {
125 return v_end;
126 }
127
128 template <typename T, typename Allocator>
clear()129 inline void FixedSizeVector<T, Allocator>::clear() {
130 for (T* p = v_begin; p != v_end; ++p) {
131 p->~T();
132 }
133 v_end = v_begin;
134 }
135
136 } // namespace impl
137 } // namespace fruit
138
139 #endif // FRUIT_FIXED_SIZE_VECTOR_DEFN_H
140