2017-04-11 12 views
0

저는 계층 적 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; 
}; 

답변

1

나를 뛰어 우선 당신이 ChildrenViewChildrenView::cursor 모두 참조 데이터 멤버를 가지고 있었다. 따라서 이러한 유형을 지정할 수 없으며 범위 -v3이 필요합니다. 그것들을 포인터 또는 std::reference_wrapper s로 변경해보고 더 가까이에 있는지 확인하십시오.

+0

감사합니다. Eric. 방금 문제가 발생했습니다. 내가 std :: reference_wrapper를 작동시키기에 충분한 시간이 없었지만, Cursor 개념에서 계속 실패했다. 지금은 원시 포인터로 참조를 변경했습니다. 이제 구조에 ForwardRange와 같은 특정 개념을 모델링하고 싶습니다. forward()/end() 메소드와 forward Iterator를 생성해야합니까? 범위 개념이 iterator boilerplating을 대체하기로되어 있다고 생각했습니다. – csguth

+1

@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