0

So I am writing a graph traversal routine and I would like to be able to turn it into either depth-first or breadth-first traversal by choosing a FIFO or a LIFO neighbor traversal policy. In practice this means that I need to abstract "enqueue" and "dequeue" operations over std::deque and std::vector (or stack).

This can be done easily enough by having a couple of template functions specialized for these containers. However, I am wondering: is there a canonical way to accomplish this in STL? Looks like I could use back_insert_iterator for "enqueue", but I didn't find a front_remove_iterator for "dequeue". Did I miss anything?

J. D.
  • 113
  • 13
user1411900
  • 384
  • 4
  • 14

1 Answers1

0

This already exists as std::stack and std::queue. Annoyingly the interface is not quite identical between them, but that can be fixed. That also gives the opportunity to fix the void pop() wart.

template <typename Traversal, typename T, typename Container>
struct GraphNeighbors;

template<typename T, typename Container=std::deque<T>>
struct GraphNeighbors<class FIFO, T, Container>
{
private:
    std::queue<T, Container> nodes;
public:
    T pop() 
    { 
         T elem = std::move(nodes.front()); 
         nodes.pop(); 
         return elem; 
    }
    void push(const T & elem)
    {
        nodes.push(elem);
    }
    void push(T&& elem)
        nodes.emplace(std::move(elem));
    }
};

template<typename T, typename Container=std::deque<T>>
struct GraphNeighbors<class LIFO, T, Container>
{
private:
    std::stack<T, Container> nodes;
public:
    T pop() 
    { 
         T elem = std::move(nodes.top()); 
         nodes.pop(); 
         return elem; 
    }
    void push(const T & elem)
    {
        nodes.push(elem);
    }
    void push(T&& elem)
        nodes.emplace(std::move(elem));
    }
};
Caleth
  • 52,200
  • 2
  • 44
  • 75