13.1.25.2 Insertion into Any
To allow a value to be set in an any
in a type-safe
fashion, the following overloaded operator function is provided for
each separate OMG IDL type T:
// C++
void operator<<=(Any&, T);
This function signature suffices for the following types, which are usually passed by value:
-
Short
,UShort
,Long
,ULong
,Float
,Double
- Enumerations
- Unbounded strings (
char*
passed by value) - Object references (
T_ptr
)
For values of type T that are too large to be passed by value efficiently, two forms of the insertion function are provided:
// C++
void operator<<=(Any&, const T&); // copying form
void operator<<=(Any&, T*); // non-copying form
The copying form is largely equivalent to the first form shown, as far as the caller is concerned.
These “left-shift-assign” operators are used to
insert a typed value into an any
, as follows:
// C++
Long value = 42;
Any a;
a <<= value;
In this case, the version of operator<<=
overloaded for type Long
sets both the value and the
TypeCode properly for the Any variable.
Setting a value in an any
using
operator<<=
means the following:
- For the copying version of
operator<<=
, the lifetime of the value in the Any is independent of the lifetime of the value passed tooperator<<=
. The implementation of the Any does not store its value as a reference or a pointer to the value passed tooperator<<=
. - For the noncopying version of
operator<<=
, the insertedT*
is consumed by the Any. The caller may not use theT*
to access the pointed-to data after insertion because the Any assumes ownership ofT*
, and the Any may immediately copy the pointed-to data and destroy the original. - With both the copying and noncopying versions of
operator<<=
, any previous value held by theAny
is properly deallocated. For example, if theAny(TypeCode_ptr,void*,TRUE)
constructor (described in Handling Untyped Values) were called to create the Any, theAny
is responsible for deallocating the memory pointed to by thevoid*
before copying the new value.
Copying insertion of a string type causes the following function to be invoked:
// C++
void operator<<=(Any&, const char*);
Since all string types are mapped to char*
, this insertion function assumes that the value being inserted is an unbounded string. Distinguishing Boolean, Octet, Char, and Bounded Strings describes how bounded strings may be correctly inserted into an Any
. Noncopying insertion of both bounded and unbounded strings can be achieved using the Any::from_string
helper type described in Distinguishing Boolean, Octet, Char, and Bounded Strings.
Type-safe insertion of arrays uses the Array_forany
types described in Arrays. The ORB
provides a version of operator<<=
overloaded for
each Array_forany
type. For example:
// IDL
typedef long LongArray[4][5];
// C++
typedef Long LongArray[4][5];
typedef Long LongArray_slice[5];
class LongArray_forany { ... };
void operator<<=(Any &, const LongArray_forany &);
The Array_forany
types are always passed to
operator<<=
by reference to
const
.The nocopy
flag in the
Array_forany
constructor is used to control whether
the inserted value is copied (nocopy == FALSE
) or
consumed (nocopy == TRUE
). Because the
nocopy
flag defaults to FALSE
, copying
insertion is the default.
Because of the type ambiguity between an array of T
and a T*
, it is highly recommended that portable code
explicitly use the appropriate Array_forany
type when
inserting an array into an Any. For example:
// IDL
struct S {... };
typedef S SA[5];
// C++
struct S { ... };
typedef S SA[5];
typedef S SA_slice;
class SA_forany { ... };
SA s;
// ...initialize s...
Any a;
a <<= s; // line 1
a <<= SA_forany(s); // line 2
Line 1 results in the invocation of the noncopying
operator<<=(Any&, S*)
due to the decay of
the SA
array type into a pointer to its first element,
rather than the invocation of the copying SA_forany
insertion operator. Line 2 explicitly constructs the
SA_forany
type and thus results in the desired
insertion operator being invoked.
The noncopying version of operator<<=
for
object references takes the address of the T_ptr
type,
as follows:
// IDL
interface T { ... };
// C++
void operator<<=(Any&, T_ptr); // copying
void operator<<=(Any&, T_ptr*); // non-copying
The noncopying object reference insertion consumes the object
reference pointed to by T_ptr*
; therefore, after
insertion the caller may not access the object referred to by
T_ptr
because the Any may have duplicated and then
immediately released the original object reference. The caller
maintains ownership of the storage for the T_ptr
itself.
The copying version of operator<<=
is also supported on the Any_var
type.
Parent topic: Any Type