From 9e6af218e3023b48fbbfcb9454099a6c0a0592dc Mon Sep 17 00:00:00 2001 From: Davide Beatrici Date: Tue, 27 Sep 2022 04:44:45 +0200 Subject: [PATCH] Use GSL's "span" implementation instead of Boost's Boost's "span.hpp" was added in b4a9a100a164c1f2259d3193f5238b4c67db8ac5. The idea was to make sure it would be available (introduced in Boost 1.78). Now that ~9 months have passed, boost::span should be widespread in repositories. Unfortunately Debian (and in turn Ubuntu) is stuck with 1.74 for some reason. Thus, let's just use GSL, which is intended to be used also as a submodule. Co-authored-by: Robert Adam --- .gitmodules | 3 + 3rdparty/gsl | 1 + CMakeLists.txt | 2 + CMakePresets.json | 4 + include/boost/core/span.hpp | 407 ----------------------------- include/mumble/Cert.hpp | 4 +- include/mumble/IP.hpp | 6 +- include/mumble/Types.hpp | 6 +- src/CMakeLists.txt | 9 + src/Cert.cpp | 4 +- src/CryptOCB2.cpp | 14 +- src/CryptOCB2.hpp | 6 +- src/IP.cpp | 2 +- src/Monitor.cpp | 4 +- src/Monitor.hpp | 4 +- src/Pack.cpp | 2 +- src/Peer.cpp | 5 +- src/example/ExampleServer/Node.cpp | 2 +- src/example/ExampleServer/User.cpp | 5 +- src/test/TestCrypt/main.cpp | 2 + src/test/TestHash/main.cpp | 4 +- vcpkg.json | 1 + 22 files changed, 57 insertions(+), 440 deletions(-) create mode 160000 3rdparty/gsl delete mode 100644 include/boost/core/span.hpp diff --git a/.gitmodules b/.gitmodules index 2736d91..24995ea 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ +[submodule "3rdparty/gsl"] + path = 3rdparty/gsl + url = https://github.com/microsoft/GSL.git [submodule "3rdparty/quickpool"] path = 3rdparty/quickpool url = https://github.com/tnagler/quickpool.git diff --git a/3rdparty/gsl b/3rdparty/gsl new file mode 160000 index 0000000..10df83d --- /dev/null +++ b/3rdparty/gsl @@ -0,0 +1 @@ +Subproject commit 10df83d292bf5bbdc487e57dc8c2dc8c7a01f4d1 diff --git a/CMakeLists.txt b/CMakeLists.txt index 51fb6b0..92f4907 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,6 +18,8 @@ if(build-tests) include(CTest) endif() +option(bundled-gsl "Use the bundled GSL version instead of looking for one on the system" ON) + set(CMAKE_CXX_EXTENSIONS OFF) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) diff --git a/CMakePresets.json b/CMakePresets.json index f2e9fe6..eeb04a9 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -21,6 +21,10 @@ "CMAKE_TOOLCHAIN_FILE": { "type": "FILEPATH", "value": "$env{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake" + }, + "bundled-gsl": { + "type": "BOOL", + "value": "OFF" } } } diff --git a/include/boost/core/span.hpp b/include/boost/core/span.hpp deleted file mode 100644 index 54dafdb..0000000 --- a/include/boost/core/span.hpp +++ /dev/null @@ -1,407 +0,0 @@ -/* -Copyright 2019 Glen Joseph Fernandes -(glenjofe@gmail.com) - -Distributed under the Boost Software License, Version 1.0. -(http://www.boost.org/LICENSE_1_0.txt) -*/ -#ifndef BOOST_CORE_SPAN_HPP -#define BOOST_CORE_SPAN_HPP - -#include -#include -#include -#include - -namespace boost { - -constexpr std::size_t dynamic_extent = static_cast(-1); - -template -class span; - -namespace detail { - -template -struct span_convertible { - static constexpr bool value = std::is_convertible::value; -}; - -template -struct span_capacity { - static constexpr bool value = E == boost::dynamic_extent || E == N; -}; - -template -struct span_compatible { - static constexpr bool value = span_capacity::value && - span_convertible::value; -}; - -template -struct span_uncvref { - typedef typename std::remove_cv::type>::type type; -}; - -template -struct span_is_span { - static constexpr bool value = false; -}; - -template -struct span_is_span > { - static constexpr bool value = true; -}; - -template -struct span_is_array { - static constexpr bool value = false; -}; - -template -struct span_is_array > { - static constexpr bool value = true; -}; - -template -struct span_data { }; - -template -struct span_data().data())>::value>::type> { - typedef typename std::remove_pointer().data())>::type type; -}; - -template -struct span_has_data { - static constexpr bool value = false; -}; - -template -struct span_has_data::type, T>::value>::type> { - static constexpr bool value = true; -}; - -template -struct span_has_size { - static constexpr bool value = false; -}; - -template -struct span_has_size().size()), - std::size_t>::value>::type> { - static constexpr bool value = true; -}; - -template -struct span_is_range { - static constexpr bool value = (std::is_const::value || - std::is_lvalue_reference::value) && - !span_is_span::type>::value && - !span_is_array::type>::value && - !std::is_array::type>::value && - span_has_data::value && - span_has_size::value; -}; - -template -struct span_implicit { - static constexpr bool value = E == boost::dynamic_extent || - N != boost::dynamic_extent; -}; - -template -struct span_copyable { - static constexpr bool value = (N == boost::dynamic_extent || - span_capacity::value) && span_convertible::value; -}; - -template -struct span_sub { - static constexpr std::size_t value = E == boost::dynamic_extent ? - boost::dynamic_extent : E - O; -}; - -template -struct span_store { - constexpr span_store(T* p_, std::size_t) noexcept - : p(p_) { } - static constexpr std::size_t n = E; - T* p; -}; - -template -struct span_store { - constexpr span_store(T* p_, std::size_t n_) noexcept - : p(p_) - , n(n_) { } - T* p; - std::size_t n; -}; - -template -struct span_bytes { - static constexpr std::size_t value = sizeof(T) * E; -}; - -template -struct span_bytes { - static constexpr std::size_t value = boost::dynamic_extent; -}; - -} /* detail */ - -template -class span { -public: - typedef T element_type; - typedef typename std::remove_cv::type value_type; - typedef std::size_t size_type; - typedef std::ptrdiff_t difference_type; - typedef T* pointer; - typedef const T* const_pointer; - typedef T& reference; - typedef const T& const_reference; - typedef T* iterator; - typedef const T* const_iterator; - typedef std::reverse_iterator reverse_iterator; - typedef std::reverse_iterator const_reverse_iterator; - - static constexpr std::size_t extent = E; - - template::type = 0> - constexpr span() noexcept - : s_(0, 0) { } - - template::value, int>::type = 0> - constexpr span(I* f, size_type c) - : s_(f, c) { } - - template::value, int>::type = 0> - explicit constexpr span(I* f, size_type c) - : s_(f, c) { } - - template::value, int>::type = 0> - constexpr span(I* f, L* l) - : s_(f, l - f) { } - - template::value, int>::type = 0> - explicit constexpr span(I* f, L* l) - : s_(f, l - f) { } - - template::value, - int>::type = 0> - constexpr span(typename std::enable_if::type (&a)[N]) noexcept - : s_(a, N) { } - - template::value, - int>::type = 0> - constexpr span(std::array& a) noexcept - : s_(a.data(), N) { } - - template::value, int>::type = 0> - constexpr span(const std::array& a) noexcept - : s_(a.data(), N) { } - - template::value, int>::type = 0> - constexpr span(R&& r) noexcept(noexcept(r.data()) && noexcept(r.size())) - : s_(r.data(), r.size()) { } - - template::value, int>::type = 0> - explicit constexpr span(R&& r) noexcept(noexcept(r.data()) && - noexcept(r.size())) - : s_(r.data(), r.size()) { } - - template::value && - detail::span_copyable::value, int>::type = 0> - constexpr span(const span& s) noexcept - : s_(s.data(), s.size()) { } - - template::value && - detail::span_copyable::value, int>::type = 0> - explicit constexpr span(const span& s) noexcept - : s_(s.data(), s.size()) { } - - template - constexpr span first() const { - static_assert(C <= E, "Count <= Extent"); - return span(s_.p, C); - } - - template - constexpr span last() const { - static_assert(C <= E, "Count <= Extent"); - return span(s_.p + (s_.n - C), C); - } - - template - constexpr typename std::enable_if::value> >::type subspan() const { - static_assert(O <= E, "Offset <= Extent"); - return span::value>(s_.p + O, s_.n - O); - } - - template - constexpr typename std::enable_if >::type subspan() const { - static_assert(O <= E && C <= E - O, - "Offset <= Extent && Count <= Extent - Offset"); - return span(s_.p + O, C); - } - - constexpr span first(size_type c) const { - return span(s_.p, c); - } - - constexpr span last(size_type c) const { - return span(s_.p + (s_.n - c), c); - } - - constexpr span subspan(size_type o, - size_type c = dynamic_extent) const { - return span(s_.p + o, - c == dynamic_extent ? s_.n - o : c); - } - - constexpr size_type size() const noexcept { - return s_.n; - } - - constexpr size_type size_bytes() const noexcept { - return s_.n * sizeof(T); - } - - constexpr bool empty() const noexcept { - return s_.n == 0; - } - - constexpr reference operator[](size_type i) const { - return s_.p[i]; - } - - constexpr reference front() const { - return *s_.p; - } - - constexpr reference back() const { - return s_.p[s_.n - 1]; - } - - constexpr pointer data() const noexcept { - return s_.p; - } - - constexpr iterator begin() const noexcept { - return s_.p; - } - - constexpr iterator end() const noexcept { - return s_.p + s_.n; - } - - constexpr reverse_iterator rbegin() const noexcept { - return reverse_iterator(s_.p + s_.n); - } - - constexpr reverse_iterator rend() const noexcept { - return reverse_iterator(s_.p); - } - - constexpr const_iterator cbegin() const noexcept { - return s_.p; - } - - constexpr const_iterator cend() const noexcept { - return s_.p + s_.n; - } - - constexpr const_reverse_iterator crbegin() const noexcept { - return const_reverse_iterator(s_.p + s_.n); - } - - constexpr const_reverse_iterator crend() const noexcept { - return const_reverse_iterator(s_.p); - } - - friend constexpr iterator begin(span s) noexcept { - return s.begin(); - } - - friend constexpr iterator end(span s) noexcept { - return s.end(); - } - -private: - detail::span_store s_; -}; - -template -constexpr std::size_t span::extent; - -#ifdef __cpp_deduction_guides -template -span(I*, L) -> span; - -template -span(T(&)[N]) -> span; - -template -span(std::array&) -> span; - -template -span(const std::array&) -> span; - -template -span(R&&) -> span::type>; - -template -span(span) -> span; -#endif - -#ifdef __cpp_lib_byte -template -inline span::value> -as_bytes(span s) noexcept -{ - return span::value>(reinterpret_cast(s.data()), - s.size_bytes()); -} - -template -inline typename std::enable_if::value, - span::value> >::type -as_writable_bytes(span s) noexcept -{ - return span::value>(reinterpret_cast(s.data()), s.size_bytes()); -} -#endif - -} /* boost */ - -#endif diff --git a/include/mumble/Cert.hpp b/include/mumble/Cert.hpp index 75f2fa8..9139c1c 100644 --- a/include/mumble/Cert.hpp +++ b/include/mumble/Cert.hpp @@ -22,8 +22,8 @@ class MUMBLE_EXPORT Cert { using Attributes = std::map< std::string_view, std::string >; using Chain = std::vector< Cert >; using Der = std::vector< std::byte >; - using DerRef = boost::span< std::byte >; - using DerRefConst = boost::span< const std::byte >; + using DerRef = gsl::span< std::byte >; + using DerRefConst = gsl::span< const std::byte >; Cert(); Cert(const Cert &cert); diff --git a/include/mumble/IP.hpp b/include/mumble/IP.hpp index 3aec530..239c884 100644 --- a/include/mumble/IP.hpp +++ b/include/mumble/IP.hpp @@ -13,7 +13,7 @@ #include #include -#include +#include struct sockaddr_in6; @@ -27,8 +27,8 @@ class MUMBLE_EXPORT IP { using V6 = std::array< uint8_t, v6Size >; using V4 = std::array< uint8_t, v4Size >; - using Ref = boost::span< uint8_t >; - using RefConst = boost::span< const uint8_t >; + using Ref = gsl::span< uint8_t >; + using RefConst = gsl::span< const uint8_t >; IP(); IP(const IP &ip); diff --git a/include/mumble/Types.hpp b/include/mumble/Types.hpp index 9c12019..0655b42 100644 --- a/include/mumble/Types.hpp +++ b/include/mumble/Types.hpp @@ -16,7 +16,7 @@ namespace mumble {} #include #include -#include +#include namespace mumble { enum class Code : int8_t { @@ -110,8 +110,8 @@ static constexpr uint32_t infinite32 = UINT32_MAX; static constexpr uint64_t infinite64 = UINT64_MAX; using Buf = std::vector< std::byte >; -using BufRef = boost::span< std::byte >; -using BufRefConst = boost::span< const std::byte >; +using BufRef = gsl::span< std::byte >; +using BufRefConst = gsl::span< const std::byte >; template< size_t size > using FixedBuf = std::array< std::byte, size >; diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index df25027..3e5914c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -9,6 +9,13 @@ find_package(Boost REQUIRED COMPONENTS thread ) + +if(NOT bundled-gsl) + find_package(Microsoft.GSL REQUIRED) +else() + add_subdirectory("${3RDPARTY_DIR}/gsl" "${CMAKE_CURRENT_BINARY_DIR}/gsl" EXCLUDE_FROM_ALL) +endif() + find_package(OpenSSL REQUIRED) find_package(Opus) @@ -126,6 +133,8 @@ target_link_libraries(mumble $ $<$:WS2_32> + PUBLIC + GSL ) if(build-examples) diff --git a/src/Cert.cpp b/src/Cert.cpp index ee22cd4..a60be54 100644 --- a/src/Cert.cpp +++ b/src/Cert.cpp @@ -13,7 +13,7 @@ #include #include -#include +#include #include #include @@ -191,7 +191,7 @@ P::P(X509 *x509) : m_x509(x509) { } P::P(const DerRefConst der) { - auto bytes = boost::as_bytes(der); + auto bytes = gsl::as_bytes(der); d2i_X509(&m_x509, reinterpret_cast< const unsigned char ** >(&bytes), static_cast< long >(bytes.size())); } diff --git a/src/CryptOCB2.cpp b/src/CryptOCB2.cpp index 2cfac58..021c756 100644 --- a/src/CryptOCB2.cpp +++ b/src/CryptOCB2.cpp @@ -10,7 +10,7 @@ #include #include -#include +#include #include #include @@ -126,7 +126,7 @@ size_t CryptOCB2::decrypt(BufRef out, BufRefConst in, const BufRefConst tag) { } KeyBlock delta; - const auto deltaBytes = boost::as_writable_bytes(KeyBlockRef(delta)); + const auto deltaBytes = gsl::as_writable_bytes(KeyBlockRef(delta)); if (!m_p->process(true, deltaBytes, m_p->m_nonce)) { return {}; @@ -135,7 +135,7 @@ size_t CryptOCB2::decrypt(BufRef out, BufRefConst in, const BufRefConst tag) { size_t written = 0; KeyBlock checksum{}, tmp; - const auto tmpBytes = boost::as_writable_bytes(KeyBlockRef(tmp)); + const auto tmpBytes = gsl::as_writable_bytes(KeyBlockRef(tmp)); while (in.size() > P::blockSize) { P::s2(delta); @@ -161,7 +161,7 @@ size_t CryptOCB2::decrypt(BufRef out, BufRefConst in, const BufRefConst tag) { P::xorBlock(tmp, tmp, delta); KeyBlock pad; - const auto padBytes = boost::as_writable_bytes(KeyBlockRef(pad)); + const auto padBytes = gsl::as_writable_bytes(KeyBlockRef(pad)); if (!m_p->process(true, padBytes, tmpBytes)) { return {}; @@ -215,14 +215,14 @@ size_t CryptOCB2::encrypt(BufRef out, BufRefConst in, const BufRef tag) { } KeyBlock delta; - if (!m_p->process(true, boost::as_writable_bytes(KeyBlockRef(delta)), m_p->m_nonce)) { + if (!m_p->process(true, gsl::as_writable_bytes(KeyBlockRef(delta)), m_p->m_nonce)) { return {}; } size_t written = 0; KeyBlock checksum{}, tmp; - const auto tmpBytes = boost::as_writable_bytes(KeyBlockRef(tmp)); + const auto tmpBytes = gsl::as_writable_bytes(KeyBlockRef(tmp)); while (in.size() > P::blockSize) { // Counter-cryptanalysis described in section 9 of https://eprint.iacr.org/2019/311 @@ -277,7 +277,7 @@ size_t CryptOCB2::encrypt(BufRef out, BufRefConst in, const BufRef tag) { P::xorBlock(tmp, tmp, delta); KeyBlock pad; - const auto padBytes = boost::as_writable_bytes(KeyBlockRef(pad)); + const auto padBytes = gsl::as_writable_bytes(KeyBlockRef(pad)); if (!m_p->process(true, padBytes, tmpBytes)) { return {}; diff --git a/src/CryptOCB2.hpp b/src/CryptOCB2.hpp index dd22700..08e0d24 100644 --- a/src/CryptOCB2.hpp +++ b/src/CryptOCB2.hpp @@ -14,7 +14,7 @@ #include #include -#include +#include #include @@ -35,8 +35,8 @@ class CryptOCB2::P { static constexpr uint8_t shiftBits = 31; #endif using KeyBlock = std::array< SubBlock, subBlocks >; - using KeyBlockRef = boost::span< SubBlock, subBlocks >; - using KeyBlockRefConst = boost::span< const SubBlock, subBlocks >; + using KeyBlockRef = gsl::span< SubBlock, subBlocks >; + using KeyBlockRefConst = gsl::span< const SubBlock, subBlocks >; static constexpr uint8_t blockSize = 128 / 8; static constexpr uint8_t keySize = 128 / 8; diff --git a/src/IP.cpp b/src/IP.cpp index 5e2852a..7b14860 100644 --- a/src/IP.cpp +++ b/src/IP.cpp @@ -9,7 +9,7 @@ #include #include -#include +#include #ifdef OS_WINDOWS # include diff --git a/src/Monitor.cpp b/src/Monitor.cpp index 88b9907..e3eaeca 100644 --- a/src/Monitor.cpp +++ b/src/Monitor.cpp @@ -157,7 +157,7 @@ uint32_t Monitor::wait(const EventsRef events, const uint32_t timeout) { } #if defined(HAVE_EPOLL) || defined(HAVE_WEPOLL) -# include +# include uint32_t Monitor::waitEpoll(const EventsRef events, const uint32_t timeout) { const int32_t ret = epoll_wait(m_handle, m_targets.data(), static_cast< int >(m_targets.size()), @@ -168,7 +168,7 @@ uint32_t Monitor::waitEpoll(const EventsRef events, const uint32_t timeout) { uint32_t num = 0; - for (const auto &target : boost::span< Target >(m_targets.data(), ret)) { + for (const auto &target : gsl::span< Target >(m_targets.data(), ret)) { if (num >= events.size()) { break; } diff --git a/src/Monitor.hpp b/src/Monitor.hpp index 5fa3e48..28e1480 100644 --- a/src/Monitor.hpp +++ b/src/Monitor.hpp @@ -14,7 +14,7 @@ #include #include -#include +#include #if defined(HAVE_EPOLL) || defined(HAVE_WEPOLL) struct epoll_event; @@ -42,7 +42,7 @@ class Monitor { Event(const int32_t fd) : fd(fd), state(None) {} }; - using EventsRef = boost::span< Event >; + using EventsRef = gsl::span< Event >; Monitor(); ~Monitor(); diff --git a/src/Pack.cpp b/src/Pack.cpp index d8d9d15..94aa4d2 100644 --- a/src/Pack.cpp +++ b/src/Pack.cpp @@ -21,7 +21,7 @@ #include #include -#include +#include #include #include diff --git a/src/Peer.cpp b/src/Peer.cpp index 0a8f266..55bc97e 100644 --- a/src/Peer.cpp +++ b/src/Peer.cpp @@ -22,9 +22,10 @@ #include #include -#include #include +#include + #ifndef MUMBLE_COMPILER_MSVC # include #else @@ -240,7 +241,7 @@ void P::TCP::threadFunc(const uint32_t threads) { uint32_t num = 0; while (!m_halt) { - boost::span< Event > ref(events.data(), num); + gsl::span< Event > ref(events.data(), num); pool->parallel_for_each(ref, [this](Event &event) { if (m_socket && event.fd == m_socket->fd()) { if (event.state & Event::Error) { diff --git a/src/example/ExampleServer/Node.cpp b/src/example/ExampleServer/Node.cpp index f181438..24d80f2 100644 --- a/src/example/ExampleServer/Node.cpp +++ b/src/example/ExampleServer/Node.cpp @@ -399,7 +399,7 @@ bool Node::startUDP() { case Type::Audio: break; case Type::Ping: { - std::copy(packet.cbegin(), packet.cend(), pack.data().begin()); + std::copy(packet.begin(), packet.end(), pack.data().begin()); Message::Ping ping; if (!pack(ping)) { diff --git a/src/example/ExampleServer/User.cpp b/src/example/ExampleServer/User.cpp index 48b6f04..80d29e5 100644 --- a/src/example/ExampleServer/User.cpp +++ b/src/example/ExampleServer/User.cpp @@ -13,7 +13,8 @@ #include #include -#include +#include +#include using namespace mumble; @@ -83,7 +84,7 @@ size_t User::decrypt(const BufRef out, const BufRefConst in) { const auto encrypted = in.subspan(4); const auto prevNonce = m_decryptNonce; - boost::span< uint8_t > nonce(reinterpret_cast< uint8_t * >(m_decryptNonce.data()), m_decryptNonce.size()); + gsl::span< uint8_t > nonce(reinterpret_cast< uint8_t * >(m_decryptNonce.data()), m_decryptNonce.size()); bool restore = false; diff --git a/src/test/TestCrypt/main.cpp b/src/test/TestCrypt/main.cpp index cb5913b..8c45323 100644 --- a/src/test/TestCrypt/main.cpp +++ b/src/test/TestCrypt/main.cpp @@ -17,6 +17,8 @@ #include +#include + static constexpr size_t iterations = 100000; static constexpr size_t minBufSize = 1; diff --git a/src/test/TestHash/main.cpp b/src/test/TestHash/main.cpp index 65e3570..bf51d44 100644 --- a/src/test/TestHash/main.cpp +++ b/src/test/TestHash/main.cpp @@ -18,10 +18,10 @@ #include #include -#include - #include +#include + static constexpr size_t iterations = 100000; using namespace mumble; diff --git a/vcpkg.json b/vcpkg.json index 482977f..d01e152 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -4,6 +4,7 @@ "version-string": "0.1.0", "dependencies": [ "boost-thread", + "ms-gsl", "openssl", "opus", "protobuf"