Export of internal Abseil changes
-- 24162e64040e89f174531fa78fc0ff43c3a67da4 by Abseil Team <absl-team@google.com>: Make ABSL_RETIRED_FLAG behave consistently with ABSL_FLAG. Before the change: ABSL_RETIRED_FLAG does not compile when there are competing ctors in the type, even when ABSL_FLAG does. After the change: ABSL_RETIRED_FLAG compiles when ABSL_FLAG does. PiperOrigin-RevId: 286437395 -- 870d4cb4d114813e9cefe30d26d020b0fdcdc4b4 by Tom Manshreck <shreck@google.com>: Add docs on bind_front PiperOrigin-RevId: 286433540 -- b0c328bd9bb64e0382f942f93b85054229dafeac by Tom Manshreck <shreck@google.com>: Specify the format for LogSeverity flags PiperOrigin-RevId: 286402811 GitOrigin-RevId: 24162e64040e89f174531fa78fc0ff43c3a67da4 Change-Id: I89785145d049fee49c6b9cf3357893ece9a6231c
This commit is contained in:
parent
7bd1935dcb
commit
ad904b6cd3
5 changed files with 127 additions and 34 deletions
|
@ -24,19 +24,45 @@
|
||||||
namespace absl {
|
namespace absl {
|
||||||
ABSL_NAMESPACE_BEGIN
|
ABSL_NAMESPACE_BEGIN
|
||||||
|
|
||||||
// Four severity levels are defined. Logging APIs should terminate the program
|
// absl::LogSeverity
|
||||||
|
//
|
||||||
|
// Four severity levels are defined. Logging APIs should terminate the program
|
||||||
// when a message is logged at severity `kFatal`; the other levels have no
|
// when a message is logged at severity `kFatal`; the other levels have no
|
||||||
// special semantics.
|
// special semantics.
|
||||||
//
|
//
|
||||||
// Abseil flags may be defined with type `LogSeverity`. Dependency layering
|
// Values other than the four defined levels (e.g. produced by `static_cast`)
|
||||||
// constraints require that the `AbslParseFlag` overload be declared and defined
|
// are valid, but their semantics when passed to a function, macro, or flag
|
||||||
// in the flags module rather than here. The `AbslUnparseFlag` overload is
|
// depend on the function, macro, or flag. The usual behavior is to normalize
|
||||||
// defined there too for consistency.
|
// such values to a defined severity level, however in some cases values other
|
||||||
|
// than the defined levels are useful for comparison.
|
||||||
//
|
//
|
||||||
// The parser accepts arbitrary integers (as if the type were `int`). It also
|
// Exmaple:
|
||||||
// accepts each named enumerator, without regard for case, with or without the
|
//
|
||||||
// leading 'k'. For example: "kInfo", "INFO", and "info" all parse to the value
|
// // Effectively disables all logging:
|
||||||
// `absl::LogSeverity::kInfo`.
|
// SetMinLogLevel(static_cast<absl::LogSeverity>(100));
|
||||||
|
//
|
||||||
|
// Abseil flags may be defined with type `LogSeverity`. Dependency layering
|
||||||
|
// constraints require that the `AbslParseFlag()` overload be declared and
|
||||||
|
// defined in the flags library itself rather than here. The `AbslUnparseFlag()`
|
||||||
|
// overload is defined there as well for consistency.
|
||||||
|
//
|
||||||
|
// absl::LogSeverity Flag String Representation
|
||||||
|
//
|
||||||
|
// An `absl::LogSeverity` has a string representation used for parsing
|
||||||
|
// command-line flags based on the enumerator name (e.g. `kFatal`) or
|
||||||
|
// its unprefixed name (without the `k`) in any case-insensitive form. (E.g.
|
||||||
|
// "FATAL", "fatal" or "Fatal" are all valid.) Unparsing such flags produces an
|
||||||
|
// unprefixed string representation in all caps (e.g. "FATAL") or an integer.
|
||||||
|
//
|
||||||
|
// Additionally, the parser accepts arbitrary integers (as if the type were
|
||||||
|
// `int`).
|
||||||
|
//
|
||||||
|
// Examples:
|
||||||
|
//
|
||||||
|
// --my_log_level=kInfo
|
||||||
|
// --my_log_level=INFO
|
||||||
|
// --my_log_level=info
|
||||||
|
// --my_log_level=0
|
||||||
//
|
//
|
||||||
// Unparsing a flag produces the same result as `absl::LogSeverityName()` for
|
// Unparsing a flag produces the same result as `absl::LogSeverityName()` for
|
||||||
// the standard levels and a base-ten integer otherwise.
|
// the standard levels and a base-ten integer otherwise.
|
||||||
|
@ -47,6 +73,8 @@ enum class LogSeverity : int {
|
||||||
kFatal = 3,
|
kFatal = 3,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// LogSeverities()
|
||||||
|
//
|
||||||
// Returns an iterable of all standard `absl::LogSeverity` values, ordered from
|
// Returns an iterable of all standard `absl::LogSeverity` values, ordered from
|
||||||
// least to most severe.
|
// least to most severe.
|
||||||
constexpr std::array<absl::LogSeverity, 4> LogSeverities() {
|
constexpr std::array<absl::LogSeverity, 4> LogSeverities() {
|
||||||
|
@ -54,6 +82,8 @@ constexpr std::array<absl::LogSeverity, 4> LogSeverities() {
|
||||||
absl::LogSeverity::kError, absl::LogSeverity::kFatal}};
|
absl::LogSeverity::kError, absl::LogSeverity::kFatal}};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// LogSeverityName()
|
||||||
|
//
|
||||||
// Returns the all-caps string representation (e.g. "INFO") of the specified
|
// Returns the all-caps string representation (e.g. "INFO") of the specified
|
||||||
// severity level if it is one of the standard levels and "UNKNOWN" otherwise.
|
// severity level if it is one of the standard levels and "UNKNOWN" otherwise.
|
||||||
constexpr const char* LogSeverityName(absl::LogSeverity s) {
|
constexpr const char* LogSeverityName(absl::LogSeverity s) {
|
||||||
|
@ -66,6 +96,8 @@ constexpr const char* LogSeverityName(absl::LogSeverity s) {
|
||||||
: s == absl::LogSeverity::kFatal ? "FATAL" : "UNKNOWN";
|
: s == absl::LogSeverity::kFatal ? "FATAL" : "UNKNOWN";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NormalizeLogSeverity()
|
||||||
|
//
|
||||||
// Values less than `kInfo` normalize to `kInfo`; values greater than `kFatal`
|
// Values less than `kInfo` normalize to `kInfo`; values greater than `kFatal`
|
||||||
// normalize to `kError` (**NOT** `kFatal`).
|
// normalize to `kError` (**NOT** `kFatal`).
|
||||||
constexpr absl::LogSeverity NormalizeLogSeverity(absl::LogSeverity s) {
|
constexpr absl::LogSeverity NormalizeLogSeverity(absl::LogSeverity s) {
|
||||||
|
@ -77,6 +109,8 @@ constexpr absl::LogSeverity NormalizeLogSeverity(int s) {
|
||||||
return absl::NormalizeLogSeverity(static_cast<absl::LogSeverity>(s));
|
return absl::NormalizeLogSeverity(static_cast<absl::LogSeverity>(s));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// operator<<
|
||||||
|
//
|
||||||
// The exact representation of a streamed `absl::LogSeverity` is deliberately
|
// The exact representation of a streamed `absl::LogSeverity` is deliberately
|
||||||
// unspecified; do not rely on it.
|
// unspecified; do not rely on it.
|
||||||
std::ostream& operator<<(std::ostream& os, absl::LogSeverity s);
|
std::ostream& operator<<(std::ostream& os, absl::LogSeverity s);
|
||||||
|
|
|
@ -384,11 +384,19 @@ ABSL_NAMESPACE_END
|
||||||
//
|
//
|
||||||
// `default_value` is only used as a double check on the type. `explanation` is
|
// `default_value` is only used as a double check on the type. `explanation` is
|
||||||
// unused.
|
// unused.
|
||||||
|
//
|
||||||
|
// ABSL_RETIRED_FLAG support omitting the default value for default
|
||||||
|
// constructible value type, so that users can delete the code generatring this
|
||||||
|
// value.
|
||||||
|
//
|
||||||
// TODO(rogeeff): Return an anonymous struct instead of bool, and place it into
|
// TODO(rogeeff): Return an anonymous struct instead of bool, and place it into
|
||||||
// the unnamed namespace.
|
// the unnamed namespace.
|
||||||
#define ABSL_RETIRED_FLAG(type, flagname, default_value, explanation) \
|
#define ABSL_RETIRED_FLAG(type, flagname, default_value, explanation) \
|
||||||
ABSL_ATTRIBUTE_UNUSED static const bool ignored_##flagname = \
|
ABSL_ATTRIBUTE_UNUSED static const bool ignored_##flagname = \
|
||||||
([] { return type(default_value); }, \
|
([] { \
|
||||||
|
return absl::flags_internal::MakeFromDefaultValueOrEmpty<type>( \
|
||||||
|
default_value); \
|
||||||
|
}, \
|
||||||
absl::flags_internal::RetiredFlag<type>(#flagname))
|
absl::flags_internal::RetiredFlag<type>(#flagname))
|
||||||
|
|
||||||
#endif // ABSL_FLAGS_FLAG_H_
|
#endif // ABSL_FLAGS_FLAG_H_
|
||||||
|
|
|
@ -486,11 +486,30 @@ TEST_F(FlagTest, TestNonDefaultConstructibleType) {
|
||||||
|
|
||||||
// --------------------------------------------------------------------
|
// --------------------------------------------------------------------
|
||||||
|
|
||||||
|
struct Wrapper {
|
||||||
|
Wrapper() {}
|
||||||
|
|
||||||
|
// NOLINTNEXTLINE(runtime/explicit)
|
||||||
|
Wrapper(const std::string& val) : val(val) {}
|
||||||
|
|
||||||
|
// NOLINTNEXTLINE(runtime/explicit)
|
||||||
|
template <typename T>
|
||||||
|
Wrapper(T&& t) : val(std::forward<T>(t)) {}
|
||||||
|
|
||||||
|
// NOLINTNEXTLINE(runtime/explicit)
|
||||||
|
operator std::string() const& { return val; }
|
||||||
|
|
||||||
|
std::string val;
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
ABSL_RETIRED_FLAG(bool, old_bool_flag, true, "old descr");
|
ABSL_RETIRED_FLAG(bool, old_bool_flag, true, "old descr");
|
||||||
ABSL_RETIRED_FLAG(int, old_int_flag, (int)std::sqrt(10), "old descr");
|
ABSL_RETIRED_FLAG(int, old_int_flag, (int)std::sqrt(10), "old descr");
|
||||||
ABSL_RETIRED_FLAG(std::string, old_str_flag, "", absl::StrCat("old ", "descr"));
|
ABSL_RETIRED_FLAG(std::string, old_str_flag, "", absl::StrCat("old ", "descr"));
|
||||||
|
ABSL_RETIRED_FLAG(Wrapper, old_wrapper_flag, {}, "old wrapper");
|
||||||
|
ABSL_RETIRED_FLAG(Wrapper, old_wrapper_no_default_flag, ,
|
||||||
|
"old wrapper no default");
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
@ -502,6 +521,10 @@ TEST_F(FlagTest, TestRetiredFlagRegistration) {
|
||||||
EXPECT_FALSE(is_bool);
|
EXPECT_FALSE(is_bool);
|
||||||
EXPECT_TRUE(flags::IsRetiredFlag("old_str_flag", &is_bool));
|
EXPECT_TRUE(flags::IsRetiredFlag("old_str_flag", &is_bool));
|
||||||
EXPECT_FALSE(is_bool);
|
EXPECT_FALSE(is_bool);
|
||||||
|
EXPECT_TRUE(flags::IsRetiredFlag("old_wrapper_flag", &is_bool));
|
||||||
|
EXPECT_FALSE(is_bool);
|
||||||
|
EXPECT_TRUE(flags::IsRetiredFlag("old_wrapper_no_default_flag", &is_bool));
|
||||||
|
EXPECT_FALSE(is_bool);
|
||||||
EXPECT_FALSE(flags::IsRetiredFlag("some_other_flag", &is_bool));
|
EXPECT_FALSE(flags::IsRetiredFlag("some_other_flag", &is_bool));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -416,6 +416,20 @@ T* MakeFromDefaultValue(EmptyBraces) {
|
||||||
return new T;
|
return new T;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MakeFromDefaultValueOrEmpty is basically the same as MakeFromDefaultValue. It
|
||||||
|
// also allows for empty macro parameter (hence no argument), which was somehow
|
||||||
|
// widely used for ABSL_RETIRED_FLAG().
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
T* MakeFromDefaultValueOrEmpty(T t) {
|
||||||
|
return MakeFromDefaultValue(std::move(t));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
T* MakeFromDefaultValueOrEmpty() {
|
||||||
|
return MakeFromDefaultValue<T>(EmptyBraces());
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace flags_internal
|
} // namespace flags_internal
|
||||||
ABSL_NAMESPACE_END
|
ABSL_NAMESPACE_END
|
||||||
} // namespace absl
|
} // namespace absl
|
||||||
|
|
|
@ -11,17 +11,44 @@
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
// `absl::bind_front()` returns a functor by binding a number of arguments to
|
|
||||||
// the front of a provided functor, allowing you to avoid known problems with
|
|
||||||
// `std::bind()`. It is a form of partial function application
|
|
||||||
// https://en.wikipedia.org/wiki/Partial_application.
|
|
||||||
//
|
//
|
||||||
// Like `std::bind()` it is implicitly convertible to `std::function`. In
|
// -----------------------------------------------------------------------------
|
||||||
// particular, it may be used as a simpler replacement for `std::bind()` in most
|
// File: bind_front.h
|
||||||
// cases, as it does not require placeholders to be specified. More
|
// -----------------------------------------------------------------------------
|
||||||
// importantly, it provides more reliable correctness guarantees than
|
//
|
||||||
// `std::bind()`.
|
// `absl::bind_front()` returns a functor by binding a number of arguments to
|
||||||
|
// the front of a provided (usually more generic) functor. Unlike `std::bind`,
|
||||||
|
// it does not require the use of argument placeholders. The simpler syntax of
|
||||||
|
// `absl::bind_front()` allows you to avoid known misuses with `std::bind()`.
|
||||||
|
//
|
||||||
|
// `absl::bind_front()` is meant as a drop-in replacement for C++20's upcoming
|
||||||
|
// `std::bind_front()`, which similarly resolves these issues with
|
||||||
|
// `std::bind()`. Both `bind_front()` alternatives, unlike `std::bind()`, allow
|
||||||
|
// partial function application. (See
|
||||||
|
// https://en.wikipedia.org/wiki/Partial_application).
|
||||||
|
|
||||||
|
#ifndef ABSL_FUNCTIONAL_BIND_FRONT_H_
|
||||||
|
#define ABSL_FUNCTIONAL_BIND_FRONT_H_
|
||||||
|
|
||||||
|
#include "absl/functional/internal/front_binder.h"
|
||||||
|
#include "absl/utility/utility.h"
|
||||||
|
|
||||||
|
namespace absl {
|
||||||
|
ABSL_NAMESPACE_BEGIN
|
||||||
|
|
||||||
|
// bind_front()
|
||||||
|
//
|
||||||
|
// Binds the first N arguments of an invocable object and stores them by value,
|
||||||
|
// except types of `std::reference_wrapper` which are 'unwound' and stored by
|
||||||
|
// reference.
|
||||||
|
//
|
||||||
|
// Like `std::bind()`, `absl::bind_front()` is implicitly convertible to
|
||||||
|
// `std::function`. In particular, it may be used as a simpler replacement for
|
||||||
|
// `std::bind()` in most cases, as it does not require placeholders to be
|
||||||
|
// specified. More importantly, it provides more reliable correctness guarantees
|
||||||
|
// than `std::bind()`; while `std::bind()` will silently ignore passing more
|
||||||
|
// parameters than expected, for example, `absl::bind_front()` will report such
|
||||||
|
// mis-uses as errors.
|
||||||
//
|
//
|
||||||
// absl::bind_front(a...) can be seen as storing the results of
|
// absl::bind_front(a...) can be seen as storing the results of
|
||||||
// std::make_tuple(a...).
|
// std::make_tuple(a...).
|
||||||
|
@ -125,19 +152,6 @@
|
||||||
// // dangling references.
|
// // dangling references.
|
||||||
// foo->DoInFuture(absl::bind_front(Print, std::ref(hi), "Guest")); // BAD!
|
// foo->DoInFuture(absl::bind_front(Print, std::ref(hi), "Guest")); // BAD!
|
||||||
// auto f = absl::bind_front(Print, std::ref(hi), "Guest"); // BAD!
|
// auto f = absl::bind_front(Print, std::ref(hi), "Guest"); // BAD!
|
||||||
|
|
||||||
#ifndef ABSL_FUNCTIONAL_BIND_FRONT_H_
|
|
||||||
#define ABSL_FUNCTIONAL_BIND_FRONT_H_
|
|
||||||
|
|
||||||
#include "absl/functional/internal/front_binder.h"
|
|
||||||
#include "absl/utility/utility.h"
|
|
||||||
|
|
||||||
namespace absl {
|
|
||||||
ABSL_NAMESPACE_BEGIN
|
|
||||||
|
|
||||||
// Binds the first N arguments of an invocable object and stores them by value,
|
|
||||||
// except types of std::reference_wrapper which are 'unwound' and stored by
|
|
||||||
// reference.
|
|
||||||
template <class F, class... BoundArgs>
|
template <class F, class... BoundArgs>
|
||||||
constexpr functional_internal::bind_front_t<F, BoundArgs...> bind_front(
|
constexpr functional_internal::bind_front_t<F, BoundArgs...> bind_front(
|
||||||
F&& func, BoundArgs&&... args) {
|
F&& func, BoundArgs&&... args) {
|
||||||
|
|
Loading…
Reference in a new issue