mirror of
https://github.com/transmission/transmission
synced 2025-01-03 05:25:52 +00:00
refactor: tr_variant API update (#5998)
This commit is contained in:
parent
8234fe39d2
commit
9a82372e95
2 changed files with 218 additions and 67 deletions
|
@ -117,10 +117,11 @@ void tr_variant::Merge::operator()(tr_variant::Map const& src)
|
|||
{
|
||||
tgt_.val_.emplace<tr_variant::Map>();
|
||||
}
|
||||
auto* const tgt = tgt_.get_if<tr_variant::MapIndex>();
|
||||
auto& tgt = *tgt_.get_if<tr_variant::MapIndex>();
|
||||
tgt.reserve(std::size(tgt) + std::size(src));
|
||||
for (auto const& [key, val] : src)
|
||||
{
|
||||
std::visit(Merge{ (*tgt)[key] }, val.val_);
|
||||
std::visit(Merge{ tgt[key] }, val.val_);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -380,31 +381,38 @@ void tr_variantInitStr(tr_variant* initme, std::string_view value)
|
|||
*initme = value;
|
||||
}
|
||||
|
||||
void tr_variantInitList(tr_variant* initme, size_t reserve_count)
|
||||
void tr_variantInitList(tr_variant* initme, size_t n_reserve)
|
||||
{
|
||||
auto vec = tr_variant::Vector{};
|
||||
vec.reserve(reserve_count);
|
||||
vec.reserve(n_reserve);
|
||||
*initme = std::move(vec);
|
||||
}
|
||||
|
||||
void tr_variantListReserve(tr_variant* const var, size_t count)
|
||||
void tr_variantListReserve(tr_variant* const var, size_t n_reserve)
|
||||
{
|
||||
TR_ASSERT(var != nullptr);
|
||||
TR_ASSERT(var->holds_alternative<tr_variant::Vector>());
|
||||
|
||||
if (auto* const vec = var != nullptr ? var->get_if<tr_variant::VectorIndex>() : nullptr; vec != nullptr)
|
||||
{
|
||||
vec->reserve(std::size(*vec) + count);
|
||||
vec->reserve(std::size(*vec) + n_reserve);
|
||||
}
|
||||
}
|
||||
|
||||
void tr_variantInitDict(tr_variant* initme, size_t /*reserve_count*/)
|
||||
void tr_variantInitDict(tr_variant* initme, size_t n_reserve)
|
||||
{
|
||||
*initme = tr_variant::Map{};
|
||||
*initme = tr_variant::Map{ n_reserve };
|
||||
}
|
||||
|
||||
void tr_variantDictReserve(tr_variant* const /*var*/, size_t /*reserve_count*/)
|
||||
void tr_variantDictReserve(tr_variant* const var, size_t n_reserve)
|
||||
{
|
||||
TR_ASSERT(var != nullptr);
|
||||
TR_ASSERT(var->holds_alternative<tr_variant::Map>());
|
||||
|
||||
if (auto* const map = var != nullptr ? var->get_if<tr_variant::MapIndex>() : nullptr; map != nullptr)
|
||||
{
|
||||
map->reserve(std::size(*map) + n_reserve);
|
||||
}
|
||||
}
|
||||
|
||||
tr_variant* tr_variantListAdd(tr_variant* const var)
|
||||
|
@ -460,26 +468,26 @@ tr_variant* tr_variantListAddQuark(tr_variant* const var, tr_quark value)
|
|||
return tr_variantListAddStrView(var, tr_quark_get_string_view(value));
|
||||
}
|
||||
|
||||
tr_variant* tr_variantListAddRaw(tr_variant* const var, void const* value, size_t value_len)
|
||||
tr_variant* tr_variantListAddRaw(tr_variant* const var, void const* value, size_t n_bytes)
|
||||
{
|
||||
auto* const child = tr_variantListAdd(var);
|
||||
*child = std::string_view{ static_cast<char const*>(value), value_len };
|
||||
*child = tr_variant::make_raw(value, n_bytes);
|
||||
return child;
|
||||
}
|
||||
|
||||
tr_variant* tr_variantListAddList(tr_variant* const var, size_t reserve_count)
|
||||
tr_variant* tr_variantListAddList(tr_variant* const var, size_t n_reserve)
|
||||
{
|
||||
auto* const child = tr_variantListAdd(var);
|
||||
auto vec = tr_variant::Vector{};
|
||||
vec.reserve(reserve_count);
|
||||
vec.reserve(n_reserve);
|
||||
*child = std::move(vec);
|
||||
return child;
|
||||
}
|
||||
|
||||
tr_variant* tr_variantListAddDict(tr_variant* const var, size_t reserve_count)
|
||||
tr_variant* tr_variantListAddDict(tr_variant* const var, size_t n_reserve)
|
||||
{
|
||||
auto* const child = tr_variantListAdd(var);
|
||||
tr_variantInitDict(child, reserve_count);
|
||||
tr_variantInitDict(child, n_reserve);
|
||||
return child;
|
||||
}
|
||||
|
||||
|
@ -544,25 +552,25 @@ tr_variant* tr_variantDictAddStrView(tr_variant* const var, tr_quark key, std::s
|
|||
return child;
|
||||
}
|
||||
|
||||
tr_variant* tr_variantDictAddRaw(tr_variant* const var, tr_quark key, void const* value, size_t len)
|
||||
tr_variant* tr_variantDictAddRaw(tr_variant* const var, tr_quark key, void const* value, size_t n_bytes)
|
||||
{
|
||||
tr_variantDictRemove(var, key);
|
||||
auto* const child = tr_variantDictAdd(var, key);
|
||||
tr_variantInitRaw(child, value, len);
|
||||
*child = tr_variant::make_raw(value, n_bytes);
|
||||
return child;
|
||||
}
|
||||
|
||||
tr_variant* tr_variantDictAddList(tr_variant* const var, tr_quark key, size_t reserve_count)
|
||||
tr_variant* tr_variantDictAddList(tr_variant* const var, tr_quark key, size_t n_reserve)
|
||||
{
|
||||
auto* const child = tr_variantDictAdd(var, key);
|
||||
tr_variantInitList(child, reserve_count);
|
||||
tr_variantInitList(child, n_reserve);
|
||||
return child;
|
||||
}
|
||||
|
||||
tr_variant* tr_variantDictAddDict(tr_variant* const var, tr_quark key, size_t reserve_count)
|
||||
tr_variant* tr_variantDictAddDict(tr_variant* const var, tr_quark key, size_t n_reserve)
|
||||
{
|
||||
auto* const child = tr_variantDictAdd(var, key);
|
||||
tr_variantInitDict(child, reserve_count);
|
||||
tr_variantInitDict(child, n_reserve);
|
||||
return child;
|
||||
}
|
||||
|
||||
|
|
|
@ -8,16 +8,16 @@
|
|||
#include <algorithm> // std::move()
|
||||
#include <cstddef> // size_t
|
||||
#include <cstdint> // int64_t
|
||||
#include <map>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <type_traits> // std::is_same_v
|
||||
#include <utility> // std::as_const, std::pair
|
||||
#include <utility> // std::pair
|
||||
#include <variant>
|
||||
#include <vector>
|
||||
|
||||
#include "libtransmission/quark.h"
|
||||
#include "libtransmission/tr-macros.h" // TR_CONSTEXPR20
|
||||
|
||||
struct tr_error;
|
||||
|
||||
|
@ -43,7 +43,126 @@ public:
|
|||
};
|
||||
|
||||
using Vector = std::vector<tr_variant>;
|
||||
using Map = std::map<tr_quark, tr_variant>;
|
||||
|
||||
class Map
|
||||
{
|
||||
public:
|
||||
Map(size_t const n_reserve = 0U)
|
||||
{
|
||||
vec_.reserve(n_reserve);
|
||||
}
|
||||
|
||||
[[nodiscard]] TR_CONSTEXPR20 auto begin() noexcept
|
||||
{
|
||||
return std::begin(vec_);
|
||||
}
|
||||
|
||||
[[nodiscard]] TR_CONSTEXPR20 auto begin() const noexcept
|
||||
{
|
||||
return std::cbegin(vec_);
|
||||
}
|
||||
|
||||
[[nodiscard]] TR_CONSTEXPR20 auto cbegin() const noexcept
|
||||
{
|
||||
return std::cbegin(vec_);
|
||||
}
|
||||
|
||||
[[nodiscard]] TR_CONSTEXPR20 auto end() noexcept
|
||||
{
|
||||
return std::end(vec_);
|
||||
}
|
||||
|
||||
[[nodiscard]] TR_CONSTEXPR20 auto end() const noexcept
|
||||
{
|
||||
return std::cend(vec_);
|
||||
}
|
||||
|
||||
[[nodiscard]] TR_CONSTEXPR20 auto cend() const noexcept
|
||||
{
|
||||
return std::cend(vec_);
|
||||
}
|
||||
|
||||
[[nodiscard]] TR_CONSTEXPR20 auto find(tr_quark const key) noexcept
|
||||
{
|
||||
return std::find_if(begin(), end(), [key](auto const& item) { return item.first == key; });
|
||||
}
|
||||
|
||||
[[nodiscard]] TR_CONSTEXPR20 auto find(tr_quark const key) const noexcept
|
||||
{
|
||||
return std::find_if(begin(), end(), [key](auto const& item) { return item.first == key; });
|
||||
}
|
||||
|
||||
[[nodiscard]] TR_CONSTEXPR20 auto size() const noexcept
|
||||
{
|
||||
return std::size(vec_);
|
||||
}
|
||||
|
||||
[[nodiscard]] TR_CONSTEXPR20 auto empty() const noexcept
|
||||
{
|
||||
return std::empty(vec_);
|
||||
}
|
||||
|
||||
void reserve(size_t new_cap)
|
||||
{
|
||||
vec_.reserve(new_cap);
|
||||
}
|
||||
|
||||
auto erase(tr_quark const key)
|
||||
{
|
||||
if (auto iter = find(key); iter != end())
|
||||
{
|
||||
vec_.erase(iter);
|
||||
return 1U;
|
||||
}
|
||||
|
||||
return 0U;
|
||||
}
|
||||
|
||||
[[nodiscard]] tr_variant& operator[](tr_quark const& key)
|
||||
{
|
||||
if (auto const iter = find(key); iter != end())
|
||||
{
|
||||
return iter->second;
|
||||
}
|
||||
|
||||
return vec_.emplace_back(key, tr_variant{}).second;
|
||||
}
|
||||
|
||||
template<typename Val>
|
||||
std::pair<tr_variant&, bool> try_emplace(tr_quark const key, Val&& val)
|
||||
{
|
||||
if (auto iter = find(key); iter != end())
|
||||
{
|
||||
return { iter->second, false };
|
||||
}
|
||||
|
||||
return { vec_.emplace_back(key, tr_variant{ std::move(val) }).second, true };
|
||||
}
|
||||
|
||||
// --- custom functions
|
||||
|
||||
template<typename Type>
|
||||
[[nodiscard]] TR_CONSTEXPR20 auto TR_CONSTEXPR20 find_if(tr_quark const key) const noexcept
|
||||
{
|
||||
auto const iter = find(key);
|
||||
return iter != end() ? iter->second.get_if<Type>() : nullptr;
|
||||
}
|
||||
|
||||
template<typename Type>
|
||||
[[nodiscard]] TR_CONSTEXPR20 std::optional<Type> value_if(tr_quark const key) const noexcept
|
||||
{
|
||||
if (auto const* const value = find_if<Type>(key); value != nullptr)
|
||||
{
|
||||
return std::optional<Type>{ *value };
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
private:
|
||||
using Vector = std::vector<std::pair<tr_quark, tr_variant>>;
|
||||
Vector vec_;
|
||||
};
|
||||
|
||||
constexpr tr_variant() noexcept = default;
|
||||
tr_variant(tr_variant const&) = delete;
|
||||
|
@ -51,23 +170,66 @@ public:
|
|||
tr_variant& operator=(tr_variant const&) = delete;
|
||||
tr_variant& operator=(tr_variant&& that) noexcept = default;
|
||||
|
||||
[[nodiscard]] static auto make_map() noexcept
|
||||
{
|
||||
auto ret = tr_variant{};
|
||||
ret.val_.emplace<Map>();
|
||||
return ret;
|
||||
}
|
||||
|
||||
template<typename Val>
|
||||
tr_variant(Val value)
|
||||
{
|
||||
*this = std::move(value);
|
||||
}
|
||||
|
||||
[[nodiscard]] static auto make_map(size_t const n_reserve = 0U) noexcept
|
||||
{
|
||||
auto ret = tr_variant{};
|
||||
ret.val_.emplace<Map>(n_reserve);
|
||||
return ret;
|
||||
}
|
||||
|
||||
[[nodiscard]] static auto make_vector(size_t const n_reserve = 0U)
|
||||
{
|
||||
auto ret = tr_variant{};
|
||||
ret.val_.emplace<Vector>().reserve(n_reserve);
|
||||
return ret;
|
||||
}
|
||||
|
||||
[[nodiscard]] static auto make_raw(void const* value, size_t n_bytes)
|
||||
{
|
||||
return tr_variant{ std::string{ static_cast<char const*>(value), n_bytes } };
|
||||
}
|
||||
|
||||
template<typename CharSpan>
|
||||
[[nodiscard]] static auto make_raw(CharSpan const& value)
|
||||
{
|
||||
static_assert(sizeof(CharSpan::value_type) == 1U);
|
||||
return make_raw(std::data(value), std::size(value));
|
||||
}
|
||||
|
||||
[[nodiscard]] static tr_variant unmanaged_string(std::string_view val)
|
||||
{
|
||||
auto ret = tr_variant{};
|
||||
ret.val_.emplace<StringHolder>().set_unmanaged(val);
|
||||
return ret;
|
||||
}
|
||||
|
||||
template<typename Val>
|
||||
tr_variant& operator=(Val value)
|
||||
{
|
||||
val_ = std::move(value);
|
||||
if constexpr (std::is_same_v<Val, std::string_view>)
|
||||
{
|
||||
val_.emplace<StringHolder>(std::string{ value });
|
||||
}
|
||||
// note: std::is_integral_v<bool> is true, so this check
|
||||
// must come first to prevent bools from being stored as ints
|
||||
else if constexpr (std::is_same_v<Val, bool>)
|
||||
{
|
||||
val_.emplace<bool>(value);
|
||||
}
|
||||
else if constexpr (std::is_integral_v<Val> || std::is_enum_v<Val>)
|
||||
{
|
||||
val_ = static_cast<int64_t>(value);
|
||||
}
|
||||
else
|
||||
{
|
||||
val_ = std::move(value);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -79,25 +241,13 @@ public:
|
|||
|
||||
tr_variant& operator=(std::string const& value)
|
||||
{
|
||||
val_.emplace<StringHolder>(std::string(value));
|
||||
*this = std::string{ value };
|
||||
return *this;
|
||||
}
|
||||
|
||||
tr_variant& operator=(std::string_view value)
|
||||
tr_variant& operator=(char const* const value)
|
||||
{
|
||||
val_.emplace<StringHolder>(std::string(value));
|
||||
return *this;
|
||||
}
|
||||
|
||||
tr_variant& operator=(int value)
|
||||
{
|
||||
*this = static_cast<int64_t>(value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
tr_variant& operator=(uint64_t value)
|
||||
{
|
||||
*this = static_cast<int64_t>(value); // hmmm
|
||||
*this = std::string{ value != nullptr ? value : "" };
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -132,7 +282,7 @@ public:
|
|||
}
|
||||
|
||||
template<size_t Index>
|
||||
[[nodiscard]] auto* get_if() noexcept
|
||||
[[nodiscard]] constexpr auto* get_if() noexcept
|
||||
{
|
||||
if constexpr (Index == StringIndex)
|
||||
{
|
||||
|
@ -151,13 +301,6 @@ public:
|
|||
return const_cast<tr_variant*>(this)->get_if<Index>();
|
||||
}
|
||||
|
||||
[[nodiscard]] static tr_variant unmanaged_string(std::string_view val)
|
||||
{
|
||||
auto ret = tr_variant{};
|
||||
ret.val_.emplace<StringHolder>().set_unmanaged(val);
|
||||
return ret;
|
||||
}
|
||||
|
||||
template<typename Val>
|
||||
[[nodiscard]] constexpr bool holds_alternative() const noexcept
|
||||
{
|
||||
|
@ -250,8 +393,8 @@ void tr_variantInitInt(tr_variant* initme, int64_t value);
|
|||
|
||||
// --- Lists
|
||||
|
||||
void tr_variantInitList(tr_variant* initme, size_t reserve_count);
|
||||
void tr_variantListReserve(tr_variant* var, size_t reserve_count);
|
||||
void tr_variantInitList(tr_variant* initme, size_t n_reserve);
|
||||
void tr_variantListReserve(tr_variant* var, size_t n_reserve);
|
||||
|
||||
tr_variant* tr_variantListAdd(tr_variant* var);
|
||||
tr_variant* tr_variantListAddBool(tr_variant* var, bool value);
|
||||
|
@ -260,9 +403,9 @@ tr_variant* tr_variantListAddReal(tr_variant* var, double value);
|
|||
tr_variant* tr_variantListAddStr(tr_variant* var, std::string_view value);
|
||||
tr_variant* tr_variantListAddStrView(tr_variant* var, std::string_view value);
|
||||
tr_variant* tr_variantListAddQuark(tr_variant* var, tr_quark value);
|
||||
tr_variant* tr_variantListAddRaw(tr_variant* var, void const* value, size_t value_len);
|
||||
tr_variant* tr_variantListAddList(tr_variant* var, size_t reserve_count);
|
||||
tr_variant* tr_variantListAddDict(tr_variant* var, size_t reserve_count);
|
||||
tr_variant* tr_variantListAddRaw(tr_variant* var, void const* value, size_t n_bytes);
|
||||
tr_variant* tr_variantListAddList(tr_variant* var, size_t n_reserve);
|
||||
tr_variant* tr_variantListAddDict(tr_variant* var, size_t n_reserve);
|
||||
tr_variant* tr_variantListChild(tr_variant* var, size_t pos);
|
||||
|
||||
bool tr_variantListRemove(tr_variant* var, size_t pos);
|
||||
|
@ -282,8 +425,8 @@ bool tr_variantListRemove(tr_variant* var, size_t pos);
|
|||
|
||||
// --- Dictionaries
|
||||
|
||||
void tr_variantInitDict(tr_variant* initme, size_t reserve_count);
|
||||
void tr_variantDictReserve(tr_variant* var, size_t reserve_count);
|
||||
void tr_variantInitDict(tr_variant* initme, size_t n_reserve);
|
||||
void tr_variantDictReserve(tr_variant* var, size_t n_reserve);
|
||||
bool tr_variantDictRemove(tr_variant* var, tr_quark key);
|
||||
|
||||
tr_variant* tr_variantDictAdd(tr_variant* var, tr_quark key);
|
||||
|
@ -293,9 +436,9 @@ tr_variant* tr_variantDictAddBool(tr_variant* var, tr_quark key, bool value);
|
|||
tr_variant* tr_variantDictAddStr(tr_variant* var, tr_quark key, std::string_view value);
|
||||
tr_variant* tr_variantDictAddStrView(tr_variant* var, tr_quark key, std::string_view value);
|
||||
tr_variant* tr_variantDictAddQuark(tr_variant* var, tr_quark key, tr_quark val);
|
||||
tr_variant* tr_variantDictAddList(tr_variant* var, tr_quark key, size_t reserve_count);
|
||||
tr_variant* tr_variantDictAddDict(tr_variant* var, tr_quark key, size_t reserve_count);
|
||||
tr_variant* tr_variantDictAddRaw(tr_variant* var, tr_quark key, void const* value, size_t len);
|
||||
tr_variant* tr_variantDictAddList(tr_variant* var, tr_quark key, size_t n_reserve);
|
||||
tr_variant* tr_variantDictAddDict(tr_variant* var, tr_quark key, size_t n_reserve);
|
||||
tr_variant* tr_variantDictAddRaw(tr_variant* var, tr_quark key, void const* value, size_t n_bytes);
|
||||
|
||||
bool tr_variantDictChild(tr_variant* var, size_t pos, tr_quark* setme_key, tr_variant** setme_value);
|
||||
tr_variant* tr_variantDictFind(tr_variant* var, tr_quark key);
|
||||
|
@ -321,12 +464,12 @@ class tr_variant_serde
|
|||
public:
|
||||
~tr_variant_serde();
|
||||
|
||||
static tr_variant_serde benc() noexcept
|
||||
[[nodiscard]] static tr_variant_serde benc() noexcept
|
||||
{
|
||||
return tr_variant_serde{ Type::Benc };
|
||||
}
|
||||
|
||||
static tr_variant_serde json() noexcept
|
||||
[[nodiscard]] static tr_variant_serde json() noexcept
|
||||
{
|
||||
return tr_variant_serde{ Type::Json };
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue