blob: 2af9768a99b5f276349ac1b27be595b2b3bebb7f [file] [log] [blame]
hbos74e1a4f2016-09-15 23:33:01 -07001/*
2 * Copyright 2016 The WebRTC Project Authors. All rights reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
Steve Anton10542f22019-01-11 09:11:00 -080011#ifndef API_STATS_RTC_STATS_H_
12#define API_STATS_RTC_STATS_H_
hbos74e1a4f2016-09-15 23:33:01 -070013
Yves Gerey3e707812018-11-28 16:47:49 +010014#include <stddef.h>
15#include <stdint.h>
Jonas Olssona4d87372019-07-05 19:08:33 +020016
Byoungchan Lee0a52ede2021-05-22 08:41:02 +090017#include <map>
hbos74e1a4f2016-09-15 23:33:01 -070018#include <memory>
19#include <string>
20#include <utility>
21#include <vector>
22
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020023#include "rtc_base/checks.h"
Mirko Bonadei276827c2018-10-16 14:13:50 +020024#include "rtc_base/system/rtc_export.h"
Mirko Bonadei054f1852019-11-04 16:31:08 +010025#include "rtc_base/system/rtc_export_template.h"
hbos74e1a4f2016-09-15 23:33:01 -070026
27namespace webrtc {
28
29class RTCStatsMemberInterface;
30
31// Abstract base class for RTCStats-derived dictionaries, see
32// https://w3c.github.io/webrtc-stats/.
33//
34// All derived classes must have the following static variable defined:
35// static const char kType[];
36// It is used as a unique class identifier and a string representation of the
37// class type, see https://w3c.github.io/webrtc-stats/#rtcstatstype-str*.
Artem Titov0e61fdd2021-07-25 21:50:14 +020038// Use the `WEBRTC_RTCSTATS_IMPL` macro when implementing subclasses, see macro
hbos74e1a4f2016-09-15 23:33:01 -070039// for details.
40//
41// Derived classes list their dictionary members, RTCStatsMember<T>, as public
42// fields, allowing the following:
43//
44// RTCFooStats foo("fooId", GetCurrentTime());
45// foo.bar = 42;
46// foo.baz = std::vector<std::string>();
47// foo.baz->push_back("hello world");
48// uint32_t x = *foo.bar;
49//
Artem Titov0e61fdd2021-07-25 21:50:14 +020050// Pointers to all the members are available with `Members`, allowing iteration:
hbos74e1a4f2016-09-15 23:33:01 -070051//
52// for (const RTCStatsMemberInterface* member : foo.Members()) {
53// printf("%s = %s\n", member->name(), member->ValueToString().c_str());
54// }
Mirko Bonadei276827c2018-10-16 14:13:50 +020055class RTC_EXPORT RTCStats {
hbos74e1a4f2016-09-15 23:33:01 -070056 public:
57 RTCStats(const std::string& id, int64_t timestamp_us)
58 : id_(id), timestamp_us_(timestamp_us) {}
59 RTCStats(std::string&& id, int64_t timestamp_us)
60 : id_(std::move(id)), timestamp_us_(timestamp_us) {}
61 virtual ~RTCStats() {}
62
63 virtual std::unique_ptr<RTCStats> copy() const = 0;
64
65 const std::string& id() const { return id_; }
66 // Time relative to the UNIX epoch (Jan 1, 1970, UTC), in microseconds.
67 int64_t timestamp_us() const { return timestamp_us_; }
Artem Titov0e61fdd2021-07-25 21:50:14 +020068 // Returns the static member variable `kType` of the implementing class.
hbos74e1a4f2016-09-15 23:33:01 -070069 virtual const char* type() const = 0;
Artem Titov0e61fdd2021-07-25 21:50:14 +020070 // Returns a vector of pointers to all the `RTCStatsMemberInterface` members
hbos67c8bc42016-10-25 04:31:23 -070071 // of this class. This allows for iteration of members. For a given class,
Artem Titov0e61fdd2021-07-25 21:50:14 +020072 // `Members` always returns the same members in the same order.
hbos74e1a4f2016-09-15 23:33:01 -070073 std::vector<const RTCStatsMemberInterface*> Members() const;
hbos67c8bc42016-10-25 04:31:23 -070074 // Checks if the two stats objects are of the same type and have the same
hbos0583b282016-11-30 01:50:14 -080075 // member values. Timestamps are not compared. These operators are exposed for
76 // testing.
hbos67c8bc42016-10-25 04:31:23 -070077 bool operator==(const RTCStats& other) const;
78 bool operator!=(const RTCStats& other) const;
hbos74e1a4f2016-09-15 23:33:01 -070079
ehmaldonado35a872c2017-07-28 07:29:12 -070080 // Creates a JSON readable string representation of the stats
81 // object, listing all of its members (names and values).
82 std::string ToJson() const;
hbos74e1a4f2016-09-15 23:33:01 -070083
Artem Titov0e61fdd2021-07-25 21:50:14 +020084 // Downcasts the stats object to an `RTCStats` subclass `T`. DCHECKs that the
85 // object is of type `T`.
Yves Gerey665174f2018-06-19 15:03:05 +020086 template <typename T>
hbos74e1a4f2016-09-15 23:33:01 -070087 const T& cast_to() const {
88 RTC_DCHECK_EQ(type(), T::kType);
89 return static_cast<const T&>(*this);
90 }
91
92 protected:
Artem Titov0e61fdd2021-07-25 21:50:14 +020093 // Gets a vector of all members of this `RTCStats` object, including members
94 // derived from parent classes. `additional_capacity` is how many more members
hbos74e1a4f2016-09-15 23:33:01 -070095 // shall be reserved in the vector (so that subclasses can allocate a vector
96 // with room for both parent and child members without it having to resize).
97 virtual std::vector<const RTCStatsMemberInterface*>
Yves Gerey665174f2018-06-19 15:03:05 +020098 MembersOfThisObjectAndAncestors(size_t additional_capacity) const;
hbos74e1a4f2016-09-15 23:33:01 -070099
100 std::string const id_;
101 int64_t timestamp_us_;
102};
103
Artem Titov0e61fdd2021-07-25 21:50:14 +0200104// All `RTCStats` classes should use these macros.
105// `WEBRTC_RTCSTATS_DECL` is placed in a public section of the class definition.
106// `WEBRTC_RTCSTATS_IMPL` is placed outside the class definition (in a .cc).
hbos74e1a4f2016-09-15 23:33:01 -0700107//
Artem Titov0e61fdd2021-07-25 21:50:14 +0200108// These macros declare (in _DECL) and define (in _IMPL) the static `kType` and
109// overrides methods as required by subclasses of `RTCStats`: `copy`, `type` and
110// `MembersOfThisObjectAndAncestors`. The |...| argument is a list of addresses
hbosfc5e0502016-10-06 02:06:10 -0700111// to each member defined in the implementing class. The list must have at least
112// one member.
hbos74e1a4f2016-09-15 23:33:01 -0700113//
114// (Since class names need to be known to implement these methods this cannot be
Artem Titov0e61fdd2021-07-25 21:50:14 +0200115// part of the base `RTCStats`. While these methods could be implemented using
hbos74e1a4f2016-09-15 23:33:01 -0700116// templates, that would only work for immediate subclasses. Subclasses of
117// subclasses also have to override these methods, resulting in boilerplate
Artem Titov0e61fdd2021-07-25 21:50:14 +0200118// code. Using a macro avoids this and works for any `RTCStats` class, including
hbos74e1a4f2016-09-15 23:33:01 -0700119// grandchildren.)
120//
121// Sample usage:
122//
123// rtcfoostats.h:
124// class RTCFooStats : public RTCStats {
125// public:
hbosfc5e0502016-10-06 02:06:10 -0700126// WEBRTC_RTCSTATS_DECL();
hbos74e1a4f2016-09-15 23:33:01 -0700127//
hbosfc5e0502016-10-06 02:06:10 -0700128// RTCFooStats(const std::string& id, int64_t timestamp_us);
hbos74e1a4f2016-09-15 23:33:01 -0700129//
130// RTCStatsMember<int32_t> foo;
131// RTCStatsMember<int32_t> bar;
132// };
133//
134// rtcfoostats.cc:
hbosfc5e0502016-10-06 02:06:10 -0700135// WEBRTC_RTCSTATS_IMPL(RTCFooStats, RTCStats, "foo-stats"
136// &foo,
137// &bar);
hbos74e1a4f2016-09-15 23:33:01 -0700138//
hbosfc5e0502016-10-06 02:06:10 -0700139// RTCFooStats::RTCFooStats(const std::string& id, int64_t timestamp_us)
140// : RTCStats(id, timestamp_us),
141// foo("foo"),
142// bar("bar") {
143// }
144//
Yves Gerey665174f2018-06-19 15:03:05 +0200145#define WEBRTC_RTCSTATS_DECL() \
Yves Gerey665174f2018-06-19 15:03:05 +0200146 protected: \
147 std::vector<const webrtc::RTCStatsMemberInterface*> \
148 MembersOfThisObjectAndAncestors(size_t local_var_additional_capacity) \
149 const override; \
150 \
Nico Weber22f99252019-02-20 10:13:16 -0500151 public: \
152 static const char kType[]; \
153 \
154 std::unique_ptr<webrtc::RTCStats> copy() const override; \
155 const char* type() const override
hbosfc5e0502016-10-06 02:06:10 -0700156
157#define WEBRTC_RTCSTATS_IMPL(this_class, parent_class, type_str, ...) \
158 const char this_class::kType[] = type_str; \
159 \
160 std::unique_ptr<webrtc::RTCStats> this_class::copy() const { \
Philipp Hanckeb5cf12d2022-09-06 11:55:31 +0200161 return std::make_unique<this_class>(*this); \
hbosfc5e0502016-10-06 02:06:10 -0700162 } \
163 \
Yves Gerey665174f2018-06-19 15:03:05 +0200164 const char* this_class::type() const { return this_class::kType; } \
hbosfc5e0502016-10-06 02:06:10 -0700165 \
166 std::vector<const webrtc::RTCStatsMemberInterface*> \
167 this_class::MembersOfThisObjectAndAncestors( \
168 size_t local_var_additional_capacity) const { \
hbos74e1a4f2016-09-15 23:33:01 -0700169 const webrtc::RTCStatsMemberInterface* local_var_members[] = { \
Yves Gerey665174f2018-06-19 15:03:05 +0200170 __VA_ARGS__}; \
hbos74e1a4f2016-09-15 23:33:01 -0700171 size_t local_var_members_count = \
172 sizeof(local_var_members) / sizeof(local_var_members[0]); \
Yves Gerey665174f2018-06-19 15:03:05 +0200173 std::vector<const webrtc::RTCStatsMemberInterface*> \
174 local_var_members_vec = parent_class::MembersOfThisObjectAndAncestors( \
hbos74e1a4f2016-09-15 23:33:01 -0700175 local_var_members_count + local_var_additional_capacity); \
176 RTC_DCHECK_GE( \
177 local_var_members_vec.capacity() - local_var_members_vec.size(), \
178 local_var_members_count + local_var_additional_capacity); \
179 local_var_members_vec.insert(local_var_members_vec.end(), \
180 &local_var_members[0], \
181 &local_var_members[local_var_members_count]); \
182 return local_var_members_vec; \
hbosfc5e0502016-10-06 02:06:10 -0700183 }
hbos74e1a4f2016-09-15 23:33:01 -0700184
Henrik Boström646fda02019-05-22 15:49:42 +0200185// A version of WEBRTC_RTCSTATS_IMPL() where "..." is omitted, used to avoid a
186// compile error on windows. This is used if the stats dictionary does not
187// declare any members of its own (but perhaps its parent dictionary does).
188#define WEBRTC_RTCSTATS_IMPL_NO_MEMBERS(this_class, parent_class, type_str) \
189 const char this_class::kType[] = type_str; \
190 \
191 std::unique_ptr<webrtc::RTCStats> this_class::copy() const { \
Philipp Hanckeb5cf12d2022-09-06 11:55:31 +0200192 return std::make_unique<this_class>(*this); \
Henrik Boström646fda02019-05-22 15:49:42 +0200193 } \
194 \
195 const char* this_class::type() const { return this_class::kType; } \
196 \
197 std::vector<const webrtc::RTCStatsMemberInterface*> \
198 this_class::MembersOfThisObjectAndAncestors( \
199 size_t local_var_additional_capacity) const { \
200 return parent_class::MembersOfThisObjectAndAncestors(0); \
201 }
202
Jakob Ivarsson22936222019-03-22 11:29:49 +0100203// Non-standard stats members can be exposed to the JavaScript API in Chrome
204// e.g. through origin trials. The group ID can be used by the blink layer to
205// determine if a stats member should be exposed or not. Multiple non-standard
206// stats members can share the same group ID so that they are exposed together.
207enum class NonStandardGroupId {
Jakob Ivarssonaa023e22019-03-27 10:17:31 +0100208 // Group ID used for testing purposes only.
209 kGroupIdForTesting,
Jakob Ivarsson22936222019-03-22 11:29:49 +0100210 // I2E:
211 // https://groups.google.com/a/chromium.org/forum/#!topic/blink-dev/hE2B1iItPDk
212 kRtcAudioJitterBufferMaxPackets,
213 // I2E:
214 // https://groups.google.com/a/chromium.org/forum/#!topic/blink-dev/YbhMyqLXXXo
215 kRtcStatsRelativePacketArrivalDelay,
216};
217
Artem Titov0e61fdd2021-07-25 21:50:14 +0200218// Interface for `RTCStats` members, which have a name and a value of a type
219// defined in a subclass. Only the types listed in `Type` are supported, these
Artem Titovcfea2182021-08-10 01:22:31 +0200220// are implemented by `RTCStatsMember<T>`. The value of a member may be
Artem Titov0e61fdd2021-07-25 21:50:14 +0200221// undefined, the value can only be read if `is_defined`.
hbos74e1a4f2016-09-15 23:33:01 -0700222class RTCStatsMemberInterface {
223 public:
224 // Member value types.
225 enum Type {
Yves Gerey665174f2018-06-19 15:03:05 +0200226 kBool, // bool
227 kInt32, // int32_t
228 kUint32, // uint32_t
229 kInt64, // int64_t
230 kUint64, // uint64_t
231 kDouble, // double
232 kString, // std::string
hbos74e1a4f2016-09-15 23:33:01 -0700233
Yves Gerey665174f2018-06-19 15:03:05 +0200234 kSequenceBool, // std::vector<bool>
235 kSequenceInt32, // std::vector<int32_t>
236 kSequenceUint32, // std::vector<uint32_t>
237 kSequenceInt64, // std::vector<int64_t>
238 kSequenceUint64, // std::vector<uint64_t>
239 kSequenceDouble, // std::vector<double>
240 kSequenceString, // std::vector<std::string>
Byoungchan Lee0a52ede2021-05-22 08:41:02 +0900241
242 kMapStringUint64, // std::map<std::string, uint64_t>
243 kMapStringDouble, // std::map<std::string, double>
hbos74e1a4f2016-09-15 23:33:01 -0700244 };
245
246 virtual ~RTCStatsMemberInterface() {}
247
248 const char* name() const { return name_; }
249 virtual Type type() const = 0;
250 virtual bool is_sequence() const = 0;
251 virtual bool is_string() const = 0;
252 bool is_defined() const { return is_defined_; }
Taylor Brandstettere2751742018-06-25 13:42:44 -0700253 // Is this part of the stats spec? Used so that chromium can easily filter
254 // out anything unstandardized.
255 virtual bool is_standardized() const = 0;
Jakob Ivarsson22936222019-03-22 11:29:49 +0100256 // Non-standard stats members can have group IDs in order to be exposed in
257 // JavaScript through experiments. Standardized stats have no group IDs.
258 virtual std::vector<NonStandardGroupId> group_ids() const { return {}; }
hbos67c8bc42016-10-25 04:31:23 -0700259 // Type and value comparator. The names are not compared. These operators are
260 // exposed for testing.
261 virtual bool operator==(const RTCStatsMemberInterface& other) const = 0;
262 bool operator!=(const RTCStatsMemberInterface& other) const {
263 return !(*this == other);
264 }
hbos74e1a4f2016-09-15 23:33:01 -0700265 virtual std::string ValueToString() const = 0;
ehmaldonado35a872c2017-07-28 07:29:12 -0700266 // This is the same as ValueToString except for kInt64 and kUint64 types,
267 // where the value is represented as a double instead of as an integer.
268 // Since JSON stores numbers as floating point numbers, very large integers
269 // cannot be accurately represented, so we prefer to display them as doubles
270 // instead.
271 virtual std::string ValueToJson() const = 0;
hbos74e1a4f2016-09-15 23:33:01 -0700272
Yves Gerey665174f2018-06-19 15:03:05 +0200273 template <typename T>
hbos74e1a4f2016-09-15 23:33:01 -0700274 const T& cast_to() const {
Mirko Bonadei054f1852019-11-04 16:31:08 +0100275 RTC_DCHECK_EQ(type(), T::StaticType());
hbos74e1a4f2016-09-15 23:33:01 -0700276 return static_cast<const T&>(*this);
277 }
278
279 protected:
280 RTCStatsMemberInterface(const char* name, bool is_defined)
281 : name_(name), is_defined_(is_defined) {}
282
283 const char* const name_;
284 bool is_defined_;
285};
286
Artem Titov0e61fdd2021-07-25 21:50:14 +0200287// Template implementation of `RTCStatsMemberInterface`.
Mirko Bonadei054f1852019-11-04 16:31:08 +0100288// The supported types are the ones described by
Artem Titovcfea2182021-08-10 01:22:31 +0200289// `RTCStatsMemberInterface::Type`.
Yves Gerey665174f2018-06-19 15:03:05 +0200290template <typename T>
Mirko Bonadei1e6aa1f2019-11-05 17:20:58 +0100291class RTCStatsMember : public RTCStatsMemberInterface {
hbos74e1a4f2016-09-15 23:33:01 -0700292 public:
hbos74e1a4f2016-09-15 23:33:01 -0700293 explicit RTCStatsMember(const char* name)
Taylor Brandstettere2751742018-06-25 13:42:44 -0700294 : RTCStatsMemberInterface(name, /*is_defined=*/false), value_() {}
hbos74e1a4f2016-09-15 23:33:01 -0700295 RTCStatsMember(const char* name, const T& value)
Taylor Brandstettere2751742018-06-25 13:42:44 -0700296 : RTCStatsMemberInterface(name, /*is_defined=*/true), value_(value) {}
hbos74e1a4f2016-09-15 23:33:01 -0700297 RTCStatsMember(const char* name, T&& value)
Taylor Brandstettere2751742018-06-25 13:42:44 -0700298 : RTCStatsMemberInterface(name, /*is_defined=*/true),
299 value_(std::move(value)) {}
hbos74e1a4f2016-09-15 23:33:01 -0700300 explicit RTCStatsMember(const RTCStatsMember<T>& other)
301 : RTCStatsMemberInterface(other.name_, other.is_defined_),
302 value_(other.value_) {}
303 explicit RTCStatsMember(RTCStatsMember<T>&& other)
304 : RTCStatsMemberInterface(other.name_, other.is_defined_),
305 value_(std::move(other.value_)) {}
306
Mirko Bonadei054f1852019-11-04 16:31:08 +0100307 static Type StaticType();
308 Type type() const override { return StaticType(); }
hbos74e1a4f2016-09-15 23:33:01 -0700309 bool is_sequence() const override;
310 bool is_string() const override;
Taylor Brandstettere2751742018-06-25 13:42:44 -0700311 bool is_standardized() const override { return true; }
hbos67c8bc42016-10-25 04:31:23 -0700312 bool operator==(const RTCStatsMemberInterface& other) const override {
Taylor Brandstettere2751742018-06-25 13:42:44 -0700313 if (type() != other.type() || is_standardized() != other.is_standardized())
hbos67c8bc42016-10-25 04:31:23 -0700314 return false;
315 const RTCStatsMember<T>& other_t =
316 static_cast<const RTCStatsMember<T>&>(other);
317 if (!is_defined_)
318 return !other_t.is_defined();
hbos28747962016-11-21 09:17:41 -0800319 if (!other.is_defined())
320 return false;
hbos67c8bc42016-10-25 04:31:23 -0700321 return value_ == other_t.value_;
322 }
hbos74e1a4f2016-09-15 23:33:01 -0700323 std::string ValueToString() const override;
ehmaldonado35a872c2017-07-28 07:29:12 -0700324 std::string ValueToJson() const override;
hbos74e1a4f2016-09-15 23:33:01 -0700325
Andrey Logvin1f0f59f2020-06-15 12:49:25 +0000326 template <typename U>
327 inline T ValueOrDefault(U default_value) const {
328 if (is_defined()) {
329 return *(*this);
330 }
331 return default_value;
332 }
333
hbos74e1a4f2016-09-15 23:33:01 -0700334 // Assignment operators.
335 T& operator=(const T& value) {
336 value_ = value;
337 is_defined_ = true;
338 return value_;
339 }
340 T& operator=(const T&& value) {
341 value_ = std::move(value);
342 is_defined_ = true;
343 return value_;
344 }
hbos74e1a4f2016-09-15 23:33:01 -0700345
346 // Value getters.
347 T& operator*() {
348 RTC_DCHECK(is_defined_);
349 return value_;
350 }
351 const T& operator*() const {
352 RTC_DCHECK(is_defined_);
353 return value_;
354 }
355
356 // Value getters, arrow operator.
357 T* operator->() {
358 RTC_DCHECK(is_defined_);
359 return &value_;
360 }
361 const T* operator->() const {
362 RTC_DCHECK(is_defined_);
363 return &value_;
364 }
365
366 private:
367 T value_;
368};
369
Byoungchan Lee0a52ede2021-05-22 08:41:02 +0900370namespace rtc_stats_internal {
371
372typedef std::map<std::string, uint64_t> MapStringUint64;
373typedef std::map<std::string, double> MapStringDouble;
374
375} // namespace rtc_stats_internal
376
Mirko Bonadei62a19d02019-11-11 19:59:54 +0100377#define WEBRTC_DECLARE_RTCSTATSMEMBER(T) \
378 template <> \
379 RTC_EXPORT RTCStatsMemberInterface::Type RTCStatsMember<T>::StaticType(); \
380 template <> \
Mirko Bonadei6dd488b2019-11-20 14:06:39 +0100381 RTC_EXPORT bool RTCStatsMember<T>::is_sequence() const; \
Mirko Bonadei62a19d02019-11-11 19:59:54 +0100382 template <> \
Mirko Bonadei6dd488b2019-11-20 14:06:39 +0100383 RTC_EXPORT bool RTCStatsMember<T>::is_string() const; \
Mirko Bonadei62a19d02019-11-11 19:59:54 +0100384 template <> \
Mirko Bonadei6dd488b2019-11-20 14:06:39 +0100385 RTC_EXPORT std::string RTCStatsMember<T>::ValueToString() const; \
Mirko Bonadei62a19d02019-11-11 19:59:54 +0100386 template <> \
Mirko Bonadei6dd488b2019-11-20 14:06:39 +0100387 RTC_EXPORT std::string RTCStatsMember<T>::ValueToJson() const; \
Mirko Bonadei62a19d02019-11-11 19:59:54 +0100388 extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT) \
Mirko Bonadei054f1852019-11-04 16:31:08 +0100389 RTCStatsMember<T>
390
391WEBRTC_DECLARE_RTCSTATSMEMBER(bool);
392WEBRTC_DECLARE_RTCSTATSMEMBER(int32_t);
393WEBRTC_DECLARE_RTCSTATSMEMBER(uint32_t);
394WEBRTC_DECLARE_RTCSTATSMEMBER(int64_t);
395WEBRTC_DECLARE_RTCSTATSMEMBER(uint64_t);
396WEBRTC_DECLARE_RTCSTATSMEMBER(double);
397WEBRTC_DECLARE_RTCSTATSMEMBER(std::string);
398WEBRTC_DECLARE_RTCSTATSMEMBER(std::vector<bool>);
399WEBRTC_DECLARE_RTCSTATSMEMBER(std::vector<int32_t>);
400WEBRTC_DECLARE_RTCSTATSMEMBER(std::vector<uint32_t>);
401WEBRTC_DECLARE_RTCSTATSMEMBER(std::vector<int64_t>);
402WEBRTC_DECLARE_RTCSTATSMEMBER(std::vector<uint64_t>);
403WEBRTC_DECLARE_RTCSTATSMEMBER(std::vector<double>);
404WEBRTC_DECLARE_RTCSTATSMEMBER(std::vector<std::string>);
Byoungchan Lee0a52ede2021-05-22 08:41:02 +0900405WEBRTC_DECLARE_RTCSTATSMEMBER(rtc_stats_internal::MapStringUint64);
406WEBRTC_DECLARE_RTCSTATSMEMBER(rtc_stats_internal::MapStringDouble);
Mirko Bonadei054f1852019-11-04 16:31:08 +0100407
Taylor Brandstettere2751742018-06-25 13:42:44 -0700408// Using inheritance just so that it's obvious from the member's declaration
409// whether it's standardized or not.
410template <typename T>
Mirko Bonadei759f1612019-11-13 11:18:31 +0100411class RTCNonStandardStatsMember : public RTCStatsMember<T> {
Taylor Brandstettere2751742018-06-25 13:42:44 -0700412 public:
413 explicit RTCNonStandardStatsMember(const char* name)
414 : RTCStatsMember<T>(name) {}
Jakob Ivarsson758d9462019-03-19 15:38:49 +0100415 RTCNonStandardStatsMember(const char* name,
416 std::initializer_list<NonStandardGroupId> group_ids)
417 : RTCStatsMember<T>(name), group_ids_(group_ids) {}
Taylor Brandstettere2751742018-06-25 13:42:44 -0700418 RTCNonStandardStatsMember(const char* name, const T& value)
419 : RTCStatsMember<T>(name, value) {}
420 RTCNonStandardStatsMember(const char* name, T&& value)
421 : RTCStatsMember<T>(name, std::move(value)) {}
422 explicit RTCNonStandardStatsMember(const RTCNonStandardStatsMember<T>& other)
Jakob Ivarsson758d9462019-03-19 15:38:49 +0100423 : RTCStatsMember<T>(other), group_ids_(other.group_ids_) {}
Taylor Brandstettere2751742018-06-25 13:42:44 -0700424 explicit RTCNonStandardStatsMember(RTCNonStandardStatsMember<T>&& other)
Mirko Bonadei759f1612019-11-13 11:18:31 +0100425 : RTCStatsMember<T>(std::move(other)),
426 group_ids_(std::move(other.group_ids_)) {}
Taylor Brandstettere2751742018-06-25 13:42:44 -0700427
428 bool is_standardized() const override { return false; }
Ruslan Burakov8af88962018-11-22 17:21:10 +0100429
Jakob Ivarsson22936222019-03-22 11:29:49 +0100430 std::vector<NonStandardGroupId> group_ids() const override {
431 return group_ids_;
432 }
Jakob Ivarsson758d9462019-03-19 15:38:49 +0100433
Ruslan Burakov8af88962018-11-22 17:21:10 +0100434 T& operator=(const T& value) { return RTCStatsMember<T>::operator=(value); }
435 T& operator=(const T&& value) {
436 return RTCStatsMember<T>::operator=(std::move(value));
437 }
Jakob Ivarsson758d9462019-03-19 15:38:49 +0100438
439 private:
440 std::vector<NonStandardGroupId> group_ids_;
Taylor Brandstettere2751742018-06-25 13:42:44 -0700441};
Mirko Bonadei759f1612019-11-13 11:18:31 +0100442
443extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
444 RTCNonStandardStatsMember<bool>;
445extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
446 RTCNonStandardStatsMember<int32_t>;
447extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
448 RTCNonStandardStatsMember<uint32_t>;
449extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
450 RTCNonStandardStatsMember<int64_t>;
451extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
452 RTCNonStandardStatsMember<uint64_t>;
453extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
454 RTCNonStandardStatsMember<double>;
455extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
456 RTCNonStandardStatsMember<std::string>;
457extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
458 RTCNonStandardStatsMember<std::vector<bool>>;
459extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
460 RTCNonStandardStatsMember<std::vector<int32_t>>;
461extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
462 RTCNonStandardStatsMember<std::vector<uint32_t>>;
463extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
464 RTCNonStandardStatsMember<std::vector<int64_t>>;
465extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
466 RTCNonStandardStatsMember<std::vector<uint64_t>>;
467extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
468 RTCNonStandardStatsMember<std::vector<double>>;
469extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
470 RTCNonStandardStatsMember<std::vector<std::string>>;
Byoungchan Lee0a52ede2021-05-22 08:41:02 +0900471extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
472 RTCNonStandardStatsMember<std::map<std::string, uint64_t>>;
473extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
474 RTCNonStandardStatsMember<std::map<std::string, double>>;
Mirko Bonadei759f1612019-11-13 11:18:31 +0100475
hbos74e1a4f2016-09-15 23:33:01 -0700476} // namespace webrtc
477
Steve Anton10542f22019-01-11 09:11:00 -0800478#endif // API_STATS_RTC_STATS_H_