Back to home page

EIC code displayed by LXR

 
 

    


Warning, file /include/pybind11/operators.h was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

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,
0020     op_sub,
0021     op_mul,
0022     op_div,
0023     op_mod,
0024     op_divmod,
0025     op_pow,
0026     op_lshift,
0027     op_rshift,
0028     op_and,
0029     op_xor,
0030     op_or,
0031     op_neg,
0032     op_pos,
0033     op_abs,
0034     op_invert,
0035     op_int,
0036     op_long,
0037     op_float,
0038     op_str,
0039     op_cmp,
0040     op_gt,
0041     op_ge,
0042     op_lt,
0043     op_le,
0044     op_eq,
0045     op_ne,
0046     op_iadd,
0047     op_isub,
0048     op_imul,
0049     op_idiv,
0050     op_imod,
0051     op_ilshift,
0052     op_irshift,
0053     op_iand,
0054     op_ixor,
0055     op_ior,
0056     op_complex,
0057     op_bool,
0058     op_nonzero,
0059     op_repr,
0060     op_truediv,
0061     op_itruediv,
0062     op_hash
0063 };
0064 
0065 enum op_type : int {
0066     op_l, /* base type on left */
0067     op_r, /* base type on right */
0068     op_u  /* unary operator */
0069 };
0070 
0071 struct self_t {};
0072 static const self_t self = self_t();
0073 
0074 /// Type for an unused type slot
0075 struct undefined_t {};
0076 
0077 /// Don't warn about an unused variable
0078 inline self_t __self() { return self; }
0079 
0080 /// base template of operator implementations
0081 template <op_id, op_type, typename B, typename L, typename R>
0082 struct op_impl {};
0083 
0084 /// Operator implementation generator
0085 template <op_id id, op_type ot, typename L, typename R>
0086 struct op_ {
0087     static constexpr bool op_enable_if_hook = true;
0088     template <typename Class, typename... Extra>
0089     void execute(Class &cl, const Extra &...extra) const {
0090         using Base = typename Class::type;
0091         using L_type = conditional_t<std::is_same<L, self_t>::value, Base, L>;
0092         using R_type = conditional_t<std::is_same<R, self_t>::value, Base, R>;
0093         using op = op_impl<id, ot, Base, L_type, R_type>;
0094         cl.def(op::name(), &op::execute, is_operator(), extra...);
0095     }
0096     template <typename Class, typename... Extra>
0097     void execute_cast(Class &cl, const Extra &...extra) const {
0098         using Base = typename Class::type;
0099         using L_type = conditional_t<std::is_same<L, self_t>::value, Base, L>;
0100         using R_type = conditional_t<std::is_same<R, self_t>::value, Base, R>;
0101         using op = op_impl<id, ot, Base, L_type, R_type>;
0102         cl.def(op::name(), &op::execute_cast, is_operator(), extra...);
0103     }
0104 };
0105 
0106 #define PYBIND11_BINARY_OPERATOR(id, rid, op, expr)                                               \
0107     template <typename B, typename L, typename R>                                                 \
0108     struct op_impl<op_##id, op_l, B, L, R> {                                                      \
0109         static char const *name() { return "__" #id "__"; }                                       \
0110         static auto execute(const L &l, const R &r) -> decltype(expr) { return (expr); }          \
0111         static B execute_cast(const L &l, const R &r) { return B(expr); }                         \
0112     };                                                                                            \
0113     template <typename B, typename L, typename R>                                                 \
0114     struct op_impl<op_##id, op_r, B, L, R> {                                                      \
0115         static char const *name() { return "__" #rid "__"; }                                      \
0116         static auto execute(const R &r, const L &l) -> decltype(expr) { return (expr); }          \
0117         static B execute_cast(const R &r, const L &l) { return B(expr); }                         \
0118     };                                                                                            \
0119     inline op_<op_##id, op_l, self_t, self_t> op(const self_t &, const self_t &) {                \
0120         return op_<op_##id, op_l, self_t, self_t>();                                              \
0121     }                                                                                             \
0122     template <typename T>                                                                         \
0123     op_<op_##id, op_l, self_t, T> op(const self_t &, const T &) {                                 \
0124         return op_<op_##id, op_l, self_t, T>();                                                   \
0125     }                                                                                             \
0126     template <typename T>                                                                         \
0127     op_<op_##id, op_r, T, self_t> op(const T &, const self_t &) {                                 \
0128         return op_<op_##id, op_r, T, self_t>();                                                   \
0129     }
0130 
0131 #define PYBIND11_INPLACE_OPERATOR(id, op, expr)                                                   \
0132     template <typename B, typename L, typename R>                                                 \
0133     struct op_impl<op_##id, op_l, B, L, R> {                                                      \
0134         static char const *name() { return "__" #id "__"; }                                       \
0135         static auto execute(L &l, const R &r) -> decltype(expr) { return expr; }                  \
0136         static B execute_cast(L &l, const R &r) { return B(expr); }                               \
0137     };                                                                                            \
0138     template <typename T>                                                                         \
0139     op_<op_##id, op_l, self_t, T> op(const self_t &, const T &) {                                 \
0140         return op_<op_##id, op_l, self_t, T>();                                                   \
0141     }
0142 
0143 #define PYBIND11_UNARY_OPERATOR(id, op, expr)                                                     \
0144     template <typename B, typename L>                                                             \
0145     struct op_impl<op_##id, op_u, B, L, undefined_t> {                                            \
0146         static char const *name() { return "__" #id "__"; }                                       \
0147         static auto execute(const L &l) -> decltype(expr) { return expr; }                        \
0148         static B execute_cast(const L &l) { return B(expr); }                                     \
0149     };                                                                                            \
0150     inline op_<op_##id, op_u, self_t, undefined_t> op(const self_t &) {                           \
0151         return op_<op_##id, op_u, self_t, undefined_t>();                                         \
0152     }
0153 
0154 PYBIND11_BINARY_OPERATOR(sub, rsub, operator-, l - r)
0155 PYBIND11_BINARY_OPERATOR(add, radd, operator+, l + r)
0156 PYBIND11_BINARY_OPERATOR(mul, rmul, operator*, l *r)
0157 PYBIND11_BINARY_OPERATOR(truediv, rtruediv, operator/, l / r)
0158 PYBIND11_BINARY_OPERATOR(mod, rmod, operator%, l % r)
0159 PYBIND11_BINARY_OPERATOR(lshift, rlshift, operator<<, l << r)
0160 PYBIND11_BINARY_OPERATOR(rshift, rrshift, operator>>, l >> r)
0161 PYBIND11_BINARY_OPERATOR(and, rand, operator&, l &r)
0162 PYBIND11_BINARY_OPERATOR(xor, rxor, operator^, l ^ r)
0163 PYBIND11_BINARY_OPERATOR(eq, eq, operator==, l == r)
0164 PYBIND11_BINARY_OPERATOR(ne, ne, operator!=, l != r)
0165 PYBIND11_BINARY_OPERATOR(or, ror, operator|, l | r)
0166 PYBIND11_BINARY_OPERATOR(gt, lt, operator>, l > r)
0167 PYBIND11_BINARY_OPERATOR(ge, le, operator>=, l >= r)
0168 PYBIND11_BINARY_OPERATOR(lt, gt, operator<, l < r)
0169 PYBIND11_BINARY_OPERATOR(le, ge, operator<=, l <= r)
0170 // PYBIND11_BINARY_OPERATOR(pow,       rpow,         pow,          std::pow(l,  r))
0171 PYBIND11_INPLACE_OPERATOR(iadd, operator+=, l += r)
0172 PYBIND11_INPLACE_OPERATOR(isub, operator-=, l -= r)
0173 PYBIND11_INPLACE_OPERATOR(imul, operator*=, l *= r)
0174 PYBIND11_INPLACE_OPERATOR(itruediv, operator/=, l /= r)
0175 PYBIND11_INPLACE_OPERATOR(imod, operator%=, l %= r)
0176 PYBIND11_INPLACE_OPERATOR(ilshift, operator<<=, l <<= r)
0177 PYBIND11_INPLACE_OPERATOR(irshift, operator>>=, l >>= r)
0178 PYBIND11_INPLACE_OPERATOR(iand, operator&=, l &= r)
0179 PYBIND11_INPLACE_OPERATOR(ixor, operator^=, l ^= r)
0180 PYBIND11_INPLACE_OPERATOR(ior, operator|=, l |= r)
0181 PYBIND11_UNARY_OPERATOR(neg, operator-, -l)
0182 PYBIND11_UNARY_OPERATOR(pos, operator+, +l)
0183 // WARNING: This usage of `abs` should only be done for existing STL overloads.
0184 // Adding overloads directly in to the `std::` namespace is advised against:
0185 // https://en.cppreference.com/w/cpp/language/extending_std
0186 PYBIND11_UNARY_OPERATOR(abs, abs, std::abs(l))
0187 PYBIND11_UNARY_OPERATOR(hash, hash, std::hash<L>()(l))
0188 PYBIND11_UNARY_OPERATOR(invert, operator~, (~l))
0189 PYBIND11_UNARY_OPERATOR(bool, operator!, !!l)
0190 PYBIND11_UNARY_OPERATOR(int, int_, (int) l)
0191 PYBIND11_UNARY_OPERATOR(float, float_, (double) l)
0192 
0193 #undef PYBIND11_BINARY_OPERATOR
0194 #undef PYBIND11_INPLACE_OPERATOR
0195 #undef PYBIND11_UNARY_OPERATOR
0196 PYBIND11_NAMESPACE_END(detail)
0197 
0198 using detail::self;
0199 // Add named operators so that they are accessible via `py::`.
0200 using detail::hash;
0201 
0202 PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)