Use struct parser for rate control trial.
Bug: webrtc:9883
Change-Id: I9ec7988da2e4d88bedd9b71cae00452f531980d6
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/148581
Commit-Queue: Sebastian Jansson <srte@webrtc.org>
Reviewed-by: Jonas Olsson <jonasolsson@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#28856}
diff --git a/rtc_base/experiments/struct_parameters_parser.h b/rtc_base/experiments/struct_parameters_parser.h
index f6728f6..b40f381 100644
--- a/rtc_base/experiments/struct_parameters_parser.h
+++ b/rtc_base/experiments/struct_parameters_parser.h
@@ -26,189 +26,83 @@
namespace webrtc {
namespace struct_parser_impl {
-inline std::string StringEncode(bool val) {
- return rtc::ToString(val);
-}
-inline std::string StringEncode(double val) {
- return rtc::ToString(val);
-}
-inline std::string StringEncode(int val) {
- return rtc::ToString(val);
-}
-inline std::string StringEncode(std::string val) {
- return val;
-}
-inline std::string StringEncode(DataRate val) {
- return ToString(val);
-}
-inline std::string StringEncode(DataSize val) {
- return ToString(val);
-}
-inline std::string StringEncode(TimeDelta val) {
- return ToString(val);
-}
+struct TypedMemberParser {
+ public:
+ bool (*parse)(const absl::string_view src, void* target);
+ void (*encode)(const void* src, std::string* target);
+};
+
+struct MemberParameter {
+ const char* key;
+ void* member_ptr;
+ TypedMemberParser parser;
+};
template <typename T>
-inline std::string StringEncode(absl::optional<T> val) {
- if (val)
- return StringEncode(*val);
- return "";
-}
+class TypedParser {
+ public:
+ static bool Parse(absl::string_view src, void* target);
+ static void Encode(const void* src, std::string* target);
+};
+
+// Instantiated in cc file to avoid duplication during compile. Add additional
+// parsers as needed. Generally, try to use these suggested types even if the
+// context where the value is used might require a different type. For instance,
+// a size_t representing a packet size should use an int parameter as there's no
+// need to support packet sizes larger than INT32_MAX.
+extern template class TypedParser<bool>;
+extern template class TypedParser<double>;
+extern template class TypedParser<int>;
+extern template class TypedParser<absl::optional<double>>;
+extern template class TypedParser<absl::optional<int>>;
+
+extern template class TypedParser<DataRate>;
+extern template class TypedParser<DataSize>;
+extern template class TypedParser<TimeDelta>;
+extern template class TypedParser<absl::optional<DataRate>>;
+extern template class TypedParser<absl::optional<DataSize>>;
+extern template class TypedParser<absl::optional<TimeDelta>>;
template <typename T>
-struct LambdaTraits : public LambdaTraits<decltype(&T::operator())> {};
-
-template <typename ClassType, typename RetType, typename SourceType>
-struct LambdaTraits<RetType* (ClassType::*)(SourceType*)const> {
- using ret = RetType;
- using src = SourceType;
-};
-
-void ParseConfigParams(
- absl::string_view config_str,
- std::map<std::string, std::function<bool(absl::string_view)>> field_map);
-
-std::string EncodeStringStringMap(std::map<std::string, std::string> mapping);
-
-template <typename StructType>
-class StructParameterParser {
- public:
- virtual bool Parse(absl::string_view src, StructType* target) const = 0;
- virtual bool Changed(const StructType& src, const StructType& base) const = 0;
- virtual std::string Encode(const StructType& src) const = 0;
- virtual ~StructParameterParser() = default;
-};
-
-template <typename StructType, typename T>
-class StructParameterImpl : public StructParameterParser<StructType> {
- public:
- explicit StructParameterImpl(std::function<T*(StructType*)> field_getter)
- : field_getter_(std::move(field_getter)) {}
- bool Parse(absl::string_view src, StructType* target) const override {
- auto parsed = ParseTypedParameter<T>(std::string(src));
- if (parsed.has_value())
- *field_getter_(target) = *parsed;
- return parsed.has_value();
- }
- bool Changed(const StructType& src, const StructType& base) const override {
- T base_value = *field_getter_(const_cast<StructType*>(&base));
- T value = *field_getter_(const_cast<StructType*>(&src));
- return value != base_value;
- }
- std::string Encode(const StructType& src) const override {
- T value = *field_getter_(const_cast<StructType*>(&src));
- return struct_parser_impl::StringEncode(value);
- }
-
- private:
- const std::function<T*(StructType*)> field_getter_;
-};
-
-template <typename StructType>
-struct StructParameter {
- std::string key;
- StructParameterParser<StructType>* parser;
-};
-
-template <typename S,
- typename Closure,
- typename T = typename LambdaTraits<Closure>::ret>
-void AddParameters(std::vector<StructParameter<S>>* out,
- std::string key,
- Closure getter) {
- auto* parser = new StructParameterImpl<S, T>(getter);
- out->push_back(StructParameter<S>{std::move(key), parser});
+void AddMembers(MemberParameter* out, const char* key, T* member) {
+ *out = MemberParameter{
+ key, member,
+ TypedMemberParser{&TypedParser<T>::Parse, &TypedParser<T>::Encode}};
}
-template <typename S,
- typename Closure,
- typename T = typename LambdaTraits<Closure>::ret,
- typename... Args>
-void AddParameters(std::vector<StructParameter<S>>* out,
- std::string key,
- Closure getter,
- Args... args) {
- AddParameters(out, key, getter);
- AddParameters<S>(out, args...);
+template <typename T, typename... Args>
+void AddMembers(MemberParameter* out,
+ const char* key,
+ T* member,
+ Args... args) {
+ AddMembers(out, key, member);
+ AddMembers(++out, args...);
}
-
} // namespace struct_parser_impl
-template <typename StructType>
class StructParametersParser {
public:
- ~StructParametersParser() {
- for (auto& param : parameters_) {
- delete param.parser;
- }
+ template <typename T, typename... Args>
+ static std::unique_ptr<StructParametersParser> Create(const char* first_key,
+ T* first_member,
+ Args... args) {
+ std::vector<struct_parser_impl::MemberParameter> members(
+ sizeof...(args) / 2 + 1);
+ struct_parser_impl::AddMembers(&members.front(), std::move(first_key),
+ first_member, args...);
+ return absl::WrapUnique(new StructParametersParser(std::move(members)));
}
- void Parse(StructType* target, absl::string_view src) {
- std::map<std::string, std::function<bool(absl::string_view)>> field_parsers;
- for (const auto& param : parameters_) {
- field_parsers.emplace(param.key, [target, param](absl::string_view src) {
- return param.parser->Parse(src, target);
- });
- }
- struct_parser_impl::ParseConfigParams(src, std::move(field_parsers));
- }
-
- StructType Parse(absl::string_view src) {
- StructType res;
- Parse(&res, src);
- return res;
- }
-
- std::string EncodeChanged(const StructType& src) {
- static StructType base;
- std::map<std::string, std::string> pairs;
- for (const auto& param : parameters_) {
- if (param.parser->Changed(src, base))
- pairs[param.key] = param.parser->Encode(src);
- }
- return struct_parser_impl::EncodeStringStringMap(pairs);
- }
-
- std::string EncodeAll(const StructType& src) {
- std::map<std::string, std::string> pairs;
- for (const auto& param : parameters_) {
- pairs[param.key] = param.parser->Encode(src);
- }
- return struct_parser_impl::EncodeStringStringMap(pairs);
- }
+ void Parse(absl::string_view src);
+ std::string Encode() const;
private:
- template <typename C, typename S, typename... Args>
- friend std::unique_ptr<StructParametersParser<S>>
- CreateStructParametersParser(std::string, C, Args...);
-
explicit StructParametersParser(
- std::vector<struct_parser_impl::StructParameter<StructType>> parameters)
- : parameters_(parameters) {}
+ std::vector<struct_parser_impl::MemberParameter> members);
- std::vector<struct_parser_impl::StructParameter<StructType>> parameters_;
+ std::vector<struct_parser_impl::MemberParameter> members_;
};
-// Creates a struct parameters parser based on interleaved key and field
-// accessor arguments, where the field accessor converts a struct pointer to a
-// member pointer: FieldType*(StructType*). See the unit tests for example
-// usage. Note that the struct type is inferred from the field getters. Beware
-// of providing incorrect arguments to this, such as mixing the struct type or
-// incorrect return values, as this will cause very confusing compile errors.
-template <typename Closure,
- typename S = typename struct_parser_impl::LambdaTraits<Closure>::src,
- typename... Args>
-std::unique_ptr<StructParametersParser<S>> CreateStructParametersParser(
- std::string first_key,
- Closure first_getter,
- Args... args) {
- std::vector<struct_parser_impl::StructParameter<S>> parameters;
- struct_parser_impl::AddParameters<S>(¶meters, std::move(first_key),
- first_getter, args...);
- // absl::make_unique can't be used since the StructParametersParser
- // constructor is only visible to this create function.
- return absl::WrapUnique(new StructParametersParser<S>(std::move(parameters)));
-}
} // namespace webrtc
#endif // RTC_BASE_EXPERIMENTS_STRUCT_PARAMETERS_PARSER_H_