Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef BASE_METRICS_FIELD_TRIAL_PARAMS_H_ | 5 #ifndef BASE_METRICS_FIELD_TRIAL_PARAMS_H_ |
| 6 #define BASE_METRICS_FIELD_TRIAL_PARAMS_H_ | 6 #define BASE_METRICS_FIELD_TRIAL_PARAMS_H_ |
| 7 | 7 |
| 8 #include <map> | 8 #include <map> |
| 9 #include <string> | 9 #include <string> |
| 10 | 10 |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 84 // Same as GetFieldTrialParamValueByFeature(). On top of that, it converts the | 84 // Same as GetFieldTrialParamValueByFeature(). On top of that, it converts the |
| 85 // string value into a boolean and returns it, if successful. Otherwise, it | 85 // string value into a boolean and returns it, if successful. Otherwise, it |
| 86 // returns |default_value|. The only string representations accepted here are | 86 // returns |default_value|. The only string representations accepted here are |
| 87 // "true" and "false". If the string value is not empty and the conversion does | 87 // "true" and "false". If the string value is not empty and the conversion does |
| 88 // not succeed, it produces a warning to LOG. | 88 // not succeed, it produces a warning to LOG. |
| 89 BASE_EXPORT bool GetFieldTrialParamByFeatureAsBool( | 89 BASE_EXPORT bool GetFieldTrialParamByFeatureAsBool( |
| 90 const base::Feature& feature, | 90 const base::Feature& feature, |
| 91 const std::string& param_name, | 91 const std::string& param_name, |
| 92 bool default_value); | 92 bool default_value); |
| 93 | 93 |
| 94 // Shared declaration for various FeatureParam<T> types. | |
| 95 // | |
| 96 // 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.
| |
| 97 // tend to prefer template specialization when classes/functions have the same | |
| 98 // functionality for different types, but separate functions are used above. | |
| 99 // (Note that the T=enum case even has a slightly different API). | |
| 100 template <typename T, bool IsEnum = std::is_enum<T>::value> | |
| 101 struct FeatureParam { | |
| 102 // Prevent use of FeatureParam<> with unsupported types (e.g. void*). Uses T | |
| 103 // in its definition so that evaluation is deferred until the template is | |
| 104 // instantiated. | |
| 105 // TODO(sfiera): no-compile test: | |
| 106 // https://www.chromium.org/developers/testing/no-compile-tests | |
| 107 static_assert(!std::is_same<T, T>::value, "unsupported FeatureParam<> type"); | |
| 108 }; | |
| 109 | |
| 110 // Declares a string-valued parameter. Example: | |
| 111 // | |
| 112 // constexpr FeatureParam<string> kAssistantName{ | |
| 113 // &kAssistantFeature, "assistant_name", "HAL"}; | |
| 114 // | |
| 115 // If the feature is not set, or set to the empty string, then Get() will return | |
| 116 // the default value. | |
| 117 // | |
| 118 // TODO(sfiera): should Get() be a method on the object, or would it be better | |
| 119 // to have a free function like GetFieldTrialParam(kAssistantName)? | |
| 120 template <> | |
| 121 struct FeatureParam<std::string> { | |
| 122 constexpr FeatureParam(const Feature* feature, | |
| 123 const char* name, | |
| 124 const char* default_value) | |
| 125 : feature(feature), name(name), default_value(default_value) {} | |
| 126 | |
| 127 BASE_EXPORT std::string Get() const; | |
| 128 | |
| 129 const Feature* const feature; | |
| 130 const char* const name; | |
| 131 const char* const default_value; | |
| 132 }; | |
| 133 | |
| 134 // Declares a double-valued parameter. Example: | |
| 135 // | |
| 136 // constexpr FeatureParam<double> kAssistantTriggerThreshold{ | |
| 137 // &kAssistantFeature, "trigger_threshold", 0.10}; | |
| 138 // | |
| 139 // If the feature is not set, or set to an invalid double value, then Get() will | |
| 140 // return the default value. | |
| 141 template <> | |
| 142 struct FeatureParam<double> { | |
| 143 constexpr FeatureParam(const Feature* feature, | |
| 144 const char* name, | |
| 145 double default_value) | |
| 146 : feature(feature), name(name), default_value(default_value) {} | |
| 147 | |
| 148 BASE_EXPORT double Get() const; | |
| 149 | |
| 150 const Feature* const feature; | |
| 151 const char* const name; | |
| 152 const double default_value; | |
| 153 }; | |
| 154 | |
| 155 // Declares an int-valued parameter. Example: | |
| 156 // | |
| 157 // constexpr FeatureParam<int> kAssistantParallelism{ | |
| 158 // &kAssistantFeature, "parallelism", 4}; | |
| 159 // | |
| 160 // If the feature is not set, or set to an invalid double value, then Get() will | |
| 161 // return the default value. | |
| 162 template <> | |
| 163 struct FeatureParam<int> { | |
| 164 constexpr FeatureParam(const Feature* feature, | |
| 165 const char* name, | |
| 166 int default_value) | |
| 167 : feature(feature), name(name), default_value(default_value) {} | |
| 168 | |
| 169 BASE_EXPORT int Get() const; | |
| 170 | |
| 171 const Feature* const feature; | |
| 172 const char* const name; | |
| 173 const int default_value; | |
| 174 }; | |
| 175 | |
| 176 template <> | |
| 177 struct FeatureParam<bool> { | |
| 178 constexpr FeatureParam(const Feature* feature, | |
| 179 const char* name, | |
| 180 bool default_value) | |
| 181 : feature(feature), name(name), default_value(default_value) {} | |
| 182 | |
| 183 BASE_EXPORT bool Get() const; | |
| 184 | |
| 185 const Feature* const feature; | |
| 186 const char* const name; | |
| 187 const bool default_value; | |
| 188 }; | |
| 189 | |
| 190 BASE_EXPORT void LogInvalidEnumValue(const Feature& feature, | |
| 191 const std::string& param_name, | |
| 192 const std::string& value_as_string, | |
| 193 int default_value_as_int); | |
| 194 | |
| 195 // Feature param declaration for an enum, with associated options. Example: | |
| 196 // | |
| 197 // constexpr FeatureParam<ShapeEnum>::Option[] kShapeParamOptions[] = { | |
| 198 // {SHAPE_CIRCLE, "circle"}, | |
| 199 // {SHAPE_CYLINDER, "cylinder"}, | |
| 200 // {SHAPE_PAPERCLIP, "paperclip"}}; | |
| 201 // constexpr FeatureParam<ShapeEnum> kAssistantShapeParam{ | |
| 202 // &kAssistantFeature, "shape", SHAPE_CIRCLE, &kShapeParamOptions}; | |
| 203 // | |
| 204 // With this declaration, the parameter may be set to "circle", "cylinder", or | |
| 205 // "paperclip", and that will be translated to one of the three enum values. By | |
| 206 // default, or if the param is set to an unknown value, the parameter will be | |
| 207 // assumed to be SHAPE_CIRCLE. | |
| 208 // | |
| 209 // TODO(sfiera): Should there be a "GetFieldTrialParamByFeatureAsEnum()" | |
| 210 // function above to match the other types? Is this something we even want to | |
| 211 // 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.
| |
| 212 template <typename Enum> | |
| 213 struct FeatureParam<Enum, true> { | |
| 214 struct Option { | |
| 215 constexpr Option(Enum value, const char* name) : value(value), name(name) {} | |
| 216 Enum value; | |
| 217 const char* const name; | |
| 218 }; | |
| 219 | |
| 220 template <int option_count> | |
| 221 constexpr FeatureParam(const Feature* feature, | |
| 222 const char* name, | |
| 223 const Enum default_value, | |
| 224 const Option (*options)[option_count]) | |
| 225 : feature(feature), | |
| 226 name(name), | |
| 227 default_value(default_value), | |
| 228 options(*options), | |
| 229 option_count(option_count) { | |
| 230 // TODO(sfiera): no-compile test | |
| 231 static_assert(option_count >= 1, "FeatureParam<enum> has no options"); | |
| 232 } | |
| 233 | |
| 234 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
| |
| 235 std::string value = GetFieldTrialParamValueByFeature(*feature, name); | |
| 236 if (value.empty()) { | |
|
Alexei Svitkine (slow)
2017/04/24 18:35:48
Nit: No {}'s
sfiera
2017/04/28 16:07:04
Done.
| |
| 237 return default_value; | |
| 238 } | |
| 239 for (int i = 0; i < option_count; ++i) { | |
| 240 if (value == options[i].name) { | |
| 241 return options[i].value; | |
| 242 } | |
| 243 } | |
| 244 LogInvalidEnumValue(*feature, name, value, static_cast<int>(default_value)); | |
| 245 return default_value; | |
| 246 } | |
| 247 | |
| 248 const base::Feature* const feature; | |
| 249 const char* const name; | |
| 250 const Enum default_value; | |
| 251 const Option* const options; | |
| 252 const int option_count; | |
| 253 }; | |
| 254 | |
| 94 } // namespace base | 255 } // namespace base |
| 95 | 256 |
| 96 #endif // BASE_METRICS_FIELD_TRIAL_PARAMS_H_ | 257 #endif // BASE_METRICS_FIELD_TRIAL_PARAMS_H_ |
| OLD | NEW |