diff options
author | 2018-03-02 12:01:51 -0800 | |
---|---|---|
committer | 2018-03-05 13:58:20 -0800 | |
commit | c431b9dc4b23cc950eb313695258df5d89f53b22 (patch) | |
tree | 422273559c3ae52caff0c6b1cf1a62a8312f0e26 /libartbase/base/array_slice.h | |
parent | f46f46cf5bd32788d5252b7107628a66594a5e98 (diff) |
Move most of runtime/base to libartbase/base
Enforce the layering that code in runtime/base should not depend on
runtime by separating it into libartbase. Some of the code in
runtime/base depends on the Runtime class, so it cannot be moved yet.
Also, some of the tests depend on CommonRuntimeTest, which itself needs
to be factored (in a subsequent CL).
Bug: 22322814
Test: make -j 50 checkbuild
make -j 50 test-art-host
Change-Id: I8b096c1e2542f829eb456b4b057c71421b77d7e2
Diffstat (limited to 'libartbase/base/array_slice.h')
-rw-r--r-- | libartbase/base/array_slice.h | 152 |
1 files changed, 152 insertions, 0 deletions
diff --git a/libartbase/base/array_slice.h b/libartbase/base/array_slice.h new file mode 100644 index 0000000000..1ef2fbad8b --- /dev/null +++ b/libartbase/base/array_slice.h @@ -0,0 +1,152 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ART_LIBARTBASE_BASE_ARRAY_SLICE_H_ +#define ART_LIBARTBASE_BASE_ARRAY_SLICE_H_ + +#include "base/bit_utils.h" +#include "base/casts.h" +#include "base/iteration_range.h" +#include "stride_iterator.h" + +namespace art { + +// An ArraySlice is an abstraction over an array or a part of an array of a particular type. It does +// bounds checking and can be made from several common array-like structures in Art. +template <typename T> +class ArraySlice { + public: + using value_type = T; + using reference = T&; + using const_reference = const T&; + using pointer = T*; + using const_pointer = const T*; + using iterator = StrideIterator<T>; + using const_iterator = StrideIterator<const T>; + using reverse_iterator = std::reverse_iterator<iterator>; + using const_reverse_iterator = std::reverse_iterator<const_iterator>; + using difference_type = ptrdiff_t; + using size_type = size_t; + + // Create an empty array slice. + ArraySlice() : array_(nullptr), size_(0), element_size_(0) {} + + // Create an array slice of the first 'length' elements of the array, with each element being + // element_size bytes long. + ArraySlice(T* array, + size_t length, + size_t element_size = sizeof(T)) + : array_(array), + size_(dchecked_integral_cast<uint32_t>(length)), + element_size_(element_size) { + DCHECK(array_ != nullptr || length == 0); + } + + // Iterators. + iterator begin() { return iterator(&AtUnchecked(0), element_size_); } + const_iterator begin() const { return const_iterator(&AtUnchecked(0), element_size_); } + const_iterator cbegin() const { return const_iterator(&AtUnchecked(0), element_size_); } + StrideIterator<T> end() { return StrideIterator<T>(&AtUnchecked(size_), element_size_); } + const_iterator end() const { return const_iterator(&AtUnchecked(size_), element_size_); } + const_iterator cend() const { return const_iterator(&AtUnchecked(size_), element_size_); } + reverse_iterator rbegin() { return reverse_iterator(end()); } + const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); } + const_reverse_iterator crbegin() const { return const_reverse_iterator(cend()); } + reverse_iterator rend() { return reverse_iterator(begin()); } + const_reverse_iterator rend() const { return const_reverse_iterator(begin()); } + const_reverse_iterator crend() const { return const_reverse_iterator(cbegin()); } + + // Size. + size_type size() const { return size_; } + bool empty() const { return size() == 0u; } + + // Element access. NOTE: Not providing at() and data(). + + reference operator[](size_t index) { + DCHECK_LT(index, size_); + return AtUnchecked(index); + } + + const_reference operator[](size_t index) const { + DCHECK_LT(index, size_); + return AtUnchecked(index); + } + + reference front() { + DCHECK(!empty()); + return (*this)[0]; + } + + const_reference front() const { + DCHECK(!empty()); + return (*this)[0]; + } + + reference back() { + DCHECK(!empty()); + return (*this)[size_ - 1u]; + } + + const_reference back() const { + DCHECK(!empty()); + return (*this)[size_ - 1u]; + } + + ArraySlice<T> SubArray(size_type pos) { + return SubArray(pos, size() - pos); + } + + ArraySlice<const T> SubArray(size_type pos) const { + return SubArray(pos, size() - pos); + } + + ArraySlice<T> SubArray(size_type pos, size_type length) { + DCHECK_LE(pos, size()); + DCHECK_LE(length, size() - pos); + return ArraySlice<T>(&AtUnchecked(pos), length, element_size_); + } + + ArraySlice<const T> SubArray(size_type pos, size_type length) const { + DCHECK_LE(pos, size()); + DCHECK_LE(length, size() - pos); + return ArraySlice<const T>(&AtUnchecked(pos), length, element_size_); + } + + size_t ElementSize() const { + return element_size_; + } + + bool Contains(const T* element) const { + return &AtUnchecked(0) <= element && element < &AtUnchecked(size_); + } + + private: + T& AtUnchecked(size_t index) { + return *reinterpret_cast<T*>(reinterpret_cast<uintptr_t>(array_) + index * element_size_); + } + + const T& AtUnchecked(size_t index) const { + return *reinterpret_cast<T*>(reinterpret_cast<uintptr_t>(array_) + index * element_size_); + } + + T* array_; + size_t size_; + size_t element_size_; +}; + +} // namespace art + +#endif // ART_LIBARTBASE_BASE_ARRAY_SLICE_H_ |