diff options
author | Joe George <joe@zeroc.com> | 2016-07-11 09:17:55 -0400 |
---|---|---|
committer | Joe George <joe@zeroc.com> | 2016-07-11 09:25:01 -0400 |
commit | ef64ff67e60bf1e64d15608b96fcb4591add2426 (patch) | |
tree | 71d77ee61490e0fb213128468a910d6303b5645e /cpp | |
parent | Update to use latest Gradle Ice builder version (diff) | |
download | ice-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.h | 15 | ||||
-rw-r--r-- | cpp/include/Ice/StreamHelpers.h | 7 | ||||
-rw-r--r-- | cpp/src/Slice/CPlusPlusUtil.cpp | 162 | ||||
-rw-r--r-- | cpp/src/Slice/CPlusPlusUtil.h | 4 | ||||
-rw-r--r-- | cpp/src/slice2cpp/Gen.cpp | 16 |
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()); } } |