So, yes, I know that "you shouldn't derive from std containers" but by now it's more of philosophical rule in my mind than a technical one. I've googled again for the one fundamental reason one should never-ever-ever-ever-do-that-ever-ever-ever-or-you-die but couldn't find it.
So, if there's nothing fundamentally wrong with the following and if we set aside performance considerations, can I a get a plain-old code review of this:
namespace growth
{
template<size_t N>
class linear
{
public:
static_assert(N != 0, "Linear growth requires positive factor");
static size_t grow(size_t size, size_t capacity)
{
return (size == capacity) ? capacity + N : capacity;
}
};
template<typename Ratio = std::ratio<2, 1>>
class geometric
{
public:
static_assert(Ratio::num > Ratio::den, "Geometric growth requires ratio greater than 1");
static size_t grow(size_t size, size_t capacity)
{
return (size == capacity) ? std::max((size_t)(capacity * (Ratio::num / (double)Ratio::den)), capacity + 1) : capacity;
}
};
}
template<typename T, typename Growth, class Allocator = std::allocator<T>>
class custom_growth_vector : public std::vector<T, Allocator>
{
public:
using vector = std::vector<T, Allocator>;
using vector::vector;
void push_back(T&& value)
{
vector::reserve(Growth::grow(vector::size(), vector::capacity()));
vector::push_back(value);
}
// Also replace emplace_back, insert, etc.
};
// ...
// Grows by 50% rather than double when size == capacity.
custom_growth_vector<int, growth::geometric<ratio<3, 2>>> cgvi;
1 < r < = 1.618
(assuming you want to be able to reuse released memory). – Loki Astari Apr 1 at 20:15