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 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 Out;

Description

The Marshal::Out class is a helper class designed to allow largely transparent and automatic marshalling of types as output arguments for functions. Through appropriate use, implicit conversions in the Marshal::Out type allow identical code to be written by the caller whether marshalling is employed or not. An object supplied as an output argument can be marshalled out of the target function, allowing the caller to receive an updated value. Marshalling a parameter with Marshal::Out provides similar functionality to passing an argument by non-const reference, with the exception that the target function can only modify the value, it can't retrieve its current value.

Note that the Marshal::Out 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
Public member Out
Constructs the marshaller and binds the output object

Marshal methods (varies between specializations)

Name Description
Public member Set
Marshals the supplied value to the bound element, performing a move if possible.

Capacity methods (varies between specializations)

Name Description
Public member resize
Resizes the bound collection to contain the specified number of elements.
Public member reserve
Reserves memory capacity for the specified number of elements in the bound collection.

Element access methods (varies between specializations)

Name Description
Public member SetElement
Marshals a single element to the bound collection.

Modifier methods (varies between specializations)

Name Description
Public member push_back
Appends the specified value to the end of the bound collection.
Public member pop_back
Removes the last entry from the bound collection.
Public member clear
Removes all entries from the bound collection.
Public member assign
Replaces the current contents of the bound collection with the indicated number of copies of the specified value.
Public member AssignFrom
Replaces the current contents of the bound collection with the specified data.
Public member AssignFromWithMove
Replaces the current contents of the bound collection with the specified data, performing a move operation if possible.

Custom operators (varies between specializations)

Name Description
Public member operator=
Performs the same operation as calling the Set method.

Examples

Recommended usage

Given the following code without any marshalling involved:

void SomeFunction(std::vector<int>& argByNonConstRef)
{
    argByNonConstRef.clear();
    argByNonConstRef.push_back(1);
}

int main()
{
    std::vector<int> arg;
    SomeFunction(arg);
    std::cout << arg.back() << std::endl;
    return 0;
}

The recommended conversion to use marshalling would take this form:

void SomeFunction(const Marshal::Out<std::vector<int>>& argByNonConstRef)
{
    std::vector<int> localArg;
    localArg.push_back(1);
    argByNonConstRef.Set(std::move(localArg));
}

int main()
{
    std::vector<int> arg;
    SomeFunction(arg);
    std::cout << arg.back() << std::endl;
    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::Out helper. Note that the marshal helpers are always passed in by const reference, even though the original signature passed in the parameter by non-const reference. This is essential in order to allow implicit conversions to the marshal helper by the caller. In the function implementation, this example follows the simplest approach of constructing a local variable of the same type, populating it with the required data, and calling the Set method on the marshal helper to explicitly marshal the object. The assignment operator could also be used. The use of std::move here can give a performance boost with some types.

Be aware that this example shows the basic form of how any object type can be marshalled using the Marshal::Out helper. The std::vector and std::array types have additional functions available that can be used to selectively marshal only certain elements, or perform more efficient marshalling of the entire collection in some cases. The function implementation could have been left unchanged from the original code sample in this case. Please refer to the list of members above for more information on these specialized methods.

String conversion example

Given the following code without any marshalling involved:

void SomeFunction(std::string& argByNonConstRef)
{
    argByNonConstRef = "Test1";
}

int main()
{
    std::string test1;
    SomeFunction(test1);
    std::cout << test1 << std::endl;
    return 0;
}

The code can be converted to marshal the string argument by changing the function signature alone, as follows:

void SomeFunction(const Marshal::Out<std::string>& argByNonConstRef)
{
    argByNonConstRef = "Test1";
}

int main()
{
    std::string test1;
    SomeFunction(test1);
    std::cout << test1 << std::endl;
    return 0;
}

In this case, implicit conversions handle the conversion from string literals to our marshal helper.

See also