aboutsummaryrefslogtreecommitdiff
path: root/src/univalue/include/univalue.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/univalue/include/univalue.h')
-rw-r--r--src/univalue/include/univalue.h168
1 files changed, 67 insertions, 101 deletions
diff --git a/src/univalue/include/univalue.h b/src/univalue/include/univalue.h
index fc5cf402be..8ba6fd5425 100644
--- a/src/univalue/include/univalue.h
+++ b/src/univalue/include/univalue.h
@@ -3,16 +3,17 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or https://opensource.org/licenses/mit-license.php.
-#ifndef __UNIVALUE_H__
-#define __UNIVALUE_H__
-
-#include <stdint.h>
-#include <string.h>
+#ifndef BITCOIN_UNIVALUE_INCLUDE_UNIVALUE_H
+#define BITCOIN_UNIVALUE_INCLUDE_UNIVALUE_H
+#include <charconv>
+#include <cstdint>
+#include <cstring>
+#include <map>
+#include <stdexcept>
#include <string>
+#include <type_traits>
#include <vector>
-#include <map>
-#include <cassert>
class UniValue {
public:
@@ -23,41 +24,39 @@ public:
typ = initialType;
val = initialStr;
}
- UniValue(uint64_t val_) {
- setInt(val_);
- }
- UniValue(int64_t val_) {
- setInt(val_);
- }
- UniValue(bool val_) {
- setBool(val_);
- }
- UniValue(int val_) {
- setInt(val_);
- }
- UniValue(double val_) {
- setFloat(val_);
- }
- UniValue(const std::string& val_) {
- setStr(val_);
- }
- UniValue(const char *val_) {
- std::string s(val_);
- setStr(s);
+ 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::is_same_v<bool, T> || // setBool
+ std::is_signed_v<T> || std::is_unsigned_v<T> || // setInt
+ std::is_constructible_v<std::string, T>, // setStr
+ bool> = true>
+ UniValue(Ref&& val)
+ {
+ if constexpr (std::is_floating_point_v<T>) {
+ setFloat(val);
+ } else if constexpr (std::is_same_v<bool, T>) {
+ setBool(val);
+ } else if constexpr (std::is_signed_v<T>) {
+ setInt(int64_t{val});
+ } else if constexpr (std::is_unsigned_v<T>) {
+ setInt(uint64_t{val});
+ } else {
+ setStr(std::string{std::forward<Ref>(val)});
+ }
}
void clear();
- bool setNull();
- bool setBool(bool val);
- bool setNumStr(const 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 setArray();
- bool setObject();
+ void setNull();
+ void setBool(bool val);
+ void setNumStr(const std::string& val);
+ void setInt(uint64_t val);
+ void setInt(int64_t val);
+ void setInt(int val_) { return setInt(int64_t{val_}); }
+ void setFloat(double val);
+ void setStr(const std::string& val);
+ void setArray();
+ void setObject();
enum VType getType() const { return typ; }
const std::string& getValStr() const { return val; }
@@ -81,68 +80,14 @@ public:
bool isArray() const { return (typ == VARR); }
bool isObject() const { return (typ == VOBJ); }
- bool push_back(const UniValue& val);
- bool push_back(const std::string& val_) {
- UniValue tmpVal(VSTR, val_);
- return push_back(tmpVal);
- }
- bool push_back(const char *val_) {
- std::string s(val_);
- return push_back(s);
- }
- bool push_back(uint64_t val_) {
- UniValue tmpVal(val_);
- return push_back(tmpVal);
- }
- bool push_back(int64_t val_) {
- UniValue tmpVal(val_);
- return push_back(tmpVal);
- }
- bool push_back(bool val_) {
- UniValue tmpVal(val_);
- return push_back(tmpVal);
- }
- bool push_back(int val_) {
- UniValue tmpVal(val_);
- return push_back(tmpVal);
- }
- bool push_back(double val_) {
- UniValue tmpVal(val_);
- return push_back(tmpVal);
- }
- bool push_backV(const std::vector<UniValue>& vec);
+ void push_back(const UniValue& val);
+ void push_backV(const std::vector<UniValue>& vec);
+ template <class It>
+ void push_backV(It first, It last);
void __pushKV(const std::string& key, const UniValue& val);
- bool pushKV(const std::string& key, const UniValue& val);
- bool pushKV(const std::string& key, const std::string& val_) {
- UniValue tmpVal(VSTR, val_);
- return pushKV(key, tmpVal);
- }
- bool pushKV(const std::string& key, const char *val_) {
- std::string _val(val_);
- return pushKV(key, _val);
- }
- bool pushKV(const std::string& key, int64_t val_) {
- UniValue tmpVal(val_);
- return pushKV(key, tmpVal);
- }
- bool pushKV(const std::string& key, uint64_t val_) {
- UniValue tmpVal(val_);
- return pushKV(key, tmpVal);
- }
- bool pushKV(const std::string& key, bool val_) {
- UniValue tmpVal(val_);
- return pushKV(key, tmpVal);
- }
- bool pushKV(const std::string& key, int val_) {
- UniValue tmpVal((int64_t)val_);
- return pushKV(key, tmpVal);
- }
- bool pushKV(const std::string& key, double val_) {
- UniValue tmpVal(val_);
- return pushKV(key, tmpVal);
- }
- bool pushKVs(const UniValue& obj);
+ void pushKV(const std::string& key, const UniValue& val);
+ void pushKVs(const UniValue& obj);
std::string write(unsigned int prettyIndent = 0,
unsigned int indentLevel = 0) const;
@@ -159,6 +104,7 @@ private:
std::vector<std::string> keys;
std::vector<UniValue> values;
+ void checkType(const VType& expected) const;
bool findKey(const std::string& key, size_t& retIdx) 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;
@@ -168,10 +114,10 @@ public:
// value is of unexpected type
const std::vector<std::string>& getKeys() const;
const std::vector<UniValue>& getValues() const;
+ template <typename Int>
+ Int getInt() const;
bool get_bool() const;
const std::string& get_str() const;
- int get_int() const;
- int64_t get_int64() const;
double get_real() const;
const UniValue& get_obj() const;
const UniValue& get_array() const;
@@ -180,6 +126,26 @@ public:
friend const UniValue& find_value( const UniValue& obj, const std::string& name);
};
+template <class It>
+void UniValue::push_backV(It first, It last)
+{
+ checkType(VARR);
+ values.insert(values.end(), first, last);
+}
+
+template <typename Int>
+Int UniValue::getInt() const
+{
+ static_assert(std::is_integral<Int>::value);
+ checkType(VNUM);
+ Int result;
+ const auto [first_nonmatching, error_condition] = std::from_chars(val.data(), val.data() + val.size(), result);
+ if (first_nonmatching != val.data() + val.size() || error_condition != std::errc{}) {
+ throw std::runtime_error("JSON integer out of range");
+ }
+ return result;
+}
+
enum jtokentype {
JTOK_ERR = -1,
JTOK_NONE = 0, // eof
@@ -237,4 +203,4 @@ extern const UniValue NullUniValue;
const UniValue& find_value( const UniValue& obj, const std::string& name);
-#endif // __UNIVALUE_H__
+#endif // BITCOIN_UNIVALUE_INCLUDE_UNIVALUE_H