582 typedef typename Parent::Node Node; |
582 typedef typename Parent::Node Node; |
583 typedef typename Parent::Edge Edge; |
583 typedef typename Parent::Edge Edge; |
584 |
584 |
585 typedef _Graph Graph; |
585 typedef _Graph Graph; |
586 |
586 |
587 class UnsupportedOperation : public LogicError { |
|
588 public: |
|
589 virtual const char* what() const throw() { |
|
590 return "lemon::SmartEdgeSet::UnsupportedOperation"; |
|
591 } |
|
592 }; |
|
593 |
|
594 |
|
595 |
|
596 protected: |
587 protected: |
597 |
588 |
598 typedef typename Parent::NodesImplBase NodesImplBase; |
589 typedef typename Parent::NodesImplBase NodesImplBase; |
599 |
590 |
600 void eraseNode(const Node& node) { |
591 void eraseNode(const Node& node) { |
616 NodesImpl(const Graph& graph, SmartEdgeSet& edgeset) |
607 NodesImpl(const Graph& graph, SmartEdgeSet& edgeset) |
617 : Parent(graph), _edgeset(edgeset) {} |
608 : Parent(graph), _edgeset(edgeset) {} |
618 |
609 |
619 virtual ~NodesImpl() {} |
610 virtual ~NodesImpl() {} |
620 |
611 |
621 protected: |
612 bool attached() const { |
622 |
613 return Parent::attached(); |
623 virtual void erase(const Node& node) { |
614 } |
624 try { |
615 |
625 _edgeset.eraseNode(node); |
|
626 Parent::erase(node); |
|
627 } catch (const typename NodesImplBase::Notifier::ImmediateDetach&) { |
|
628 Parent::clear(); |
|
629 } |
|
630 } |
|
631 virtual void erase(const std::vector<Node>& nodes) { |
|
632 try { |
|
633 for (int i = 0; i < (int)nodes.size(); ++i) { |
|
634 _edgeset.eraseNode(nodes[i]); |
|
635 } |
|
636 Parent::erase(nodes); |
|
637 } catch (const typename NodesImplBase::Notifier::ImmediateDetach&) { |
|
638 Parent::clear(); |
|
639 } |
|
640 } |
|
641 virtual void clear() { |
|
642 _edgeset.clearNodes(); |
|
643 Parent::clear(); |
|
644 } |
|
645 |
|
646 private: |
|
647 SmartEdgeSet& _edgeset; |
|
648 }; |
|
649 |
|
650 NodesImpl nodes; |
|
651 |
|
652 public: |
|
653 |
|
654 /// \brief Constructor of the adaptor. |
|
655 /// |
|
656 /// Constructor of the adaptor. |
|
657 SmartEdgeSet(const Graph& graph) : nodes(graph, *this) { |
|
658 Parent::initalize(graph, nodes); |
|
659 } |
|
660 |
|
661 }; |
|
662 |
|
663 /// \ingroup semi_adaptors |
|
664 /// |
|
665 /// \brief Graph using a node set of another graph and an |
|
666 /// own uedge set. |
|
667 /// |
|
668 /// This structure can be used to establish another graph over a node set |
|
669 /// of an existing one. The node iterator will go through the nodes of the |
|
670 /// original graph. |
|
671 /// |
|
672 /// \param _Graph The type of the graph which shares its node set with |
|
673 /// this class. Its interface must conform to the \ref concept::Graph |
|
674 /// "Graph" concept. |
|
675 /// |
|
676 /// In the edge extension and removing it conforms to the |
|
677 /// \ref concept::UGraph "UGraph" concept. |
|
678 template <typename _Graph> |
|
679 class SmartUEdgeSet |
|
680 : public UEdgeSetExtender<UndirGraphExtender<SmartEdgeSetBase<_Graph> > > { |
|
681 |
|
682 public: |
|
683 |
|
684 typedef UEdgeSetExtender<UndirGraphExtender< |
|
685 SmartEdgeSetBase<_Graph> > > Parent; |
|
686 |
|
687 typedef typename Parent::Node Node; |
|
688 typedef typename Parent::Edge Edge; |
|
689 |
|
690 typedef _Graph Graph; |
|
691 |
|
692 protected: |
|
693 |
|
694 typedef typename Parent::NodesImplBase NodesImplBase; |
|
695 |
|
696 void eraseNode(const Node& node) { |
|
697 if (typename Parent::IncEdgeIt(*this, node) == INVALID) { |
|
698 return; |
|
699 } |
|
700 throw typename NodesImplBase::Notifier::ImmediateDetach(); |
|
701 } |
|
702 |
|
703 void clearNodes() { |
|
704 Parent::clear(); |
|
705 } |
|
706 |
|
707 class NodesImpl : public NodesImplBase { |
|
708 public: |
|
709 typedef NodesImplBase Parent; |
|
710 |
|
711 NodesImpl(const Graph& graph, SmartUEdgeSet& edgeset) |
|
712 : Parent(graph), _edgeset(edgeset) {} |
|
713 |
|
714 virtual ~NodesImpl() {} |
|
715 |
|
716 protected: |
616 protected: |
717 |
617 |
718 virtual void erase(const Node& node) { |
618 virtual void erase(const Node& node) { |
719 try { |
619 try { |
720 _edgeset.eraseNode(node); |
620 _edgeset.eraseNode(node); |
739 _edgeset.clearNodes(); |
639 _edgeset.clearNodes(); |
740 Parent::clear(); |
640 Parent::clear(); |
741 } |
641 } |
742 |
642 |
743 private: |
643 private: |
|
644 SmartEdgeSet& _edgeset; |
|
645 }; |
|
646 |
|
647 NodesImpl nodes; |
|
648 |
|
649 public: |
|
650 |
|
651 /// \brief Constructor of the adaptor. |
|
652 /// |
|
653 /// Constructor of the adaptor. |
|
654 SmartEdgeSet(const Graph& graph) : nodes(graph, *this) { |
|
655 Parent::initalize(graph, nodes); |
|
656 } |
|
657 |
|
658 bool valid() const { |
|
659 return nodes.attached(); |
|
660 } |
|
661 |
|
662 }; |
|
663 |
|
664 /// \ingroup semi_adaptors |
|
665 /// |
|
666 /// \brief Graph using a node set of another graph and an |
|
667 /// own uedge set. |
|
668 /// |
|
669 /// This structure can be used to establish another graph over a node set |
|
670 /// of an existing one. The node iterator will go through the nodes of the |
|
671 /// original graph. |
|
672 /// |
|
673 /// \param _Graph The type of the graph which shares its node set with |
|
674 /// this class. Its interface must conform to the \ref concept::Graph |
|
675 /// "Graph" concept. |
|
676 /// |
|
677 /// In the edge extension and removing it conforms to the |
|
678 /// \ref concept::UGraph "UGraph" concept. |
|
679 template <typename _Graph> |
|
680 class SmartUEdgeSet |
|
681 : public UEdgeSetExtender<UndirGraphExtender<SmartEdgeSetBase<_Graph> > > { |
|
682 |
|
683 public: |
|
684 |
|
685 typedef UEdgeSetExtender<UndirGraphExtender< |
|
686 SmartEdgeSetBase<_Graph> > > Parent; |
|
687 |
|
688 typedef typename Parent::Node Node; |
|
689 typedef typename Parent::Edge Edge; |
|
690 |
|
691 typedef _Graph Graph; |
|
692 |
|
693 protected: |
|
694 |
|
695 typedef typename Parent::NodesImplBase NodesImplBase; |
|
696 |
|
697 void eraseNode(const Node& node) { |
|
698 if (typename Parent::IncEdgeIt(*this, node) == INVALID) { |
|
699 return; |
|
700 } |
|
701 throw typename NodesImplBase::Notifier::ImmediateDetach(); |
|
702 } |
|
703 |
|
704 void clearNodes() { |
|
705 Parent::clear(); |
|
706 } |
|
707 |
|
708 class NodesImpl : public NodesImplBase { |
|
709 public: |
|
710 typedef NodesImplBase Parent; |
|
711 |
|
712 NodesImpl(const Graph& graph, SmartUEdgeSet& edgeset) |
|
713 : Parent(graph), _edgeset(edgeset) {} |
|
714 |
|
715 virtual ~NodesImpl() {} |
|
716 |
|
717 bool attached() const { |
|
718 return Parent::attached(); |
|
719 } |
|
720 |
|
721 protected: |
|
722 |
|
723 virtual void erase(const Node& node) { |
|
724 try { |
|
725 _edgeset.eraseNode(node); |
|
726 Parent::erase(node); |
|
727 } catch (const typename NodesImplBase::Notifier::ImmediateDetach&) { |
|
728 Parent::clear(); |
|
729 throw; |
|
730 } |
|
731 } |
|
732 virtual void erase(const std::vector<Node>& nodes) { |
|
733 try { |
|
734 for (int i = 0; i < (int)nodes.size(); ++i) { |
|
735 _edgeset.eraseNode(nodes[i]); |
|
736 } |
|
737 Parent::erase(nodes); |
|
738 } catch (const typename NodesImplBase::Notifier::ImmediateDetach&) { |
|
739 Parent::clear(); |
|
740 throw; |
|
741 } |
|
742 } |
|
743 virtual void clear() { |
|
744 _edgeset.clearNodes(); |
|
745 Parent::clear(); |
|
746 } |
|
747 |
|
748 private: |
744 SmartUEdgeSet& _edgeset; |
749 SmartUEdgeSet& _edgeset; |
745 }; |
750 }; |
746 |
751 |
747 NodesImpl nodes; |
752 NodesImpl nodes; |
748 |
753 |