Maintenance - Mise à jour mensuelle Lundi 7 Décembre 2021 entre 7h00 et 9h00

Commit caa44d5c authored by Gauthier Quesnel's avatar Gauthier Quesnel
Browse files

core: remove array and vector container

parent adadac76
......@@ -63,6 +63,7 @@ status_string(const status s) noexcept
"model_flow_bad_samplerate",
"model_flow_bad_data",
"gui_not_enough_memory",
"io_not_enough_memory",
"io_file_format_error",
"io_file_format_model_error",
"io_file_format_model_number_error",
......
......@@ -166,6 +166,7 @@ enum class status
model_flow_bad_samplerate,
model_flow_bad_data,
gui_not_enough_memory,
io_not_enough_memory,
io_file_format_error,
io_file_format_model_error,
io_file_format_model_number_error,
......@@ -1456,372 +1457,6 @@ public:
}
};
template<typename T>
class vector
{
public:
using value_type = T;
using reference = T&;
using const_reference = const T&;
using pointer = T*;
using const_pointer = const T*;
using difference_type = std::ptrdiff_t;
using size_type = std::size_t;
using iterator = T*;
using const_iterator = const T*;
private:
value_type* m_items{ nullptr };
unsigned m_capacity = 0u;
unsigned m_size = 0u;
public:
vector() = default;
~vector() noexcept
{
clear();
if (m_items)
std::free(m_items);
}
vector(const vector&) noexcept = delete;
vector& operator=(const vector&) noexcept = delete;
vector(vector&&) noexcept = delete;
vector& operator=(vector&&) noexcept = delete;
status init(std::size_t new_capacity_) noexcept
{
if (new_capacity_ > std::numeric_limits<unsigned>::max())
return status::vector_init_capacity_too_big;
if (new_capacity_ == 0)
return status::vector_init_capacity_zero;
clear();
const auto new_capacity = static_cast<unsigned int>(new_capacity_);
if (new_capacity > m_capacity) {
if (m_items)
std::free(m_items);
m_items = static_cast<value_type*>(
std::malloc(new_capacity * sizeof(value_type)));
if (m_items == nullptr)
return status::vector_init_not_enough_memory;
m_capacity = new_capacity;
}
return status::success;
}
status resize(std::size_t new_capacity_) noexcept
{
static_assert(std::is_trivial_v<T>,
"vector::resize only for trivial data");
irt_return_if_bad(init(new_capacity_));
m_size = m_capacity;
return status::success;
}
void clear() noexcept
{
if constexpr (!std::is_trivial_v<T>)
for (auto i = 0u; i != m_size; ++i)
m_items[i].~T();
m_size = 0;
}
bool can_alloc(size_type number) const noexcept
{
return number + m_size <= m_capacity;
}
template<typename... Args>
std::pair<bool, iterator> try_emplace_back(Args&&... args) noexcept
{
if (!can_alloc(1u))
return std::make_pair(false, end());
unsigned ret = m_size++;
new (&m_items[ret]) T(std::forward<Args>(args)...);
return std::pair(true, begin() + ret);
}
template<typename... Args>
iterator emplace_back(Args&&... args) noexcept
{
irt_assert(m_size < m_capacity);
unsigned ret = m_size++;
new (&m_items[ret]) T(std::forward<Args>(args)...);
return begin() + ret;
}
void pop_back() noexcept
{
if (m_size == 0)
return;
--m_size;
if constexpr (!std::is_trivial_v<T>)
m_items[m_size].~T();
}
iterator erase_and_swap(const_iterator it) noexcept
{
auto diff = std::distance(cbegin(), it);
irt_assert(diff < std::numeric_limits<unsigned>::max());
auto i = static_cast<unsigned>(diff);
irt_assert(i < m_size);
if (m_size - 1 == i) {
pop_back();
return end();
} else {
using std::swap;
swap(m_items[m_size - 1], m_items[i]);
pop_back();
return begin() + i;
}
}
reference operator[](size_type i) noexcept
{
irt_assert(i < m_size);
return m_items[i];
}
const_reference operator[](size_type i) const noexcept
{
irt_assert(i < m_size);
return m_items[i];
}
pointer data() noexcept
{
return m_items;
}
const_pointer data() const noexcept
{
return m_items;
}
iterator begin() noexcept
{
return m_items;
}
iterator end() noexcept
{
return m_items + m_size;
}
const_iterator begin() const noexcept
{
return m_items;
}
const_iterator end() const noexcept
{
return m_items + m_size;
}
const_iterator cbegin() const noexcept
{
return m_items;
}
const_iterator cend() const noexcept
{
return m_items + m_size;
}
size_t size() const noexcept
{
return m_size;
}
size_type capacity() const noexcept
{
return m_capacity;
}
reference front() noexcept
{
irt_assert(m_size > 0);
return m_items[0];
}
const_reference front() const noexcept
{
irt_assert(m_size > 0);
return m_items[0];
}
reference back() noexcept
{
irt_assert(m_size > 0);
return m_items[m_size - 1];
}
const_reference back() const noexcept
{
irt_assert(m_size > 0);
return m_items[m_size - 1];
}
};
template<typename T>
class array
{
public:
using value_type = T;
using reference = T&;
using const_reference = const T&;
using pointer = T*;
using const_pointer = const T*;
using difference_type = std::ptrdiff_t;
using size_type = std::size_t;
using iterator = T*;
using const_iterator = const T*;
private:
value_type* m_items{ nullptr };
unsigned m_capacity{ 0 };
public:
array() = default;
~array() noexcept
{
clear();
if (m_items)
std::free(m_items);
}
array(const array&) noexcept = delete;
array& operator=(const array&) noexcept = delete;
array(array&&) noexcept = delete;
array& operator=(array&&) noexcept = delete;
status init(std::size_t new_capacity) noexcept
{
if (new_capacity > std::numeric_limits<unsigned>::max())
return status::array_init_capacity_too_big;
if (new_capacity == 0)
return status::array_init_capacity_zero;
if (new_capacity != m_capacity) {
if (m_items) {
if constexpr (!std::is_trivial_v<T>)
for (auto i = 0u; i != m_capacity; ++i)
m_items[i].~T();
std::free(m_items);
}
m_items = static_cast<value_type*>(
std::malloc(new_capacity * sizeof(value_type)));
if constexpr (!std::is_trivial_v<T>)
for (auto i = 0u; i != m_capacity; ++i)
new (&m_items[i]) T();
if (m_items == nullptr)
return status::array_init_not_enough_memory;
}
m_capacity = static_cast<unsigned>(new_capacity);
return status::success;
}
void clear() noexcept
{
if constexpr (!std::is_trivial_v<T>)
for (auto i = 0u; i != m_capacity; ++i)
m_items[i].~T();
}
reference operator[](size_type i) noexcept
{
irt_assert(i < m_capacity);
return m_items[i];
}
const_reference operator[](size_type i) const noexcept
{
irt_assert(i < m_capacity);
return m_items[i];
}
pointer data() noexcept
{
return m_items;
}
const_pointer data() const noexcept
{
return m_items;
}
iterator begin() noexcept
{
return m_items;
}
iterator end() noexcept
{
return m_items + m_capacity;
}
const_iterator begin() const noexcept
{
return m_items;
}
const_iterator end() const noexcept
{
return m_items + m_capacity;
}
const_iterator cbegin() const noexcept
{
return m_items;
}
const_iterator cend() const noexcept
{
return m_items + m_capacity;
}
size_t size() const noexcept
{
return m_capacity;
}
size_t capacity() const noexcept
{
return m_capacity;
}
};
/*****************************************************************************
*
* data-array
......
......@@ -18,7 +18,7 @@ class reader
private:
std::istream& is;
array<model_id> map;
std::vector<model_id> map;
int model_error = 0;
int connection_error = 0;
......@@ -40,9 +40,11 @@ public:
irt_return_if_fail(model_number > 0,
status::io_file_format_model_number_error);
irt_return_if_bad(map.init(model_number));
std::fill_n(std::begin(map), std::size(map), static_cast<model_id>(0));
try {
map.resize(model_number, model_id{ 0 });
} catch (const std::bad_alloc& /*e*/) {
return status::io_not_enough_memory;
}
int id;
......@@ -547,7 +549,7 @@ struct writer
{
std::ostream& os;
array<model_id> map;
std::vector<model_id> map;
writer(std::ostream& os_) noexcept
: os(os_)
......@@ -557,9 +559,11 @@ struct writer
{
os << sim.models.size() << '\n';
irt_return_if_bad(map.init(sim.models.size()));
std::fill_n(std::begin(map), std::size(map), static_cast<model_id>(0));
try {
map.resize(sim.models.size(), model_id{ 0 });
} catch (const std::bad_alloc& /*e*/) {
return status::io_not_enough_memory;
}
model* mdl = nullptr;
int id = 0;
......
......@@ -300,105 +300,6 @@ main()
}
};
"array_api"_test = [] {
struct position
{
position() noexcept = default;
position(int x_, int y_)
: x(x_)
, y(y_)
{}
int x = 0, y = 0;
};
irt::array<position> positions;
!expect(irt::status::success == positions.init(16u));
expect(positions.size() == 16_u);
expect(positions.capacity() == 16u);
for (int i = 0; i != 16; ++i) {
positions[i].x = i;
positions[i].y = i;
}
for (int i = 0; i != 16; ++i) {
expect(positions[i].x == i);
expect(positions[i].y == i);
}
};
"vector_api"_test = [] {
struct position
{
position() noexcept = default;
position(int x_, int y_)
: x(x_)
, y(y_)
{}
int x = 0, y = 0;
};
irt::vector<position> positions;
!expect(irt::status::success == positions.init(16u));
expect(positions.size() == 0_u);
expect(positions.capacity() == 16u);
{
expect(positions.can_alloc(1u));
auto it = positions.emplace_back(0, 1);
expect(positions.size() == 1_u);
expect(positions.begin() == it);
expect(it->x == 0);
expect(it->y == 1);
}
{
auto ret = positions.try_emplace_back(2, 3);
expect(ret.first == true);
expect(ret.second == positions.begin() + 1);
expect(positions.size() == 2_u);
expect(positions.begin()->x == 0);
expect(positions.begin()->y == 1);
expect((positions.begin() + 1)->x == 2);
expect((positions.begin() + 1)->y == 3);
}
{
auto it = positions.erase_and_swap(positions.begin());
expect(positions.size() == 1_u);
expect(it == positions.begin());
expect(it->x == 2);
expect(it->y == 3);
}
positions.clear();
expect(positions.size() == 0_ul);
expect(positions.capacity() == 16_u);
expect(positions.can_alloc(16u));
for (int i = 0; i != 16; ++i)
positions.emplace_back(i, i);
auto ret = positions.try_emplace_back(16, 16);
expect(ret.first == false);
expect(positions.size() == 16_ul);
expect(positions.capacity() == 16_u);
auto it = positions.begin();
while (it != positions.end())
it = positions.erase_and_swap(it);
expect(positions.size() == 0_ul);
expect(positions.capacity() == 16_u);
};
"data_array_api"_test = [] {
struct position
{
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment