4141#include  " jni_dep.h" 
4242#include  " metaprogramming/double_locked_value.h" 
4343#include  " metaprogramming/string_concatenate.h" 
44+ #include  " implementation/id.h" 
4445
4546namespace  jni  {
47+ namespace  detail  {
48+ template  <typename  T>
49+ auto  ForwardWithRefStripImpl (T&& t, std::true_type /*  is_ref_base */  ) {
50+   using  U = std::remove_reference_t <T>;
51+   using  CastT = RefBaseStorageT_t<U>;
52+   return  CastT (std::forward<T>(t)); //  return by value, move or copy
53+ }
54+ 
55+ template  <typename  T>
56+ decltype (auto ) ForwardWithRefStripImpl(
57+     T&& t, std::false_type /*  not ref base */  ) {
58+   return  std::forward<T>(t); //  perfect forward
59+ }
60+ } //  namespace detail
61+ 
62+ template  <typename  T>
63+ decltype (auto ) ForwardWithRefStrip(T&& t) {
64+   using  U = std::remove_reference_t <T>;
65+   return  detail::ForwardWithRefStripImpl (
66+       std::forward<T>(t),
67+       std::is_base_of<RefBaseBase, U>{});
68+ }
4669
4770//  Transforms a OverloadRef IdT into a fully qualified ID. Storage is keyed
4871//  against these IDs to reduce excess MethodID lookups.
@@ -56,7 +79,7 @@ struct OverloadRefUniqueId {
5679  //  Dashes are solely for readability in debugging.
5780  static  constexpr  std::string_view TypeName () {
5881    return  metaprogramming::StringConcatenate_v<
59-          kClassQualifier , kDash , kOverloadName , kDash , Signature_v<IdT>>;
82+       kClassQualifier , kDash , kOverloadName , kDash , Signature_v<IdT>>;
6083  }
6184};
6285
@@ -68,25 +91,25 @@ struct OverloadRef {
6891  using  SelfIdT = typename  IdT::template  ChangeIdType<IdType::CLASS>;
6992
7093  using  ReturnProxied = std::conditional_t <
71-        ReturnIdT::kIsSelf ,
72-        Return_t<typename  SelfIdT::MaterializeCDeclT, SelfIdT>,
73-        Return_t<typename  ReturnIdT::MaterializeCDeclT, ReturnIdT>>;
94+     ReturnIdT::kIsSelf ,
95+     Return_t<typename  SelfIdT::MaterializeCDeclT, SelfIdT>,
96+     Return_t<typename  ReturnIdT::MaterializeCDeclT, ReturnIdT>>;
7497
7598  static  jmethodID GetMethodID (jclass clazz) {
7699    static  auto  get_lambda =
77100        [clazz](metaprogramming::DoubleLockedValue<jmethodID>* storage) {
78-            if  (kConfiguration .release_method_ids_on_teardown_ ) {
79-              DefaultRefs<jmethodID>().push_back (storage);
80-            }
81- 
82-            if  constexpr  (IdT::kIsStatic ) {
83-              return  jni::JniHelper::GetStaticMethodID (clazz, IdT::Name (),
84-                                                       Signature_v<IdT>.data ());
85-            } else  {
86-              return  jni::JniHelper::GetMethodID (clazz, IdT::Name (),
87-                                                 Signature_v<IdT>.data ());
88-            }
89-          };
101+       if  (kConfiguration .release_method_ids_on_teardown_ ) {
102+         DefaultRefs<jmethodID>().push_back (storage);
103+       }
104+ 
105+       if  constexpr  (IdT::kIsStatic ) {
106+         return  jni::JniHelper::GetStaticMethodID (clazz, IdT::Name (),
107+                                                  Signature_v<IdT>.data ());
108+       } else  {
109+         return  jni::JniHelper::GetMethodID (clazz, IdT::Name (),
110+                                            Signature_v<IdT>.data ());
111+       }
112+     };
90113
91114    return  RefStorage<decltype (get_lambda), OverloadRefUniqueId<IdT>>::Get (
92115        get_lambda);
@@ -102,30 +125,36 @@ struct OverloadRef {
102125    if  constexpr  (std::is_same_v<ReturnProxied, void >) {
103126      return  InvokeHelper<void , kRank , kStatic >::Invoke (
104127          object, clazz, mthd,
105-           Proxy_t<Params>::ProxyAsArg (std::forward<Params>(params))...);
128+           ForwardWithRefStrip (Proxy_t<Params>::ProxyAsArg (
129+               std::forward<Params>(params)))...);
106130    } else  if  constexpr  (IdT::kIsConstructor ) {
107131      return  ReturnProxied{
108132          AdoptLocal{},
109133          LifecycleHelper<jobject, LifecycleType::LOCAL>::Construct (
110134              clazz, mthd,
111-               Proxy_t<Params>::ProxyAsArg (std::forward<Params>(params))...)};
135+               ForwardWithRefStrip (
136+                   Proxy_t<Params>::ProxyAsArg (
137+                       std::forward<Params>(params)))...)};
112138    } else  {
113139      if  constexpr  (std::is_base_of_v<RefBaseBase, ReturnProxied>) {
114140        return  ReturnProxied{
115141            AdoptLocal{},
116142            InvokeHelper<typename  ReturnIdT::CDecl, kRank , kStatic >::Invoke (
117143                object, clazz, mthd,
118-                 Proxy_t<Params>::ProxyAsArg (std::forward<Params>(params))...)};
144+                 ForwardWithRefStrip (
145+                     Proxy_t<Params>::ProxyAsArg (std::forward<Params>(params)))
146+                 ...)};
119147      } else  {
120148        return  static_cast <ReturnProxied>(
121-             InvokeHelper<typename  ReturnIdT::CDecl, kRank , kStatic >::Invoke (
122-                 object, clazz, mthd,
123-                 Proxy_t<Params>::ProxyAsArg (std::forward<Params>(params))...));
149+           InvokeHelper<typename  ReturnIdT::CDecl, kRank , kStatic >::Invoke (
150+               object, clazz, mthd,
151+               ForwardWithRefStrip (
152+                   Proxy_t<Params>::ProxyAsArg (
153+                       std::forward<Params>(params)))...));
124154      }
125155    }
126156  }
127157};
158+ } //  namespace jni
128159
129- }  //  namespace jni
130- 
131- #endif   //  JNI_BIND_OVERLOAD_REF_H
160+ #endif   //  JNI_BIND_OVERLOAD_REF_H
0 commit comments