I have a class which has-a deque which it uses as a stack (could be a vector, just happened to choose deque).
At any rate, I wish to allow consumers to iterate over the contents of the stack (something that std::stack cannot do). I am currently using push_back() to push items onto the stack, and hence if one iterates over the contents in forward ordering, one goes from bottom to the top of the stack.
I would prefer to expose things in reverse order, so that iterating over the stack using for (auto e: thestack) works in top-down fashion.
I found C++11 reverse range-based for-loop which shows a couple of solutions for reversing the iteration ordering for the new for-loop syntax (as well as range-based algorithms).
What is unclear to me is how to provide a simple mechanic for giving my users access to this automatically reversed deque.
e.g. without any real effort, I can simply allow const& access to the underlying deque:
const std::deque<T> & GetStack() const { return m_stack; }
and consumers could be responsible for the reversing:
for (auto e : reverse(m_toolstack.GetStack()))
Here, I am attempting to use the following solution for reverse:
template<class Fwd>
struct reverser_generic
{
Fwd &fwd;
reverser_generic(Fwd& fwd_): fwd(fwd_) {}
typedef std::reverse_iterator<typename Fwd::iterator> reverse_iterator;
reverse_iterator begin() { return reverse_iterator(std::end(fwd)); }
reverse_iterator end() { return reverse_iterator(std::begin(fwd)); }
};
template<class Fwd>
struct reverser_special
{
Fwd &fwd;
reverser_special(Fwd& fwd) : fwd(fwd) { }
auto begin() -> decltype(fwd.rbegin()) { return fwd.rbegin(); }
auto end() -> decltype(fwd.rend()) { return fwd.rend(); }
};
template<class Fwd>
auto reverse_impl(Fwd& fwd, long) -> decltype(reverser_generic<Fwd>(fwd))
{
return reverser_generic<Fwd>(fwd);
}
template<class Fwd>
auto reverse_impl(Fwd& fwd, int) -> decltype(fwd.rbegin(), reverser_special<Fwd>(fwd))
{
return reverser_special<Fwd>(fwd);
}
template<class Fwd>
auto reverse(Fwd&& fwd) -> decltype(reverse_impl(fwd,int(0)))
{
static_assert(!(std::is_rvalue_reference<Fwd&&>::value), "Cannot pass an rvalue reference to reverse()");
return reverse_impl(fwd,int(0));
}
The above all compiles and runs correctly using VS2012 (thanks to Jive Dadson et. al. for that solution).
However, in my stack facade, I really want to simply always return the reverse of the underlying container, but I am unclear on how to do so in a sensible fashion:
auto GetContents() const -> decltype(reverse(m_stack)) { return reverse(m_stack); }
The above errors, indicating that m_stack is unknown. this->m_stack is equally unknown.
How might I go about returning the "whatever it is that is the reverse of my member m_stack"?
Note, once that is answered, I also need "How do I return the const & of whatever is the decltype of reverse(m_stack)?