• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef API_BASE_CONTAINERS_ARRAYVIEW_H
17 #define API_BASE_CONTAINERS_ARRAYVIEW_H
18 
19 #include <cassert>
20 #include <cstddef>
21 #include <cstdint>
22 
23 #include <base/containers/iterator.h>
24 #include <base/containers/type_traits.h>
25 #include <base/namespace.h>
26 #include <base/util/hash.h>
27 #include <base/util/log.h>
28 
BASE_BEGIN_NAMESPACE()29 BASE_BEGIN_NAMESPACE()
30 /** @ingroup group_containers_arrayview */
31 /** Array view */
32 template<class T>
33 class array_view {
34 public:
35     using value_type = T;
36     using difference_type = ptrdiff_t;
37     using pointer = value_type*;
38     using reference = value_type&;
39 
40     using size_type = size_t;
41     using const_reference = const value_type&;
42     using const_pointer = const value_type*;
43 
44     using iterator = BASE_NS::iterator<array_view<T>>;
45     using const_iterator = BASE_NS::const_iterator<array_view<T>>;
46 
47     constexpr array_view() noexcept : begin_(nullptr), size_(0) {}
48     constexpr array_view(pointer begin, pointer end) noexcept
49         : begin_(begin), size_(static_cast<size_type>(end - begin))
50     {
51         BASE_ASSERT(end >= begin);
52     }
53     constexpr array_view(pointer begin, size_type size) noexcept : begin_(begin), size_(size) {}
54     template<size_t N>
55     constexpr array_view(value_type (&arr)[N]) noexcept : begin_(arr), size_(N)
56     {}
57     template<class U, class = enable_if_t<is_same_v<remove_const_t<T>, U>>>
58     constexpr array_view(const array_view<U>& other) noexcept : begin_(other.begin_), size_(other.size_)
59     {}
60     template<class U, class = enable_if_t<is_same_v<remove_const_t<T>, typename U::value_type>>>
61     constexpr array_view(U& container) noexcept : array_view(container.data(), container.size())
62     {}
63     template<class U, class = enable_if_t<is_same_v<remove_const_t<T>, typename U::value_type>>>
64     constexpr array_view(const U& container) noexcept : array_view(container.data(), container.size())
65     {}
66     template<class U = T, class = enable_if_t<is_const_v<U>>>
67     constexpr array_view(std::initializer_list<T> container) noexcept : array_view(container.begin(), container.end())
68     {}
69     ~array_view() = default;
70     constexpr size_type size() const noexcept
71     {
72         return size_;
73     }
74     constexpr size_type size_bytes() const noexcept
75     {
76         return size_ * sizeof(T);
77     }
78     constexpr bool empty() const noexcept
79     {
80         return size_ == 0;
81     }
82     constexpr const_pointer data() const noexcept
83     {
84         return begin_;
85     }
86     constexpr pointer data() noexcept
87     {
88         return begin_;
89     }
90     constexpr reference at(size_type aIndex) noexcept
91     {
92         // If index out-of-range, undefined behaviour on release builds, assert on debug builds.
93         BASE_ASSERT(aIndex < size());
94         return begin_[aIndex];
95     }
96     constexpr const_reference at(size_type aIndex) const noexcept
97     {
98         // If index out-of-range, undefined behaviour on release builds, assert on debug builds.
99         BASE_ASSERT(aIndex < size());
100         return begin_[aIndex];
101     }
102     constexpr reference operator[](size_type aIndex)
103     {
104         // If index out-of-range, undefined behaviour on release builds, assert on debug builds.
105         BASE_ASSERT(aIndex < size());
106         return begin_[aIndex];
107     }
108     constexpr const_reference operator[](size_type aIndex) const
109     {
110         // If index out-of-range, undefined behaviour on release builds, assert on debug builds.
111         BASE_ASSERT(aIndex < size());
112         return begin_[aIndex];
113     }
114     constexpr iterator begin() noexcept
115     {
116         return iterator(begin_);
117     }
118     constexpr iterator end() noexcept
119     {
120         return iterator(begin_ + size_);
121     }
122     constexpr const_iterator begin() const noexcept
123     {
124         return const_iterator(begin_);
125     }
126     constexpr const_iterator end() const noexcept
127     {
128         return const_iterator(begin_ + size_);
129     }
130     constexpr const_iterator cbegin() const noexcept
131     {
132         return begin();
133     }
134     constexpr const_iterator cend() const noexcept
135     {
136         return end();
137     }
138 
139 private:
140     template<class U>
141     friend class array_view;
142 
143     pointer begin_;
144     size_type size_;
145 };
146 
147 template<typename T, size_t N>
arrayview(T (& arr)[N])148 constexpr array_view<T> arrayview(T (&arr)[N]) noexcept
149 {
150     return array_view<T>(arr, N);
151 }
152 // Returns a const uint8_t array_view of any object.
153 template<typename T>
arrayviewU8(const T & arr)154 constexpr array_view<const uint8_t> arrayviewU8(const T& arr) noexcept
155 {
156     return array_view(reinterpret_cast<const uint8_t*>(&arr), sizeof(arr));
157 }
158 
159 template<typename T>
hash(const array_view<T> & view)160 inline uint64_t hash(const array_view<T>& view)
161 {
162     return FNV1aHash(view.data(), view.size());
163 }
164 BASE_END_NAMESPACE()
165 
166 #endif // API_BASE_CONTAINERS_ARRAYVIEW_H
167