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