diff --git a/api/stats/attribute.h b/api/stats/attribute.h index 3f6d058b0e..bc5bdedde1 100644 --- a/api/stats/attribute.h +++ b/api/stats/attribute.h @@ -53,6 +53,18 @@ class RTC_EXPORT Attribute : public RTCStatsMemberInterface { const char* name() const; const StatVariant& as_variant() const; + bool has_value() const; + template + bool holds_alternative() const { + return absl::holds_alternative*>(attribute_); + } + template + const T& get() const { + RTC_CHECK(holds_alternative()); + RTC_CHECK(has_value()); + return absl::get*>(attribute_)->value(); + } + static Attribute FromMemberInterface(const RTCStatsMemberInterface* member); // RTCStatsMemberInterface implementation. // TODO(https://crbug.com/webrtc/15164): Delete RTCStatsMemberInterface in diff --git a/stats/attribute.cc b/stats/attribute.cc index 36cdc454f4..b2e2986e50 100644 --- a/stats/attribute.cc +++ b/stats/attribute.cc @@ -99,6 +99,11 @@ const Attribute::StatVariant& Attribute::as_variant() const { return attribute_; } +bool Attribute::has_value() const { + return absl::visit([](const auto* attr) { return attr->has_value(); }, + attribute_); +} + RTCStatsMemberInterface::Type Attribute::type() const { return absl::visit([](const auto* attr) { return attr->type(); }, attribute_); } diff --git a/stats/rtc_stats.cc b/stats/rtc_stats.cc index 398987fd7b..e6a1854d98 100644 --- a/stats/rtc_stats.cc +++ b/stats/rtc_stats.cc @@ -24,16 +24,13 @@ RTCStats::~RTCStats() {} bool RTCStats::operator==(const RTCStats& other) const { if (type() != other.type() || id() != other.id()) return false; - std::vector members = Members(); - std::vector other_members = other.Members(); - RTC_DCHECK_EQ(members.size(), other_members.size()); - for (size_t i = 0; i < members.size(); ++i) { - const RTCStatsMemberInterface* member = members[i]; - const RTCStatsMemberInterface* other_member = other_members[i]; - RTC_DCHECK_EQ(member->type(), other_member->type()); - RTC_DCHECK_EQ(member->name(), other_member->name()); - if (*member != *other_member) + std::vector attributes = Attributes(); + std::vector other_attributes = other.Attributes(); + RTC_DCHECK_EQ(attributes.size(), other_attributes.size()); + for (size_t i = 0; i < attributes.size(); ++i) { + if (attributes[i] != other_attributes[i]) { return false; + } } return true; } @@ -51,13 +48,17 @@ std::string RTCStats::ToJson() const { << "\"," "\"timestamp\":" << timestamp_.us(); - for (const RTCStatsMemberInterface* member : Members()) { - if (member->is_defined()) { - sb << ",\"" << member->name() << "\":"; - if (member->is_string()) - sb << "\"" << member->ValueToJson() << "\""; - else - sb << member->ValueToJson(); + for (const Attribute& attribute : Attributes()) { + if (attribute.has_value()) { + sb << ",\"" << attribute.name() << "\":"; + if (attribute.holds_alternative()) { + sb << "\""; + } + sb << absl::visit([](const auto* attr) { return attr->ValueToJson(); }, + attribute.as_variant()); + if (attribute.holds_alternative()) { + sb << "\""; + } } } sb << "}"; diff --git a/stats/rtc_stats_unittest.cc b/stats/rtc_stats_unittest.cc index 249491effd..b26436f491 100644 --- a/stats/rtc_stats_unittest.cc +++ b/stats/rtc_stats_unittest.cc @@ -66,14 +66,14 @@ WEBRTC_RTCSTATS_IMPL(RTCGrandChildStats, "grandchild-stats", &grandchild_int) -TEST(RTCStatsTest, RTCStatsAndMembers) { +TEST(RTCStatsTest, RTCStatsAndAttributes) { RTCTestStats stats("testId", Timestamp::Micros(42)); EXPECT_EQ(stats.id(), "testId"); EXPECT_EQ(stats.timestamp().us(), static_cast(42)); - std::vector members = stats.Members(); - EXPECT_EQ(members.size(), static_cast(16)); - for (const RTCStatsMemberInterface* member : members) { - EXPECT_FALSE(member->is_defined()); + std::vector attributes = stats.Attributes(); + EXPECT_EQ(attributes.size(), static_cast(16)); + for (const auto& attribute : attributes) { + EXPECT_FALSE(attribute.has_value()); } stats.m_bool = true; stats.m_int32 = 123; @@ -111,8 +111,8 @@ TEST(RTCStatsTest, RTCStatsAndMembers) { stats.m_sequence_string = sequence_string; stats.m_map_string_uint64 = map_string_uint64; stats.m_map_string_double = map_string_double; - for (const RTCStatsMemberInterface* member : members) { - EXPECT_TRUE(member->is_defined()); + for (const auto& attribute : attributes) { + EXPECT_TRUE(attribute.has_value()); } EXPECT_EQ(*stats.m_bool, true); EXPECT_EQ(*stats.m_int32, static_cast(123)); @@ -217,8 +217,8 @@ TEST(RTCStatsTest, RTCStatsGrandChild) { stats.child_int = 1; stats.grandchild_int = 2; int32_t sum = 0; - for (const RTCStatsMemberInterface* member : stats.Members()) { - sum += *member->cast_to>(); + for (const auto& attribute : stats.Attributes()) { + sum += attribute.get(); } EXPECT_EQ(sum, static_cast(3));