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