저는 계층 적 Entity-Component System에서 작업하고 있습니다. 엔티티가 여러 엔티티로 구성 될 수 있기 때문에이를 계층 구조 이라고합니다.range-v3를 사용하여 view_facade를 만드는 방법
내 계층 구조는 여러 연결된 목록으로 구현됩니다. 비록 여러 개의 std::list
또는 std::forward_list
에 의존하지 않습니다. 사실, 두 개의 벡터가 있습니다 : 1) Entity를 첫 번째 자식으로 매핑합니다. 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;
};
감사합니다. Eric. 방금 문제가 발생했습니다. 내가 std :: reference_wrapper를 작동시키기에 충분한 시간이 없었지만, Cursor 개념에서 계속 실패했다. 지금은 원시 포인터로 참조를 변경했습니다. 이제 구조에 ForwardRange와 같은 특정 개념을 모델링하고 싶습니다. forward()/end() 메소드와 forward Iterator를 생성해야합니까? 범위 개념이 iterator boilerplating을 대체하기로되어 있다고 생각했습니다. – 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