Type trait to check if a class has defined schema for schemer (#5546)

Summary:
Pull Request resolved: https://github.com/facebook/osquery/pull/5546

Recursive formatters require it to support nested classes.

Reviewed By: SAlexandru

Differential Revision: D14683348

fbshipit-source-id: 840a3e32729b07a3407ca6899d0cfaa73ab3afe4
This commit is contained in:
Alexander Kindyakov 2019-04-01 09:22:44 -07:00 committed by Facebook Github Bot
parent b9a78f2388
commit eca9296a88
2 changed files with 63 additions and 0 deletions

View File

@ -8,6 +8,8 @@
#pragma once
#include <type_traits>
namespace osquery {
namespace schemer {
@ -64,5 +66,35 @@ inline void record(Archive& a, KeyType const& key, ValueType& value) {
a.template record<KeyType, ValueType>(key, value);
};
namespace impl {
class DummyArchive {
public:
template <typename KeyType, typename ValueType>
void record(KeyType const& key, ValueType& value);
};
} // namespace impl
/**
* @brief Type trait to check if a type has a defined schema
*/
template <typename Type>
class has_schema {
private:
template <typename T>
static constexpr bool test(
decltype(&T::template discloseSchema<impl::DummyArchive, Type>)) {
return true;
}
template <typename T>
static constexpr bool test(...) {
return false;
}
public:
static constexpr bool value = test<Type>(nullptr);
};
} // namespace schemer
} // namespace osquery

View File

@ -106,5 +106,36 @@ TEST_F(SchemerTests, deserializing) {
EXPECT_EQ(alpha.getCharlie(), 1234 + 1234);
}
class Beta {
public:
template <typename Archive, typename ValueType>
static void discloseSchema(Archive&, ValueType&) {}
};
class Gama {};
TEST_F(SchemerTests, has_schema_static_go) {
static_assert(schemer::has_schema<Alpha>::value,
"expected true, class Alpha has defined schema");
static_assert(schemer::has_schema<Beta>::value,
"expected true, class Beta has defined schema");
}
TEST_F(SchemerTests, has_schema_static_no_go) {
static_assert(!schemer::has_schema<Gama>::value,
"expected false, there is no schema");
static_assert(!schemer::has_schema<int>::value,
"expected false, there is no schema for int as a basic type");
static_assert(
!schemer::has_schema<unsigned>::value,
"expected false, there is no schema for unsigned as a basic type");
static_assert(!schemer::has_schema<float>::value,
"expected false, there is no schema for float as a basic type");
static_assert(!schemer::has_schema<char const*>::value,
"expected false, there is no schema for c string");
static_assert(!schemer::has_schema<std::string>::value,
"expected false, there is no schema for std::string");
}
} // namespace
} // namespace osquery