diff --git a/api/DEPS b/api/DEPS index f23b1b86b2..a86b42f25b 100644 --- a/api/DEPS +++ b/api/DEPS @@ -43,6 +43,7 @@ specific_include_rules = { ".*\.h": [ "+rtc_base/checks.h", "+rtc_base/system/rtc_export.h", + "+rtc_base/system/rtc_export_template.h", "+rtc_base/units/unit_base.h", "+rtc_base/deprecation.h", ], diff --git a/api/stats/rtc_stats.h b/api/stats/rtc_stats.h index 0cfbc06a0f..80a1276417 100644 --- a/api/stats/rtc_stats.h +++ b/api/stats/rtc_stats.h @@ -21,6 +21,7 @@ #include "rtc_base/checks.h" #include "rtc_base/system/rtc_export.h" +#include "rtc_base/system/rtc_export_template.h" namespace webrtc { @@ -267,7 +268,7 @@ class RTCStatsMemberInterface { template const T& cast_to() const { - RTC_DCHECK_EQ(type(), T::kType); + RTC_DCHECK_EQ(type(), T::StaticType()); return static_cast(*this); } @@ -279,15 +280,12 @@ class RTCStatsMemberInterface { bool is_defined_; }; -// Template implementation of |RTCStatsMemberInterface|. Every possible |T| is -// specialized in rtcstats.cc, using a different |T| results in a linker error -// (undefined reference to |kType|). The supported types are the ones described -// by |RTCStatsMemberInterface::Type|. +// Template implementation of |RTCStatsMemberInterface|. +// The supported types are the ones described by +// |RTCStatsMemberInterface::Type|. template class RTC_EXPORT RTCStatsMember : public RTCStatsMemberInterface { public: - static const Type kType; - explicit RTCStatsMember(const char* name) : RTCStatsMemberInterface(name, /*is_defined=*/false), value_() {} RTCStatsMember(const char* name, const T& value) @@ -302,7 +300,8 @@ class RTC_EXPORT RTCStatsMember : public RTCStatsMemberInterface { : RTCStatsMemberInterface(other.name_, other.is_defined_), value_(std::move(other.value_)) {} - Type type() const override { return kType; } + static Type StaticType(); + Type type() const override { return StaticType(); } bool is_sequence() const override; bool is_string() const override; bool is_standardized() const override { return true; } @@ -356,6 +355,35 @@ class RTC_EXPORT RTCStatsMember : public RTCStatsMemberInterface { T value_; }; +#define WEBRTC_DECLARE_RTCSTATSMEMBER(T) \ + template <> \ + RTCStatsMemberInterface::Type RTCStatsMember::StaticType(); \ + template <> \ + bool RTCStatsMember::is_sequence() const; \ + template <> \ + bool RTCStatsMember::is_string() const; \ + template <> \ + std::string RTCStatsMember::ValueToString() const; \ + template <> \ + std::string RTCStatsMember::ValueToJson() const; \ + extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT) \ + RTCStatsMember + +WEBRTC_DECLARE_RTCSTATSMEMBER(bool); +WEBRTC_DECLARE_RTCSTATSMEMBER(int32_t); +WEBRTC_DECLARE_RTCSTATSMEMBER(uint32_t); +WEBRTC_DECLARE_RTCSTATSMEMBER(int64_t); +WEBRTC_DECLARE_RTCSTATSMEMBER(uint64_t); +WEBRTC_DECLARE_RTCSTATSMEMBER(double); +WEBRTC_DECLARE_RTCSTATSMEMBER(std::string); +WEBRTC_DECLARE_RTCSTATSMEMBER(std::vector); +WEBRTC_DECLARE_RTCSTATSMEMBER(std::vector); +WEBRTC_DECLARE_RTCSTATSMEMBER(std::vector); +WEBRTC_DECLARE_RTCSTATSMEMBER(std::vector); +WEBRTC_DECLARE_RTCSTATSMEMBER(std::vector); +WEBRTC_DECLARE_RTCSTATSMEMBER(std::vector); +WEBRTC_DECLARE_RTCSTATSMEMBER(std::vector); + // Using inheritance just so that it's obvious from the member's declaration // whether it's standardized or not. template diff --git a/stats/rtc_stats.cc b/stats/rtc_stats.cc index f5139a7dbb..92f64e4654 100644 --- a/stats/rtc_stats.cc +++ b/stats/rtc_stats.cc @@ -128,8 +128,9 @@ RTCStats::MembersOfThisObjectAndAncestors(size_t additional_capacity) const { #define WEBRTC_DEFINE_RTCSTATSMEMBER(T, type, is_seq, is_str, to_str, to_json) \ template <> \ - const RTCStatsMemberInterface::Type RTCStatsMember::kType = \ - RTCStatsMemberInterface::type; \ + RTCStatsMemberInterface::Type RTCStatsMember::StaticType() { \ + return type; \ + } \ template <> \ bool RTCStatsMember::is_sequence() const { \ return is_seq; \ @@ -147,86 +148,87 @@ RTCStats::MembersOfThisObjectAndAncestors(size_t additional_capacity) const { std::string RTCStatsMember::ValueToJson() const { \ RTC_DCHECK(is_defined_); \ return to_json; \ - } + } \ + template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT) RTCStatsMember WEBRTC_DEFINE_RTCSTATSMEMBER(bool, kBool, false, false, rtc::ToString(value_), - rtc::ToString(value_)) + rtc::ToString(value_)); WEBRTC_DEFINE_RTCSTATSMEMBER(int32_t, kInt32, false, false, rtc::ToString(value_), - rtc::ToString(value_)) + rtc::ToString(value_)); WEBRTC_DEFINE_RTCSTATSMEMBER(uint32_t, kUint32, false, false, rtc::ToString(value_), - rtc::ToString(value_)) + rtc::ToString(value_)); WEBRTC_DEFINE_RTCSTATSMEMBER(int64_t, kInt64, false, false, rtc::ToString(value_), - ToStringAsDouble(value_)) + ToStringAsDouble(value_)); WEBRTC_DEFINE_RTCSTATSMEMBER(uint64_t, kUint64, false, false, rtc::ToString(value_), - ToStringAsDouble(value_)) + ToStringAsDouble(value_)); WEBRTC_DEFINE_RTCSTATSMEMBER(double, kDouble, false, false, rtc::ToString(value_), - ToStringAsDouble(value_)) -WEBRTC_DEFINE_RTCSTATSMEMBER(std::string, kString, false, true, value_, value_) + ToStringAsDouble(value_)); +WEBRTC_DEFINE_RTCSTATSMEMBER(std::string, kString, false, true, value_, value_); WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector, kSequenceBool, true, false, VectorToString(value_), - VectorToString(value_)) + VectorToString(value_)); WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector, kSequenceInt32, true, false, VectorToString(value_), - VectorToString(value_)) + VectorToString(value_)); WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector, kSequenceUint32, true, false, VectorToString(value_), - VectorToString(value_)) + VectorToString(value_)); WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector, kSequenceInt64, true, false, VectorToString(value_), - VectorToStringAsDouble(value_)) + VectorToStringAsDouble(value_)); WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector, kSequenceUint64, true, false, VectorToString(value_), - VectorToStringAsDouble(value_)) + VectorToStringAsDouble(value_)); WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector, kSequenceDouble, true, false, VectorToString(value_), - VectorToStringAsDouble(value_)) + VectorToStringAsDouble(value_)); WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector, kSequenceString, true, false, VectorOfStringsToString(value_), - VectorOfStringsToString(value_)) + VectorOfStringsToString(value_)); } // namespace webrtc