Add `no_constructors` option to C++ compiler
diff --git a/compiler/cpp/src/thrift/generate/t_cpp_generator.cc b/compiler/cpp/src/thrift/generate/t_cpp_generator.cc
index 13d27a1..c0767c3 100644
--- a/compiler/cpp/src/thrift/generate/t_cpp_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_cpp_generator.cc
@@ -66,6 +66,7 @@
gen_moveable_ = false;
gen_no_ostream_operators_ = false;
gen_no_skeleton_ = false;
+ gen_no_constructors_ = false;
has_members_ = false;
for( iter = parsed_options.begin(); iter != parsed_options.end(); ++iter) {
@@ -88,6 +89,8 @@
gen_no_ostream_operators_ = true;
} else if ( iter->first.compare("no_skeleton") == 0) {
gen_no_skeleton_ = true;
+ } else if ( iter->first.compare("no_constructors") == 0) {
+ gen_no_constructors_ = true;
} else {
throw "unknown option cpp:" + iter->first;
}
@@ -124,7 +127,7 @@
void generate_service(t_service* tservice) override;
void print_const_value(std::ostream& out, std::string name, t_type* type, t_const_value* value);
- std::string render_const_value(std::ostream& out,
+ std::string render_const_value(std::ostream* out,
std::string name,
t_type* type,
t_const_value* value);
@@ -369,11 +372,16 @@
bool gen_no_default_operators_;
/**
- * True if we should generate skeleton.
+ * True if we should omit generating skeleton.
*/
bool gen_no_skeleton_;
/**
+ * True if we should omit generating constructors/destructors/assignment/destructors.
+ */
+ bool gen_no_constructors_;
+
+ /**
* True if thrift has member(s)
*/
bool has_members_;
@@ -786,7 +794,7 @@
t_const_value* value) {
type = get_true_type(type);
if (type->is_base_type()) {
- string v2 = render_const_value(out, name, type, value);
+ string v2 = render_const_value(&out, name, type, value);
indent(out) << name << " = " << v2 << ";" << '\n' << '\n';
} else if (type->is_enum()) {
indent(out) << name
@@ -810,7 +818,7 @@
if (field_type == nullptr) {
throw "type error: " + type->get_name() + " has no field " + v_iter->first->get_string();
}
- string item_val = render_const_value(out, name, field_type, v_iter->second);
+ string item_val = render_const_value(&out, name, field_type, v_iter->second);
indent(out) << name << "." << v_iter->first->get_string() << " = " << item_val << ";" << '\n';
if (is_nonrequired_field) {
indent(out) << name << ".__isset." << v_iter->first->get_string() << " = true;" << '\n';
@@ -823,8 +831,8 @@
const map<t_const_value*, t_const_value*, t_const_value::value_compare>& val = value->get_map();
map<t_const_value*, t_const_value*, t_const_value::value_compare>::const_iterator v_iter;
for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) {
- string key = render_const_value(out, name, ktype, v_iter->first);
- string item_val = render_const_value(out, name, vtype, v_iter->second);
+ string key = render_const_value(&out, name, ktype, v_iter->first);
+ string item_val = render_const_value(&out, name, vtype, v_iter->second);
indent(out) << name << ".insert(std::make_pair(" << key << ", " << item_val << "));" << '\n';
}
out << '\n';
@@ -833,7 +841,7 @@
const vector<t_const_value*>& val = value->get_list();
vector<t_const_value*>::const_iterator v_iter;
for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) {
- string item_val = render_const_value(out, name, etype, *v_iter);
+ string item_val = render_const_value(&out, name, etype, *v_iter);
indent(out) << name << ".push_back(" << item_val << ");" << '\n';
}
out << '\n';
@@ -842,7 +850,7 @@
const vector<t_const_value*>& val = value->get_list();
vector<t_const_value*>::const_iterator v_iter;
for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) {
- string item_val = render_const_value(out, name, etype, *v_iter);
+ string item_val = render_const_value(&out, name, etype, *v_iter);
indent(out) << name << ".insert(" << item_val << ");" << '\n';
}
out << '\n';
@@ -854,7 +862,7 @@
/**
*
*/
-string t_cpp_generator::render_const_value(ostream& out,
+string t_cpp_generator::render_const_value(ostream* out,
string name,
t_type* type,
t_const_value* value) {
@@ -891,10 +899,10 @@
} else if (type->is_enum()) {
render << "static_cast<" << type_name(type) << '>'
<< '(' << value->get_integer() << ')';
- } else {
+ } else if (out) {
string t = tmp("tmp");
- indent(out) << type_name(type) << " " << t << ";" << '\n';
- print_const_value(out, t, type, value);
+ indent(*out) << type_name(type) << " " << t << ";" << '\n';
+ print_const_value(*out, t, type, value);
render << t;
}
@@ -924,13 +932,15 @@
if (!gen_no_default_operators_) {
generate_equality_operator(f_types_impl_, tstruct);
}
- generate_copy_constructor(f_types_impl_, tstruct, is_exception);
- if (gen_moveable_) {
- generate_move_constructor(f_types_impl_, tstruct, is_exception);
- }
- generate_assignment_operator(f_types_impl_, tstruct);
- if (gen_moveable_) {
- generate_move_assignment_operator(f_types_impl_, tstruct);
+ if (!gen_no_constructors_) {
+ generate_copy_constructor(f_types_impl_, tstruct, is_exception);
+ if (gen_moveable_) {
+ generate_move_constructor(f_types_impl_, tstruct, is_exception);
+ }
+ generate_assignment_operator(f_types_impl_, tstruct);
+ if (gen_moveable_) {
+ generate_move_assignment_operator(f_types_impl_, tstruct);
+ }
}
if (!has_custom_ostream(tstruct)) {
@@ -1026,7 +1036,7 @@
string dval;
t_const_value* cv = (*m_iter)->get_value();
if (cv != nullptr) {
- dval += render_const_value(out, (*m_iter)->get_name(), t, cv);
+ dval += render_const_value(&out, (*m_iter)->get_name(), t, cv);
} else if (t->is_enum()) {
dval += "static_cast<" + type_name(t) + ">(0)";
} else {
@@ -1266,7 +1276,7 @@
<< " public:" << '\n' << '\n';
indent_up();
- if (!pointers) {
+ if (!gen_no_constructors_ && !pointers) {
bool ok_noexcept = is_struct_storage_not_throwing(tstruct);
// Copy constructor
indent(out) << tstruct->get_name() << "(const " << tstruct->get_name() << "&)"
@@ -1295,15 +1305,17 @@
indent(out) << clsname_ctor << (has_default_value ? "" : " noexcept") << ";" << '\n';
}
- if (tstruct->annotations_.find("final") == tstruct->annotations_.end()) {
- out << '\n' << indent() << "virtual ~" << tstruct->get_name() << "() noexcept;" << '\n';
+ if (!gen_no_constructors_ && tstruct->annotations_.find("final") == tstruct->annotations_.end()) {
+ out << '\n' << indent();
+ if (!gen_templates_) out << "virtual ";
+ out << "~" << tstruct->get_name() << "() noexcept;\n";
}
// Declare all fields
for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
generate_java_doc(out, *m_iter);
indent(out) << declare_field(*m_iter,
- false,
+ !pointers && gen_no_constructors_,
(pointers && !(*m_iter)->get_type()->is_xception()),
!read) << '\n';
}
@@ -1376,7 +1388,8 @@
out << '\n';
if (is_user_struct && !has_custom_ostream(tstruct)) {
- out << indent() << "virtual ";
+ out << indent();
+ if (!gen_templates_) out << "virtual ";
generate_struct_print_method_decl(out, nullptr);
out << ";" << '\n';
}
@@ -1419,7 +1432,7 @@
const vector<t_field*>& members = tstruct->get_members();
// Destructor
- if (tstruct->annotations_.find("final") == tstruct->annotations_.end()) {
+ if (!gen_no_constructors_ && tstruct->annotations_.find("final") == tstruct->annotations_.end()) {
force_cpp_out << '\n' << indent() << tstruct->get_name() << "::~" << tstruct->get_name()
<< "() noexcept {" << '\n';
indent_up();
@@ -1428,7 +1441,7 @@
force_cpp_out << indent() << "}" << '\n' << '\n';
}
- if (!pointers)
+ if (!gen_no_constructors_ && !pointers)
{
// 'force_cpp_out' always goes into the .cpp file, and never into a .tcc
// file in case templates are involved. Since the constructor is not templated,
@@ -4607,31 +4620,35 @@
result += " " + tfield->get_name();
if (init) {
t_type* type = get_true_type(tfield->get_type());
+ if (t_const_value* cv = tfield->get_value()) {
+ result += " = " + render_const_value(nullptr, tfield->get_name(), type, cv);
+ } else {
+ if (type->is_base_type()) {
+ t_base_type::t_base tbase = ((t_base_type*)type)->get_base();
- if (type->is_base_type()) {
- t_base_type::t_base tbase = ((t_base_type*)type)->get_base();
- switch (tbase) {
- case t_base_type::TYPE_VOID:
- case t_base_type::TYPE_STRING:
- case t_base_type::TYPE_UUID:
- break;
- case t_base_type::TYPE_BOOL:
- result += " = false";
- break;
- case t_base_type::TYPE_I8:
- case t_base_type::TYPE_I16:
- case t_base_type::TYPE_I32:
- case t_base_type::TYPE_I64:
- result += " = 0";
- break;
- case t_base_type::TYPE_DOUBLE:
- result += " = 0.0";
- break;
- default:
- throw "compiler error: no C++ initializer for base type " + t_base_type::t_base_name(tbase);
+ switch (tbase) {
+ case t_base_type::TYPE_VOID:
+ case t_base_type::TYPE_STRING:
+ case t_base_type::TYPE_UUID:
+ break;
+ case t_base_type::TYPE_BOOL:
+ result += " = false";
+ break;
+ case t_base_type::TYPE_I8:
+ case t_base_type::TYPE_I16:
+ case t_base_type::TYPE_I32:
+ case t_base_type::TYPE_I64:
+ result += " = 0";
+ break;
+ case t_base_type::TYPE_DOUBLE:
+ result += " = 0.0";
+ break;
+ default:
+ throw "compiler error: no C++ initializer for base type " + t_base_type::t_base_name(tbase);
+ }
+ } else if (type->is_enum()) {
+ result += " = static_cast<" + type_name(type) + ">(0)";
}
- } else if (type->is_enum()) {
- result += " = static_cast<" + type_name(type) + ">(0)";
}
}
if (!reference) {