提交 2fc7de77 编写于 作者: L lixinqi

list_head

上级 250c5d7b
#ifndef ONEFLOW_CORE_COMMON_LIST_H_
#define ONEFLOW_CORE_COMMON_LIST_H_
#ifndef ONEFLOW_CORE_COMMON_LIST_HEAD_H_
#define ONEFLOW_CORE_COMMON_LIST_HEAD_H_
#include "oneflow/core/common/struct_traits.h"
#include <glog/logging.h>
......@@ -10,10 +10,6 @@ struct ListHead final {
public:
ListHead() { Clear(); }
void Clear() {
prev_ = this;
next_ = this;
}
ListHead* prev() const { return prev_; }
ListHead* next() const { return next_; }
......@@ -21,6 +17,10 @@ struct ListHead final {
prev->set_next(this);
this->set_prev(prev);
}
void Clear() {
prev_ = this;
next_ = this;
}
private:
void set_prev(ListHead* prev) { prev_ = prev; }
......@@ -48,9 +48,10 @@ class EmbeddedListViewImpl {
using container_type = typename ContainerField::struct_type;
using item_type = typename ItemField::struct_type;
static_assert(std::is_same<ContainerField::field_type, ListHead>::value,
static_assert(std::is_same<typename ContainerField::field_type, ListHead>::value,
"no ListHead found in container");
static_assert(std::is_same<ItemField::field_type, ListHead>::value, "no ListHead found in item");
static_assert(std::is_same<typename ItemField::field_type, ListHead>::value,
"no ListHead found in item");
explicit EmbeddedListViewImpl(container_type* container) : container_(container) {}
~EmbeddedListViewImpl() = default;
......@@ -58,14 +59,7 @@ class EmbeddedListViewImpl {
CHECK_NE(item, end_item());
ListHead* list_head = ItemField::FieldPtr4StructPtr(item);
list_head->next()->AppendTo(list_head->prev());
item->Clear();
}
void InsertAfter(item_type* prev_item, item_type* new_item) {
ListHead* prev_list_head = ItemField::FieldPtr4StructPtr(prev_item);
ListHead* next_list_head = prev_list_head->next();
ListHead* new_list_head = ItemField::FieldPtr4StructPtr(new_item);
new_list_head->AppendTo(prev_list_head);
next_list_head->AppendTo(new_list_head);
list_head->Clear();
}
void PushBack(item_type* item) { InsertAfter(last_item(), item); }
void PushFront(item_type* item) { InsertAfter(end_item(), item); }
......@@ -96,14 +90,25 @@ class EmbeddedListViewImpl {
}
private:
void InsertAfter(item_type* prev_item, item_type* new_item) {
ListHead* prev_list_head = ItemField::FieldPtr4StructPtr(prev_item);
ListHead* next_list_head = prev_list_head->next();
ListHead* new_list_head = ItemField::FieldPtr4StructPtr(new_item);
new_list_head->AppendTo(prev_list_head);
next_list_head->AppendTo(new_list_head);
}
container_type* container_;
};
#define _DEFINE_EMBEDDED_LIST_VIEW(container_field, item_field) \
template<> \
class EmbeddedListView<container_field> final \
: EmbeddedListViewImpl<container_field, item_field> {};
#define _DEFINE_EMBEDDED_LIST_VIEW(container_field, item_field) \
template<> \
class EmbeddedListView<container_field> final \
: public EmbeddedListViewImpl<container_field, item_field> { \
public: \
explicit EmbeddedListView(container_type* container) \
: EmbeddedListViewImpl<container_field, item_field>(container) {} \
};
} // namespace oneflow
#endif // ONEFLOW_CORE_COMMON_LIST_H_
#endif // ONEFLOW_CORE_COMMON_LIST_HEAD_H_
#include "oneflow/core/common/list_head.h"
#include "oneflow/core/common/util.h"
namespace oneflow {
namespace test {
struct ListHeadFoo final {
int head_field_0;
int head_field_1;
ListHead bar_list;
};
struct ListItemBar final {
int value;
ListHead bar_list;
};
} // namespace test
DEFINE_EMBEDDED_LIST_VIEW(test::ListHeadFoo, bar_list, test::ListItemBar, bar_list);
using BarListView = EMBEDDED_LIST_VIEW(test::ListHeadFoo, bar_list);
namespace test {
TEST(ListHead, init) {
ListHead list_head;
ASSERT_EQ(&list_head, list_head.prev());
ASSERT_EQ(&list_head, list_head.next());
}
TEST(ListHead, append_to) {
ListHead list_head0;
ListHead list_head1;
list_head1.AppendTo(&list_head0);
ASSERT_EQ(&list_head0, list_head1.prev());
ASSERT_EQ(&list_head1, list_head0.next());
}
TEST(ListHead, clear) {
ListHead list_head0;
ListHead list_head1;
list_head1.AppendTo(&list_head0);
list_head1.Clear();
ASSERT_EQ(&list_head1, list_head1.prev());
ASSERT_EQ(&list_head1, list_head1.next());
}
TEST(EmbeddedListView, empty) {
ListHeadFoo head;
BarListView list_view(&head);
ASSERT_TRUE(list_view.empty());
}
TEST(EmbeddedListView, push_front) {
ListHeadFoo head;
BarListView list_view(&head);
ListItemBar item0;
list_view.PushFront(&item0);
ASSERT_EQ(head.bar_list.next(), &item0.bar_list);
ASSERT_EQ(head.bar_list.prev(), &item0.bar_list);
ASSERT_EQ(item0.bar_list.next(), &head.bar_list);
ASSERT_EQ(item0.bar_list.prev(), &head.bar_list);
ListItemBar item1;
list_view.PushFront(&item1);
ASSERT_EQ(head.bar_list.next(), &item1.bar_list);
ASSERT_EQ(item1.bar_list.prev(), &head.bar_list);
ASSERT_EQ(item1.bar_list.next(), &item0.bar_list);
ASSERT_EQ(item0.bar_list.prev(), &item1.bar_list);
ASSERT_EQ(item0.bar_list.next(), &head.bar_list);
ASSERT_EQ(head.bar_list.prev(), &item0.bar_list);
}
TEST(EmbeddedListView, end) {
ListHeadFoo head;
BarListView list_view(&head);
ListItemBar* end_item = list_view.end_item();
ListItemBar item0;
list_view.PushFront(&item0);
ASSERT_EQ(end_item, list_view.end_item());
}
TEST(EmbeddedListView, begin) {
ListHeadFoo head;
BarListView list_view(&head);
ASSERT_EQ(list_view.begin_item(), list_view.end_item());
ListItemBar item0;
list_view.PushFront(&item0);
ASSERT_EQ(list_view.begin_item(), &item0);
ListItemBar item1;
list_view.PushFront(&item1);
ASSERT_EQ(list_view.begin_item(), &item1);
}
TEST(EmbeddedListView, last) {
ListHeadFoo head;
BarListView list_view(&head);
ASSERT_EQ(list_view.begin_item(), list_view.end_item());
ListItemBar item0;
list_view.PushFront(&item0);
ASSERT_EQ(list_view.last_item(), &item0);
ListItemBar item1;
list_view.PushFront(&item1);
ASSERT_EQ(list_view.last_item(), &item0);
}
TEST(EmbeddedListView, push_back) {
ListHeadFoo head;
BarListView list_view(&head);
ASSERT_EQ(list_view.begin_item(), list_view.end_item());
ListItemBar item0;
list_view.PushBack(&item0);
ASSERT_EQ(list_view.last_item(), &item0);
ListItemBar item1;
list_view.PushBack(&item1);
ASSERT_EQ(list_view.last_item(), &item1);
}
TEST(EmbeddedListView, erase) {
ListHeadFoo head;
BarListView list_view(&head);
ASSERT_EQ(list_view.begin_item(), list_view.end_item());
ListItemBar item0;
list_view.PushBack(&item0);
ASSERT_EQ(list_view.last_item(), &item0);
ListItemBar item1;
list_view.PushBack(&item1);
ASSERT_EQ(list_view.last_item(), &item1);
list_view.Erase(&item0);
ASSERT_EQ(list_view.last_item(), &item1);
ASSERT_EQ(list_view.begin_item(), &item1);
ASSERT_EQ(item0.bar_list.prev(), &item0.bar_list);
ASSERT_EQ(item0.bar_list.next(), &item0.bar_list);
}
TEST(EmbeddedListView, pop_front) {
ListHeadFoo head;
BarListView list_view(&head);
ASSERT_EQ(list_view.begin_item(), list_view.end_item());
ListItemBar item0;
list_view.PushBack(&item0);
ASSERT_EQ(list_view.last_item(), &item0);
ListItemBar item1;
list_view.PushBack(&item1);
ASSERT_EQ(list_view.last_item(), &item1);
list_view.PopFront();
ASSERT_EQ(list_view.last_item(), &item1);
ASSERT_EQ(list_view.begin_item(), &item1);
ASSERT_EQ(item0.bar_list.prev(), &item0.bar_list);
ASSERT_EQ(item0.bar_list.next(), &item0.bar_list);
}
TEST(EmbeddedListView, pop_back) {
ListHeadFoo head;
BarListView list_view(&head);
ASSERT_EQ(list_view.begin_item(), list_view.end_item());
ListItemBar item0;
list_view.PushBack(&item0);
ASSERT_EQ(list_view.last_item(), &item0);
ListItemBar item1;
list_view.PushBack(&item1);
ASSERT_EQ(list_view.last_item(), &item1);
list_view.PopBack();
ASSERT_EQ(list_view.last_item(), &item0);
ASSERT_EQ(list_view.begin_item(), &item0);
ASSERT_EQ(item1.bar_list.prev(), &item1.bar_list);
ASSERT_EQ(item1.bar_list.next(), &item1.bar_list);
}
TEST(EmbeddedListView, next_item) {
ListHeadFoo head;
BarListView list_view(&head);
ListItemBar item0;
list_view.PushBack(&item0);
ListItemBar item1;
list_view.PushBack(&item1);
ListItemBar* item = list_view.begin_item();
ASSERT_EQ(item, &item0);
item = list_view.next_item(item);
ASSERT_EQ(item, &item1);
item = list_view.next_item(item);
ASSERT_EQ(item, list_view.end_item());
item = list_view.next_item(item);
ASSERT_EQ(item, &item0);
}
TEST(EmbeddedListView, prev_item) {
ListHeadFoo head;
BarListView list_view(&head);
ListItemBar item0;
list_view.PushBack(&item0);
ListItemBar item1;
list_view.PushBack(&item1);
ListItemBar* item = list_view.begin_item();
ASSERT_EQ(item, &item0);
item = list_view.prev_item(item);
ASSERT_EQ(item, list_view.end_item());
item = list_view.prev_item(item);
ASSERT_EQ(item, &item1);
item = list_view.prev_item(item);
ASSERT_EQ(item, &item0);
}
} // namespace test
} // namespace oneflow
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册