diff --git a/include/json/value.h b/include/json/value.h index d0af711..bf4f9c4 100644 --- a/include/json/value.h +++ b/include/json/value.h @@ -412,6 +412,10 @@ public: bool isArray() const; bool isObject() const; + /// The `as` and `is` member function templates and specializations. + template T as() const = delete; + template bool is() const = delete; + bool isConvertibleTo(ValueType other) const; /// Number of values in array or object @@ -673,6 +677,41 @@ private: ptrdiff_t limit_; }; +template <> inline bool Value::as() const { return asBool(); } +template <> inline bool Value::is() const { return isBool(); } + +template <> inline Int Value::as() const { return asInt(); } +template <> inline bool Value::is() const { return isInt(); } + +template <> inline UInt Value::as() const { return asUInt(); } +template <> inline bool Value::is() const { return isUInt(); } + +#if defined(JSON_HAS_INT64) +template <> inline Int64 Value::as() const { return asInt64(); } +template <> inline bool Value::is() const { return isInt64(); } + +template <> inline UInt64 Value::as() const { return asUInt64(); } +template <> inline bool Value::is() const { return isUInt64(); } +#endif + +template <> inline double Value::as() const { return asDouble(); } +template <> inline bool Value::is() const { return isDouble(); } + +template <> inline String Value::as() const { return asString(); } +template <> inline bool Value::is() const { return isString(); } + +/// These `as` specializations are type conversions, and do not have a +/// corresponding `is`. +template <> inline float Value::as() const { return asFloat(); } +template <> inline const char* Value::as() const { + return asCString(); +} +#ifdef JSON_USE_CPPTL +template <> inline CppTL::ConstString Value::as() const { + return asConstString(); +} +#endif + /** \brief Experimental and untested: represents an element of the "path" to * access a node. */ diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index fff5b2c..c0cc00e 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -3502,6 +3502,53 @@ int main(int argc, const char* argv[]) { return runner.runCommandLine(argc, argv); } +struct MemberTemplateAs : JsonTest::TestCase { + template + JsonTest::TestResult& EqEval(T v, F f) const { + const Json::Value j = v; + return JSONTEST_ASSERT_EQUAL(j.as(), f(j)); + } +}; + +JSONTEST_FIXTURE_LOCAL(MemberTemplateAs, BehavesSameAsNamedAs) { + const Json::Value jstr = "hello world"; + JSONTEST_ASSERT_STRING_EQUAL(jstr.as(), jstr.asCString()); + JSONTEST_ASSERT_STRING_EQUAL(jstr.as(), jstr.asString()); +#ifdef JSON_USE_CPPTL + JSONTEST_ASSERT_STRING_EQUAL(js.as(), js.asConstString()); +#endif + EqEval(Json::Int(64), [](const Json::Value& j) { return j.asInt(); }); + EqEval(Json::UInt(64), [](const Json::Value& j) { return j.asUInt(); }); +#if defined(JSON_HAS_INT64) + EqEval(Json::Int64(64), [](const Json::Value& j) { return j.asInt64(); }); + EqEval(Json::UInt64(64), [](const Json::Value& j) { return j.asUInt64(); }); +#endif // if defined(JSON_HAS_INT64) + EqEval(Json::LargestInt(64), + [](const Json::Value& j) { return j.asLargestInt(); }); + EqEval(Json::LargestUInt(64), + [](const Json::Value& j) { return j.asLargestUInt(); }); + + EqEval(69.69f, [](const Json::Value& j) { return j.asFloat(); }); + EqEval(69.69, [](const Json::Value& j) { return j.asDouble(); }); + EqEval(false, [](const Json::Value& j) { return j.asBool(); }); + EqEval(true, [](const Json::Value& j) { return j.asBool(); }); +} + +class MemberTemplateIs : public JsonTest::TestCase {}; + +JSONTEST_FIXTURE_LOCAL(MemberTemplateIs, BehavesSameAsNamedIs) { + const Json::Value values[] = {true, 142, 40.63, "hello world"}; + for (const Json::Value& j : values) { + JSONTEST_ASSERT_EQUAL(j.is(), j.isBool()); + JSONTEST_ASSERT_EQUAL(j.is(), j.isInt()); + JSONTEST_ASSERT_EQUAL(j.is(), j.isInt64()); + JSONTEST_ASSERT_EQUAL(j.is(), j.isUInt()); + JSONTEST_ASSERT_EQUAL(j.is(), j.isUInt64()); + JSONTEST_ASSERT_EQUAL(j.is(), j.isDouble()); + JSONTEST_ASSERT_EQUAL(j.is(), j.isString()); + } +} + #if defined(__GNUC__) #pragma GCC diagnostic pop #endif