tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

feature_list.h (7802B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 // This is a cut down version of base/feature_list.h.
      8 // This just returns the default state for a feature.
      9 
     10 #ifndef BASE_FEATURE_LIST_H_
     11 #define BASE_FEATURE_LIST_H_
     12 
     13 namespace base {
     14 
     15 
     16 // Specifies whether a given feature is enabled or disabled by default.
     17 // NOTE: The actual runtime state may be different, due to a field trial or a
     18 // command line switch.
     19 enum FeatureState {
     20  FEATURE_DISABLED_BY_DEFAULT,
     21  FEATURE_ENABLED_BY_DEFAULT,
     22 };
     23 
     24 // Recommended macros for declaring and defining features and parameters:
     25 //
     26 // - `kFeature` is the C++ identifier that will be used for the `base::Feature`.
     27 // - `name` is the feature name, which must be globally unique. This name is
     28 //   used to enable/disable features via experiments and command-line flags.
     29 //   Names should use CamelCase-style naming, e.g. "MyGreatFeature".
     30 // - `default_state` is the default state to use for the feature, i.e.
     31 //   `base::FEATURE_DISABLED_BY_DEFAULT` or `base::FEATURE_ENABLED_BY_DEFAULT`.
     32 //   As noted above, the actual runtime state may differ from the default state,
     33 //   due to field trials or command-line switches.
     34 
     35 // Provides a forward declaration for `kFeature` in a header file, e.g.
     36 //
     37 //   BASE_DECLARE_FEATURE(kMyFeature);
     38 //
     39 // If the feature needs to be marked as exported, i.e. it is referenced by
     40 // multiple components, then write:
     41 //
     42 //   COMPONENT_EXPORT(MY_COMPONENT) BASE_DECLARE_FEATURE(kMyFeature);
     43 #define BASE_DECLARE_FEATURE(kFeature) \
     44  extern CONSTINIT const base::Feature kFeature
     45 
     46 // Provides a definition for `kFeature` with `name` and `default_state`, e.g.
     47 //
     48 //   BASE_FEATURE(kMyFeature, "MyFeature", base::FEATURE_DISABLED_BY_DEFAULT);
     49 //
     50 // Features should *not* be defined in header files; do not use this macro in
     51 // header files.
     52 #define BASE_FEATURE(feature, name, default_state) \
     53  CONSTINIT const base::Feature feature(           \
     54      name, default_state, base::internal::FeatureMacroHandshake::kSecret)
     55 
     56 // Provides a forward declaration for `feature_object_name` in a header file,
     57 // e.g.
     58 //
     59 //   BASE_DECLARE_FEATURE_PARAM(kMyFeatureParam);
     60 //
     61 // If the feature needs to be marked as exported, i.e. it is referenced by
     62 // multiple components, then write:
     63 //
     64 //   COMPONENT_EXPORT(MY_COMPONENT) BASE_DECLARE_FEATURE_PARAM(kMyFeatureParam);
     65 //
     66 // This macro enables optimizations to make the second and later calls faster,
     67 // but requires additional memory uses. If you obtain the parameter only once,
     68 // you can instantiate base::FeatureParam directly, or can call
     69 // base::GetFieldTrialParamByFeatureAsInt or equivalent functions for other
     70 // types directly.
     71 #define BASE_DECLARE_FEATURE_PARAM(T, feature_object_name) \
     72  extern CONSTINIT const base::FeatureParam<T> feature_object_name
     73 
     74 // Provides a definition for `feature_object_name` with `T`, `feature`, `name`
     75 // and `default_value`, with an internal parsed value cache, e.g.
     76 //
     77 //   BASE_FEATURE_PARAM(int, kMyFeatureParam, kMyFeature, "MyFeatureParam", 0);
     78 //
     79 // `T` is a parameter type, one of bool, int, size_t, double, std::string, and
     80 // base::TimeDelta. Enum types are not supported for now.
     81 //
     82 // For now, ScopedFeatureList doesn't work to change the value dynamically when
     83 // the cache is used with this macro.
     84 //
     85 // It should *not* be defined in header files; do not use this macro in header
     86 // files.
     87 #define BASE_FEATURE_PARAM(T, feature_object_name, feature, name,       \
     88                           default_value)                               \
     89  namespace field_trial_params_internal {                               \
     90  T GetFeatureParamWithCacheFor##feature_object_name(                   \
     91      const base::FeatureParam<T>* feature_param) {                     \
     92    static const typename base::internal::FeatureParamTraits<           \
     93        T>::CacheStorageType storage =                                  \
     94        base::internal::FeatureParamTraits<T>::ToCacheStorageType(      \
     95            feature_param->GetWithoutCache());                          \
     96    return base::internal::FeatureParamTraits<T>::FromCacheStorageType( \
     97        storage);                                                       \
     98  }                                                                     \
     99  } /* field_trial_params_internal */                                   \
    100  CONSTINIT const base::FeatureParam<T> feature_object_name(            \
    101      feature, name, default_value,                                     \
    102      &field_trial_params_internal::                                    \
    103          GetFeatureParamWithCacheFor##feature_object_name)
    104 
    105 // Same as BASE_FEATURE_PARAM() but used for enum type parameters with on extra
    106 // argument, `options`. See base::FeatureParam<Enum> template declaration in
    107 // //base/metrics/field_trial_params.h for `options`' details.
    108 #define BASE_FEATURE_ENUM_PARAM(T, feature_object_name, feature, name, \
    109                                default_value, options)                \
    110  namespace field_trial_params_internal {                              \
    111  T GetFeatureParamWithCacheFor##feature_object_name(                  \
    112      const base::FeatureParam<T>* feature_param) {                    \
    113    static const T param = feature_param->GetWithoutCache();           \
    114    return param;                                                      \
    115  }                                                                    \
    116  } /* field_trial_params_internal */                                  \
    117  CONSTINIT const base::FeatureParam<T> feature_object_name(           \
    118      feature, name, default_value, options,                           \
    119      &field_trial_params_internal::                                   \
    120          GetFeatureParamWithCacheFor##feature_object_name)
    121 
    122 // Secret handshake to (try to) ensure all places that construct a base::Feature
    123 // go through the helper `BASE_FEATURE()` macro above.
    124 namespace internal {
    125 enum class FeatureMacroHandshake { kSecret };
    126 }
    127 
    128 // The Feature struct is used to define the default state for a feature. See
    129 // comment below for more details. There must only ever be one struct instance
    130 // for a given feature name - generally defined as a constant global variable or
    131 // file static. It should never be used as a constexpr as it breaks
    132 // pointer-based identity lookup.
    133 struct BASE_EXPORT Feature {
    134  constexpr Feature(const char* name, FeatureState default_state,
    135                    internal::FeatureMacroHandshake)
    136      : name(name), default_state(default_state) {
    137  }
    138 
    139  // Non-copyable since:
    140  // - there should be only one `Feature` instance per unique name.
    141  // - a `Feature` contains internal cached state about the override state.
    142  Feature(const Feature&) = delete;
    143  Feature& operator=(const Feature&) = delete;
    144 
    145  // The name of the feature. This should be unique to each feature and is used
    146  // for enabling/disabling features via command line flags and experiments.
    147  // It is strongly recommended to use CamelCase style for feature names, e.g.
    148  // "MyGreatFeature".
    149  const char* const name;
    150 
    151  // The default state (i.e. enabled or disabled) for this feature.
    152  const FeatureState default_state;
    153 };
    154 
    155 class BASE_EXPORT FeatureList {
    156 public:
    157  static bool IsEnabled(const Feature& feature) {
    158    return feature.default_state == FEATURE_ENABLED_BY_DEFAULT;
    159  }
    160 
    161  static FeatureList* GetInstance() { return nullptr; }
    162 
    163  FeatureList(const FeatureList&) = delete;
    164  FeatureList& operator=(const FeatureList&) = delete;
    165 };
    166 
    167 }  // namespace base
    168 
    169 #endif  // BASE_FEATURE_LIST_H_