summaryrefslogtreecommitdiff
path: root/libartbase/base/array_ref.h
diff options
context:
space:
mode:
author David Sehr <sehr@google.com> 2018-03-02 12:01:51 -0800
committer David Sehr <sehr@google.com> 2018-03-05 13:58:20 -0800
commitc431b9dc4b23cc950eb313695258df5d89f53b22 (patch)
tree422273559c3ae52caff0c6b1cf1a62a8312f0e26 /libartbase/base/array_ref.h
parentf46f46cf5bd32788d5252b7107628a66594a5e98 (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_ref.h')
-rw-r--r--libartbase/base/array_ref.h209
1 files changed, 209 insertions, 0 deletions
diff --git a/libartbase/base/array_ref.h b/libartbase/base/array_ref.h
new file mode 100644
index 0000000000..1d7bde6044
--- /dev/null
+++ b/libartbase/base/array_ref.h
@@ -0,0 +1,209 @@
+/*
+ * Copyright (C) 2014 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_REF_H_
+#define ART_LIBARTBASE_BASE_ARRAY_REF_H_
+
+#include <type_traits>
+#include <vector>
+
+#include <android-base/logging.h>
+
+namespace art {
+
+/**
+ * @brief A container that references an array.
+ *
+ * @details The template class ArrayRef provides a container that references
+ * an external array. This external array must remain alive while the ArrayRef
+ * object is in use. The external array may be a std::vector<>-backed storage
+ * or any other contiguous chunk of memory but that memory must remain valid,
+ * i.e. the std::vector<> must not be resized for example.
+ *
+ * Except for copy/assign and insert/erase/capacity functions, the interface
+ * is essentially the same as std::vector<>. Since we don't want to throw
+ * exceptions, at() is also excluded.
+ */
+template <typename T>
+class ArrayRef {
+ public:
+ using value_type = T;
+ using reference = T&;
+ using const_reference = const T&;
+ using pointer = T*;
+ using const_pointer = const T*;
+ using iterator = T*;
+ using const_iterator = 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;
+
+ // Constructors.
+
+ constexpr ArrayRef()
+ : array_(nullptr), size_(0u) {
+ }
+
+ template <size_t size>
+ explicit constexpr ArrayRef(T (&array)[size])
+ : array_(array), size_(size) {
+ }
+
+ template <typename U,
+ size_t size,
+ typename = typename std::enable_if<std::is_same<T, const U>::value>::type>
+ explicit constexpr ArrayRef(U (&array)[size])
+ : array_(array), size_(size) {
+ }
+
+ constexpr ArrayRef(T* array_in, size_t size_in)
+ : array_(array_in), size_(size_in) {
+ }
+
+ template <typename Vector,
+ typename = typename std::enable_if<
+ std::is_same<typename Vector::value_type, value_type>::value>::type>
+ explicit ArrayRef(Vector& v)
+ : array_(v.data()), size_(v.size()) {
+ }
+
+ template <typename Vector,
+ typename = typename std::enable_if<
+ std::is_same<
+ typename std::add_const<typename Vector::value_type>::type,
+ value_type>::value>::type>
+ explicit ArrayRef(const Vector& v)
+ : array_(v.data()), size_(v.size()) {
+ }
+
+ ArrayRef(const ArrayRef&) = default;
+
+ // Assignment operators.
+
+ ArrayRef& operator=(const ArrayRef& other) {
+ array_ = other.array_;
+ size_ = other.size_;
+ return *this;
+ }
+
+ template <typename U>
+ typename std::enable_if<std::is_same<T, const U>::value, ArrayRef>::type&
+ operator=(const ArrayRef<U>& other) {
+ return *this = ArrayRef(other);
+ }
+
+ template <typename U>
+ static ArrayRef Cast(const ArrayRef<U>& src) {
+ return ArrayRef(reinterpret_cast<const T*>(src.data()),
+ src.size() * sizeof(T) / sizeof(U));
+ }
+
+ // Destructor.
+ ~ArrayRef() = default;
+
+ // Iterators.
+ iterator begin() { return array_; }
+ const_iterator begin() const { return array_; }
+ const_iterator cbegin() const { return array_; }
+ iterator end() { return array_ + size_; }
+ const_iterator end() const { return array_ + size_; }
+ const_iterator cend() const { return array_ + 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().
+
+ reference operator[](size_type n) {
+ DCHECK_LT(n, size_);
+ return array_[n];
+ }
+
+ const_reference operator[](size_type n) const {
+ DCHECK_LT(n, size_);
+ return array_[n];
+ }
+
+ reference front() {
+ DCHECK(!empty());
+ return array_[0];
+ }
+
+ const_reference front() const {
+ DCHECK(!empty());
+ return array_[0];
+ }
+
+ reference back() {
+ DCHECK(!empty());
+ return array_[size_ - 1u];
+ }
+
+ const_reference back() const {
+ DCHECK(!empty());
+ return array_[size_ - 1u];
+ }
+
+ value_type* data() { return array_; }
+ const value_type* data() const { return array_; }
+
+ ArrayRef SubArray(size_type pos) {
+ return SubArray(pos, size() - pos);
+ }
+
+ ArrayRef<const T> SubArray(size_type pos) const {
+ return SubArray(pos, size() - pos);
+ }
+
+ ArrayRef SubArray(size_type pos, size_type length) {
+ DCHECK_LE(pos, size());
+ DCHECK_LE(length, size() - pos);
+ return ArrayRef(data() + pos, length);
+ }
+
+ ArrayRef<const T> SubArray(size_type pos, size_type length) const {
+ DCHECK_LE(pos, size());
+ DCHECK_LE(length, size() - pos);
+ return ArrayRef<const T>(data() + pos, length);
+ }
+
+ private:
+ T* array_;
+ size_t size_;
+};
+
+template <typename T>
+bool operator==(const ArrayRef<T>& lhs, const ArrayRef<T>& rhs) {
+ return lhs.size() == rhs.size() && std::equal(lhs.begin(), lhs.end(), rhs.begin());
+}
+
+template <typename T>
+bool operator!=(const ArrayRef<T>& lhs, const ArrayRef<T>& rhs) {
+ return !(lhs == rhs);
+}
+
+} // namespace art
+
+
+#endif // ART_LIBARTBASE_BASE_ARRAY_REF_H_