diff --git a/include/mapbox/feature.hpp b/include/mapbox/feature.hpp index decb22a..dc080e9 100644 --- a/include/mapbox/feature.hpp +++ b/include/mapbox/feature.hpp @@ -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(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, @@ -64,9 +75,18 @@ struct value : public value_base value(object_type object) : value_base(std::move(object)) {} explicit operator bool() const { return !is(); } + + 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; +#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; diff --git a/test/feature.cpp b/test/feature.cpp index 2908126..29f85ea 100644 --- a/test/feature.cpp +++ b/test/feature.cpp @@ -36,6 +36,18 @@ TEST_CASE("test value") value intV{32}; CHECK_THROWS(intV.get()); + + auto* result = intV.getInt(); + CHECK(result); + CHECK(*result == 32); + *result = 100; + CHECK(intV.get() == 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")