Electroneum
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 
38 namespace 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&;
75  using iterator = pointer;
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 }
const uint32_t T[512]
span< const std::uint8_t > as_byte_span(const T &src) noexcept
Definition: span.h:153
span & operator=(const span &) noexcept=default
::std::string string
Definition: gtest-port.h:1097
constexpr const_iterator cbegin() const noexcept
Definition: span.h:104
span< const T > strspan(const std::string &s) noexcept
make a span from a std::string
Definition: span.h:171
const const std::uint8_t * const_pointer
Definition: span.h:72
span< std::uint8_t > as_mut_byte_span(T &src) noexcept
Definition: span.h:162
Non-owning sequence of data. Does not deep copy.
Definition: span.h:56
unsigned char uint8_t
Definition: stdint.h:124
const std::uint8_t value_type
Definition: span.h:68
constexpr bool has_padding() noexcept
Definition: span.h:138
constexpr std::size_t size() const noexcept
Definition: span.h:111
constexpr span< typename T::value_type > to_mut_span(T &src)
Definition: span.h:131
mdb_size_t count(MDB_cursor *cur)
constexpr const_iterator cend() const noexcept
Definition: span.h:107
const_pointer const_iterator
Definition: span.h:76
const T & operator[](size_t idx) const
Definition: span.h:114
constexpr iterator end() const noexcept
Definition: span.h:106
constexpr span(std::nullptr_t) noexcept
Definition: span.h:79
std::size_t remove_prefix(std::size_t amount) noexcept
Definition: span.h:95
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 span< const typename T::value_type > to_span(const T &src)
Definition: span.h:123
const const std::uint8_t & const_reference
Definition: span.h:74
constexpr iterator begin() const noexcept
Definition: span.h:103
constexpr std::size_t size_bytes() const noexcept
Definition: span.h:112
constexpr span() noexcept
Definition: span.h:78
constexpr bool empty() const noexcept
Definition: span.h:109
const std::uint8_t * pointer
Definition: span.h:71
constexpr span(T(&src)[N]) noexcept
Conversion from C-array. Prevents common bugs with sizeof + arrays.
Definition: span.h:88
std::ptrdiff_t difference_type
Definition: span.h:70
span< const std::uint8_t > to_byte_span(const span< const T > src) noexcept
Definition: span.h:145
constexpr pointer data() const noexcept
Definition: span.h:110