summaryrefslogtreecommitdiffhomepage
path: root/src/path-search-result.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/path-search-result.cpp')
-rw-r--r--src/path-search-result.cpp68
1 files changed, 50 insertions, 18 deletions
diff --git a/src/path-search-result.cpp b/src/path-search-result.cpp
index 2d9f6ebd..fb2c41ca 100644
--- a/src/path-search-result.cpp
+++ b/src/path-search-result.cpp
@@ -1,38 +1,70 @@
#include "path-search.hpp"
#include "path-search-result.hpp"
#include "compat/assert.hpp"
+#include <utility>
namespace floormat {
-path_search_result::path_search_result() : _next{nullptr} {}
-size_t path_search_result::size() const { return _path.size(); }
-path_search_result::operator bool() const { return !_path.empty(); }
-path_search_result::operator ArrayView<const global_coords>() const { return {_path.data(), _path.size()}; }
-const global_coords* path_search_result::begin() const { return _path.data(); }
-const global_coords* path_search_result::end() const { return _path.data() + _path.size(); }
+std::unique_ptr<path_search_result::node> path_search_result::_pool; // NOLINT
-const global_coords& path_search_result::operator[](size_t index) const
+path_search_result::path_search_result()
{
- fm_debug_assert(index < _path.size());
- return data()[index];
+ if (_pool)
+ {
+ auto ptr = std::move(_pool);
+ fm_debug_assert(ptr->vec.empty());
+ auto next = std::move(ptr->_next);
+ _node = std::move(ptr);
+ _pool = std::move(next);
+ }
+ else
+ {
+ _node = std::make_unique<node>();
+ _node->vec.reserve(min_length);
+ }
+}
+
+path_search_result::~path_search_result() noexcept
+{
+ fm_debug_assert(_node);
+ _node->vec.clear();
+ _node->_next = std::move(_pool);
+ _pool = std::move(_node);
}
-const global_coords* path_search_result::data() const
+path_search_result::path_search_result(const path_search_result& x) noexcept
{
- fm_debug_assert(!_next);
- return _path.data();
+ fm_debug_assert(x._node);
+ auto self = path_search_result{};
+ self._node->vec = x._node->vec;
+ _node = std::move(self._node);
}
-path_search_result::path_search_result(ArrayView<const global_coords> array) : _next{nullptr}
+path_search_result& path_search_result::operator=(const path_search_result& x) noexcept
{
- _path.reserve(std::max(array.size(), min_length));
- _path = {array.begin(), array.end()};
+ fm_debug_assert(_node);
+ fm_debug_assert(!_node->_next);
+ if (&x != this)
+ _node->vec = x._node->vec;
+ return *this;
}
-path_search_result::path_search_result(const path_search_result& other) : _next{nullptr}
+path_search_result::node::node() noexcept = default;
+size_t path_search_result::size() const { return _node->vec.size(); }
+const global_coords* path_search_result::data() const { return _node->vec.data(); }
+path_search_result::operator bool() const { return !_node->vec.empty(); }
+
+path_search_result::operator ArrayView<const global_coords>() const
{
- _path.reserve(std::max(min_length, other._path.size()));
- _path = {other._path.begin(), other._path.end()};
+ fm_debug_assert(_node);
+ return {_node->vec.data(), _node->vec.size()};
+}
+
+const global_coords& path_search_result::operator[](size_t index) const
+{
+ fm_debug_assert(_node);
+ fm_debug_assert(index < _node->vec.size());
+ return data()[index];
}
} // namespace floormat