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

Side by Side 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 unified diff | Download patch
« no previous file with comments | « no previous file | base/metrics/field_trial_params.cc » ('j') | base/metrics/field_trial_params.cc » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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_
OLDNEW
« 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