Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[feature::value] Add type accessor API #65

Merged
merged 1 commit into from
Sep 25, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 21 additions & 1 deletion include/mapbox/feature.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,17 @@ constexpr bool operator<(const null_value_t&, const null_value_t&) { return fals

constexpr null_value_t null_value = null_value_t();

#define DECLARE_VALUE_TYPE_ACCESOR(NAME, TYPE) \
TYPE* get##NAME() noexcept \
{ \
return match( \
[](TYPE& val) -> TYPE* { return &val; }, \
[](auto&) -> TYPE* { return nullptr; }); \
} \
const TYPE* get##NAME() const noexcept \
{ \
return const_cast<value*>(this)->get##NAME(); \
}
// Multiple numeric types (uint64_t, int64_t, double) are present in order to support
// the widest possible range of JSON numbers, which do not have a maximum range.
// Implementations that produce `value`s should use that order for type preference,
Expand Down Expand Up @@ -64,9 +75,18 @@ struct value : public value_base
value(object_type object) : value_base(std::move(object)) {}

explicit operator bool() const { return !is<null_value_t>(); }

DECLARE_VALUE_TYPE_ACCESOR(Int, int64_t)
DECLARE_VALUE_TYPE_ACCESOR(Uint, uint64_t)
DECLARE_VALUE_TYPE_ACCESOR(Bool, bool)
DECLARE_VALUE_TYPE_ACCESOR(Double, double)
DECLARE_VALUE_TYPE_ACCESOR(Array, array_type)
DECLARE_VALUE_TYPE_ACCESOR(Object, object_type)
};

using property_map = std::unordered_map<std::string, value>;
#undef DECLARE_VALUE_TYPE_ACCESOR

using property_map = value::object_type;

// The same considerations and requirement for numeric types apply as for `value_base`.
using identifier = mapbox::util::variant<null_value_t, uint64_t, int64_t, double, std::string>;
Expand Down
12 changes: 12 additions & 0 deletions test/feature.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,18 @@ TEST_CASE("test value")

value intV{32};
CHECK_THROWS(intV.get<uint64_t>());

auto* result = intV.getInt();
CHECK(result);
CHECK(*result == 32);
*result = 100;
CHECK(intV.get<int64_t>() == 100);

CHECK_FALSE(intV.getUint());
CHECK_FALSE(intV.getBool());
CHECK_FALSE(intV.getDouble());
CHECK_FALSE(intV.getArray());
CHECK_FALSE(intV.getObject());
}

TEST_CASE("test feature")
Expand Down