merge(3p/abseil_cpp): Merge upstream at 'ccdbb5941'
Change-Id: I6e85fc7b5f76bba1f1eef15e600a8acb64e97ef5
This commit is contained in:
commit
543379ce45
97 changed files with 3546 additions and 2316 deletions
105
third_party/abseil_cpp/absl/flags/internal/flag.h
vendored
105
third_party/abseil_cpp/absl/flags/internal/flag.h
vendored
|
|
@ -16,31 +16,36 @@
|
|||
#ifndef ABSL_FLAGS_INTERNAL_FLAG_H_
|
||||
#define ABSL_FLAGS_INTERNAL_FLAG_H_
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <atomic>
|
||||
#include <cstring>
|
||||
#include <memory>
|
||||
#include <new>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
#include <typeinfo>
|
||||
|
||||
#include "absl/base/attributes.h"
|
||||
#include "absl/base/call_once.h"
|
||||
#include "absl/base/config.h"
|
||||
#include "absl/base/optimization.h"
|
||||
#include "absl/base/thread_annotations.h"
|
||||
#include "absl/flags/commandlineflag.h"
|
||||
#include "absl/flags/config.h"
|
||||
#include "absl/flags/internal/commandlineflag.h"
|
||||
#include "absl/flags/internal/registry.h"
|
||||
#include "absl/flags/marshalling.h"
|
||||
#include "absl/memory/memory.h"
|
||||
#include "absl/meta/type_traits.h"
|
||||
#include "absl/strings/str_cat.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/synchronization/mutex.h"
|
||||
#include "absl/utility/utility.h"
|
||||
|
||||
namespace absl {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Forward declaration of absl::Flag<T> public API.
|
||||
namespace flags_internal {
|
||||
template <typename T>
|
||||
|
|
@ -64,12 +69,15 @@ void SetFlag(absl::Flag<T>* flag, const T& v);
|
|||
template <typename T, typename V>
|
||||
void SetFlag(absl::Flag<T>* flag, const V& v);
|
||||
|
||||
namespace flags_internal {
|
||||
template <typename U>
|
||||
const CommandLineFlag& GetFlagReflectionHandle(const absl::Flag<U>& f);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Flag value type operations, eg., parsing, copying, etc. are provided
|
||||
// by function specific to that type with a signature matching FlagOpFn.
|
||||
|
||||
namespace flags_internal {
|
||||
|
||||
enum class FlagOp {
|
||||
kAlloc,
|
||||
kDelete,
|
||||
|
|
@ -168,6 +176,28 @@ inline const std::type_info* GenRuntimeTypeId() {
|
|||
// cases.
|
||||
using HelpGenFunc = std::string (*)();
|
||||
|
||||
template <size_t N>
|
||||
struct FixedCharArray {
|
||||
char value[N];
|
||||
|
||||
template <size_t... I>
|
||||
static constexpr FixedCharArray<N> FromLiteralString(
|
||||
absl::string_view str, absl::index_sequence<I...>) {
|
||||
return (void)str, FixedCharArray<N>({{str[I]..., '\0'}});
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Gen, size_t N = Gen::Value().size()>
|
||||
constexpr FixedCharArray<N + 1> HelpStringAsArray(int) {
|
||||
return FixedCharArray<N + 1>::FromLiteralString(
|
||||
Gen::Value(), absl::make_index_sequence<N>{});
|
||||
}
|
||||
|
||||
template <typename Gen>
|
||||
constexpr std::false_type HelpStringAsArray(char) {
|
||||
return std::false_type{};
|
||||
}
|
||||
|
||||
union FlagHelpMsg {
|
||||
constexpr explicit FlagHelpMsg(const char* help_msg) : literal(help_msg) {}
|
||||
constexpr explicit FlagHelpMsg(HelpGenFunc help_gen) : gen_func(help_gen) {}
|
||||
|
|
@ -185,40 +215,28 @@ struct FlagHelpArg {
|
|||
|
||||
extern const char kStrippedFlagHelp[];
|
||||
|
||||
// HelpConstexprWrap is used by struct AbslFlagHelpGenFor##name generated by
|
||||
// ABSL_FLAG macro. It is only used to silence the compiler in the case where
|
||||
// help message expression is not constexpr and does not have type const char*.
|
||||
// If help message expression is indeed constexpr const char* HelpConstexprWrap
|
||||
// is just a trivial identity function.
|
||||
template <typename T>
|
||||
const char* HelpConstexprWrap(const T&) {
|
||||
return nullptr;
|
||||
}
|
||||
constexpr const char* HelpConstexprWrap(const char* p) { return p; }
|
||||
constexpr const char* HelpConstexprWrap(char* p) { return p; }
|
||||
|
||||
// These two HelpArg overloads allows us to select at compile time one of two
|
||||
// way to pass Help argument to absl::Flag. We'll be passing
|
||||
// AbslFlagHelpGenFor##name as T and integer 0 as a single argument to prefer
|
||||
// first overload if possible. If T::Const is evaluatable on constexpr
|
||||
// context (see non template int parameter below) we'll choose first overload.
|
||||
// In this case the help message expression is immediately evaluated and is used
|
||||
// to construct the absl::Flag. No additionl code is generated by ABSL_FLAG.
|
||||
// Otherwise SFINAE kicks in and first overload is dropped from the
|
||||
// AbslFlagHelpGenFor##name as Gen and integer 0 as a single argument to prefer
|
||||
// first overload if possible. If help message is evaluatable on constexpr
|
||||
// context We'll be able to make FixedCharArray out of it and we'll choose first
|
||||
// overload. In this case the help message expression is immediately evaluated
|
||||
// and is used to construct the absl::Flag. No additionl code is generated by
|
||||
// ABSL_FLAG Otherwise SFINAE kicks in and first overload is dropped from the
|
||||
// consideration, in which case the second overload will be used. The second
|
||||
// overload does not attempt to evaluate the help message expression
|
||||
// immediately and instead delays the evaluation by returing the function
|
||||
// pointer (&T::NonConst) genering the help message when necessary. This is
|
||||
// evaluatable in constexpr context, but the cost is an extra function being
|
||||
// generated in the ABSL_FLAG code.
|
||||
template <typename T, int = (T::Const(), 1)>
|
||||
constexpr FlagHelpArg HelpArg(int) {
|
||||
return {FlagHelpMsg(T::Const()), FlagHelpKind::kLiteral};
|
||||
template <typename Gen, size_t N>
|
||||
constexpr FlagHelpArg HelpArg(const FixedCharArray<N>& value) {
|
||||
return {FlagHelpMsg(value.value), FlagHelpKind::kLiteral};
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
constexpr FlagHelpArg HelpArg(char) {
|
||||
return {FlagHelpMsg(&T::NonConst), FlagHelpKind::kGenFunc};
|
||||
template <typename Gen>
|
||||
constexpr FlagHelpArg HelpArg(std::false_type) {
|
||||
return {FlagHelpMsg(&Gen::NonConst), FlagHelpKind::kGenFunc};
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -364,31 +382,31 @@ struct FlagValue;
|
|||
|
||||
template <typename T>
|
||||
struct FlagValue<T, FlagValueStorageKind::kAlignedBuffer> {
|
||||
bool Get(T*) const { return false; }
|
||||
bool Get(T&) const { return false; }
|
||||
|
||||
alignas(T) char value[sizeof(T)];
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct FlagValue<T, FlagValueStorageKind::kOneWordAtomic> : FlagOneWordValue {
|
||||
bool Get(T* dst) const {
|
||||
bool Get(T& dst) const {
|
||||
int64_t one_word_val = value.load(std::memory_order_acquire);
|
||||
if (ABSL_PREDICT_FALSE(one_word_val == UninitializedFlagValue())) {
|
||||
return false;
|
||||
}
|
||||
std::memcpy(dst, static_cast<const void*>(&one_word_val), sizeof(T));
|
||||
std::memcpy(&dst, static_cast<const void*>(&one_word_val), sizeof(T));
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct FlagValue<T, FlagValueStorageKind::kTwoWordsAtomic> : FlagTwoWordsValue {
|
||||
bool Get(T* dst) const {
|
||||
bool Get(T& dst) const {
|
||||
AlignedTwoWords two_words_val = value.load(std::memory_order_acquire);
|
||||
if (ABSL_PREDICT_FALSE(!two_words_val.IsInitialized())) {
|
||||
return false;
|
||||
}
|
||||
std::memcpy(dst, static_cast<const void*>(&two_words_val), sizeof(T));
|
||||
std::memcpy(&dst, static_cast<const void*>(&two_words_val), sizeof(T));
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
|
@ -419,7 +437,7 @@ struct DynValueDeleter {
|
|||
|
||||
class FlagState;
|
||||
|
||||
class FlagImpl final : public flags_internal::CommandLineFlag {
|
||||
class FlagImpl final : public CommandLineFlag {
|
||||
public:
|
||||
constexpr FlagImpl(const char* name, const char* filename, FlagOpFn op,
|
||||
FlagHelpArg help, FlagValueStorageKind value_kind,
|
||||
|
|
@ -492,7 +510,7 @@ class FlagImpl final : public flags_internal::CommandLineFlag {
|
|||
// Attempts to parse supplied `value` string. If parsing is successful,
|
||||
// returns new value. Otherwise returns nullptr.
|
||||
std::unique_ptr<void, DynValueDeleter> TryParse(absl::string_view value,
|
||||
std::string* err) const
|
||||
std::string& err) const
|
||||
ABSL_EXCLUSIVE_LOCKS_REQUIRED(*DataGuard());
|
||||
// Stores the flag value based on the pointer to the source.
|
||||
void StoreValue(const void* src) ABSL_EXCLUSIVE_LOCKS_REQUIRED(*DataGuard());
|
||||
|
|
@ -534,7 +552,7 @@ class FlagImpl final : public flags_internal::CommandLineFlag {
|
|||
ABSL_LOCKS_EXCLUDED(*DataGuard());
|
||||
|
||||
bool ParseFrom(absl::string_view value, FlagSettingMode set_mode,
|
||||
ValueSource source, std::string* error) override
|
||||
ValueSource source, std::string& error) override
|
||||
ABSL_LOCKS_EXCLUDED(*DataGuard());
|
||||
|
||||
// Immutable flag's state.
|
||||
|
|
@ -641,7 +659,7 @@ class Flag {
|
|||
impl_.AssertValidType(base_internal::FastTypeId<T>(), &GenRuntimeTypeId<T>);
|
||||
#endif
|
||||
|
||||
if (!value_.Get(&u.value)) impl_.Read(&u.value);
|
||||
if (!value_.Get(u.value)) impl_.Read(&u.value);
|
||||
return std::move(u.value);
|
||||
}
|
||||
void Set(const T& v) {
|
||||
|
|
@ -649,6 +667,13 @@ class Flag {
|
|||
impl_.Write(&v);
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
friend const CommandLineFlag& absl::GetFlagReflectionHandle(
|
||||
const absl::Flag<U>& f);
|
||||
|
||||
// Access to the reflection.
|
||||
const CommandLineFlag& Reflect() const { return impl_; }
|
||||
|
||||
// Flag's data
|
||||
// The implementation depends on value_ field to be placed exactly after the
|
||||
// impl_ field, so that impl_ can figure out the offset to the value and
|
||||
|
|
@ -720,12 +745,12 @@ struct FlagRegistrarEmpty {};
|
|||
template <typename T, bool do_register>
|
||||
class FlagRegistrar {
|
||||
public:
|
||||
explicit FlagRegistrar(Flag<T>* flag) : flag_(flag) {
|
||||
if (do_register) flags_internal::RegisterCommandLineFlag(&flag_->impl_);
|
||||
explicit FlagRegistrar(Flag<T>& flag) : flag_(flag) {
|
||||
if (do_register) flags_internal::RegisterCommandLineFlag(flag_.impl_);
|
||||
}
|
||||
|
||||
FlagRegistrar OnUpdate(FlagCallbackFunc cb) && {
|
||||
flag_->impl_.SetCallback(cb);
|
||||
flag_.impl_.SetCallback(cb);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
|
@ -735,7 +760,7 @@ class FlagRegistrar {
|
|||
operator FlagRegistrarEmpty() const { return {}; } // NOLINT
|
||||
|
||||
private:
|
||||
Flag<T>* flag_; // Flag being registered (not owned).
|
||||
Flag<T>& flag_; // Flag being registered (not owned).
|
||||
};
|
||||
|
||||
} // namespace flags_internal
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue