20 class PavingNode :
public std::enable_shared_from_this<PavingNode<P>>
24 explicit PavingNode(
const P& paving,
const IntervalVector& x, std::shared_ptr<PavingNode<P>> top =
nullptr)
25 : _paving(paving), _x(P::init_tuple(x)), _top(top)
28 const P& paving()
const
33 const typename P::NodeTuple_& boxes()
const
38 typename P::NodeTuple_& boxes()
40 return const_cast<typename P::NodeTuple_&
>(
const_cast<const PavingNode<P>*
>(
this)->boxes());
43 void set_boxes(
const typename P::NodeTuple_& x)
48 IntervalVector hull()
const
50 IntervalVector h = std::get<0>(_x);
51 std::apply([&](
auto &&... xs) { ((h |= xs), ...); }, _x);
55 IntervalVector unknown()
const
57 IntervalVector h = std::get<0>(_x);
58 std::apply([&](
auto &&... xs) { ((h &= xs), ...); }, _x);
62 std::shared_ptr<const PavingNode<P>> top()
const
67 std::shared_ptr<PavingNode<P>> top()
69 return std::const_pointer_cast<PavingNode<P>>(
const_cast<const PavingNode<P>*
>(
this)->top());
72 std::shared_ptr<const PavingNode<P>> left()
const
77 std::shared_ptr<PavingNode<P>> left()
79 return std::const_pointer_cast<PavingNode<P>>(
const_cast<const PavingNode<P>*
>(
this)->left());
82 std::shared_ptr<const PavingNode<P>> right()
const
87 std::shared_ptr<PavingNode<P>> right()
89 return std::const_pointer_cast<PavingNode<P>>(
const_cast<const PavingNode<P>*
>(
this)->right());
103 void visit(std::function<
bool(std::shared_ptr<
const PavingNode<P>>)> visitor)
const
105 if(!_top && !_right && _left && left()->boxes() == _x)
106 left()->visit(visitor);
108 else if(visitor(this->shared_from_this()))
110 if(_left) left()->visit(visitor);
111 if(_right) right()->visit(visitor);
115 void visit(std::function<
bool(std::shared_ptr<PavingNode<P>>)> visitor)
117 if(!_top && !_right && _left && left()->boxes() == _x)
118 _left->visit(visitor);
120 else if(visitor(this->shared_from_this()))
122 if(_left) left()->visit(visitor);
123 if(_right) right()->visit(visitor);
129 return not _left && not _right;
134 bisect([](
const IntervalVector& x) {
return x.bisect_largest(); });
137 void bisect(std::function<std::pair<IntervalVector,IntervalVector>(
const IntervalVector&)> bisect_fnc)
139 assert_release(is_leaf() &&
"only leaves can be bisected");
141 bool bisectable_node =
true;
142 std::apply([&](
auto &&... xs) { ((bisectable_node &= xs.is_bisectable()), ...); }, _x);
143 assert_release(bisectable_node);
145 auto p = bisect_fnc(unknown());
147 _left = make_shared<PavingNode<P>>(_paving, p.first, this->shared_from_this());
148 _right = make_shared<PavingNode<P>>(_paving, p.second, this->shared_from_this());
151 std::vector<IntervalVector> complementary_value(
const typename P::NodeValue_& node_value)
const
153 return hull().diff(node_value(_x));
159 typename P::NodeTuple_ _x;
160 std::shared_ptr<PavingNode<P>> _top =
nullptr;
161 std::shared_ptr<PavingNode<P>> _left =
nullptr, _right =
nullptr;