File indexing completed on 2025-02-16 05:12:17
0001 /* 0002 pybind11/operator.h: Metatemplates for operator overloading 0003 0004 Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch> 0005 0006 All rights reserved. Use of this source code is governed by a 0007 BSD-style license that can be found in the LICENSE file. 0008 */ 0009 0010 #pragma once 0011 0012 #include "pybind11.h" 0013 0014 PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE) 0015 PYBIND11_NAMESPACE_BEGIN(detail) 0016 0017 /// Enumeration with all supported operator types 0018 enum op_id : int { 0019 op_add, op_sub, op_mul, op_div, op_mod, op_divmod, op_pow, op_lshift, 0020 op_rshift, op_and, op_xor, op_or, op_neg, op_pos, op_abs, op_invert, 0021 op_int, op_long, op_float, op_str, op_cmp, op_gt, op_ge, op_lt, op_le, 0022 op_eq, op_ne, op_iadd, op_isub, op_imul, op_idiv, op_imod, op_ilshift, 0023 op_irshift, op_iand, op_ixor, op_ior, op_complex, op_bool, op_nonzero, 0024 op_repr, op_truediv, op_itruediv, op_hash 0025 }; 0026 0027 enum op_type : int { 0028 op_l, /* base type on left */ 0029 op_r, /* base type on right */ 0030 op_u /* unary operator */ 0031 }; 0032 0033 struct self_t { }; 0034 static const self_t self = self_t(); 0035 0036 /// Type for an unused type slot 0037 struct undefined_t { }; 0038 0039 /// Don't warn about an unused variable 0040 inline self_t __self() { return self; } 0041 0042 /// base template of operator implementations 0043 template <op_id, op_type, typename B, typename L, typename R> struct op_impl { }; 0044 0045 /// Operator implementation generator 0046 template <op_id id, op_type ot, typename L, typename R> struct op_ { 0047 template <typename Class, typename... Extra> void execute(Class &cl, const Extra&... extra) const { 0048 using Base = typename Class::type; 0049 using L_type = conditional_t<std::is_same<L, self_t>::value, Base, L>; 0050 using R_type = conditional_t<std::is_same<R, self_t>::value, Base, R>; 0051 using op = op_impl<id, ot, Base, L_type, R_type>; 0052 cl.def(op::name(), &op::execute, is_operator(), extra...); 0053 #if PY_MAJOR_VERSION < 3 0054 if (PYBIND11_SILENCE_MSVC_C4127(id == op_truediv) || 0055 PYBIND11_SILENCE_MSVC_C4127(id == op_itruediv)) 0056 cl.def(id == op_itruediv ? "__idiv__" : ot == op_l ? "__div__" : "__rdiv__", 0057 &op::execute, is_operator(), extra...); 0058 #endif 0059 } 0060 template <typename Class, typename... Extra> void execute_cast(Class &cl, const Extra&... extra) const { 0061 using Base = typename Class::type; 0062 using L_type = conditional_t<std::is_same<L, self_t>::value, Base, L>; 0063 using R_type = conditional_t<std::is_same<R, self_t>::value, Base, R>; 0064 using op = op_impl<id, ot, Base, L_type, R_type>; 0065 cl.def(op::name(), &op::execute_cast, is_operator(), extra...); 0066 #if PY_MAJOR_VERSION < 3 0067 if (id == op_truediv || id == op_itruediv) 0068 cl.def(id == op_itruediv ? "__idiv__" : ot == op_l ? "__div__" : "__rdiv__", 0069 &op::execute, is_operator(), extra...); 0070 #endif 0071 } 0072 }; 0073 0074 #define PYBIND11_BINARY_OPERATOR(id, rid, op, expr) \ 0075 template <typename B, typename L, typename R> struct op_impl<op_##id, op_l, B, L, R> { \ 0076 static char const* name() { return "__" #id "__"; } \ 0077 static auto execute(const L &l, const R &r) -> decltype(expr) { return (expr); } \ 0078 static B execute_cast(const L &l, const R &r) { return B(expr); } \ 0079 }; \ 0080 template <typename B, typename L, typename R> struct op_impl<op_##id, op_r, B, L, R> { \ 0081 static char const* name() { return "__" #rid "__"; } \ 0082 static auto execute(const R &r, const L &l) -> decltype(expr) { return (expr); } \ 0083 static B execute_cast(const R &r, const L &l) { return B(expr); } \ 0084 }; \ 0085 inline op_<op_##id, op_l, self_t, self_t> op(const self_t &, const self_t &) { \ 0086 return op_<op_##id, op_l, self_t, self_t>(); \ 0087 } \ 0088 template <typename T> op_<op_##id, op_l, self_t, T> op(const self_t &, const T &) { \ 0089 return op_<op_##id, op_l, self_t, T>(); \ 0090 } \ 0091 template <typename T> op_<op_##id, op_r, T, self_t> op(const T &, const self_t &) { \ 0092 return op_<op_##id, op_r, T, self_t>(); \ 0093 } 0094 0095 #define PYBIND11_INPLACE_OPERATOR(id, op, expr) \ 0096 template <typename B, typename L, typename R> struct op_impl<op_##id, op_l, B, L, R> { \ 0097 static char const* name() { return "__" #id "__"; } \ 0098 static auto execute(L &l, const R &r) -> decltype(expr) { return expr; } \ 0099 static B execute_cast(L &l, const R &r) { return B(expr); } \ 0100 }; \ 0101 template <typename T> op_<op_##id, op_l, self_t, T> op(const self_t &, const T &) { \ 0102 return op_<op_##id, op_l, self_t, T>(); \ 0103 } 0104 0105 #define PYBIND11_UNARY_OPERATOR(id, op, expr) \ 0106 template <typename B, typename L> struct op_impl<op_##id, op_u, B, L, undefined_t> { \ 0107 static char const* name() { return "__" #id "__"; } \ 0108 static auto execute(const L &l) -> decltype(expr) { return expr; } \ 0109 static B execute_cast(const L &l) { return B(expr); } \ 0110 }; \ 0111 inline op_<op_##id, op_u, self_t, undefined_t> op(const self_t &) { \ 0112 return op_<op_##id, op_u, self_t, undefined_t>(); \ 0113 } 0114 0115 PYBIND11_BINARY_OPERATOR(sub, rsub, operator-, l - r) 0116 PYBIND11_BINARY_OPERATOR(add, radd, operator+, l + r) 0117 PYBIND11_BINARY_OPERATOR(mul, rmul, operator*, l * r) 0118 PYBIND11_BINARY_OPERATOR(truediv, rtruediv, operator/, l / r) 0119 PYBIND11_BINARY_OPERATOR(mod, rmod, operator%, l % r) 0120 PYBIND11_BINARY_OPERATOR(lshift, rlshift, operator<<, l << r) 0121 PYBIND11_BINARY_OPERATOR(rshift, rrshift, operator>>, l >> r) 0122 PYBIND11_BINARY_OPERATOR(and, rand, operator&, l & r) 0123 PYBIND11_BINARY_OPERATOR(xor, rxor, operator^, l ^ r) 0124 PYBIND11_BINARY_OPERATOR(eq, eq, operator==, l == r) 0125 PYBIND11_BINARY_OPERATOR(ne, ne, operator!=, l != r) 0126 PYBIND11_BINARY_OPERATOR(or, ror, operator|, l | r) 0127 PYBIND11_BINARY_OPERATOR(gt, lt, operator>, l > r) 0128 PYBIND11_BINARY_OPERATOR(ge, le, operator>=, l >= r) 0129 PYBIND11_BINARY_OPERATOR(lt, gt, operator<, l < r) 0130 PYBIND11_BINARY_OPERATOR(le, ge, operator<=, l <= r) 0131 //PYBIND11_BINARY_OPERATOR(pow, rpow, pow, std::pow(l, r)) 0132 PYBIND11_INPLACE_OPERATOR(iadd, operator+=, l += r) 0133 PYBIND11_INPLACE_OPERATOR(isub, operator-=, l -= r) 0134 PYBIND11_INPLACE_OPERATOR(imul, operator*=, l *= r) 0135 PYBIND11_INPLACE_OPERATOR(itruediv, operator/=, l /= r) 0136 PYBIND11_INPLACE_OPERATOR(imod, operator%=, l %= r) 0137 PYBIND11_INPLACE_OPERATOR(ilshift, operator<<=, l <<= r) 0138 PYBIND11_INPLACE_OPERATOR(irshift, operator>>=, l >>= r) 0139 PYBIND11_INPLACE_OPERATOR(iand, operator&=, l &= r) 0140 PYBIND11_INPLACE_OPERATOR(ixor, operator^=, l ^= r) 0141 PYBIND11_INPLACE_OPERATOR(ior, operator|=, l |= r) 0142 PYBIND11_UNARY_OPERATOR(neg, operator-, -l) 0143 PYBIND11_UNARY_OPERATOR(pos, operator+, +l) 0144 // WARNING: This usage of `abs` should only be done for existing STL overloads. 0145 // Adding overloads directly in to the `std::` namespace is advised against: 0146 // https://en.cppreference.com/w/cpp/language/extending_std 0147 PYBIND11_UNARY_OPERATOR(abs, abs, std::abs(l)) 0148 PYBIND11_UNARY_OPERATOR(hash, hash, std::hash<L>()(l)) 0149 PYBIND11_UNARY_OPERATOR(invert, operator~, (~l)) 0150 PYBIND11_UNARY_OPERATOR(bool, operator!, !!l) 0151 PYBIND11_UNARY_OPERATOR(int, int_, (int) l) 0152 PYBIND11_UNARY_OPERATOR(float, float_, (double) l) 0153 0154 #undef PYBIND11_BINARY_OPERATOR 0155 #undef PYBIND11_INPLACE_OPERATOR 0156 #undef PYBIND11_UNARY_OPERATOR 0157 PYBIND11_NAMESPACE_END(detail) 0158 0159 using detail::self; 0160 // Add named operators so that they are accessible via `py::`. 0161 using detail::hash; 0162 0163 PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)