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
Public member In
Constructs the marshaller and binds the input object

Marshal methods (varies between specializations)

Name Description
Public member Get
Marshals the bound element to a new object, performing a move if possible.
Public member GetWithoutMove
Marshals the bound element to a new object, leaving the original object unchanged.

Capacity methods (varies between specializations)

Name Description
Public member size
Returns the number of elements in the bound collection.
Public member capacity
Returns the currently allocated memory capacity of the bound collection.
Public member empty
Returns true if the bound collection is currently empty.

Element access methods (varies between specializations)

Name Description
Public member GetElement
Marshals a single element from the bound collection.

Conversion operators (varies between specializations)

Name Description
Public member 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.

See also