Skip to content

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

Merge request reports