Thrift C++ code generator returns complex types by reference
Summary: Efficiency, Yo.
Reviewed By: aditya
git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@664910 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 68a491b..efe327b 100644
--- a/compiler/cpp/src/generate/t_cpp_generator.cc
+++ b/compiler/cpp/src/generate/t_cpp_generator.cc
@@ -788,10 +788,15 @@
f_header_ <<
indent() << "return;" << endl;
} else {
- t_field returnfield(returntype, "rval");
- f_header_ <<
- indent() << declare_field(&returnfield, true) << endl <<
- indent() << "return rval;" << endl;
+ if (is_complex_type(returntype)) {
+ f_header_ <<
+ indent() << "return;" << endl;
+ } else {
+ t_field returnfield(returntype, "_return");
+ f_header_ <<
+ indent() << declare_field(&returnfield, true) << endl <<
+ indent() << "return _return;" << endl;
+ }
}
indent_down();
f_header_ <<
@@ -873,6 +878,10 @@
string call = string("ifaces_[i]->") + (*f_iter)->get_name() + "(";
bool first = true;
+ if (is_complex_type((*f_iter)->get_returntype())) {
+ call += "_return";
+ first = false;
+ }
for (a_iter = args.begin(); a_iter != args.end(); ++a_iter) {
if (first) {
first = false;
@@ -891,8 +900,16 @@
indent() << "for (uint32_t i = 0; i < sz; ++i) {" << endl;
if (!(*f_iter)->get_returntype()->is_void()) {
f_header_ <<
- indent() << " if (i == sz - 1) {" << endl <<
- indent() << " return " << call << ";" << endl <<
+ indent() << " if (i == sz - 1) {" << endl;
+ if (is_complex_type((*f_iter)->get_returntype())) {
+ f_header_ <<
+ indent() << " " << call << ";" << endl <<
+ indent() << " return;" << endl;
+ } else {
+ f_header_ <<
+ indent() << " return " << call << ";" << endl;
+ }
+ f_header_ <<
indent() << " } else {" << endl <<
indent() << " " << call << ";" << endl <<
indent() << " }" << endl;
@@ -1024,10 +1041,15 @@
if (!(*f_iter)->is_async()) {
f_service_ << indent();
if (!(*f_iter)->get_returntype()->is_void()) {
- f_service_ << "return ";
+ if (is_complex_type((*f_iter)->get_returntype())) {
+ f_service_ << "recv_" << funname << "(_return);" << endl;
+ } else {
+ f_service_ << "return recv_" << funname << "();" << endl;
+ }
+ } else {
+ f_service_ <<
+ "recv_" << funname << "();" << endl;
}
- f_service_ <<
- "recv_" << funname << "();" << endl;
}
scope_down(f_service_);
f_service_ << endl;
@@ -1100,10 +1122,18 @@
// Careful, only look for _result if not a void function
if (!(*f_iter)->get_returntype()->is_void()) {
- f_service_ <<
- indent() << "if (result.__isset.success) {" << endl <<
- indent() << " return result.success;" << endl <<
- indent() << "}" << endl;
+ if (is_complex_type((*f_iter)->get_returntype())) {
+ f_service_ <<
+ indent() << "if (result.__isset.success) {" << endl <<
+ indent() << " _return = result.success;" << endl <<
+ indent() << " return;" << endl <<
+ indent() << "}" << endl;
+ } else {
+ f_service_ <<
+ indent() << "if (result.__isset.success) {" << endl <<
+ indent() << " return result.success;" << endl <<
+ indent() << "}" << endl;
+ }
}
t_struct* xs = (*f_iter)->get_xceptions();
@@ -1349,13 +1379,19 @@
const std::vector<t_field*>& fields = arg_struct->get_members();
vector<t_field*>::const_iterator f_iter;
+ bool first = true;
f_service_ << indent();
if (!tfunction->is_async() && !tfunction->get_returntype()->is_void()) {
- f_service_ << "result.success = ";
+ if (is_complex_type(tfunction->get_returntype())) {
+ first = false;
+ f_service_ << "iface_->" << tfunction->get_name() << "(result.success";
+ } else {
+ f_service_ << "result.success = iface_->" << tfunction->get_name() << "(";
+ }
+ } else {
+ f_service_ <<
+ "iface_->" << tfunction->get_name() << "(";
}
- f_service_ <<
- "iface_->" << tfunction->get_name() << "(";
- bool first = true;
for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
if (first) {
first = false;
@@ -2095,9 +2131,19 @@
string t_cpp_generator::function_signature(t_function* tfunction,
string prefix) {
t_type* ttype = tfunction->get_returntype();
- return
- type_name(ttype) + " " + prefix + tfunction->get_name() +
- "(" + argument_list(tfunction->get_arglist()) + ")";
+ t_struct* arglist = tfunction->get_arglist();
+
+ if (is_complex_type(ttype)) {
+ bool empty = arglist->get_members().size() == 0;
+ return
+ "void " + prefix + tfunction->get_name() +
+ "(" + type_name(ttype) + "& _return" +
+ (empty ? "" : (", " + argument_list(arglist))) + ")";
+ } else {
+ return
+ type_name(ttype) + " " + prefix + tfunction->get_name() +
+ "(" + argument_list(arglist) + ")";
+ }
}
/**
diff --git a/compiler/cpp/src/generate/t_cpp_generator.h b/compiler/cpp/src/generate/t_cpp_generator.h
index aae6f4f..886279d 100644
--- a/compiler/cpp/src/generate/t_cpp_generator.h
+++ b/compiler/cpp/src/generate/t_cpp_generator.h
@@ -134,6 +134,14 @@
std::string argument_list(t_struct* tstruct);
std::string type_to_enum(t_type* ttype);
+ bool is_complex_type(t_type* ttype) {
+ return
+ ttype->is_container() ||
+ ttype->is_struct() ||
+ ttype->is_xception() ||
+ (ttype->is_base_type() && (((t_base_type*)ttype)->get_base() == t_base_type::TYPE_STRING));
+ }
+
private:
/**