Monero
span.h
Go to the documentation of this file.
1 // Copyright (c) 2017-2022, The Monero Project
2 //
3 // All rights reserved.
4 //
5 // Redistribution and use in source and binary forms, with or without modification, are
6 // permitted provided that the following conditions are met:
7 //
8 // 1. Redistributions of source code must retain the above copyright notice, this list of
9 // conditions and the following disclaimer.
10 //
11 // 2. Redistributions in binary form must reproduce the above copyright notice, this list
12 // of conditions and the following disclaimer in the documentation and/or other
13 // materials provided with the distribution.
14 //
15 // 3. Neither the name of the copyright holder nor the names of its contributors may be
16 // used to endorse or promote products derived from this software without specific
17 // prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
20 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
22 // THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26 // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
27 // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 
29 #pragma once
30 
31 #include <algorithm>
32 #include <cstdint>
33 #include <memory>
34 #include <type_traits>
35 
36 namespace epee
37 {
53  template<typename T>
54  class span
55  {
56  template<typename U>
57  static constexpr bool safe_conversion() noexcept
58  {
59  // Allow exact matches or `T*` -> `const T*`.
60  using with_const = typename std::add_const<U>::type;
61  return std::is_same<T, U>() ||
62  (std::is_const<T>() && std::is_same<T, with_const>());
63  }
64 
65  public:
66  using value_type = T;
67  using size_type = std::size_t;
68  using difference_type = std::ptrdiff_t;
69  using pointer = T*;
70  using const_pointer = const T*;
71  using reference = T&;
72  using const_reference = const T&;
73  using iterator = pointer;
75 
76  constexpr span() noexcept : ptr(nullptr), len(0) {}
77  constexpr span(std::nullptr_t) noexcept : span() {}
78 
80  template<typename U, typename = typename std::enable_if<safe_conversion<U>()>::type>
81  constexpr span(U* const src_ptr, const std::size_t count) noexcept
82  : ptr(src_ptr), len(count) {}
83 
85  template<std::size_t N>
86  constexpr span(T (&src)[N]) noexcept : span(src, N) {}
87 
88  constexpr span(const span&) noexcept = default;
89  span& operator=(const span&) noexcept = default;
90 
93  std::size_t remove_prefix(std::size_t amount) noexcept
94  {
95  amount = std::min(len, amount);
96  ptr += amount;
97  len -= amount;
98  return amount;
99  }
100 
101  constexpr iterator begin() const noexcept { return ptr; }
102  constexpr const_iterator cbegin() const noexcept { return ptr; }
103 
104  constexpr iterator end() const noexcept { return begin() + size(); }
105  constexpr const_iterator cend() const noexcept { return cbegin() + size(); }
106 
107  constexpr bool empty() const noexcept { return size() == 0; }
108  constexpr pointer data() const noexcept { return ptr; }
109  constexpr std::size_t size() const noexcept { return len; }
110  constexpr std::size_t size_bytes() const noexcept { return size() * sizeof(value_type); }
111 
112  T &operator[](size_t idx) noexcept { return ptr[idx]; }
113  const T &operator[](size_t idx) const noexcept { return ptr[idx]; }
114 
115  private:
116  T* ptr;
117  std::size_t len;
118  };
119 
121  template<typename T>
123  {
124  // compiler provides diagnostic if size() is not size_t.
125  return {src.data(), src.size()};
126  }
127 
129  template<typename T>
131  {
132  // compiler provides diagnostic if size() is not size_t.
133  return {src.data(), src.size()};
134  }
135 
137  template<typename T>
139  {
140  static_assert(!std::is_empty<T>(), "empty value types will not work -> sizeof == 1");
141  static_assert(std::is_standard_layout<T>(), "type must have standard layout");
142  static_assert(std::is_trivially_copyable<T>(), "type must be trivially copyable");
143  static_assert(alignof(T) == 1, "type may have padding");
144  return {reinterpret_cast<const std::uint8_t*>(src.data()), src.size_bytes()};
145  }
146 
148  template<typename T>
150  {
151  using value_type = typename T::value_type;
152  static_assert(!std::is_empty<value_type>(), "empty value types will not work -> sizeof == 1");
153  static_assert(std::is_standard_layout<value_type>(), "value type must have standard layout");
154  static_assert(std::is_trivially_copyable<value_type>(), "value type must be trivially copyable");
155  static_assert(alignof(value_type) == 1, "value type may have padding");
156  return {reinterpret_cast<std::uint8_t*>(src.data()), src.size() * sizeof(value_type)};
157  }
158 
160  template<typename T>
162  {
163  static_assert(!std::is_empty<T>(), "empty types will not work -> sizeof == 1");
164  static_assert(std::is_standard_layout<T>(), "type must have standard layout");
165  static_assert(std::is_trivially_copyable<T>(), "type must be trivially copyable");
166  static_assert(alignof(T) == 1, "type may have padding");
167  return {reinterpret_cast<const std::uint8_t*>(std::addressof(src)), sizeof(T)};
168  }
169 
171  template<typename T>
173  {
174  static_assert(!std::is_empty<T>(), "empty types will not work -> sizeof == 1");
175  static_assert(std::is_standard_layout<T>(), "type must have standard layout");
176  static_assert(std::is_trivially_copyable<T>(), "type must be trivially copyable");
177  static_assert(alignof(T) == 1, "type may have padding");
178  return {reinterpret_cast<std::uint8_t*>(std::addressof(src)), sizeof(T)};
179  }
180 
182  template<typename T, typename U>
183  span<const T> strspan(const U&s) noexcept
184  {
185  static_assert(std::is_same<typename U::value_type, char>(), "unexpected source type");
186  static_assert(std::is_same<T, char>() || std::is_same<T, unsigned char>() || std::is_same<T, int8_t>() || std::is_same<T, uint8_t>(), "Unexpected destination type");
187  return {reinterpret_cast<const T*>(s.data()), s.size()};
188  }
189 }
std::size_t size_type
Definition: span.h:67
const uint32_t T[512]
Definition: groestl_tables.h:36
span< const std::uint8_t > as_byte_span(const T &src) noexcept
Definition: span.h:161
span & operator=(const span &) noexcept=default
int * count
Definition: gmock_stress_test.cc:176
constexpr const_iterator cbegin() const noexcept
Definition: span.h:102
static constexpr bool safe_conversion() noexcept
Definition: span.h:57
int type
Definition: superscalar.cpp:50
const char * s
Definition: minissdp.c:596
std::size_t len
Definition: span.h:117
const const std::uint8_t * const_pointer
Definition: span.h:70
span< std::uint8_t > as_mut_byte_span(T &src) noexcept
Definition: span.h:172
Non-owning sequence of data. Does not deep copy.
Definition: span.h:54
unsigned char uint8_t
Definition: stdint.h:124
const std::uint8_t value_type
Definition: span.h:66
constexpr std::size_t size() const noexcept
Definition: span.h:109
constexpr span< typename T::value_type > to_mut_span(T &src)
Definition: span.h:130
constexpr const_iterator cend() const noexcept
Definition: span.h:105
const_pointer const_iterator
Definition: span.h:74
#define min(a, b)
Definition: oaes_lib.c:78
constexpr span< std::uint8_t > to_mut_byte_span(T &src)
Definition: span.h:149
constexpr iterator end() const noexcept
Definition: span.h:104
constexpr span(std::nullptr_t) noexcept
Definition: span.h:77
const T & operator[](size_t idx) const noexcept
Definition: span.h:113
std::size_t remove_prefix(std::size_t amount) noexcept
Definition: span.h:93
constexpr span(U *const src_ptr, const std::size_t count) noexcept
Prevent derived-to-base conversions; invalid in this context.
Definition: span.h:81
TODO: (mj-xmr) This will be reduced in an another PR.
Definition: byte_slice.h:39
constexpr span< const typename T::value_type > to_span(const T &src)
Definition: span.h:122
span< const T > strspan(const U &s) noexcept
make a span from a std::string
Definition: span.h:183
const const std::uint8_t & const_reference
Definition: span.h:72
T & operator[](size_t idx) noexcept
Definition: span.h:112
constexpr iterator begin() const noexcept
Definition: span.h:101
constexpr std::size_t size_bytes() const noexcept
Definition: span.h:110
constexpr span() noexcept
Definition: span.h:76
constexpr bool empty() const noexcept
Definition: span.h:107
const std::uint8_t * pointer
Definition: span.h:69
constexpr span(T(&src)[N]) noexcept
Conversion from C-array. Prevents common bugs with sizeof + arrays.
Definition: span.h:86
#define const
Definition: ipfrdr.c:80
T * ptr
Definition: span.h:116
std::ptrdiff_t difference_type
Definition: span.h:68
pointer iterator
Definition: span.h:73
span< const std::uint8_t > to_byte_span(const span< const T > src) noexcept
Definition: span.h:138
Definition: blockchain_usage.cpp:71
constexpr pointer data() const noexcept
Definition: span.h:108