aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPieter Wuille <pieter.wuille@gmail.com>2018-04-04 11:56:22 -0700
committerPieter Wuille <pieter.wuille@gmail.com>2018-04-05 08:20:37 -0700
commit833bc085835dd1bcd8c0fc2a25aa746b7d6fe012 (patch)
treee698a0cde4504510fa5d93bc4c6536dad6753750
parentbfaed1ab2ec7fb3a1a6a7ed0b84503c2ed461c67 (diff)
Add Slice: a (pointer, size) array view that acts like a container
-rw-r--r--src/Makefile.am1
-rw-r--r--src/span.h40
2 files changed, 41 insertions, 0 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 72e5cdb95d..1cb4f46340 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -312,6 +312,7 @@ libbitcoin_consensus_a_SOURCES = \
script/script_error.cpp \
script/script_error.h \
serialize.h \
+ span.h \
tinyformat.h \
uint256.cpp \
uint256.h \
diff --git a/src/span.h b/src/span.h
new file mode 100644
index 0000000000..707fc21918
--- /dev/null
+++ b/src/span.h
@@ -0,0 +1,40 @@
+// Copyright (c) 2018 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_SPAN_H
+#define BITCOIN_SPAN_H
+
+#include <type_traits>
+#include <cstddef>
+
+/** A Span is an object that can refer to a contiguous sequence of objects.
+ *
+ * It implements a subset of C++20's std::span.
+ */
+template<typename C>
+class Span
+{
+ C* m_data;
+ std::ptrdiff_t m_size;
+
+public:
+ constexpr Span() noexcept : m_data(nullptr), m_size(0) {}
+ constexpr Span(C* data, std::ptrdiff_t size) noexcept : m_data(data), m_size(size) {}
+
+ constexpr C* data() const noexcept { return m_data; }
+ constexpr std::ptrdiff_t size() const noexcept { return m_size; }
+};
+
+/** Create a span to a container exposing data() and size().
+ *
+ * This correctly deals with constness: the returned Span's element type will be
+ * whatever data() returns a pointer to. If either the passed container is const,
+ * or its element type is const, the resulting span will have a const element type.
+ *
+ * std::span will have a constructor that implements this functionality directly.
+ */
+template<typename V>
+constexpr Span<typename std::remove_pointer<decltype(std::declval<V>().data())>::type> MakeSpan(V& v) { return Span<typename std::remove_pointer<decltype(std::declval<V>().data())>::type>(v.data(), v.size()); }
+
+#endif