Skip to content

Custom allocator #2

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 45 additions & 14 deletions include/Quadtree.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,27 @@
namespace quadtree
{

template<typename T, typename GetBox, typename Equal = std::equal_to<T>, typename Float = float>
namespace detail
{
template <typename T>
struct StdMakeUnique
{
template <typename... Args>
std::unique_ptr<T> operator() (Args&&... args)
{
return std::make_unique<T>(std::forward<Args>(args)...);
}
};
}

template<
typename T,
typename GetBox,
typename Equal = std::equal_to<T>,
typename Float = float,
template <typename> class Allocator = std::allocator,
template <typename> class MakeUnique = detail::StdMakeUnique
>
class Quadtree
{
static_assert(std::is_convertible_v<std::invoke_result_t<GetBox, const T&>, Box<Float>>,
Expand All @@ -20,9 +40,12 @@ class Quadtree
static_assert(std::is_arithmetic_v<Float>);

public:
template <typename U>
using vector_type = std::vector< U, Allocator<U> >;

Quadtree(const Box<Float>& box, const GetBox& getBox = GetBox(),
const Equal& equal = Equal()) :
mBox(box), mRoot(std::make_unique<Node>()), mGetBox(getBox), mEqual(equal)
mBox(box), mMakeUnique(), mRoot(mMakeUnique()), mGetBox(getBox), mEqual(equal)
{

}
Expand All @@ -37,16 +60,16 @@ class Quadtree
remove(mRoot.get(), nullptr, mBox, value);
}

std::vector<T> query(const Box<Float>& box) const
vector_type<T> query(const Box<Float>& box) const
{
auto values = std::vector<T>();
auto values = vector_type<T>();
query(mRoot.get(), mBox, box, values);
return values;
}

std::vector<std::pair<T, T>> findAllIntersections() const
vector_type<std::pair<T, T>> findAllIntersections() const
{
auto intersections = std::vector<std::pair<T, T>>();
auto intersections = vector_type<std::pair<T, T>>();
findAllIntersections(mRoot.get(), intersections);
return intersections;
}
Expand All @@ -55,14 +78,22 @@ class Quadtree
static constexpr auto Threshold = std::size_t(16);
static constexpr auto MaxDepth = std::size_t(8);

struct Node;
#if __cplusplus < 201703L
typedef typename std::result_of<MakeUnique<Node>()>::type UniqueNodePtr;
#else
typedef std::invoke_result_t<MakeUnique<Node>> UniqueNodePtr;
#endif

struct Node
{
std::array<std::unique_ptr<Node>, 4> children;
std::vector<T> values;
std::array<UniqueNodePtr, 4> children;
vector_type<T> values;
};

Box<Float> mBox;
std::unique_ptr<Node> mRoot;
MakeUnique<Node> mMakeUnique;
UniqueNodePtr mRoot;
GetBox mGetBox;
Equal mEqual;

Expand Down Expand Up @@ -163,9 +194,9 @@ class Quadtree
assert(isLeaf(node) && "Only leaves can be split");
// Create children
for (auto& child : node->children)
child = std::make_unique<Node>();
child = mMakeUnique();
// Assign values to children
auto newValues = std::vector<T>(); // New values for this node
auto newValues = vector_type<T>(); // New values for this node
for (const auto& value : node->values)
{
auto i = getQuadrant(box, mGetBox(value));
Expand Down Expand Up @@ -238,7 +269,7 @@ class Quadtree
}
}

void query(Node* node, const Box<Float>& box, const Box<Float>& queryBox, std::vector<T>& values) const
void query(Node* node, const Box<Float>& box, const Box<Float>& queryBox, vector_type<T>& values) const
{
assert(node != nullptr);
assert(queryBox.intersects(box));
Expand All @@ -258,7 +289,7 @@ class Quadtree
}
}

void findAllIntersections(Node* node, std::vector<std::pair<T, T>>& intersections) const
void findAllIntersections(Node* node, vector_type<std::pair<T, T>>& intersections) const
{
// Find intersections between values stored in this node
// Make sure to not report the same intersection twice
Expand All @@ -284,7 +315,7 @@ class Quadtree
}
}

void findIntersectionsInDescendants(Node* node, const T& value, std::vector<std::pair<T, T>>& intersections) const
void findIntersectionsInDescendants(Node* node, const T& value, vector_type<std::pair<T, T>>& intersections) const
{
// Test against the values stored in this node
for (const auto& other : node->values)
Expand Down