remove using namespace std and qualify std:: namespaces

This commit is contained in:
woodser
2020-05-18 16:24:22 -04:00
parent 583e11d663
commit dd31aa5d67
14 changed files with 1399 additions and 1418 deletions
-2
View File
@@ -51,5 +51,3 @@
*/
#include "gen_utils.h"
using namespace std;
+15 -17
View File
@@ -62,13 +62,11 @@
*/
namespace gen_utils
{
using namespace std;
// ------------------------- VALUE RECONCILATION- ---------------------------
// TODO: refactor common template code
template <class T, typename std::enable_if<std::is_same<T, string>::value, T>::type* = nullptr>
boost::optional<T> reconcile(const boost::optional<T>& val1, const boost::optional<T>& val2, boost::optional<bool> resolve_defined, boost::optional<bool> resolve_true, boost::optional<bool> resolve_max, const string& err_msg = "") {
template <class T, typename std::enable_if<std::is_same<T, std::string>::value, T>::type* = nullptr>
boost::optional<T> reconcile(const boost::optional<T>& val1, const boost::optional<T>& val2, boost::optional<bool> resolve_defined, boost::optional<bool> resolve_true, boost::optional<bool> resolve_max, const std::string& err_msg = "") {
// check for equality
if (val1 == val2) return val1;
@@ -79,15 +77,15 @@ namespace gen_utils
else return val1 == boost::none ? val2 : val1;
}
throw runtime_error(string("Cannot reconcile strings: ") + to_string(val1) + string(" vs ") + to_string(val2) + (!err_msg.empty() ? string(". ") + err_msg : string("")));
throw std::runtime_error(std::string("Cannot reconcile strings: ") + to_string(val1) + std::string(" vs ") + to_string(val2) + (!err_msg.empty() ? std::string(". ") + err_msg : std::string("")));
}
template <class T, typename std::enable_if<std::is_same<T, string>::value, T>::type* = nullptr>
boost::optional<T> reconcile(const boost::optional<T>& val1, const boost::optional<T>& val2, const string& err_msg = "") {
template <class T, typename std::enable_if<std::is_same<T, std::string>::value, T>::type* = nullptr>
boost::optional<T> reconcile(const boost::optional<T>& val1, const boost::optional<T>& val2, const std::string& err_msg = "") {
return reconcile(val1, val2, boost::none, boost::none, boost::none, err_msg);
}
template <class T, typename std::enable_if<std::is_integral<T>::value, T>::type* = nullptr>
boost::optional<T> reconcile(const boost::optional<T>& val1, const boost::optional<T>& val2, boost::optional<bool> resolve_defined, boost::optional<bool> resolve_true, boost::optional<bool> resolve_max, const string& err_msg = "") {
boost::optional<T> reconcile(const boost::optional<T>& val1, const boost::optional<T>& val2, boost::optional<bool> resolve_defined, boost::optional<bool> resolve_true, boost::optional<bool> resolve_max, const std::string& err_msg = "") {
// check for equality
if (val1 == val2) return val1;
@@ -100,19 +98,19 @@ namespace gen_utils
// resolve different numbers
if (resolve_max != boost::none) {
return *resolve_max ? max(*val1, *val2) : min(*val1, *val2);
return *resolve_max ? std::max(*val1, *val2) : std::min(*val1, *val2);
}
// throw runtime_error("Cannot reconcile values " + val1 + " and " + val2 + " with config: [" + resolve_defined + ", " + resolve_true + ", " + resolve_max + "]", val1, val2);
throw runtime_error(string("Cannot reconcile integrals: ") + to_string(val1) + string(" vs ") + to_string(val2) + (!err_msg.empty() ? string(". ") + err_msg : string("")));
// throw std::runtime_error("Cannot reconcile values " + val1 + " and " + val2 + " with config: [" + resolve_defined + ", " + resolve_true + ", " + resolve_max + "]", val1, val2);
throw std::runtime_error(std::string("Cannot reconcile integrals: ") + to_string(val1) + std::string(" vs ") + to_string(val2) + (!err_msg.empty() ? std::string(". ") + err_msg : std::string("")));
}
template <class T, typename std::enable_if<std::is_integral<T>::value, T>::type* = nullptr>
boost::optional<T> reconcile(const boost::optional<T>& val1, const boost::optional<T>& val2, const string& err_msg = "") {
boost::optional<T> reconcile(const boost::optional<T>& val1, const boost::optional<T>& val2, const std::string& err_msg = "") {
return reconcile(val1, val2, boost::none, boost::none, boost::none, err_msg);
}
template <class T, typename std::enable_if<std::is_same<T, bool>::value, T>::type>
boost::optional<T> reconcile(const boost::optional<T>& val1, const boost::optional<T>& val2, boost::optional<bool> resolve_defined, boost::optional<bool> resolve_true, boost::optional<bool> resolve_max, const string& err_msg = "") {
boost::optional<T> reconcile(const boost::optional<T>& val1, const boost::optional<T>& val2, boost::optional<bool> resolve_defined, boost::optional<bool> resolve_true, boost::optional<bool> resolve_max, const std::string& err_msg = "") {
// check for equality
if (val1 == val2) return val1;
@@ -127,16 +125,16 @@ namespace gen_utils
if (resolve_true != boost::none) {
return val1 == resolve_true ? val1 : val2; // if resolve true, return true, else return false
} else {
throw runtime_error(string("Cannot reconcile booleans: ") + to_string(val1) + string(" vs ") + to_string(val2) + (!err_msg.empty() ? string(". ") + err_msg : string("")));
throw std::runtime_error(std::string("Cannot reconcile booleans: ") + to_string(val1) + std::string(" vs ") + to_string(val2) + (!err_msg.empty() ? std::string(". ") + err_msg : std::string("")));
}
}
template <class T, typename std::enable_if<std::is_same<T, bool>::value, T>::type>
boost::optional<T> reconcile(const boost::optional<T>& val1, const boost::optional<T>& val2, const string& err_msg = "") {
boost::optional<T> reconcile(const boost::optional<T>& val1, const boost::optional<T>& val2, const std::string& err_msg = "") {
return reconcile(val1, val2, boost::none, boost::none, boost::none, err_msg);
}
template <class T>
vector<T> reconcile(const vector<T>& v1, const vector<T>& v2, const string& err_msg = "") {
std::vector<T> reconcile(const std::vector<T>& v1, const std::vector<T>& v2, const std::string& err_msg = "") {
// check for equality
if (v1 == v2) return v1;
@@ -146,7 +144,7 @@ namespace gen_utils
if (v2.empty()) return v1;
// otherwise cannot reconcile
throw runtime_error("Cannot reconcile vectors" + (!err_msg.empty() ? string(". ") + err_msg : string("")));
throw std::runtime_error("Cannot reconcile vectors" + (!err_msg.empty() ? std::string(". ") + err_msg : std::string("")));
}
}
#endif /* gen_utils_h */
+25 -26
View File
@@ -56,7 +56,6 @@
#include "cryptonote_basic/cryptonote_format_utils.h"
#include "string_tools.h"
using namespace std;
using namespace cryptonote;
using namespace monero_utils;
@@ -120,7 +119,7 @@ void monero_utils::binary_blocks_to_json(const std::string &bin, std::string &js
root.put("status", resp_struct.status);
root.put("untrusted", resp_struct.untrusted); // TODO: loss of ints and bools
// convert root to string // TODO: common utility with serial_bridge
// convert root to std::string // TODO: common utility with serial_bridge
std::stringstream ss;
boost::property_tree::write_json(ss, root, false/*pretty*/);
json = ss.str();
@@ -128,38 +127,38 @@ void monero_utils::binary_blocks_to_json(const std::string &bin, std::string &js
// ------------------------------- RAPIDJSON ----------------------------------
string monero_utils::serialize(const rapidjson::Document& doc) {
std::string monero_utils::serialize(const rapidjson::Document& doc) {
rapidjson::StringBuffer buffer;
rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
doc.Accept(writer);
return buffer.GetString();
}
void monero_utils::addJsonMember(string key, uint8_t val, rapidjson::Document::AllocatorType& allocator, rapidjson::Value& root, rapidjson::Value& field) {
void monero_utils::addJsonMember(std::string key, uint8_t val, rapidjson::Document::AllocatorType& allocator, rapidjson::Value& root, rapidjson::Value& field) {
rapidjson::Value field_key(key.c_str(), key.size(), allocator);
field.SetInt(val);
root.AddMember(field_key, field, allocator);
}
void monero_utils::addJsonMember(string key, uint32_t val, rapidjson::Document::AllocatorType& allocator, rapidjson::Value& root, rapidjson::Value& field) {
void monero_utils::addJsonMember(std::string key, uint32_t val, rapidjson::Document::AllocatorType& allocator, rapidjson::Value& root, rapidjson::Value& field) {
rapidjson::Value field_key(key.c_str(), key.size(), allocator);
field.SetUint64(val);
root.AddMember(field_key, field, allocator);
}
void monero_utils::addJsonMember(string key, uint64_t val, rapidjson::Document::AllocatorType& allocator, rapidjson::Value& root, rapidjson::Value& field) {
void monero_utils::addJsonMember(std::string key, uint64_t val, rapidjson::Document::AllocatorType& allocator, rapidjson::Value& root, rapidjson::Value& field) {
rapidjson::Value field_key(key.c_str(), key.size(), allocator);
field.SetUint64(val);
root.AddMember(field_key, field, allocator);
}
void monero_utils::addJsonMember(string key, string val, rapidjson::Document::AllocatorType& allocator, rapidjson::Value& root, rapidjson::Value& field) {
void monero_utils::addJsonMember(std::string key, std::string val, rapidjson::Document::AllocatorType& allocator, rapidjson::Value& root, rapidjson::Value& field) {
rapidjson::Value field_key(key.c_str(), key.size(), allocator);
field.SetString(val.c_str(), val.size(), allocator);
root.AddMember(field_key, field, allocator);
}
void monero_utils::addJsonMember(string key, bool val, rapidjson::Document::AllocatorType& allocator, rapidjson::Value& root) {
void monero_utils::addJsonMember(std::string key, bool val, rapidjson::Document::AllocatorType& allocator, rapidjson::Value& root) {
rapidjson::Value field_key(key.c_str(), key.size(), allocator);
if (val) {
rapidjson::Value field_val(rapidjson::kTrueType);
@@ -170,17 +169,17 @@ void monero_utils::addJsonMember(string key, bool val, rapidjson::Document::Allo
}
}
rapidjson::Value monero_utils::to_rapidjson_val(rapidjson::Document::AllocatorType& allocator, const vector<string>& strs) {
rapidjson::Value monero_utils::to_rapidjson_val(rapidjson::Document::AllocatorType& allocator, const std::vector<std::string>& strs) {
rapidjson::Value value_arr(rapidjson::kArrayType);
rapidjson::Value value_str(rapidjson::kStringType);
for (const string& str : strs) {
for (const std::string& str : strs) {
value_str.SetString(str.c_str(), str.size(), allocator);
value_arr.PushBack(value_str, allocator);
}
return value_arr;
}
rapidjson::Value monero_utils::to_rapidjson_val(rapidjson::Document::AllocatorType& allocator, const vector<uint8_t>& nums) {
rapidjson::Value monero_utils::to_rapidjson_val(rapidjson::Document::AllocatorType& allocator, const std::vector<uint8_t>& nums) {
rapidjson::Value value_arr(rapidjson::kArrayType);
rapidjson::Value value_num(rapidjson::kNumberType);
for (const auto& num : nums) {
@@ -191,7 +190,7 @@ rapidjson::Value monero_utils::to_rapidjson_val(rapidjson::Document::AllocatorTy
}
// TODO: remove these redundant implementations for different sizes?
rapidjson::Value monero_utils::to_rapidjson_val(rapidjson::Document::AllocatorType& allocator, const vector<uint32_t>& nums) {
rapidjson::Value monero_utils::to_rapidjson_val(rapidjson::Document::AllocatorType& allocator, const std::vector<uint32_t>& nums) {
rapidjson::Value value_arr(rapidjson::kArrayType);
rapidjson::Value value_num(rapidjson::kNumberType);
for (const auto& num : nums) {
@@ -201,7 +200,7 @@ rapidjson::Value monero_utils::to_rapidjson_val(rapidjson::Document::AllocatorTy
return value_arr;
}
rapidjson::Value monero_utils::to_rapidjson_val(rapidjson::Document::AllocatorType& allocator, const vector<uint64_t>& nums) {
rapidjson::Value monero_utils::to_rapidjson_val(rapidjson::Document::AllocatorType& allocator, const std::vector<uint64_t>& nums) {
rapidjson::Value value_arr(rapidjson::kArrayType);
rapidjson::Value value_num(rapidjson::kNumberType);
for (const auto& num : nums) {
@@ -213,19 +212,19 @@ rapidjson::Value monero_utils::to_rapidjson_val(rapidjson::Document::AllocatorTy
// ------------------------ PROPERTY TREES ---------------------------
string monero_utils::serialize(const boost::property_tree::ptree& node) {
std::string monero_utils::serialize(const boost::property_tree::ptree& node) {
std::stringstream ss;
boost::property_tree::write_json(ss, node, false);
string str = ss.str();
std::string str = ss.str();
return str.substr(0, str.size() - 1); // strip newline
}
void monero_utils::deserialize(const string& json, boost::property_tree::ptree& root) {
void monero_utils::deserialize(const std::string& json, boost::property_tree::ptree& root) {
std::istringstream iss = json.empty() ? std::istringstream() : std::istringstream(json);
try {
boost::property_tree::read_json(iss, root);
} catch (std::exception const& e) {
throw runtime_error("Invalid JSON");
throw std::runtime_error("Invalid JSON");
}
}
@@ -233,10 +232,10 @@ void monero_utils::deserialize(const string& json, boost::property_tree::ptree&
// TODO: this is unused
shared_ptr<monero_block> monero_utils::cn_block_to_block(const cryptonote::block& cn_block) {
std::shared_ptr<monero_block> monero_utils::cn_block_to_block(const cryptonote::block& cn_block) {
cryptonote::block temp = cn_block;
cout << cryptonote::obj_to_json_str(temp) << endl;
shared_ptr<monero_block> block = make_shared<monero_block>();
std::cout << cryptonote::obj_to_json_str(temp) << std::endl;
std::shared_ptr<monero_block> block = std::make_shared<monero_block>();
block->m_major_version = cn_block.major_version;
block->m_minor_version = cn_block.minor_version;
block->m_timestamp = cn_block.timestamp;
@@ -249,8 +248,8 @@ shared_ptr<monero_block> monero_utils::cn_block_to_block(const cryptonote::block
return block;
}
shared_ptr<monero_tx> monero_utils::cn_tx_to_tx(const cryptonote::transaction& cn_tx, bool init_as_tx_wallet) {
shared_ptr<monero_tx> tx = init_as_tx_wallet ? make_shared<monero_tx_wallet>() : make_shared<monero_tx>();
std::shared_ptr<monero_tx> monero_utils::cn_tx_to_tx(const cryptonote::transaction& cn_tx, bool init_as_tx_wallet) {
std::shared_ptr<monero_tx> tx = init_as_tx_wallet ? std::make_shared<monero_tx_wallet>() : std::make_shared<monero_tx>();
tx->m_version = cn_tx.version;
tx->m_unlock_time = cn_tx.unlock_time;
tx->m_hash = epee::string_tools::pod_to_hex(cn_tx.hash);
@@ -258,23 +257,23 @@ shared_ptr<monero_tx> monero_utils::cn_tx_to_tx(const cryptonote::transaction& c
// init inputs
for (const txin_v& cnVin : cn_tx.vin) {
if (cnVin.which() != 0 && cnVin.which() != 3) throw runtime_error("Unsupported variant type");
if (cnVin.which() != 0 && cnVin.which() != 3) throw std::runtime_error("Unsupported variant type");
if (tx->m_is_miner_tx == boost::none) tx->m_is_miner_tx = cnVin.which() == 0;
if (cnVin.which() != 3) continue; // only process txin_to_key of variant TODO: support other types, like 0 "gen" which is miner tx?
shared_ptr<monero_output> input = init_as_tx_wallet ? make_shared<monero_output_wallet>() : make_shared<monero_output>();
std::shared_ptr<monero_output> input = init_as_tx_wallet ? std::make_shared<monero_output_wallet>() : std::make_shared<monero_output>();
input->m_tx = tx;
tx->m_inputs.push_back(input);
const txin_to_key& txin = boost::get<txin_to_key>(cnVin);
input->m_amount = txin.amount;
input->m_ring_output_indices = txin.key_offsets;
crypto::key_image cnKeyImage = txin.k_image;
input->m_key_image = make_shared<monero_key_image>();
input->m_key_image = std::make_shared<monero_key_image>();
input->m_key_image.get()->m_hex = epee::string_tools::pod_to_hex(cnKeyImage);
}
// init outputs
for (const tx_out& cnVout : cn_tx.vout) {
shared_ptr<monero_output> output = init_as_tx_wallet ? make_shared<monero_output_wallet>() : make_shared<monero_output>();
std::shared_ptr<monero_output> output = init_as_tx_wallet ? std::make_shared<monero_output_wallet>() : std::make_shared<monero_output>();
output->m_tx = tx;
tx->m_outputs.push_back(output);
output->m_amount = cnVout.amount;
+25 -26
View File
@@ -65,7 +65,6 @@
*/
namespace monero_utils
{
using namespace std;
using namespace cryptonote;
// ------------------------ CONSTANTS ---------------------------
@@ -80,16 +79,16 @@ namespace monero_utils
// ------------------------------ RAPIDJSON ---------------------------------
string serialize(const rapidjson::Document& doc);
std::string serialize(const rapidjson::Document& doc);
void addJsonMember(string key, uint8_t val, rapidjson::Document::AllocatorType& allocator, rapidjson::Value& root, rapidjson::Value& field);
void addJsonMember(string key, uint32_t val, rapidjson::Document::AllocatorType& allocator, rapidjson::Value& root, rapidjson::Value& field);
void addJsonMember(string key, uint64_t val, rapidjson::Document::AllocatorType& allocator, rapidjson::Value& root, rapidjson::Value& field);
void addJsonMember(string key, string val, rapidjson::Document::AllocatorType& allocator, rapidjson::Value& root, rapidjson::Value& field);
void addJsonMember(string key, bool val, rapidjson::Document::AllocatorType& allocator, rapidjson::Value& root);
void addJsonMember(std::string key, uint8_t val, rapidjson::Document::AllocatorType& allocator, rapidjson::Value& root, rapidjson::Value& field);
void addJsonMember(std::string key, uint32_t val, rapidjson::Document::AllocatorType& allocator, rapidjson::Value& root, rapidjson::Value& field);
void addJsonMember(std::string key, uint64_t val, rapidjson::Document::AllocatorType& allocator, rapidjson::Value& root, rapidjson::Value& field);
void addJsonMember(std::string key, std::string val, rapidjson::Document::AllocatorType& allocator, rapidjson::Value& root, rapidjson::Value& field);
void addJsonMember(std::string key, bool val, rapidjson::Document::AllocatorType& allocator, rapidjson::Value& root);
// TODO: template implementation here, could move to monero_utils.hpp per https://stackoverflow.com/questions/3040480/c-template-function-compiles-in-header-but-not-implementation
template <class T> rapidjson::Value to_rapidjson_val(rapidjson::Document::AllocatorType& allocator, const vector<shared_ptr<T>>& vals) {
template <class T> rapidjson::Value to_rapidjson_val(rapidjson::Document::AllocatorType& allocator, const std::vector<std::shared_ptr<T>>& vals) {
rapidjson::Value value_arr(rapidjson::kArrayType);
for (const auto& val : vals) {
value_arr.PushBack(val->to_rapidjson_val(allocator), allocator);
@@ -98,7 +97,7 @@ namespace monero_utils
}
// TODO: template implementation here, could move to monero_utils.hpp per https://stackoverflow.com/questions/3040480/c-template-function-compiles-in-header-but-not-implementation
template <class T> rapidjson::Value to_rapidjson_val(rapidjson::Document::AllocatorType& allocator, const vector<T>& vals) {
template <class T> rapidjson::Value to_rapidjson_val(rapidjson::Document::AllocatorType& allocator, const std::vector<T>& vals) {
rapidjson::Value value_arr(rapidjson::kArrayType);
for (const auto& val : vals) {
value_arr.PushBack(val.to_rapidjson_val(allocator), allocator);
@@ -106,21 +105,21 @@ namespace monero_utils
return value_arr;
}
rapidjson::Value to_rapidjson_val(rapidjson::Document::AllocatorType& allocator, const vector<string>& strs);
rapidjson::Value to_rapidjson_val(rapidjson::Document::AllocatorType& allocator, const vector<uint8_t>& nums);
rapidjson::Value to_rapidjson_val(rapidjson::Document::AllocatorType& allocator, const vector<uint32_t>& nums);
rapidjson::Value to_rapidjson_val(rapidjson::Document::AllocatorType& allocator, const vector<uint64_t>& nums);
rapidjson::Value to_rapidjson_val(rapidjson::Document::AllocatorType& allocator, const std::vector<std::string>& strs);
rapidjson::Value to_rapidjson_val(rapidjson::Document::AllocatorType& allocator, const std::vector<uint8_t>& nums);
rapidjson::Value to_rapidjson_val(rapidjson::Document::AllocatorType& allocator, const std::vector<uint32_t>& nums);
rapidjson::Value to_rapidjson_val(rapidjson::Document::AllocatorType& allocator, const std::vector<uint64_t>& nums);
// ------------------------ PROPERTY TREES ---------------------------
// TODO: fully switch from property trees to rapidjson
string serialize(const boost::property_tree::ptree& node);
void deserialize(const string& json, boost::property_tree::ptree& root);
std::string serialize(const boost::property_tree::ptree& node);
void deserialize(const std::string& json, boost::property_tree::ptree& root);
// --------------------------------------------------------------------------
void deserialize(const string& json, boost::property_tree::ptree& root);
void deserialize(const std::string& json, boost::property_tree::ptree& root);
/**
* Convert a Monero Core cryptonote::block to a block in this library's native model.
@@ -128,7 +127,7 @@ namespace monero_utils
* @param cn_block is the Core block to convert
* @return a block in this library's native model
*/
shared_ptr<monero_block> cn_block_to_block(const cryptonote::block& cn_block);
std::shared_ptr<monero_block> cn_block_to_block(const cryptonote::block& cn_block);
/**
* Convert a Monero Core crpytonote::transaction to a transaction in this library's
@@ -137,10 +136,10 @@ namespace monero_utils
* @param cn_tx is the Core transaction to convert
* @param init_as_tx_wallet specifies if a monero_tx xor monero_tx_wallet should be initialized
*/
shared_ptr<monero_tx> cn_tx_to_tx(const cryptonote::transaction& cn_tx, bool init_as_tx_wallet = false);
std::shared_ptr<monero_tx> cn_tx_to_tx(const cryptonote::transaction& cn_tx, bool init_as_tx_wallet = false);
/**
* Modified from core_rpc_server.cpp to return a string.
* Modified from core_rpc_server.cpp to return a std::string.
*
* TODO: remove this duplicate, use core_rpc_server instead
*/
@@ -158,15 +157,15 @@ namespace monero_utils
*
* @param block is the block to free
*/
static void free(shared_ptr<monero_block> block) {
for (shared_ptr<monero_tx>& tx : block->m_txs) {
static void free(std::shared_ptr<monero_block> block) {
for (std::shared_ptr<monero_tx>& tx : block->m_txs) {
tx->m_block.reset();
monero_tx_wallet* tx_wallet = dynamic_cast<monero_tx_wallet*>(tx.get());
if (tx_wallet != nullptr) {
if (tx_wallet->m_outgoing_transfer != boost::none) tx_wallet->m_outgoing_transfer.get()->m_tx.reset();
for (shared_ptr<monero_transfer> transfer : tx_wallet->m_incoming_transfers) transfer->m_tx.reset();
for (shared_ptr<monero_output> output : tx_wallet->m_outputs) output->m_tx.reset();
for (shared_ptr<monero_output> input : tx_wallet->m_inputs) {
for (std::shared_ptr<monero_transfer> transfer : tx_wallet->m_incoming_transfers) transfer->m_tx.reset();
for (std::shared_ptr<monero_output> output : tx_wallet->m_outputs) output->m_tx.reset();
for (std::shared_ptr<monero_output> input : tx_wallet->m_inputs) {
input->m_key_image.reset();
input->m_tx.reset();
}
@@ -180,8 +179,8 @@ namespace monero_utils
*
* @param blocks are blocks to free
*/
static void free(vector<shared_ptr<monero_block>> blocks) {
for (shared_ptr<monero_block>& block : blocks) monero_utils::free(block);
static void free(std::vector<std::shared_ptr<monero_block>> blocks) {
for (std::shared_ptr<monero_block>& block : blocks) monero_utils::free(block);
}
}
#endif /* monero_utils_h */