From 4e02630e32b17be32fa19ec147c0c25bf5cd75c3 Mon Sep 17 00:00:00 2001 From: Billy Donahue Date: Sun, 3 Nov 2019 11:40:34 -0500 Subject: [PATCH] Remove macros and prune some overloads. (#1066) Combine is tests and combine as tests. --- include/json/value.h | 78 ++++++++++----------- src/test_lib_json/main.cpp | 136 ++++++++++--------------------------- 2 files changed, 70 insertions(+), 144 deletions(-) diff --git a/include/json/value.h b/include/json/value.h index 4d74b00..2f5bfc5 100644 --- a/include/json/value.h +++ b/include/json/value.h @@ -399,33 +399,6 @@ public: double asDouble() const; bool asBool() const; - template struct asLookupHelper; - -#define defAsLookupHelper(type, lookup) \ - template <> struct asLookupHelper { \ - static type as(const Value& val) { return val.lookup(); } \ - } - - defAsLookupHelper(const char*, asCString); - defAsLookupHelper(String, asString); -#ifdef JSON_USE_CPPTL - defAsLookupHelper(CppTL::ConstString, asConstString); -#endif - defAsLookupHelper(Int, asInt); - defAsLookupHelper(UInt, asUInt); -#if defined(JSON_HAS_INT64) - defAsLookupHelper(Int64, asInt64); - defAsLookupHelper(UInt64, asUInt64); -#endif // if defined(JSON_HAS_INT64) - // (U)LargestInt is a type alias of int or int64 and thus cannot be defined - defAsLookupHelper(float, asFloat); - defAsLookupHelper(double, asDouble); - defAsLookupHelper(bool, asBool); - -#undef defAsLookupHelper - - template T as() const { return asLookupHelper::as(*this); } - bool isNull() const; bool isBool() const; bool isInt() const; @@ -439,25 +412,42 @@ public: bool isArray() const; bool isObject() const; - template struct isLookupHelper; + /// The `as` and `is` member function templates and specializations. + template T as() const = delete; + template bool is() const = delete; -#define defIsLookupHelper(type, lookup) \ - template <> struct isLookupHelper { \ - static bool is(const Value& val) { return val.lookup(); } \ + template <> bool as() const { return asBool(); } + template <> bool is() const { return isBool(); } + + template <> Int as() const { return asInt(); } + template <> bool is() const { return isInt(); } + + template <> UInt as() const { return asUInt(); } + template <> bool is() const { return isUInt(); } + +#if defined(JSON_HAS_INT64) + template <> Int64 as() const { return asInt64(); } + template <> bool is() const { return isInt64(); } + + template <> UInt64 as() const { return asUInt64(); } + template <> bool is() const { return isUInt64(); } +#endif + + template <> double as() const { return asDouble(); } + template <> bool is() const { return isDouble(); } + + template <> String as() const { return asString(); } + template <> bool is() const { return isString(); } + + /// These `as` specializations are type conversions, and do not have a + /// corresponding `is`. + template <> float as() const { return asFloat(); } + template <> const char* as() const { return asCString(); } +#ifdef JSON_USE_CPPTL + template <> CppTL::ConstString as() const { + return asConstString(); } - - defIsLookupHelper(bool, isBool); - defIsLookupHelper(Int, isInt); - defIsLookupHelper(Int64, isInt64); - defIsLookupHelper(UInt, isUInt); - defIsLookupHelper(UInt64, isUInt64); - defIsLookupHelper(double, isDouble); - defIsLookupHelper(const char*, isString); - defIsLookupHelper(String, isString); - -#undef defIsLookupHelper - - template bool is() const { return isLookupHelper::is(*this); } +#endif bool isConvertibleTo(ValueType other) const; diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index b5f0e60..146aa9a 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -3361,115 +3361,51 @@ int main(int argc, const char* argv[]) { return runner.runCommandLine(argc, argv); } -struct TemplatedAs : JsonTest::TestCase {}; - -JSONTEST_FIXTURE_LOCAL(TemplatedAs, equalBehaviorCString) { - Json::Value json = "hello world"; - JSONTEST_ASSERT_STRING_EQUAL(json.asCString(), json.as()); -} - -JSONTEST_FIXTURE_LOCAL(TemplatedAs, equalBehaviorString) { - Json::Value json = "hello world"; - JSONTEST_ASSERT_STRING_EQUAL(json.asString(), json.as()); -} +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_FIXTURE_LOCAL(TemplatedAs, equalBehaviorConstString) { - Json::Value json = "hello world"; - JSONTEST_ASSERT_STRING_EQUAL(json.asConstString(), - json.as()); -} + JSONTEST_ASSERT_STRING_EQUAL(js.as(), js.asConstString()); #endif - -JSONTEST_FIXTURE_LOCAL(TemplatedAs, equalBehaviorInt) { - Json::Value json = Json::Int(64); - JSONTEST_ASSERT_EQUAL(json.asInt(), json.as()); -} - -JSONTEST_FIXTURE_LOCAL(TemplatedAs, equalBehaviorUInt) { - Json::Value json = Json::UInt(64); - JSONTEST_ASSERT_EQUAL(json.asUInt(), json.as()); -} - + 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) -JSONTEST_FIXTURE_LOCAL(TemplatedAs, equalBehaviorInt64) { - Json::Value json = Json::Int64(64); - JSONTEST_ASSERT_EQUAL(json.asUInt64(), json.as()); -} - -JSONTEST_FIXTURE_LOCAL(TemplatedAs, equalBehaviorUInt64) { - Json::Value json = Json::UInt64(64); - JSONTEST_ASSERT_EQUAL(json.asUInt64(), json.as()); -} + 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(); }); -JSONTEST_FIXTURE_LOCAL(TemplatedAs, equalBehaviorLargestInt) { - Json::Value json = Json::LargestInt(64); - JSONTEST_ASSERT_EQUAL(json.asLargestInt(), json.as()); + 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(); }); } -JSONTEST_FIXTURE_LOCAL(TemplatedAs, equalBehaviorLargestUInt) { - Json::Value json = Json::LargestUInt(64); - JSONTEST_ASSERT_EQUAL(json.asLargestUInt(), json.as()); -} +class MemberTemplateIs : public JsonTest::TestCase {}; -JSONTEST_FIXTURE_LOCAL(TemplatedAs, equalBehaviorFloat) { - Json::Value json = float(69.69); - JSONTEST_ASSERT_EQUAL(json.asFloat(), json.as()); -} - -JSONTEST_FIXTURE_LOCAL(TemplatedAs, equalBehaviorDouble) { - Json::Value json = double(69.69); - JSONTEST_ASSERT_EQUAL(json.asDouble(), json.as()); -} - -JSONTEST_FIXTURE_LOCAL(TemplatedAs, equalBehaviorBool) { - Json::Value jsonTrue = true; - Json::Value jsonFalse = false; - JSONTEST_ASSERT_EQUAL(jsonTrue.asBool(), jsonTrue.as()); - JSONTEST_ASSERT_EQUAL(jsonFalse.asBool(), jsonFalse.as()); -} - -struct TemplatedIs : JsonTest::TestCase {}; - -JSONTEST_FIXTURE_LOCAL(TemplatedIs, equalBehaviorIsBool) { - Json::Value json = true; - JSONTEST_ASSERT_EQUAL(json.isBool(), json.is()); -} - -JSONTEST_FIXTURE_LOCAL(TemplatedIs, equalBehaviorIsInt) { - Json::Value json = 142; - JSONTEST_ASSERT_EQUAL(json.isInt(), json.is()); -} - -JSONTEST_FIXTURE_LOCAL(TemplatedIs, equalBehaviorIsInt64) { - Json::Value json = 142; - JSONTEST_ASSERT_EQUAL(json.isInt64(), json.is()); -} - -JSONTEST_FIXTURE_LOCAL(TemplatedIs, equalBehaviorIsUInt) { - Json::Value json = 142; - JSONTEST_ASSERT_EQUAL(json.isUInt(), json.is()); -} - -JSONTEST_FIXTURE_LOCAL(TemplatedIs, equalBehaviorIsUInt64) { - Json::Value json = 142; - JSONTEST_ASSERT_EQUAL(json.isUInt64(), json.is()); -} - -JSONTEST_FIXTURE_LOCAL(TemplatedIs, equalBehaviorIsDouble) { - Json::Value json = 40.63; - JSONTEST_ASSERT_EQUAL(json.isDouble(), json.is()); -} - -JSONTEST_FIXTURE_LOCAL(TemplatedIs, equalBehaviorIsCString) { - Json::Value json = "hello world"; - JSONTEST_ASSERT_EQUAL(json.isString(), json.is()); -} - -JSONTEST_FIXTURE_LOCAL(TemplatedIs, equalBehaviorIsString) { - Json::Value json = "hello world"; - JSONTEST_ASSERT_EQUAL(json.isString(), json.is()); +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__)