Adds enum field trial parser.
Removed the need to create a custom parser function and reuses some of the code to reduce binary overhead of enums. Bug: webrtc:9346 Change-Id: I51c9da713ed5456a86a2afbcf0991477bb83b894 Reviewed-on: https://webrtc-review.googlesource.com/83623 Reviewed-by: Stefan Holmer <stefan@webrtc.org> Commit-Queue: Sebastian Jansson <srte@webrtc.org> Cr-Commit-Position: refs/heads/master@{#23752}
This commit is contained in:

committed by
Commit Bot

parent
b3f5aed433
commit
2c74d85c16
@ -121,6 +121,37 @@ bool FieldTrialFlag::Parse(absl::optional<std::string> str_value) {
|
||||
return true;
|
||||
}
|
||||
|
||||
AbstractFieldTrialEnum::AbstractFieldTrialEnum(
|
||||
std::string key,
|
||||
int default_value,
|
||||
std::map<std::string, int> mapping)
|
||||
: FieldTrialParameterInterface(key),
|
||||
value_(default_value),
|
||||
enum_mapping_(mapping) {
|
||||
for (auto& key_val : enum_mapping_)
|
||||
valid_values_.insert(key_val.second);
|
||||
}
|
||||
AbstractFieldTrialEnum::AbstractFieldTrialEnum(const AbstractFieldTrialEnum&) =
|
||||
default;
|
||||
AbstractFieldTrialEnum::~AbstractFieldTrialEnum() = default;
|
||||
|
||||
bool AbstractFieldTrialEnum::Parse(absl::optional<std::string> str_value) {
|
||||
if (str_value) {
|
||||
auto it = enum_mapping_.find(*str_value);
|
||||
if (it != enum_mapping_.end()) {
|
||||
value_ = it->second;
|
||||
return true;
|
||||
}
|
||||
absl::optional<int> value = ParseTypedParameter<int>(*str_value);
|
||||
if (value.has_value() &&
|
||||
(valid_values_.find(*value) != valid_values_.end())) {
|
||||
value_ = *value;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template class FieldTrialParameter<bool>;
|
||||
template class FieldTrialParameter<double>;
|
||||
template class FieldTrialParameter<int>;
|
||||
|
@ -12,6 +12,8 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include <initializer_list>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include "absl/types/optional.h"
|
||||
|
||||
@ -83,6 +85,47 @@ class FieldTrialParameter : public FieldTrialParameterInterface {
|
||||
T value_;
|
||||
};
|
||||
|
||||
class AbstractFieldTrialEnum : public FieldTrialParameterInterface {
|
||||
public:
|
||||
AbstractFieldTrialEnum(std::string key,
|
||||
int default_value,
|
||||
std::map<std::string, int> mapping);
|
||||
~AbstractFieldTrialEnum() override;
|
||||
AbstractFieldTrialEnum(const AbstractFieldTrialEnum&);
|
||||
|
||||
protected:
|
||||
bool Parse(absl::optional<std::string> str_value) override;
|
||||
|
||||
protected:
|
||||
int value_;
|
||||
std::map<std::string, int> enum_mapping_;
|
||||
std::set<int> valid_values_;
|
||||
};
|
||||
|
||||
// The FieldTrialEnum class can be used to quickly define a parser for a
|
||||
// specific enum. It handles values provided as integers and as strings if a
|
||||
// mapping is provided.
|
||||
template <typename T>
|
||||
class FieldTrialEnum : public AbstractFieldTrialEnum {
|
||||
public:
|
||||
FieldTrialEnum(std::string key,
|
||||
T default_value,
|
||||
std::map<std::string, T> mapping)
|
||||
: AbstractFieldTrialEnum(key,
|
||||
static_cast<int>(default_value),
|
||||
ToIntMap(mapping)) {}
|
||||
T Get() const { return static_cast<T>(value_); }
|
||||
operator T() const { return Get(); }
|
||||
|
||||
private:
|
||||
static std::map<std::string, int> ToIntMap(std::map<std::string, T> mapping) {
|
||||
std::map<std::string, int> res;
|
||||
for (const auto& it : mapping)
|
||||
res[it.first] = static_cast<int>(it.second);
|
||||
return res;
|
||||
}
|
||||
};
|
||||
|
||||
// This class uses the ParseTypedParameter function to implement an optional
|
||||
// parameter implementation that can default to absl::nullopt.
|
||||
template <typename T>
|
||||
|
@ -34,25 +34,12 @@ struct DummyExperiment {
|
||||
};
|
||||
|
||||
enum class CustomEnum {
|
||||
kDefault,
|
||||
kRed,
|
||||
kBlue,
|
||||
kDefault = 0,
|
||||
kRed = 1,
|
||||
kBlue = 2,
|
||||
};
|
||||
} // namespace
|
||||
|
||||
// Providing a custom parser for an enum can make the trial string easier to
|
||||
// read, but also adds more code and makes the string more verbose.
|
||||
template <>
|
||||
absl::optional<CustomEnum> ParseTypedParameter<CustomEnum>(std::string str) {
|
||||
if (str == "default")
|
||||
return CustomEnum::kDefault;
|
||||
else if (str == "red")
|
||||
return CustomEnum::kRed;
|
||||
else if (str == "blue")
|
||||
return CustomEnum::kBlue;
|
||||
return absl::nullopt;
|
||||
}
|
||||
|
||||
TEST(FieldTrialParserTest, ParsesValidParameters) {
|
||||
DummyExperiment exp("Enabled,f:-1.7,r:2,p:1,h:x7c");
|
||||
EXPECT_TRUE(exp.enabled.Get());
|
||||
@ -122,10 +109,17 @@ TEST(FieldTrialParserTest, ParsesOptionalParameters) {
|
||||
EXPECT_FALSE(optional_string.Get().has_value());
|
||||
}
|
||||
TEST(FieldTrialParserTest, ParsesCustomEnumParameter) {
|
||||
FieldTrialParameter<CustomEnum> my_enum("e", CustomEnum::kDefault);
|
||||
FieldTrialEnum<CustomEnum> my_enum("e", CustomEnum::kDefault,
|
||||
{{"default", CustomEnum::kDefault},
|
||||
{"red", CustomEnum::kRed},
|
||||
{"blue", CustomEnum::kBlue}});
|
||||
ParseFieldTrial({&my_enum}, "");
|
||||
EXPECT_EQ(my_enum.Get(), CustomEnum::kDefault);
|
||||
ParseFieldTrial({&my_enum}, "e:red");
|
||||
EXPECT_EQ(my_enum.Get(), CustomEnum::kRed);
|
||||
ParseFieldTrial({&my_enum}, "e:2");
|
||||
EXPECT_EQ(my_enum.Get(), CustomEnum::kBlue);
|
||||
ParseFieldTrial({&my_enum}, "e:5");
|
||||
EXPECT_EQ(my_enum.Get(), CustomEnum::kBlue);
|
||||
}
|
||||
} // namespace webrtc
|
||||
|
Reference in New Issue
Block a user