From 1d2f2dcf9d7b52cbfea7260e7e4da8743bf5fc4b Mon Sep 17 00:00:00 2001 From: Giuseppe Ottaviano Date: Tue, 11 Oct 2016 21:12:59 -0700 Subject: [PATCH] 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 --- folly/Enumerate.h | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) 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: -- 2.34.1