summaryrefslogtreecommitdiff
path: root/absl/flags/internal/flag.h
diff options
context:
space:
mode:
authorGravatar Abseil Team <absl-team@google.com>2020-05-20 00:23:37 -0700
committerGravatar Mark Barolak <mbar@google.com>2020-05-21 10:16:55 -0400
commitcf1a02e2dc5a1bc9d095f4c996306de448ca200f (patch)
tree74cd530ed421fb27a8774a5a11243bd81682ee18 /absl/flags/internal/flag.h
parent768eb2ca2857342673fcd462792ce04b8bac3fa3 (diff)
Export of internal Abseil changes
-- 30e5e00a54cabc50118a3e1055826ea02a0d32e4 by Gennadiy Rozental <rogeeff@google.com>: Move flag help into flag_cold section. To facilitate this we set flag help not in a constructor, but during flag registration. This allows us to place flag name as static variable inside non constexpr lambda and invoke it immediately in FlagRegistrar argument location. PiperOrigin-RevId: 312432625 -- efd91b05152b68df648cff5ba38e9669a817c12f by Gennadiy Rozental <rogeeff@google.com>: Make CommandLineFlag public. PiperOrigin-RevId: 312404666 -- dc7f5fb73487766fa8a76d6b97d28116e5334445 by Mark Barolak <mbar@google.com>: Internal change. PiperOrigin-RevId: 312297164 GitOrigin-RevId: 30e5e00a54cabc50118a3e1055826ea02a0d32e4 Change-Id: Ic46ab011bb804645264572caddff0becba5f9170
Diffstat (limited to 'absl/flags/internal/flag.h')
-rw-r--r--absl/flags/internal/flag.h62
1 files changed, 36 insertions, 26 deletions
diff --git a/absl/flags/internal/flag.h b/absl/flags/internal/flag.h
index e374ecde..97ddb5f9 100644
--- a/absl/flags/internal/flag.h
+++ b/absl/flags/internal/flag.h
@@ -28,8 +28,8 @@
#include "absl/base/call_once.h"
#include "absl/base/config.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"
@@ -168,6 +168,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 +207,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};
}
///////////////////////////////////////////////////////////////////////////////
@@ -419,7 +429,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,