summaryrefslogtreecommitdiff
path: root/absl/flags
diff options
context:
space:
mode:
Diffstat (limited to 'absl/flags')
-rw-r--r--absl/flags/flag.h20
-rw-r--r--absl/flags/internal/flag.h38
2 files changed, 34 insertions, 24 deletions
diff --git a/absl/flags/flag.h b/absl/flags/flag.h
index cdac545b..a9cb2b79 100644
--- a/absl/flags/flag.h
+++ b/absl/flags/flag.h
@@ -144,11 +144,17 @@ class Flag {
inline bool IsOfType() const {
return GetImpl().template IsOfType<U>();
}
- T Get() const { return GetImpl().Get(); }
- void Set(const T& v) { GetImpl().Set(v); }
+ T Get() const {
+ return flags_internal::FlagImplPeer::InvokeGet<T>(GetImpl());
+ }
+ void Set(const T& v) {
+ flags_internal::FlagImplPeer::InvokeSet(GetImpl(), v);
+ }
void InvokeCallback() { GetImpl().InvokeCallback(); }
- const CommandLineFlag& Reflect() const { return GetImpl().Reflect(); }
+ const CommandLineFlag& Reflect() const {
+ return flags_internal::FlagImplPeer::InvokeReflect(GetImpl());
+ }
// The data members are logically private, but they need to be public for
// this to be an aggregate type.
@@ -180,7 +186,7 @@ class Flag {
// 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();
+ return flags_internal::FlagImplPeer::InvokeGet<T>(flag);
}
// SetFlag()
@@ -192,7 +198,7 @@ ABSL_MUST_USE_RESULT T GetFlag(const absl::Flag<T>& flag) {
// but especially within performance-critical code.
template <typename T>
void SetFlag(absl::Flag<T>* flag, const T& v) {
- flag->Set(v);
+ flags_internal::FlagImplPeer::InvokeSet(*flag, v);
}
// Overload of `SetFlag()` to allow callers to pass in a value that is
@@ -201,7 +207,7 @@ void SetFlag(absl::Flag<T>* flag, const T& v) {
template <typename T, typename V>
void SetFlag(absl::Flag<T>* flag, const V& v) {
T value(v);
- flag->Set(value);
+ flags_internal::FlagImplPeer::InvokeSet(*flag, value);
}
// GetFlagReflectionHandle()
@@ -216,7 +222,7 @@ void SetFlag(absl::Flag<T>* flag, const V& v) {
template <typename T>
const CommandLineFlag& GetFlagReflectionHandle(const absl::Flag<T>& f) {
- return f.Reflect();
+ return flags_internal::FlagImplPeer::InvokeReflect(f);
}
ABSL_NAMESPACE_END
diff --git a/absl/flags/internal/flag.h b/absl/flags/internal/flag.h
index 89e43ad7..370d8a02 100644
--- a/absl/flags/internal/flag.h
+++ b/absl/flags/internal/flag.h
@@ -632,20 +632,9 @@ class Flag {
std::string CurrentValue() const { return impl_.CurrentValue(); }
private:
- template <typename U, bool do_register>
+ template <typename, bool>
friend class FlagRegistrar;
-
-#if !defined(_MSC_VER) || defined(__clang__)
- template <typename U>
- friend U absl::GetFlag(const flags_internal::Flag<U>& flag);
- template <typename U>
- friend void absl::SetFlag(flags_internal::Flag<U>* flag, const U& v);
- template <typename U, typename V>
- friend void absl::SetFlag(flags_internal::Flag<U>* flag, const V& v);
-#else
- template <typename U>
- friend class absl::Flag;
-#endif
+ friend class FlagImplPeer;
T Get() const {
// See implementation notes in CommandLineFlag::Get().
@@ -668,10 +657,6 @@ 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_; }
@@ -684,6 +669,25 @@ class Flag {
};
///////////////////////////////////////////////////////////////////////////////
+// Trampoline for friend access
+
+class FlagImplPeer {
+ public:
+ template <typename T, typename FlagType>
+ static T InvokeGet(const FlagType& flag) {
+ return flag.Get();
+ }
+ template <typename FlagType, typename T>
+ static void InvokeSet(FlagType& flag, const T& v) {
+ flag.Set(v);
+ }
+ template <typename FlagType>
+ static const CommandLineFlag& InvokeReflect(const FlagType& f) {
+ return f.Reflect();
+ }
+};
+
+///////////////////////////////////////////////////////////////////////////////
// Implementation of Flag value specific operations routine.
template <typename T>
void* FlagOps(FlagOp op, const void* v1, void* v2, void* v3) {