boostiteratorc++03boost-iterators

Custom Iterator using boost iterator


I've a custom data structure like following:

class Node;

class GraphDM {
public:
    GraphDM();
    // these are to iterate on all items of _faninNodes 
    // like all elements in multimap
    FaninIter  faninBegin(); 
    FaninIter  faninEnd();

    // these are to iterate on all items of _fanoutNodes
    FanoutIter fanoutBegin();
    FanoutIter fanoutEnd();

    // these should work like equal_range of multimap
    std::pair<FaninIter, FaninIter > getFanins (const Node *node_);
    std::pair<FaninIter, FaninIter > getFanouts(const Node *node_);

private:
    typedef std::vector< Node* > NodeList;
    typedef boost::unordered_map< Node*, 
                                  NodeList > Map;

    Map     _faninNodes;
    Map     _fanoutNodes;
};

I need to implement these APIs. How can I implement these using boost iterator library?

Also, I may need to take a Predicate to allow filtering

Some pointer to get started will be very helpful. One clarification: I cannot use c++0x compiler flags as I need to use c++98 only. So, please suggest a solution that doesn't need c++11 or c++03 compiler flag.

Also, if I design an iterator like following (nested in the GraphDM class), I'm essentially exposing details my data-structure. Is there a way to make the iterator to iterate only on the Key's of the map (and not the value)? Then I can return a different type of iterator for the getFanins() and getFanout() which would be iterator from the value list.

   class Iter : public boost::iterator_adaptor< Iter,
                                                 Map::iterator,
                                                 boost::use_default >
    {
    public:
        Iter() : Iter::iterator_adaptor_() {}


    private:
        friend class GraphDM;

        Iter(Map::iterator it)
                : Iter::iterator_adaptor_(it) {}

        friend class boost::iterator_core_access;

    };

Solution

  • I don't see any requirement in your text to be creating custom iterators. You can just typedef the iterators from the inner maps.

    Here, I fixed some things:

    Live On Coliru

    #include <utility>
    #include <boost/unordered_map.hpp>
    #include <vector>
    
    struct Node {};
    
    class GraphDM {
        typedef std::vector<Node const*> NodeList;
        typedef boost::unordered_map<Node const *, NodeList/*, boost::hash<Node const*>*/ > Id2NodeListMap;
    
      public:
        typedef Id2NodeListMap::const_iterator FaninIter;
        typedef Id2NodeListMap::const_iterator FanoutIter;
    
        GraphDM() {}
    
        FaninIter  faninBegin()  const;
        FaninIter  faninEnd()    const;
    
        FanoutIter fanoutBegin() const;
        FanoutIter fanoutEnd()   const;
    
        // these should work like equal_range of multimap
        std::pair<FaninIter, FaninIter> getFanins(Node const *node_) const;
        std::pair<FaninIter, FaninIter> getFanouts(Node const *node_) const;
    
      private:
        Id2NodeListMap _faninNodes;
        Id2NodeListMap _fanoutNodes;
    };
    
    GraphDM::FaninIter  GraphDM::faninBegin() const {
        return _faninNodes.begin();  
    }
    
    GraphDM::FaninIter  GraphDM::faninEnd()   const {
        return _faninNodes.end();
    }
    
    GraphDM::FanoutIter GraphDM::fanoutBegin() const {
        return _fanoutNodes.begin();
    }
    
    GraphDM::FanoutIter GraphDM::fanoutEnd()   const {
        return _fanoutNodes.end();
    }
    
    // these should work like equal_range of multimap
    std::pair<GraphDM::FaninIter, GraphDM::FaninIter> GraphDM::getFanins(Node const *node_) const {
        return _faninNodes.equal_range(node_);
    }
    std::pair<GraphDM::FaninIter, GraphDM::FaninIter> GraphDM::getFanouts(Node const *node_) const {
        return _fanoutNodes.equal_range(node_);
    }
    
    int main() {
        GraphDM demo;
    }