std::vector
#include <iostream>
int main()
{
std::cout << "Hi, I'm Borislav!\n";
std::cout << "These slides are here: https://is.gd/beyondvec\n";
return 0;
}
A blog post of what we do: ibob.bg/blog
Popular in multi-platform software and game development
std::string_view arrived in C++17std::span arrived in C++20.map/set of string pre-C++14 is uselessunordered_map/set of string pre-C++20 is uselessiostream: a notoriously bad offenderflat_map/set in contiguous memorystd::hash (this is a documented extension point)map, set, list allocate every nodeunoredered_map/set also allocate every nodefunctionsizeof std::<pretty-much-anything>std::string sizestd::filesystem::path::c_str() returns whateversize_tstd::move_if_noexcept The Great Dividerstd::function must be copyablestd::map::map is not noexcept
...usually
std::vectorstd::vectorstd::vectorstd::reference_wrapperconst std::vectormy::vectorA 100% compatible drop-in replacement reimplementation
shrink_to_fit is not required to shrinkemplace returns a ref since C++17noexcept move since C++17std::move_if_noexceptstd::move_if_noexcept DramaSpeaking of immutable objects
Think std::string_view
You don't change. You copy.
template <typename T>
class ivector {
std::vector<T> m_vector;
// ...
ivector erase(const_iterator i) {
auto offset = i - begin();
auto copy = m_vector;
copy.erase(copy.begin() + offset);
return {copy};
}
};
We copied the erased item as well
We allocated more memory
template <typename T>
class ivector {
std::vector<T> m_vector;
// ...
ivector erase(const_iterator i) {
auto offset = i - begin();
std::vector<T> copy;
copy.reserve(m_vector.size() - 1);
copy.insert(copy.end(), m_vector.begin(), i);
copy.insert(copy.end(), i+1, m_vector.end());
return {copy};
}
};
gh/arximboldi/immer - immutable container library
I've been quite into immutable objects for the past two years.
Let's chat!
Most std::vector alternatives are there to deal with allocations.
So, what about them?
Rule of thumb: Always Avoid Allocations!
... unless you really know what you're doingstd::pmr helps, but not muchstd::pmr is not zero cost
I'm not against std::pmr
Use std::pmr as much as possible!
Sometimes you can completely avoid allocations
What if the size is always smaller than a given N?
std::array?
std::arraystatic_vectorstatic_vectorboost::static_vector - a powerful implementationitlib::static_vectorstd::move_if_noexceptatCan we have the best of all worlds?
small_vectorsmall_vectorboost::small_vector - a poweful implementationitlib::small_vectorstd::move_if_noexceptatWhat if the size is absolutely random?
std::vector?
reallocWe have a block of memory:
_expand (Windows only)We have a block of memory (on Windows):
std::vector and reallocmemcpy disregards constructors and destructors_expand can actually work_expand can be implemented for any allocatorallocate_at_least is a poor attempt to helppod_vectoritlib::pod_vectorrealloc, memcpy, memmove..._expand if availableatoptimal_alloc_vector: uses _expanduber_vector: can be any of thesestd::vector is still quite powerfulstd::pmr::vector is awesomeWe have a bajillion vector types. How do we write an algorithm?
void work(const std::vector<obj>& data);
doesn't work anymore
Templates, of course work, but at a cost.
And don't get me started on ranges!
How about
void work(const obj* buf, size_t size);
The answer is yes!
std::spanstd::span... not even C++11
my::spanstd::spanboost::spanitlib::spanBut what about ranges?
But that's just, like, my opinion, man
ufunction - capture non-copyable (like unique_ptr)flat_map, flat_set - map with cache localitysentry - finally-type blocksBorislav Stanimirov / ibob.bg / @stanimirovb
These slides: ibob.bg/slides/beyond-vec/
Demo code: github.com/iboB/vec-span-demo
Slides license Creative Commons By 4.0