• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 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 <cstdint>
21 
22 #include <base/containers/iterator.h>
23 #include <base/containers/type_traits.h>
24 #include <base/namespace.h>
25 #include <base/util/log.h>
26 
BASE_BEGIN_NAMESPACE()27 BASE_BEGIN_NAMESPACE()
28 /** @ingroup group_containers_arrayview */
29 /** Array view */
30 template<class T>
31 class array_view {
32 public:
33     using value_type = T;
34     using difference_type = size_t;
35     using pointer = value_type*;
36     using reference = value_type&;
37 
38     using size_type = size_t;
39     using const_reference = const value_type&;
40     using const_pointer = const value_type*;
41 
42     using iterator = BASE_NS::iterator<array_view<T>>;
43     using const_iterator = BASE_NS::const_iterator<array_view<T>>;
44 
45     constexpr array_view() noexcept : begin_(nullptr), size_(0) {}
46     constexpr array_view(pointer aBegin, pointer aEnd) noexcept : begin_(aBegin), size_(aEnd - aBegin)
47     {
48         BASE_ASSERT(aEnd >= aBegin);
49     }
50     constexpr array_view(pointer aBegin, size_type aSize) noexcept : begin_(aBegin), size_(aSize) {}
51     template<size_t N>
52     constexpr array_view(value_type (&arr)[N]) noexcept : begin_(arr), size_(N)
53     {}
54     template<class U, class = enable_if_t<is_same<remove_const_t<T>, U>::value>>
55     constexpr array_view(const array_view<U>& other) noexcept : begin_(other.begin_), size_(other.size_)
56     {}
57     template<class U, class = enable_if_t<is_same<remove_const_t<T>, typename U::value_type>::value>>
58     constexpr array_view(U& container) noexcept : array_view(container.data(), container.size())
59     {}
60     template<class U, class = enable_if_t<is_same<remove_const_t<T>, typename U::value_type>::value>>
61     constexpr array_view(const U& container) noexcept : array_view(container.data(), container.size())
62     {}
63     ~array_view() = default;
64     constexpr size_type size() const noexcept
65     {
66         return size_;
67     }
68     constexpr size_type size_bytes() const noexcept
69     {
70         return size_ * sizeof(T);
71     }
72     constexpr bool empty() const noexcept
73     {
74         return size_ == 0;
75     }
76     constexpr const_pointer data() const noexcept
77     {
78         return begin_;
79     }
80     constexpr pointer data() noexcept
81     {
82         return begin_;
83     }
84     constexpr reference at(size_type aIndex) noexcept
85     {
86         // If index out-of-range, undefined behaviour on release builds, assert on debug builds.
87         BASE_ASSERT(aIndex < size());
88         return begin_[aIndex];
89     }
90     constexpr const_reference at(size_type aIndex) const 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 reference operator[](size_type aIndex)
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 const_reference operator[](size_type aIndex) const
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 iterator begin() noexcept
109     {
110         return iterator(begin_);
111     }
112     constexpr iterator end() noexcept
113     {
114         return iterator(begin_ + size_);
115     }
116     constexpr const_iterator begin() const noexcept
117     {
118         return const_iterator(begin_);
119     }
120     constexpr const_iterator end() const noexcept
121     {
122         return const_iterator(begin_ + size_);
123     }
124     constexpr const_iterator cbegin() const noexcept
125     {
126         return begin();
127     }
128     constexpr const_iterator cend() const noexcept
129     {
130         return end();
131     }
132 
133 private:
134     template<class U>
135     friend class array_view;
136 
137     pointer begin_;
138     size_type size_;
139 };
140 
141 template<typename T, size_t N>
countof(T (&)[N])142 constexpr size_t countof(T (&)[N]) noexcept
143 {
144     return N;
145 }
146 template<typename T, size_t N>
arrayview(T (& arr)[N])147 constexpr array_view<T> arrayview(T (&arr)[N]) noexcept
148 {
149     return array_view<T>(arr, N);
150 }
151 // Returns a const uint8_t array_view of any object.
152 template<typename T>
arrayviewU8(const T & arr)153 constexpr array_view<const uint8_t> arrayviewU8(const T& arr) noexcept
154 {
155     return array_view(reinterpret_cast<const uint8_t*>(&arr), sizeof(arr));
156 }
157 BASE_END_NAMESPACE()
158 
159 #endif // API_BASE_CONTAINERS_ARRAYVIEW_H
160