Skip to content

Instantly share code, notes, and snippets.

@danlark1
Last active January 11, 2020 21:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save danlark1/9d42bfaef141a97b7dcd015ddd002b50 to your computer and use it in GitHub Desktop.
Save danlark1/9d42bfaef141a97b7dcd015ddd002b50 to your computer and use it in GitHub Desktop.
// ABSL_CONST_INIT
//
// A variable declaration annotated with the `ABSL_CONST_INIT` attribute will
// not compile (on supported platforms) unless the variable has a constant
// initializer. This is useful for variables with static and thread storage
// duration, because it guarantees that they will not suffer from the so-called
// "static init order fiasco". Prefer to put this attribute on the most visible
// declaration of the variable, if there's more than one, because code that
// accesses the variable can then use the attribute for optimization.
// Note that this attribute is redundant if the variable is declared constexpr.
#define ABSL_CONST_INIT [[clang::require_constant_initialization]]
// This struct and corresponding overload to MakeDefaultValue are used to
// facilitate usage of {} as default value in ABSL_FLAG macro.
struct EmptyBraces {};
template <typename T>
T* MakeFromDefaultValue(T t) {
return new T(std::move(t));
}
template <typename T>
T* MakeFromDefaultValue(EmptyBraces) {
return new T;
}
#define ABSL_FLAG_IMPL_DECLARE_DEF_VAL_WRAPPER(name, Type, default_value) \
static void* AbslFlagsInitFlag##name() { \
return absl::flags_internal::MakeFromDefaultValue<Type>(default_value); \
}
#define ABSL_FLAG(Type, name, default_value, help) \
namespace absl /* block flags in namespaces */ {} \
ABSL_FLAG_IMPL_DECLARE_DEF_VAL_WRAPPER(name, Type, default_value) \ // Creating a function to create a default flag
ABSL_FLAG_IMPL_DECLARE_HELP_WRAPPER(name, help); \
ABSL_CONST_INIT absl::Flag<Type> FLAGS_##name{ \ // Const init initialization (see above)
ABSL_FLAG_IMPL_FLAGNAME(#name), ABSL_FLAG_IMPL_FILENAME(), \ // Both compile time pointers.
&absl::flags_internal::FlagMarshallingOps<Type>, \ // Compile time pointer to dispatch the operations.
absl::flags_internal::HelpArg<AbslFlagHelpGenFor##name>(0), \ // Compile time struct to generate --help values.
&AbslFlagsInitFlag##name}; // Compile time pointer from line 34.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment