Thrift-1567:Thrift/cpp: Allow alternate classes to be used for strings
Client: cpp
Patch: dreiss

The goal of this diff is to allow Thrift strings to be used without
depending on std::string, since it looks like we're starting to move
away from std::string instead of moving to a better implementation.



git-svn-id: https://svn.apache.org/repos/asf/thrift/trunk@1352765 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/compiler/cpp/src/generate/t_cpp_generator.cc b/compiler/cpp/src/generate/t_cpp_generator.cc
index 20b991d..f4136e1 100644
--- a/compiler/cpp/src/generate/t_cpp_generator.cc
+++ b/compiler/cpp/src/generate/t_cpp_generator.cc
@@ -69,6 +69,9 @@
     iter = parsed_options.find("templates");
     gen_templates_ = (iter != parsed_options.end());
 
+    gen_templates_only_ =
+      (iter != parsed_options.end() && iter->second == "only");
+
     out_dir_base_ = "gen-cpp";
   }
 
@@ -253,7 +256,13 @@
   bool gen_templates_;
 
   /**
-   * True if we should use a path prefix in our #include statements for other
+   * True iff we should generate process function pointers for only templatized
+   * reader/writer methods.
+   */
+  bool gen_templates_only_;
+
+  /**
+   * True iff we should use a path prefix in our #include statements for other
    * thrift-generated header files.
    */
   bool use_include_prefix_;
@@ -2896,11 +2905,15 @@
     f_header_ <<
       indent() << "processMap_[\"" << (*f_iter)->get_name() << "\"] = ";
     if (generator_->gen_templates_) {
-      f_header_ << "ProcessFunctions(" << endl <<
-        indent() << "  &" << class_name_ << "::process_" <<
-          (*f_iter)->get_name() << "," << endl <<
-        indent() << "  &" << class_name_ << "::process_" <<
-          (*f_iter)->get_name() << ")";
+      f_header_ << "ProcessFunctions(" << endl;
+      if (generator_->gen_templates_only_) {
+        indent(f_header_) << "  NULL," << endl;
+      } else {
+        indent(f_header_) << "  &" << class_name_ << "::process_" <<
+          (*f_iter)->get_name() << "," << endl;
+      }
+      indent(f_header_) << "  &" << class_name_ << "::process_" <<
+        (*f_iter)->get_name() << ")";
     } else {
       f_header_ << "&" << class_name_ << "::process_" << (*f_iter)->get_name();
     }
@@ -2988,7 +3001,12 @@
     f_out_ <<
       indent() << "(this->*(pfn->second.specialized))";
   } else {
-    if (generator_->gen_templates_) {
+    if (generator_->gen_templates_only_) {
+      // TODO: This is a null pointer, so nothing good will come from calling
+      // it.  Throw an exception instead.
+      f_out_ <<
+        indent() << "(this->*(pfn->second.generic))";
+    } else if (generator_->gen_templates_) {
       f_out_ <<
         indent() << "(this->*(pfn->second.generic))";
     } else {
@@ -4246,6 +4264,11 @@
 string t_cpp_generator::type_name(t_type* ttype, bool in_typedef, bool arg) {
   if (ttype->is_base_type()) {
     string bname = base_type_name(((t_base_type*)ttype)->get_base());
+    std::map<string, string>::iterator it = ttype->annotations_.find("cpp.type");
+    if (it != ttype->annotations_.end()) {
+      bname = it->second;
+    }
+
     if (!arg) {
       return bname;
     }
diff --git a/lib/cpp/src/thrift/protocol/TBinaryProtocol.h b/lib/cpp/src/thrift/protocol/TBinaryProtocol.h
index 37d33f4..b762ad4 100644
--- a/lib/cpp/src/thrift/protocol/TBinaryProtocol.h
+++ b/lib/cpp/src/thrift/protocol/TBinaryProtocol.h
@@ -134,7 +134,8 @@
 
   inline uint32_t writeDouble(const double dub);
 
-  inline uint32_t writeString(const std::string& str);
+  template <typename StrType>
+  inline uint32_t writeString(const StrType& str);
 
   inline uint32_t writeBinary(const std::string& str);
 
@@ -187,12 +188,14 @@
 
   inline uint32_t readDouble(double& dub);
 
-  inline uint32_t readString(std::string& str);
+  template<typename StrType>
+  inline uint32_t readString(StrType& str);
 
   inline uint32_t readBinary(std::string& str);
 
  protected:
-  uint32_t readStringBody(std::string& str, int32_t sz);
+  template<typename StrType>
+  uint32_t readStringBody(StrType& str, int32_t sz);
 
   Transport_* trans_;
 
diff --git a/lib/cpp/src/thrift/protocol/TBinaryProtocol.tcc b/lib/cpp/src/thrift/protocol/TBinaryProtocol.tcc
index a95fdba..f3f38f7 100644
--- a/lib/cpp/src/thrift/protocol/TBinaryProtocol.tcc
+++ b/lib/cpp/src/thrift/protocol/TBinaryProtocol.tcc
@@ -176,7 +176,8 @@
 
 
 template <class Transport_>
-uint32_t TBinaryProtocolT<Transport_>::writeString(const std::string& str) {
+template<typename StrType>
+uint32_t TBinaryProtocolT<Transport_>::writeString(const StrType& str) {
   uint32_t size = str.size();
   uint32_t result = writeI32((int32_t)size);
   if (size > 0) {
@@ -401,7 +402,8 @@
 }
 
 template <class Transport_>
-uint32_t TBinaryProtocolT<Transport_>::readString(std::string& str) {
+template<typename StrType>
+uint32_t TBinaryProtocolT<Transport_>::readString(StrType& str) {
   uint32_t result;
   int32_t size;
   result = readI32(size);
@@ -414,7 +416,8 @@
 }
 
 template <class Transport_>
-uint32_t TBinaryProtocolT<Transport_>::readStringBody(std::string& str,
+template<typename StrType>
+uint32_t TBinaryProtocolT<Transport_>::readStringBody(StrType& str,
                                                       int32_t size) {
   uint32_t result = 0;