Remove macros and prune some overloads. (#1066)

Combine is<T> tests and combine as<T> tests.
This commit is contained in:
Billy Donahue 2019-11-03 11:40:34 -05:00
parent a2117e01d3
commit 4e02630e32
2 changed files with 70 additions and 144 deletions

View File

@ -399,33 +399,6 @@ public:
double asDouble() const;
bool asBool() const;
template <class T> struct asLookupHelper;
#define defAsLookupHelper(type, lookup) \
template <> struct asLookupHelper<type> { \
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 <class T> T as() const { return asLookupHelper<T>::as(*this); }
bool isNull() const;
bool isBool() const;
bool isInt() const;
@ -439,25 +412,42 @@ public:
bool isArray() const;
bool isObject() const;
template <class T> struct isLookupHelper;
/// The `as<T>` and `is<T>` member function templates and specializations.
template <typename T> T as() const = delete;
template <typename T> bool is() const = delete;
#define defIsLookupHelper(type, lookup) \
template <> struct isLookupHelper<type> { \
static bool is(const Value& val) { return val.lookup(); } \
template <> bool as<bool>() const { return asBool(); }
template <> bool is<bool>() const { return isBool(); }
template <> Int as<Int>() const { return asInt(); }
template <> bool is<Int>() const { return isInt(); }
template <> UInt as<UInt>() const { return asUInt(); }
template <> bool is<UInt>() const { return isUInt(); }
#if defined(JSON_HAS_INT64)
template <> Int64 as<Int64>() const { return asInt64(); }
template <> bool is<Int64>() const { return isInt64(); }
template <> UInt64 as<UInt64>() const { return asUInt64(); }
template <> bool is<UInt64>() const { return isUInt64(); }
#endif
template <> double as<double>() const { return asDouble(); }
template <> bool is<double>() const { return isDouble(); }
template <> String as<String>() const { return asString(); }
template <> bool is<String>() const { return isString(); }
/// These `as` specializations are type conversions, and do not have a
/// corresponding `is`.
template <> float as<float>() const { return asFloat(); }
template <> const char* as<const char*>() const { return asCString(); }
#ifdef JSON_USE_CPPTL
template <> CppTL::ConstString as<CppTL::ConstString>() 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 <class T> bool is() const { return isLookupHelper<T>::is(*this); }
#endif
bool isConvertibleTo(ValueType other) const;

View File

@ -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<const char*>());
}
JSONTEST_FIXTURE_LOCAL(TemplatedAs, equalBehaviorString) {
Json::Value json = "hello world";
JSONTEST_ASSERT_STRING_EQUAL(json.asString(), json.as<Json::String>());
}
struct MemberTemplateAs : JsonTest::TestCase {
template <typename T, typename F>
JsonTest::TestResult& EqEval(T v, F f) const {
const Json::Value j = v;
return JSONTEST_ASSERT_EQUAL(j.as<T>(), f(j));
}
};
JSONTEST_FIXTURE_LOCAL(MemberTemplateAs, BehavesSameAsNamedAs) {
const Json::Value jstr = "hello world";
JSONTEST_ASSERT_STRING_EQUAL(jstr.as<const char*>(), jstr.asCString());
JSONTEST_ASSERT_STRING_EQUAL(jstr.as<Json::String>(), jstr.asString());
#ifdef JSON_USE_CPPTL
JSONTEST_FIXTURE_LOCAL(TemplatedAs, equalBehaviorConstString) {
Json::Value json = "hello world";
JSONTEST_ASSERT_STRING_EQUAL(json.asConstString(),
json.as<CppTL::ConstString>());
}
JSONTEST_ASSERT_STRING_EQUAL(js.as<CppTL::ConstString>(), js.asConstString());
#endif
JSONTEST_FIXTURE_LOCAL(TemplatedAs, equalBehaviorInt) {
Json::Value json = Json::Int(64);
JSONTEST_ASSERT_EQUAL(json.asInt(), json.as<Json::Int>());
}
JSONTEST_FIXTURE_LOCAL(TemplatedAs, equalBehaviorUInt) {
Json::Value json = Json::UInt(64);
JSONTEST_ASSERT_EQUAL(json.asUInt(), json.as<Json::UInt>());
}
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<Json::Int64>());
}
JSONTEST_FIXTURE_LOCAL(TemplatedAs, equalBehaviorUInt64) {
Json::Value json = Json::UInt64(64);
JSONTEST_ASSERT_EQUAL(json.asUInt64(), json.as<Json::UInt64>());
}
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<Json::LargestInt>());
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<Json::LargestUInt>());
}
class MemberTemplateIs : public JsonTest::TestCase {};
JSONTEST_FIXTURE_LOCAL(TemplatedAs, equalBehaviorFloat) {
Json::Value json = float(69.69);
JSONTEST_ASSERT_EQUAL(json.asFloat(), json.as<float>());
}
JSONTEST_FIXTURE_LOCAL(TemplatedAs, equalBehaviorDouble) {
Json::Value json = double(69.69);
JSONTEST_ASSERT_EQUAL(json.asDouble(), json.as<double>());
}
JSONTEST_FIXTURE_LOCAL(TemplatedAs, equalBehaviorBool) {
Json::Value jsonTrue = true;
Json::Value jsonFalse = false;
JSONTEST_ASSERT_EQUAL(jsonTrue.asBool(), jsonTrue.as<bool>());
JSONTEST_ASSERT_EQUAL(jsonFalse.asBool(), jsonFalse.as<bool>());
}
struct TemplatedIs : JsonTest::TestCase {};
JSONTEST_FIXTURE_LOCAL(TemplatedIs, equalBehaviorIsBool) {
Json::Value json = true;
JSONTEST_ASSERT_EQUAL(json.isBool(), json.is<bool>());
}
JSONTEST_FIXTURE_LOCAL(TemplatedIs, equalBehaviorIsInt) {
Json::Value json = 142;
JSONTEST_ASSERT_EQUAL(json.isInt(), json.is<Json::Int>());
}
JSONTEST_FIXTURE_LOCAL(TemplatedIs, equalBehaviorIsInt64) {
Json::Value json = 142;
JSONTEST_ASSERT_EQUAL(json.isInt64(), json.is<Json::Int64>());
}
JSONTEST_FIXTURE_LOCAL(TemplatedIs, equalBehaviorIsUInt) {
Json::Value json = 142;
JSONTEST_ASSERT_EQUAL(json.isUInt(), json.is<Json::UInt>());
}
JSONTEST_FIXTURE_LOCAL(TemplatedIs, equalBehaviorIsUInt64) {
Json::Value json = 142;
JSONTEST_ASSERT_EQUAL(json.isUInt64(), json.is<Json::UInt64>());
}
JSONTEST_FIXTURE_LOCAL(TemplatedIs, equalBehaviorIsDouble) {
Json::Value json = 40.63;
JSONTEST_ASSERT_EQUAL(json.isDouble(), json.is<double>());
}
JSONTEST_FIXTURE_LOCAL(TemplatedIs, equalBehaviorIsCString) {
Json::Value json = "hello world";
JSONTEST_ASSERT_EQUAL(json.isString(), json.is<const char*>());
}
JSONTEST_FIXTURE_LOCAL(TemplatedIs, equalBehaviorIsString) {
Json::Value json = "hello world";
JSONTEST_ASSERT_EQUAL(json.isString(), json.is<Json::String>());
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<bool>(), j.isBool());
JSONTEST_ASSERT_EQUAL(j.is<Json::Int>(), j.isInt());
JSONTEST_ASSERT_EQUAL(j.is<Json::Int64>(), j.isInt64());
JSONTEST_ASSERT_EQUAL(j.is<Json::UInt>(), j.isUInt());
JSONTEST_ASSERT_EQUAL(j.is<Json::UInt64>(), j.isUInt64());
JSONTEST_ASSERT_EQUAL(j.is<double>(), j.isDouble());
JSONTEST_ASSERT_EQUAL(j.is<Json::String>(), j.isString());
}
}
#if defined(__GNUC__)