CETL 0.0.0
 
Loading...
Searching...
No Matches
Example 8: Comparing std::vector to CETL's VariableLengthArray

Full example for cetl::VariableLengthArray

//CSpell: words sayin
#include <iostream>
#include <vector>
#include <gtest/gtest.h>
template <typename T>
void add_hello_world(T& container)
{
container.reserve(12);
container.push_back('H');
container.push_back('e');
container.push_back('l');
container.push_back('l');
container.push_back('o');
container.push_back(' ');
container.push_back('W');
container.push_back('o');
container.push_back('r');
container.push_back('l');
container.push_back('d');
}
template <typename T>
void print_container(const T& container)
{
for (auto c : container)
{
std::cout << c;
}
}
#ifdefined(__cpp_exceptions)
TEST(example_08_variable_length_array_vs_vector, example_tight_fit_0)
{
array_storage_1.max_size()};
try
{
for (std::size_t i = 0; i < 56; ++i)
{
std::cout << i << ", ";
space_waster.push_back(static_cast<char>(i + 46));
}
} catch (const std::bad_alloc&)
{
std::cout << "<- vector claimed to have run out of memory but we know better." << std::endl;
}
}
TEST(example_08_variable_length_array_vs_vector, example_tight_fit_1)
{
// The problem with the C++17 standard is the lack of support for max_size in pmr types.
// VariableLengthArray provides the "max_size_max" argument that lets the user limit the amount of memory
// the container will use.
array_storage_1.max_size()};
array_storage_0.size(),
{&array_storage_0},
};
for (std::size_t i = 0; i < 56; ++i)
{
std::cout << i << ", ";
tight_fit.push_back(static_cast<char>(i + 46));
}
std::cout << "<- The VLA was able to fit tightly inside of the maximum size it was given." << std::endl;
}
TEST(example_08_variable_length_array_vs_vector, example_exact_fit)
{
array_storage_0.size(),
{&array_storage_0},
};
exact_fit.reserve(56);
for (std::size_t i = 0; i < 56; ++i)
{
std::cout << i << ", ";
exact_fit.push_back(static_cast<char>(i + 46));
}
std::cout << "<- The VLA only used the 56 chars we gave it and no more." << std::endl;
}
TEST(example_08_variable_length_array_vs_vector, example_no_exceptions)
{
// compile with -fno-exceptions to enable this example.
}
#else
TEST(example_08_variable_length_array_vs_vector, example_no_exceptions)
{
// Using the cetlpf.hpp header we can create a polymorphic allocator that is aliased to
// std::pmr::polymorphic_allocator when compiling with C++17 or newer and cetl::pf17::pmr::polymorphic_allocator
// when compiling with C++14.
cetl::pf17::pmr::polymorphic_allocator<char> alloc{cetl::pf17::pmr::new_delete_resource()};
// This allows us to demonstrate that the cetl::variable_length_array behaves like a std::vector...
add_hello_world(a);
add_hello_world(b);
print_container(a);
print_container(b);
// So why not just use vector?
// The primary reason is std::vector has some edge cases where it cannot be used when exceptions are disabled.
// Here we are giving a vector and a VariableLengthArray the same allocator CETL pf17 allocator. This allocator
// returns nullptr when out of memory and exceptions are disabled.
// In this case, the VariableLengthArray will fail gracefully when it failed to allocate.
bad_b.push_back('H');
// But this would cause undefined behavior in the vector. Some implementations might cause an abort() whereas
// others may cause a segfault (or worse).
// of course, we commented out the following line but feel free to uncomment and try yourself.
// bad_a.push_back('H');
// You can detect that VariableLengthArray was not able to allocate memory for push_back using the following
// technique:
const std::size_t size_before = bad_b.size();
bad_b.push_back('H');
if (bad_b.size() == size_before)
{
if (size_before == bad_b.max_size())
{
std::cout << "bad_b was not able to allocate memory because it reached its max_size. You probably should "
"have checked this first? Just sayin'."
}
else
{
std::cout << "bad_b allocator is out of memory." << std::endl;
}
}
}
#endif // __cpp_exceptions
Defines a memory_resource type backed by an array data member and using cetl::pf17 types.
Minimal, generic container for storing Cyphal variable-length arrays.
Definition variable_length_array.hpp:893
void reserve(const size_type desired_capacity)
Ensure enough memory is allocated to store at least the desired_capacity number of elements.
Definition variable_length_array.hpp:1359
constexpr void push_back(const value_type &value)
Allocate a new element on to the back of the array and copy value into it.
Definition variable_length_array.hpp:1414
Implementation of cetl::pf17::pmr::memory_resource that uses cetl::pmr::UnsynchronizedBufferMemoryRes...
Definition array_memory_resource.hpp:45
Adheres to the std::pmr::polymorphic_allocator specification.
Definition memory_resource.hpp:356
T endl(T... args)
memory_resource * null_memory_resource() noexcept
Adheres to the null_memory_resource specification.
Definition memory_resource.hpp:303
Extends the cetl::pf17::pmr namespace with system memory resources.
Includes cetl::VariableLengthArray type and non-member functions.