I defined a red-black tree node (with template):
struct rb_node {
rb_node *left;
rb_node *right;
rb_node *parent;
value_type val;
enum _Node_color { Black, Red } color;
};
Obviously, I can't create a sentinel node for the Test
class, for example:
class Test {
private:
int v;
public:
explicit Test(int x) : v(x) {}
bool operator<(const Test & t) const noexcept { return t.V() > v; }
int V() const noexcept { return v; }
};
// ... In rb_node<Test>:
static const rb_node sentinel_node; // Wrong!
How to fix this problem without changing Test
? --- I found that MSVC STL also uses sentinel nodes, but they solved this problem. How did they do it?
// In <xtree>
template <class _Value_type, class _Voidptr>
struct _Tree_node {
using _Nodeptr = _Rebind_pointer_t<_Voidptr, _Tree_node>;
using value_type = _Value_type;
_Nodeptr _Left; // left subtree, or smallest element if head
_Nodeptr _Parent; // parent, or root of tree if head
_Nodeptr _Right; // right subtree, or largest element if head
char _Color; // _Red or _Black, _Black if head
char _Isnil; // true only if head (also nil) node; TRANSITION, should be bool
value_type _Myval = // the stored value, unused if head
_Returns_exactly<value_type>(); // fake a viable constructor to workaround GH-2749
}
// ...
void _Alloc_sentinel_and_proxy() {
const auto _Scary = _Get_scary();
auto&& _Alproxy = _GET_PROXY_ALLOCATOR(_Alnode, _Getal());
_Container_proxy_ptr<_Alnode> _Proxy(_Alproxy, *_Scary);
_Scary->_Myhead = _Node::_Buyheadnode(_Getal());
_Proxy._Release();
}