/* * Copyright 2022 Axel Waggershauser */ // SPDX-License-Identifier: Apache-2.0 #pragma once #include "ZXAlgorithms.h" #include #include namespace ZXing { template struct StrideIter { Iterator pos; int stride; using iterator_category = std::random_access_iterator_tag; using difference_type = typename std::iterator_traits::difference_type; using value_type = typename std::iterator_traits::value_type; using pointer = Iterator; using reference = typename std::iterator_traits::reference; auto operator*() const { return *pos; } auto operator[](int i) const { return *(pos + i * stride); } StrideIter& operator++() { return pos += stride, *this; } StrideIter operator++(int) { auto temp = *this; ++*this; return temp; } bool operator==(const StrideIter& rhs) const { return pos == rhs.pos; } bool operator!=(const StrideIter& rhs) const { return pos != rhs.pos; } StrideIter operator+(int i) const { return {pos + i * stride, stride}; } StrideIter operator-(int i) const { return {pos - i * stride, stride}; } int operator-(const StrideIter& rhs) const { return narrow_cast((pos - rhs.pos) / stride); } }; template StrideIter(const Iterator&, int) -> StrideIter; template struct Range { Iterator _begin, _end; Range(Iterator b, Iterator e) : _begin(b), _end(e) {} template Range(const C& c) : _begin(std::begin(c)), _end(std::end(c)) {} Iterator begin() const noexcept { return _begin; } Iterator end() const noexcept { return _end; } explicit operator bool() const { return begin() < end(); } int size() const { return narrow_cast(end() - begin()); } }; template Range(const C&) -> Range; /** * ArrayView is a lightweight, non-owning, non-mutable view over a contiguous sequence of elements. * Similar to std::span. See also Range template for general iterator use case. */ template class ArrayView { const T* _data = nullptr; std::size_t _size = 0; public: using value_type = T; using pointer = const value_type*; using const_pointer = const value_type*; using reference = const value_type&; using const_reference = const value_type&; using size_type = std::size_t; constexpr ArrayView() noexcept = default; constexpr ArrayView(pointer data, size_type size) noexcept : _data(data), _size(size) {} template >>>>> constexpr ArrayView(P data, size_type size) noexcept : _data(reinterpret_cast(data)), _size(size) {} template ())), const_pointer>>> constexpr ArrayView(const Container& c) noexcept : _data(std::data(c)), _size(std::size(c)) {} constexpr pointer data() const noexcept { return _data; } constexpr size_type size() const noexcept { return _size; } constexpr bool empty() const noexcept { return _size == 0; } constexpr const_reference operator[](size_type index) const noexcept { return _data[index]; } constexpr pointer begin() const noexcept { return _data; } constexpr pointer end() const noexcept { return _data + _size; } constexpr ArrayView subview(size_type pos, size_type len = size_type(-1)) const noexcept { if (pos > _size) return {}; return {_data + pos, std::min(len, _size - pos)}; } }; using ByteView = ArrayView; } // namespace ZXing