Declaration

template<class ContainerType,
         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 InOut;

Description

The Marshal::InOut class is a helper class designed to allow largely transparent and automatic marshalling of types as bi-directional read/write arguments for functions. Through appropriate use, implicit conversions in the Marshal::InOut type allow identical code to be written by the caller whether marshalling is employed or not. An object supplied as an input/output argument can be marshalled into the target function, allowing the supplied value to be retrieved, while also allowing an updated value to be marshalled back out to the caller. Marshalling a parameter with Marshal::InOut provides similar functionality to passing an argument by non-const reference.

Note that the Marshal::InOut 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.

Note that as the Marshal::InOut type is effectively a compound of Marshal::In and Marshal::Out, method documentation for this type will usually redirect to the documentation for these other types, as the usage is the same.

Members

Constructors

Name Description
Public member InOut
Constructs the marshaller and binds the target object

Marshal methods

Name Description
Public member Get
Marshals the bound element to a new object.
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 size
Returns the number of elements in the bound collection.
Public member resize
Resizes the bound collection to contain the specified number of elements.
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.
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 GetElement
Marshals a single element from the bound collection.
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.

Conversion operators

Name Description
Public member operator ContainerType()
Performs an implicit conversion from the marshaller to the native type.

Custom operators

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:

int SomeFunction(std::vector<int>& argByNonConstRef)
{
    int originalLastEntry = (argByNonConstRef.empty() ? 0 : argByNonConstRef.back());
    argByNonConstRef.clear();
    argByNonConstRef.push_back(1);
    return originalLastEntry;
}

int main()
{
    std::vector<int> test1;
    test1.push_back(1);
    test1.push_back(2);
    int originalLastEntry = SomeFunction(test1);
    std::cout << originalLastEntry << "\t" << test1.back() << std::endl;
    return 0;
}

The recommended conversion to use marshalling would take this form:

int SomeFunction(const Marshal::InOut<std::vector<int>>& argByNonConstRef)
{
    std::vector<int> localArg = argByNonConstRef.Get();
    int originalLastEntry = (localArg.empty() ? 0 : localArg.back());
    localArg.clear();
    localArg.push_back(1);
    argByNonConstRef.Set(std::move(localArg));
    return originalLastEntry;
}

int main()
{
    std::vector<int> test1;
    test1.push_back(1);
    test1.push_back(2);
    int originalLastEntry = SomeFunction(test1);
    std::cout << originalLastEntry << "\t" << test1.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::InOut 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::InOut 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. Please refer to the list of members above for more information on these specialized methods.

See also