Declaration
template<class ContainerType,
bool IsOnlyMovable = cobalt::marshalling::internal::is_only_movable<typename cobalt::marshalling::internal::get_last_nested_container_element_type<ContainerType>::type>::value,
bool IsAssignable = cobalt::marshalling::internal::is_assignable<ContainerType>::value,
bool IsLastElement = cobalt::marshalling::internal::is_last_nested_container_element<ContainerType>::value,
bool IsThisOrNextElementLastElement = cobalt::marshalling::internal::is_this_or_nested_element_last_nested_container_element<ContainerType>::value>
class In;Description
The Marshal::In class is a helper class designed to allow largely transparent and automatic marshalling of types as input arguments for functions. Through appropriate use, implicit conversions in the Marshal::In type allow identical code to be written by the caller whether marshalling is employed or not. An object supplied as an input argument can be marshalled into the target function, allowing the supplied value to be retrieved, but not modified. Marshalling a parameter with Marshal::In provides similar functionality to passing an argument by const reference or by value.
Note that the Marshal::In template type makes use of template specialization to change its implementation based on the specific type supplied in its first template argument, and the characteristics of that type. As such, its list of members varies based on the type supplied.
Members
Constructors (varies between specializations)
| Name | Description | |
|---|---|---|
| In |
Constructs the marshaller and binds the input object
|
Marshal methods (varies between specializations)
| Name | Description | |
|---|---|---|
| Get |
Marshals the bound element to a new object, performing a move if possible.
|
|
| GetWithoutMove |
Marshals the bound element to a new object, leaving the original object unchanged.
|
Capacity methods (varies between specializations)
| Name | Description | |
|---|---|---|
| size |
Returns the number of elements in the bound collection.
|
|
| capacity |
Returns the currently allocated memory capacity of the bound collection.
|
|
| empty |
Returns true if the bound collection is currently empty.
|
Element access methods (varies between specializations)
| Name | Description | |
|---|---|---|
| GetElement |
Marshals a single element from the bound collection.
|
Conversion operators (varies between specializations)
| Name | Description | |
|---|---|---|
| operator ContainerType() |
Performs an implicit conversion from the marshaller to the native type. A copy is always used in this case, never a move.
|
Examples
Recommended usage
Given the following code without any marshalling involved:
void SomeFunction(const std::list<int>& argByRef)
{
std::cout << argByRef.back() << std::endl;
}
int main()
{
std::list<int> arg;
arg.push_back(1);
SomeFunction(arg);
return 0;
}
The recommended conversion to use marshalling would take this form:
void SomeFunction(const Marshal::In<std::list<int>>& argByRef)
{
std::list<int> localArg = argByRef.Get();
std::cout << localArg.back() << std::endl;
}
int main()
{
std::list<int> arg;
arg.push_back(1);
SomeFunction(arg);
return 0;
}
Note that the syntax remains unchanged for the caller, making it relatively easy to add marshalling to existing APIs. The function argument is adapted to use marshalling simply by wrapping it in a Marshal::In helper. Note that the marshal helpers are always passed in by const reference, even if the original signature passed in the parameter by value. This is essential in order to allow implicit conversions to the marshal helper by the caller. In the function implementation, this example follows the recommended approach of calling the Get method on the marshal helper to explicitly marshal the object. Although implicit conversions exist from the helper to the marshalled type, so it could be used directly in many cases as though it was the native object, each time an implicit conversion is invoked the object is marshalled again, and move semantics can't be used to efficiently marshal temporary objects or arguments explicitly passed in with std::move, so relying on an implicit conversion can be less efficient.
String conversion example
Given the following code without any marshalling involved:
void SomeFunction(const std::string& argByRef)
{
std::cout << argByRef << std::endl;
}
int main()
{
std::string test1 = "Test1";
SomeFunction(test1);
SomeFunction("Test2");
return 0;
}
The code can be converted to marshal the string argument by changing the function signature alone, as follows:
void SomeFunction(const Marshal::In<std::string>& argByRef)
{
std::cout << argByRef << std::endl;
}
int main()
{
std::string test1 = "Test1";
SomeFunction(test1);
SomeFunction("Test2");
return 0;
}
In this case, special constructor overloads for the std::basic_string type custom allow a string literal to be used directly by the caller, regardless of whether the type is being marshalled or not. Custom marshal string operators allow the function implementation to use the marshalled string directly in stream operations without needing to explicitly unpack it, if desired.