Thrift: Local Reflection for C++.

Summary:
The compiler now takes a "-dense" flag that will cause it to
generate some extra metadata for C++.  This metadata will be used by
TDenseProtocol.  This should be the last compiler change necessary
to enable that feature.

Reviewed By: mcslee

Test Plan: test/DenseLinkingTest.thrift

Revert Plan: ok


git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@665240 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/lib/cpp/src/TReflectionLocal.h b/lib/cpp/src/TReflectionLocal.h
new file mode 100644
index 0000000..6f082e7
--- /dev/null
+++ b/lib/cpp/src/TReflectionLocal.h
@@ -0,0 +1,69 @@
+// Copyright (c) 2006- Facebook
+// Distributed under the Thrift Software License
+//
+// See accompanying file LICENSE or visit the Thrift site at:
+// http://developers.facebook.com/thrift/
+
+#ifndef _THRIFT_TREFLECTIONLOCAL_H_
+#define _THRIFT_TREFLECTIONLOCAL_H_ 1
+
+#include <stdint.h>
+#include <protocol/TProtocol.h>
+
+namespace facebook { namespace thrift { namespace reflection { namespace local {
+
+using facebook::thrift::protocol::TType;
+
+/**
+ * A local reflection is a representation of a Thrift structure.
+ * (It is called local because it cannot be serialized by Thrift).
+ *
+ * @author David Reiss <dreiss@facebook.com>
+ */
+
+struct TypeSpec {
+  // Use an anonymous union here so we can fit two TypeSpecs in one cache line.
+  union {
+    struct {
+      // Use parallel arrays here for denser packing (of the arrays).
+      int16_t*   ftags;
+      TypeSpec** specs;
+      int        n_fields;
+    } tstruct;
+    struct {
+      TypeSpec *subtype1;
+      TypeSpec *subtype2;
+    } tcontainer;
+  };
+
+  // Put this at the end so the 32-bit enum can be crammed up next to the
+  // 32-bit int (n_fields).
+  TType ttype;
+
+
+  // Static initialization of unions isn't really possible,
+  // so take the plunge and use constructors.
+  // Hopefully they'll be evaluated at compile time.
+
+  TypeSpec(TType ttype) : ttype(ttype) {}
+
+  TypeSpec(TType ttype, int n_fields, int16_t* ftags, TypeSpec** specs) :
+    ttype(ttype)
+  {
+    tstruct.n_fields = n_fields;
+    tstruct.ftags = ftags;
+    tstruct.specs = specs;
+  }
+
+  TypeSpec(TType ttype, TypeSpec* subtype1, TypeSpec* subtype2) :
+    ttype(ttype)
+  {
+    tcontainer.subtype1 = subtype1;
+    tcontainer.subtype2 = subtype2;
+  }
+
+};
+
+}}}} // facebook::thrift::reflection::local
+
+#endif // #ifndef _THRIFT_TREFLECTIONLOCAL_H_
diff --git a/lib/cpp/src/Thrift.h b/lib/cpp/src/Thrift.h
index 07ccb97..4a3df65 100644
--- a/lib/cpp/src/Thrift.h
+++ b/lib/cpp/src/Thrift.h
@@ -134,6 +134,12 @@
 };
 
 
+// Forward declare this structure used by TDenseProtocol
+namespace reflection { namespace local {
+struct TypeSpec;
+}}
+
+
 }} // facebook::thrift
 
 #endif // #ifndef _THRIFT_THRIFT_H_