Skip to content

Commit

Permalink
Enc, Dec: add support for std::monostate
Browse files Browse the repository at this point in the history
`std::monostate` can be used as well-behaved empty alternative for
`std::variant` with better comparison qualities than `std::nullptr_t`. It
can also be used as an empty value corresponding to `MP_NIL` with the same
semantics as `std::nullptr_t`.

Closes #82
  • Loading branch information
CuriousGeorgiy committed Jan 17, 2024
1 parent 40fafcc commit de6774a
Show file tree
Hide file tree
Showing 5 changed files with 19 additions and 7 deletions.
2 changes: 1 addition & 1 deletion src/mpp/Constants.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,7 @@ struct ExtValue { int8_t type; uint8_t offset; uint32_t size; };

// The order of types must be exactly the same as in compact::Family!
using Value_t = std::variant<
std::nullptr_t, bool, uint64_t, int64_t, float, double,
std::nullptr_t, std::monostate, bool, uint64_t, int64_t, float, double,
StrValue, BinValue, ArrValue, MapValue, ExtValue
>;

Expand Down
10 changes: 8 additions & 2 deletions src/mpp/Dec.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,8 @@ constexpr auto detectFamily()
detectFamily<BUF, tnt::value_type_t<U>>());
} else if constexpr (tnt::is_variant_v<U>) {
return detectFamilyVariant<BUF, U>();
} else if constexpr (std::is_same_v<U, std::nullptr_t>) {
} else if constexpr (std::is_same_v<U, std::nullptr_t> ||
std::is_same_v<U, std::monostate>) {
return family_sequence<compact::MP_NIL>{};
} else if constexpr (std::is_same_v<U, bool>) {
return family_sequence<compact::MP_BOOL>{};
Expand Down Expand Up @@ -406,6 +407,11 @@ constexpr auto get_subrules()
return complex_seq{};
}

struct {
operator std::nullptr_t() const { return {}; }
operator std::monostate() const { return {}; }
} constexpr empty_value;

template <compact::Family FAMILY, size_t SUBRULE, class BUF>
auto read_value(BUF& buf)
{
Expand All @@ -419,7 +425,7 @@ auto read_value(BUF& buf)
tag - RULE::simplex_tag;

if constexpr (FAMILY == compact::MP_NIL)
return nullptr;
return empty_value;
else if constexpr (RULE::is_bool)
return bool(val);
else if constexpr (RULE::is_simplex_log_range)
Expand Down
3 changes: 2 additions & 1 deletion src/mpp/Enc.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,8 @@ constexpr compact::Family detectFamily()
using V = std::remove_cv_t<tnt::uni_integral_base_t<U>>;
if constexpr (is_wrapped_family_v<T>) {
return T::family;
} else if constexpr (std::is_same_v<V, std::nullptr_t>) {
} else if constexpr (std::is_same_v<V, std::nullptr_t> ||
std::is_same_v<V, std::monostate>) {
return compact::MP_NIL;
} else if constexpr (std::is_same_v<V, bool>) {
return compact::MP_BOOL;
Expand Down
2 changes: 1 addition & 1 deletion src/mpp/Rules.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ struct BaseRule {
using simplex_value_range_t = RuleRange<simplex_value_t>;
};

struct NilRule : BaseRule<compact::MP_NIL, std::nullptr_t> {
struct NilRule : BaseRule<compact::MP_NIL, std::nullptr_t, std::monostate> {
static constexpr simplex_value_range_t simplex_value_range = {0, 0};
static constexpr uint8_t simplex_tag = 0xc0;
};
Expand Down
9 changes: 7 additions & 2 deletions test/EncDecTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1627,8 +1627,8 @@ test_variant()
Buf_t buf;
auto run = buf.begin<true>();

using variant_t = std::variant<bool, int, std::string, nullptr_t,
std::optional<double>, std::vector<int>, Body>;
using variant_t = std::variant<bool, int, std::string, std::nullptr_t,
std::optional<double>, std::vector<int>, Body, std::monostate>;

variant_t wr;
variant_t rd;
Expand Down Expand Up @@ -1669,6 +1669,11 @@ test_variant()
mpp::encode(buf, wr);
mpp::decode(run, rd);
fail_unless(wr == rd);

wr.emplace<7>();
mpp::encode(buf, wr);
mpp::decode(run, rd);
fail_unless(wr == rd);
}

int main()
Expand Down

0 comments on commit de6774a

Please sign in to comment.