Monero
Loading...
Searching...
No Matches
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
36namespace 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&;
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:
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}
#define s(x, c)
Definition aesb.c:47
Non-owning sequence of data. Does not deep copy.
Definition span.h:55
std::size_t remove_prefix(std::size_t amount) noexcept
Definition span.h:93
T & operator[](size_t idx) noexcept
Definition span.h:112
const T & const_reference
Definition span.h:72
constexpr const_iterator cend() const noexcept
Definition span.h:105
constexpr span(T(&src)[N]) noexcept
Conversion from C-array. Prevents common bugs with sizeof + arrays.
Definition span.h:86
static constexpr bool safe_conversion() noexcept
Definition span.h:57
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
constexpr std::size_t size_bytes() const noexcept
Definition span.h:110
constexpr iterator end() const noexcept
Definition span.h:104
constexpr std::size_t size() const noexcept
Definition span.h:109
const T * const_pointer
Definition span.h:70
std::ptrdiff_t difference_type
Definition span.h:68
pointer iterator
Definition span.h:73
T value_type
Definition span.h:66
constexpr const_iterator cbegin() const noexcept
Definition span.h:102
const T & operator[](size_t idx) const noexcept
Definition span.h:113
span & operator=(const span &) noexcept=default
std::size_t len
Definition span.h:117
constexpr span(std::nullptr_t) noexcept
Definition span.h:77
constexpr span(const span &) noexcept=default
const_pointer const_iterator
Definition span.h:74
T * ptr
Definition span.h:116
T * pointer
Definition span.h:69
constexpr span() noexcept
Definition span.h:76
constexpr bool empty() const noexcept
Definition span.h:107
constexpr iterator begin() const noexcept
Definition span.h:101
constexpr pointer data() const noexcept
Definition span.h:108
T & reference
Definition span.h:71
std::size_t size_type
Definition span.h:67
#define const
Definition ipfrdr.c:80
TODO: (mj-xmr) This will be reduced in an another PR.
Definition byte_slice.h:40
span< std::uint8_t > as_mut_byte_span(T &src) noexcept
Definition span.h:172
span< const std::uint8_t > to_byte_span(const span< const T > src) noexcept
Definition span.h:138
span< const T > strspan(const U &s) noexcept
make a span from a std::string
Definition span.h:183
constexpr span< const typename T::value_type > to_span(const T &src)
Definition span.h:122
constexpr span< std::uint8_t > to_mut_byte_span(T &src)
Definition span.h:149
span< const std::uint8_t > as_byte_span(const T &src) noexcept
Definition span.h:161
constexpr span< typename T::value_type > to_mut_span(T &src)
Definition span.h:130
#define T(x)