THRIFT-922. cpp: Convert protocol classes to use non-virtual functions

Updated the thrift protocol classes to use non-virtual calls for most
functions.  The correct implementation is determined at compile time via
templates now.  Only the base TProtocol class falls back to using
virtual function calls.

git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@1005135 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/lib/cpp/src/protocol/TProtocol.h b/lib/cpp/src/protocol/TProtocol.h
index 2e24f75..6bf7e3b 100644
--- a/lib/cpp/src/protocol/TProtocol.h
+++ b/lib/cpp/src/protocol/TProtocol.h
@@ -165,6 +165,111 @@
   T_ONEWAY     = 4
 };
 
+
+/**
+ * Helper template for implementing TProtocol::skip().
+ *
+ * Templatized to avoid having to make virtual function calls.
+ */
+template <class Protocol_>
+uint32_t skip(Protocol_& prot, TType type) {
+  switch (type) {
+  case T_BOOL:
+    {
+      bool boolv;
+      return prot.readBool(boolv);
+    }
+  case T_BYTE:
+    {
+      int8_t bytev;
+      return prot.readByte(bytev);
+    }
+  case T_I16:
+    {
+      int16_t i16;
+      return prot.readI16(i16);
+    }
+  case T_I32:
+    {
+      int32_t i32;
+      return prot.readI32(i32);
+    }
+  case T_I64:
+    {
+      int64_t i64;
+      return prot.readI64(i64);
+    }
+  case T_DOUBLE:
+    {
+      double dub;
+      return prot.readDouble(dub);
+    }
+  case T_STRING:
+    {
+      std::string str;
+      return prot.readBinary(str);
+    }
+  case T_STRUCT:
+    {
+      uint32_t result = 0;
+      std::string name;
+      int16_t fid;
+      TType ftype;
+      result += prot.readStructBegin(name);
+      while (true) {
+        result += prot.readFieldBegin(name, ftype, fid);
+        if (ftype == T_STOP) {
+          break;
+        }
+        result += skip(prot, ftype);
+        result += prot.readFieldEnd();
+      }
+      result += prot.readStructEnd();
+      return result;
+    }
+  case T_MAP:
+    {
+      uint32_t result = 0;
+      TType keyType;
+      TType valType;
+      uint32_t i, size;
+      result += prot.readMapBegin(keyType, valType, size);
+      for (i = 0; i < size; i++) {
+        result += skip(prot, keyType);
+        result += skip(prot, valType);
+      }
+      result += prot.readMapEnd();
+      return result;
+    }
+  case T_SET:
+    {
+      uint32_t result = 0;
+      TType elemType;
+      uint32_t i, size;
+      result += prot.readSetBegin(elemType, size);
+      for (i = 0; i < size; i++) {
+        result += skip(prot, elemType);
+      }
+      result += prot.readSetEnd();
+      return result;
+    }
+  case T_LIST:
+    {
+      uint32_t result = 0;
+      TType elemType;
+      uint32_t i, size;
+      result += prot.readListBegin(elemType, size);
+      for (i = 0; i < size; i++) {
+        result += skip(prot, elemType);
+      }
+      result += prot.readListEnd();
+      return result;
+    }
+  default:
+    return 0;
+  }
+}
+
 /**
  * Abstract class for a thrift protocol driver. These are all the methods that
  * a protocol must implement. Essentially, there must be some way of reading
@@ -187,108 +292,324 @@
    * Writing functions.
    */
 
-  virtual uint32_t writeMessageBegin(const std::string& name,
-                                     const TMessageType messageType,
-                                     const int32_t seqid) = 0;
+  virtual uint32_t writeMessageBegin_virt(const std::string& name,
+                                          const TMessageType messageType,
+                                          const int32_t seqid) = 0;
 
-  virtual uint32_t writeMessageEnd() = 0;
+  virtual uint32_t writeMessageEnd_virt() = 0;
 
 
-  virtual uint32_t writeStructBegin(const char* name) = 0;
+  virtual uint32_t writeStructBegin_virt(const char* name) = 0;
 
-  virtual uint32_t writeStructEnd() = 0;
+  virtual uint32_t writeStructEnd_virt() = 0;
 
-  virtual uint32_t writeFieldBegin(const char* name,
-                                   const TType fieldType,
-                                   const int16_t fieldId) = 0;
+  virtual uint32_t writeFieldBegin_virt(const char* name,
+                                        const TType fieldType,
+                                        const int16_t fieldId) = 0;
 
-  virtual uint32_t writeFieldEnd() = 0;
+  virtual uint32_t writeFieldEnd_virt() = 0;
 
-  virtual uint32_t writeFieldStop() = 0;
+  virtual uint32_t writeFieldStop_virt() = 0;
 
-  virtual uint32_t writeMapBegin(const TType keyType,
-                                 const TType valType,
-                                 const uint32_t size) = 0;
+  virtual uint32_t writeMapBegin_virt(const TType keyType,
+                                      const TType valType,
+                                      const uint32_t size) = 0;
 
-  virtual uint32_t writeMapEnd() = 0;
+  virtual uint32_t writeMapEnd_virt() = 0;
 
-  virtual uint32_t writeListBegin(const TType elemType,
-                                  const uint32_t size) = 0;
+  virtual uint32_t writeListBegin_virt(const TType elemType,
+                                       const uint32_t size) = 0;
 
-  virtual uint32_t writeListEnd() = 0;
+  virtual uint32_t writeListEnd_virt() = 0;
 
-  virtual uint32_t writeSetBegin(const TType elemType,
-                                 const uint32_t size) = 0;
+  virtual uint32_t writeSetBegin_virt(const TType elemType,
+                                      const uint32_t size) = 0;
 
-  virtual uint32_t writeSetEnd() = 0;
+  virtual uint32_t writeSetEnd_virt() = 0;
 
-  virtual uint32_t writeBool(const bool value) = 0;
+  virtual uint32_t writeBool_virt(const bool value) = 0;
 
-  virtual uint32_t writeByte(const int8_t byte) = 0;
+  virtual uint32_t writeByte_virt(const int8_t byte) = 0;
 
-  virtual uint32_t writeI16(const int16_t i16) = 0;
+  virtual uint32_t writeI16_virt(const int16_t i16) = 0;
 
-  virtual uint32_t writeI32(const int32_t i32) = 0;
+  virtual uint32_t writeI32_virt(const int32_t i32) = 0;
 
-  virtual uint32_t writeI64(const int64_t i64) = 0;
+  virtual uint32_t writeI64_virt(const int64_t i64) = 0;
 
-  virtual uint32_t writeDouble(const double dub) = 0;
+  virtual uint32_t writeDouble_virt(const double dub) = 0;
 
-  virtual uint32_t writeString(const std::string& str) = 0;
+  virtual uint32_t writeString_virt(const std::string& str) = 0;
 
-  virtual uint32_t writeBinary(const std::string& str) = 0;
+  virtual uint32_t writeBinary_virt(const std::string& str) = 0;
+
+  uint32_t writeMessageBegin(const std::string& name,
+                             const TMessageType messageType,
+                             const int32_t seqid) {
+    T_VIRTUAL_CALL();
+    return writeMessageBegin_virt(name, messageType, seqid);
+  }
+
+  uint32_t writeMessageEnd() {
+    T_VIRTUAL_CALL();
+    return writeMessageEnd_virt();
+  }
+
+
+  uint32_t writeStructBegin(const char* name) {
+    T_VIRTUAL_CALL();
+    return writeStructBegin_virt(name);
+  }
+
+  uint32_t writeStructEnd() {
+    T_VIRTUAL_CALL();
+    return writeStructEnd_virt();
+  }
+
+  uint32_t writeFieldBegin(const char* name,
+                           const TType fieldType,
+                           const int16_t fieldId) {
+    T_VIRTUAL_CALL();
+    return writeFieldBegin_virt(name, fieldType, fieldId);
+  }
+
+  uint32_t writeFieldEnd() {
+    T_VIRTUAL_CALL();
+    return writeFieldEnd_virt();
+  }
+
+  uint32_t writeFieldStop() {
+    T_VIRTUAL_CALL();
+    return writeFieldStop_virt();
+  }
+
+  uint32_t writeMapBegin(const TType keyType,
+                         const TType valType,
+                         const uint32_t size) {
+    T_VIRTUAL_CALL();
+    return writeMapBegin_virt(keyType, valType, size);
+  }
+
+  uint32_t writeMapEnd() {
+    T_VIRTUAL_CALL();
+    return writeMapEnd_virt();
+  }
+
+  uint32_t writeListBegin(const TType elemType, const uint32_t size) {
+    T_VIRTUAL_CALL();
+    return writeListBegin_virt(elemType, size);
+  }
+
+  uint32_t writeListEnd() {
+    T_VIRTUAL_CALL();
+    return writeListEnd_virt();
+  }
+
+  uint32_t writeSetBegin(const TType elemType, const uint32_t size) {
+    T_VIRTUAL_CALL();
+    return writeSetBegin_virt(elemType, size);
+  }
+
+  uint32_t writeSetEnd() {
+    T_VIRTUAL_CALL();
+    return writeSetEnd_virt();
+  }
+
+  uint32_t writeBool(const bool value) {
+    T_VIRTUAL_CALL();
+    return writeBool_virt(value);
+  }
+
+  uint32_t writeByte(const int8_t byte) {
+    T_VIRTUAL_CALL();
+    return writeByte_virt(byte);
+  }
+
+  uint32_t writeI16(const int16_t i16) {
+    T_VIRTUAL_CALL();
+    return writeI16_virt(i16);
+  }
+
+  uint32_t writeI32(const int32_t i32) {
+    T_VIRTUAL_CALL();
+    return writeI32_virt(i32);
+  }
+
+  uint32_t writeI64(const int64_t i64) {
+    T_VIRTUAL_CALL();
+    return writeI64_virt(i64);
+  }
+
+  uint32_t writeDouble(const double dub) {
+    T_VIRTUAL_CALL();
+    return writeDouble_virt(dub);
+  }
+
+  uint32_t writeString(const std::string& str) {
+    T_VIRTUAL_CALL();
+    return writeString_virt(str);
+  }
+
+  uint32_t writeBinary(const std::string& str) {
+    T_VIRTUAL_CALL();
+    return writeBinary_virt(str);
+  }
 
   /**
    * Reading functions
    */
 
-  virtual uint32_t readMessageBegin(std::string& name,
-                                    TMessageType& messageType,
-                                    int32_t& seqid) = 0;
+  virtual uint32_t readMessageBegin_virt(std::string& name,
+                                         TMessageType& messageType,
+                                         int32_t& seqid) = 0;
 
-  virtual uint32_t readMessageEnd() = 0;
+  virtual uint32_t readMessageEnd_virt() = 0;
 
-  virtual uint32_t readStructBegin(std::string& name) = 0;
+  virtual uint32_t readStructBegin_virt(std::string& name) = 0;
 
-  virtual uint32_t readStructEnd() = 0;
+  virtual uint32_t readStructEnd_virt() = 0;
 
-  virtual uint32_t readFieldBegin(std::string& name,
-                                  TType& fieldType,
-                                  int16_t& fieldId) = 0;
+  virtual uint32_t readFieldBegin_virt(std::string& name,
+                                       TType& fieldType,
+                                       int16_t& fieldId) = 0;
 
-  virtual uint32_t readFieldEnd() = 0;
+  virtual uint32_t readFieldEnd_virt() = 0;
 
-  virtual uint32_t readMapBegin(TType& keyType,
-                                TType& valType,
-                                uint32_t& size) = 0;
+  virtual uint32_t readMapBegin_virt(TType& keyType,
+                                     TType& valType,
+                                     uint32_t& size) = 0;
 
-  virtual uint32_t readMapEnd() = 0;
+  virtual uint32_t readMapEnd_virt() = 0;
 
-  virtual uint32_t readListBegin(TType& elemType,
-                                 uint32_t& size) = 0;
+  virtual uint32_t readListBegin_virt(TType& elemType,
+                                      uint32_t& size) = 0;
 
-  virtual uint32_t readListEnd() = 0;
+  virtual uint32_t readListEnd_virt() = 0;
 
-  virtual uint32_t readSetBegin(TType& elemType,
-                                uint32_t& size) = 0;
+  virtual uint32_t readSetBegin_virt(TType& elemType,
+                                     uint32_t& size) = 0;
 
-  virtual uint32_t readSetEnd() = 0;
+  virtual uint32_t readSetEnd_virt() = 0;
 
-  virtual uint32_t readBool(bool& value) = 0;
+  virtual uint32_t readBool_virt(bool& value) = 0;
 
-  virtual uint32_t readByte(int8_t& byte) = 0;
+  virtual uint32_t readByte_virt(int8_t& byte) = 0;
 
-  virtual uint32_t readI16(int16_t& i16) = 0;
+  virtual uint32_t readI16_virt(int16_t& i16) = 0;
 
-  virtual uint32_t readI32(int32_t& i32) = 0;
+  virtual uint32_t readI32_virt(int32_t& i32) = 0;
 
-  virtual uint32_t readI64(int64_t& i64) = 0;
+  virtual uint32_t readI64_virt(int64_t& i64) = 0;
 
-  virtual uint32_t readDouble(double& dub) = 0;
+  virtual uint32_t readDouble_virt(double& dub) = 0;
 
-  virtual uint32_t readString(std::string& str) = 0;
+  virtual uint32_t readString_virt(std::string& str) = 0;
 
-  virtual uint32_t readBinary(std::string& str) = 0;
+  virtual uint32_t readBinary_virt(std::string& str) = 0;
+
+  uint32_t readMessageBegin(std::string& name,
+                            TMessageType& messageType,
+                            int32_t& seqid) {
+    T_VIRTUAL_CALL();
+    return readMessageBegin_virt(name, messageType, seqid);
+  }
+
+  uint32_t readMessageEnd() {
+    T_VIRTUAL_CALL();
+    return readMessageEnd_virt();
+  }
+
+  uint32_t readStructBegin(std::string& name) {
+    T_VIRTUAL_CALL();
+    return readStructBegin_virt(name);
+  }
+
+  uint32_t readStructEnd() {
+    T_VIRTUAL_CALL();
+    return readStructEnd_virt();
+  }
+
+  uint32_t readFieldBegin(std::string& name,
+                          TType& fieldType,
+                          int16_t& fieldId) {
+    T_VIRTUAL_CALL();
+    return readFieldBegin_virt(name, fieldType, fieldId);
+  }
+
+  uint32_t readFieldEnd() {
+    T_VIRTUAL_CALL();
+    return readFieldEnd_virt();
+  }
+
+  uint32_t readMapBegin(TType& keyType, TType& valType, uint32_t& size) {
+    T_VIRTUAL_CALL();
+    return readMapBegin_virt(keyType, valType, size);
+  }
+
+  uint32_t readMapEnd() {
+    T_VIRTUAL_CALL();
+    return readMapEnd_virt();
+  }
+
+  uint32_t readListBegin(TType& elemType, uint32_t& size) {
+    T_VIRTUAL_CALL();
+    return readListBegin_virt(elemType, size);
+  }
+
+  uint32_t readListEnd() {
+    T_VIRTUAL_CALL();
+    return readListEnd_virt();
+  }
+
+  uint32_t readSetBegin(TType& elemType, uint32_t& size) {
+    T_VIRTUAL_CALL();
+    return readSetBegin_virt(elemType, size);
+  }
+
+  uint32_t readSetEnd() {
+    T_VIRTUAL_CALL();
+    return readSetEnd_virt();
+  }
+
+  uint32_t readBool(bool& value) {
+    T_VIRTUAL_CALL();
+    return readBool_virt(value);
+  }
+
+  uint32_t readByte(int8_t& byte) {
+    T_VIRTUAL_CALL();
+    return readByte_virt(byte);
+  }
+
+  uint32_t readI16(int16_t& i16) {
+    T_VIRTUAL_CALL();
+    return readI16_virt(i16);
+  }
+
+  uint32_t readI32(int32_t& i32) {
+    T_VIRTUAL_CALL();
+    return readI32_virt(i32);
+  }
+
+  uint32_t readI64(int64_t& i64) {
+    T_VIRTUAL_CALL();
+    return readI64_virt(i64);
+  }
+
+  uint32_t readDouble(double& dub) {
+    T_VIRTUAL_CALL();
+    return readDouble_virt(dub);
+  }
+
+  uint32_t readString(std::string& str) {
+    T_VIRTUAL_CALL();
+    return readString_virt(str);
+  }
+
+  uint32_t readBinary(std::string& str) {
+    T_VIRTUAL_CALL();
+    return readBinary_virt(str);
+  }
 
   uint32_t readBool(std::vector<bool>::reference ref) {
     bool value;
@@ -301,101 +622,11 @@
    * Method to arbitrarily skip over data.
    */
   uint32_t skip(TType type) {
-    switch (type) {
-    case T_BOOL:
-      {
-        bool boolv;
-        return readBool(boolv);
-      }
-    case T_BYTE:
-      {
-        int8_t bytev;
-        return readByte(bytev);
-      }
-    case T_I16:
-      {
-        int16_t i16;
-        return readI16(i16);
-      }
-    case T_I32:
-      {
-        int32_t i32;
-        return readI32(i32);
-      }
-    case T_I64:
-      {
-        int64_t i64;
-        return readI64(i64);
-      }
-    case T_DOUBLE:
-      {
-        double dub;
-        return readDouble(dub);
-      }
-    case T_STRING:
-      {
-        std::string str;
-        return readBinary(str);
-      }
-    case T_STRUCT:
-      {
-        uint32_t result = 0;
-        std::string name;
-        int16_t fid;
-        TType ftype;
-        result += readStructBegin(name);
-        while (true) {
-          result += readFieldBegin(name, ftype, fid);
-          if (ftype == T_STOP) {
-            break;
-          }
-          result += skip(ftype);
-          result += readFieldEnd();
-        }
-        result += readStructEnd();
-        return result;
-      }
-    case T_MAP:
-      {
-        uint32_t result = 0;
-        TType keyType;
-        TType valType;
-        uint32_t i, size;
-        result += readMapBegin(keyType, valType, size);
-        for (i = 0; i < size; i++) {
-          result += skip(keyType);
-          result += skip(valType);
-        }
-        result += readMapEnd();
-        return result;
-      }
-    case T_SET:
-      {
-        uint32_t result = 0;
-        TType elemType;
-        uint32_t i, size;
-        result += readSetBegin(elemType, size);
-        for (i = 0; i < size; i++) {
-          result += skip(elemType);
-        }
-        result += readSetEnd();
-        return result;
-      }
-    case T_LIST:
-      {
-        uint32_t result = 0;
-        TType elemType;
-        uint32_t i, size;
-        result += readListBegin(elemType, size);
-        for (i = 0; i < size; i++) {
-          result += skip(elemType);
-        }
-        result += readListEnd();
-        return result;
-      }
-    default:
-      return 0;
-    }
+    T_VIRTUAL_CALL();
+    return skip_virt(type);
+  }
+  virtual uint32_t skip_virt(TType type) {
+    return ::apache::thrift::protocol::skip(*this, type);
   }
 
   inline boost::shared_ptr<TTransport> getTransport() {