Skip to content

Commit df1375b

Browse files
committed
moveonly: add mp/type-number.h
1 parent 6d831eb commit df1375b

File tree

4 files changed

+89
-76
lines changed

4 files changed

+89
-76
lines changed

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ set(MP_PUBLIC_HEADERS
4747
include/mp/proxy.h
4848
include/mp/type-context.h
4949
include/mp/type-map.h
50+
include/mp/type-number.h
5051
include/mp/type-optional.h
5152
include/mp/type-pair.h
5253
include/mp/type-pointer.h

include/mp/proxy-types.h

Lines changed: 0 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -141,45 +141,6 @@ struct ReadDestUpdate
141141
Value& m_value;
142142
};
143143

144-
template <typename LocalType, typename Input, typename ReadDest>
145-
decltype(auto) CustomReadField(TypeList<LocalType>,
146-
Priority<1>,
147-
InvokeContext& invoke_context,
148-
Input&& input,
149-
ReadDest&& read_dest,
150-
typename std::enable_if<std::is_enum<LocalType>::value>::type* enable = 0)
151-
{
152-
return read_dest.construct(static_cast<LocalType>(input.get()));
153-
}
154-
155-
template <typename LocalType, typename Input, typename ReadDest>
156-
decltype(auto) CustomReadField(TypeList<LocalType>,
157-
Priority<1>,
158-
InvokeContext& invoke_context,
159-
Input&& input,
160-
ReadDest&& read_dest,
161-
typename std::enable_if<std::is_integral<LocalType>::value>::type* enable = nullptr)
162-
{
163-
auto value = input.get();
164-
if (value < std::numeric_limits<LocalType>::min() || value > std::numeric_limits<LocalType>::max()) {
165-
throw std::range_error("out of bound int received");
166-
}
167-
return read_dest.construct(static_cast<LocalType>(value));
168-
}
169-
170-
template <typename LocalType, typename Input, typename ReadDest>
171-
decltype(auto) CustomReadField(TypeList<LocalType>,
172-
Priority<1>,
173-
InvokeContext& invoke_context,
174-
Input&& input,
175-
ReadDest&& read_dest,
176-
typename std::enable_if<std::is_floating_point<LocalType>::value>::type* enable = 0)
177-
{
178-
auto value = input.get();
179-
static_assert(std::is_same<LocalType, decltype(value)>::value, "floating point type mismatch");
180-
return read_dest.construct(value);
181-
}
182-
183144
template <typename Input, typename ReadDest>
184145
decltype(auto) CustomReadField(TypeList<std::string>,
185146
Priority<1>,
@@ -516,43 +477,6 @@ ::capnp::Void BuildPrimitive(InvokeContext& invoke_context, Value&&, TypeList<::
516477
{
517478
return {};
518479
}
519-
520-
template <typename LocalType, typename Value>
521-
LocalType BuildPrimitive(InvokeContext& invoke_context,
522-
const Value& value,
523-
TypeList<LocalType>,
524-
typename std::enable_if<std::is_enum<Value>::value>::type* enable = nullptr)
525-
{
526-
using E = std::make_unsigned_t<std::underlying_type_t<Value>>;
527-
using T = std::make_unsigned_t<LocalType>;
528-
static_assert(std::numeric_limits<T>::max() >= std::numeric_limits<E>::max(), "mismatched integral/enum types");
529-
return static_cast<LocalType>(value);
530-
}
531-
532-
template <typename LocalType, typename Value>
533-
LocalType BuildPrimitive(InvokeContext& invoke_context,
534-
const Value& value,
535-
TypeList<LocalType>,
536-
typename std::enable_if<std::is_integral<Value>::value, int>::type* enable = nullptr)
537-
{
538-
static_assert(
539-
std::numeric_limits<LocalType>::lowest() <= std::numeric_limits<Value>::lowest(), "mismatched integral types");
540-
static_assert(
541-
std::numeric_limits<LocalType>::max() >= std::numeric_limits<Value>::max(), "mismatched integral types");
542-
return value;
543-
}
544-
545-
template <typename LocalType, typename Value>
546-
LocalType BuildPrimitive(InvokeContext& invoke_context,
547-
const Value& value,
548-
TypeList<LocalType>,
549-
typename std::enable_if<std::is_floating_point<Value>::value>::type* enable = nullptr)
550-
{
551-
static_assert(std::is_same<Value, LocalType>::value,
552-
"mismatched floating point types. please fix message.capnp type declaration to match wrapped interface");
553-
return value;
554-
}
555-
556480
template <typename Output>
557481
void CustomBuildField(TypeList<std::exception>,
558482
Priority<1>,

include/mp/type-number.h

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
// Copyright (c) 2025 The Bitcoin Core developers
2+
// Distributed under the MIT software license, see the accompanying
3+
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4+
5+
#ifndef MP_PROXY_TYPE_NUMBER_H
6+
#define MP_PROXY_TYPE_NUMBER_H
7+
8+
#include <mp/util.h>
9+
10+
namespace mp {
11+
template <typename LocalType, typename Value>
12+
LocalType BuildPrimitive(InvokeContext& invoke_context,
13+
const Value& value,
14+
TypeList<LocalType>,
15+
typename std::enable_if<std::is_enum<Value>::value>::type* enable = nullptr)
16+
{
17+
using E = std::make_unsigned_t<std::underlying_type_t<Value>>;
18+
using T = std::make_unsigned_t<LocalType>;
19+
static_assert(std::numeric_limits<T>::max() >= std::numeric_limits<E>::max(), "mismatched integral/enum types");
20+
return static_cast<LocalType>(value);
21+
}
22+
23+
template <typename LocalType, typename Value>
24+
LocalType BuildPrimitive(InvokeContext& invoke_context,
25+
const Value& value,
26+
TypeList<LocalType>,
27+
typename std::enable_if<std::is_integral<Value>::value, int>::type* enable = nullptr)
28+
{
29+
static_assert(
30+
std::numeric_limits<LocalType>::lowest() <= std::numeric_limits<Value>::lowest(), "mismatched integral types");
31+
static_assert(
32+
std::numeric_limits<LocalType>::max() >= std::numeric_limits<Value>::max(), "mismatched integral types");
33+
return value;
34+
}
35+
36+
template <typename LocalType, typename Value>
37+
LocalType BuildPrimitive(InvokeContext& invoke_context,
38+
const Value& value,
39+
TypeList<LocalType>,
40+
typename std::enable_if<std::is_floating_point<Value>::value>::type* enable = nullptr)
41+
{
42+
static_assert(std::is_same<Value, LocalType>::value,
43+
"mismatched floating point types. please fix message.capnp type declaration to match wrapped interface");
44+
return value;
45+
}
46+
47+
template <typename LocalType, typename Input, typename ReadDest>
48+
decltype(auto) CustomReadField(TypeList<LocalType>,
49+
Priority<1>,
50+
InvokeContext& invoke_context,
51+
Input&& input,
52+
ReadDest&& read_dest,
53+
typename std::enable_if<std::is_enum<LocalType>::value>::type* enable = 0)
54+
{
55+
return read_dest.construct(static_cast<LocalType>(input.get()));
56+
}
57+
58+
template <typename LocalType, typename Input, typename ReadDest>
59+
decltype(auto) CustomReadField(TypeList<LocalType>,
60+
Priority<1>,
61+
InvokeContext& invoke_context,
62+
Input&& input,
63+
ReadDest&& read_dest,
64+
typename std::enable_if<std::is_integral<LocalType>::value>::type* enable = nullptr)
65+
{
66+
auto value = input.get();
67+
if (value < std::numeric_limits<LocalType>::min() || value > std::numeric_limits<LocalType>::max()) {
68+
throw std::range_error("out of bound int received");
69+
}
70+
return read_dest.construct(static_cast<LocalType>(value));
71+
}
72+
73+
template <typename LocalType, typename Input, typename ReadDest>
74+
decltype(auto) CustomReadField(TypeList<LocalType>,
75+
Priority<1>,
76+
InvokeContext& invoke_context,
77+
Input&& input,
78+
ReadDest&& read_dest,
79+
typename std::enable_if<std::is_floating_point<LocalType>::value>::type* enable = 0)
80+
{
81+
auto value = input.get();
82+
static_assert(std::is_same<LocalType, decltype(value)>::value, "floating point type mismatch");
83+
return read_dest.construct(value);
84+
}
85+
} // namespace mp
86+
87+
#endif // MP_PROXY_TYPE_NUMBER_H

test/mp/test/foo-types.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include <mp/proxy-types.h>
99
#include <mp/type-context.h>
1010
#include <mp/type-map.h>
11+
#include <mp/type-number.h>
1112
#include <mp/type-set.h>
1213
#include <mp/type-vector.h>
1314

0 commit comments

Comments
 (0)