@@ -42,10 +42,64 @@ namespace rtl
4242
4343 GETTER (rtl::error, _init_error, m_init_err)
4444
45- constexpr operator bool () const noexcept ;
45+ constexpr operator bool () const noexcept {
46+ return !(m_init_err != error::None || m_functors.empty () ||
47+ (m_functors.size () == 1 && m_functors[0 ] == nullptr ));
48+ }
49+
50+ constexpr bool must_bind_refs () const noexcept {
51+ return (m_functors[call_by::value] == nullptr &&
52+ (m_functors.size () > call_by::ncref || m_functors[call_by::cref]->is_any_arg_ncref ()));
53+ }
4654
4755 template <class ...args_t >
4856 requires (sizeof ...(args_t ) == sizeof ...(signature_t ))
49- constexpr Return operator ()(args_t &&...params) const noexcept ;
57+ constexpr Return operator ()(alloc p_alloc_on, args_t &&...params) const noexcept
58+ {
59+ if (!(*this )) [[unlikely]] {
60+ return { m_init_err, RObject{} };
61+ }
62+
63+ if (must_bind_refs ()) [[unlikely]] {
64+ return { error::ExplicitRefBindingRequired, RObject{} };
65+ }
66+
67+ auto index = (m_functors[call_by::value] != nullptr ? call_by::value : call_by::cref);
68+ return m_hop[index](p_alloc_on, std::forward<args_t >(params)...);
69+ }
70+
71+ template <class ...fwd_args_t >
72+ struct perfect_fwd
73+ {
74+ const constructor<signature_t ...>& fn;
75+
76+ template <class ...args_t >
77+ [[nodiscard]] [[gnu::hot]] [[gnu::flatten]]
78+ constexpr Return operator ()(alloc p_alloc_on, args_t &&...params) const noexcept
79+ {
80+ if (!fn) [[unlikely]] {
81+ return { fn.m_init_err , RObject{} };
82+ }
83+
84+ auto signature_id = traits::uid<traits::strict_sign_id_t <fwd_args_t ...>>::value;
85+ for (int index = 0 ; index < fn.m_functors .size (); index++)
86+ {
87+ if (fn.m_functors [index] != nullptr &&
88+ signature_id == fn.m_functors [index]->get_strict_sign_id ()) {
89+ return fn.m_hop [index](p_alloc_on, std::forward<args_t >(params)...);
90+ }
91+ }
92+ return { error::RefBindingMismatch, RObject{} };
93+ }
94+ };
95+
96+ template <class ...args_t >
97+ requires (std::is_same_v<traits::normal_sign_id_t <args_t ...>, std::tuple<signature_t ...>>)
98+ constexpr const perfect_fwd<args_t ...> bind () const noexcept {
99+ return perfect_fwd<args_t ...>{ *this };
100+ }
101+
102+ static_assert ((!std::is_reference_v<signature_t > && ...),
103+ " rtl::function<...>: any type cannot be specified as reference here" );
50104 };
51105}
0 commit comments