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 | |
|---|---|---|
| InOut |
Constructs the marshaller and binds the target object
|
Marshal methods
| Name | Description | |
|---|---|---|
| Get |
Marshals the bound element to a new object.
|
|
| Set |
Marshals the supplied value to the bound element, performing a move if possible.
|
Capacity methods (varies between specializations)
| Name | Description | |
|---|---|---|
| size |
Returns the number of elements in the bound collection.
|
|
| resize |
Resizes the bound collection to contain the specified number of elements.
|
|
| capacity |
Returns the currently allocated memory capacity of the bound collection.
|
|
| empty |
Returns true if the bound collection is currently empty.
|
|
| reserve |
Reserves memory capacity for the specified number of elements in the bound collection.
|
Element access methods (varies between specializations)
| Name | Description | |
|---|---|---|
| GetElement |
Marshals a single element from the bound collection.
|
|
| SetElement |
Marshals a single element to the bound collection.
|
Modifier methods (varies between specializations)
| Name | Description | |
|---|---|---|
| push_back |
Appends the specified value to the end of the bound collection.
|
|
| pop_back |
Removes the last entry from the bound collection.
|
|
| clear |
Removes all entries from the bound collection.
|
|
| assign |
Replaces the current contents of the bound collection with the indicated number of copies of the specified value.
|
|
| AssignFrom |
Replaces the current contents of the bound collection with the specified data.
|
|
| AssignFromWithMove |
Replaces the current contents of the bound collection with the specified data, performing a move operation if possible.
|
Conversion operators
| Name | Description | |
|---|---|---|
| operator ContainerType() |
Performs an implicit conversion from the marshaller to the native type.
|
Custom operators
| Name | Description | |
|---|---|---|
| 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.