18bf80f4bSopenharmony_ci/* 28bf80f4bSopenharmony_ci * Copyright (C) 2023 Huawei Device Co., Ltd. 38bf80f4bSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 48bf80f4bSopenharmony_ci * you may not use this file except in compliance with the License. 58bf80f4bSopenharmony_ci * You may obtain a copy of the License at 68bf80f4bSopenharmony_ci * 78bf80f4bSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 88bf80f4bSopenharmony_ci * 98bf80f4bSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 108bf80f4bSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 118bf80f4bSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 128bf80f4bSopenharmony_ci * See the License for the specific language governing permissions and 138bf80f4bSopenharmony_ci * limitations under the License. 148bf80f4bSopenharmony_ci */ 158bf80f4bSopenharmony_ci 168bf80f4bSopenharmony_ci#ifndef API_BASE_CONTAINERS_ARRAYVIEW_H 178bf80f4bSopenharmony_ci#define API_BASE_CONTAINERS_ARRAYVIEW_H 188bf80f4bSopenharmony_ci 198bf80f4bSopenharmony_ci#include <cassert> 208bf80f4bSopenharmony_ci#include <cstdint> 218bf80f4bSopenharmony_ci#include <iterator> 228bf80f4bSopenharmony_ci#include <type_traits> 238bf80f4bSopenharmony_ci 248bf80f4bSopenharmony_ci/** @ingroup group_containers_arrayview */ 258bf80f4bSopenharmony_ci/** Array view */ 268bf80f4bSopenharmony_citemplate<class T> 278bf80f4bSopenharmony_ciclass array_view { 288bf80f4bSopenharmony_cipublic: 298bf80f4bSopenharmony_ci struct Iterator { 308bf80f4bSopenharmony_ci using iterator_category = std::forward_iterator_tag; 318bf80f4bSopenharmony_ci using difference_type = std::ptrdiff_t; 328bf80f4bSopenharmony_ci using value_type = T; 338bf80f4bSopenharmony_ci using pointer = T*; 348bf80f4bSopenharmony_ci using reference = T&; 358bf80f4bSopenharmony_ci 368bf80f4bSopenharmony_ci Iterator(pointer ptr) : m_ptr(ptr) {} 378bf80f4bSopenharmony_ci 388bf80f4bSopenharmony_ci reference operator*() const 398bf80f4bSopenharmony_ci { 408bf80f4bSopenharmony_ci return *m_ptr; 418bf80f4bSopenharmony_ci } 428bf80f4bSopenharmony_ci pointer operator->() 438bf80f4bSopenharmony_ci { 448bf80f4bSopenharmony_ci return m_ptr; 458bf80f4bSopenharmony_ci } 468bf80f4bSopenharmony_ci Iterator& operator++() 478bf80f4bSopenharmony_ci { 488bf80f4bSopenharmony_ci m_ptr++; 498bf80f4bSopenharmony_ci return *this; 508bf80f4bSopenharmony_ci } 518bf80f4bSopenharmony_ci Iterator operator++(int) 528bf80f4bSopenharmony_ci { 538bf80f4bSopenharmony_ci Iterator tmp = *this; 548bf80f4bSopenharmony_ci ++(*this); 558bf80f4bSopenharmony_ci return tmp; 568bf80f4bSopenharmony_ci } 578bf80f4bSopenharmony_ci friend bool operator==(const Iterator& a, const Iterator& b) 588bf80f4bSopenharmony_ci { 598bf80f4bSopenharmony_ci return a.m_ptr == b.m_ptr; 608bf80f4bSopenharmony_ci }; 618bf80f4bSopenharmony_ci friend bool operator!=(const Iterator& a, const Iterator& b) 628bf80f4bSopenharmony_ci { 638bf80f4bSopenharmony_ci return a.m_ptr != b.m_ptr; 648bf80f4bSopenharmony_ci }; 658bf80f4bSopenharmony_ci 668bf80f4bSopenharmony_ci private: 678bf80f4bSopenharmony_ci pointer m_ptr; 688bf80f4bSopenharmony_ci }; 698bf80f4bSopenharmony_ci using value_type = T; 708bf80f4bSopenharmony_ci using difference_type = size_t; 718bf80f4bSopenharmony_ci using pointer = value_type*; 728bf80f4bSopenharmony_ci using reference = value_type&; 738bf80f4bSopenharmony_ci 748bf80f4bSopenharmony_ci using size_type = size_t; 758bf80f4bSopenharmony_ci using const_reference = const value_type&; 768bf80f4bSopenharmony_ci using const_pointer = const value_type*; 778bf80f4bSopenharmony_ci 788bf80f4bSopenharmony_ci using iterator = Iterator; 798bf80f4bSopenharmony_ci using const_iterator = Iterator; 808bf80f4bSopenharmony_ci 818bf80f4bSopenharmony_ci constexpr array_view() noexcept : begin_(nullptr), size_(0), end_(nullptr) {} 828bf80f4bSopenharmony_ci constexpr array_view(pointer aBegin, pointer aEnd) noexcept : begin_(aBegin), size_(aEnd - aBegin), end_(aEnd) 838bf80f4bSopenharmony_ci { 848bf80f4bSopenharmony_ci assert(end_ >= begin_); 858bf80f4bSopenharmony_ci } 868bf80f4bSopenharmony_ci constexpr array_view(pointer aBegin, size_type aSize) noexcept : begin_(aBegin), size_(aSize), end_(aBegin + aSize) 878bf80f4bSopenharmony_ci {} 888bf80f4bSopenharmony_ci template<size_t N> 898bf80f4bSopenharmony_ci constexpr array_view(value_type (&arr)[N]) noexcept : begin_(arr), size_(N), end_(arr + N) 908bf80f4bSopenharmony_ci {} 918bf80f4bSopenharmony_ci template<class U, class = std::enable_if_t<std::is_same<std::remove_const_t<T>, U>::value>> 928bf80f4bSopenharmony_ci constexpr array_view(const array_view<U>& other) noexcept 938bf80f4bSopenharmony_ci : begin_(other.begin_), size_(other.size_), end_(other.end_) 948bf80f4bSopenharmony_ci {} 958bf80f4bSopenharmony_ci template<class U, class = std::enable_if_t<std::is_same<std::remove_const_t<T>, typename U::value_type>::value>> 968bf80f4bSopenharmony_ci constexpr array_view(U& container) noexcept : array_view(container.data(), container.size()) 978bf80f4bSopenharmony_ci {} 988bf80f4bSopenharmony_ci template<class U, class = std::enable_if_t<std::is_same<std::remove_const_t<T>, typename U::value_type>::value>> 998bf80f4bSopenharmony_ci constexpr array_view(const U& container) noexcept : array_view(container.data(), container.size()) 1008bf80f4bSopenharmony_ci {} 1018bf80f4bSopenharmony_ci ~array_view() = default; 1028bf80f4bSopenharmony_ci constexpr size_type size() const noexcept 1038bf80f4bSopenharmony_ci { 1048bf80f4bSopenharmony_ci return size_; 1058bf80f4bSopenharmony_ci } 1068bf80f4bSopenharmony_ci constexpr size_type size_bytes() const noexcept 1078bf80f4bSopenharmony_ci { 1088bf80f4bSopenharmony_ci return size_ * sizeof(T); 1098bf80f4bSopenharmony_ci } 1108bf80f4bSopenharmony_ci constexpr bool empty() const noexcept 1118bf80f4bSopenharmony_ci { 1128bf80f4bSopenharmony_ci return size_ == 0; 1138bf80f4bSopenharmony_ci } 1148bf80f4bSopenharmony_ci constexpr const_pointer data() const noexcept 1158bf80f4bSopenharmony_ci { 1168bf80f4bSopenharmony_ci return begin_; 1178bf80f4bSopenharmony_ci } 1188bf80f4bSopenharmony_ci constexpr pointer data() noexcept 1198bf80f4bSopenharmony_ci { 1208bf80f4bSopenharmony_ci return begin_; 1218bf80f4bSopenharmony_ci } 1228bf80f4bSopenharmony_ci constexpr reference at(size_type aIndex) noexcept 1238bf80f4bSopenharmony_ci { 1248bf80f4bSopenharmony_ci // If index out-of-range, undefined behaviour on release builds, assert on debug builds. 1258bf80f4bSopenharmony_ci assert(aIndex < size()); 1268bf80f4bSopenharmony_ci return begin_[aIndex]; 1278bf80f4bSopenharmony_ci } 1288bf80f4bSopenharmony_ci constexpr const_reference at(size_type aIndex) const noexcept 1298bf80f4bSopenharmony_ci { 1308bf80f4bSopenharmony_ci // If index out-of-range, undefined behaviour on release builds, assert on debug builds. 1318bf80f4bSopenharmony_ci assert(aIndex < size()); 1328bf80f4bSopenharmony_ci return begin_[aIndex]; 1338bf80f4bSopenharmony_ci } 1348bf80f4bSopenharmony_ci constexpr reference operator[](size_type aIndex) 1358bf80f4bSopenharmony_ci { 1368bf80f4bSopenharmony_ci // If index out-of-range, undefined behaviour on release builds, assert on debug builds. 1378bf80f4bSopenharmony_ci assert(aIndex < size()); 1388bf80f4bSopenharmony_ci return begin_[aIndex]; 1398bf80f4bSopenharmony_ci } 1408bf80f4bSopenharmony_ci constexpr const_reference operator[](size_type aIndex) const 1418bf80f4bSopenharmony_ci { 1428bf80f4bSopenharmony_ci // If index out-of-range, undefined behaviour on release builds, assert on debug builds. 1438bf80f4bSopenharmony_ci assert(aIndex < size()); 1448bf80f4bSopenharmony_ci return begin_[aIndex]; 1458bf80f4bSopenharmony_ci } 1468bf80f4bSopenharmony_ci constexpr iterator begin() noexcept 1478bf80f4bSopenharmony_ci { 1488bf80f4bSopenharmony_ci return iterator(begin_); 1498bf80f4bSopenharmony_ci } 1508bf80f4bSopenharmony_ci constexpr iterator end() noexcept 1518bf80f4bSopenharmony_ci { 1528bf80f4bSopenharmony_ci return iterator(begin_ + size_); 1538bf80f4bSopenharmony_ci } 1548bf80f4bSopenharmony_ci constexpr const_iterator begin() const noexcept 1558bf80f4bSopenharmony_ci { 1568bf80f4bSopenharmony_ci return const_iterator(begin_); 1578bf80f4bSopenharmony_ci } 1588bf80f4bSopenharmony_ci constexpr const_iterator end() const noexcept 1598bf80f4bSopenharmony_ci { 1608bf80f4bSopenharmony_ci return const_iterator(begin_ + size_); 1618bf80f4bSopenharmony_ci } 1628bf80f4bSopenharmony_ci constexpr const_iterator cbegin() const noexcept 1638bf80f4bSopenharmony_ci { 1648bf80f4bSopenharmony_ci return begin(); 1658bf80f4bSopenharmony_ci } 1668bf80f4bSopenharmony_ci constexpr const_iterator cend() const noexcept 1678bf80f4bSopenharmony_ci { 1688bf80f4bSopenharmony_ci return end(); 1698bf80f4bSopenharmony_ci } 1708bf80f4bSopenharmony_ci 1718bf80f4bSopenharmony_ciprivate: 1728bf80f4bSopenharmony_ci template<class U> 1738bf80f4bSopenharmony_ci friend class array_view; 1748bf80f4bSopenharmony_ci 1758bf80f4bSopenharmony_ci pointer begin_; 1768bf80f4bSopenharmony_ci size_type size_; 1778bf80f4bSopenharmony_ci pointer end_; 1788bf80f4bSopenharmony_ci}; 1798bf80f4bSopenharmony_ci 1808bf80f4bSopenharmony_citemplate<typename T, size_t N> 1818bf80f4bSopenharmony_ciconstexpr size_t countof(T (&)[N]) noexcept 1828bf80f4bSopenharmony_ci{ 1838bf80f4bSopenharmony_ci return N; 1848bf80f4bSopenharmony_ci} 1858bf80f4bSopenharmony_citemplate<typename T, size_t N> 1868bf80f4bSopenharmony_ciconstexpr array_view<T> arrayview(T (&arr)[N]) noexcept 1878bf80f4bSopenharmony_ci{ 1888bf80f4bSopenharmony_ci return array_view<T>(arr, N); 1898bf80f4bSopenharmony_ci} 1908bf80f4bSopenharmony_ci// Returns a const uint8_t array_view of any object. 1918bf80f4bSopenharmony_citemplate<typename T> 1928bf80f4bSopenharmony_ciconstexpr array_view<const uint8_t> arrayviewU8(const T& arr) noexcept 1938bf80f4bSopenharmony_ci{ 1948bf80f4bSopenharmony_ci return array_view(reinterpret_cast<const uint8_t*>(&arr), sizeof(arr)); 1958bf80f4bSopenharmony_ci} 1968bf80f4bSopenharmony_ci 1978bf80f4bSopenharmony_ci#endif // API_BASE_CONTAINERS_ARRAYVIEW_H 198