Skip to content

Commit e1e60d2

Browse files
committed
Use perfect forward
1 parent 7e418f4 commit e1e60d2

File tree

1 file changed

+61
-61
lines changed

1 file changed

+61
-61
lines changed

include/pybind11/pybind11.h

+61-61
Original file line numberDiff line numberDiff line change
@@ -114,62 +114,62 @@ class cpp_function : public function {
114114
/// Construct a cpp_function from a vanilla function pointer
115115
template <typename Return, typename... Args, typename... Extra>
116116
// NOLINTNEXTLINE(google-explicit-constructor)
117-
cpp_function(Return (*f)(Args...), const Extra &...extra) {
118-
initialize(f, f, extra...);
117+
cpp_function(Return (*f)(Args...), Extra &&...extra) {
118+
initialize(f, f, std::forward<Extra>(extra)...);
119119
}
120120

121121
/// Construct a cpp_function from a lambda function (possibly with internal state)
122122
template <typename Func,
123123
typename... Extra,
124124
typename = detail::enable_if_t<detail::is_lambda<Func>::value>>
125125
// NOLINTNEXTLINE(google-explicit-constructor)
126-
cpp_function(Func &&f, const Extra &...extra) {
126+
cpp_function(Func &&f, Extra &&...extra) {
127127
initialize(
128-
std::forward<Func>(f), (detail::function_signature_t<Func> *) nullptr, extra...);
128+
std::forward<Func>(f), (detail::function_signature_t<Func> *) nullptr, std::forward<Extra>(extra)...);
129129
}
130130

131131
/// Construct a cpp_function from a class method (non-const, no ref-qualifier)
132132
template <typename Return, typename Class, typename... Arg, typename... Extra>
133133
// NOLINTNEXTLINE(google-explicit-constructor)
134-
cpp_function(Return (Class::*f)(Arg...), const Extra &...extra) {
134+
cpp_function(Return (Class::*f)(Arg...), Extra &&...extra) {
135135
initialize(
136136
[f](Class *c, Arg... args) -> Return { return (c->*f)(std::forward<Arg>(args)...); },
137137
(Return(*)(Class *, Arg...)) nullptr,
138-
extra...);
138+
std::forward<Extra>(extra)...);
139139
}
140140

141141
/// Construct a cpp_function from a class method (non-const, lvalue ref-qualifier)
142142
/// A copy of the overload for non-const functions without explicit ref-qualifier
143143
/// but with an added `&`.
144144
template <typename Return, typename Class, typename... Arg, typename... Extra>
145145
// NOLINTNEXTLINE(google-explicit-constructor)
146-
cpp_function(Return (Class::*f)(Arg...) &, const Extra &...extra) {
146+
cpp_function(Return (Class::*f)(Arg...) &, Extra &&...extra) {
147147
initialize(
148148
[f](Class *c, Arg... args) -> Return { return (c->*f)(std::forward<Arg>(args)...); },
149149
(Return(*)(Class *, Arg...)) nullptr,
150-
extra...);
150+
std::forward<Extra>(extra)...);
151151
}
152152

153153
/// Construct a cpp_function from a class method (const, no ref-qualifier)
154154
template <typename Return, typename Class, typename... Arg, typename... Extra>
155155
// NOLINTNEXTLINE(google-explicit-constructor)
156-
cpp_function(Return (Class::*f)(Arg...) const, const Extra &...extra) {
156+
cpp_function(Return (Class::*f)(Arg...) const, Extra &&...extra) {
157157
initialize([f](const Class *c,
158158
Arg... args) -> Return { return (c->*f)(std::forward<Arg>(args)...); },
159159
(Return(*)(const Class *, Arg...)) nullptr,
160-
extra...);
160+
std::forward<Extra>(extra)...);
161161
}
162162

163163
/// Construct a cpp_function from a class method (const, lvalue ref-qualifier)
164164
/// A copy of the overload for const functions without explicit ref-qualifier
165165
/// but with an added `&`.
166166
template <typename Return, typename Class, typename... Arg, typename... Extra>
167167
// NOLINTNEXTLINE(google-explicit-constructor)
168-
cpp_function(Return (Class::*f)(Arg...) const &, const Extra &...extra) {
168+
cpp_function(Return (Class::*f)(Arg...) const &, Extra &&...extra) {
169169
initialize([f](const Class *c,
170170
Arg... args) -> Return { return (c->*f)(std::forward<Arg>(args)...); },
171171
(Return(*)(const Class *, Arg...)) nullptr,
172-
extra...);
172+
std::forward<Extra>(extra)...);
173173
}
174174

175175
/// Return the function name
@@ -191,7 +191,7 @@ class cpp_function : public function {
191191

192192
/// Special internal constructor for functors, lambda functions, etc.
193193
template <typename Func, typename Return, typename... Args, typename... Extra>
194-
void initialize(Func &&f, Return (*)(Args...), const Extra &...extra) {
194+
void initialize(Func &&f, Return (*)(Args...), Extra &&... extra) {
195195
using namespace detail;
196196
struct capture {
197197
remove_reference_t<Func> f;
@@ -295,7 +295,7 @@ class cpp_function : public function {
295295
rec->has_kwargs = cast_in::has_kwargs;
296296

297297
/* Process any user-provided function attributes */
298-
process_attributes<Extra...>::init(extra..., rec);
298+
process_attributes<Extra...>::init(std::forward<Extra>(extra)..., rec);
299299

300300
{
301301
constexpr bool has_kw_only_args = any_of<std::is_same<kw_only, Extra>...>::value,
@@ -1184,12 +1184,12 @@ class module_ : public object {
11841184
details on the ``Extra&& ... extra`` argument, see section :ref:`extras`.
11851185
\endrst */
11861186
template <typename Func, typename... Extra>
1187-
module_ &def(const char *name_, Func &&f, const Extra &...extra) {
1187+
module_ &def(const char *name_, Func &&f, Extra &&...extra) {
11881188
cpp_function func(std::forward<Func>(f),
11891189
name(name_),
11901190
scope(*this),
11911191
sibling(getattr(*this, name_, none())),
1192-
extra...);
1192+
std::forward<Extra>(extra)...);
11931193
// NB: allow overwriting here because cpp_function sets up a chain with the intention of
11941194
// overwriting (and has already checked internally that it isn't overwriting
11951195
// non-functions).
@@ -1572,7 +1572,7 @@ class class_ : public detail::generic_type {
15721572
PYBIND11_OBJECT(class_, generic_type, PyType_Check)
15731573

15741574
template <typename... Extra>
1575-
class_(handle scope, const char *name, const Extra &...extra) {
1575+
class_(handle scope, const char *name, Extra &&...extra) {
15761576
using namespace detail;
15771577

15781578
// MI can only be specified via class_ template options, not constructor parameters
@@ -1601,7 +1601,7 @@ class class_ : public detail::generic_type {
16011601
PYBIND11_EXPAND_SIDE_EFFECTS(add_base<options>(record));
16021602

16031603
/* Process optional arguments, if any */
1604-
process_attributes<Extra...>::init(extra..., &record);
1604+
process_attributes<Extra...>::init(std::forward<Extra>(extra)..., &record);
16051605

16061606
generic_type::initialize(record);
16071607

@@ -1627,65 +1627,65 @@ class class_ : public detail::generic_type {
16271627
static void add_base(detail::type_record &) {}
16281628

16291629
template <typename Func, typename... Extra>
1630-
class_ &def(const char *name_, Func &&f, const Extra &...extra) {
1630+
class_ &def(const char *name_, Func &&f, Extra &&...extra) {
16311631
cpp_function cf(method_adaptor<type>(std::forward<Func>(f)),
16321632
name(name_),
16331633
is_method(*this),
16341634
sibling(getattr(*this, name_, none())),
1635-
extra...);
1635+
std::forward<Extra>(extra)...);
16361636
add_class_method(*this, name_, cf);
16371637
return *this;
16381638
}
16391639

16401640
template <typename Func, typename... Extra>
1641-
class_ &def_static(const char *name_, Func &&f, const Extra &...extra) {
1641+
class_ &def_static(const char *name_, Func &&f, Extra &&...extra) {
16421642
static_assert(!std::is_member_function_pointer<Func>::value,
16431643
"def_static(...) called with a non-static member function pointer");
16441644
cpp_function cf(std::forward<Func>(f),
16451645
name(name_),
16461646
scope(*this),
16471647
sibling(getattr(*this, name_, none())),
1648-
extra...);
1648+
std::forward<Extra>(extra)...);
16491649
auto cf_name = cf.name();
16501650
attr(std::move(cf_name)) = staticmethod(std::move(cf));
16511651
return *this;
16521652
}
16531653

16541654
template <typename T, typename... Extra, detail::enable_if_t<T::op_enable_if_hook, int> = 0>
1655-
class_ &def(const T &op, const Extra &...extra) {
1656-
op.execute(*this, extra...);
1655+
class_ &def(const T &op, Extra &&...extra) {
1656+
op.execute(*this, std::forward<Extra>(extra)...);
16571657
return *this;
16581658
}
16591659

16601660
template <typename T, typename... Extra, detail::enable_if_t<T::op_enable_if_hook, int> = 0>
1661-
class_ &def_cast(const T &op, const Extra &...extra) {
1662-
op.execute_cast(*this, extra...);
1661+
class_ &def_cast(const T &op, Extra &&...extra) {
1662+
op.execute_cast(*this, std::forward<Extra>(extra)...);
16631663
return *this;
16641664
}
16651665

16661666
template <typename... Args, typename... Extra>
1667-
class_ &def(const detail::initimpl::constructor<Args...> &init, const Extra &...extra) {
1667+
class_ &def(const detail::initimpl::constructor<Args...> &init, Extra &&...extra) {
16681668
PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(init);
1669-
init.execute(*this, extra...);
1669+
init.execute(*this, std::forward<Extra>(extra)...);
16701670
return *this;
16711671
}
16721672

16731673
template <typename... Args, typename... Extra>
1674-
class_ &def(const detail::initimpl::alias_constructor<Args...> &init, const Extra &...extra) {
1674+
class_ &def(const detail::initimpl::alias_constructor<Args...> &init, Extra &&...extra) {
16751675
PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(init);
1676-
init.execute(*this, extra...);
1676+
init.execute(*this, std::forward<Extra>(extra)...);
16771677
return *this;
16781678
}
16791679

16801680
template <typename... Args, typename... Extra>
1681-
class_ &def(detail::initimpl::factory<Args...> &&init, const Extra &...extra) {
1682-
std::move(init).execute(*this, extra...);
1681+
class_ &def(detail::initimpl::factory<Args...> &&init, Extra &&...extra) {
1682+
std::move(init).execute(*this, std::forward<Extra>(extra)...);
16831683
return *this;
16841684
}
16851685

16861686
template <typename... Args, typename... Extra>
1687-
class_ &def(detail::initimpl::pickle_factory<Args...> &&pf, const Extra &...extra) {
1688-
std::move(pf).execute(*this, extra...);
1687+
class_ &def(detail::initimpl::pickle_factory<Args...> &&pf, Extra &&...extra) {
1688+
std::move(pf).execute(*this, std::forward<Extra>(extra)...);
16891689
return *this;
16901690
}
16911691

@@ -1723,115 +1723,115 @@ class class_ : public detail::generic_type {
17231723
}
17241724

17251725
template <typename C, typename D, typename... Extra>
1726-
class_ &def_readwrite(const char *name, D C::*pm, const Extra &...extra) {
1726+
class_ &def_readwrite(const char *name, D C::*pm, Extra &&...extra) {
17271727
static_assert(std::is_same<C, type>::value || std::is_base_of<C, type>::value,
17281728
"def_readwrite() requires a class member (or base class member)");
17291729
cpp_function fget([pm](const type &c) -> const D & { return c.*pm; }, is_method(*this)),
17301730
fset([pm](type &c, const D &value) { c.*pm = value; }, is_method(*this));
1731-
def_property(name, fget, fset, return_value_policy::reference_internal, extra...);
1731+
def_property(name, fget, fset, return_value_policy::reference_internal, std::forward<Extra>(extra)...);
17321732
return *this;
17331733
}
17341734

17351735
template <typename C, typename D, typename... Extra>
1736-
class_ &def_readonly(const char *name, const D C::*pm, const Extra &...extra) {
1736+
class_ &def_readonly(const char *name, const D C::*pm, Extra &&...extra) {
17371737
static_assert(std::is_same<C, type>::value || std::is_base_of<C, type>::value,
17381738
"def_readonly() requires a class member (or base class member)");
17391739
cpp_function fget([pm](const type &c) -> const D & { return c.*pm; }, is_method(*this));
1740-
def_property_readonly(name, fget, return_value_policy::reference_internal, extra...);
1740+
def_property_readonly(name, fget, return_value_policy::reference_internal, std::forward<Extra>(extra)...);
17411741
return *this;
17421742
}
17431743

17441744
template <typename D, typename... Extra>
1745-
class_ &def_readwrite_static(const char *name, D *pm, const Extra &...extra) {
1745+
class_ &def_readwrite_static(const char *name, D *pm, Extra &&...extra) {
17461746
cpp_function fget([pm](const object &) -> const D & { return *pm; }, scope(*this)),
17471747
fset([pm](const object &, const D &value) { *pm = value; }, scope(*this));
1748-
def_property_static(name, fget, fset, return_value_policy::reference, extra...);
1748+
def_property_static(name, fget, fset, return_value_policy::reference, std::forward<Extra>(extra)...);
17491749
return *this;
17501750
}
17511751

17521752
template <typename D, typename... Extra>
1753-
class_ &def_readonly_static(const char *name, const D *pm, const Extra &...extra) {
1753+
class_ &def_readonly_static(const char *name, const D *pm, Extra &&...extra) {
17541754
cpp_function fget([pm](const object &) -> const D & { return *pm; }, scope(*this));
1755-
def_property_readonly_static(name, fget, return_value_policy::reference, extra...);
1755+
def_property_readonly_static(name, fget, return_value_policy::reference, std::forward<Extra>(extra)...);
17561756
return *this;
17571757
}
17581758

17591759
/// Uses return_value_policy::reference_internal by default
17601760
template <typename Getter, typename... Extra>
1761-
class_ &def_property_readonly(const char *name, const Getter &fget, const Extra &...extra) {
1761+
class_ &def_property_readonly(const char *name, const Getter &fget, Extra &&...extra) {
17621762
return def_property_readonly(name,
17631763
cpp_function(method_adaptor<type>(fget)),
17641764
return_value_policy::reference_internal,
1765-
extra...);
1765+
std::forward<Extra>(extra)...);
17661766
}
17671767

17681768
/// Uses cpp_function's return_value_policy by default
17691769
template <typename... Extra>
17701770
class_ &
1771-
def_property_readonly(const char *name, const cpp_function &fget, const Extra &...extra) {
1772-
return def_property(name, fget, nullptr, extra...);
1771+
def_property_readonly(const char *name, const cpp_function &fget, Extra &&...extra) {
1772+
return def_property(name, fget, nullptr, std::forward<Extra>(extra)...);
17731773
}
17741774

17751775
/// Uses return_value_policy::reference by default
17761776
template <typename Getter, typename... Extra>
17771777
class_ &
1778-
def_property_readonly_static(const char *name, const Getter &fget, const Extra &...extra) {
1778+
def_property_readonly_static(const char *name, const Getter &fget, Extra &&...extra) {
17791779
return def_property_readonly_static(
1780-
name, cpp_function(fget), return_value_policy::reference, extra...);
1780+
name, cpp_function(fget), return_value_policy::reference, std::forward<Extra>(extra)...);
17811781
}
17821782

17831783
/// Uses cpp_function's return_value_policy by default
17841784
template <typename... Extra>
17851785
class_ &def_property_readonly_static(const char *name,
17861786
const cpp_function &fget,
1787-
const Extra &...extra) {
1788-
return def_property_static(name, fget, nullptr, extra...);
1787+
Extra &&...extra) {
1788+
return def_property_static(name, fget, nullptr, std::forward<Extra>(extra)...);
17891789
}
17901790

17911791
/// Uses return_value_policy::reference_internal by default
17921792
template <typename Getter, typename Setter, typename... Extra>
17931793
class_ &
1794-
def_property(const char *name, const Getter &fget, const Setter &fset, const Extra &...extra) {
1794+
def_property(const char *name, const Getter &fget, const Setter &fset, Extra &&...extra) {
17951795
return def_property(
1796-
name, fget, cpp_function(method_adaptor<type>(fset), is_setter()), extra...);
1796+
name, fget, cpp_function(method_adaptor<type>(fset), is_setter()), std::forward<Extra>(extra)...);
17971797
}
17981798
template <typename Getter, typename... Extra>
17991799
class_ &def_property(const char *name,
18001800
const Getter &fget,
18011801
const cpp_function &fset,
1802-
const Extra &...extra) {
1802+
Extra &&...extra) {
18031803
return def_property(name,
18041804
cpp_function(method_adaptor<type>(fget)),
18051805
fset,
18061806
return_value_policy::reference_internal,
1807-
extra...);
1807+
std::forward<Extra>(extra)...);
18081808
}
18091809

18101810
/// Uses cpp_function's return_value_policy by default
18111811
template <typename... Extra>
18121812
class_ &def_property(const char *name,
18131813
const cpp_function &fget,
18141814
const cpp_function &fset,
1815-
const Extra &...extra) {
1816-
return def_property_static(name, fget, fset, is_method(*this), extra...);
1815+
Extra &&...extra) {
1816+
return def_property_static(name, fget, fset, is_method(*this), std::forward<Extra>(extra)...);
18171817
}
18181818

18191819
/// Uses return_value_policy::reference by default
18201820
template <typename Getter, typename... Extra>
18211821
class_ &def_property_static(const char *name,
18221822
const Getter &fget,
18231823
const cpp_function &fset,
1824-
const Extra &...extra) {
1824+
Extra &&...extra) {
18251825
return def_property_static(
1826-
name, cpp_function(fget), fset, return_value_policy::reference, extra...);
1826+
name, cpp_function(fget), fset, return_value_policy::reference, std::forward<Extra>(extra)...);
18271827
}
18281828

18291829
/// Uses cpp_function's return_value_policy by default
18301830
template <typename... Extra>
18311831
class_ &def_property_static(const char *name,
18321832
const cpp_function &fget,
18331833
const cpp_function &fset,
1834-
const Extra &...extra) {
1834+
Extra &&...extra) {
18351835
static_assert(0 == detail::constexpr_sum(std::is_base_of<arg, Extra>::value...),
18361836
"Argument annotations are not allowed for properties");
18371837
auto rec_fget = get_function_record(fget), rec_fset = get_function_record(fset);
@@ -2238,8 +2238,8 @@ class enum_ : public class_<Type> {
22382238
Underlying>;
22392239

22402240
template <typename... Extra>
2241-
enum_(const handle &scope, const char *name, const Extra &...extra)
2242-
: class_<Type>(scope, name, extra...), m_base(*this, scope) {
2241+
enum_(const handle &scope, const char *name, Extra &&...extra)
2242+
: class_<Type>(scope, name, std::forward<Extra>(extra)...), m_base(*this, scope) {
22432243
constexpr bool is_arithmetic = detail::any_of<std::is_same<arithmetic, Extra>...>::value;
22442244
constexpr bool is_convertible = std::is_convertible<Type, Underlying>::value;
22452245
m_base.init(is_arithmetic, is_convertible);

0 commit comments

Comments
 (0)