0
我正在处理分层实体组件系统。它被称为等级 ,因为实体可能由多个实体组成。如何使用范围创建view_facade -v3
我的层次结构实现为多个链接列表。虽然,我不是依靠几个std::list
或std::forward_list
。实际上,我有两个向量:1)将实体映射到其第一个孩子; 2)将孩子映射到下一个兄弟姐妹。
我想在这个结构上创建一个ranges::view
,但似乎我忘记了一些东西。
我想使用的范围内这样(Complete Code on GitHub):
TEST_CASE("Range adaptors")
{
auto parentSystem = System<Test::Parent>{};
auto childSystem = System<Test::Child>{};
auto parent0 = parentSystem.add();
auto parent1 = parentSystem.add();
LeftMapped<Test::Parent, System, Test::Child, System> leftMapped(parentSystem, childSystem);
leftMapped.addChild(parent0, childSystem.add());
leftMapped.addChild(parent0, childSystem.add());
leftMapped.addChild(parent0, childSystem.add());
leftMapped.addChild(parent1, childSystem.add());
// HERE \/
ranges::for_each(leftMapped.children(parent0), [](Test::Child child)
{
std::cout << static_cast<Base>(child).id() << std::endl;
});
}
,当然还有,使它pipeable与视图和兼容的行动与前进档位的工作(我不这样用概念成语)。
这是我想适应的部分代码:
// A composition should inherit Left Mapped when it is necessary O(1) mapping from parent to children.
template <typename ParentType, template <typename> class ParentSystemType, typename ChildType, template <typename> class ChildSystemType>
class LeftMapped
{
public:
LeftMapped(ParentSystemType<ParentType>& parent, ChildSystemType<ChildType>& child):
m_firstChild(makeProperty<ChildType>(parent)),
m_nextSibling(makeProperty<ChildType>(child))
{
}
ChildType firstChild(ParentType parent) const
{
return m_firstChild[parent];
}
ChildType nextSibling(ChildType child) const
{
return m_nextSibling[child];
}
void firstChild(ParentType parent, ChildType child)
{
m_firstChild[parent] = child;
}
void nextSibling(ChildType child, ChildType next)
{
m_nextSibling[child] = next;
}
void addChild(ParentType parent, ChildType child)
{
m_nextSibling[child] = m_firstChild[parent];
m_firstChild[parent] = child;
}
// HERE \/ I don't know how to properly adapt my container.
class ChildrenView : public ranges::view_facade<ChildrenView> {
friend ranges::range_access;
const LeftMapped& mapped;
const ParentType parent;
struct cursor
{
const LeftMapped& mapped;
ChildType current;
decltype(auto) read() const
{
return current;
}
void next()
{
current = mapped.nextSibling(current);
}
bool equal(ranges::default_sentinel) const {
return current == ChildType{};
}
};
cursor begin_cursor() {
return {mapped, mapped.firstChild(parent)};
}
public:
ChildrenView() = default;
explicit ChildrenView(const LeftMapped& mapped, ParentType parent)
: mapped(mapped),
parent(parent)
{}
};
auto children(ParentType parent) const
{
return ChildrenView(*this, parent);
}
private:
Property<ParentType, ChildType, ParentSystemType> m_firstChild;
Property<ChildType, ChildType, ChildSystemType> m_nextSibling;
};
谢谢埃里克。你刚刚得到了问题。虽然我没有足够的时间让std :: reference_wrapper工作,但它仍然在Cursor概念上失败。现在,我只是改变了原始指针的引用。 现在,我希望我的结构能够模拟特定的概念,如ForwardRange。我是否必须创建begin()/ end()方法以及前向迭代器?我认为范围概念应该取代那个迭代器锅炉... – csguth
@csguth'view_facade'为你添加'begin'和'end'。默认'begin'大致返回'basic_iterator begin_cursor())> {this-> begin_cursor()}',默认'end'返回'default_sentinel {}'。如果你想让你的范围为'ForwardRange'建模,那么你的光标需要为'ForwardCursor'建模。值得注意的是,它缺少'basic_iterator'需要实现迭代器相等的'bool equal(const cursor&that)const'。 –
Casey