Merge "Add template type checking for EventMetric."
This commit is contained in:
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user