@@ -649,7 +649,6 @@ class method<Name, Return(Parameters...), Options...>
649
649
using Signature = Return(Parameters...);
650
650
using FunctionPointer =
651
651
Return (*)(detail::remove_virtual<Parameters>...) noexcept (NoExcept);
652
- using Next = FunctionPointer;
653
652
654
653
static constexpr auto arity = detail::arity<Parameters...>;
655
654
static_assert (arity > 0 , " method must have at least one virtual argument" );
@@ -703,42 +702,13 @@ class method<Name, Return(Parameters...), Options...>
703
702
template <auto , typename >
704
703
struct thunk ;
705
704
706
- template <
707
- auto Overrider, typename OverriderReturn,
708
- typename ... OverriderParameters>
709
- struct thunk <Overrider, OverriderReturn (*)(OverriderParameters...)> {
710
- static auto fn (detail::remove_virtual<Parameters>... arg) -> Return;
711
- using OverriderParameterTypeIds = detail::type_id_list<
712
- Policy,
713
- detail::spec_polymorphic_types<
714
- Policy, DeclaredParameters,
715
- detail::types<OverriderParameters...>>>;
716
- };
717
-
718
- template <class Container , bool has_next>
719
- struct override_ ;
720
-
721
705
friend class generator ;
722
706
723
- public:
724
- template <auto Function>
725
- struct override_fn ;
726
-
727
- private:
728
- template <class Container >
729
- struct override_ <Container, false > {
730
- override_fn<Container::fn> override_{nullptr };
731
- };
732
-
733
- template <class Container >
734
- struct override_ <Container, true > {
735
- override_fn<Container::fn> add{&Container::next};
736
- };
737
-
738
707
public:
739
708
// Public aliases.
740
709
using return_type = Return;
741
- using next_type = Next;
710
+ using next_type =
711
+ Return (*)(detail::remove_virtual<Parameters>...) noexcept (NoExcept);
742
712
743
713
static method fn;
744
714
@@ -753,9 +723,31 @@ class method<Name, Return(Parameters...), Options...>
753
723
template <class Container >
754
724
using next = detail::next_aux<method, Container>;
755
725
726
+ template <auto >
727
+ static FunctionPointer next_fn;
728
+
729
+ private:
730
+ template <
731
+ auto Overrider, typename OverriderReturn,
732
+ typename ... OverriderParameters>
733
+ struct thunk <Overrider, OverriderReturn (*)(OverriderParameters...)> {
734
+ static auto fn (detail::remove_virtual<Parameters>... arg) -> Return;
735
+ using OverriderParameterTypeIds = detail::type_id_list<
736
+ Policy,
737
+ detail::spec_polymorphic_types<
738
+ Policy, DeclaredParameters,
739
+ detail::types<OverriderParameters...>>>;
740
+ };
741
+
756
742
template <auto Function>
757
- struct override_fn {
758
- explicit override_fn (Next* next = nullptr ) {
743
+ struct override_fn_impl {
744
+ explicit override_fn_impl (FunctionPointer* next = nullptr ) {
745
+ // Work around MSVC bug: using &next_fn<Function> as a default value
746
+ // for 'next' confuses it about Parameters not being expanded.
747
+ if (!next) {
748
+ next = &next_fn<Function>;
749
+ }
750
+
759
751
static detail::definition_info info;
760
752
761
753
if (info.method ) {
@@ -774,25 +766,73 @@ class method<Name, Return(Parameters...), Options...>
774
766
}
775
767
};
776
768
777
- template <class Container >
778
- struct override
779
- : override_<Container, detail::has_next<Container>::value> {
780
- using type = override ; // make it a meta-function
769
+ template <auto Function, typename FunctionType>
770
+ struct override_fn_aux ;
771
+
772
+ template <auto Function, typename FnReturnType, typename ... FnParameters>
773
+ struct override_fn_aux <Function, FnReturnType (*)(FnParameters...)>
774
+ : override_fn_impl<Function> {
775
+ using override_fn_impl<Function>::override_fn_impl;
776
+ };
777
+
778
+ template <
779
+ auto Function, class FnClass , typename FnReturnType,
780
+ typename ... FnParameters>
781
+ struct override_fn_aux <
782
+ Function, FnReturnType (FnClass::*)(FnParameters...)> {
783
+ static auto fn (FnClass* this_, FnParameters&&... args) -> FnReturnType {
784
+ return (this_->*Function)(std::forward<FnParameters>(args)...);
785
+ }
786
+
787
+ override_fn_impl<fn> impl{&next_fn<Function>};
781
788
};
782
789
783
- template <auto F>
784
- struct add_member_function
785
- : override_fn<detail::member_function_thunk<F, decltype (F)>::fn> {};
790
+ public:
791
+ template <auto Function>
792
+ struct override_fn : override_fn_aux<Function, decltype (Function)> {
793
+ using override_fn_aux<Function, decltype (Function)>::override_fn_aux;
794
+ };
786
795
787
796
template <auto ... F>
788
- struct add_member_functions : std::tuple<add_member_function<F>...> {};
797
+ struct override_fns {
798
+ std::tuple<override_fn<F>...> fns;
799
+ };
800
+
801
+ private:
802
+ template <class Container , bool HasNext>
803
+ struct override_aux ;
804
+
805
+ template <class Container >
806
+ struct override_aux <Container, false > : override_fn<Container::fn> {
807
+ override_aux () : override_fn<Container::fn>(nullptr ) {
808
+ }
809
+ };
810
+
811
+ template <class Container >
812
+ struct override_aux <Container, true > : override_fn<Container::fn> {
813
+ override_aux () : override_fn<Container::fn>(&Container::next) {
814
+ }
815
+ };
816
+
817
+ public:
818
+ template <class Container >
819
+ struct override
820
+ : override_aux<Container, detail::has_next<Container>::value> {
821
+ using type = override ; // make it a meta-function
822
+ };
789
823
};
790
824
791
825
template <
792
826
typename Name, typename Return, typename ... Parameters, class ... Options>
793
827
method<Name, Return(Parameters...), Options...>
794
828
method<Name, Return(Parameters...), Options...>::fn;
795
829
830
+ template <
831
+ typename Name, typename Return, typename ... Parameters, class ... Options>
832
+ template <auto >
833
+ typename method<Name, Return(Parameters...), Options...>::FunctionPointer
834
+ method<Name, Return(Parameters...), Options...>::next_fn;
835
+
796
836
template <typename T>
797
837
constexpr bool is_method = std::is_base_of_v<detail::method_info, T>;
798
838
0 commit comments