22 #include <type_traits> 40 using RRef_ = MetaQuoteTrait<std::add_rvalue_reference>;
41 using LRef_ = MetaQuoteTrait<std::add_lvalue_reference>;
44 struct XRef_ :
Type<MetaQuoteTrait<Type>> {};
46 using XRef = _t<XRef_<T>>;
48 struct XRef_<
T&&> : Type<MetaCompose<RRef_, XRef<T>>> {};
50 struct XRef_<
T&> : Type<MetaCompose<LRef_, XRef<T>>> {};
52 struct XRef_<
T const> :
Type<MetaQuoteTrait<std::add_const>> {};
54 template <
class A,
class B>
55 using AddCvrefOf = MetaApply<XRef<B>,
A>;
62 template <
class T,
class I>
63 detail::AddCvrefOf<T, I>&
poly_cast(detail::PolyRoot<I>&);
65 template <
class T,
class I>
66 detail::AddCvrefOf<T, I>
const&
poly_cast(detail::PolyRoot<I>
const&);
68 #if !defined(__cpp_template_auto) 69 #define FOLLY_AUTO class 70 template <
class... Ts>
73 #define FOLLY_AUTO auto 184 using Uncvref = std::remove_cv_t<std::remove_reference_t<T>>;
186 template <
class T,
template <
class...>
class U>
189 template <
class... Ts,
template <
class...>
class U>
197 static constexpr
T value{};
203 template <
class Then>
208 template <
class Then>
211 template <
class Then,
class Else>
216 template <
class Then,
class Else>
221 enum class Op : short { eNuke, eMove, eCopy, eType, eAddr, eRefr };
223 enum class RefType : std::uintptr_t { eRvalue, eLvalue, eConstLvalue };
236 using IsPoly = IsInstanceOf<Uncvref<T>,
Poly>;
241 template <
class I,
class T>
242 using MembersOf =
typename I::template Members<Uncvref<T>>;
246 template <
class I,
class T>
249 #if !defined(__cpp_template_auto) 250 template <
class T, T V>
251 using Member = std::integral_constant<T, V>;
257 inline constexpr MemberType<M> memberValue()
noexcept {
261 template <
class... Ts>
267 template <
class... Ts>
268 MakeMembers<Ts...> deduceMembers(Ts...);
270 template <
class Member,
class = MemberType<Member>>
273 template <
class Member,
class R,
class D,
class... As>
274 struct MemberDef<Member, R (D::*)(As...)> {
275 static R
value(D& d, As...
as) {
276 return folly::invoke(memberValue<Member>(), d, static_cast<As&&>(
as)...);
280 template <
class Member,
class R,
class D,
class... As>
281 struct MemberDef<Member, R (D::*)(As...)
const> {
282 static R
value(D
const& d, As...
as) {
283 return folly::invoke(memberValue<Member>(), d, static_cast<As&&>(
as)...);
292 inline constexpr MemberType<M> memberValue()
noexcept {
299 template <
class I,
class =
void>
300 struct SubsumptionsOf_ {
308 struct SubsumptionsOf_<I, void_t<typename I::Subsumptions>> {
310 typename I::Subsumptions,
319 [[noreturn]]
operator T &&()
const {
327 struct ArchetypeRoot;
333 struct ArchetypeBase : Bottom {
334 ArchetypeBase() =
default;
337 template <std::size_t,
class... As>
338 [[noreturn]] Bottom _polyCall_(As&&...)
const {
342 friend bool operator==(ArchetypeBase
const&, ArchetypeBase
const&);
343 friend bool operator!=(ArchetypeBase
const&, ArchetypeBase
const&);
344 friend bool operator<(ArchetypeBase
const&, ArchetypeBase
const&);
345 friend bool operator<=(ArchetypeBase
const&, ArchetypeBase
const&);
346 friend bool operator>(ArchetypeBase
const&, ArchetypeBase
const&);
347 friend bool operator>=(ArchetypeBase
const&, ArchetypeBase
const&);
348 friend Bottom operator++(ArchetypeBase
const&);
349 friend Bottom operator++(ArchetypeBase
const&,
int);
350 friend Bottom operator--(ArchetypeBase
const&);
351 friend Bottom operator--(ArchetypeBase
const&,
int);
352 friend Bottom
operator+(ArchetypeBase
const&, ArchetypeBase
const&);
353 friend Bottom
operator+=(ArchetypeBase
const&, ArchetypeBase
const&);
354 friend Bottom
operator-(ArchetypeBase
const&, ArchetypeBase
const&);
355 friend Bottom
operator-=(ArchetypeBase
const&, ArchetypeBase
const&);
356 friend Bottom operator*(ArchetypeBase
const&, ArchetypeBase
const&);
357 friend Bottom operator*=(ArchetypeBase
const&, ArchetypeBase
const&);
358 friend Bottom operator/(ArchetypeBase
const&, ArchetypeBase
const&);
359 friend Bottom operator/=(ArchetypeBase
const&, ArchetypeBase
const&);
360 friend Bottom operator%(ArchetypeBase
const&, ArchetypeBase
const&);
361 friend Bottom operator%=(ArchetypeBase
const&, ArchetypeBase
const&);
362 friend Bottom
operator<<(ArchetypeBase
const&, ArchetypeBase
const&);
363 friend Bottom operator<<=(ArchetypeBase
const&, ArchetypeBase
const&);
364 friend Bottom
operator>>(ArchetypeBase
const&, ArchetypeBase
const&);
365 friend Bottom operator>>=(ArchetypeBase
const&, ArchetypeBase
const&);
369 struct ArchetypeRoot : ArchetypeBase {
370 template <
class Node,
class Tfx>
371 using _polySelf_ = Archetype<AddCvrefOf<MetaApply<Tfx, I>,
Node>>;
372 using _polyInterface_ = I;
383 void* pobj_ =
nullptr;
384 std::aligned_storage_t<sizeof(double[2])> buff_;
388 template <
class U,
class I>
394 template <
class U,
class I>
397 AddCvrefOf<Poly<I>, U>,
400 template <
class Member,
class I>
403 template <
class R,
class C,
class... As,
class I>
404 struct SignatureOf_<R (C::*)(As...), I> {
405 using type = Ret<R, I> (*)(
Data&, Arg<As, I>...);
408 template <
class R,
class C,
class... As,
class I>
409 struct SignatureOf_<R (C::*)(As...)
const, I> {
410 using type = Ret<R, I> (*)(
Data const&, Arg<As, I>...);
413 template <
class R,
class This,
class... As,
class I>
414 struct SignatureOf_<R (*)(This&, As...), I> {
415 using type = Ret<R, I> (*)(
Data&, Arg<As, I>...);
418 template <
class R,
class This,
class... As,
class I>
419 struct SignatureOf_<R (*)(This
const&, As...), I> {
420 using type = Ret<R, I> (*)(
Data const&, Arg<As, I>...);
423 template <FOLLY_AUTO Arch,
class I>
426 template <FOLLY_AUTO User,
class I,
class Sig = SignatureOf<User, I>>
430 struct ArgTypes_<User, I, Ret (*)(Data,
Args...)> {
434 template <FOLLY_AUTO User,
class I>
437 template <
class R,
class...
Args>
438 using FnPtr = R (*)(
Args...);
441 template <
class R,
class...
Args>
445 throw_exception<BadPolyAccess>();
452 inline constexpr ThrowThunk throw_()
noexcept {
457 inline constexpr
bool inSitu()
noexcept {
459 sizeof(std::decay_t<T>) <=
sizeof(Data) &&
460 std::is_nothrow_move_constructible<std::decay_t<T>>
::value;
466 return *(std::add_pointer_t<T>)static_cast<void*>(&d.buff_);
468 return *
static_cast<std::add_pointer_t<T>
>(d.pobj_);
475 return *(std::add_pointer_t<T const>)static_cast<void const*>(&d.buff_);
477 return *
static_cast<std::add_pointer_t<T const>
>(d.pobj_);
481 enum class State : short { eEmpty, eInSitu, eOnHeap };
489 template <
class Arg,
class U>
490 decltype(
auto) convert(U&& u) {
491 return detail::if_constexpr(
493 IsPolyRef<Uncvref<U>>,
494 Negation<std::is_convertible<U, Arg>>>(),
495 [&](
auto id) -> decltype(
auto) {
496 return poly_cast<Uncvref<Arg>>(id(u).get());
498 [&](
auto id) -> U&& {
return static_cast<U&&
>(id(u)); });
504 template <
class R,
class C,
class... As>
507 template <
class R,
class C,
class... As>
514 class = ArgTypes<User, I>,
517 template <
class R,
class D,
class... As>
518 constexpr
operator FnPtr<R, D&, As...>()
const noexcept {
530 !std::
is_const<std::remove_reference_t<T>>::value ||
531 IsConstMember<MemberType<User>>::value>> {
532 template <
class R,
class D,
class... As>
533 constexpr
operator FnPtr<R, D&, As...>()
const noexcept {
535 static R
call(D& d, As...
as) {
539 convert<Args>(static_cast<As&&>(
as))...);
548 class = MembersOf<I, Archetype<I>>,
549 class = SubsumptionsOf<I>>
552 template <
class T, FOLLY_AUTO User,
class I>
553 inline constexpr ThunkFn<T, User, I> thunk()
noexcept {
554 return ThunkFn<T, User, I>{};
558 constexpr VTable<I>
const* vtable()
noexcept {
559 return &StaticConst<VTable<I>>
::value;
562 template <
class I,
class T>
563 struct VTableFor : VTable<I> {
567 template <
class I,
class T>
568 constexpr VTable<I>
const* vtableFor()
noexcept {
569 return &StaticConst<VTableFor<I, T>>
::value;
572 template <
class I,
class T>
573 constexpr
void* vtableForRef(RefType ref) {
575 case RefType::eRvalue:
576 return const_cast<VTable<I>*
>(vtableFor<I, T&&>());
577 case RefType::eLvalue:
578 return const_cast<VTable<I>*
>(vtableFor<I, T&>());
579 case RefType::eConstLvalue:
580 return const_cast<VTable<I>*
>(vtableFor<I, T const&>());
589 void* execOnHeap(
Op op, Data*
from,
void*
to) {
595 static_cast<Data*
>(
to)->pobj_ = from->pobj_;
598 return const_cast<void*>(static_cast<void const*>(&
typeid(T)));
600 if (*static_cast<std::type_info const*>(to) ==
typeid(
T)) {
603 throw_exception<BadPolyCast>();
605 return vtableForRef<I, Uncvref<T>>(
606 static_cast<RefType
>(
reinterpret_cast<std::uintptr_t
>(
to)));
614 std::enable_if_t<Not<std::is_reference<T>>
::value,
int> = 0>
615 void* execOnHeap(
Op op, Data* from,
void* to) {
618 delete &get<T>(*from);
624 detail::if_constexpr(std::is_copy_constructible<T>(), [&](
auto id) {
625 static_cast<Data*
>(
to)->pobj_ =
new T(
id(get<T>(*from)));
629 return const_cast<void*
>(
static_cast<void const*
>(&
typeid(
T)));
631 if (*static_cast<std::type_info const*>(to) ==
typeid(
T)) {
634 throw_exception<BadPolyCast>();
636 return vtableForRef<I, Uncvref<T>>(
637 static_cast<RefType
>(
reinterpret_cast<std::uintptr_t
>(
to)));
642 template <
class I,
class T>
643 void* execInSitu(
Op op, Data* from,
void* to) {
649 ::new (static_cast<void*>(&static_cast<Data*>(to)->buff_))
654 detail::if_constexpr(std::is_copy_constructible<T>(), [&](
auto id) {
655 ::new (static_cast<void*>(&static_cast<Data*>(to)->buff_))
656 T(
id(get<T>(*from)));
660 return const_cast<void*
>(
static_cast<void const*
>(&
typeid(
T)));
662 if (*static_cast<std::type_info const*>(to) ==
typeid(
T)) {
665 throw_exception<BadPolyCast>();
667 return vtableForRef<I, Uncvref<T>>(
668 static_cast<RefType
>(
reinterpret_cast<std::uintptr_t
>(
to)));
673 inline void* noopExec(
Op op, Data*,
void*) {
675 throw_exception<BadPolyAccess>();
676 return const_cast<void*
>(
static_cast<void const*
>(&
typeid(void)));
681 VTable<I>
const* vptr_;
684 template <
class I,
class T, std::enable_if_t<inSitu<T>(),
int> = 0>
685 constexpr
void* (*getOps()
noexcept)(
Op, Data*,
void*) {
686 return &execInSitu<I, T>;
689 template <
class I,
class T, std::enable_if_t<!inSitu<T>(),
int> = 0>
690 constexpr
void* (*getOps()
noexcept)(
Op, Data*,
void*) {
691 return &execOnHeap<I, T>;
694 template <
class I,
FOLLY_AUTO... Arch,
class... S>
695 struct VTable<I, PolyMembers<Arch...>, TypeList<S...>>
696 : BasePtr<S>..., std::tuple<SignatureOf<Arch, I>...> {
700 : BasePtr<S>{vtableFor<S, T>()}...,
701 std::tuple<SignatureOf<Arch, I>...>{thunk<T, User, I>()...},
702 state_{inSitu<T>() ? State::eInSitu : State::eOnHeap},
703 ops_{getOps<I, T>()} {}
707 : BasePtr<S>{vtable<S>()}...,
708 std::tuple<SignatureOf<Arch, I>...>{
709 static_cast<SignatureOf<Arch, I>
>(throw_())...},
710 state_{State::eEmpty},
715 : VTable{
Type<T>{}, MembersOf<I, T>{}} {}
718 void* (*ops_)(
Op, Data*,
void*);
732 template <std::size_t N,
typename This,
typename... As>
733 static auto call(This&& _this, As&&... args)
734 -> decltype(static_cast<This&&>(_this).
template _polyCall_<N>(
735 static_cast<As&&>(args)...)) {
737 !IsInstanceOf<std::decay_t<This>, Poly>::
value,
738 "When passing a Poly<> object to call(), you must explicitly " 739 "say which Interface to dispatch to, as in " 740 "call<0, MyInterface>(self, args...)");
741 return static_cast<This&&
>(_this).
template _polyCall_<N>(
742 static_cast<As&&>(args)...);
745 template <
class Poly>
746 using Iface =
typename Uncvref<Poly>::_polyInterface_;
748 template <
class Node,
class Tfx = MetaIdentity>
749 static typename Uncvref<Node>::template _polySelf_<Node, Tfx> self_();
751 template <
class T,
class Poly,
class I = Iface<Poly>>
752 static decltype(
auto) cast(Poly&& _this) {
753 using Ret = AddCvrefOf<AddCvrefOf<T, I>, Poly&&>;
754 return static_cast<Ret
>(
755 *
static_cast<std::add_pointer_t<Ret>
>(_this.vptr_->ops_(
757 const_cast<Data*>(static_cast<Data const*>(&_this)),
758 const_cast<void*>(static_cast<void const*>(&
typeid(T))))));
761 template <
class Poly>
762 static decltype(
auto) root(Poly&& _this)
noexcept {
763 return static_cast<Poly&&
>(_this)._polyRoot_();
767 static std::type_info
const&
type(PolyRoot<I>
const& _this)
noexcept {
768 return *
static_cast<std::type_info
const*
>(
769 _this.vptr_->ops_(Op::eType,
nullptr,
nullptr));
773 static VTable<Uncvref<I>>
const* vtable(PolyRoot<I>
const& _this)
noexcept {
783 static Data
const*
data(PolyRoot<I>
const& _this)
noexcept {
798 template <
class I,
class Tail>
799 struct PolyNode : Tail {
804 template <std::size_t K,
typename... As>
805 decltype(
auto) _polyCall_(As&&...
as) {
806 return std::get<K>(select<I>(*PolyAccess::vtable(*
this)))(
809 template <std::size_t K,
typename... As>
810 decltype(
auto) _polyCall_(As&&...
as)
const {
811 return std::get<K>(select<I>(*PolyAccess::vtable(*
this)))(
816 struct MakePolyNode {
817 template <
class I,
class State>
818 using apply = InterfaceOf<I, PolyNode<I, State>>;
822 struct PolyRoot :
private PolyBase,
private Data {
827 template <
class Node,
class Tfx>
829 using _polyInterface_ = I;
835 PolyRoot
const& _polyRoot_()
const noexcept {
838 VTable<std::decay_t<I>>
const* vptr_ = vtable<std::decay_t<I>>();
850 constexpr Fun T::*operator()(Fun T::*
t)
const volatile noexcept {
853 template <
class F,
class T>
854 constexpr F T::*operator()(F T::*t)
const volatile noexcept {
862 struct Sig<R()> : Sig<R() const> {
864 using Sig<R() const>::operator();
867 constexpr Fun T::*operator()(Fun T::*
t)
const noexcept {
872 template <
class R,
class... As>
873 struct SigImpl : Sig<R(As...) const> {
874 using Fun = R(As...);
875 using Sig<R(As...)
const>::operator();
878 constexpr Fun T::*operator()(Fun T::*
t)
const noexcept {
881 constexpr Fun* operator()(Fun* t)
const noexcept {
885 constexpr F* operator()(F* t)
const noexcept {
891 template <
class R,
class... As>
892 struct Sig<R(As...)> : SigImpl<R, As...> {};
897 template <
class R,
class A,
class... As>
898 struct Sig<R(A&, As...)> : SigImpl<R, A&, As...> {
899 using CCFun = R(A
const&, As...);
900 using SigImpl<R, A&, As...>::operator();
902 constexpr CCFun* operator()(CCFun*
t)
const volatile noexcept {
910 class U = std::decay_t<T>,
911 std::enable_if_t<Not<std::is_base_of<PolyBase, U>>
::value,
int> = 0,
912 std::enable_if_t<std::is_constructible<AddCvrefOf<U, I>, T>
::value,
int> =
914 class = MembersOf<std::decay_t<I>, U>>
916 template <class T, class I>
919 template <class T, class I>
920 struct ModelsInterface : decltype(modelsInterface_<T, I>(0)) {};
922 template <
class I1,
class I2>
923 struct ValueCompatible : std::is_base_of<I1, I2> {};
930 template <
class I1,
class I2,
class I2Ref>
931 struct ReferenceCompatible : std::is_constructible<I1, I2Ref> {};
935 template <
class I1,
class I2Ref>
bool operator>(const Expected< Value, Error > &lhs, const Expected< Value, Error > &rhs)
constexpr detail::Map< Move > move
internal::ArgsMatcher< InnerMatcher > Args(const InnerMatcher &matcher)
—— Concurrent Priority Queue Implementation ——
requires E e noexcept(noexcept(s.error(std::move(e))))
MetaApply< MetaApply< List, impl::FoldR_< Fn >>, State > TypeFold
bool_constant< true > true_type
ScopeGuardImpl< typename std::decay< FunctionType >::type, true > operator+(detail::ScopeGuardOnExit, FunctionType &&fn)
bool operator!=(const Unexpected< Error > &lhs, const Unexpected< Error > &rhs)
MetaApply< impl::If_< If_ >, Then, Else > If
State
See Core for details.
constexpr auto invoke(F &&f, Args &&...args) noexcept(noexcept(static_cast< F && >(f)(static_cast< Args && >(args)...))) -> decltype(static_cast< F && >(f)(static_cast< Args && >(args)...))
MetaApply< List, MetaBindFront< MetaQuote< TypeList >, Ts... >> TypePushFront
std::enable_if< detail::is_chrono_conversion< Tgt, Src >::value, Tgt >::type to(const Src &value)
internal::NotMatcher< InnerMatcher > Not(InnerMatcher m)
detail::TypeList< Ts... > PolyMembers
constexpr auto data(C &c) -> decltype(c.data())
MetaApply< List, impl::TypeTransform_< Fn >> TypeTransform
LogLevel & operator-=(LogLevel &level, uint32_t value)
static const char *const value
PUSHMI_INLINE_VAR constexpr struct folly::pushmi::operators::from_fn from
**Optimized Holders **The template hazptr_array< M > provides most of the functionality *of M hazptr_holder s but with faster construction destruction *for M
bool operator>=(const Expected< Value, Error > &lhs, const Expected< Value, Error > &rhs)
detail::AddCvrefOf< T, I > & poly_cast(detail::PolyRoot< I > &)
T exchange(T &obj, U &&new_value)
TypeReverseFold< List, TypeList<>, MetaFlip< impl::Unique_ >> TypeReverseUnique
bool operator==(const Unexpected< Error > &lhs, const Unexpected< Error > &rhs)
bool operator<=(const Expected< Value, Error > &lhs, const Expected< Value, Error > &rhs)
uint64_t value(const typename LockFreeRingBuffer< T, Atom >::Cursor &rbcursor)
bool_constant< false > false_type
const internal::AnythingMatcher _
constexpr LogLevel operator-(LogLevel level, uint32_t value)
MetaApply< TypeFold< List, MetaQuote< TypeList >, impl::Join_ >> TypeJoin
decltype(auto) constexpr apply(F &&func, Tuple &&tuple)
static constexpr uint64_t data[1]
LogLevel & operator+=(LogLevel &level, uint32_t value)
Future< bool > call(int depth, Executor *executor)
std::basic_istream< typename basic_fbstring< E, T, A, S >::value_type, typename basic_fbstring< E, T, A, S >::traits_type > & operator>>(std::basic_istream< typename basic_fbstring< E, T, A, S >::value_type, typename basic_fbstring< E, T, A, S >::traits_type > &is, basic_fbstring< E, T, A, S > &str)
std::enable_if< IsLessThanComparable< Value >::value, bool >::type operator<(const Expected< Value, Error > &lhs, const Expected< Value, Error > &rhs)
static bool is_const(T &&)
std::ostream & operator<<(std::ostream &out, dynamic const &d)