aboutsummaryrefslogtreecommitdiff
path: root/src/google/protobuf/generated_message_reflection.h
diff options
context:
space:
mode:
authorBo Yang <teboring@google.com>2015-05-21 14:28:59 -0700
committerBo Yang <teboring@google.com>2015-05-21 19:32:02 -0700
commit5db217305f37a79eeccd70f000088a06ec82fcec (patch)
treebe53dcf0c0b47ef9178ab8a6fa5c1946ee84a28f /src/google/protobuf/generated_message_reflection.h
parent56095026ccc2f755a6fdb296e30c3ddec8f556a2 (diff)
downloadprotobuf-5db217305f37a79eeccd70f000088a06ec82fcec.tar.gz
protobuf-5db217305f37a79eeccd70f000088a06ec82fcec.tar.bz2
protobuf-5db217305f37a79eeccd70f000088a06ec82fcec.zip
down-integrate internal changes
Diffstat (limited to 'src/google/protobuf/generated_message_reflection.h')
-rw-r--r--src/google/protobuf/generated_message_reflection.h37
1 files changed, 37 insertions, 0 deletions
diff --git a/src/google/protobuf/generated_message_reflection.h b/src/google/protobuf/generated_message_reflection.h
index 4dddf6c7..dc8abb98 100644
--- a/src/google/protobuf/generated_message_reflection.h
+++ b/src/google/protobuf/generated_message_reflection.h
@@ -40,6 +40,7 @@
#include <string>
#include <vector>
+#include <google/protobuf/stubs/casts.h>
#include <google/protobuf/stubs/common.h>
// TODO(jasonh): Remove this once the compiler change to directly include this
// is released to components.
@@ -597,6 +598,42 @@ inline To dynamic_cast_if_available(From from) {
#endif
}
+// Tries to downcast this message to a generated message type.
+// Returns NULL if this class is not an instance of T.
+//
+// This is like dynamic_cast_if_available, except it works even when
+// dynamic_cast is not available by using Reflection. However it only works
+// with Message objects.
+//
+// TODO(haberman): can we remove dynamic_cast_if_available in favor of this?
+template <typename T>
+T* DynamicCastToGenerated(const Message* from) {
+ // Compile-time assert that T is a generated type that has a
+ // default_instance() accessor, but avoid actually calling it.
+ const T&(*get_default_instance)() = &T::default_instance;
+ (void)get_default_instance;
+
+ // Compile-time assert that T is a subclass of google::protobuf::Message.
+ const Message* unused = static_cast<T*>(NULL);
+ (void)unused;
+
+#if defined(GOOGLE_PROTOBUF_NO_RTTI) || \
+ (defined(_MSC_VER) && !defined(_CPPRTTI))
+ bool ok = &T::default_instance() ==
+ from->GetReflection()->GetMessageFactory()->GetPrototype(
+ from->GetDescriptor());
+ return ok ? down_cast<T*>(from) : NULL;
+#else
+ return dynamic_cast<T*>(from);
+#endif
+}
+
+template <typename T>
+T* DynamicCastToGenerated(Message* from) {
+ const Message* message_const = from;
+ return const_cast<T*>(DynamicCastToGenerated<const T>(message_const));
+}
+
} // namespace internal
} // namespace protobuf