diff options
author | Bernard Normier <bernard@zeroc.com> | 2012-09-19 12:00:52 -0400 |
---|---|---|
committer | Bernard Normier <bernard@zeroc.com> | 2012-09-19 12:09:56 -0400 |
commit | 2068ac0ec6ce1f239abc73ff23407326ba33ffbf (patch) | |
tree | 110b52821232cdc5ffb1d6cd4f5f2110ed520f4d /cpp | |
parent | Python support for optionals (diff) | |
download | ice-2068ac0ec6ce1f239abc73ff23407326ba33ffbf.tar.bz2 ice-2068ac0ec6ce1f239abc73ff23407326ba33ffbf.tar.xz ice-2068ac0ec6ce1f239abc73ff23407326ba33ffbf.zip |
Partial fix for ICE-3393:
- strealined StreamTraits.h
- added ability to define custom dictionaries in C++ (with cpp:type:...)
- added tests for custom dictionaries in test/Ice/custom
Fixed ICE-4867:
- clear parameter before unmarshaling into dictionary/map in C++
- added test
Diffstat (limited to 'cpp')
-rw-r--r-- | cpp/include/Ice/BasicStream.h | 4 | ||||
-rw-r--r-- | cpp/include/Ice/StreamTraits.h | 316 | ||||
-rw-r--r-- | cpp/src/Ice/StreamI.cpp | 7 | ||||
-rw-r--r-- | cpp/src/Slice/CPlusPlusUtil.cpp | 35 | ||||
-rw-r--r-- | cpp/src/slice2cpp/Gen.cpp | 57 | ||||
-rwxr-xr-x | cpp/test/Ice/custom/AllTests.cpp | 215 | ||||
-rw-r--r-- | cpp/test/Ice/custom/CustomMap.h | 38 | ||||
-rw-r--r-- | cpp/test/Ice/custom/Makefile.mak | 2 | ||||
-rw-r--r-- | cpp/test/Ice/custom/MyByteSeq.h | 2 | ||||
-rw-r--r-- | cpp/test/Ice/custom/Test.ice | 17 | ||||
-rw-r--r-- | cpp/test/Ice/custom/TestAMD.ice | 17 | ||||
-rw-r--r-- | cpp/test/Ice/custom/TestAMDI.cpp | 22 | ||||
-rw-r--r-- | cpp/test/Ice/custom/TestAMDI.h | 10 | ||||
-rw-r--r-- | cpp/test/Ice/custom/TestI.cpp | 21 | ||||
-rw-r--r-- | cpp/test/Ice/custom/TestI.h | 9 | ||||
-rw-r--r-- | cpp/test/Ice/optional/AllTests.cpp | 30 |
16 files changed, 608 insertions, 194 deletions
diff --git a/cpp/include/Ice/BasicStream.h b/cpp/include/Ice/BasicStream.h index fcffd268000..77b2d4dec56 100644 --- a/cpp/include/Ice/BasicStream.h +++ b/cpp/include/Ice/BasicStream.h @@ -459,14 +459,14 @@ public: void startSize() { - _sizePos = static_cast<int>(b.size()); + _sizePos = static_cast<Ice::Int>(b.size()); write(Ice::Int(0)); } void endSize() { assert(_sizePos >= 0); - rewrite(b.size() - _sizePos - 4, _sizePos); + rewrite(static_cast<Ice::Int>(b.size()) - _sizePos - 4, _sizePos); _sizePos = -1; } diff --git a/cpp/include/Ice/StreamTraits.h b/cpp/include/Ice/StreamTraits.h index 97638d5152b..00f38cb5819 100644 --- a/cpp/include/Ice/StreamTraits.h +++ b/cpp/include/Ice/StreamTraits.h @@ -15,7 +15,6 @@ #include <Ice/ObjectF.h> - namespace Ice { @@ -34,7 +33,7 @@ enum StreamTraitType StreamTraitTypeProxy, StreamTraitTypeClass, StreamTraitTypeUserException, - StreamTraitTypeUnknown + StreamTraitTypeCustom }; // @@ -42,58 +41,106 @@ enum StreamTraitType // // 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 skiped by the un-marhsalling code if the optional +// and how it can be skipped by the un-marhsalling code if the optional // isn't known to the receiver. // enum OptionalType { - OptionalTypeF1 = 0, - OptionalTypeF2 = 1, - OptionalTypeF4 = 2, - OptionalTypeF8 = 3, - OptionalTypeSize = 4, - OptionalTypeVSize = 5, - OptionalTypeFSize = 6, - OptionalTypeEndMarker = 7 + OptionalTypeF1 = 0, // Fixed 1-byte encoding + OptionalTypeF2 = 1, // Fixed 2 bytes encoding + OptionalTypeF4 = 2, // Fixed 4 bytes encoding + OptionalTypeF8 = 3, // Fixed 8 bytes encoding + OptionalTypeSize = 4, // "Size encoding" on 1 to 5 bytes, e.g. enum, class identifier + OptionalTypeVSize = 5, // "Size encoding" on 1 to 5 bytes followed by data, e.g. string, fixed size struct, + // or containers whose size can be computed prior to marshaling + OptionalTypeFSize = 6, // Fixed size on 4 bytes followed by data, e.g. variable-size struct, container. + OptionalTypeEndMarker = 7 }; + // -// Base trait template. This doesn't actually do anything -- we just -// use it as a template that we can specialize. +// Is the provided type a container? +// For now, the implementation only checks if there is a T::iterator typedef +// using SFINAE +// +template<typename T> +struct IsContainer +{ + template<typename C> + static char test(typename C::iterator*); + + template<typename C> + static long test(...); + + static const bool value = sizeof(test<T>(0)) == sizeof(char); +}; + // -// Note that types which don't define a specialized trait will end up -// using this trait. The marshalling of unknown types assume that -// such traits are custom sequences. If not appropriate, a trait has -// to defined with the appropriate type. +// Is the provided type a map? +// For now, the implementation only checks if there is a T::mapped_type typedef +// using SFINAE // template<typename T> -struct StreamTrait +struct IsMap { - static const StreamTraitType type = StreamTraitTypeUnknown; - static const int minWireSize = 1; - static const OptionalType optionalType = OptionalTypeVSize; // Not used - static const bool isVariableLength = true; + template<typename C> + static char test(typename C::mapped_type*); + + template<typename C> + static long test(...); + + static const bool value = IsContainer<T>::value && sizeof(test<T>(0)) == sizeof(char); }; // -// StreamTrait specialization for std::vector +// Base trait template. +// Types with no specialized trait use this trait. // template<typename T> -struct StreamTrait< ::std::vector<T> > +struct StreamTrait { - static const StreamTraitType type = StreamTraitTypeSequence; + static const StreamTraitType type = IsMap<T>::value ? StreamTraitTypeDictionary : + (IsContainer<T>::value ? StreamTraitTypeSequence : StreamTraitTypeCustom); + + // + // When extracting a sequence<T> from a stream, we can ensure the + // stream as at least StreamTrait<T>::minWireSize * size bytes + // For containers, the minWireSize is 1 - just 1 byte for an empty container. + // static const int minWireSize = 1; - static const OptionalType optionalType = OptionalTypeVSize; // Not used but still need to be defined. - static const bool isVariableLength = true; + + // + // The OptionalType, for reading/writing optional T from/to the stream + // For containers, it can be either OptionalTypeVSize or OptionalTypeFSize + // depending on whether the contained element is fixed size or not. + // We can't easily compute it here, so we set optionalType to OptionalTypeEndMarker + // and compute the correct optionalType for the container in the StreamOptionalHelpers + // below. + // + static const OptionalType optionalType = OptionalTypeEndMarker; +}; + +template<typename T> +struct IsFixedLength +{ + typedef typename StreamTrait<T> Traits; + + static const bool value = (Traits::optionalType <= OptionalTypeF8) + || ((Traits::type == StreamTraitTypeStruct || Traits::type == StreamTraitTypeStructClass) + && Traits::optionalType == OptionalTypeVSize); }; +// +// StreamTrait specialization for array / range mapped sequences +// The type can be a std::pair<T, T> or a +// std::pair<IceUtil::ScopedArray<T>, std::pair<const T*, const T*> > +// template<typename T, typename U> struct StreamTrait< ::std::pair<T, U> > { static const StreamTraitType type = StreamTraitTypeSequence; static const int minWireSize = 1; - static const OptionalType optionalType = OptionalTypeVSize; // Not used but still need to be defined. - static const bool isVariableLength = true; + static const OptionalType optionalType = OptionalTypeEndMarker; }; // @@ -103,85 +150,72 @@ template<> struct StreamTrait<UserException> { static const StreamTraitType type = StreamTraitTypeUserException; -}; -// -// StreamTrait specialization for std::map. -// -template<typename K, typename V> -struct StreamTrait< ::std::map<K, V> > -{ - static const StreamTraitType type = StreamTraitTypeDictionary; - static const int minWireSize = 1; - static const OptionalType optionalType = OptionalTypeVSize; // Not used - static const bool isVariableLength = true; + // + // There is no sequence/dictionary of UserException (so no need for minWireSize) + // and no optional UserException (so no need for optionalType) + // }; + // // StreamTrait specialization for builtins (these are needed for sequence // marshalling to figure out the minWireSize of each built-in). // template<> -struct StreamTrait< bool> +struct StreamTrait<bool> { static const StreamTraitType type = StreamTraitTypeBuiltin; static const int minWireSize = 1; static const OptionalType optionalType = OptionalTypeF1; - static const bool isVariableLength = false; }; template<> -struct StreamTrait< Byte> +struct StreamTrait<Byte> { static const StreamTraitType type = StreamTraitTypeBuiltin; static const int minWireSize = 1; static const OptionalType optionalType = OptionalTypeF1; - static const bool isVariableLength = false; }; template<> -struct StreamTrait< Short> +struct StreamTrait<Short> { static const StreamTraitType type = StreamTraitTypeBuiltin; static const int minWireSize = 2; static const OptionalType optionalType = OptionalTypeF2; - static const bool isVariableLength = false; }; template<> -struct StreamTrait< Int> +struct StreamTrait<Int> { static const StreamTraitType type = StreamTraitTypeBuiltin; static const int minWireSize = 4; static const OptionalType optionalType = OptionalTypeF4; - static const bool isVariableLength = false; }; template<> -struct StreamTrait< Long> +struct StreamTrait<Long> { static const StreamTraitType type = StreamTraitTypeBuiltin; static const int minWireSize = 8; static const OptionalType optionalType = OptionalTypeF8; - static const bool isVariableLength = false; }; template<> -struct StreamTrait< Float> +struct StreamTrait<Float> { static const StreamTraitType type = StreamTraitTypeBuiltin; static const int minWireSize = 4; static const OptionalType optionalType = OptionalTypeF4; - static const bool isVariableLength = false; }; template<> -struct StreamTrait< Double> +struct StreamTrait<Double> { static const StreamTraitType type = StreamTraitTypeBuiltin; static const int minWireSize = 8; static const OptionalType optionalType = OptionalTypeF8; - static const bool isVariableLength = false; }; template<> @@ -190,7 +224,6 @@ struct StreamTrait< ::std::string> static const StreamTraitType type = StreamTraitTypeBuiltin; static const int minWireSize = 1; static const OptionalType optionalType = OptionalTypeVSize; - static const bool isVariableLength = true; }; template<> @@ -199,7 +232,6 @@ struct StreamTrait< ::std::wstring> static const StreamTraitType type = StreamTraitTypeBuiltin; static const int minWireSize = 1; static const OptionalType optionalType = OptionalTypeVSize; - static const bool isVariableLength = true; }; template<typename T> @@ -208,7 +240,6 @@ struct StreamTrait< ::IceInternal::ProxyHandle<T> > static const StreamTraitType type = StreamTraitTypeProxy; static const int minWireSize = 2; static const OptionalType optionalType = OptionalTypeFSize; - static const bool isVariableLength = true; }; template<typename T> @@ -217,48 +248,17 @@ struct StreamTrait< ::IceInternal::Handle<T> > static const StreamTraitType type = StreamTraitTypeClass; static const int minWireSize = 1; static const OptionalType optionalType = OptionalTypeSize; - static const bool isVariableLength = true; }; + // // StreamHelper templates used by streams to read and write data. // +// Base StreamHelper template; it must be specialized for each type template<typename T, StreamTraitType st> -struct StreamHelper -{ - template<class S> static inline void - write(S* stream, const T& v) - { - assert(false); - } - - template<class S> static inline void - read(S* stream, T& v) - { - assert(false); - } -}; - -template<typename T, StreamTraitType st, OptionalType ot> -struct StreamOptionalHelper -{ - static const OptionalType optionalType = ot; +struct StreamHelper; - template<class S> static inline void - write(S* stream, const T& v) - { - assert((ot != OptionalTypeVSize && ot != OptionalTypeFSize) || st == StreamTraitTypeBuiltin); - StreamHelper<T, st>::write(stream, v); - } - - template<class S> static inline void - read(S* stream, T& v) - { - assert((ot != OptionalTypeVSize && ot != OptionalTypeFSize) || st == StreamTraitTypeBuiltin); - StreamHelper<T, st>::read(stream, v); - } -}; // Helper for builtins, delegates read/write to the stream. template<typename T> @@ -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>::minWireSize); + Int sz = stream->readAndCheckSeqSize(StreamTrait<T::value_type>::minWireSize); T(sz).swap(v); for(typename T::iterator p = v.begin(); p != v.end(); ++p) { @@ -417,11 +417,7 @@ struct StreamHelper<std::pair< ::std::vector<bool>::const_iterator, } } - template<class S> static inline void - read(S* stream, std::pair< ::std::vector<bool>::const_iterator, ::std::vector<bool>::const_iterator>&) - { - assert(false); // Only used for marshaling. - } + // no read: only used for marshaling }; // Helper for zero-copy array sequence parameters @@ -429,16 +425,12 @@ template<typename T> struct StreamHelper<std::pair<IceUtil::ScopedArray<T>, std::pair<const T*, const T*> >, StreamTraitTypeSequence> { template<class S> static inline void - write(S* stream, const std::pair<IceUtil::ScopedArray<T>, std::pair<const T*, const T*> > & v) - { - assert(false); // Only used to un-marshal - } - - template<class S> static inline void read(S* stream, std::pair<IceUtil::ScopedArray<T>, std::pair<const T*, const T*> >& v) { v.first.reset(stream->read(v.second)); } + + // no write: only used for unmarshaling }; // Helper for dictionaries @@ -460,6 +452,7 @@ struct StreamHelper<T, StreamTraitTypeDictionary> read(S* stream, T& v) { Int sz = stream->readSize(); + v.clear(); while(sz--) { typename T::value_type p; @@ -480,11 +473,7 @@ struct StreamHelper<T, StreamTraitTypeUserException> stream->writeException(v); } - template<class S> static inline void - read(S* stream, T& v) - { - assert(false); - } + // no read: only used for marshaling }; // Helper for proxies @@ -521,16 +510,34 @@ struct StreamHelper<T, StreamTraitTypeClass> } }; -// Helper for unknown types, assume custom sequences. -template<typename T> -struct StreamHelper<T, StreamTraitTypeUnknown> : StreamHelper<T, StreamTraitTypeSequence> -{ -}; // // Helpers to read/write optional attributes or members. // +// Base helper +template<typename T, StreamTraitType st, OptionalType ot> +struct StreamOptionalHelper +{ + static const OptionalType optionalType = ot; + + template<class S> static inline void + write(S* stream, const T& v) + { + assert((ot != OptionalTypeVSize && ot != OptionalTypeFSize && ot != OptionalTypeEndMarker) + || st == StreamTraitTypeBuiltin); + StreamHelper<T, st>::write(stream, v); + } + + template<class S> static inline void + read(S* stream, T& v) + { + assert((ot != OptionalTypeVSize && ot != OptionalTypeFSize && ot != OptionalTypeEndMarker) + || st == StreamTraitTypeBuiltin); + StreamHelper<T, st>::read(stream, v); + } +}; + // Helper to write fixed size structs template<typename T> struct StreamOptionalHelper<T, StreamTraitTypeStruct, OptionalTypeVSize> @@ -591,24 +598,8 @@ struct StreamOptionalHelper<T, StreamTraitTypeProxy, OptionalTypeFSize> : // // Helpers to read/write optional sequences or dictionaries // - -template<typename T, bool isVariableLength, int sz> -struct StreamOptionalContainerHelper -{ - static const OptionalType optionalType = OptionalTypeFSize; - - template<class S> static inline void - write(S* stream, const T& v, Ice::Int n) - { - assert(false); - } - - template<class S> static inline void - read(S* stream, T& v) - { - assert(false); - } -}; +template<typename T, bool isFixedLength, int sz> +struct StreamOptionalContainerHelper; // // Encode containers of variable size elements with the FSize optional @@ -617,7 +608,7 @@ struct StreamOptionalContainerHelper // so we just re-use its implementation. // template<typename T, int sz> -struct StreamOptionalContainerHelper<T, true, sz> +struct StreamOptionalContainerHelper<T, false, sz> { static const OptionalType optionalType = OptionalTypeFSize; @@ -640,7 +631,7 @@ struct StreamOptionalContainerHelper<T, true, sz> // encoding. // template<typename T, int sz> -struct StreamOptionalContainerHelper<T, false, sz> +struct StreamOptionalContainerHelper<T, true, sz> { static const OptionalType optionalType = OptionalTypeVSize; @@ -671,7 +662,7 @@ struct StreamOptionalContainerHelper<T, false, sz> // skip the optional. // template<typename T> -struct StreamOptionalContainerHelper<T, false, 1> +struct StreamOptionalContainerHelper<T, true, 1> { static const OptionalType optionalType = OptionalTypeVSize; @@ -697,22 +688,22 @@ struct StreamOptionalHelper<T, StreamTraitTypeSequence, ot> { typedef typename T::value_type E; static const int size = StreamTrait<E>::minWireSize; - static const bool isVariableLength = StreamTrait<E>::isVariableLength; + static const bool isFixedLength = IsFixedLength<E>::value; - // The optional type of a sequence depends on wether or not elements are fixed + // The optional type of a sequence depends on whether or not elements are fixed // or variable size elements and their size. - static const OptionalType optionalType = StreamOptionalContainerHelper<T, isVariableLength, size>::optionalType; + static const OptionalType optionalType = StreamOptionalContainerHelper<T, isFixedLength, size>::optionalType; template<class S> static inline void write(S* stream, const T& v) { - StreamOptionalContainerHelper<T, isVariableLength, size>::write(stream, v, v.size()); + StreamOptionalContainerHelper<T, isFixedLength, size>::write(stream, v, static_cast<Int>(v.size())); } template<class S> static inline void read(S* stream, T& v) { - StreamOptionalContainerHelper<T, isVariableLength, size>::read(stream, v); + StreamOptionalContainerHelper<T, isFixedLength, size>::read(stream, v); } }; @@ -721,23 +712,23 @@ struct StreamOptionalHelper<std::pair<const T*, const T*>, StreamTraitTypeSequen { typedef std::pair<const T*, const T*> P; static const int size = StreamTrait<T>::minWireSize; - static const bool isVariableLength = StreamTrait<T>::isVariableLength; + static const bool isFixedLength = IsFixedLength<T>::value; - // The optional type of a sequence depends on wether or not elements are fixed + // The optional type of a sequence depends on whether or not elements are fixed // or variable size elements and their size. - static const OptionalType optionalType = StreamOptionalContainerHelper<P, isVariableLength, size>::optionalType; + static const OptionalType optionalType = StreamOptionalContainerHelper<P, isFixedLength, size>::optionalType; template<class S> static inline void write(S* stream, const P& v) { Ice::Int n = static_cast<Ice::Int>(v.second - v.first); - StreamOptionalContainerHelper<P, isVariableLength, size>::write(stream, v, n); + StreamOptionalContainerHelper<P, isFixedLength, size>::write(stream, v, n); } template<class S> static inline void read(S* stream, P& v) { - StreamOptionalContainerHelper<P, isVariableLength, size>::read(stream, v); + StreamOptionalContainerHelper<P, isFixedLength, size>::read(stream, v); } }; @@ -746,23 +737,23 @@ struct StreamOptionalHelper<std::pair<T, T>, StreamTraitTypeSequence, ot> { typedef std::pair<T, T> P; static const int size = StreamTrait<typename T::value_type>::minWireSize; - static const bool isVariableLength = StreamTrait<typename T::value_type>::isVariableLength; + static const bool isFixedLength = IsFixedLength<typename T::value_type>::value; - // The optional type of a sequence depends on wether or not elements are fixed + // The optional type of a sequence depends on whether or not elements are fixed // or variable size elements and their size. - static const OptionalType optionalType = StreamOptionalContainerHelper<P, isVariableLength, size>::optionalType; + static const OptionalType optionalType = StreamOptionalContainerHelper<P, isFixedLength, size>::optionalType; template<class S> static inline void write(S* stream, const P& v) { Ice::Int n = static_cast<Ice::Int>(v.second - v.first); - StreamOptionalContainerHelper<P, isVariableLength, size>::write(stream, v, n); + StreamOptionalContainerHelper<P, isFixedLength, size>::write(stream, v, n); } template<class S> static inline void read(S* stream, P& v) { - StreamOptionalContainerHelper<P, isVariableLength, size>::read(stream, v); + StreamOptionalContainerHelper<P, isFixedLength, size>::read(stream, v); } }; @@ -772,25 +763,20 @@ struct StreamOptionalHelper<std::pair<IceUtil::ScopedArray<T>, std::pair<const T { typedef std::pair<IceUtil::ScopedArray<T>, std::pair<const T*, const T*> > P; static const int size = StreamTrait<T>::minWireSize; - static const bool isVariableLength = StreamTrait<T>::isVariableLength; + static const bool isFixedLength = IsFixedLength<T>::value; - // The optional type of a sequence depends on wether or not elements are fixed + // The optional type of a sequence depends on whether or not elements are fixed // or variable size elements and their size. - static const OptionalType optionalType = StreamOptionalContainerHelper<P, isVariableLength, size>::optionalType; - - template<class S> static inline void - write(S* stream, const P& v) - { - assert(false); - } + static const OptionalType optionalType = StreamOptionalContainerHelper<P, isFixedLength, size>::optionalType; template<class S> static inline void read(S* stream, P& v) { - StreamOptionalContainerHelper<P, isVariableLength, size>::read(stream, v); + StreamOptionalContainerHelper<P, isFixedLength, size>::read(stream, v); } -}; + // no write: only used for unmarshaling +}; // // Helper to write dictionaries, delegates to the optional container @@ -803,22 +789,22 @@ struct StreamOptionalHelper<T, StreamTraitTypeDictionary, ot> typedef typename T::mapped_type V; static const int size = StreamTrait<K>::minWireSize + StreamTrait<V>::minWireSize; - static const bool isVariableLength = StreamTrait<K>::isVariableLength || StreamTrait<V>::isVariableLength; + static const bool isFixedLength = IsFixedLength<K>::value && IsFixedLength<V>::value; - // The optional type of a dictionary depends on wether or not elements are fixed + // The optional type of a dictionary depends on whether or not elements are fixed // or variable size elements. - static const OptionalType optionalType = StreamOptionalContainerHelper<T, isVariableLength, size>::optionalType; + static const OptionalType optionalType = StreamOptionalContainerHelper<T, isFixedLength, size>::optionalType; template<class S> static inline void write(S* stream, const T& v) { - StreamOptionalContainerHelper<T, isVariableLength, size>::write(stream, v, v.size()); + StreamOptionalContainerHelper<T, isFixedLength, size>::write(stream, v, static_cast<Int>(v.size())); } template<class S> static inline void read(S* stream, T& v) { - StreamOptionalContainerHelper<T, isVariableLength, size>::read(stream, v); + StreamOptionalContainerHelper<T, isFixedLength, size>::read(stream, v); } }; diff --git a/cpp/src/Ice/StreamI.cpp b/cpp/src/Ice/StreamI.cpp index 431926d64b0..e533b77ceda 100644 --- a/cpp/src/Ice/StreamI.cpp +++ b/cpp/src/Ice/StreamI.cpp @@ -702,6 +702,13 @@ void ObjectReader::__read(BasicStream* is) { InputStreamI* stream = reinterpret_cast<InputStreamI*>(is->closure()); + + if(stream == 0) + { + Ice::ObjectNotExistException ex(__FILE__, __LINE__); + cerr << ex.ice_stackTrace() << endl; + } + assert(stream); read(stream); } diff --git a/cpp/src/Slice/CPlusPlusUtil.cpp b/cpp/src/Slice/CPlusPlusUtil.cpp index 9eaed2ebcc5..992ba303cda 100644 --- a/cpp/src/Slice/CPlusPlusUtil.cpp +++ b/cpp/src/Slice/CPlusPlusUtil.cpp @@ -116,6 +116,21 @@ sequenceTypeToString(const SequencePtr& seq, const StringList& metaData, int typ } } +string +dictionaryTypeToString(const DictionaryPtr& dict, const StringList& metaData, int typeCtx) +{ + string dictType = findMetaData(metaData, typeCtx); + if(!dictType.empty()) + { + return dictType; + } + else + { + return fixKwd(dict->scoped()); + } +} + + void writeParamAllocateCode(Output& out, const TypePtr& type, bool optional, const string& fixedName, const StringList& metaData, int typeCtx) @@ -472,7 +487,13 @@ Slice::typeToString(const TypePtr& type, const StringList& metaData, int typeCtx { return sequenceTypeToString(seq, metaData, typeCtx); } - + + DictionaryPtr dict = DictionaryPtr::dynamicCast(type); + if(dict) + { + return dictionaryTypeToString(dict, metaData, typeCtx); + } + ContainedPtr contained = ContainedPtr::dynamicCast(type); if(contained) { @@ -596,6 +617,12 @@ Slice::inputTypeToString(const TypePtr& type, bool optional, const StringList& m { return "const " + sequenceTypeToString(seq, metaData, typeCtx) + "&"; } + + DictionaryPtr dict = DictionaryPtr::dynamicCast(type); + if(dict) + { + return "const " + dictionaryTypeToString(dict, metaData, typeCtx) + "&"; + } ContainedPtr contained = ContainedPtr::dynamicCast(type); if(contained) @@ -678,6 +705,12 @@ Slice::outputTypeToString(const TypePtr& type, bool optional, const StringList& return sequenceTypeToString(seq, metaData, typeCtx) + "&"; } + DictionaryPtr dict = DictionaryPtr::dynamicCast(type); + if(dict) + { + return dictionaryTypeToString(dict, metaData, typeCtx) + "&"; + } + ContainedPtr contained = ContainedPtr::dynamicCast(type); if(contained) { diff --git a/cpp/src/slice2cpp/Gen.cpp b/cpp/src/slice2cpp/Gen.cpp index b0c4f5666db..e7477b1bd95 100644 --- a/cpp/src/slice2cpp/Gen.cpp +++ b/cpp/src/slice2cpp/Gen.cpp @@ -1384,31 +1384,48 @@ void Slice::Gen::TypesVisitor::visitDictionary(const DictionaryPtr& p) { string name = fixKwd(p->name()); - TypePtr keyType = p->keyType(); - if(SequencePtr::dynamicCast(keyType)) + string dictType = findMetaData(p->getMetaData()); + + if(dictType.empty()) { - SequencePtr s = SequencePtr::dynamicCast(keyType); - BuiltinPtr builtin = BuiltinPtr::dynamicCast(s->type()); - if(builtin && builtin->kind() == Builtin::KindByte) + // + // A default std::map dictionary + // + + TypePtr keyType = p->keyType(); + if(SequencePtr::dynamicCast(keyType)) { - StringList metaData = s->getMetaData(); - bool protobuf; - findMetaData(s, metaData, protobuf); - if(protobuf) + SequencePtr s = SequencePtr::dynamicCast(keyType); + BuiltinPtr builtin = BuiltinPtr::dynamicCast(s->type()); + if(builtin && builtin->kind() == Builtin::KindByte) { - emitWarning(p->file(), p->line(), "protobuf cannot be used as a dictionary key in C++"); + 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] == ':') + { + ks.insert(0, " "); + } + string vs = typeToString(valueType, p->valueMetaData(), _useWstring); + + H << sp << nl << "typedef ::std::map<" << ks << ", " << vs << "> " << name << ';'; } - - TypePtr valueType = p->valueType(); - string ks = typeToString(keyType, p->keyMetaData(), _useWstring); - if(ks[0] == ':') + else { - ks.insert(0, " "); + // + // A custom dictionary + // + H << sp << nl << "typedef " << dictType << ' ' << name << ';'; } - string vs = typeToString(valueType, p->valueMetaData(), _useWstring); - H << sp << nl << "typedef ::std::map<" << ks << ", " << vs << "> " << name << ';'; } void @@ -6143,7 +6160,6 @@ Slice::Gen::StreamVisitor::visitStructStart(const StructPtr& p) H << nl << "static const ::Ice::StreamTraitType type = ::Ice::StreamTraitTypeStruct;"; } H << nl << "static const int minWireSize = " << p->minWireSize() << ";"; - H << nl << "static const bool isVariableLength = " << p->isVariableLength() << ";"; if(p->isVariableLength()) { H << nl << "static const ::Ice::OptionalType optionalType = ::Ice::OptionalTypeFSize;"; @@ -6167,7 +6183,6 @@ Slice::Gen::StreamVisitor::visitEnum(const EnumPtr& p) H << nl << "static const ::Ice::StreamTraitType type = ::Ice::StreamTraitTypeEnum;"; H << nl << "static const int enumLimit = " << p->getEnumerators().size() << ";"; H << nl << "static const int minWireSize = " << p->minWireSize() << ";"; - H << nl << "static const bool isVariableLength = true;"; H << nl << "static const ::Ice::OptionalType optionalType = ::Ice::OptionalTypeSize;"; H << eb << ";" << nl; } @@ -6431,6 +6446,10 @@ Slice::Gen::MetaDataVisitor::validate(const SyntaxTreeBasePtr& cont, const Strin continue; } } + if(DictionaryPtr::dynamicCast(cont) && ss.find("type:") == 0) + { + continue; + } if(StructPtr::dynamicCast(cont) && ss.find("class") == 0) { continue; diff --git a/cpp/test/Ice/custom/AllTests.cpp b/cpp/test/Ice/custom/AllTests.cpp index 0f6853e19a5..de4f598f5e9 100755 --- a/cpp/test/Ice/custom/AllTests.cpp +++ b/cpp/test/Ice/custom/AllTests.cpp @@ -1405,8 +1405,8 @@ public: void opOutArrayByteSeq(const ::std::pair<const ::Ice::Byte*, const ::Ice::Byte*>& data, const InParamPtr& cookie) { - Test::ByteSeq dumy; - const Test::ByteSeq& in = getIn(dumy, cookie); + Test::ByteSeq dummy; + const Test::ByteSeq& in = getIn(dummy, cookie); Test::ByteSeq out(data.first, data.second); Test::ByteSeq::const_iterator p1; Test::ByteSeq::const_iterator p2; @@ -1421,8 +1421,8 @@ public: void opOutRangeByteSeq(const ::std::pair< ::Test::ByteSeq::const_iterator, ::Test::ByteSeq::const_iterator>& data, const InParamPtr& cookie) { - Test::ByteSeq dumy; - const Test::ByteSeq& in = getIn(dumy, cookie); + Test::ByteSeq dummy; + const Test::ByteSeq& in = getIn(dummy, cookie); Test::ByteSeq out(data.first, data.second); Test::ByteSeq::const_iterator p1; Test::ByteSeq::const_iterator p2; @@ -1434,6 +1434,34 @@ public: called(); } + void opIntStringDict(const Test::IntStringDict& ret, const Test::IntStringDict& out, const InParamPtr& cookie) + { + Test::IntStringDict dummy; // just for type + const Test::IntStringDict& in = getIn(dummy, cookie); + + test(ret == in); + test(out == in); + called(); + } + + void opVarDict(const Test::CustomMap<Ice::Long, Ice::Long>& ret, + const Test::CustomMap<std::string, Ice::Int>& out, const InParamPtr& cookie) + { + Test::CustomMap<std::string, Ice::Int> dummy; // just for type + const Test::CustomMap<std::string, Ice::Int>& in = getIn(dummy, cookie); + + test(out == in); + + test(ret.size() == 1000); + for(Test::CustomMap<Ice::Long, Ice::Long>::const_iterator i = ret.begin(); i != ret.end(); ++i) + { + test(i->second == i->first * i->first); + } + + called(); + } + + void throwExcept1(const Ice::AsyncResultPtr& result) { wstring in = getIn(in, InParamPtr::dynamicCast(result->getCookie())); @@ -2020,6 +2048,46 @@ allTests(const Ice::CommunicatorPtr& communicator, bool collocated) cout << "ok" << endl; + cout << "testing alternate dictionaries... " << flush; + + { + Test::IntStringDict idict; + + idict[1] = "one"; + idict[2] = "two"; + idict[3] = "three"; + idict[-1] = "minus one"; + + Test::IntStringDict out; + out[5] = "five"; + + Test::IntStringDict ret = t->opIntStringDict(idict, out); + test(out == idict); + test(ret == idict); + } + + { + Test::CustomMap<std::string, Ice::Int> idict; + + idict["one"] = 1; + idict["two"] = 2; + idict["three"] = 3; + idict["minus one"] = -1; + + Test::CustomMap<std::string, Ice::Int> out; + out["five"] = 5; + + Test::CustomMap<Ice::Long, Ice::Long> ret = t->opVarDict(idict, out); + test(out == idict); + test(ret.size() == 1000); + for(Test::CustomMap<Ice::Long, Ice::Long>::const_iterator i = ret.begin(); i != ret.end(); ++i) + { + test(i->second == i->first * i->first); + } + } + + cout << "ok" << endl; + if(!collocated) { cout << "testing alternate sequences with AMI... " << flush; @@ -4276,6 +4344,145 @@ allTests(const Ice::CommunicatorPtr& communicator, bool collocated) } cout << "ok" << endl; #endif + + cout << "testing alternate dictionaries with new AMI... " << flush; + { + { + Test::IntStringDict idict; + + idict[1] = "one"; + idict[2] = "two"; + idict[3] = "three"; + idict[-1] = "minus one"; + + Test::IntStringDict out; + out[5] = "five"; + + Ice::AsyncResultPtr r = t->begin_opIntStringDict(idict); + Test::IntStringDict ret = t->end_opIntStringDict(out, r); + test(out == idict); + test(ret == idict); + } + + { + Test::CustomMap<std::string, Ice::Int> idict; + + idict["one"] = 1; + idict["two"] = 2; + idict["three"] = 3; + idict["minus one"] = -1; + + Test::CustomMap<std::string, Ice::Int> out; + out["five"] = 5; + + Ice::AsyncResultPtr r = t->begin_opVarDict(idict); + Test::CustomMap<Ice::Long, Ice::Long> ret = t->end_opVarDict(out, r); + test(out == idict); + test(ret.size() == 1000); + for(Test::CustomMap<Ice::Long, Ice::Long>::const_iterator i = ret.begin(); i != ret.end(); ++i) + { + test(i->second == i->first * i->first); + } + } + } + cout << "ok" << endl; + + cout << "testing alternate dictionaries with new AMI callbacks... " << flush; + { + { + Test::IntStringDict idict; + + idict[1] = "one"; + idict[2] = "two"; + idict[3] = "three"; + idict[-1] = "minus one"; + + Test::IntStringDict out; + out[5] = "five"; + + CallbackPtr cb = new Callback(); + Test::Callback_TestIntf_opIntStringDictPtr callback = + Test::newCallback_TestIntf_opIntStringDict(cb, &Callback::opIntStringDict, &Callback::noEx); + t->begin_opIntStringDict(idict, callback, newInParam(idict)); + cb->check(); + } + + { + Test::CustomMap<std::string, Ice::Int> idict; + + idict["one"] = 1; + idict["two"] = 2; + idict["three"] = 3; + idict["minus one"] = -1; + + Test::CustomMap<std::string, Ice::Int> out; + out["five"] = 5; + + CallbackPtr cb = new Callback(); + Test::Callback_TestIntf_opVarDictPtr callback = + Test::newCallback_TestIntf_opVarDict(cb, &Callback::opVarDict, &Callback::noEx); + t->begin_opVarDict(idict, callback, newInParam(idict)); + cb->check(); + } + } + cout << "ok" << endl; + +#ifdef ICE_CPP11 + cout << "testing alternate dictionaries with new C++11 AMI callbacks... " << flush; + { + { + Test::IntStringDict idict; + + idict[1] = "one"; + idict[2] = "two"; + idict[3] = "three"; + idict[-1] = "minus one"; + + Test::IntStringDict out; + out[5] = "five"; + + CallbackPtr cb = new Callback(); + + t->begin_opIntStringDict(idict, + [=](const Test::IntStringDict& ret, const Test::IntStringDict& out) + { + cb->opIntStringDict(ret, out, newInParam(idict)); + }, + [=](const Ice::Exception& ex) + { + cb->noEx(ex, newInParam(idict)); + }); + cb->check(); + } + + { + Test::CustomMap<std::string, Ice::Int> idict; + + idict["one"] = 1; + idict["two"] = 2; + idict["three"] = 3; + idict["minus one"] = -1; + + Test::CustomMap<std::string, Ice::Int> out; + out["five"] = 5; + + CallbackPtr cb = new Callback(); + + t->begin_opVarDict(idict, + [=](const Test::CustomMap<Ice::Long, Ice::Long>& ret, + const Test::CustomMap<std::string, Ice::Int>& out) + { + cb->opVarDict(ret, out, newInParam(idict)); + }, + [=](const Ice::Exception& ex) + { + cb->noEx(ex, newInParam(idict)); + }); + cb->check(); + } + } + cout << "ok" << endl; +#endif } cout << "testing class mapped structs ... " << flush; diff --git a/cpp/test/Ice/custom/CustomMap.h b/cpp/test/Ice/custom/CustomMap.h new file mode 100644 index 00000000000..49eb3d2e785 --- /dev/null +++ b/cpp/test/Ice/custom/CustomMap.h @@ -0,0 +1,38 @@ +// **********************************************************************
+//
+// Copyright (c) 2003-2012 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#ifndef CUSTOM_MAP_H
+#define CUSTOM_MAP_H
+
+#include <IceUtil/Config.h>
+
+#ifdef ICE_CPP11
+# include <unordered_map>
+#else
+# include <map>
+#endif
+
+namespace Test
+{
+
+#ifdef ICE_CPP11
+template<typename K, typename V>
+class CustomMap : public std::unordered_map<K, V>
+{
+};
+#else
+template<typename K, typename V>
+class CustomMap : public std::map<K, V>
+{
+};
+#endif
+
+}
+
+#endif
diff --git a/cpp/test/Ice/custom/Makefile.mak b/cpp/test/Ice/custom/Makefile.mak index 5aa4f7d34e6..83051789c84 100644 --- a/cpp/test/Ice/custom/Makefile.mak +++ b/cpp/test/Ice/custom/Makefile.mak @@ -56,7 +56,7 @@ SRCS = $(COBJS:.obj=.cpp) \ !include $(top_srcdir)/config/Make.rules.mak
SLICE2CPPFLAGS = --stream $(SLICE2CPPFLAGS)
-CPPFLAGS = -I. -I../../include $(CPPFLAGS) -DWIN32_LEAN_AND_MEAN -Zm300
+CPPFLAGS = -I. -I../../include $(CPPFLAGS) -DWIN32_LEAN_AND_MEAN -Zm300 -bigobj
!if "$(GENERATE_PDB)" == "yes"
CPDBFLAGS = /pdb:$(CLIENT:.exe=.pdb)
diff --git a/cpp/test/Ice/custom/MyByteSeq.h b/cpp/test/Ice/custom/MyByteSeq.h index e9d21b4adb3..78a880783d9 100644 --- a/cpp/test/Ice/custom/MyByteSeq.h +++ b/cpp/test/Ice/custom/MyByteSeq.h @@ -19,6 +19,8 @@ public: typedef Ice::Byte* iterator; typedef Ice::Byte* const_iterator; + typedef Ice::Byte value_type; + MyByteSeq(); MyByteSeq(size_t); MyByteSeq(const MyByteSeq&); diff --git a/cpp/test/Ice/custom/Test.ice b/cpp/test/Ice/custom/Test.ice index 738e6c817d6..c3b40f188a5 100644 --- a/cpp/test/Ice/custom/Test.ice +++ b/cpp/test/Ice/custom/Test.ice @@ -9,7 +9,7 @@ #pragma once -[["cpp:include:deque", "cpp:include:list", "cpp:include:MyByteSeq.h"]] +[["cpp:include:deque", "cpp:include:list", "cpp:include:MyByteSeq.h", "cpp:include:CustomMap.h"]] module Test { @@ -110,6 +110,15 @@ sequence<ClassOtherStruct> ClassOtherStructSeq; }; sequence<ClassStruct> ClassStructSeq; +["cpp:type:Test::CustomMap<Ice::Int, std::string>"] dictionary<int, string> IntStringDict; +dictionary<long, long> LongLongDict; +dictionary<string, int> StringIntDict; + +class DictClass +{ + IntStringDict isdict; +}; + ["ami"] class TestIntf { ["cpp:array"] DoubleSeq opDoubleArray(["cpp:array"] DoubleSeq inSeq, out ["cpp:array"] DoubleSeq outSeq); @@ -202,6 +211,12 @@ sequence<ClassStruct> ClassStructSeq; void opOutRangeByteSeq(ByteSeq org, out ["cpp:range"] ByteSeq copy); + IntStringDict opIntStringDict(IntStringDict idict, out IntStringDict odict); + + ["cpp:type:::Test::CustomMap< ::Ice::Long, ::Ice::Long>"] LongLongDict + opVarDict(["cpp:type:::Test::CustomMap<std::string, ::Ice::Int>"] StringIntDict idict, + out ["cpp:type:::Test::CustomMap<std::string, ::Ice::Int>"] StringIntDict odict); + void shutdown(); }; diff --git a/cpp/test/Ice/custom/TestAMD.ice b/cpp/test/Ice/custom/TestAMD.ice index 295f81980b1..f4bb852d942 100644 --- a/cpp/test/Ice/custom/TestAMD.ice +++ b/cpp/test/Ice/custom/TestAMD.ice @@ -9,7 +9,7 @@ #pragma once -[["cpp:include:deque", "cpp:include:list", "cpp:include:MyByteSeq.h"]] +[["cpp:include:deque", "cpp:include:list", "cpp:include:MyByteSeq.h", "cpp:include:CustomMap.h"]] module Test { @@ -108,6 +108,15 @@ sequence<ClassOtherStruct> ClassOtherStructSeq; }; sequence<ClassStruct> ClassStructSeq; +["cpp:type:Test::CustomMap<Ice::Int, std::string>"] dictionary<int, string> IntStringDict; +dictionary<long, long> LongLongDict; +dictionary<string, int> StringIntDict; + +class DictClass +{ + IntStringDict isdict; +}; + ["amd", "ami"] class TestIntf { DoubleSeq opDoubleArray(["cpp:array"] DoubleSeq inSeq, out DoubleSeq outSeq); @@ -191,6 +200,12 @@ sequence<ClassStruct> ClassStructSeq; void opOutRangeByteSeq(ByteSeq org, out ["cpp:range"] ByteSeq copy); + IntStringDict opIntStringDict(IntStringDict idict, out IntStringDict odict); + + ["cpp:type:::Test::CustomMap< ::Ice::Long, ::Ice::Long>"] LongLongDict + opVarDict(["cpp:type:::Test::CustomMap<std::string, ::Ice::Int>"] StringIntDict idict, + out ["cpp:type:::Test::CustomMap<std::string, ::Ice::Int>"] StringIntDict odict); + void shutdown(); }; diff --git a/cpp/test/Ice/custom/TestAMDI.cpp b/cpp/test/Ice/custom/TestAMDI.cpp index 79c1ac30e31..d8624cf48ea 100644 --- a/cpp/test/Ice/custom/TestAMDI.cpp +++ b/cpp/test/Ice/custom/TestAMDI.cpp @@ -308,6 +308,28 @@ TestIntfI::opOutRangeByteSeq_async(const ::Test::AMD_TestIntf_opOutRangeByteSeqP ::Test::ByteSeq::const_iterator>(inS.begin(), inS.end())); } +void +TestIntfI::opIntStringDict_async(const ::Test::AMD_TestIntf_opIntStringDictPtr& cb, + const ::Test::IntStringDict& inDict, + const ::Ice::Current&) +{ + cb->ice_response(inDict, inDict); +} + +void +TestIntfI::opVarDict_async(const ::Test::AMD_TestIntf_opVarDictPtr& cb, + const ::Test::CustomMap<std::string, Ice::Int>& inDict, + const ::Ice::Current&) +{ + Test::CustomMap<Ice::Long, Ice::Long> result; + for(Ice::Long i = 0; i < 1000; ++i) + { + result[i] = i*i; + } + cb->ice_response(result, inDict); +} + + void TestIntfI::shutdown_async(const Test::AMD_TestIntf_shutdownPtr& shutdownCB, const Ice::Current& current) diff --git a/cpp/test/Ice/custom/TestAMDI.h b/cpp/test/Ice/custom/TestAMDI.h index f44c4569f93..759434157b2 100644 --- a/cpp/test/Ice/custom/TestAMDI.h +++ b/cpp/test/Ice/custom/TestAMDI.h @@ -151,6 +151,16 @@ public: const ::Test::ByteSeq&, const ::Ice::Current&); + virtual void opIntStringDict_async(const ::Test::AMD_TestIntf_opIntStringDictPtr&, + const ::Test::IntStringDict&, + const ::Ice::Current&); + + virtual void opVarDict_async(const ::Test::AMD_TestIntf_opVarDictPtr&, + const ::Test::CustomMap<std::string, Ice::Int>&, + const ::Ice::Current&); + + + virtual void shutdown_async(const Test::AMD_TestIntf_shutdownPtr&, const Ice::Current&); diff --git a/cpp/test/Ice/custom/TestI.cpp b/cpp/test/Ice/custom/TestI.cpp index 7fe8a0f1b9e..2e148c6f2cd 100644 --- a/cpp/test/Ice/custom/TestI.cpp +++ b/cpp/test/Ice/custom/TestI.cpp @@ -337,6 +337,27 @@ TestIntfI::opOutRangeByteSeq(const Test::ByteSeq& data, Test::ByteSeq& copy, con copy = data; } +Test::IntStringDict +TestIntfI::opIntStringDict(const Test::IntStringDict& data, Test::IntStringDict& copy, const Ice::Current&) +{ + copy = data; + return data; +} + +Test::CustomMap<Ice::Long, Ice::Long> +TestIntfI::opVarDict(const Test::CustomMap<std::string, Ice::Int>& data, + Test::CustomMap<std::string, Ice::Int>& copy, const Ice::Current&) +{ + copy = data; + + Test::CustomMap<Ice::Long, Ice::Long> result; + for(Ice::Long i = 0; i < 1000; ++i) + { + result[i] = i*i; + } + return result; +} + void TestIntfI::shutdown(const Ice::Current& current) { diff --git a/cpp/test/Ice/custom/TestI.h b/cpp/test/Ice/custom/TestI.h index 474ad7c51b5..4afbd43d613 100644 --- a/cpp/test/Ice/custom/TestI.h +++ b/cpp/test/Ice/custom/TestI.h @@ -163,6 +163,15 @@ public: virtual void opOutRangeByteSeq(const Test::ByteSeq&, Test::ByteSeq&, const Ice::Current&); + + virtual Test::IntStringDict opIntStringDict(const Test::IntStringDict&, Test::IntStringDict&, + const Ice::Current&); + + virtual Test::CustomMap<Ice::Long, Ice::Long> opVarDict(const Test::CustomMap<std::string, Ice::Int>&, + Test::CustomMap<std::string, Ice::Int>&, + const Ice::Current&); + + virtual void shutdown(const Ice::Current&); private: diff --git a/cpp/test/Ice/optional/AllTests.cpp b/cpp/test/Ice/optional/AllTests.cpp index 994bab81bc9..fb075f19ec1 100644 --- a/cpp/test/Ice/optional/AllTests.cpp +++ b/cpp/test/Ice/optional/AllTests.cpp @@ -849,7 +849,12 @@ allTests(const Ice::CommunicatorPtr& communicator, bool collocated) vector<Ice::Byte> bs(100); fill(bs.begin(), bs.end(), 56); +#if defined(__SUNPRO_CC) && defined(_RWSTD_NO_MEMBER_TEMPLATES) + std::pair<const Ice::Byte*, const Ice::Byte*> cpair(&bs[0], &bs[0] + bs.size()); + p1 = cpair; +#else p1 = make_pair(&bs[0], &bs[0] + bs.size()); +#endif p2 = initial->opByteSeq(p1, p3); test(p2 && p3); test(p2 == bs && p3 == bs); @@ -880,7 +885,12 @@ allTests(const Ice::CommunicatorPtr& communicator, bool collocated) vector<Ice::Short> bs(100); fill(bs.begin(), bs.end(), 56); +#if defined(__SUNPRO_CC) && defined(_RWSTD_NO_MEMBER_TEMPLATES) + std::pair<const Ice::Short*, const Ice::Short*> cpair(&bs[0], &bs[0] + bs.size()); + p1 = cpair; +#else p1 = make_pair(&bs[0], &bs[0] + bs.size()); +#endif p2 = initial->opShortSeq(p1, p3); test(p2 && p3); test(p2 == bs && p3 == bs); @@ -911,7 +921,12 @@ allTests(const Ice::CommunicatorPtr& communicator, bool collocated) bool bs[100]; vector<bool> bsv(&bs[0], &bs[0] + 100); +#if defined(__SUNPRO_CC) && defined(_RWSTD_NO_MEMBER_TEMPLATES) + std::pair<const bool*, const bool*> cpair(&bs[0], &bs[0] + 100); + p1 = cpair; +#else p1 = make_pair(&bs[0], &bs[0] + 100); +#endif p2 = initial->opBoolSeq(p1, p3); test(p2 && p3); test(p2 == bsv && p3 == bsv); @@ -942,7 +957,12 @@ allTests(const Ice::CommunicatorPtr& communicator, bool collocated) StringSeq ss(10); fill(ss.begin(), ss.end(), "test1"); +#if defined(__SUNPRO_CC) && defined(_RWSTD_NO_MEMBER_TEMPLATES) + std::pair<StringSeq::const_iterator, StringSeq::const_iterator> cpair(ss.begin(), ss.end()); + p1 = cpair; +#else p1 = make_pair(ss.begin(), ss.end()); +#endif p2 = initial->opStringSeq(p1, p3); test(p2 && p3); test(p2 == ss && p3 == ss); @@ -973,7 +993,12 @@ allTests(const Ice::CommunicatorPtr& communicator, bool collocated) FixedStruct fss[10]; vector<FixedStruct> fssv(&fss[0], &fss[0] + 10); +#if defined(__SUNPRO_CC) && defined(_RWSTD_NO_MEMBER_TEMPLATES) + std::pair<const FixedStruct*, const FixedStruct*> cpair(&fss[0], &fss[0] + 10); + p1 = cpair; +#else p1 = make_pair(&fss[0], &fss[0] + 10); +#endif p2 = initial->opFixedStructSeq(p1, p3); test(p2 && p3); test(p2 == fssv && p3 == fssv); @@ -1003,7 +1028,12 @@ allTests(const Ice::CommunicatorPtr& communicator, bool collocated) test(!p2 && !p3); VarStructSeq ss(10); +#if defined(__SUNPRO_CC) && defined(_RWSTD_NO_MEMBER_TEMPLATES) + std::pair<VarStructSeq::const_iterator, VarStructSeq::const_iterator> cpair(ss.begin(), ss.end()); + p1 = cpair; +#else p1 = make_pair(ss.begin(), ss.end()); +#endif p2 = initial->opVarStructSeq(p1, p3); test(p2 && p3); test(p2 == ss && p3 == ss); |