Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(60)

Unified Diff: base/metrics/field_trial_params.h

Issue 2804633003: Add base::FeatureParam<> struct (Closed)
Patch Set: Remove windows-incompatible constexpr Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | base/metrics/field_trial_params.cc » ('j') | base/metrics/field_trial_params.cc » ('J')
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: base/metrics/field_trial_params.h
diff --git a/base/metrics/field_trial_params.h b/base/metrics/field_trial_params.h
index 2490149f69457cca85f9798bd192ebd194ae7bfc..6b3b754d7fb6a7b75390c2f8948b4affd10444f9 100644
--- a/base/metrics/field_trial_params.h
+++ b/base/metrics/field_trial_params.h
@@ -91,6 +91,167 @@ BASE_EXPORT bool GetFieldTrialParamByFeatureAsBool(
const std::string& param_name,
bool default_value);
+// Shared declaration for various FeatureParam<T> types.
+//
+// TODO(sfiera): is this the way we want to parameterize for different types? I
Alexei Svitkine (slow) 2017/04/24 18:35:47 I think this is a good use of templates - since th
sfiera 2017/04/28 16:07:04 Acknowledged.
+// tend to prefer template specialization when classes/functions have the same
+// functionality for different types, but separate functions are used above.
+// (Note that the T=enum case even has a slightly different API).
+template <typename T, bool IsEnum = std::is_enum<T>::value>
+struct FeatureParam {
+ // Prevent use of FeatureParam<> with unsupported types (e.g. void*). Uses T
+ // in its definition so that evaluation is deferred until the template is
+ // instantiated.
+ // TODO(sfiera): no-compile test:
+ // https://www.chromium.org/developers/testing/no-compile-tests
+ static_assert(!std::is_same<T, T>::value, "unsupported FeatureParam<> type");
+};
+
+// Declares a string-valued parameter. Example:
+//
+// constexpr FeatureParam<string> kAssistantName{
+// &kAssistantFeature, "assistant_name", "HAL"};
+//
+// If the feature is not set, or set to the empty string, then Get() will return
+// the default value.
+//
+// TODO(sfiera): should Get() be a method on the object, or would it be better
+// to have a free function like GetFieldTrialParam(kAssistantName)?
+template <>
+struct FeatureParam<std::string> {
+ constexpr FeatureParam(const Feature* feature,
+ const char* name,
+ const char* default_value)
+ : feature(feature), name(name), default_value(default_value) {}
+
+ BASE_EXPORT std::string Get() const;
+
+ const Feature* const feature;
+ const char* const name;
+ const char* const default_value;
+};
+
+// Declares a double-valued parameter. Example:
+//
+// constexpr FeatureParam<double> kAssistantTriggerThreshold{
+// &kAssistantFeature, "trigger_threshold", 0.10};
+//
+// If the feature is not set, or set to an invalid double value, then Get() will
+// return the default value.
+template <>
+struct FeatureParam<double> {
+ constexpr FeatureParam(const Feature* feature,
+ const char* name,
+ double default_value)
+ : feature(feature), name(name), default_value(default_value) {}
+
+ BASE_EXPORT double Get() const;
+
+ const Feature* const feature;
+ const char* const name;
+ const double default_value;
+};
+
+// Declares an int-valued parameter. Example:
+//
+// constexpr FeatureParam<int> kAssistantParallelism{
+// &kAssistantFeature, "parallelism", 4};
+//
+// If the feature is not set, or set to an invalid double value, then Get() will
+// return the default value.
+template <>
+struct FeatureParam<int> {
+ constexpr FeatureParam(const Feature* feature,
+ const char* name,
+ int default_value)
+ : feature(feature), name(name), default_value(default_value) {}
+
+ BASE_EXPORT int Get() const;
+
+ const Feature* const feature;
+ const char* const name;
+ const int default_value;
+};
+
+template <>
+struct FeatureParam<bool> {
+ constexpr FeatureParam(const Feature* feature,
+ const char* name,
+ bool default_value)
+ : feature(feature), name(name), default_value(default_value) {}
+
+ BASE_EXPORT bool Get() const;
+
+ const Feature* const feature;
+ const char* const name;
+ const bool default_value;
+};
+
+BASE_EXPORT void LogInvalidEnumValue(const Feature& feature,
+ const std::string& param_name,
+ const std::string& value_as_string,
+ int default_value_as_int);
+
+// Feature param declaration for an enum, with associated options. Example:
+//
+// constexpr FeatureParam<ShapeEnum>::Option[] kShapeParamOptions[] = {
+// {SHAPE_CIRCLE, "circle"},
+// {SHAPE_CYLINDER, "cylinder"},
+// {SHAPE_PAPERCLIP, "paperclip"}};
+// constexpr FeatureParam<ShapeEnum> kAssistantShapeParam{
+// &kAssistantFeature, "shape", SHAPE_CIRCLE, &kShapeParamOptions};
+//
+// With this declaration, the parameter may be set to "circle", "cylinder", or
+// "paperclip", and that will be translated to one of the three enum values. By
+// default, or if the param is set to an unknown value, the parameter will be
+// assumed to be SHAPE_CIRCLE.
+//
+// TODO(sfiera): Should there be a "GetFieldTrialParamByFeatureAsEnum()"
+// function above to match the other types? Is this something we even want to
+// provide?
Alexei Svitkine (slow) 2017/04/24 18:35:48 I think it's not to have one given we'll be encour
sfiera 2017/04/28 16:07:04 Acknowledged.
+template <typename Enum>
+struct FeatureParam<Enum, true> {
+ struct Option {
+ constexpr Option(Enum value, const char* name) : value(value), name(name) {}
+ Enum value;
+ const char* const name;
+ };
+
+ template <int option_count>
+ constexpr FeatureParam(const Feature* feature,
+ const char* name,
+ const Enum default_value,
+ const Option (*options)[option_count])
+ : feature(feature),
+ name(name),
+ default_value(default_value),
+ options(*options),
+ option_count(option_count) {
+ // TODO(sfiera): no-compile test
+ static_assert(option_count >= 1, "FeatureParam<enum> has no options");
+ }
+
+ Enum Get() const {
Alexei Svitkine (slow) 2017/04/24 18:35:48 Can this be implemented out of line? If so, LogInv
sfiera 2017/04/28 16:07:04 No, unfortunately. It needs to be instantiated for
+ std::string value = GetFieldTrialParamValueByFeature(*feature, name);
+ if (value.empty()) {
Alexei Svitkine (slow) 2017/04/24 18:35:48 Nit: No {}'s
sfiera 2017/04/28 16:07:04 Done.
+ return default_value;
+ }
+ for (int i = 0; i < option_count; ++i) {
+ if (value == options[i].name) {
+ return options[i].value;
+ }
+ }
+ LogInvalidEnumValue(*feature, name, value, static_cast<int>(default_value));
+ return default_value;
+ }
+
+ const base::Feature* const feature;
+ const char* const name;
+ const Enum default_value;
+ const Option* const options;
+ const int option_count;
+};
+
} // namespace base
#endif // BASE_METRICS_FIELD_TRIAL_PARAMS_H_
« no previous file with comments | « no previous file | base/metrics/field_trial_params.cc » ('j') | base/metrics/field_trial_params.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698