diff --git a/libwvdrmengine/cdm/metrics/include/event_metric.h b/libwvdrmengine/cdm/metrics/include/event_metric.h index 61012fa2..4e81ad62 100644 --- a/libwvdrmengine/cdm/metrics/include/event_metric.h +++ b/libwvdrmengine/cdm/metrics/include/event_metric.h @@ -238,20 +238,57 @@ inline void AppendFieldNames(std::vector* field_name_vector, 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 +struct CompileAssert {}; +#define COMPILE_ASSERT(expr, msg) \ + typedef impl::CompileAssert<(bool(expr))> msg[bool(expr) ? 1 : -1] + +template struct is_unused { static const bool value = false; }; +template <> struct is_unused { static const bool value = true; }; + +template +class FirstUnusedType { + static const bool a = is_unused::value; + static const bool b = is_unused::value; + static const bool c = is_unused::value; + static const bool d = is_unused::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::value) == N, \ + Unused_Start_From_##N) + } // namespace impl // Overloaded template constructor implementations for EventMetric. template EventMetric::EventMetric( const std::string& metric_name) - : BaseEventMetric(metric_name) {} + : BaseEventMetric(metric_name) { + ASSERT_METRIC_UNUSED_START_FROM(1); +} template EventMetric::EventMetric( const std::string& metric_name, const char* field_name) : BaseEventMetric(metric_name) { - impl::AppendFieldNames(&field_names_, 1, field_name); + ASSERT_METRIC_UNUSED_START_FROM(2); + impl::AppendFieldNames(&field_names_, + impl::FirstUnusedType::value - 1, + field_name); } template EventMetric::EventMetric( @@ -259,7 +296,10 @@ EventMetric::EventMetric( const char* field_name1, const char* field_name2) : BaseEventMetric(metric_name) { - impl::AppendFieldNames(&field_names_, 2, field_name1, field_name2); + ASSERT_METRIC_UNUSED_START_FROM(3); + impl::AppendFieldNames(&field_names_, + impl::FirstUnusedType::value - 1, + field_name1, field_name2); } template EventMetric::EventMetric( @@ -268,8 +308,10 @@ EventMetric::EventMetric( const char* field_name2, const char* field_name3) : BaseEventMetric(metric_name) { + ASSERT_METRIC_UNUSED_START_FROM(4); impl::AppendFieldNames(&field_names_, - 3, field_name1, field_name2, field_name3); + impl::FirstUnusedType::value - 1, + field_name1, field_name2, field_name3); } template EventMetric::EventMetric( @@ -279,8 +321,10 @@ EventMetric::EventMetric( const char* field_name3, const char* field_name4) : BaseEventMetric(metric_name) { + ASSERT_METRIC_UNUSED_START_FROM(5); impl::AppendFieldNames(&field_names_, - 4, field_name1, field_name2, + impl::FirstUnusedType::value - 1, + field_name1, field_name2, field_name3, field_name4); }