diff options
Diffstat (limited to 'absl/flags')
-rw-r--r-- | absl/flags/flag.h | 33 | ||||
-rw-r--r-- | absl/flags/internal/flag.h | 28 |
2 files changed, 27 insertions, 34 deletions
diff --git a/absl/flags/flag.h b/absl/flags/flag.h index bd61668ff4f1..fcfdd58cbf4a 100644 --- a/absl/flags/flag.h +++ b/absl/flags/flag.h @@ -186,15 +186,17 @@ class Flag { // // // FLAGS_firstname is a Flag of type `std::string` // std::string first_name = absl::GetFlag(FLAGS_firstname); +template <typename T> +ABSL_MUST_USE_RESULT T GetFlag(const absl::Flag<T>& flag) { + return flag.Get(); +} + #ifndef NDEBUG // We want to validate the type mismatch between type definition and // declaration. The lock-free implementation does not allow us to do it, // so in debug builds we always use the slower implementation, which always // validates the type. -template <typename T> -ABSL_MUST_USE_RESULT T GetFlag(const absl::Flag<T>& flag) { - return flag.Get(); -} + // We currently need an external linkage for built-in types because shared // libraries have different addresses of flags_internal::FlagOps<T> which // might cause log spam when checking the same flag type. @@ -202,29 +204,6 @@ ABSL_MUST_USE_RESULT T GetFlag(const absl::Flag<T>& flag) { ABSL_MUST_USE_RESULT T GetFlag(const absl::Flag<T>& flag); ABSL_FLAGS_INTERNAL_BUILTIN_TYPES(ABSL_FLAGS_INTERNAL_BUILT_IN_EXPORT) #undef ABSL_FLAGS_INTERNAL_BUILT_IN_EXPORT -#else -template <typename T, - typename std::enable_if< - !flags_internal::IsAtomicFlagTypeTrait<T>::value, int>::type = 0> -ABSL_MUST_USE_RESULT T GetFlag(const absl::Flag<T>& flag) { - return flag.Get(); -} -// Overload for `GetFlag()` for types that support lock-free reads. -template <typename T, - typename std::enable_if< - flags_internal::IsAtomicFlagTypeTrait<T>::value, int>::type = 0> -ABSL_MUST_USE_RESULT T GetFlag(const absl::Flag<T>& flag) { - // T might not be default constructible. - union U { - T value; - U() {} - }; - U result; - if (flag.AtomicGet(&result.value)) { - return result.value; - } - return flag.Get(); -} #endif // SetFlag() diff --git a/absl/flags/internal/flag.h b/absl/flags/internal/flag.h index ec467c3194ef..4341f1137d9d 100644 --- a/absl/flags/internal/flag.h +++ b/absl/flags/internal/flag.h @@ -244,16 +244,32 @@ class FlagImpl { bool TryParse(void** dst, absl::string_view value, std::string* err) const ABSL_EXCLUSIVE_LOCKS_REQUIRED(*DataGuard()); +#ifndef NDEBUG template <typename T> - bool AtomicGet(T* v) const { + void Get(T* dst) const { + Read(dst, &flags_internal::FlagOps<T>); + } +#else + template <typename T, typename std::enable_if< + !flags_internal::IsAtomicFlagTypeTrait<T>::value, + int>::type = 0> + void Get(T* dst) const { + Read(dst, &flags_internal::FlagOps<T>); + } + // Overload for `GetFlag()` for types that support lock-free reads. + template <typename T, + typename std::enable_if< + flags_internal::IsAtomicFlagTypeTrait<T>::value, int>::type = 0> + void Get(T* dst) const { using U = flags_internal::BestAtomicType<T>; const typename U::type r = atomics_.template load<T>(); if (r != U::AtomicInit()) { - std::memcpy(static_cast<void*>(v), &r, sizeof(T)); - return true; + std::memcpy(static_cast<void*>(dst), &r, sizeof(T)); + } else { + Read(dst, &flags_internal::FlagOps<T>); } - return false; } +#endif // Mutating access methods void Write(const void* src, const flags_internal::FlagOpFn src_op) @@ -397,12 +413,10 @@ class Flag final : public flags_internal::CommandLineFlag { }; U u; - impl_.Read(&u.value, &flags_internal::FlagOps<T>); + impl_.Get(&u.value); return std::move(u.value); } - bool AtomicGet(T* v) const { return impl_.AtomicGet(v); } - void Set(const T& v) { impl_.Write(&v, &flags_internal::FlagOps<T>); } void SetCallback(const flags_internal::FlagCallback mutation_callback) { |