summaryrefslogtreecommitdiff
path: root/cpp
diff options
context:
space:
mode:
Diffstat (limited to 'cpp')
-rw-r--r--cpp/include/Ice/BasicStream.h4
-rw-r--r--cpp/include/Ice/StreamTraits.h316
-rw-r--r--cpp/src/Ice/StreamI.cpp7
-rw-r--r--cpp/src/Slice/CPlusPlusUtil.cpp35
-rw-r--r--cpp/src/slice2cpp/Gen.cpp57
-rwxr-xr-xcpp/test/Ice/custom/AllTests.cpp215
-rw-r--r--cpp/test/Ice/custom/CustomMap.h38
-rw-r--r--cpp/test/Ice/custom/Makefile.mak2
-rw-r--r--cpp/test/Ice/custom/MyByteSeq.h2
-rw-r--r--cpp/test/Ice/custom/Test.ice17
-rw-r--r--cpp/test/Ice/custom/TestAMD.ice17
-rw-r--r--cpp/test/Ice/custom/TestAMDI.cpp22
-rw-r--r--cpp/test/Ice/custom/TestAMDI.h10
-rw-r--r--cpp/test/Ice/custom/TestI.cpp21
-rw-r--r--cpp/test/Ice/custom/TestI.h9
-rw-r--r--cpp/test/Ice/optional/AllTests.cpp30
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);