From: Giuseppe Ottaviano Date: Wed, 12 Oct 2016 04:12:59 +0000 (-0700) Subject: Add support in enumerate() for iterators with exotic pointers X-Git-Tag: v2016.10.17.00~13 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=1d2f2dcf9d7b52cbfea7260e7e4da8743bf5fc4b;p=folly.git Add support in enumerate() for iterators with exotic pointers Summary: I thought we wouldn't need this but it turns out Thrift Frozen2 iterators return proxies (it's proxies all the way down). Thanks to ericniebler for trick. Reviewed By: yfeldblum Differential Revision: D4005700 fbshipit-source-id: 1911996afa075c1d819a3aaea2ee924bc2ae2f20 --- diff --git a/folly/Enumerate.h b/folly/Enumerate.h index f4fb12be..28681487 100644 --- a/folly/Enumerate.h +++ b/folly/Enumerate.h @@ -60,6 +60,18 @@ struct MakeConst { using type = const T*; }; +// Raw pointers don't have an operator->() member function, so the +// second overload will be SFINAEd out in that case. Otherwise, the +// second is preferred in the partial order for getPointer(_, 0). +template +auto getPointer(const Iterator& it, long) -> decltype(std::addressof(*it)) { + return std::addressof(*it); +} +template +auto getPointer(const Iterator& it, int) -> decltype(it.operator->()) { + return it.operator->(); +} + template class Enumerator { public: @@ -80,7 +92,7 @@ class Enumerator { return *it_; } pointer operator->() { - return std::addressof(**this); + return getPointer(it_, 0); } // Const Proxy: Force const references. @@ -88,7 +100,7 @@ class Enumerator { return *it_; } typename MakeConst::type operator->() const { - return std::addressof(**this); + return getPointer(it_, 0); } private: