Quick start¶
The following code demonstrates a simple use case of storing values of double
and std::string types in a single container using multi_type_vector.
#include <mdds/multi_type_vector.hpp>
#include <iostream>
#include <vector>
#include <string>
using std::cout;
using std::endl;
using mtv_type = mdds::multi_type_vector<mdds::mtv::standard_element_blocks_traits>;
template<typename BlockT>
void print_block(const mtv_type::value_type& v)
{
for (const auto& elem : BlockT::range(*v.data))
{
cout << " * " << elem << endl;
}
}
int main() try
{
mtv_type con(20); // Initialized with 20 empty elements.
// Set values individually.
con.set(0, 1.1);
con.set(1, 1.2);
con.set(2, 1.3);
// Set a sequence of values in one step.
std::vector<double> vals = { 10.1, 10.2, 10.3, 10.4, 10.5 };
con.set(3, vals.begin(), vals.end());
// Set string values.
con.set<std::string>(10, "Andy");
con.set<std::string>(11, "Bruce");
con.set<std::string>(12, "Charlie");
// Iterate through all blocks and print all elements.
for (const auto& v : con)
{
switch (v.type)
{
case mdds::mtv::element_type_double:
{
cout << "numeric block of size " << v.size << endl;
print_block<mdds::mtv::double_element_block>(v);
break;
}
case mdds::mtv::element_type_string:
{
cout << "string block of size " << v.size << endl;
print_block<mdds::mtv::string_element_block>(v);
break;
}
case mdds::mtv::element_type_empty:
cout << "empty block of size " << v.size << endl;
cout << " - no data - " << endl;
default:
;
}
}
return EXIT_SUCCESS;
}
catch (...)
{
return EXIT_FAILURE;
}
You’ll see the following console output when you compile and execute this code:
numeric block of size 8
* 1.1
* 1.2
* 1.3
* 10.1
* 10.2
* 10.3
* 10.4
* 10.5
empty block of size 2
- no data -
string block of size 3
* Andy
* Bruce
* Charlie
empty block of size 7
- no data -
Logical structure between the primary array, blocks, and element blocks.¶
Each multi_type_vector instance maintains a logical storage structure of one
primary array containing one or more blocks each of which consists of type,
position, size and data members:
type- numeric value representing the block type.position- numeridc value representing the logical position of the first element of the block.size- number of elements present in the block a.k.a its logical size.data- pointer to the secondary storage (element block) storing the element values.
In this example code, the type member is referenced to determine its block
type and its logical size is determined from the size member. For the
numeric and string blocks, their data members, which should point to the
memory addresses of their respective element blocks, are dereferenced in order
to print out their element values to stdout inside the print_block function.
Standard element block types¶
It is worth noting that the two block types used in the previous example, namely
double_element_block and string_element_block
didn’t come out of nowhere. By default, including the header that defines multi_type_vector
implicitly also defines the following block types:
which respectively store elements of the following value types:
boolint8_tuint8_tint16_tuint16_tint32_tuint32_tint64_tuint64_tfloatdoublestd::string
The header also defines the mdds::mtv::standard_element_blocks_traits
struct which you can pass to the multi_type_vector template
definition in order to have all of the above mentioned block types and their
respective value types available for use.