Commit 38c76b0d authored by Christos Stratopoulos's avatar Christos Stratopoulos Committed by Facebook Github Bot

Compatibility with VS2019 (#1182)

Summary:
Some changes to get Poly compiling with VS2019 (and correcting an oversight from https://github.com/facebook/folly/pull/1174)

The change to `detail/TypeList.h` is straightforward I think.

The introduction of `getOpsImpl` I find a bit distasteful...I will remark that as of Visual Studio 16.2.0 Preview 3.0 it is not necessary, but it is still needed on Visual Studio 16.1.5 (latest release, non preview).

Orvid in your comment [here](https://github.com/facebook/folly/pull/1178#issuecomment-506864383)  you mentioned the question of supporting VS 2017 or VS 2019 given that Poly had no MSVC support at all beforehand. I re-downloaded VS 2017 on my machine to test against the fixes added here and the situation seemed discouraging with lots more errors and perhaps less obvious workarounds.

I have not made any changes to the CMake stuff for Poly on MSVC: https://github.com/facebook/folly/blob/master/CMakeLists.txt#L235

I'm not sure if once we resolve the issue above we might want to add some logic maybe [here](https://github.com/facebook/folly/blob/master/CMakeLists.txt#L63) to handle which version of MSVC is approved for poly; will wait for further direction on that.
Pull Request resolved: https://github.com/facebook/folly/pull/1182

Reviewed By: Orvid

Differential Revision: D16109504

Pulled By: yfeldblum

fbshipit-source-id: d20b242494b075ce91452215c2025584fe488d65
parent f14a5668
...@@ -50,6 +50,12 @@ namespace folly { ...@@ -50,6 +50,12 @@ namespace folly {
template <class I> template <class I>
struct Poly; struct Poly;
// MSVC workaround
template <class Node, class Tfx, class Access>
struct PolySelf_ {
using type = decltype(Access::template self_<Node, Tfx>());
};
/** /**
* Within the definition of interface `I`, `PolySelf<Base>` is an alias for * Within the definition of interface `I`, `PolySelf<Base>` is an alias for
* the instance of `Poly` that is currently being instantiated. It is * the instance of `Poly` that is currently being instantiated. It is
...@@ -101,7 +107,7 @@ template < ...@@ -101,7 +107,7 @@ template <
class Node, class Node,
class Tfx = detail::MetaIdentity, class Tfx = detail::MetaIdentity,
class Access = detail::PolyAccess> class Access = detail::PolyAccess>
using PolySelf = decltype(Access::template self_<Node, Tfx>()); using PolySelf = _t<PolySelf_<Node, Tfx, Access>>;
/** /**
* When used in conjunction with `PolySelf`, controls how to construct `Poly` * When used in conjunction with `PolySelf`, controls how to construct `Poly`
...@@ -111,7 +117,7 @@ using PolySelf = decltype(Access::template self_<Node, Tfx>()); ...@@ -111,7 +117,7 @@ using PolySelf = decltype(Access::template self_<Node, Tfx>());
*/ */
using PolyDecay = detail::MetaQuote<std::decay_t>; using PolyDecay = detail::MetaQuote<std::decay_t>;
#if !defined(__cpp_template_auto) #if !FOLLY_POLY_NTTP_AUTO
/** /**
* Use `FOLLY_POLY_MEMBERS(MEMS...)` on pre-C++17 compilers to specify a * Use `FOLLY_POLY_MEMBERS(MEMS...)` on pre-C++17 compilers to specify a
......
...@@ -695,16 +695,21 @@ struct BasePtr { ...@@ -695,16 +695,21 @@ struct BasePtr {
VTable<I> const* vptr_; VTable<I> const* vptr_;
}; };
template <class I, class T, std::enable_if_t<inSitu<T>(), int> = 0> template <class I, class T>
constexpr void* (*getOps() noexcept)(Op, Data*, void*) { constexpr void* (*getOpsImpl(std::true_type) noexcept)(Op, Data*, void*) {
return &execInSitu<I, T>; return &execInSitu<I, T>;
} }
template <class I, class T, std::enable_if_t<!inSitu<T>(), int> = 0> template <class I, class T>
constexpr void* (*getOps() noexcept)(Op, Data*, void*) { constexpr void* (*getOpsImpl(std::false_type) noexcept)(Op, Data*, void*) {
return &execOnHeap<I, T>; return &execOnHeap<I, T>;
} }
template <class I, class T>
constexpr void* (*getOps() noexcept)(Op, Data*, void*) {
return getOpsImpl<I, T>(std::integral_constant<bool, inSitu<T>()>{});
}
template <class I, FOLLY_AUTO... Arch, class... S> template <class I, FOLLY_AUTO... Arch, class... S>
struct VTable<I, PolyMembers<Arch...>, TypeList<S...>> struct VTable<I, PolyMembers<Arch...>, TypeList<S...>>
: BasePtr<S>..., std::tuple<SignatureOf<Arch, I>...> { : BasePtr<S>..., std::tuple<SignatureOf<Arch, I>...> {
......
...@@ -168,8 +168,10 @@ using If = MetaApply<impl::If_<If_>, Then, Else>; ...@@ -168,8 +168,10 @@ using If = MetaApply<impl::If_<If_>, Then, Else>;
*/ */
template <template <class...> class C, class... Ts> template <template <class...> class C, class... Ts>
class MetaDefer { class MetaDefer {
template <template <class...> class D = C, class = D<Ts...>> template <template <class...> class D, class = D<Ts...>>
static char (&try_(int))[1]; static char (&try_(int))[1];
template <template <class...> class D, class = void>
static char (&try_(long))[2]; static char (&try_(long))[2];
struct Result { struct Result {
using type = C<Ts...>; using type = C<Ts...>;
...@@ -177,7 +179,7 @@ class MetaDefer { ...@@ -177,7 +179,7 @@ class MetaDefer {
public: public:
template <class... Us> template <class... Us>
using apply = _t<If<sizeof(try_(0)) - 1 || sizeof...(Us), Empty, Result>>; using apply = _t<If<sizeof(try_<C>(0)) - 1 || sizeof...(Us), Empty, Result>>;
}; };
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment