Introduce UniValue::emplace_back() to construct values/entries in-place
emplace_back()
is introduced for both arrays and objects. Whether to
select the array version or the object version is determined by overload
resolution: the object version must be supplied with some combination of
a key-like thing and a value-like thing, whereas the array version only
accepts a value-like thing without key-like thing. Very paranoid
static_assert()s are in place to verify this.
To keep the code simple, you are not allowed to use multi-argument constructors for emplacing, except for the two-argument constructors of std::pair. Violation safely results in a compile error.
This MR also declares push_back()
overloads for objects (accepting an
std::pair
), but defines these as deleted as a backporting safety
precaution, which is explained in comments. emplace_back()
with a
single std::pair
argument can be used instead. Note that in practice,
push_back()
with std::pair
would be unlikely to be used anyway,
because in almost all cases you did not construct an std::pair
beforehand such that it makes more sense to construct the pair with
emplace_back()
.
Hence this MR conceptually defines both push_back()
and
emplace_back()
for both objects and arrays. Their behaviour is both
mutually consistent, as well as consistent with STL container behaviour
for pushing and emplacing. This is the main improvement over !685 (closed), and
solves the semantic concerns regarding !685 (closed).
For objects, there is no duplicate key check. This replaces the need for
the optional boolean argument of pushKV()
to disable the duplicate key
check. This boolean argument has now been removed - all call sites that
used it have been upgraded to emplace_back()
. The remainder of
pushKV()
has a comment marking it as deprecated as it is envisioned
that pushKV()
will be removed completely in the future (if not, we
should come up with a better name).
UniValue unit tests check the behaviour of emplace_back()
in all
scenarios. The duplicate key check or absence thereof is now also
checked.
Test plan: ninja check-univalue all bench_bitcoin check check-functional