Use hazptr_local and hazptr_array
[folly.git] / folly / Poly.h
1 /*
2  * Copyright 2017-present Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 // TODO: [x] "cast" from Poly<C&> to Poly<C&&>
18 // TODO: [ ] copy/move from Poly<C&>/Poly<C&&> to Poly<C>
19 // TODO: [ ] copy-on-write?
20 // TODO: [ ] down- and cross-casting? (Possible?)
21 // TODO: [ ] shared ownership? (Dubious.)
22 // TODO: [ ] can games be played with making the VTable a member of a struct
23 //           with strange alignment such that the address of the VTable can
24 //           be used to tell whether the object is stored in-situ or not?
25
26 #pragma once
27
28 #if defined(__GNUC__) && !defined(__clang__) && __GNUC__ < 5
29 #error Folly.Poly requires gcc-5 or greater
30 #endif
31
32 #include <cassert>
33 #include <new>
34 #include <type_traits>
35 #include <typeinfo>
36 #include <utility>
37
38 #include <folly/Assume.h>
39 #include <folly/CppAttributes.h>
40 #include <folly/Traits.h>
41 #include <folly/detail/TypeList.h>
42
43 #if !defined(__cpp_inline_variables)
44 #define FOLLY_INLINE_CONSTEXPR constexpr
45 #else
46 #define FOLLY_INLINE_CONSTEXPR inline constexpr
47 #endif
48
49 #include <folly/detail/PolyDetail.h>
50
51 namespace folly {
52 template <class I>
53 struct Poly;
54
55 /**
56  * Within the definition of interface `I`, `PolySelf<Base>` is an alias for
57  * the instance of `Poly` that is currently being instantiated. It is
58  * one of: `Poly<J>`, `Poly<J&&>`, `Poly<J&>`, or `Poly<J const&>`; where
59  * `J` is either `I` or some interface that extends `I`.
60  *
61  * It can be used within interface definitions to declare members that accept
62  * other `Poly` objects of the same type as `*this`.
63  *
64  * The first parameter may optionally be cv- and/or reference-qualified, in
65  * which case, the qualification is applies to the type of the interface in the
66  * resulting `Poly<>` instance. The second template parameter controls whether
67  * or not the interface is decayed before the cv-ref qualifiers of the first
68  * argument are applied. For example, given the following:
69  *
70  *     struct Foo {
71  *       template <class Base>
72  *       struct Interface : Base {
73  *         using A = PolySelf<Base>;
74  *         using B = PolySelf<Base &>;
75  *         using C = PolySelf<Base const &>;
76  *         using X = PolySelf<Base, PolyDecay>;
77  *         using Y = PolySelf<Base &, PolyDecay>;
78  *         using Z = PolySelf<Base const &, PolyDecay>;
79  *       };
80  *       // ...
81  *     };
82  *     struct Bar : PolyExtends<Foo> {
83  *       // ...
84  *     };
85  *
86  * Then for `Poly<Bar>`, the typedefs are aliases for the following types:
87  * - `A` is `Poly<Bar>`
88  * - `B` is `Poly<Bar &>`
89  * - `C` is `Poly<Bar const &>`
90  * - `X` is `Poly<Bar>`
91  * - `Y` is `Poly<Bar &>`
92  * - `Z` is `Poly<Bar const &>`
93  *
94  * And for `Poly<Bar &>`, the typedefs are aliases for the following types:
95  * - `A` is `Poly<Bar &>`
96  * - `B` is `Poly<Bar &>`
97  * - `C` is `Poly<Bar &>`
98  * - `X` is `Poly<Bar>`
99  * - `Y` is `Poly<Bar &>`
100  * - `Z` is `Poly<Bar const &>`
101  */
102 template <
103     class Node,
104     class Tfx = detail::MetaIdentity,
105     class Access = detail::PolyAccess>
106 using PolySelf = decltype(Access::template self_<Node, Tfx>());
107
108 /**
109  * When used in conjunction with `PolySelf`, controls how to construct `Poly`
110  * types related to the one currently being instantiated.
111  *
112  * \sa PolySelf
113  */
114 using PolyDecay = detail::MetaQuote<std::decay_t>;
115
116 #if !defined(__cpp_template_auto)
117
118 /**
119  * Use `FOLLY_POLY_MEMBERS(MEMS...)` on pre-C++17 compilers to specify a
120  * comma-separated list of member function bindings.
121  *
122  * For example:
123  *
124  *     struct IFooBar {
125  *       template <class Base>
126  *       struct Interface : Base {
127  *         int foo() const { return folly::poly_call<0>(*this); }
128  *         void bar() { folly::poly_call<1>(*this); }
129  *       };
130  *       template <class T>
131  *       using Members = FOLLY_POLY_MEMBERS(&T::foo, &T::bar);
132  *     };
133  */
134 #define FOLLY_POLY_MEMBERS(...)                     \
135   typename decltype(::folly::detail::deduceMembers( \
136       __VA_ARGS__))::template Members<__VA_ARGS__>
137
138 /**
139  * Use `FOLLY_POLY_MEMBER(SIG, MEM)` on pre-C++17 compilers to specify a member
140  * function binding that needs to be disambiguated because of overloads. `SIG`
141  * should the (possibly const-qualified) signature of the `MEM` member function
142  * pointer.
143  *
144  * For example:
145  *
146  *     struct IFoo {
147  *       template <class Base> struct Interface : Base {
148  *         int foo() const { return folly::poly_call<0>(*this); }
149  *       };
150  *       template <class T> using Members = FOLLY_POLY_MEMBERS(
151  *         // This works even if T::foo is overloaded:
152  *         FOLLY_POLY_MEMBER(int()const, &T::foo)
153  *       );
154  *     };
155  */
156 #define FOLLY_POLY_MEMBER(SIG, MEM) \
157   ::folly::detail::MemberDef<       \
158       ::folly::detail::Member<decltype(::folly::sig<SIG>(MEM)), MEM>>::value
159
160 /**
161  * A list of member function bindings.
162  */
163 template <class... Ts>
164 using PolyMembers = detail::TypeList<Ts...>;
165
166 #else
167 #define FOLLY_POLY_MEMBER(SIG, MEM) ::folly::sig<SIG>(MEM)
168 #define FOLLY_POLY_MEMBERS(...) ::folly::PolyMembers<__VA_ARGS__>
169
170 template <auto... Ps>
171 struct PolyMembers {};
172
173 #endif
174
175 /**
176  * Exception type that is thrown on invalid access of an empty `Poly` object.
177  */
178 struct BadPolyAccess : std::exception {
179   BadPolyAccess() = default;
180   char const* what() const noexcept override {
181     return "BadPolyAccess";
182   }
183 };
184
185 /**
186  * Exception type that is thrown when attempting to extract from a `Poly` a
187  * value of the wrong type.
188  */
189 struct BadPolyCast : std::bad_cast {
190   BadPolyCast() = default;
191   char const* what() const noexcept override {
192     return "BadPolyCast";
193   }
194 };
195
196 /**
197  * Used in the definition of a `Poly` interface to say that the current
198  * interface is an extension of a set of zero or more interfaces.
199  *
200  * Example:
201  *
202  *   struct IFoo {
203  *     template <class Base> struct Interface : Base {
204  *       void foo() { folly::poly_call<0>(*this); }
205  *     };
206  *     template <class T> using Members = FOLLY_POLY_MEMBERS(&T::foo);
207  *   }
208  *   struct IBar : PolyExtends<IFoo> {
209  *     template <class Base> struct Interface : Base {
210  *       void bar(int i) { folly::poly_call<0>(*this, i); }
211  *     };
212  *     template <class T> using Members = FOLLY_POLY_MEMBERS(&T::bar);
213  *   }
214  */
215 template <class... I>
216 struct PolyExtends : virtual I... {
217   using Subsumptions = detail::TypeList<I...>;
218
219   template <class Base>
220   struct Interface : Base {
221     Interface() = default;
222     using Base::Base;
223   };
224
225   template <class...>
226   using Members = PolyMembers<>;
227 };
228
229 ////////////////////////////////////////////////////////////////////////////////
230 /**
231  * Call the N-th member of the currently-being-defined interface. When the
232  * first parameter is an object of type `PolySelf<Base>` (as opposed to `*this`)
233  * you must explicitly specify which interface through which to dispatch.
234  * For instance:
235  *
236  *     struct IAddable {
237  *       template <class Base>
238  *       struct Interface : Base {
239  *         friend PolySelf<Base, Decay>
240  *         operator+(PolySelf<Base> const& a, PolySelf<Base> const& b) {
241  *           return folly::poly_call<0, IAddable>(a, b);
242  *         }
243  *       };
244  *       template <class T>
245  *       static auto plus_(T const& a, T const& b) -> decltype(a + b) {
246  *         return a + b;
247  *       }
248  *       template <class T>
249  *       using Members = FOLLY_POLY_MEMBERS(&plus_<std::decay_t<T>>);
250  *     };
251  *
252  * \sa PolySelf
253  */
254 template <std::size_t N, typename This, typename... As>
255 auto poly_call(This&& _this, As&&... as)
256     -> decltype(detail::PolyAccess::call<N>(
257         static_cast<This&&>(_this),
258         static_cast<As&&>(as)...)) {
259   return detail::PolyAccess::call<N>(
260       static_cast<This&&>(_this), static_cast<As&&>(as)...);
261 }
262
263 /// \overload
264 template <std::size_t N, class I, class Tail, typename... As>
265 decltype(auto) poly_call(detail::PolyNode<I, Tail>&& _this, As&&... as) {
266   using This = detail::InterfaceOf<I, detail::PolyNode<I, Tail>>;
267   return detail::PolyAccess::call<N>(
268       static_cast<This&&>(_this), static_cast<As&&>(as)...);
269 }
270
271 /// \overload
272 template <std::size_t N, class I, class Tail, typename... As>
273 decltype(auto) poly_call(detail::PolyNode<I, Tail>& _this, As&&... as) {
274   using This = detail::InterfaceOf<I, detail::PolyNode<I, Tail>>;
275   return detail::PolyAccess::call<N>(
276       static_cast<This&>(_this), static_cast<As&&>(as)...);
277 }
278
279 /// \overload
280 template <std::size_t N, class I, class Tail, typename... As>
281 decltype(auto) poly_call(detail::PolyNode<I, Tail> const& _this, As&&... as) {
282   using This = detail::InterfaceOf<I, detail::PolyNode<I, Tail>>;
283   return detail::PolyAccess::call<N>(
284       static_cast<This const&>(_this), static_cast<As&&>(as)...);
285 }
286
287 /// \overload
288 template <
289     std::size_t N,
290     class I,
291     class Poly,
292     typename... As,
293     std::enable_if_t<detail::IsPoly<Poly>::value, int> = 0>
294 auto poly_call(Poly&& _this, As&&... as) -> decltype(poly_call<N, I>(
295     static_cast<Poly&&>(_this).get(),
296     static_cast<As&&>(as)...)) {
297   return poly_call<N, I>(
298       static_cast<Poly&&>(_this).get(), static_cast<As&&>(as)...);
299 }
300
301 /// \cond
302 /// \overload
303 template <std::size_t N, class I, typename... As>
304 [[noreturn]] detail::Bottom poly_call(detail::ArchetypeBase const&, As&&...) {
305   assume_unreachable();
306 }
307 /// \endcond
308
309 ////////////////////////////////////////////////////////////////////////////////
310 /**
311  * Try to cast the `Poly` object to the requested type. If the `Poly` stores an
312  * object of that type, return a reference to the object; otherwise, throw an
313  * exception.
314  * \tparam T The (unqualified) type to which to cast the `Poly` object.
315  * \tparam Poly The type of the `Poly` object.
316  * \param that The `Poly` object to be cast.
317  * \return A reference to the `T` object stored in or refered to by `that`.
318  * \throw BadPolyAccess if `that` is empty.
319  * \throw BadPolyCast if `that` does not store or refer to an object of type
320  *        `T`.
321  */
322 template <class T, class I>
323 detail::AddCvrefOf<T, I>&& poly_cast(detail::PolyRoot<I>&& that) {
324   return detail::PolyAccess::cast<T>(std::move(that));
325 }
326
327 /// \overload
328 template <class T, class I>
329 detail::AddCvrefOf<T, I>& poly_cast(detail::PolyRoot<I>& that) {
330   return detail::PolyAccess::cast<T>(that);
331 }
332
333 /// \overload
334 template <class T, class I>
335 detail::AddCvrefOf<T, I> const& poly_cast(detail::PolyRoot<I> const& that) {
336   return detail::PolyAccess::cast<T>(that);
337 }
338
339 /// \cond
340 /// \overload
341 template <class T, class I>
342 [[noreturn]] detail::AddCvrefOf<T, I>&& poly_cast(detail::ArchetypeRoot<I>&&) {
343   assume_unreachable();
344 }
345
346 /// \overload
347 template <class T, class I>
348 [[noreturn]] detail::AddCvrefOf<T, I>& poly_cast(detail::ArchetypeRoot<I>&) {
349   assume_unreachable();
350 }
351
352 /// \overload
353 template <class T, class I>
354 [[noreturn]] detail::AddCvrefOf<T, I> const& poly_cast(
355     detail::ArchetypeRoot<I> const&) { assume_unreachable(); }
356 /// \endcond
357
358 /// \overload
359 template <
360     class T,
361     class Poly,
362     std::enable_if_t<detail::IsPoly<Poly>::value, int> = 0>
363 constexpr auto poly_cast(Poly&& that)
364     -> decltype(poly_cast<T>(std::declval<Poly>().get())) {
365   return poly_cast<T>(static_cast<Poly&&>(that).get());
366 }
367
368 ////////////////////////////////////////////////////////////////////////////////
369 /**
370  * Returns a reference to the `std::type_info` object corresponding to the
371  * object currently stored in `that`. If `that` is empty, returns
372  * `typeid(void)`.
373  */
374 template <class I>
375 std::type_info const& poly_type(detail::PolyRoot<I> const& that) noexcept {
376   return detail::PolyAccess::type(that);
377 }
378
379 /// \cond
380 /// \overload
381 [[noreturn]] inline std::type_info const& poly_type(
382     detail::ArchetypeBase const&) noexcept {
383   assume_unreachable();
384 }
385 /// \endcond
386
387 /// \overload
388 template <class Poly, std::enable_if_t<detail::IsPoly<Poly>::value, int> = 0>
389 constexpr auto poly_type(Poly const& that) noexcept
390     -> decltype(poly_type(that.get())) {
391   return poly_type(that.get());
392 }
393
394 ////////////////////////////////////////////////////////////////////////////////
395 /**
396  * Returns `true` if `that` is not currently storing an object; `false`,
397  * otherwise.
398  */
399 template <class I>
400 bool poly_empty(detail::PolyRoot<I> const& that) noexcept {
401   return detail::State::eEmpty == detail::PolyAccess::vtable(that)->state_;
402 }
403
404 /// \overload
405 template <class I>
406 constexpr bool poly_empty(detail::PolyRoot<I&&> const&) noexcept {
407   return false;
408 }
409
410 /// \overload
411 template <class I>
412 constexpr bool poly_empty(detail::PolyRoot<I&> const&) noexcept {
413   return false;
414 }
415
416 /// \overload
417 template <class I>
418 constexpr bool poly_empty(Poly<I&&> const&) noexcept {
419   return false;
420 }
421
422 /// \overload
423 template <class I>
424 constexpr bool poly_empty(Poly<I&> const&) noexcept {
425   return false;
426 }
427
428 /// \cond
429 [[noreturn]] inline bool poly_empty(detail::ArchetypeBase const&) noexcept {
430   assume_unreachable();
431 }
432 /// \endcond
433
434 ////////////////////////////////////////////////////////////////////////////////
435 /**
436  * Given a `Poly<I&>`, return a `Poly<I&&>`. Otherwise, when `I` is not a
437  * reference type, returns a `Poly<I>&&` when given a `Poly<I>&`, like
438  * `std::move`.
439  */
440 template <
441     class I,
442     std::enable_if_t<detail::Not<std::is_reference<I>>::value, int> = 0>
443 constexpr Poly<I>&& poly_move(detail::PolyRoot<I>& that) noexcept {
444   return static_cast<Poly<I>&&>(static_cast<Poly<I>&>(that));
445 }
446
447 /// \overload
448 template <
449     class I,
450     std::enable_if_t<detail::Not<std::is_const<I>>::value, int> = 0>
451 Poly<I&&> poly_move(detail::PolyRoot<I&> const& that) noexcept {
452   return detail::PolyAccess::move(that);
453 }
454
455 /// \overload
456 template <class I>
457 Poly<I const&> poly_move(detail::PolyRoot<I const&> const& that) noexcept {
458   return detail::PolyAccess::move(that);
459 }
460
461 /// \cond
462 /// \overload
463 [[noreturn]] inline detail::ArchetypeBase poly_move(
464     detail::ArchetypeBase const&) noexcept {
465   assume_unreachable();
466 }
467 /// \endcond
468
469 /// \overload
470 template <class Poly, std::enable_if_t<detail::IsPoly<Poly>::value, int> = 0>
471 constexpr auto poly_move(Poly& that) noexcept
472     -> decltype(poly_move(that.get())) {
473   return poly_move(that.get());
474 }
475
476 /// \cond
477 namespace detail {
478 /**
479  * The implementation for `Poly` for when the interface type is not
480  * reference-like qualified, as in `Poly<SemiRegular>`.
481  */
482 template <class I>
483 struct PolyVal : PolyImpl<I> {
484  private:
485   friend PolyAccess;
486
487   struct NoneSuch {};
488   using Copyable = std::is_copy_constructible<PolyImpl<I>>;
489   using PolyOrNonesuch = If<Copyable::value, PolyVal, NoneSuch>;
490
491   using PolyRoot<I>::vptr_;
492
493   PolyRoot<I>& _polyRoot_() noexcept {
494     return *this;
495   }
496   PolyRoot<I> const& _polyRoot_() const noexcept {
497     return *this;
498   }
499
500   Data* _data_() noexcept {
501     return PolyAccess::data(*this);
502   }
503   Data const* _data_() const noexcept {
504     return PolyAccess::data(*this);
505   }
506
507  public:
508   /**
509    * Default constructor.
510    * \post `poly_empty(*this) == true`
511    */
512   PolyVal() = default;
513   /**
514    * Move constructor.
515    * \post `poly_empty(that) == true`
516    */
517   PolyVal(PolyVal&& that) noexcept;
518   /**
519    * A copy constructor if `I` is copyable; otherwise, a useless constructor
520    * from a private, incomplete type.
521    */
522   /* implicit */ PolyVal(PolyOrNonesuch const& that);
523
524   ~PolyVal();
525
526   /**
527    * Inherit any constructors defined by any of the interfaces.
528    */
529   using PolyImpl<I>::PolyImpl;
530
531   /**
532    * Copy assignment, destroys the object currently held (if any) and makes
533    * `*this` equal to `that` by stealing its guts.
534    */
535   Poly<I>& operator=(PolyVal that) noexcept;
536
537   /**
538    * Construct a Poly<I> from a concrete type that satisfies the I concept
539    */
540   template <class T, std::enable_if_t<ModelsInterface<T, I>::value, int> = 0>
541   /* implicit */ PolyVal(T&& t);
542
543   /**
544    * Construct a `Poly` from a compatible `Poly`. "Compatible" here means: the
545    * other interface extends this one either directly or indirectly.
546    */
547   template <class I2, std::enable_if_t<ValueCompatible<I, I2>::value, int> = 0>
548   /* implicit */ PolyVal(Poly<I2> that);
549
550   /**
551    * Assign to this `Poly<I>` from a concrete type that satisfies the `I`
552    * concept.
553    */
554   template <class T, std::enable_if_t<ModelsInterface<T, I>::value, int> = 0>
555   Poly<I>& operator=(T&& t);
556
557   /**
558    * Assign a compatible `Poly` to `*this`. "Compatible" here means: the
559    * other interface extends this one either directly or indirectly.
560    */
561   template <class I2, std::enable_if_t<ValueCompatible<I, I2>::value, int> = 0>
562   Poly<I>& operator=(Poly<I2> that);
563
564   /**
565    * Swaps the values of two `Poly` objects.
566    */
567   void swap(Poly<I>& that) noexcept;
568 };
569
570 ////////////////////////////////////////////////////////////////////////////////
571 /**
572  * The implementation of `Poly` for when the interface type is
573  * reference-quelified, like `Poly<SemuRegular &>`.
574  */
575 template <class I>
576 struct PolyRef : private PolyImpl<I> {
577  private:
578   friend PolyAccess;
579
580   AddCvrefOf<PolyRoot<I>, I>& _polyRoot_() const noexcept;
581
582   Data* _data_() noexcept {
583     return PolyAccess::data(*this);
584   }
585   Data const* _data_() const noexcept {
586     return PolyAccess::data(*this);
587   }
588
589   static constexpr RefType refType() noexcept;
590
591  protected:
592   template <class That, class I2>
593   PolyRef(That&& that, Type<I2>);
594
595  public:
596   /**
597    * Copy constructor
598    * \post `&poly_cast<T>(*this) == &poly_cast<T>(that)`, where `T` is the
599    *       type of the object held by `that`.
600    */
601   PolyRef(PolyRef const& that) noexcept;
602
603   /**
604    * Copy assignment
605    * \post `&poly_cast<T>(*this) == &poly_cast<T>(that)`, where `T` is the
606    *       type of the object held by `that`.
607    */
608   Poly<I>& operator=(PolyRef const& that) noexcept;
609
610   /**
611    * Construct a `Poly<I>` from a concrete type that satisfies concept `I`.
612    * \post `!poly_empty(*this)`
613    */
614   template <class T, std::enable_if_t<ModelsInterface<T, I>::value, int> = 0>
615   /* implicit */ PolyRef(T&& t) noexcept;
616
617   /**
618    * Construct a `Poly<I>` from a compatible `Poly<I2>`.
619    */
620   template <
621       class I2,
622       std::enable_if_t<ReferenceCompatible<I, I2, I2&&>::value, int> = 0>
623   /* implicit */ PolyRef(Poly<I2>&& that) noexcept(
624       std::is_reference<I2>::value);
625
626   template <
627       class I2,
628       std::enable_if_t<ReferenceCompatible<I, I2, I2&>::value, int> = 0>
629   /* implicit */ PolyRef(Poly<I2>& that) noexcept(std::is_reference<I2>::value)
630       : PolyRef{that, Type<I2>{}} {}
631
632   template <
633       class I2,
634       std::enable_if_t<ReferenceCompatible<I, I2, I2 const&>::value, int> = 0>
635   /* implicit */ PolyRef(Poly<I2> const& that) noexcept(
636       std::is_reference<I2>::value)
637       : PolyRef{that, Type<I2>{}} {}
638
639   /**
640    * Assign to a `Poly<I>` from a concrete type that satisfies concept `I`.
641    * \post `!poly_empty(*this)`
642    */
643   template <class T, std::enable_if_t<ModelsInterface<T, I>::value, int> = 0>
644   Poly<I>& operator=(T&& t) noexcept;
645
646   /**
647    * Assign to `*this` from another compatible `Poly`.
648    */
649   template <
650       class I2,
651       std::enable_if_t<ReferenceCompatible<I, I2, I2&&>::value, int> = 0>
652   Poly<I>& operator=(Poly<I2>&& that) noexcept(std::is_reference<I2>::value);
653
654   /**
655    * \overload
656    */
657   template <
658       class I2,
659       std::enable_if_t<ReferenceCompatible<I, I2, I2&>::value, int> = 0>
660   Poly<I>& operator=(Poly<I2>& that) noexcept(std::is_reference<I2>::value);
661
662   /**
663    * \overload
664    */
665   template <
666       class I2,
667       std::enable_if_t<ReferenceCompatible<I, I2, I2 const&>::value, int> = 0>
668   Poly<I>& operator=(Poly<I2> const& that) noexcept(
669       std::is_reference<I2>::value);
670
671   /**
672    * Swap which object this `Poly` references ("shallow" swap).
673    */
674   void swap(Poly<I>& that) noexcept;
675
676   /**
677    * Get a reference to the interface, with correct `const`-ness applied.
678    */
679   AddCvrefOf<PolyImpl<I>, I>& get() const noexcept;
680
681   /**
682    * Get a reference to the interface, with correct `const`-ness applied.
683    */
684   AddCvrefOf<PolyImpl<I>, I>& operator*() const noexcept {
685     return get();
686   }
687
688   /**
689    * Get a pointer to the interface, with correct `const`-ness applied.
690    */
691   auto operator-> () const noexcept {
692     return &get();
693   }
694 };
695
696 template <class I>
697 using PolyValOrRef = If<std::is_reference<I>::value, PolyRef<I>, PolyVal<I>>;
698 } // namespace detail
699 /// \endcond
700
701 /**
702  * `Poly` is a class template that makes it relatively easy to define a
703  * type-erasing polymorphic object wrapper.
704  *
705  * \par Type-erasure
706  *
707  * \par
708  * `std::function` is one example of a type-erasing polymorphic object wrapper;
709  * `folly::exception_wrapper` is another. Type-erasure is often used as an
710  * alternative to dynamic polymorphism via inheritance-based virtual dispatch.
711  * The distinguishing characteristic of type-erasing wrappers are:
712  * \li **Duck typing:** Types do not need to inherit from an abstract base
713  *     class in order to be assignable to a type-erasing wrapper; they merely
714  *     need to satisfy a particular interface.
715  * \li **Value semantics:** Type-erasing wrappers are objects that can be
716  *     passed around _by value_. This is in contrast to abstract base classes
717  *     which must be passed by reference or by pointer or else suffer from
718  *     _slicing_, which causes them to lose their polymorphic behaviors.
719  *     Reference semantics make it difficult to reason locally about code.
720  * \li **Automatic memory management:** When dealing with inheritance-based
721  *     dynamic polymorphism, it is often necessary to allocate and manage
722  *     objects on the heap. This leads to a proliferation of `shared_ptr`s and
723  *     `unique_ptr`s in APIs, complicating their point-of-use. APIs that take
724  *     type-erasing wrappers, on the other hand, can often store small objects
725  *     in-situ, with no dynamic allocation. The memory management, if any, is
726  *     handled for you, and leads to cleaner APIs: consumers of your API don't
727  *     need to pass `shared_ptr<AbstractBase>`; they can simply pass any object
728  *     that satisfies the interface you require. (`std::function` is a
729  *     particularly compelling example of this benefit. Far worse would be an
730  *     inheritance-based callable solution like
731  *     `shared_ptr<ICallable<void(int)>>`. )
732  *
733  * \par Example: Defining a type-erasing function wrapper with `folly::Poly`
734  *
735  * \par
736  * Defining a polymorphic wrapper with `Poly` is a matter of defining two
737  * things:
738  * \li An *interface*, consisting of public member functions, and
739  * \li A *mapping* from a concrete type to a set of member function bindings.
740  *
741  * Below is a (heavily commented) example of a simple implementation of a
742  * `std::function`-like polymorphic wrapper. Its interface has only a simgle
743  * member function: `operator()`
744  *
745  *     // An interface for a callable object of a particular signature, Fun
746  *     // (most interfaces don't need to be templates, FWIW).
747  *     template <class Fun>
748  *     struct IFunction;
749  *
750  *     template <class R, class... As>
751  *     struct IFunction<R(As...)> {
752  *       // An interface is defined as a nested class template called
753  *       // Interface that takes a single template parameter, Base, from
754  *       // which it inherits.
755  *       template <class Base>
756  *       struct Interface : Base {
757  *         // The Interface has public member functions. These become the
758  *         // public interface of the resulting Poly instantiation.
759  *         // (Implementation note: Poly<IFunction<Sig>> will publicly
760  *         // inherit from this struct, which is what gives it the right
761  *         // member functions.)
762  *         R operator()(As... as) const {
763  *           // The definition of each member function in your interface will
764  *           // always consist of a single line dispatching to
765  *           // folly::poly_call<N>. The "N" corresponds to the N-th member
766  *           // function in the list of member function bindings, Members,
767  *           // defined below. The first argument will always be *this, and the
768  *           // rest of the arguments should simply forward (if necessary) the
769  *           // member function's arguments.
770  *           return static_cast<R>(
771  *               folly::poly_call<0>(*this, std::forward<As>(as)...));
772  *         }
773  *       };
774  *
775  *       // The "Members" alias template is a comma-separated list of bound
776  *       // member functions for a given concrete type "T". The
777  *       // "FOLLY_POLY_MEMBERS" macro accepts a comma-separated list, and the
778  *       // (optional) "FOLLY_POLY_MEMBER" macro lets you disambiguate overloads
779  *       // by explicitly specifying the function signature the target member
780  *       // function should have. In this case, we require "T" to have a
781  *       // function call operator with the signature `R(As...) const`.
782  *       //
783  *       // If you are using a C++17-compatible compiler, you can do away with
784  *       // the macros and write this as:
785  *       //
786  *       //   template <class T>
787  *       //   using Members = folly::PolyMembers<
788  *       //       folly::sig<R(As...) const>(&T::operator())>;
789  *       //
790  *       // And since `folly::sig` is only needed for disambiguation in case of
791  *       // overloads, if you are not concerned about objects with overloaded
792  *       // function call operators, it could be further simplified to:
793  *       //
794  *       //   template <class T>
795  *       //   using Members = folly::PolyMembers<&T::operator()>;
796  *       //
797  *       template <class T>
798  *       using Members = FOLLY_POLY_MEMBERS(
799  *           FOLLY_POLY_MEMBER(R(As...) const, &T::operator()));
800  *     };
801  *
802  *     // Now that we have defined the interface, we can pass it to Poly to
803  *     // create our type-erasing wrapper:
804  *     template <class Fun>
805  *     using Function = Poly<IFunction<Fun>>;
806  *
807  * \par
808  * Given the above definition of `Function`, users can now initialize instances
809  * of (say) `Function<int(int, int)>` with function objects like
810  * `std::plus<int>` and `std::multiplies<int>`, as below:
811  *
812  *     Function<int(int, int)> fun = std::plus<int>{};
813  *     assert(5 == fun(2, 3));
814  *     fun = std::multiplies<int>{};
815  *     assert(6 = fun(2, 3));
816  *
817  * \par Defining an interface with C++17
818  *
819  * \par
820  * With C++17, defining an interface to be used with `Poly` is fairly
821  * straightforward. As in the `Function` example above, there is a struct with
822  * a nested `Interface` class template and a nested `Members` alias template.
823  * No macros are needed with C++17.
824  * \par
825  * Imagine we were defining something like a Java-style iterator. If we are
826  * using a C++17 compiler, our interface would look something like this:
827  *
828  *     template <class Value>
829  *     struct IJavaIterator {
830  *       template <class Base>
831  *       struct Interface : Base {
832  *         bool Done() const { return folly::poly_call<0>(*this); }
833  *         Value Current() const { return folly::poly_call<1>(*this); }
834  *         void Next() { folly::poly_call<2>(*this); }
835  *       };
836  *       // NOTE: This works in C++17 only:
837  *       template <class T>
838  *       using Members = folly::PolyMembers<&T::Done, &T::Current, &T::Next>;
839  *     };
840  *
841  *     template <class Value>
842  *     using JavaIterator = Poly<IJavaIterator>;
843  *
844  * \par
845  * Given the above definition, `JavaIterator<int>` can be used to hold instances
846  * of any type that has `Done`, `Current`, and `Next` member functions with the
847  * correct (or compatible) signatures.
848  *
849  * \par
850  * The presence of overloaded member functions complicates this picture. Often,
851  * property members are faked in C++ with `const` and non-`const` member
852  * function overloads, like in the interface specified below:
853  *
854  *     struct IIntProperty {
855  *       template <class Base>
856  *       struct Interface : Base {
857  *         int Value() const { return folly::poly_call<0>(*this); }
858  *         void Value(int i) { folly::poly_call<1>(*this, i); }
859  *       };
860  *       // NOTE: This works in C++17 only:
861  *       template <class T>
862  *       using Members = folly::PolyMembers<
863  *         folly::sig<int() const>(&T::Value),
864  *         folly::sig<void(int)>(&T::Value)>;
865  *     };
866  *
867  *     using IntProperty = Poly<IIntProperty>;
868  *
869  * \par
870  * Now, any object that has `Value` members of compatible signatures can be
871  * assigned to instances of `IntProperty` object. Note how `folly::sig` is used
872  * to disambiguate the overloads of `&T::Value`.
873  *
874  * \par Defining an interface with C++14
875  *
876  * \par
877  * In C++14, the nice syntax above doesn't work, so we have to resort to macros.
878  * The two examples above would look like this:
879  *
880  *     template <class Value>
881  *     struct IJavaIterator {
882  *       template <class Base>
883  *       struct Interface : Base {
884  *         bool Done() const { return folly::poly_call<0>(*this); }
885  *         Value Current() const { return folly::poly_call<1>(*this); }
886  *         void Next() { folly::poly_call<2>(*this); }
887  *       };
888  *       // NOTE: This works in C++14 and C++17:
889  *       template <class T>
890  *       using Members = FOLLY_POLY_MEMBERS(&T::Done, &T::Current, &T::Next);
891  *     };
892  *
893  *     template <class Value>
894  *     using JavaIterator = Poly<IJavaIterator>;
895  *
896  * \par
897  * and
898  *
899  *     struct IIntProperty {
900  *       template <class Base>
901  *       struct Interface : Base {
902  *         int Value() const { return folly::poly_call<0>(*this); }
903  *         void Value(int i) { return folly::poly_call<1>(*this, i); }
904  *       };
905  *       // NOTE: This works in C++14 and C++17:
906  *       template <class T>
907  *       using Members = FOLLY_POLY_MEMBERS(
908  *         FOLLY_POLY_MEMBER(int() const, &T::Value),
909  *         FOLLY_POLY_MEMBER(void(int), &T::Value));
910  *     };
911  *
912  *     using IntProperty = Poly<IIntProperty>;
913  *
914  * \par Extending interfaces
915  *
916  * \par
917  * One typical advantage of inheritance-based solutions to runtime polymorphism
918  * is that one polymorphic interface could extend another through inheritance.
919  * The same can be accomplished with type-erasing polymorphic wrappers. In
920  * the `Poly` library, you can use `folly::PolyExtends` to say that one
921  * interface extends another.
922  *
923  *     struct IFoo {
924  *       template <class Base>
925  *       struct Interface : Base {
926  *         void Foo() const { return folly::poly_call<0>(*this); }
927  *       };
928  *       template <class T>
929  *       using Members = FOLLY_POLY_MEMBERS(&T::Foo);
930  *     };
931  *
932  *     // The IFooBar interface extends the IFoo interface
933  *     struct IFooBar : PolyExtends<IFoo> {
934  *       template <class Base>
935  *       struct Interface : Base {
936  *         void Bar() const { return folly::poly_call<0>(*this); }
937  *       };
938  *       template <class T>
939  *       using Members = FOLLY_POLY_MEMBERS(&T::Bar);
940  *     };
941  *
942  *     using FooBar = Poly<IFooBar>;
943  *
944  * \par
945  * Given the above defintion, instances of type `FooBar` have both `Foo()` and
946  * `Bar()` member functions.
947  *
948  * \par
949  * The sensible conversions exist between a wrapped derived type and a wrapped
950  * base type. For instance, assuming `IDerived` extends `IBase` with
951  * `PolyExtends`:
952  *
953  *     Poly<IDerived> derived = ...;
954  *     Poly<IBase> base = derived; // This conversion is OK.
955  *
956  * \par
957  * As you would expect, there is no conversion in the other direction, and at
958  * present there is no `Poly` equivalent to `dynamic_cast`.
959  *
960  * \par Type-erasing polymorphic reference wrappers
961  *
962  * \par
963  * Sometimes you don't need to own a copy of an object; a reference will do. For
964  * that you can use `Poly` to capture a _reference_ to an object satisfying an
965  * interface rather than the whole object itself. The syntax is intuitive.
966  *
967  *     int i = 42;
968  *     // Capture a mutable reference to an object of any IRegular type:
969  *     Poly<IRegular &> intRef = i;
970  *     assert(42 == folly::poly_cast<int>(intRef));
971  *     // Assert that we captured the address of "i":
972  *     assert(&i == &folly::poly_cast<int>(intRef));
973  *
974  * \par
975  * A reference-like `Poly` has a different interface than a value-like `Poly`.
976  * Rather than calling member functions with the `obj.fun()` syntax, you would
977  * use the `obj->fun()` syntax. This is for the sake of `const`-correctness.
978  * For example, consider the code below:
979  *
980  *     struct IFoo {
981  *       template <class Base>
982  *       struct Interface {
983  *         void Foo() { folly::poly_call<0>(*this); }
984  *       };
985  *       template <class T>
986  *       using Members = folly::PolyMembers<&T::Foo>;
987  *     };
988  *
989  *     struct SomeFoo {
990  *       void Foo() { std::printf("SomeFoo::Foo\n"); }
991  *     };
992  *
993  *     SomeFoo foo;
994  *     Poly<IFoo &> const anyFoo = foo;
995  *     anyFoo->Foo(); // prints "SomeFoo::Foo"
996  *
997  * \par
998  * Notice in the above code that the `Foo` member function is non-`const`.
999  * Notice also that the `anyFoo` object is `const`. However, since it has
1000  * captured a non-`const` reference to the `foo` object, it should still be
1001  * possible to dispatch to the non-`const` `Foo` member function. When
1002  * instantiated with a reference type, `Poly` has an overloaded `operator->`
1003  * member that returns a pointer to the `IFoo` interface with the correct
1004  * `const`-ness, which makes this work.
1005  *
1006  * \par
1007  * The same mechanism also prevents users from calling non-`const` member
1008  * functions on `Poly` objects that have captured `const` references, which
1009  * would violate `const`-correctness.
1010  *
1011  * \par
1012  * Sensible conversions exist between non-reference and reference `Poly`s. For
1013  * instance:
1014  *
1015  *     Poly<IRegular> value = 42;
1016  *     Poly<IRegular &> mutable_ref = value;
1017  *     Poly<IRegular const &> const_ref = mutable_ref;
1018  *
1019  *     assert(&poly_cast<int>(value) == &poly_cast<int>(mutable_ref));
1020  *     assert(&poly_cast<int>(value) == &poly_cast<int>(const_ref));
1021  *
1022  * \par Non-member functions (C++17)
1023  *
1024  * \par
1025  * If you wanted to write the interface `ILogicallyNegatable`, which captures
1026  * all types that can be negated with unary `operator!`, you could do it
1027  * as we've shown above, by binding `&T::operator!` in the nested `Members`
1028  * alias template, but that has the problem that it won't work for types that
1029  * have defined unary `operator!` as a free function. To handle this case,
1030  * the `Poly` library lets you use a free function instead of a member function
1031  * when creating a binding.
1032  *
1033  * \par
1034  * With C++17 you may use a lambda to create a binding, as shown in the example
1035  * below:
1036  *
1037  *     struct ILogicallyNegatable {
1038  *       template <class Base>
1039  *       struct Interface : Base {
1040  *         bool operator!() const { return folly::poly_call<0>(*this); }
1041  *       };
1042  *       template <class T>
1043  *       using Members = folly::PolyMembers<
1044  *         +[](T const& t) -> decltype(!t) { return !t; }>;
1045  *     };
1046  *
1047  * \par
1048  * This requires some explanation. The unary `operator+` in front of the lambda
1049  * is necessary! It causes the lambda to decay to a C-style function pointer,
1050  * which is one of the types that `folly::PolyMembers` accepts. The `decltype`
1051  * in the lambda return type is also necessary. Through the magic of SFINAE, it
1052  * will cause `Poly<ILogicallyNegatable>` to reject any types that don't support
1053  * unary `operator!`.
1054  *
1055  * \par
1056  * If you are using a free function to create a binding, the first parameter is
1057  * implicitly the `this` parameter. It will receive the type-erased object.
1058  *
1059  * \par Non-member functions (C++14)
1060  *
1061  * \par
1062  * If you are using a C++14 compiler, the defintion of `ILogicallyNegatable`
1063  * above will fail because lambdas are not `constexpr`. We can get the same
1064  * effect by writing the lambda as a named free function, as show below:
1065  *
1066  *     struct ILogicallyNegatable {
1067  *       template <class Base>
1068  *       struct Interface : Base {
1069  *         bool operator!() const { return folly::poly_call<0>(*this); }
1070  *       };
1071  *
1072  *       template <class T>
1073  *       static auto negate(T const& t) -> decltype(!t) { return !t; }
1074  *
1075  *       template <class T>
1076  *       using Members = FOLLY_POLY_MEMBERS(&negate<T>);
1077  *     };
1078  *
1079  * \par
1080  * As with the example that uses the lambda in the preceding section, the first
1081  * parameter is implicitly the `this` parameter. It will receive the type-erased
1082  * object.
1083  *
1084  * \par Multi-dispatch
1085  *
1086  * \par
1087  * What if you want to create an `IAddable` interface for things that can be
1088  * added? Adding requires _two_ objects, both of which are type-erased. This
1089  * interface requires dispatching on both objects, doing the addition only
1090  * if the types are the same. For this we make use of the `PolySelf` template
1091  * alias to define an interface that takes more than one object of the the
1092  * erased type.
1093  *
1094  *     struct IAddable {
1095  *       template <class Base>
1096  *       struct Interface : Base {
1097  *         friend PolySelf<Base, Decay>
1098  *         operator+(PolySelf<Base> const& a, PolySelf<Base> const& b) {
1099  *           return folly::poly_call<0, IAddable>(a, b);
1100  *         }
1101  *       };
1102  *
1103  *       template <class T>
1104  *       using Members = folly::PolyMembers<
1105  *         +[](T const& a, T const& b) -> decltype(a + b) { return a + b; }>;
1106  *     };
1107  *
1108  * \par
1109  * Given the above defintion of `IAddable` we would be able to do the following:
1110  *
1111  *     Poly<IAddable> a = 2, b = 3;
1112  *     Poly<IAddable> c = a + b;
1113  *     assert(poly_cast<int>(c) == 5);
1114  *
1115  * \par
1116  * If `a` and `b` stored objects of different types, a `BadPolyCast` exception
1117  * would be thrown.
1118  *
1119  * \par Move-only types
1120  *
1121  * \par
1122  * If you want to store move-only types, then your interface should extend the
1123  * `IMoveOnly` interface.
1124  *
1125  * \par Implementation notes
1126  * \par
1127  * `Poly` will store "small" objects in an internal buffer, avoiding the cost of
1128  * of dynamic allocations. At present, this size is not configurable; it is
1129  * pegged at the size of two `double`s.
1130  *
1131  * \par
1132  * `Poly` objects are always nothrow movable. If you store an object in one that
1133  * has a potentially throwing move contructor, the object will be stored on the
1134  * heap, even if it could fit in the internal storage of the `Poly` object.
1135  * (So be sure to give your objects nothrow move constructors!)
1136  *
1137  * \par
1138  * `Poly` implements type-erasure in a manner very similar to how the compiler
1139  * accomplishes virtual dispatch. Every `Poly` object contains a pointer to a
1140  * table of function pointers. Member function calls involve a double-
1141  * indirection: once through the v-pointer, and other indirect function call
1142  * through the function pointer.
1143  */
1144 template <class I>
1145 struct Poly final : detail::PolyValOrRef<I> {
1146   friend detail::PolyAccess;
1147   Poly() = default;
1148   using detail::PolyValOrRef<I>::PolyValOrRef;
1149   using detail::PolyValOrRef<I>::operator=;
1150 };
1151
1152 /**
1153  * Swap two `Poly<I>` instances.
1154  */
1155 template <class I>
1156 void swap(Poly<I>& left, Poly<I>& right) noexcept {
1157   left.swap(right);
1158 }
1159
1160 /**
1161  * Pseudo-function template handy for disambiguating function overloads.
1162  *
1163  * For example, given:
1164  *     struct S {
1165  *       int property() const;
1166  *       void property(int);
1167  *     };
1168  *
1169  * You can get a member function pointer to the first overload with:
1170  *     folly::sig<int()const>(&S::property);
1171  *
1172  * This is arguably a nicer syntax that using the built-in `static_cast`:
1173  *     static_cast<int (S::*)() const>(&S::property);
1174  *
1175  * `sig` is also more permissive than `static_cast` about `const`. For instance,
1176  * the following also works:
1177  *     folly::sig<int()>(&S::property);
1178  *
1179  * The above is permitted
1180  */
1181 template <class Sig>
1182 FOLLY_INLINE_CONSTEXPR detail::Sig<Sig> const sig = {};
1183
1184 } // namespace folly
1185
1186 #include <folly/Poly-inl.h>
1187
1188 #undef FOLLY_INLINE_CONSTEXPR