@@ -1943,6 +1943,109 @@ namespace grb {
19431943
19441944 };
19451945
1946+ /* *
1947+ * The logical or operator, \f$ x \lxor y \f$.
1948+ *
1949+ * Assumes that the xor operator is defined on the given input types.
1950+ */
1951+ template <
1952+ typename IN1, typename IN2, typename OUT,
1953+ enum Backend implementation = config::default_backend
1954+ >
1955+ class logical_xor {
1956+
1957+ public:
1958+
1959+ /* * Alias to the left-hand input data type. */
1960+ typedef IN1 left_type;
1961+
1962+ /* * Alias to the right-hand input data type. */
1963+ typedef IN2 right_type;
1964+
1965+ /* * Alias to the output data type. */
1966+ typedef OUT result_type;
1967+
1968+ /* * Whether this operator has an in-place foldl. */
1969+ static constexpr bool has_foldl = true ;
1970+
1971+ /* * Whether this operator has an in-place foldr. */
1972+ static constexpr bool has_foldr = true ;
1973+
1974+ /* *
1975+ * Whether this operator is \em mathematically associative; that is,
1976+ * associative when assuming equivalent data types for \a IN1, \a IN2,
1977+ * and \a OUT, as well as assuming exact arithmetic, no overflows, etc.
1978+ */
1979+ static constexpr bool is_associative = true ;
1980+
1981+ /* *
1982+ * Whether this operator is \em mathematically commutative; that is,
1983+ * commutative when assuming equivalent data types for \a IN1, \a IN2,
1984+ * and \a OUT, as well as assuming exact arithmetic, no overflows, etc.
1985+ */
1986+ static constexpr bool is_commutative = true ;
1987+
1988+ /* *
1989+ * Out-of-place application of this operator.
1990+ *
1991+ * @param[in] a The left-hand side input. Must be pre-allocated and
1992+ * initialised.
1993+ * @param[in] b The right-hand side input. Must be pre-allocated and
1994+ * initialised.
1995+ * @param[out] c The output. Must be pre-allocated.
1996+ *
1997+ * At the end of the operation, \f$ c = \min\{a,b\} \f$.
1998+ */
1999+ static void apply (
2000+ const left_type * __restrict__ const a,
2001+ const right_type * __restrict__ const b,
2002+ result_type * __restrict__ const c
2003+ ) {
2004+ if ( *a xor *b ) {
2005+ *c = static_cast < OUT >( true );
2006+ } else {
2007+ *c = static_cast < OUT >( false );
2008+ }
2009+ }
2010+
2011+ /* *
2012+ * In-place left-to-right folding.
2013+ *
2014+ * @param[in] a Pointer to the left-hand side input data.
2015+ * @param[in,out] c Pointer to the right-hand side input data. This also
2016+ * dubs as the output memory area.
2017+ */
2018+ static void foldr (
2019+ const left_type * __restrict__ const a,
2020+ result_type * __restrict__ const c
2021+ ) {
2022+ if ( *a xor *c ) {
2023+ *c = static_cast < result_type >( true );
2024+ } else {
2025+ *c = static_cast < result_type >( false );
2026+ }
2027+ }
2028+
2029+ /* *
2030+ * In-place right-to-left folding.
2031+ *
2032+ * @param[in,out] c Pointer to the left-hand side input data. This also
2033+ * dubs as the output memory area.
2034+ * @param[in] b Pointer to the right-hand side input data.
2035+ */
2036+ static void foldl (
2037+ result_type * __restrict__ const c,
2038+ const right_type * __restrict__ const b
2039+ ) {
2040+ if ( *b xor *c ) {
2041+ *c = static_cast < result_type >( true );
2042+ } else {
2043+ *c = static_cast < result_type >( false );
2044+ }
2045+ }
2046+
2047+ };
2048+
19462049 /* *
19472050 * The logical-and operator, \f$ x \land y \f$.
19482051 *
0 commit comments