Skip to content

Commit

Permalink
Switch to using C++17
Browse files Browse the repository at this point in the history
Summary
---

Partial backport from Core: bitcoin/bitcoin#18591
And also ABC: https://reviews.bitcoinabc.org/D8493

Note that I also backported the `span.h` fixes from Pieter Wiulle in the
core#18591 backport, but I did not like way that class looked. It had
some unsafe behavior and was using `std::ptrdiff_t` instead of
`std::size_t`, among other problems.  I went ahead and spruced it up to
be more idiomatic and less insane.

    Commit message from Fabien:

    Debian buster ships with gcc 7/8 which is all green according to:
    https://gcc.gnu.org/projects/cxx-status.html

Test Plan
---

1. Build eveyrthing with cmake. Be sure to `rm -fr` your build directory
   and do a full build, run tests `ninja all check-all`
2. Build everything with the deprecated build system, again, using a
   fresh build dir: `./autogen.sh && ./configure --deprecated-build-system ...`
3. Run gitian build to make sure they are sane too.
  • Loading branch information
cculianu committed Dec 9, 2020
1 parent ab8a6d5 commit 195296f
Show file tree
Hide file tree
Showing 14 changed files with 519 additions and 83 deletions.
455 changes: 419 additions & 36 deletions build-aux/m4/ax_cxx_compile_stdcxx.m4

Large diffs are not rendered by default.

6 changes: 4 additions & 2 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,10 @@ case $host in
lt_cv_deplibs_check_method="pass_all"
;;
esac
dnl Require C++14 compiler (no GNU extensions)
AX_CXX_COMPILE_STDCXX([14], [noext], [mandatory], [nodefault])

dnl Require C++17 compiler (no GNU extensions)
AX_CXX_COMPILE_STDCXX([17], [noext], [mandatory])

dnl Check if -latomic is required for <std::atomic>
CHECK_ATOMIC

Expand Down
5 changes: 3 additions & 2 deletions contrib/testgen/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@ else()
find_program_or_fail(CSPLIT_EXECUTABLE csplit)
endif()

# This project can take advantage of C++14.
set(CMAKE_CXX_STANDARD 14)
# This project must use C++17
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

add_executable(gen_asert_test_vectors
EXCLUDE_FROM_ALL
Expand Down
2 changes: 1 addition & 1 deletion doc/build-osx.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ If you want to run ZMQ tests with the test framework, you need the zmq python mo
Build Bitcoin Cash Node
------------------------

Before you start building, please make sure that your compiler supports C++14.
Before you start building, please make sure that your compiler supports C++17.

Clone the Bitcoin Cash Node source code and cd into `bitcoin-cash-node`

Expand Down
2 changes: 1 addition & 1 deletion doc/build-unix.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ See [dependencies.md](dependencies.md) or your OS specific guide in build-*.md.
If you wish to compile the dependencies from source yourself, please see
instructions in [depends](/depends/README.md).

Please make sure that your compiler supports C++14.
Please make sure that your compiler supports C++17.

Assuming you have all the necessary dependencies installed the commands below will
build the node, with the `bitcoin-qt` GUI-client as well.
Expand Down
2 changes: 1 addition & 1 deletion doc/build-windows.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ Other options which may work, but which have not been extensively tested are
* On Windows, using a native compiler tool chain such as
[Visual Studio](https://www.visualstudio.com).

In any case please make sure that the compiler supports C++14.
In any case please make sure that the compiler supports C++17.

**Note** These notes cover building binaries from source, for running Bitcoin
Cash Node natively under Windows. If you just want to run Bitcoin Cash Node,
Expand Down
4 changes: 2 additions & 2 deletions doc/dependencies.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ These dependencies are required:
| --- | --- | --- | --- | --- | --- |--- | --- |
| Berkeley DB | [5.3.28](http://www.oracle.com/technetwork/database/database-technologies/berkeleydb/downloads/index.html) | 5.3 | No | | | Wallet storage | Only needed when wallet enabled |
| Boost | [1.70.0](http://www.boost.org/users/download/) | 1.58.0 | No | | | Utility | Library for threading, data structures, etc
| Clang | | [3.4](http://llvm.org/releases/download.html) (C++14 support) | | | | | |
| Clang | | [5](http://llvm.org/releases/download.html) (C++17 support) | | | | | |
| CMake | | [3.13](https://cmake.org/download/) | | | | | |
| D-Bus | [1.10.18](https://cgit.freedesktop.org/dbus/dbus/tree/NEWS?h=dbus-1.10) | | No | Yes | | | |
| Expat | [2.2.5](https://libexpat.github.io/) | | No | Yes | | | |
| fontconfig | [2.12.6](https://www.freedesktop.org/software/fontconfig/release/) | | No | Yes | | | |
| FreeType | [2.7.1](http://download.savannah.gnu.org/releases/freetype) | | No | | | | |
| GCC | | [5.0](https://gcc.gnu.org/) (C++14 support) | | | | | |
| GCC | | [7.0](https://gcc.gnu.org/) (C++17 support) | | | | | |
| HarfBuzz-NG | | | | | | | |
| libevent | [2.1.8-stable](https://github.com/libevent/libevent/releases) | 2.0.22 | No | | | Networking | OS independent asynchronous networking |
| libjpeg | | | | | Yes | | |
Expand Down
4 changes: 3 additions & 1 deletion src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

project(bitcoind)

set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)


# Default visibility is hidden on all targets.
set(CMAKE_C_VISIBILITY_PRESET hidden)
Expand Down
13 changes: 13 additions & 0 deletions src/compat/assumptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,19 @@
#error "Bitcoin cannot be compiled without assertions."
#endif

// Assumption: We assume a C++17 (ISO/IEC 14882:2017) compiler (minimum
// requirement).
// Example(s): We may use use C++17 only constructs such as if constexpr,
// structured binding, std::is_same_v, etc.
// Note: MSVC does not report the expected __cplusplus value due to
// legacy reasons.
#if !defined(_MSC_VER)
// N4713 §19.8/p1 [cpp.predefined]/p1::
// "The name __cplusplus is defined to the value 201703L when compiling a C++
// translation unit."
static_assert(__cplusplus >= 201703L, "C++17 standard assumed");
#endif

// Assumption: We assume the floating-point types to fulfill the requirements of
// IEC 559 (IEEE 754) standard.
// Example(s): Floating-point division by zero in ConnectBlock,
Expand Down
4 changes: 2 additions & 2 deletions src/script/descriptor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -522,7 +522,7 @@ enum class ParseScriptContext {
* return true.
*/
bool Const(const std::string &str, Span<const char> &sp) {
if ((size_t)sp.size() >= str.size() &&
if (sp.size() >= str.size() &&
std::equal(str.begin(), str.end(), sp.begin())) {
sp = sp.subspan(str.size());
return true;
Expand All @@ -535,7 +535,7 @@ bool Const(const std::string &str, Span<const char> &sp) {
* argument(s).
*/
bool Func(const std::string &str, Span<const char> &sp) {
if ((size_t)sp.size() >= str.size() + 2 && sp[str.size()] == '(' &&
if (sp.size() >= str.size() + 2 && sp[str.size()] == '(' &&
sp[sp.size() - 1] == ')' &&
std::equal(str.begin(), str.end(), sp.begin())) {
sp = sp.subspan(str.size() + 1, sp.size() - str.size() - 2);
Expand Down
96 changes: 64 additions & 32 deletions src/span.h
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
// Copyright (c) 2018 The Bitcoin Core developers
// Copyright (c) 2020 The Bitcoin 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 <algorithm>
#include <cassert>
#include <cstddef>
#include <type_traits>

Expand All @@ -14,58 +16,89 @@
* It implements a subset of C++20's std::span.
*/
template <typename C> class Span {
C *m_data;
std::ptrdiff_t m_size;
C *m_data{};
std::size_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 Span(C *data, C *end) noexcept
: m_data(data), m_size(end - data) {}
constexpr Span() noexcept = default;
constexpr Span(C *data, std::size_t size) noexcept : m_data(data), m_size(size) {}
constexpr Span(C *data, C *end) noexcept : m_data(data), m_size(end >= data ? end - data : 0) {}

/** Implicit conversion of spans between compatible types.
*
* Specifically, if a pointer to an array of type O can be implicitly converted to a pointer to an array of type
* C, then permit implicit conversion of Span<O> to Span<C>. This matches the behavior of the corresponding
* C++20 std::span constructor.
*
* For example this means that a Span<T> can be converted into a Span<const T>.
*/
template <typename O, typename std::enable_if_t<std::is_convertible_v<O (*)[], C (*)[]>, int> = 0>
constexpr Span(const Span<O>& other) noexcept : m_data(other.m_data), m_size(other.m_size) {}

/** Default copy constructor. */
constexpr Span(const Span&) noexcept = default;

/** Default assignment operator. */
Span& operator=(const Span& other) noexcept = default;

constexpr C *data() const noexcept { return m_data; }
constexpr C *begin() const noexcept { return m_data; }
constexpr C *end() const noexcept { return m_data + m_size; }
constexpr std::ptrdiff_t size() const noexcept { return m_size; }
constexpr C &operator[](std::ptrdiff_t pos) const noexcept {
return m_data[pos];
}
constexpr std::size_t size() const noexcept { return m_size; }
constexpr bool empty() const noexcept { return size() == 0; }
constexpr C &operator[](std::size_t pos) const noexcept { return m_data[pos]; }
constexpr C &front() const noexcept { return *begin(); }
constexpr C &back() const noexcept { return *(end()-1); }

constexpr Span<C> subspan(std::ptrdiff_t offset) const noexcept {
return Span<C>(m_data + offset, m_size - offset);
constexpr Span<C> subspan(std::size_t offset) const noexcept {
return offset <= m_size? Span<C>(m_data + offset, m_size - offset) : Span<C>(end(), std::size_t{0});
}
constexpr Span<C> subspan(std::ptrdiff_t offset, std::ptrdiff_t count) const
noexcept {
return Span<C>(m_data + offset, count);
constexpr Span<C> subspan(std::size_t offset, std::size_t count) const noexcept {
return offset + count <= m_size ? Span<C>(m_data + offset, count) : Span<C>(end(), std::size_t{0});
}
constexpr Span<C> first(std::ptrdiff_t count) const noexcept {
return Span<C>(m_data, count);
constexpr Span<C> first(std::size_t count) const noexcept {
return count <= m_size ? Span<C>(m_data, count) : Span<C>(begin(), std::size_t{0});
}
constexpr Span<C> last(std::ptrdiff_t count) const noexcept {
return Span<C>(m_data + m_size - count, count);
constexpr Span<C> last(std::size_t count) const noexcept {
return count <= m_size ? Span<C>(m_data + m_size - count, count) : Span<C>(end(), std::size_t{0});
}

/** Pop the last element off, and return a reference to that element.
Span must not be empty(); span will decrease in size by 1, having its end() moved back by 1. */
constexpr C & pop_back() noexcept {
assert(!empty());
return m_data[--m_size];
}

/** Pop the last element off, and return a reference to that element.
Span must not be empty(); span will decrease in size by 1, having its begin() moved up by 1. */
constexpr C & pop_front() noexcept {
assert(!empty());
--m_size;
return *m_data++;
}

friend constexpr bool operator==(const Span &a, const Span &b) noexcept {
return a.size() == b.size() &&
std::equal(a.begin(), a.end(), b.begin());
return a.size() == b.size() && std::equal(a.begin(), a.end(), b.begin());
}
friend constexpr bool operator!=(const Span &a, const Span &b) noexcept {
return !(a == b);
}
friend constexpr bool operator<(const Span &a, const Span &b) noexcept {
return std::lexicographical_compare(a.begin(), a.end(), b.begin(),
b.end());
return std::lexicographical_compare(a.begin(), a.end(), b.begin(), b.end());
}
friend constexpr bool operator<=(const Span &a, const Span &b) noexcept {
return !(b < a);
}
friend constexpr bool operator>(const Span &a, const Span &b) noexcept {
return (b < a);
return b < a;
}
friend constexpr bool operator>=(const Span &a, const Span &b) noexcept {
return !(a < b);
}

/** Ensures the convertible-to constructor works */
template <typename O> friend class Span;
};

/** Create a span to a container exposing data() and size().
Expand All @@ -78,17 +111,16 @@ template <typename C> class Span {
* std::span will have a constructor that implements this functionality
* directly.
*/
template <typename A, int N> constexpr Span<A> MakeSpan(A (&a)[N]) {
template <typename A, std::size_t N>
constexpr Span<A> MakeSpan(A (&a)[N]) {
return Span<A>(a, N);
}

/** Make a span from any container that has .data() and .size() */
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());
constexpr auto MakeSpan(V &v) {
using ContainerValueType = typename std::remove_pointer_t<decltype(std::declval<V>().data())>;
return Span<ContainerValueType>(v.data(), v.size());
}

#endif // BITCOIN_SPAN_H
3 changes: 3 additions & 0 deletions src/univalue/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
cmake_minimum_required(VERSION 3.13)
project(univalue)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

option(UNIVALUE_BUILD_TESTS "Build univalue's unit tests" ON)

# TODO: Version info
Expand Down
2 changes: 1 addition & 1 deletion src/univalue/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,4 @@ Commands to build the library stand-alone:
make
```

BCHN UniValue requires C++14 or later.
BCHN UniValue requires C++17 or later.
4 changes: 2 additions & 2 deletions src/univalue/configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ AC_SUBST(LIBUNIVALUE_AGE)
LT_INIT
LT_LANG([C++])

dnl Require C++14 compiler (no GNU extensions)
AX_CXX_COMPILE_STDCXX([14], [noext], [mandatory], [nodefault])
dnl Require C++17 compiler (no GNU extensions)
AX_CXX_COMPILE_STDCXX([17], [noext], [mandatory])

case $host in
*mingw*)
Expand Down

0 comments on commit 195296f

Please sign in to comment.