6
6
#ifndef BITCOIN_SERIALIZE_H
7
7
#define BITCOIN_SERIALIZE_H
8
8
9
- #if defined(HAVE_CONFIG_H)
10
- #include < config/bitcoin-config.h>
11
- #endif
12
-
13
9
#include < attributes.h>
14
10
#include < compat/assumptions.h> // IWYU pragma: keep
15
11
#include < compat/endian.h>
16
12
#include < prevector.h>
17
13
#include < span.h>
18
14
19
15
#include < algorithm>
16
+ #include < concepts>
20
17
#include < cstdint>
21
18
#include < cstring>
22
19
#include < ios>
@@ -263,9 +260,14 @@ const Out& AsBase(const In& x)
263
260
// i.e. anything that supports .read(Span<std::byte>) and .write(Span<const std::byte>)
264
261
//
265
262
// 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
269
271
template <typename Stream> void Serialize (Stream& s, std::byte a) { ser_writedata8 (s, uint8_t (a)); }
270
272
template <typename Stream> inline void Serialize (Stream& s, int8_t a ) { ser_writedata8 (s, a); }
271
273
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
279
281
template <typename Stream, BasicByte B, std::size_t N> void Serialize (Stream& s, const std::array<B, N>& a) { s.write (MakeByteSpan (a)); }
280
282
template <typename Stream, BasicByte B> void Serialize (Stream& s, Span<B> span) { s.write (AsBytes (span)); }
281
283
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
285
285
template <typename Stream> void Unserialize (Stream& s, std::byte& a) { a = std::byte{ser_readdata8 (s)}; }
286
286
template <typename Stream> inline void Unserialize (Stream& s, int8_t & a ) { a = ser_readdata8 (s); }
287
287
template <typename Stream> inline void Unserialize (Stream& s, uint8_t & a ) { a = ser_readdata8 (s); }
0 commit comments