Export of internal Abseil changes
-- d6748c733a70cd74ad9b76a0c9cd6b3fe2cecacf by Xiaoyi Zhang <zhangxy@google.com>: Remove empty block, to address alerts reported in https://github.com/abseil/abseil-cpp/issues/368. PiperOrigin-RevId: 265099887 -- 232e2036b5668d6d1296b881f9347756d84541ee by Derek Mauro <dmauro@google.com>: Make the Linux Bazel CI scripts test with the exception mode explicitly set. PiperOrigin-RevId: 265092105 -- 942a40696c2c9b833be03e92d22a6ede7bccb6d4 by Xiaoyi Zhang <zhangxy@google.com>: Import https://github.com/abseil/abseil-cpp/pull/372. Suppress the unused variable warning on GCC, i.e. "-Wunused-variable". PiperOrigin-RevId: 265063925 -- 7ef90796b52cbdc260afc77cf47206f9356471d0 by Xiaoyi Zhang <zhangxy@google.com>: Add quotes to `ABSL_COMMON_INCLUDE_DIRS` since it's a list and may contain a `;`. This addresses https://github.com/abseil/abseil-cpp/issues/373. PiperOrigin-RevId: 265059077 -- 43f3ae742e00b83672ad6c5bc5b17fdb8f9fe6fe by Gennadiy Rozental <rogeeff@google.com>: Internal re-organization PiperOrigin-RevId: 264913945 -- 6a2adf9c08ee1d98cc6b2855a676345c6495294a by Andy Soffer <asoffer@google.com>: Publicly expose type names for uniform interval tags as in, for example, absl::IntervalClosedClosedTag, and add equality comparison operators. PiperOrigin-RevId: 264861162 -- 3c90c6e05fd61d56b419cd2d39dab8f17b8711b8 by Abseil Team <absl-team@google.com>: Add validity check on returned frame pointer. PiperOrigin-RevId: 264858823 -- 2db87e0cfa0c6bea7ba81684b834cb8a73b7d748 by Gennadiy Rozental <rogeeff@google.com>: Add MUST_USE_RESULT attribute to absl::GetFlag to prevent accidental misuse. PiperOrigin-RevId: 264782762 GitOrigin-RevId: d6748c733a70cd74ad9b76a0c9cd6b3fe2cecacf Change-Id: I169e9c5358e4f63000c1255e806d26b8afecf5ff
This commit is contained in:
parent
0302d1e5fa
commit
2d2d7fbc28
24 changed files with 550 additions and 393 deletions
|
|
@ -63,8 +63,100 @@ namespace absl {
|
|||
// ABSL_FLAG(int, count, 0, "Count of items to process");
|
||||
//
|
||||
// No public methods of `absl::Flag<T>` are part of the Abseil Flags API.
|
||||
#if !defined(_MSC_VER)
|
||||
template <typename T>
|
||||
using Flag = flags_internal::Flag<T>;
|
||||
#else
|
||||
// MSVC debug builds do not implement constexpr correctly for classes with
|
||||
// virtual methods. To work around this we adding level of indirection, so that
|
||||
// the class `absl::Flag` contains an `internal::Flag*` (instead of being an
|
||||
// alias to that class) and dynamically allocates an instance when necessary.
|
||||
// We also forward all calls to internal::Flag methods via trampoline methods.
|
||||
// In this setup the `absl::Flag` class does not have virtual methods and thus
|
||||
// MSVC is able to initialize it at link time. To deal with multiple threads
|
||||
// accessing the flag for the first time concurrently we use an atomic boolean
|
||||
// indicating if flag object is constructed. We also employ the double-checked
|
||||
// locking pattern where the second level of protection is a global Mutex, so
|
||||
// if two threads attempt to construct the flag concurrently only one wins.
|
||||
|
||||
namespace flags_internal {
|
||||
void LockGlobalConstructionGuard();
|
||||
void UnlockGlobalConstructionGuard();
|
||||
} // namespace flags_internal
|
||||
|
||||
template <typename T>
|
||||
class Flag {
|
||||
public:
|
||||
constexpr Flag(const char* name, const flags_internal::HelpGenFunc help_gen,
|
||||
const char* filename,
|
||||
const flags_internal::FlagMarshallingOpFn marshalling_op,
|
||||
const flags_internal::InitialValGenFunc initial_value_gen)
|
||||
: name_(name),
|
||||
help_gen_(help_gen),
|
||||
filename_(filename),
|
||||
marshalling_op_(marshalling_op),
|
||||
initial_value_gen_(initial_value_gen),
|
||||
inited_(false) {}
|
||||
|
||||
flags_internal::Flag<T>* GetImpl() const {
|
||||
if (!inited_.load(std::memory_order_acquire)) {
|
||||
flags_internal::LockGlobalConstructionGuard();
|
||||
|
||||
if (inited_.load(std::memory_order_acquire)) {
|
||||
return impl_;
|
||||
}
|
||||
|
||||
impl_ = new flags_internal::Flag<T>(name_, help_gen_, filename_,
|
||||
marshalling_op_, initial_value_gen_);
|
||||
inited_.store(true, std::memory_order_release);
|
||||
|
||||
flags_internal::UnlockGlobalConstructionGuard();
|
||||
}
|
||||
|
||||
return impl_;
|
||||
}
|
||||
|
||||
// absl::Flag API
|
||||
bool IsRetired() const { return GetImpl()->IsRetired(); }
|
||||
bool IsAbseilFlag() const { return GetImpl()->IsAbseilFlag(); }
|
||||
absl::string_view Name() const { return GetImpl()->Name(); }
|
||||
std::string Help() const { return GetImpl()->Help(); }
|
||||
bool IsModified() const { return GetImpl()->IsModified(); }
|
||||
void SetModified(bool is_modified) { GetImpl()->SetModified(is_modified); }
|
||||
bool IsSpecifiedOnCommandLine() const {
|
||||
GetImpl()->IsSpecifiedOnCommandLine();
|
||||
}
|
||||
absl::string_view Typename() const { return GetImpl()->Typename(); }
|
||||
std::string Filename() const { return GetImpl()->Filename(); }
|
||||
std::string DefaultValue() const { return GetImpl()->DefaultValue(); }
|
||||
std::string CurrentValue() const { return GetImpl()->CurrentValue(); }
|
||||
bool HasValidatorFn() const { return GetImpl()->HasValidatorFn(); }
|
||||
bool InvokeValidator(const void* value) const {
|
||||
return GetImpl()->InvokeValidator(value);
|
||||
}
|
||||
template <typename T>
|
||||
inline bool IsOfType() const {
|
||||
return GetImpl()->IsOftype<T>();
|
||||
}
|
||||
T Get() const { return GetImpl()->Get(); }
|
||||
bool AtomicGet(T* v) const { return GetImpl()->AtomicGet(v); }
|
||||
void Set(const T& v) { GetImpl()->Set(v); }
|
||||
void SetCallback(const flags_internal::FlagCallback mutation_callback) {
|
||||
GetImpl()->SetCallback(mutation_callback);
|
||||
}
|
||||
void InvokeCallback() { GetImpl()->InvokeCallback(); }
|
||||
|
||||
private:
|
||||
const char* name_;
|
||||
const flags_internal::HelpGenFunc help_gen_;
|
||||
const char* filename_;
|
||||
const flags_internal::FlagMarshallingOpFn marshalling_op_;
|
||||
const flags_internal::InitialValGenFunc initial_value_gen_;
|
||||
|
||||
mutable std::atomic<bool> inited_;
|
||||
mutable flags_internal::Flag<T>* impl_ = nullptr;
|
||||
};
|
||||
#endif
|
||||
|
||||
// GetFlag()
|
||||
//
|
||||
|
|
@ -83,7 +175,7 @@ using Flag = flags_internal::Flag<T>;
|
|||
// // FLAGS_firstname is a Flag of type `std::string`
|
||||
// std::string first_name = absl::GetFlag(FLAGS_firstname);
|
||||
template <typename T>
|
||||
T GetFlag(const absl::Flag<T>& flag) {
|
||||
ABSL_MUST_USE_RESULT T GetFlag(const absl::Flag<T>& flag) {
|
||||
#define ABSL_FLAGS_INTERNAL_LOCK_FREE_VALIDATE(BIT) \
|
||||
static_assert( \
|
||||
!std::is_same<T, BIT>::value, \
|
||||
|
|
@ -96,7 +188,7 @@ T GetFlag(const absl::Flag<T>& flag) {
|
|||
|
||||
// Overload for `GetFlag()` for types that support lock-free reads.
|
||||
#define ABSL_FLAGS_INTERNAL_LOCK_FREE_EXPORT(T) \
|
||||
extern T GetFlag(const absl::Flag<T>& flag);
|
||||
ABSL_MUST_USE_RESULT T GetFlag(const absl::Flag<T>& flag);
|
||||
ABSL_FLAGS_INTERNAL_FOR_EACH_LOCK_FREE(ABSL_FLAGS_INTERNAL_LOCK_FREE_EXPORT)
|
||||
#undef ABSL_FLAGS_INTERNAL_LOCK_FREE_EXPORT
|
||||
|
||||
|
|
@ -184,13 +276,23 @@ void SetFlag(absl::Flag<T>* flag, const V& v) {
|
|||
#if ABSL_FLAGS_STRIP_NAMES
|
||||
#define ABSL_FLAG_IMPL_FLAGNAME(txt) ""
|
||||
#define ABSL_FLAG_IMPL_FILENAME() ""
|
||||
#if !defined(_MSC_VER)
|
||||
#define ABSL_FLAG_IMPL_REGISTRAR(T, flag) \
|
||||
absl::flags_internal::FlagRegistrar<T, false>(&flag)
|
||||
#else
|
||||
#define ABSL_FLAG_IMPL_REGISTRAR(T, flag) \
|
||||
absl::flags_internal::FlagRegistrar<T, false>(flag.GetImpl())
|
||||
#endif
|
||||
#else
|
||||
#define ABSL_FLAG_IMPL_FLAGNAME(txt) txt
|
||||
#define ABSL_FLAG_IMPL_FILENAME() __FILE__
|
||||
#if !defined(_MSC_VER)
|
||||
#define ABSL_FLAG_IMPL_REGISTRAR(T, flag) \
|
||||
absl::flags_internal::FlagRegistrar<T, true>(&flag)
|
||||
#else
|
||||
#define ABSL_FLAG_IMPL_REGISTRAR(T, flag) \
|
||||
absl::flags_internal::FlagRegistrar<T, true>(flag.GetImpl())
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// ABSL_FLAG_IMPL macro definition conditional on ABSL_FLAGS_STRIP_HELP
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue