//============================================================================ // Copyright (c) Kitware, Inc. // All rights reserved. // See LICENSE.txt for details. // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notice for more information. //============================================================================ #ifndef vtk_m_BinaryOperators_h #define vtk_m_BinaryOperators_h #include #include namespace vtkm { // Disable conversion warnings for Sum and Product on GCC only. // GCC creates false positive warnings for signed/unsigned char* operations. // This occurs because the values are implicitly casted up to int's for the // operation, and than casted back down to char's when return. // This causes a false positive warning, even when the values is within // the value types range #if (defined(VTKM_GCC) || defined(VTKM_CLANG)) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wconversion" #endif // gcc || clang /// Binary Predicate that takes two arguments argument \c x, and \c y and /// returns sum (addition) of the two values. /// @note Requires a suitable definition of `operator+(T, U)`. struct Sum { template VTKM_EXEC_CONT auto operator()(const T& x, const U& y) const -> decltype(x + y) { return x + y; } // If both types are the same integral type, explicitly cast the result to // type T to avoid narrowing conversion warnings from operations that promote // to int (e.g. `int operator+(char, char)`) template VTKM_EXEC_CONT typename std::enable_if::value && sizeof(T) < sizeof(int), T>::type operator()(const T& x, const T& y) const { return static_cast(x + y); } }; /// Binary Predicate that takes two arguments argument \c x, and \c y and /// returns product (multiplication) of the two values. /// @note Requires a suitable definition of `operator*(T, U)`. struct Product { template VTKM_EXEC_CONT auto operator()(const T& x, const U& y) const -> decltype(x * y) { return x * y; } // If both types are the same integral type, explicitly cast the result to // type T to avoid narrowing conversion warnings from operations that promote // to int (e.g. `int operator+(char, char)`) template VTKM_EXEC_CONT typename std::enable_if::value && sizeof(T) < sizeof(int), T>::type operator()(const T& x, const T& y) const { return static_cast(x * y); } }; #if (defined(VTKM_GCC) || defined(VTKM_CLANG)) #pragma GCC diagnostic pop #endif // gcc || clang /// Binary Predicate that takes two arguments argument \c x, and \c y and /// returns the \c x if x > y otherwise returns \c y. /// @note Requires a suitable definition of `bool operator<(T, U)` and that /// `T` and `U` share a common type. //needs to be full length to not clash with vtkm::math function Max. struct Maximum { template VTKM_EXEC_CONT typename std::common_type::type operator()(const T& x, const U& y) const { return x < y ? y : x; } }; /// Binary Predicate that takes two arguments argument \c x, and \c y and /// returns the \c x if x < y otherwise returns \c y. /// @note Requires a suitable definition of `bool operator<(T, U)` and that /// `T` and `U` share a common type. //needs to be full length to not clash with vtkm::math function Min. struct Minimum { template VTKM_EXEC_CONT typename std::common_type::type operator()(const T& x, const U& y) const { return x < y ? x : y; } }; /// Binary Predicate that takes two arguments argument \c x, and \c y and /// returns a vtkm::Vec that represents the minimum and maximum values. /// Note: Requires Type \p T implement the vtkm::Min and vtkm::Max functions. template struct MinAndMax { VTKM_EXEC_CONT vtkm::Vec operator()(const T& a) const { return vtkm::make_Vec(a, a); } VTKM_EXEC_CONT vtkm::Vec operator()(const T& a, const T& b) const { return vtkm::make_Vec(vtkm::Min(a, b), vtkm::Max(a, b)); } VTKM_EXEC_CONT vtkm::Vec operator()(const vtkm::Vec& a, const vtkm::Vec& b) const { return vtkm::make_Vec(vtkm::Min(a[0], b[0]), vtkm::Max(a[1], b[1])); } VTKM_EXEC_CONT vtkm::Vec operator()(const T& a, const vtkm::Vec& b) const { return vtkm::make_Vec(vtkm::Min(a, b[0]), vtkm::Max(a, b[1])); } VTKM_EXEC_CONT vtkm::Vec operator()(const vtkm::Vec& a, const T& b) const { return vtkm::make_Vec(vtkm::Min(a[0], b), vtkm::Max(a[1], b)); } }; /// Binary Predicate that takes two arguments argument \c x, and \c y and /// returns the bitwise operation x&y /// @note Requires a suitable definition of `operator&(T, U)`. struct BitwiseAnd { template VTKM_EXEC_CONT auto operator()(const T& x, const U& y) const -> decltype(x & y) { return x & y; } // If both types are the same integral type, explicitly cast the result to // type T to avoid narrowing conversion warnings from operations that promote // to int (e.g. `int operator+(char, char)`) template VTKM_EXEC_CONT typename std::enable_if::value && sizeof(T) < sizeof(int), T>::type operator()(const T& x, const T& y) const { return static_cast(x & y); } }; /// Binary Predicate that takes two arguments argument \c x, and \c y and /// returns the bitwise operation x|y /// @note Requires a suitable definition of `operator&(T, U)`. struct BitwiseOr { template VTKM_EXEC_CONT auto operator()(const T& x, const U& y) const -> decltype(x | y) { return x | y; } // If both types are the same integral type, explicitly cast the result to // type T to avoid narrowing conversion warnings from operations that promote // to int (e.g. `int operator+(char, char)`) template VTKM_EXEC_CONT typename std::enable_if::value && sizeof(T) < sizeof(int), T>::type operator()(const T& x, const T& y) const { return static_cast(x | y); } }; /// Binary Predicate that takes two arguments argument \c x, and \c y and /// returns the bitwise operation x^y /// @note Requires a suitable definition of `operator&(T, U)`. struct BitwiseXor { template VTKM_EXEC_CONT auto operator()(const T& x, const U& y) const -> decltype(x ^ y) { return x ^ y; } // If both types are the same integral type, explicitly cast the result to // type T to avoid narrowing conversion warnings from operations that promote // to int (e.g. `int operator+(char, char)`) template VTKM_EXEC_CONT typename std::enable_if::value && sizeof(T) < sizeof(int), T>::type operator()(const T& x, const T& y) const { return static_cast(x ^ y); } }; } // namespace vtkm #endif //vtk_m_BinaryOperators_h