Skip to content

Commit 65cc1f1

Browse files
committed
Merge pull request monero-project#9287
59cddbb serialization: support passing extra args to fields in DSL (jeffro256) b2c59c4 common: add va_args.h (jeffro256)
2 parents 0db9e74 + 59cddbb commit 65cc1f1

File tree

2 files changed

+62
-15
lines changed

2 files changed

+62
-15
lines changed

src/common/va_args.h

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// Copyright (c) 2024, The Monero Project
2+
//
3+
// All rights reserved.
4+
//
5+
// Redistribution and use in source and binary forms, with or without modification, are
6+
// permitted provided that the following conditions are met:
7+
//
8+
// 1. Redistributions of source code must retain the above copyright notice, this list of
9+
// conditions and the following disclaimer.
10+
//
11+
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
12+
// of conditions and the following disclaimer in the documentation and/or other
13+
// materials provided with the distribution.
14+
//
15+
// 3. Neither the name of the copyright holder nor the names of its contributors may be
16+
// used to endorse or promote products derived from this software without specific
17+
// prior written permission.
18+
//
19+
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
20+
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21+
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
22+
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23+
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24+
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25+
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26+
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
27+
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28+
29+
#pragma once
30+
31+
// Check for __VA_OPT__ support
32+
// Apdated from cpplearner's StackOverflow answer: https://stackoverflow.com/a/48045656
33+
#define PP_THIRD_ARG(a,b,c,...) c
34+
#define VA_OPT_SUPPORTED_I(...) PP_THIRD_ARG(__VA_OPT__(,),true,false,)
35+
#define VA_OPT_SUPPORTED VA_OPT_SUPPORTED_I(?)
36+
37+
// VA_ARGS_COMMAPREFIX(): VA_ARGS_COMMAPREFIX(__VA_ARGS__) expands to __VA_ARGS__ with a comma in
38+
// front if more than one argument, else nothing.
39+
// If __VA_OPT__ supported, use that. Else, use GCC's ,## hack
40+
#if VA_OPT_SUPPORTED
41+
# define VA_ARGS_COMMAPREFIX(...) __VA_OPT__(,) __VA_ARGS__
42+
#else
43+
# define VA_ARGS_COMMAPREFIX(...) , ## __VA_ARGS__
44+
#endif
45+

src/serialization/serialization.h

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@
5050
#include <boost/type_traits/integral_constant.hpp>
5151
#include <boost/mpl/bool.hpp>
5252

53+
#include "common/va_args.h"
54+
5355
/*! \struct is_blob_type / is_blob_forced
5456
*
5557
* \brief descriptors for dispatching serialize: whether to take byte-wise copy/store to type
@@ -93,6 +95,15 @@ inline bool do_serialize(Archive &ar, bool &v)
9395
ar.serialize_blob(&v, sizeof(v));
9496
return true;
9597
}
98+
template <class Archive, class T, typename... Args>
99+
inline auto do_serialize(Archive &ar, T &v, Args&&... args)
100+
-> decltype(do_serialize_object(ar, v, args...), true)
101+
{
102+
ar.begin_object();
103+
const bool r = do_serialize_object(ar, v, args...);
104+
ar.end_object();
105+
return r && ar.good();
106+
}
96107

97108
/* the following add a trait to a set and define the serialization DSL*/
98109

@@ -180,18 +191,9 @@ inline bool do_serialize(Archive &ar, bool &v)
180191
* VARINT_FIELD_F(). Otherwise, this macro is similar to
181192
* BEGIN_SERIALIZE_OBJECT(), as you should list only field serializations.
182193
*/
183-
#define BEGIN_SERIALIZE_OBJECT_FN(stype) \
184-
template <bool W, template <bool> class Archive> \
185-
bool do_serialize_object(Archive<W> &ar, stype &v); \
186-
template <bool W, template <bool> class Archive> \
187-
bool do_serialize(Archive<W> &ar, stype &v) { \
188-
ar.begin_object(); \
189-
bool r = do_serialize_object(ar, v); \
190-
ar.end_object(); \
191-
return r; \
192-
} \
193-
template <bool W, template <bool> class Archive> \
194-
bool do_serialize_object(Archive<W> &ar, stype &v) { \
194+
#define BEGIN_SERIALIZE_OBJECT_FN(stype, ...) \
195+
template <bool W, template <bool> class Archive> \
196+
bool do_serialize_object(Archive<W> &ar, stype &v VA_ARGS_COMMAPREFIX(__VA_ARGS__)) {
195197

196198
/*! \macro PREPARE_CUSTOM_VECTOR_SERIALIZATION
197199
*/
@@ -209,10 +211,10 @@ inline bool do_serialize(Archive &ar, bool &v)
209211
*
210212
* \brief serializes a field \a f tagged \a t
211213
*/
212-
#define FIELD_N(t, f) \
214+
#define FIELD_N(t, f, ...) \
213215
do { \
214216
ar.tag(t); \
215-
bool r = do_serialize(ar, f); \
217+
bool r = do_serialize(ar, f VA_ARGS_COMMAPREFIX(__VA_ARGS__)); \
216218
if (!r || !ar.good()) return false; \
217219
} while(0);
218220

@@ -231,7 +233,7 @@ inline bool do_serialize(Archive &ar, bool &v)
231233
*
232234
* \brief tags the field with the variable name and then serializes it (for use in a free function)
233235
*/
234-
#define FIELD_F(f) FIELD_N(#f, v.f)
236+
#define FIELD_F(f, ...) FIELD_N(#f, v.f VA_ARGS_COMMAPREFIX(__VA_ARGS__))
235237

236238
/*! \macro FIELDS(f)
237239
*

0 commit comments

Comments
 (0)