summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Tom Manshreck <shreck@google.com>2022-06-08 14:22:40 -0700
committerGravatar Copybara-Service <copybara-worker@google.com>2022-06-08 14:23:13 -0700
commite0a32c2aee27aadce321471be734d7643d7d9439 (patch)
tree0a111652ad5d66cb1650f96c84729b769a67dc8f
parent7a8d20b7841b43cc685230058130bd0f019e4004 (diff)
Add documentation on optional flags to the flags library overview.
PiperOrigin-RevId: 453766125 Change-Id: Id4d88ae20bdadc960a65bc1010eea746f1eba051
-rw-r--r--absl/flags/flag.h4
-rw-r--r--absl/flags/marshalling.h37
2 files changed, 41 insertions, 0 deletions
diff --git a/absl/flags/flag.h b/absl/flags/flag.h
index d2750b31..b7f94be7 100644
--- a/absl/flags/flag.h
+++ b/absl/flags/flag.h
@@ -67,6 +67,10 @@ ABSL_NAMESPACE_BEGIN
// ABSL_FLAG(int, count, 0, "Count of items to process");
//
// No public methods of `absl::Flag<T>` are part of the Abseil Flags API.
+//
+// For type support of Abseil Flags, see the marshalling.h header file, which
+// discusses supported standard types, optional flags, and additional Abseil
+// type support.
#if !defined(_MSC_VER) || defined(__clang__)
template <typename T>
using Flag = flags_internal::Flag<T>;
diff --git a/absl/flags/marshalling.h b/absl/flags/marshalling.h
index 0f63cdc5..b1e2ffa5 100644
--- a/absl/flags/marshalling.h
+++ b/absl/flags/marshalling.h
@@ -33,6 +33,7 @@
// * `double`
// * `std::string`
// * `std::vector<std::string>`
+// * `std::optional<T>`
// * `absl::LogSeverity` (provided natively for layering reasons)
//
// Note that support for integral types is implemented using overloads for
@@ -65,6 +66,42 @@
// below.)
//
// -----------------------------------------------------------------------------
+// Optional Flags
+// -----------------------------------------------------------------------------
+//
+// The Abseil flags library supports flags of type `std::optional<T>` where
+// `T` is a type of one of the supported flags. We refer to this flag type as
+// an "optional flag." An optional flag is either "valueless", holding no value
+// of type `T` (indicating that the flag has not been set) or a value of type
+// `T`. The valueless state in C++ code is represented by a value of
+// `std::nullopt` for the optional flag.
+//
+// Using `std::nullopt` as an optional flag's default value allows you to check
+// whether such a flag was ever specified on the command line:
+//
+// if (absl::GetFlag(FLAGS_foo).has_value()) {
+// // flag was set on command line
+// } else {
+// // flag was not passed on command line
+// }
+//
+// Using an optional flag in this manner avoids common workarounds for
+// indicating such an unset flag (such as using sentinal values to indicate this
+// state).
+//
+// An optional flag also allows a developer to pass a flag in an "unset"
+// valueless state on the command line, allowing the flag to later be set in
+// binary logic. An optional flag's valueless state is indicated by the special
+// notation of passing the value as an empty string through the syntax `--flag=`
+// or `--flag ""`.
+//
+// $ binary_with_optional --flag_in_unset_state=
+// $ binary_with_optional --flag_in_unset_state ""
+//
+// Note: as a result of the above syntax requirements, an optional flag cannot
+// be set to a `T` of any value which unparses to the empty string.
+//
+// -----------------------------------------------------------------------------
// Adding Type Support for Abseil Flags
// -----------------------------------------------------------------------------
//