Merge "Add template type checking for EventMetric."

This commit is contained in:
Adam Stone
2017-06-28 01:15:58 +00:00
committed by Android (Google) Code Review

View File

@@ -238,20 +238,57 @@ inline void AppendFieldNames(std::vector<std::string>* field_name_vector,
va_end(field_names); va_end(field_names);
} }
// These helper methods and FirstUnusedType assure that there is no mismatch
// between the specified types for EventMetrics and the constructors and
// methods used for the specializations.
template <bool>
struct CompileAssert {};
#define COMPILE_ASSERT(expr, msg) \
typedef impl::CompileAssert<(bool(expr))> msg[bool(expr) ? 1 : -1]
template <typename T> struct is_unused { static const bool value = false; };
template <> struct is_unused<Unused> { static const bool value = true; };
template <typename F1, typename F2, typename F3, typename F4>
class FirstUnusedType {
static const bool a = is_unused<F1>::value;
static const bool b = is_unused<F2>::value;
static const bool c = is_unused<F3>::value;
static const bool d = is_unused<F4>::value;
// Check that all types after the first Unused are also Unused.
COMPILE_ASSERT(a <= b, Invalid_Unused_At_Position_2);
COMPILE_ASSERT(b <= c, Invalid_Unused_At_Position_3);
COMPILE_ASSERT(c <= d, Invalid_Unused_At_Position_4);
public:
static const int value = 5 - (a + b + c + d);
};
// Asserts that no Unused types exist before N; after N, are all Unused types.
#define ASSERT_METRIC_UNUSED_START_FROM(N) \
COMPILE_ASSERT((\
impl::FirstUnusedType<F1, F2, F3, F4>::value) == N, \
Unused_Start_From_##N)
} // namespace impl } // namespace impl
// Overloaded template constructor implementations for EventMetric. // Overloaded template constructor implementations for EventMetric.
template<typename F1, typename F2, typename F3, typename F4> template<typename F1, typename F2, typename F3, typename F4>
EventMetric<F1, F2, F3, F4>::EventMetric( EventMetric<F1, F2, F3, F4>::EventMetric(
const std::string& metric_name) const std::string& metric_name)
: BaseEventMetric(metric_name) {} : BaseEventMetric(metric_name) {
ASSERT_METRIC_UNUSED_START_FROM(1);
}
template<typename F1, typename F2, typename F3, typename F4> template<typename F1, typename F2, typename F3, typename F4>
EventMetric<F1, F2, F3, F4>::EventMetric( EventMetric<F1, F2, F3, F4>::EventMetric(
const std::string& metric_name, const std::string& metric_name,
const char* field_name) const char* field_name)
: BaseEventMetric(metric_name) { : BaseEventMetric(metric_name) {
impl::AppendFieldNames(&field_names_, 1, field_name); ASSERT_METRIC_UNUSED_START_FROM(2);
impl::AppendFieldNames(&field_names_,
impl::FirstUnusedType<F1, F2, F3, F4>::value - 1,
field_name);
} }
template<typename F1, typename F2, typename F3, typename F4> template<typename F1, typename F2, typename F3, typename F4>
EventMetric<F1, F2, F3, F4>::EventMetric( EventMetric<F1, F2, F3, F4>::EventMetric(
@@ -259,7 +296,10 @@ EventMetric<F1, F2, F3, F4>::EventMetric(
const char* field_name1, const char* field_name1,
const char* field_name2) const char* field_name2)
: BaseEventMetric(metric_name) { : BaseEventMetric(metric_name) {
impl::AppendFieldNames(&field_names_, 2, field_name1, field_name2); ASSERT_METRIC_UNUSED_START_FROM(3);
impl::AppendFieldNames(&field_names_,
impl::FirstUnusedType<F1, F2, F3, F4>::value - 1,
field_name1, field_name2);
} }
template<typename F1, typename F2, typename F3, typename F4> template<typename F1, typename F2, typename F3, typename F4>
EventMetric<F1, F2, F3, F4>::EventMetric( EventMetric<F1, F2, F3, F4>::EventMetric(
@@ -268,8 +308,10 @@ EventMetric<F1, F2, F3, F4>::EventMetric(
const char* field_name2, const char* field_name2,
const char* field_name3) const char* field_name3)
: BaseEventMetric(metric_name) { : BaseEventMetric(metric_name) {
ASSERT_METRIC_UNUSED_START_FROM(4);
impl::AppendFieldNames(&field_names_, impl::AppendFieldNames(&field_names_,
3, field_name1, field_name2, field_name3); impl::FirstUnusedType<F1, F2, F3, F4>::value - 1,
field_name1, field_name2, field_name3);
} }
template<typename F1, typename F2, typename F3, typename F4> template<typename F1, typename F2, typename F3, typename F4>
EventMetric<F1, F2, F3, F4>::EventMetric( EventMetric<F1, F2, F3, F4>::EventMetric(
@@ -279,8 +321,10 @@ EventMetric<F1, F2, F3, F4>::EventMetric(
const char* field_name3, const char* field_name3,
const char* field_name4) const char* field_name4)
: BaseEventMetric(metric_name) { : BaseEventMetric(metric_name) {
ASSERT_METRIC_UNUSED_START_FROM(5);
impl::AppendFieldNames(&field_names_, impl::AppendFieldNames(&field_names_,
4, field_name1, field_name2, impl::FirstUnusedType<F1, F2, F3, F4>::value - 1,
field_name1, field_name2,
field_name3, field_name4); field_name3, field_name4);
} }