summaryrefslogtreecommitdiff
path: root/cpp
diff options
context:
space:
mode:
authorBernard Normier <bernard@zeroc.com>2012-09-21 11:39:40 -0400
committerBernard Normier <bernard@zeroc.com>2012-09-21 11:39:40 -0400
commitd2b0b523f878a2db545e03610836ff342888a67c (patch)
tree1519565b15c643ba657d39e86389ec88de91e008 /cpp
parentReverted temp debug addition to StreamI.cpp (diff)
downloadice-d2b0b523f878a2db545e03610836ff342888a67c.tar.bz2
ice-d2b0b523f878a2db545e03610836ff342888a67c.tar.xz
ice-d2b0b523f878a2db545e03610836ff342888a67c.zip
Partial fix for ICE-3393:
- cpp:protobuf is now an alias for cpp:type - StreamTraitType is now extensible - StreamTrait<> has now a third template parameter, typename Enabler = void, for std::enable_if expressions
Diffstat (limited to 'cpp')
-rw-r--r--cpp/include/Ice/StreamTraits.h50
-rw-r--r--cpp/include/Slice/CPlusPlusUtil.h1
-rw-r--r--cpp/src/Slice/CPlusPlusUtil.cpp252
-rw-r--r--cpp/src/slice2cpp/Gen.cpp104
4 files changed, 114 insertions, 293 deletions
diff --git a/cpp/include/Ice/StreamTraits.h b/cpp/include/Ice/StreamTraits.h
index 00f38cb5819..16dfe6a3963 100644
--- a/cpp/include/Ice/StreamTraits.h
+++ b/cpp/include/Ice/StreamTraits.h
@@ -20,28 +20,28 @@ namespace Ice
//
// The different types of Slice types supported by the stream
-// marshalling/un-marshalling methods.
+// marshaling/unmarshaling methods.
//
-enum StreamTraitType
-{
- StreamTraitTypeBuiltin,
- StreamTraitTypeStruct,
- StreamTraitTypeStructClass, // struct with cpp:class metadata
- StreamTraitTypeEnum,
- StreamTraitTypeSequence,
- StreamTraitTypeDictionary,
- StreamTraitTypeProxy,
- StreamTraitTypeClass,
- StreamTraitTypeUserException,
- StreamTraitTypeCustom
-};
+
+typedef int StreamTraitType;
+
+const StreamTraitType StreamTraitTypeUnknown = 0;
+const StreamTraitType StreamTraitTypeBuiltin = 1;
+const StreamTraitType StreamTraitTypeStruct = 2;
+const StreamTraitType StreamTraitTypeStructClass = 3; // struct with cpp:class metadata
+const StreamTraitType StreamTraitTypeEnum = 4;
+const StreamTraitType StreamTraitTypeSequence = 5;
+const StreamTraitType StreamTraitTypeDictionary = 6;
+const StreamTraitType StreamTraitTypeProxy = 7;
+const StreamTraitType StreamTraitTypeClass = 8;
+const StreamTraitType StreamTraitTypeUserException = 9;
//
// The optional type.
//
// Optional data members or attribute is encoded with a specific
// optional type. This optional type describes how the data is encoded
-// and how it can be skipped by the un-marhsalling code if the optional
+// and how it can be skipped by the unmarshaling code if the optional
// isn't known to the receiver.
//
enum OptionalType
@@ -96,11 +96,11 @@ struct IsMap
// Base trait template.
// Types with no specialized trait use this trait.
//
-template<typename T>
+template<typename T, typename Enabler = void>
struct StreamTrait
{
static const StreamTraitType type = IsMap<T>::value ? StreamTraitTypeDictionary :
- (IsContainer<T>::value ? StreamTraitTypeSequence : StreamTraitTypeCustom);
+ (IsContainer<T>::value ? StreamTraitTypeSequence : StreamTraitTypeUnknown);
//
// When extracting a sequence<T> from a stream, we can ensure the
@@ -123,7 +123,7 @@ struct StreamTrait
template<typename T>
struct IsFixedLength
{
- typedef typename StreamTrait<T> Traits;
+ typedef StreamTrait<T> Traits;
static const bool value = (Traits::optionalType <= OptionalTypeF8)
|| ((Traits::type == StreamTraitTypeStruct || Traits::type == StreamTraitTypeStructClass)
@@ -355,7 +355,7 @@ struct StreamHelper<T, StreamTraitTypeSequence>
template<class S> static inline void
read(S* stream, T& v)
{
- Int sz = stream->readAndCheckSeqSize(StreamTrait<T::value_type>::minWireSize);
+ Int sz = stream->readAndCheckSeqSize(StreamTrait<typename T::value_type>::minWireSize);
T(sz).swap(v);
for(typename T::iterator p = v.begin(); p != v.end(); ++p)
{
@@ -524,16 +524,26 @@ struct StreamOptionalHelper
template<class S> static inline void
write(S* stream, const T& v)
{
+#ifdef ICE_CPP11
+ static_assert((ot != OptionalTypeVSize && ot != OptionalTypeFSize && ot != OptionalTypeEndMarker)
+ || st == StreamTraitTypeBuiltin, "Bad helper");
+#else
assert((ot != OptionalTypeVSize && ot != OptionalTypeFSize && ot != OptionalTypeEndMarker)
|| st == StreamTraitTypeBuiltin);
+#endif
StreamHelper<T, st>::write(stream, v);
}
template<class S> static inline void
read(S* stream, T& v)
{
+#ifdef ICE_CPP11
+ static_assert((ot != OptionalTypeVSize && ot != OptionalTypeFSize && ot != OptionalTypeEndMarker)
+ || st == StreamTraitTypeBuiltin, "Bad helper");
+#else
assert((ot != OptionalTypeVSize && ot != OptionalTypeFSize && ot != OptionalTypeEndMarker)
|| st == StreamTraitTypeBuiltin);
+#endif
StreamHelper<T, st>::read(stream, v);
}
};
@@ -568,7 +578,7 @@ struct StreamOptionalHelper<T, StreamTraitTypeStruct, OptionalTypeFSize>
template<class S> static inline void
write(S* stream, const T& v)
{
- stream->write((Int)0);
+ stream->write(static_cast<Int>(0));
typename S::size_type p = stream->pos();
stream->write(v);
stream->rewrite(static_cast<Int>(stream->pos() - p), p - 4);
diff --git a/cpp/include/Slice/CPlusPlusUtil.h b/cpp/include/Slice/CPlusPlusUtil.h
index f738f5036c3..5911961e2aa 100644
--- a/cpp/include/Slice/CPlusPlusUtil.h
+++ b/cpp/include/Slice/CPlusPlusUtil.h
@@ -55,7 +55,6 @@ SLICE_API void writeAllocateCode(::IceUtilInternal::Output&, const ParamDeclList
SLICE_API std::string getEndArg(const TypePtr&, const StringList&, const std::string&);
SLICE_API void writeEndCode(::IceUtilInternal::Output&, const ParamDeclList&, const OperationPtr&);
-SLICE_API std::string findMetaData(const SequencePtr&, const StringList&, bool&, int = 0);
SLICE_API std::string findMetaData(const StringList&, int = 0);
SLICE_API bool inWstringModule(const SequencePtr&);
diff --git a/cpp/src/Slice/CPlusPlusUtil.cpp b/cpp/src/Slice/CPlusPlusUtil.cpp
index 992ba303cda..83fb812cd20 100644
--- a/cpp/src/Slice/CPlusPlusUtil.cpp
+++ b/cpp/src/Slice/CPlusPlusUtil.cpp
@@ -106,12 +106,12 @@ sequenceTypeToString(const SequencePtr& seq, const StringList& metaData, int typ
else
{
// Get the metadata associated at the point of definition.
- bool protobuf;
- seqType = findMetaData(seq, seq->getMetaData(), protobuf, typeCtx);
- if(protobuf && !seqType.empty())
+ seqType = findMetaData(seq->getMetaData(), typeCtx);
+ if(!seqType.empty())
{
return seqType;
}
+
return fixKwd(seq->scoped());
}
}
@@ -154,17 +154,12 @@ writeParamAllocateCode(Output& out, const TypePtr& type, bool optional, const st
SequencePtr seq = SequencePtr::dynamicCast(type);
if(seq)
{
- bool protobuf;
- string seqType = findMetaData(seq, metaData, protobuf, typeCtx);
- if(!protobuf && seqType.empty())
- {
- seqType = findMetaData(seq, seq->getMetaData(), protobuf, typeCtx);
- }
- if(protobuf)
+ string seqType = findMetaData(metaData, typeCtx);
+ if(seqType.empty())
{
- return;
+ seqType = findMetaData(seq->getMetaData(), typeCtx);
}
-
+
string s;
if(seqType == "%array" || seqType == "%range:array")
{
@@ -197,76 +192,73 @@ writeParamEndCode(Output& out, const TypePtr& type, bool optional, const string&
SequencePtr seq = SequencePtr::dynamicCast(type);
if(seq)
{
- bool protobuf;
- string seqType = findMetaData(seq, metaData, protobuf, TypeContextInParam);
- if(!protobuf && seqType.empty())
+ string seqType = findMetaData(metaData, TypeContextInParam);
+ if(seqType.empty())
{
- seqType = findMetaData(seq, seq->getMetaData(), protobuf, TypeContextInParam);
+ seqType = findMetaData(seq->getMetaData(), TypeContextInParam);
}
- if(!protobuf)
+
+ if(seqType == "%array" || seqType == "%range:array")
{
- if(seqType == "%array" || seqType == "%range:array")
+ BuiltinPtr builtin = BuiltinPtr::dynamicCast(seq->type());
+ if(builtin &&
+ builtin->kind() != Builtin::KindByte &&
+ builtin->kind() != Builtin::KindString &&
+ builtin->kind() != Builtin::KindObject &&
+ builtin->kind() != Builtin::KindObjectProxy)
{
- BuiltinPtr builtin = BuiltinPtr::dynamicCast(seq->type());
- if(builtin &&
- builtin->kind() != Builtin::KindByte &&
- builtin->kind() != Builtin::KindString &&
- builtin->kind() != Builtin::KindObject &&
- builtin->kind() != Builtin::KindObjectProxy)
+ if(optional)
{
- if(optional)
- {
- out << nl << "if(___" << fixedName << ")";
- out << sb;
- out << nl << fixedName << " = ___" << fixedName << "->second;";
+ out << nl << "if(___" << fixedName << ")";
+ out << sb;
+ out << nl << fixedName << " = ___" << fixedName << "->second;";
out << eb;
- }
- else
- {
- out << nl << fixedName << " = ___" << fixedName << ".second;";
- }
}
- else if(!builtin ||
- builtin->kind() == Builtin::KindString ||
- builtin->kind() == Builtin::KindObject ||
- builtin->kind() == Builtin::KindObjectProxy)
+ else
{
- if(optional)
- {
- out << nl << "if(___" << fixedName << ")";
- out << sb;
- out << nl << fixedName << ".__setIsSet();";
- out << nl << fixedName << "->first" << " = &(*___" << fixedName << ")[0];";
- out << nl << fixedName << "->second" << " = " << fixedName << "->first + " << "___"
- << fixedName << "->size();";
- out << eb;
- }
- else
- {
- out << nl << fixedName << ".first" << " = &___" << fixedName << "[0];";
- out << nl << fixedName << ".second" << " = " << fixedName << ".first + " << "___"
- << fixedName << ".size();";
- }
+ out << nl << fixedName << " = ___" << fixedName << ".second;";
}
}
- else if(seqType.find("%range") == 0)
+ else if(!builtin ||
+ builtin->kind() == Builtin::KindString ||
+ builtin->kind() == Builtin::KindObject ||
+ builtin->kind() == Builtin::KindObjectProxy)
{
if(optional)
{
out << nl << "if(___" << fixedName << ")";
out << sb;
out << nl << fixedName << ".__setIsSet();";
- out << nl << fixedName << "->first = (*___" << fixedName << ").begin();";
- out << nl << fixedName << "->second = (*___" << fixedName << ").end();";
+ out << nl << fixedName << "->first" << " = &(*___" << fixedName << ")[0];";
+ out << nl << fixedName << "->second" << " = " << fixedName << "->first + " << "___"
+ << fixedName << "->size();";
out << eb;
}
else
{
- out << nl << fixedName << ".first = ___" << fixedName << ".begin();";
- out << nl << fixedName << ".second = ___" << fixedName << ".end();";
+ out << nl << fixedName << ".first" << " = &___" << fixedName << "[0];";
+ out << nl << fixedName << ".second" << " = " << fixedName << ".first + " << "___"
+ << fixedName << ".size();";
}
}
}
+ else if(seqType.find("%range") == 0)
+ {
+ if(optional)
+ {
+ out << nl << "if(___" << fixedName << ")";
+ out << sb;
+ out << nl << fixedName << ".__setIsSet();";
+ out << nl << fixedName << "->first = (*___" << fixedName << ").begin();";
+ out << nl << fixedName << "->second = (*___" << fixedName << ").end();";
+ out << eb;
+ }
+ else
+ {
+ out << nl << fixedName << ".first = ___" << fixedName << ".begin();";
+ out << nl << fixedName << ".second = ___" << fixedName << ".end();";
+ }
+ }
}
}
@@ -962,40 +954,37 @@ Slice::getEndArg(const TypePtr& type, const StringList& metaData, const string&
SequencePtr seq = SequencePtr::dynamicCast(type);
if(seq)
{
- bool protobuf;
- string seqType = findMetaData(seq, metaData, protobuf, TypeContextInParam);
- if(!protobuf && seqType.empty())
+ string seqType = findMetaData(metaData, TypeContextInParam);
+ if(seqType.empty())
{
- seqType = findMetaData(seq, seq->getMetaData(), protobuf, TypeContextInParam);
+ seqType = findMetaData(seq->getMetaData(), TypeContextInParam);
}
- if(!protobuf)
+
+ if(seqType == "%array" || seqType == "%range:array")
{
- if(seqType == "%array" || seqType == "%range:array")
+ BuiltinPtr builtin = BuiltinPtr::dynamicCast(seq->type());
+ if(builtin &&
+ builtin->kind() != Builtin::KindByte &&
+ builtin->kind() != Builtin::KindString &&
+ builtin->kind() != Builtin::KindObject &&
+ builtin->kind() != Builtin::KindObjectProxy)
{
- BuiltinPtr builtin = BuiltinPtr::dynamicCast(seq->type());
- if(builtin &&
- builtin->kind() != Builtin::KindByte &&
- builtin->kind() != Builtin::KindString &&
- builtin->kind() != Builtin::KindObject &&
- builtin->kind() != Builtin::KindObjectProxy)
- {
- endArg = "___" + endArg;
- }
- else if(!builtin || builtin->kind() != Builtin::KindByte)
- {
- endArg = "___" + endArg;
- }
+ endArg = "___" + endArg;
}
- else if(seqType.find("%range") == 0)
+ else if(!builtin || builtin->kind() != Builtin::KindByte)
{
- StringList md;
- if(seqType.find("%range:") == 0)
- {
- md.push_back("cpp:type:" + seqType.substr(strlen("%range:")));
- }
endArg = "___" + endArg;
}
}
+ else if(seqType.find("%range") == 0)
+ {
+ StringList md;
+ if(seqType.find("%range:") == 0)
+ {
+ md.push_back("cpp:type:" + seqType.substr(strlen("%range:")));
+ }
+ endArg = "___" + endArg;
+ }
}
return endArg;
}
@@ -1013,99 +1002,6 @@ Slice::writeEndCode(Output& out, const ParamDeclList& params, const OperationPtr
}
}
-// Accepted metadata.
-//
-// cpp:type:<typename>
-// cpp:const
-// cpp:array
-// cpp:range:<typename>
-// cpp:protobuf<:typename>
-//
-// For the new AMI mapping, we ignore the array and range directives because they don't apply.
-//
-// This form is for sequences definitions only.
-//
-string
-Slice::findMetaData(const SequencePtr& seq, const StringList& metaData, bool& isProtobuf, int typeCtx)
-{
- isProtobuf = false;
- static const string prefix = "cpp:";
- for(StringList::const_iterator q = metaData.begin(); q != metaData.end(); ++q)
- {
- string str = *q;
- if(str.find(prefix) == 0)
- {
- string::size_type pos = str.find(':', prefix.size());
- string ss = str.substr(prefix.size());
-
- //
- // If the form is cpp:type:<...> the data after cpp:type:
- // is returned.
- // If the form is cpp:range[:<...>], cpp:array or cpp:class,
- // the return value is % followed by the string after cpp:.
- //
- if(ss.find("protobuf") == 0 || pos != string::npos)
- {
- if(ss.find("type:") == 0)
- {
- return str.substr(pos + 1);
- }
- else if(ss.find("protobuf:") == 0)
- {
- BuiltinPtr builtin = BuiltinPtr::dynamicCast(seq->type());
- if(!builtin || builtin->kind() != Builtin::KindByte)
- {
- continue;
- }
- isProtobuf = true;
- if(pos != string::npos)
- {
- return str.substr(pos + 1);
- }
- return "";
- }
- else if((typeCtx & (TypeContextInParam | TypeContextAMIPrivateEnd)) &&
- !(typeCtx & TypeContextAMIEnd) && ss.find("range:") == 0)
- {
- return string("%") + str.substr(prefix.size());
- }
- else if((typeCtx & TypeContextAMIPrivateEnd) && ss == "range:array")
- {
- return "%range:array";
- }
- }
- //
- // If the data is an inParam and the metadata is cpp:array
- // or cpp:range then array or range is returned.
- //
- else if(typeCtx & (TypeContextInParam | TypeContextAMIPrivateEnd) && !(typeCtx & TypeContextAMIEnd))
- {
- if(ss == "array")
- {
- return "%array";
- }
- else if((typeCtx & TypeContextInParam) && ss == "range")
- {
- return "%range";
- }
- }
- //
- // Otherwise if the data is "class" it is returned.
- //
- else
- {
- if(ss == "class")
- {
- return "%class";
- }
- }
- }
- }
-
- return "";
-}
-
-// Does not handle cpp:protobuf
string
Slice::findMetaData(const StringList& metaData, int typeCtx)
{
@@ -1126,7 +1022,7 @@ Slice::findMetaData(const StringList& metaData, int typeCtx)
if(pos != string::npos)
{
string ss = str.substr(prefix.size());
- if(ss.find("type:") == 0)
+ if(ss.find("type:") == 0 || ss.find("protobuf:") == 0)
{
return str.substr(pos + 1);
}
diff --git a/cpp/src/slice2cpp/Gen.cpp b/cpp/src/slice2cpp/Gen.cpp
index e7477b1bd95..d67d8aa3256 100644
--- a/cpp/src/slice2cpp/Gen.cpp
+++ b/cpp/src/slice2cpp/Gen.cpp
@@ -1332,27 +1332,6 @@ void
Slice::Gen::TypesVisitor::visitDataMember(const DataMemberPtr& p)
{
string name = fixKwd(p->name());
- TypePtr type = p->type();
- if(p->container() != 0 &&
- (StructPtr::dynamicCast(p->container()) || ExceptionPtr::dynamicCast(p->container())) &&
- SequencePtr::dynamicCast(type))
- {
- SequencePtr s = SequencePtr::dynamicCast(type);
- BuiltinPtr builtin = BuiltinPtr::dynamicCast(s->type());
- if(builtin && builtin->kind() == Builtin::KindByte)
- {
- StringList metaData = s->getMetaData();
- bool protobuf;
- findMetaData(s, metaData, protobuf);
- if(protobuf)
- {
- emitWarning(p->file(), p->line(), string("protobuf cannot be used as a ") +
- (StructPtr::dynamicCast(p->container()) ? "struct" : "exception") +
- " member in C++");
- }
- }
- }
-
H << nl << typeToString(p->type(), p->optional(), p->getMetaData(), _useWstring) << ' ' << name << ';';
}
@@ -1364,19 +1343,16 @@ Slice::Gen::TypesVisitor::visitSequence(const SequencePtr& p)
string s = typeToString(type, p->typeMetaData(), _useWstring);
StringList metaData = p->getMetaData();
- bool protobuf;
- string seqType = findMetaData(p, metaData, protobuf);
+ string seqType = findMetaData(metaData, _useWstring);
H << sp;
- if(!protobuf)
+
+ if(!seqType.empty())
{
- if(!seqType.empty())
- {
- H << nl << "typedef " << seqType << ' ' << name << ';';
- }
- else
- {
- H << nl << "typedef ::std::vector<" << (s[0] == ':' ? " " : "") << s << "> " << name << ';';
- }
+ H << nl << "typedef " << seqType << ' ' << name << ';';
+ }
+ else
+ {
+ H << nl << "typedef ::std::vector<" << (s[0] == ':' ? " " : "") << s << "> " << name << ';';
}
}
@@ -1393,22 +1369,6 @@ Slice::Gen::TypesVisitor::visitDictionary(const DictionaryPtr& p)
//
TypePtr keyType = p->keyType();
- if(SequencePtr::dynamicCast(keyType))
- {
- SequencePtr s = SequencePtr::dynamicCast(keyType);
- BuiltinPtr builtin = BuiltinPtr::dynamicCast(s->type());
- if(builtin && builtin->kind() == Builtin::KindByte)
- {
- StringList metaData = s->getMetaData();
- bool protobuf;
- findMetaData(s, metaData, protobuf);
- if(protobuf)
- {
- emitWarning(p->file(), p->line(), "protobuf cannot be used as a dictionary key in C++");
- }
- }
- }
-
TypePtr valueType = p->valueType();
string ks = typeToString(keyType, p->keyMetaData(), _useWstring);
if(ks[0] == ':')
@@ -4531,24 +4491,7 @@ Slice::Gen::ObjectVisitor::visitOperation(const OperationPtr& p)
void
Slice::Gen::ObjectVisitor::emitDataMember(const DataMemberPtr& p)
-{
- TypePtr type = p->type();
- if(SequencePtr::dynamicCast(type))
- {
- SequencePtr s = SequencePtr::dynamicCast(type);
- BuiltinPtr builtin = BuiltinPtr::dynamicCast(s->type());
- if(builtin && builtin->kind() == Builtin::KindByte)
- {
- StringList metaData = s->getMetaData();
- bool protobuf;
- findMetaData(s, metaData, protobuf);
- if(protobuf)
- {
- emitWarning(p->file(), p->line(), "protobuf cannot be used as a class member in C++");
- }
- }
- }
-
+{
string name = fixKwd(p->name());
H << sp << nl << typeToString(p->type(), p->optional(), p->getMetaData(), _useWstring) << ' ' << name << ';';
}
@@ -6366,34 +6309,7 @@ Slice::Gen::MetaDataVisitor::visitDataMember(const DataMemberPtr& p)
void
Slice::Gen::MetaDataVisitor::visitSequence(const SequencePtr& p)
{
- StringList metaData = p->getMetaData();
- const string file = p->file();
- const string line = p->line();
- static const string prefix = "cpp:protobuf";
- for(StringList::const_iterator q = metaData.begin(); q != metaData.end(); )
- {
- string s = *q++;
- if(_history.count(s) == 0)
- {
- if(s.find(prefix) == 0)
- {
- //
- // Remove from list so validate does not try to handle as well.
- //
- metaData.remove(s);
-
- BuiltinPtr builtin = BuiltinPtr::dynamicCast(p->type());
- if(!builtin || builtin->kind() != Builtin::KindByte)
- {
- _history.insert(s);
- emitWarning(file, line, "ignoring invalid metadata `" + s + "':\n"+
- "`protobuf' encoding must be a byte sequence.");
- }
- }
- }
- }
-
- validate(p, metaData, file, line);
+ validate(p, p->getMetaData(), p->file(), p->line());
}
void