CsCrypto  1.0.1
span.h
1 /***********************************************************************
2 *
3 * Copyright (c) 2021-2024 Tim van Deurzen
4 * Copyright (c) 2021-2024 Barbara Geller
5 * Copyright (c) 2021-2024 Ansel Sermersheim
6 *
7 * This file is part of CsCrypto.
8 *
9 * CsCrypto is free software, released under the BSD 2-Clause license.
10 * For license details refer to LICENSE provided with this project.
11 *
12 * CsCrypto is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15 *
16 * https://opensource.org/licenses/BSD-2-Clause
17 *
18 ***********************************************************************/
19 
20 #ifndef CS_CRYPTO_UTIL_SPAN_H
21 #define CS_CRYPTO_UTIL_SPAN_H
22 
23 #include <util/tools/crypto_traits.h>
24 
25 #include <array>
26 #include <iterator>
27 #include <limits>
28 #include <type_traits>
29 
30 namespace cs_crypto::util {
31 
32 template <typename T>
33 class span
34 {
35  public:
36  using element_type = T;
37  using value_type = std::remove_cv_t<T>;
38  using size_type = std::size_t;
39  using difference_type = std::ptrdiff_t;
40  using reference = element_type &;
41  using const_reference = const element_type &;
42  using pointer = element_type *;
43  using const_pointer = const element_type *;
44  using iterator = pointer;
45  using const_iterator = const_pointer;
46 
47  constexpr span() = default;
48 
49  template <typename Iter, typename = std::enable_if_t<std::is_same_v<typename std::iterator_traits<Iter>::iterator_category,
50  std::random_access_iterator_tag>>>
51  constexpr span(Iter iter, size_type size) noexcept
52  : m_data(std::addressof(*iter)), m_size(size)
53  {
54  }
55 
56  template <std::size_t N>
57  constexpr explicit span(const cs_crypto::traits::identity_t<element_type> (&arr)[N]) noexcept
58  : m_data(std::data(arr)), m_size(N)
59  {
60  }
61 
62  template <std::size_t N>
63  constexpr explicit span(std::array<T, N> &arr) noexcept
64  : m_data(std::data(arr)), m_size(N)
65  {
66  }
67 
68  template <std::size_t N>
69  constexpr explicit span(const std::array<T, N> &arr) noexcept
70  : m_data(std::data(arr)), m_size(N)
71  {
72  }
73 
74  constexpr span(const span &) = default;
75  constexpr span &operator=(const span &) & = default;
76 
77  constexpr span(span &&) = default;
78  constexpr span &operator=(span &&) & = default;
79 
80  constexpr const_iterator begin() const noexcept
81  {
82  return m_data;
83  }
84 
85  constexpr const_iterator end() const noexcept
86  {
87  return m_data + m_size;
88  }
89 
90  constexpr const_pointer data() const noexcept
91  {
92  return m_data;
93  }
94 
95  constexpr size_type size() const noexcept
96  {
97  return m_size;
98  }
99 
100  constexpr bool empty() const noexcept
101  {
102  return m_size == 0;
103  }
104 
105  private:
106  const_pointer m_data = nullptr;
107  const size_type m_size = 0;
108 };
109 
110 template <class It>
111 span(It, std::size_t) -> span<std::remove_reference_t<typename std::iterator_traits<It>::reference>>;
112 
113 } // namespace cs_crypto::util
114 
115 #endif