Merge bitcoin/bitcoin#25714: univalue: Avoid std::string copies

fa09525751 univalue: string_view test (MacroFake)
1111c7e3f1 univalue: Avoid std::string copies (MacroFake)

Pull request description:

  This shouldn't matter too much, unless a really large string is pushed into a json struct, but I think it also clarifies the code.

ACKs for top commit:
  martinus:
    Code review ACK fa09525751
  aureleoules:
    reACK fa09525751
  ryanofsky:
    Code review ACK fa09525751

Tree-SHA512: 74c441912bd0b00cdb9ea7890121f71ae5d62a7594e7d29aa402c9e3f033710c5d3afb27a37c552e6513804b249aa37e375ce013a3db853a25d1fd7b6e6cd3a8
pull/26489/head
MacroFake 2 years ago
commit 59e00c7e03
No known key found for this signature in database
GPG Key ID: CE2B75697E69A548

@ -25,10 +25,7 @@ public:
}; };
UniValue() { typ = VNULL; } UniValue() { typ = VNULL; }
UniValue(UniValue::VType initialType, const std::string& initialStr = "") { UniValue(UniValue::VType type, std::string str = {}) : typ{type}, val{std::move(str)} {}
typ = initialType;
val = initialStr;
}
template <typename Ref, typename T = std::remove_cv_t<std::remove_reference_t<Ref>>, template <typename Ref, typename T = std::remove_cv_t<std::remove_reference_t<Ref>>,
std::enable_if_t<std::is_floating_point_v<T> || // setFloat std::enable_if_t<std::is_floating_point_v<T> || // setFloat
std::is_same_v<bool, T> || // setBool std::is_same_v<bool, T> || // setBool
@ -54,12 +51,12 @@ public:
void setNull(); void setNull();
void setBool(bool val); void setBool(bool val);
void setNumStr(const std::string& val); void setNumStr(std::string str);
void setInt(uint64_t val); void setInt(uint64_t val);
void setInt(int64_t val); void setInt(int64_t val);
void setInt(int val_) { return setInt(int64_t{val_}); } void setInt(int val_) { return setInt(int64_t{val_}); }
void setFloat(double val); void setFloat(double val);
void setStr(const std::string& val); void setStr(std::string str);
void setArray(); void setArray();
void setObject(); void setObject();

@ -44,15 +44,15 @@ static bool validNumStr(const std::string& s)
return (tt == JTOK_NUMBER); return (tt == JTOK_NUMBER);
} }
void UniValue::setNumStr(const std::string& val_) void UniValue::setNumStr(std::string str)
{ {
if (!validNumStr(val_)) { if (!validNumStr(str)) {
throw std::runtime_error{"The string '" + val_ + "' is not a valid JSON number"}; throw std::runtime_error{"The string '" + str + "' is not a valid JSON number"};
} }
clear(); clear();
typ = VNUM; typ = VNUM;
val = val_; val = std::move(str);
} }
void UniValue::setInt(uint64_t val_) void UniValue::setInt(uint64_t val_)
@ -82,11 +82,11 @@ void UniValue::setFloat(double val_)
return setNumStr(oss.str()); return setNumStr(oss.str());
} }
void UniValue::setStr(const std::string& val_) void UniValue::setStr(std::string str)
{ {
clear(); clear();
typ = VSTR; typ = VSTR;
val = val_; val = std::move(str);
} }
void UniValue::setArray() void UniValue::setArray()

@ -11,6 +11,7 @@
#include <memory> #include <memory>
#include <stdexcept> #include <stdexcept>
#include <string> #include <string>
#include <string_view>
#include <vector> #include <vector>
#define BOOST_CHECK(expr) assert(expr) #define BOOST_CHECK(expr) assert(expr)
@ -160,6 +161,14 @@ void univalue_set()
BOOST_CHECK(v.isStr()); BOOST_CHECK(v.isStr());
BOOST_CHECK_EQUAL(v.getValStr(), "zum"); BOOST_CHECK_EQUAL(v.getValStr(), "zum");
{
std::string_view sv{"ab\0c", 4};
UniValue j{sv};
BOOST_CHECK(j.isStr());
BOOST_CHECK_EQUAL(j.getValStr(), sv);
BOOST_CHECK_EQUAL(j.write(), "\"ab\\u0000c\"");
}
v.setFloat(-1.01); v.setFloat(-1.01);
BOOST_CHECK(v.isNum()); BOOST_CHECK(v.isNum());
BOOST_CHECK_EQUAL(v.getValStr(), "-1.01"); BOOST_CHECK_EQUAL(v.getValStr(), "-1.01");

Loading…
Cancel
Save