Skip to content

Commit bbfddb3

Browse files
committed
Merge bitcoin/bitcoin#29484: serialization: replace char-is-int8_t autoconf detection with c++20 concept
ad7584d serialization: replace char-is-int8_t autoconf detection with c++20 concept (Cory Fields) Pull request description: Doesn't depend on #29263, but it's really only relevant after that one's merged. This removes the only remaining autoconf macro in our serialization code (after #29263), so it can now be used trivially and safely out-of-tree. ~Our code does not currently contain any concepts, but couldn't find any discussion or docs about avoiding them. I guess we'll see if this blows up our c-i.~ Edit: Ignore this. ajtowns pointed out that we're already using a few concepts. This was introduced in #13580. Please check my logic on this as I'm unable to test on a SmartOS system. Even better would be a confirmation from someone who can build there. ACKs for top commit: Empact: Code review ACK bitcoin/bitcoin@ad7584d Tree-SHA512: 1faf65c900700efb1cf3092c607a2230321b393cb2f029fbfb94bc8e50df1dabd7a9e4b91e3b34f0d2f3471aaf18ee7e56d91869db5c5f4bae84da95443e1120
2 parents 7859f4e + ad7584d commit bbfddb3

File tree

2 files changed

+10
-18
lines changed

2 files changed

+10
-18
lines changed

configure.ac

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1171,14 +1171,6 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/types.h>
11711171
[ AC_MSG_RESULT([no])]
11721172
)
11731173

1174-
AC_MSG_CHECKING([for if type char equals int8_t])
1175-
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <stdint.h>
1176-
#include <type_traits>]],
1177-
[[ static_assert(std::is_same<int8_t, char>::value, ""); ]])],
1178-
[ AC_MSG_RESULT([yes]); AC_DEFINE([CHAR_EQUALS_INT8], [1], [Define this symbol if type char equals int8_t]) ],
1179-
[ AC_MSG_RESULT([no])]
1180-
)
1181-
11821174
AC_MSG_CHECKING([for fdatasync])
11831175
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <unistd.h>]],
11841176
[[ fdatasync(0); ]])],

src/serialize.h

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,14 @@
66
#ifndef BITCOIN_SERIALIZE_H
77
#define BITCOIN_SERIALIZE_H
88

9-
#if defined(HAVE_CONFIG_H)
10-
#include <config/bitcoin-config.h>
11-
#endif
12-
139
#include <attributes.h>
1410
#include <compat/assumptions.h> // IWYU pragma: keep
1511
#include <compat/endian.h>
1612
#include <prevector.h>
1713
#include <span.h>
1814

1915
#include <algorithm>
16+
#include <concepts>
2017
#include <cstdint>
2118
#include <cstring>
2219
#include <ios>
@@ -263,9 +260,14 @@ const Out& AsBase(const In& x)
263260
// i.e. anything that supports .read(Span<std::byte>) and .write(Span<const std::byte>)
264261
//
265262
// clang-format off
266-
#ifndef CHAR_EQUALS_INT8
267-
template <typename Stream> void Serialize(Stream&, char) = delete; // char serialization forbidden. Use uint8_t or int8_t
268-
#endif
263+
264+
// Typically int8_t and char are distinct types, but some systems may define int8_t
265+
// in terms of char. Forbid serialization of char in the typical case, but allow it if
266+
// it's the only way to describe an int8_t.
267+
template<class T>
268+
concept CharNotInt8 = std::same_as<T, char> && !std::same_as<T, int8_t>;
269+
270+
template <typename Stream, CharNotInt8 V> void Serialize(Stream&, V) = delete; // char serialization forbidden. Use uint8_t or int8_t
269271
template <typename Stream> void Serialize(Stream& s, std::byte a) { ser_writedata8(s, uint8_t(a)); }
270272
template<typename Stream> inline void Serialize(Stream& s, int8_t a ) { ser_writedata8(s, a); }
271273
template<typename Stream> inline void Serialize(Stream& s, uint8_t a ) { ser_writedata8(s, a); }
@@ -279,9 +281,7 @@ template <typename Stream, BasicByte B, int N> void Serialize(Stream& s, const B
279281
template <typename Stream, BasicByte B, std::size_t N> void Serialize(Stream& s, const std::array<B, N>& a) { s.write(MakeByteSpan(a)); }
280282
template <typename Stream, BasicByte B> void Serialize(Stream& s, Span<B> span) { s.write(AsBytes(span)); }
281283

282-
#ifndef CHAR_EQUALS_INT8
283-
template <typename Stream> void Unserialize(Stream&, char) = delete; // char serialization forbidden. Use uint8_t or int8_t
284-
#endif
284+
template <typename Stream, CharNotInt8 V> void Unserialize(Stream&, V) = delete; // char serialization forbidden. Use uint8_t or int8_t
285285
template <typename Stream> void Unserialize(Stream& s, std::byte& a) { a = std::byte{ser_readdata8(s)}; }
286286
template<typename Stream> inline void Unserialize(Stream& s, int8_t& a ) { a = ser_readdata8(s); }
287287
template<typename Stream> inline void Unserialize(Stream& s, uint8_t& a ) { a = ser_readdata8(s); }

0 commit comments

Comments
 (0)