测试对象在容器中的成员资格

由于节点存储是容器中现有对象的属性, 以便检查对象本身 当前包含在容器中。这项检查始终都能快速完成 O(1) 运算。

本指南的这一部分介绍了测试对象是否 目前是它们当前可能包含的任何容器的成员 位置

使用混入测试单容器对象

所有节点状态类都提供了一个公共 InContainer() 方法, 以便测试节点状态实例当前是否属于 以及对象通常包含的 ListableContainable 混合, 来源。由于这些对象来自混入,因此它们也公开了 方法,因此测试使用混合传入的对象,并且只能是 容器成员资格很简单,只需调用 针对对象的 InContainer() 权限。

class Obj : public fbl::SinglyLinkedLisable<Obj*> { /* ... */ };

Obj* the_obj = new Obj();
fbl
::SinglyLinkedList<Obj*> the_list;
ASSERT
(the_obj->InContainer() == false);

the_list
.push_front(the_obj);
ASSERT
(the_obj->InContainer() == true);

the_list
.clear();
ASSERT
(the_obj->InContainer() == false);

delete the_obj;

使用混入而不使用 ContainableBaseClasses 的多个容器对象

当某个对象因派生自多个容器而可能因此属于多个容器时 情况就会变得更加复杂对象本身 现在有多个 InContainer() 实现,它继承自 因此来电者需要明确具体要拨打哪个号码。 虽然这是可以做到的,但语法不当, 封装在对象的自定义方法中。例如:

class Obj : public fbl::DoublyLinkedListable<Obj*>,
           
public fbl::WAVLTreeContainable<Obj*> {
 
public:
   
// ...
   
bool InList() const { return this->DoublyLinkedListable<Obj*>::InContainer(); }
   
bool InTree() const { return this->WAVLTreeContainable<Obj*>::InContainer(); }
   
// ...
};

void test(const Obj& obj) {
 
bool in_list, in_tree;

 
// The hard way
  in_list
= obj.DoublyLinkedListable<Obj*>::InContainer();
  in_tree
= obj.WAVLTreeContainable<Obj*>::InContainer();

 
// The slightly easier way (the class still needs to implement the hard way)
  in_list
= obj.InList();
  in_tree
= obj.InTree();
}

使用 Mix-in 的多个容器对象,其中 ContainableBaseClasses

对多个容器中的现有属性使用 ContainableBaseClasses 这样可大大简化这一过程 选择您要测试成员资格的容器。fbl::提供 一个独立的 InContainer 函数,该函数可与标记结合使用, 轻松测试成员资格我们来看一下之前的示例 使用 ContainableBaseClasses

struct ListTag {};
struct TreeTag {};

class Obj
 
: public fbl::ContainableBaseClasses<fbl::TaggedDoublyLinkedListable<Obj*, ListTag>,
                                       fbl
::TaggedWAVLTreeContainable<Obj*, TreeTag>> { /* ... */ };

void test(const Obj& obj) {
 
bool in_list = fbl::InContainer<ListTag>(obj);
 
bool in_tree = fbl::InContainer<TreeTag>(obj);
}

直接使用 NodeState 对象进行测试

最后,如果使用了 NodeState 对象和自定义 trait, 容器成员资格仍然可以测试,但您需要询问 NodeState 实例。

class Obj {
 
public:
 
// Obj impl here

 
bool InFooList() const { return foo_list_node_.InContainer(); }
 
bool InBarList() const { return bar_list_node_.InContainer(); }

 
private:
 
struct FooListTraits {
   
static auto& node_state(Obj& obj) {
     
return obj.foo_list_node_;
   
}
 
};

 
struct BarListTraits {
   
static auto& node_state(Obj& obj) {
     
return obj.bar_list_node_;
   
}
 
};

 
friend struct FooListTraits;
 
friend struct BarListTraits;

  fbl
::DoublyLinkedListNodeState<Obj*> foo_list_node_;
  fbl
::DoublyLinkedListNodeState<fbl::RefPtr<Obj>> bar_list_node_;

 
public:
 
using FooList = fbl::DoublyLinkedListCustomTraits<Obj*, FooListTraits>;
 
using BarList = fbl::DoublyLinkedListCustomTraits<fbl::RefPtr<Obj>, BarListTraits>;
};