You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
112 lines
3.6 KiB
112 lines
3.6 KiB
/* |
|
* Copyright 2022 Axel Waggershauser |
|
*/ |
|
// SPDX-License-Identifier: Apache-2.0 |
|
|
|
#pragma once |
|
|
|
#include "ZXAlgorithms.h" |
|
|
|
#include <cstdint> |
|
#include <iterator> |
|
|
|
namespace ZXing { |
|
|
|
template <typename Iterator> |
|
struct StrideIter |
|
{ |
|
Iterator pos; |
|
int stride; |
|
|
|
using iterator_category = std::random_access_iterator_tag; |
|
using difference_type = typename std::iterator_traits<Iterator>::difference_type; |
|
using value_type = typename std::iterator_traits<Iterator>::value_type; |
|
using pointer = Iterator; |
|
using reference = typename std::iterator_traits<Iterator>::reference; |
|
|
|
auto operator*() const { return *pos; } |
|
auto operator[](int i) const { return *(pos + i * stride); } |
|
StrideIter<Iterator>& operator++() { return pos += stride, *this; } |
|
StrideIter<Iterator> operator++(int) { auto temp = *this; ++*this; return temp; } |
|
bool operator==(const StrideIter<Iterator>& rhs) const { return pos == rhs.pos; } |
|
StrideIter<Iterator> operator+(int i) const { return {pos + i * stride, stride}; } |
|
StrideIter<Iterator> operator-(int i) const { return {pos - i * stride, stride}; } |
|
int operator-(const StrideIter<Iterator>& rhs) const { return narrow_cast<int>((pos - rhs.pos) / stride); } |
|
}; |
|
|
|
template <typename Iterator> |
|
StrideIter(const Iterator&, int) -> StrideIter<Iterator>; |
|
|
|
|
|
template <typename Iterator> |
|
struct Range |
|
{ |
|
Iterator _begin, _end; |
|
|
|
Range(Iterator b, Iterator e) : _begin(b), _end(e) {} |
|
|
|
template <typename C> |
|
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<int>(end() - begin()); } |
|
}; |
|
|
|
template <typename C> |
|
Range(const C&) -> Range<typename C::const_iterator>; |
|
|
|
/** |
|
* ArrayView is a lightweight, non-owning, non-mutable view over a contiguous sequence of elements. |
|
* Similar to std::span<const T>. See also Range template for general iterator use case. |
|
*/ |
|
template <typename T> |
|
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 <typename P, typename U = T, |
|
typename = std::enable_if_t< |
|
sizeof(U) == 1 && std::is_same_v<void, std::remove_cv_t<std::remove_reference_t<std::remove_pointer_t<P>>>>>> |
|
constexpr ArrayView(P data, size_type size) noexcept : _data(reinterpret_cast<pointer>(data)), _size(size) |
|
{} |
|
|
|
template <typename Container, |
|
typename = std::enable_if_t<std::is_convertible_v<decltype(std::data(std::declval<Container&>())), 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<T> 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<uint8_t>; |
|
|
|
} // namespace ZXing
|
|
|