Skip to content

Commit

Permalink
univalue support for move semantics (#60)
Browse files Browse the repository at this point in the history
  • Loading branch information
akobrin1 authored Jul 21, 2021
1 parent c6ad0b3 commit ec33b46
Show file tree
Hide file tree
Showing 4 changed files with 165 additions and 49 deletions.
28 changes: 21 additions & 7 deletions src/univalue/include/univalue.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,9 @@ class UniValue {
public:
enum VType { VNULL, VOBJ, VARR, VSTR, VNUM, VBOOL, };

UniValue() { typ = VNULL; }
UniValue(UniValue::VType initialType, const std::string& initialStr = "") {
typ = initialType;
val = initialStr;
}
UniValue() : typ(VNULL) {}
UniValue(UniValue::VType type, const std::string& value = std::string()) : typ(type), val(value) {}
UniValue(UniValue::VType type, std::string&& value) : typ(type), val(std::move(value)) {}
UniValue(uint64_t val_) {
setInt(val_);
}
Expand All @@ -41,9 +39,11 @@ class UniValue {
UniValue(const std::string& val_) {
setStr(val_);
}
UniValue(std::string&& val_) {
setStr(std::move(val_));
}
UniValue(const char *val_) {
std::string s(val_);
setStr(s);
setStr(std::string(val_));
}

void clear();
Expand All @@ -60,11 +60,13 @@ class UniValue {
bool setNull();
bool setBool(bool val);
bool setNumStr(const std::string& val);
bool setNumStr(std::string&& val);
bool setInt(uint64_t val);
bool setInt(int64_t val);
bool setInt(int val_) { return setInt((int64_t)val_); }
bool setFloat(double val);
bool setStr(const std::string& val);
bool setStr(std::string&& val);
bool setArray();
bool setObject();

Expand All @@ -91,11 +93,22 @@ class UniValue {
bool isObject() const { return (typ == VOBJ); }

bool push_back(const UniValue& val);
bool push_back(UniValue&& val);
bool push_backV(const std::vector<UniValue>& vec);
bool push_backV(std::vector<UniValue>&& vec);

void __pushKV(const std::string& key, const UniValue& val);
void __pushKV(const std::string& key, UniValue&& val);
void __pushKV(std::string&& key, const UniValue& val);
void __pushKV(std::string&& key, UniValue&& val);

bool pushKV(const std::string& key, const UniValue& val);
bool pushKV(const std::string& key, UniValue&& val);
bool pushKV(std::string&& key, const UniValue& val);
bool pushKV(std::string&& key, UniValue&& val);

bool pushKVs(const UniValue& obj);
bool pushKVs(UniValue&& obj);

std::string write(unsigned int prettyIndent = 0,
unsigned int indentLevel = 0) const;
Expand All @@ -113,6 +126,7 @@ class UniValue {
std::vector<UniValue> values;

bool findKey(const std::string& key, size_t& retIdx) const;
void write(unsigned int prettyIndent, unsigned int indentLevel, std::string& s) const;
void writeArray(unsigned int prettyIndent, unsigned int indentLevel, std::string& s) const;
void writeObject(unsigned int prettyIndent, unsigned int indentLevel, std::string& s) const;

Expand Down
116 changes: 107 additions & 9 deletions src/univalue/lib/univalue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,22 +54,25 @@ bool UniValue::setNumStr(const std::string& val_)
return true;
}

bool UniValue::setInt(uint64_t val_)
bool UniValue::setNumStr(std::string&& val_)
{
std::ostringstream oss;
if (!validNumStr(val_))
return false;

oss << val_;
clear();
typ = VNUM;
val = std::move(val_);
return true;
}

return setNumStr(oss.str());
bool UniValue::setInt(uint64_t val_)
{
return setNumStr(std::to_string(val_));
}

bool UniValue::setInt(int64_t val_)
{
std::ostringstream oss;

oss << val_;

return setNumStr(oss.str());
return setNumStr(std::to_string(val_));
}

bool UniValue::setFloat(double val_)
Expand All @@ -91,6 +94,14 @@ bool UniValue::setStr(const std::string& val_)
return true;
}

bool UniValue::setStr(std::string&& val_)
{
clear();
typ = VSTR;
val = std::move(val_);
return true;
}

bool UniValue::setArray()
{
clear();
Expand All @@ -114,6 +125,15 @@ bool UniValue::push_back(const UniValue& val_)
return true;
}

bool UniValue::push_back(UniValue&& val_)
{
if (typ != VARR)
return false;

values.push_back(std::move(val_));
return true;
}

bool UniValue::push_backV(const std::vector<UniValue>& vec)
{
if (typ != VARR)
Expand All @@ -124,12 +144,40 @@ bool UniValue::push_backV(const std::vector<UniValue>& vec)
return true;
}

bool UniValue::push_backV(std::vector<UniValue>&& vec)
{
if (typ != VARR)
return false;

values.insert(values.end(), std::make_move_iterator(vec.begin()), std::make_move_iterator(vec.end()));

return true;
}

void UniValue::__pushKV(const std::string& key, const UniValue& val_)
{
keys.push_back(key);
values.push_back(val_);
}

void UniValue::__pushKV(const std::string& key, UniValue&& val_)
{
keys.push_back(key);
values.push_back(std::move(val_));
}

void UniValue::__pushKV(std::string&& key, const UniValue& val_)
{
keys.push_back(std::move(key));
values.push_back(val_);
}

void UniValue::__pushKV(std::string&& key, UniValue&& val_)
{
keys.push_back(std::move(key));
values.push_back(std::move(val_));
}

bool UniValue::pushKV(const std::string& key, const UniValue& val_)
{
if (typ != VOBJ)
Expand All @@ -143,6 +191,45 @@ bool UniValue::pushKV(const std::string& key, const UniValue& val_)
return true;
}

bool UniValue::pushKV(const std::string& key, UniValue&& val_)
{
if (typ != VOBJ)
return false;

size_t idx;
if (findKey(key, idx))
values[idx] = std::move(val_);
else
__pushKV(key, std::move(val_));
return true;
}

bool UniValue::pushKV(std::string&& key, const UniValue& val_)
{
if (typ != VOBJ)
return false;

size_t idx;
if (findKey(key, idx))
values[idx] = val_;
else
__pushKV(std::move(key), val_);
return true;
}

bool UniValue::pushKV(std::string&& key, UniValue&& val_)
{
if (typ != VOBJ)
return false;

size_t idx;
if (findKey(key, idx))
values[idx] = std::move(val_);
else
__pushKV(std::move(key), std::move(val_));
return true;
}

bool UniValue::pushKVs(const UniValue& obj)
{
if (typ != VOBJ || obj.typ != VOBJ)
Expand All @@ -154,6 +241,17 @@ bool UniValue::pushKVs(const UniValue& obj)
return true;
}

bool UniValue::pushKVs(UniValue&& obj)
{
if (typ != VOBJ || obj.typ != VOBJ)
return false;

for (size_t i = 0; i < obj.keys.size(); i++)
__pushKV(std::move(obj.keys[i]), std::move(obj.values.at(i)));

return true;
}

void UniValue::getObjMap(std::map<std::string,UniValue>& kv) const
{
if (typ != VOBJ)
Expand Down
18 changes: 9 additions & 9 deletions src/univalue/lib/univalue_read.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ enum jtokentype getJsonToken(std::string& tokenVal, unsigned int& consumed,
}
}

tokenVal = numStr;
tokenVal = std::move(numStr);
consumed = static_cast<unsigned int>(raw - rawStart);
return JTOK_NUMBER;
}
Expand Down Expand Up @@ -234,7 +234,7 @@ enum jtokentype getJsonToken(std::string& tokenVal, unsigned int& consumed,

if (!writer.finalize())
return JTOK_ERR;
tokenVal = valStr;
tokenVal = std::move(valStr);
consumed = static_cast<unsigned int>(raw - rawStart);
return JTOK_STRING;
}
Expand Down Expand Up @@ -325,7 +325,7 @@ bool UniValue::read(const char *raw, size_t size)
} else {
UniValue tmpVal(utyp);
UniValue *top = stack.back();
top->values.push_back(tmpVal);
top->values.push_back(std::move(tmpVal));

UniValue *newTop = &(top->values.back());
stack.push_back(newTop);
Expand Down Expand Up @@ -400,12 +400,12 @@ bool UniValue::read(const char *raw, size_t size)
}

if (!stack.size()) {
*this = tmpVal;
*this = std::move(tmpVal);
break;
}

UniValue *top = stack.back();
top->values.push_back(tmpVal);
top->values.push_back(std::move(tmpVal));

setExpect(NOT_VALUE);
break;
Expand All @@ -414,12 +414,12 @@ bool UniValue::read(const char *raw, size_t size)
case JTOK_NUMBER: {
UniValue tmpVal(VNUM, tokenVal);
if (!stack.size()) {
*this = tmpVal;
*this = std::move(tmpVal);
break;
}

UniValue *top = stack.back();
top->values.push_back(tmpVal);
top->values.push_back(std::move(tmpVal));

setExpect(NOT_VALUE);
break;
Expand All @@ -434,11 +434,11 @@ bool UniValue::read(const char *raw, size_t size)
} else {
UniValue tmpVal(VSTR, tokenVal);
if (!stack.size()) {
*this = tmpVal;
*this = std::move(tmpVal);
break;
}
UniValue *top = stack.back();
top->values.push_back(tmpVal);
top->values.push_back(std::move(tmpVal));
}

setExpect(NOT_VALUE);
Expand Down
Loading

0 comments on commit ec33b46

Please sign in to comment.