.. _program_listing_file_src_functional_predicates.h: Program Listing for File predicates.h ===================================== |exhale_lsh| :ref:`Return to documentation for file ` (``src/functional/predicates.h``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: cpp #pragma once #include "functional/defs.h" #include "functional/operands.h" namespace marian { namespace functional { template struct UnaryFunctor { X x; template UnaryFunctor(Arg a) : x(a) {} template HOST_DEVICE_INLINE T operator()(T arg, Args&&... args) { return Function::apply(x(arg, args...)); } std::string to_string() const { return Function::n() + "<" + x.to_string() + ">"; } }; template struct BinaryFunctor { X x; Y y; template BinaryFunctor(Arg1 arg1, Arg2 arg2) : x(arg1), y(arg2) {} template HOST_DEVICE_INLINE T operator()(T arg, Args&&... args) { return Function::apply(x(arg, args...), y(arg, args...)); } std::string to_string() const { return Function::n() + "<" + x.to_string() + "," + y.to_string() + ">"; } }; #define UNARY(name, name2, func) \ namespace elem { \ struct name { \ template \ HOST_DEVICE_INLINE static ElementType apply(const ElementType& x) { return func; } \ static std::string n() { return #name; } \ }; \ } \ template \ using name = UnaryFunctor; \ template \ static inline name> name2(X x) { \ return name(x); \ } \ static inline name name2(Capture x) { return name(x); } #define BINARY(name, name2, func) \ namespace elem { \ struct name { \ template \ HOST_DEVICE_INLINE static ElementType apply(const ElementType& x, \ const ElementType& y) \ { return func; } \ static std::string n() { return #name; } \ }; \ } \ template \ using name = BinaryFunctor; \ template \ name, IsClass> name2(const X& x, const Y& y) { \ return name(x, y); \ } \ template \ name> name2(const Capture& x, const Y& y) { \ return name(x, y); \ } \ template \ name, Capture> name2(const X& x, const Capture& y) { \ return name(x, y); \ } template struct TernaryFunctor { X x; Y y; Z z; template TernaryFunctor(Arg1 arg1, Arg2 arg2, Arg3 arg3) : x(arg1), y(arg2), z(arg3) {} template HOST_DEVICE_INLINE T operator()(T arg, Args&&... args) { return Function::apply(x(arg, args...), y(arg, args...), z(arg, args...)); } }; #define TERNARY(name, name2, func) \ namespace elem { \ struct name { \ template \ HOST_DEVICE_INLINE static ElementType apply(ElementType x, \ ElementType y, \ ElementType z) \ { return func; } \ }; \ } \ template \ using name = TernaryFunctor; \ template \ name, IsClass, IsClass> name2(X x, Y y, Z z) { \ return name(x, y, z); \ } \ template \ name, Capture, IsClass> name2(X x, Capture y, Z z) { \ return name(x, y, z); \ } \ template \ name, IsClass> name2(Capture x, Y y, Z z) { \ return name(x, y, z); \ } \ template \ name, Capture, Capture> name2(X x, Capture y, Capture z) { \ return name(x, y, z); \ } \ template \ name, Capture> name2(Capture x, Y y, Capture z) { \ return name(x, y, z); \ } \ template \ name> name2(Capture x, Capture y, Z z) { \ return name(x, y, z); \ } template struct Assign { X x; Y y; template Assign(Arg1 arg1, Arg2 arg2) : x(arg1), y(arg2) {} template HOST_DEVICE_INLINE T operator()(T&& arg, Args&&... args) { return x(arg, args...) = y(arg, args...); } std::string to_string() const { return "Assign<" + x.to_string() + "," + y.to_string() + ">"; } }; template struct Assignee { Var var; Assignee() {} Assignee(Var v) : var(v) {} template HOST_DEVICE_INLINE T& operator()(T&& arg, Args&&... args) { return var(arg, args...); } template Assign, IsClass> operator=(X x) { return Assign, X>(var, x); } Assign, Capture> operator=(Capture x) { return Assign, Capture>(var, x); } template auto operator+=(X x) -> decltype(*this = *this + x) { return *this = *this + x; } template auto operator-=(X x) -> decltype(*this = *this - x) { return *this = *this - x; } template auto operator*=(X x) -> decltype(*this = *this * x) { return *this = *this * x; } template auto operator/=(X x) -> decltype(*this = *this / x) { return *this = *this / x; } std::string to_string() const { return var.to_string(); } }; /******************************************************************************/ } // namespace functional } // namespace marian