summaryrefslogtreecommitdiff
path: root/cpp
diff options
context:
space:
mode:
authorJoe George <joe@zeroc.com>2016-07-11 09:17:55 -0400
committerJoe George <joe@zeroc.com>2016-07-11 09:25:01 -0400
commitef64ff67e60bf1e64d15608b96fcb4591add2426 (patch)
tree71d77ee61490e0fb213128468a910d6303b5645e /cpp
parentUpdate to use latest Gradle Ice builder version (diff)
downloadice-ef64ff67e60bf1e64d15608b96fcb4591add2426.tar.bz2
ice-ef64ff67e60bf1e64d15608b96fcb4591add2426.tar.xz
ice-ef64ff67e60bf1e64d15608b96fcb4591add2426.zip
StreamReader/Writer improvements
- No longer generate StreamWriter partial template specialization for C++ classes/structs/exceptions which have no optional members. - Reduce generated code size for all C++11 StreamReader/Writers.
Diffstat (limited to 'cpp')
-rw-r--r--cpp/include/Ice/OutputStream.h15
-rw-r--r--cpp/include/Ice/StreamHelpers.h7
-rw-r--r--cpp/src/Slice/CPlusPlusUtil.cpp162
-rw-r--r--cpp/src/Slice/CPlusPlusUtil.h4
-rw-r--r--cpp/src/slice2cpp/Gen.cpp16
5 files changed, 161 insertions, 43 deletions
diff --git a/cpp/include/Ice/OutputStream.h b/cpp/include/Ice/OutputStream.h
index cf90475ceec..67994253814 100644
--- a/cpp/include/Ice/OutputStream.h
+++ b/cpp/include/Ice/OutputStream.h
@@ -312,6 +312,21 @@ public:
writeAll(ve...);
}
+ template<size_t I = 0, typename... Te>
+ typename std::enable_if<I == sizeof...(Te), void>::type
+ writeAll(std::tuple<Te...> tuple)
+ {
+ // Do nothing. Either tuple is empty or we are at the end.
+ }
+
+ template<size_t I = 0, typename... Te>
+ typename std::enable_if<I < sizeof...(Te), void>::type
+ writeAll(std::tuple<Te...> tuple)
+ {
+ write(std::get<I>(tuple));
+ writeAll<I + 1, Te...>(tuple);
+ }
+
template<typename T>
void writeAll(std::initializer_list<int> tags, const IceUtil::Optional<T>& v)
{
diff --git a/cpp/include/Ice/StreamHelpers.h b/cpp/include/Ice/StreamHelpers.h
index 024f50eae5f..a7773a27090 100644
--- a/cpp/include/Ice/StreamHelpers.h
+++ b/cpp/include/Ice/StreamHelpers.h
@@ -360,9 +360,12 @@ struct StreamHelper<T, StreamHelperCategoryBuiltin>
template<typename T, typename S>
struct StreamWriter
{
- static inline void write(S*, const T&)
+ static inline void write(S* stream, const T& v)
{
- // Default is to do write nothing
+#ifdef ICE_CPP11_MAPPING
+ stream->writeAll(v.ice_tuple());
+#endif
+ // Default is to write nothing for C++98
}
};
diff --git a/cpp/src/Slice/CPlusPlusUtil.cpp b/cpp/src/Slice/CPlusPlusUtil.cpp
index 1e3134c718a..2100cdedeb2 100644
--- a/cpp/src/Slice/CPlusPlusUtil.cpp
+++ b/cpp/src/Slice/CPlusPlusUtil.cpp
@@ -1398,63 +1398,160 @@ Slice::writeMarshalUnmarshalDataMemberInHolder(IceUtilInternal::Output& C,
}
void
-Slice::writeStreamHelpers(Output& out, bool checkClassMetaData, const ContainedPtr& c, DataMemberList dataMembers,
- DataMemberList optionalDataMembers)
+Slice::writeMarshalUnmarshalAllInHolder(IceUtilInternal::Output& out,
+ const string& holder,
+ const DataMemberList& dataMembers,
+ bool optional,
+ bool marshal)
{
- if(!dataMembers.empty() || !optionalDataMembers.empty())
+ if(dataMembers.empty())
{
- string scoped = c->scoped();
- bool classMetaData = false;
+ return;
+ }
- if(checkClassMetaData)
- {
- classMetaData = findMetaData(c->getMetaData(), false) == "%class";
- }
+ string stream = marshal ? "__os" : "__is";
+ string streamOp = marshal ? "writeAll" : "readAll";
- string fullName = classMetaData ? fixKwd(scoped + "Ptr") : fixKwd(scoped);
- string holder = classMetaData ? "v->" : "v.";
+ out << nl << stream << "->" << streamOp;
+ out << spar;
- out << nl << "template<typename S>";
- out << nl << "struct StreamWriter< " << fullName << ", S>";
- out << sb;
- out << nl << "static void write(S* __os, const " << fullName << "& v)";
- out << sb;
+ if(optional)
+ {
+ ostringstream os;
+ os << "{";
for(DataMemberList::const_iterator q = dataMembers.begin(); q != dataMembers.end(); ++q)
{
- if(!(*q)->optional())
+ if(q != dataMembers.begin())
{
- writeMarshalUnmarshalDataMemberInHolder(out, holder, *q, true);
+ os << ", ";
}
+ os << (*q)->tag();
+ }
+ os << "}";
+ out << os.str();
+ }
+
+ for(DataMemberList::const_iterator q = dataMembers.begin(); q != dataMembers.end(); ++q)
+ {
+ out << holder + fixKwd((*q)->name());
+ }
+
+ out << epar << ";";
+
+}
+
+void
+Slice::writeStreamHelpers(Output& out,
+ bool checkClassMetaData,
+ bool cpp11,
+ const ContainedPtr& c,
+ DataMemberList dataMembers)
+{
+ if(dataMembers.empty())
+ {
+ return;
+ }
+
+ DataMemberList requiredMembers;
+ DataMemberList optionalMembers;
+
+ for(DataMemberList::const_iterator q = dataMembers.begin(); q != dataMembers.end(); ++q)
+ {
+ if((*q)->optional())
+ {
+ optionalMembers.push_back(*q);
}
- for(DataMemberList::const_iterator q = optionalDataMembers.begin(); q != optionalDataMembers.end(); ++q)
+ else
{
- writeMarshalUnmarshalDataMemberInHolder(out, holder, *q, true);
+ requiredMembers.push_back(*q);
}
- out << eb;
- out << eb << ";" << nl;
+ }
+
+ // Sort optional data members
+ class SortFn
+ {
+ public:
+ static bool compare(const DataMemberPtr& lhs, const DataMemberPtr& rhs)
+ {
+ return lhs->tag() < rhs->tag();
+ }
+ };
+ optionalMembers.sort(SortFn::compare);
+
+ string scoped = c->scoped();
+ bool classMetaData = checkClassMetaData ? (findMetaData(c->getMetaData(), false) == "%class") : false;
+ string fullName = classMetaData ? fixKwd(scoped + "Ptr") : fixKwd(scoped);
+ string holder = classMetaData ? "v->" : "v.";
+ //
+ // Generate StreamWriter
+ //
+ // Only generate StreamWriter specializations if we are generating for C++98 or
+ // we are generating for C++11 with optional data members
+ //
+ if(!cpp11 || !optionalMembers.empty())
+ {
out << nl << "template<typename S>";
- out << nl << "struct StreamReader< " << fullName << ", S>";
+ out << nl << "struct StreamWriter" << (cpp11 ? "<" : "< ") << fullName << ", S>";
out << sb;
- out << nl << "static void read(S* __is, " << fullName << "& v)";
+ out << nl << "static void write(S* __os, const " << fullName << "& v)";
out << sb;
- for(DataMemberList::const_iterator q = dataMembers.begin(); q != dataMembers.end(); ++q)
+
+ if(cpp11)
+ {
+ writeMarshalUnmarshalTupleInHolder(out, holder, requiredMembers, false, true);
+ writeMarshalUnmarshalTupleInHolder(out, holder, optionalMembers, true, true);
+ }
+ else
{
- if(!(*q)->optional())
+ for(DataMemberList::const_iterator q = requiredMembers.begin(); q != requiredMembers.end(); ++q)
{
- writeMarshalUnmarshalDataMemberInHolder(out, holder, *q, false);
+ writeMarshalUnmarshalDataMemberInHolder(out, holder, *q, true);
+ }
+
+ for(DataMemberList::const_iterator q = optionalMembers.begin(); q != optionalMembers.end(); ++q)
+ {
+ writeMarshalUnmarshalDataMemberInHolder(out, holder, *q, true);
}
}
- for(DataMemberList::const_iterator q = optionalDataMembers.begin(); q != optionalDataMembers.end(); ++q)
+
+ out << eb;
+ out << eb << ";" << nl;
+ }
+
+ //
+ // Generate StreamWriter
+ //
+ out << nl << "template<typename S>";
+ out << nl << "struct StreamReader" << (cpp11 ? "<" : "< ") << fullName << ", S>";
+ out << sb;
+ out << nl << "static void read(S* __is, " << fullName << "& v)";
+ out << sb;
+
+ if(cpp11)
+ {
+ writeMarshalUnmarshalTupleInHolder(out, holder, requiredMembers, false, false);
+ writeMarshalUnmarshalTupleInHolder(out, holder, optionalMembers, true, false);
+ }
+ else
+ {
+ for(DataMemberList::const_iterator q = requiredMembers.begin(); q != requiredMembers.end(); ++q)
+ {
+ writeMarshalUnmarshalDataMemberInHolder(out, holder, *q, false);
+ }
+
+ for(DataMemberList::const_iterator q = optionalMembers.begin(); q != optionalMembers.end(); ++q)
{
writeMarshalUnmarshalDataMemberInHolder(out, holder, *q, false);
}
- out << eb;
- out << eb << ";" << nl;
}
+
+ out << eb;
+ out << eb << ";" << nl;
}
+
void
-Slice::writeIceTuple(::IceUtilInternal::Output& out, DataMemberList dataMembers, int useWstring)
+Slice::writeIceTuple(::IceUtilInternal::Output& out, DataMemberList dataMembers, int typeCtx)
{
out << sp << nl << "std::tuple<";
for(DataMemberList::const_iterator q = dataMembers.begin(); q != dataMembers.end(); ++q)
@@ -1464,9 +1561,10 @@ Slice::writeIceTuple(::IceUtilInternal::Output& out, DataMemberList dataMembers,
out << ", ";
}
out << "const ";
- out << typeToString((*q)->type(), (*q)->optional(), (*q)->getMetaData(), useWstring | TypeContextCpp11) << "&";
+ out << typeToString((*q)->type(), (*q)->optional(), (*q)->getMetaData(), typeCtx | TypeContextCpp11) << "&";
}
out << "> ice_tuple() const";
+
out << sb;
out << nl << "return std::tie(";
for(DataMemberList::const_iterator pi = dataMembers.begin(); pi != dataMembers.end(); ++pi)
diff --git a/cpp/src/Slice/CPlusPlusUtil.h b/cpp/src/Slice/CPlusPlusUtil.h
index 1cd1d8f32c6..cc5e0f44ded 100644
--- a/cpp/src/Slice/CPlusPlusUtil.h
+++ b/cpp/src/Slice/CPlusPlusUtil.h
@@ -60,8 +60,8 @@ void writeAllocateCode(::IceUtilInternal::Output&, const ParamDeclList&, const O
std::string getEndArg(const TypePtr&, const StringList&, const std::string&);
void writeEndCode(::IceUtilInternal::Output&, const ParamDeclList&, const OperationPtr&, bool = false);
void writeMarshalUnmarshalDataMemberInHolder(IceUtilInternal::Output&, const std::string&, const DataMemberPtr&, bool);
-void writeStreamHelpers(::IceUtilInternal::Output&, bool, const ContainedPtr&, DataMemberList,
- DataMemberList = DataMemberList());
+void writeMarshalUnmarshalAllInHolder(IceUtilInternal::Output&, const std::string&, const DataMemberList&, bool, bool);
+void writeStreamHelpers(::IceUtilInternal::Output&, bool, bool, const ContainedPtr&, DataMemberList);
void writeIceTuple(::IceUtilInternal::Output&, DataMemberList, int);
bool findMetaData(const std::string&, const ClassDeclPtr&, std::string&);
diff --git a/cpp/src/slice2cpp/Gen.cpp b/cpp/src/slice2cpp/Gen.cpp
index 93c4540b8e0..e7fe5c368bb 100644
--- a/cpp/src/slice2cpp/Gen.cpp
+++ b/cpp/src/slice2cpp/Gen.cpp
@@ -4779,7 +4779,7 @@ Slice::Gen::StreamVisitor::visitClassDefStart(const ClassDefPtr& c)
{
if(!c->isLocal())
{
- writeStreamHelpers(H, true, c, c->dataMembers(), c->orderedOptionalDataMembers());
+ writeStreamHelpers(H, true, false, c, c->dataMembers());
}
return false;
}
@@ -4796,7 +4796,7 @@ Slice::Gen::StreamVisitor::visitExceptionStart(const ExceptionPtr& p)
H << nl << "static const StreamHelperCategory helper = StreamHelperCategoryUserException;";
H << eb << ";" << nl;
- writeStreamHelpers(H, true, p, p->dataMembers(), p->orderedOptionalDataMembers());
+ writeStreamHelpers(H, true, false, p, p->dataMembers());
}
return false;
}
@@ -4835,7 +4835,7 @@ Slice::Gen::StreamVisitor::visitStructStart(const StructPtr& p)
}
H << eb << ";" << nl;
- writeStreamHelpers(H, true, p, p->dataMembers(), DataMemberList());
+ writeStreamHelpers(H, true, false, p, p->dataMembers());
}
return false;
}
@@ -5824,8 +5824,10 @@ Slice::Gen::Cpp11TypesVisitor::visitExceptionStart(const ExceptionPtr& p)
H << sb;
H << eb;
}
- H << sp;
+ writeIceTuple(H, p->dataMembers(), _useWstring);
+
+ H << sp;
H << nl << _dllMemberExport << "static const ::std::string& ice_staticId();";
@@ -7975,7 +7977,7 @@ Slice::Gen::Cpp11StreamVisitor::visitStructStart(const StructPtr& p)
H << nl << "static const bool fixedLength = " << (p->isVariableLength() ? "false" : "true") << ";";
H << eb << ";" << nl;
- writeStreamHelpers(H, false, p, p->dataMembers());
+ writeStreamHelpers(H, false, true, p, p->dataMembers());
return false;
}
@@ -7985,7 +7987,7 @@ Slice::Gen::Cpp11StreamVisitor::visitClassDefStart(const ClassDefPtr& c)
{
if(!c->isLocal() && !c->isInterface())
{
- writeStreamHelpers(H, true, c, c->dataMembers(), c->orderedOptionalDataMembers());
+ writeStreamHelpers(H, true, true, c, c->dataMembers());
}
return false;
}
@@ -7995,7 +7997,7 @@ Slice::Gen::Cpp11StreamVisitor::visitExceptionEnd(const ExceptionPtr& p)
{
if(!p->isLocal())
{
- writeStreamHelpers(H, true, p, p->dataMembers(), p->orderedOptionalDataMembers());
+ writeStreamHelpers(H, true, true, p, p->dataMembers());
}
}