blob: 2b2e8d34d20f71145590204f0fbfa5e83eca865b [file] [log] [blame]
Mathieu Chartier54d220e2015-07-30 16:20:06 -07001/*
2 * Copyright (C) 2015 The Android Open Source Project
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 ART_RUNTIME_LENGTH_PREFIXED_ARRAY_H_
18#define ART_RUNTIME_LENGTH_PREFIXED_ARRAY_H_
19
20#include <stddef.h> // for offsetof()
21
22#include "linear_alloc.h"
23#include "stride_iterator.h"
24#include "base/iteration_range.h"
25
26namespace art {
27
28template<typename T>
29class LengthPrefixedArray {
30 public:
31 explicit LengthPrefixedArray(uint64_t length) : length_(length) {}
32
33 T& At(size_t index, size_t element_size = sizeof(T)) {
34 DCHECK_LT(index, length_);
35 return *reinterpret_cast<T*>(&data_[0] + index * element_size);
36 }
37
38 StrideIterator<T> Begin(size_t element_size = sizeof(T)) {
39 return StrideIterator<T>(reinterpret_cast<T*>(&data_[0]), element_size);
40 }
41
42 StrideIterator<T> End(size_t element_size = sizeof(T)) {
43 return StrideIterator<T>(reinterpret_cast<T*>(&data_[0] + element_size * length_),
44 element_size);
45 }
46
47 static size_t OffsetOfElement(size_t index, size_t element_size = sizeof(T)) {
48 return offsetof(LengthPrefixedArray<T>, data_) + index * element_size;
49 }
50
Mathieu Chartierc0fe56a2015-08-11 13:01:23 -070051 // Alignment is the caller's responsibility.
Mathieu Chartier54d220e2015-07-30 16:20:06 -070052 static size_t ComputeSize(size_t num_elements, size_t element_size = sizeof(T)) {
Mathieu Chartierc0fe56a2015-08-11 13:01:23 -070053 return OffsetOfElement(num_elements, element_size);
Mathieu Chartier54d220e2015-07-30 16:20:06 -070054 }
55
56 uint64_t Length() const {
57 return length_;
58 }
59
Mathieu Chartierc0fe56a2015-08-11 13:01:23 -070060 // Update the length but does not reallocate storage.
61 void SetLength(uint64_t length) {
62 length_ = length;
63 }
64
Mathieu Chartier54d220e2015-07-30 16:20:06 -070065 private:
Mathieu Chartierc0fe56a2015-08-11 13:01:23 -070066 uint64_t length_; // 64 bits for 8 byte alignment of data_.
Mathieu Chartier54d220e2015-07-30 16:20:06 -070067 uint8_t data_[0];
68};
69
70// Returns empty iteration range if the array is null.
71template<typename T>
72IterationRange<StrideIterator<T>> MakeIterationRangeFromLengthPrefixedArray(
73 LengthPrefixedArray<T>* arr, size_t element_size) {
74 return arr != nullptr ?
75 MakeIterationRange(arr->Begin(element_size), arr->End(element_size)) :
76 MakeEmptyIterationRange(StrideIterator<T>(nullptr, 0));
77}
78
79} // namespace art
80
81#endif // ART_RUNTIME_LENGTH_PREFIXED_ARRAY_H_