1 // This file is part of Eigen, a lightweight C++ template library 2 // for linear algebra. 3 // 4 // Copyright (C) 2008-2010 Gael Guennebaud <[email protected]> 5 // 6 // This Source Code Form is subject to the terms of the Mozilla 7 // Public License v. 2.0. If a copy of the MPL was not distributed 8 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 9 10 #ifndef EIGEN_STL_FUNCTORS_H 11 #define EIGEN_STL_FUNCTORS_H 12 13 namespace Eigen { 14 15 // Portable replacements for certain functors. 16 namespace numext { 17 18 template<typename T = void> 19 struct equal_to { 20 typedef bool result_type; operatorequal_to21 EIGEN_DEVICE_FUNC bool operator()(const T& lhs, const T& rhs) const { 22 return lhs == rhs; 23 } 24 }; 25 26 template<typename T = void> 27 struct not_equal_to { 28 typedef bool result_type; operatornot_equal_to29 EIGEN_DEVICE_FUNC bool operator()(const T& lhs, const T& rhs) const { 30 return lhs != rhs; 31 } 32 }; 33 34 } 35 36 37 namespace internal { 38 39 // default functor traits for STL functors: 40 41 template<typename T> 42 struct functor_traits<std::multiplies<T> > 43 { enum { Cost = NumTraits<T>::MulCost, PacketAccess = false }; }; 44 45 template<typename T> 46 struct functor_traits<std::divides<T> > 47 { enum { Cost = NumTraits<T>::MulCost, PacketAccess = false }; }; 48 49 template<typename T> 50 struct functor_traits<std::plus<T> > 51 { enum { Cost = NumTraits<T>::AddCost, PacketAccess = false }; }; 52 53 template<typename T> 54 struct functor_traits<std::minus<T> > 55 { enum { Cost = NumTraits<T>::AddCost, PacketAccess = false }; }; 56 57 template<typename T> 58 struct functor_traits<std::negate<T> > 59 { enum { Cost = NumTraits<T>::AddCost, PacketAccess = false }; }; 60 61 template<typename T> 62 struct functor_traits<std::logical_or<T> > 63 { enum { Cost = 1, PacketAccess = false }; }; 64 65 template<typename T> 66 struct functor_traits<std::logical_and<T> > 67 { enum { Cost = 1, PacketAccess = false }; }; 68 69 template<typename T> 70 struct functor_traits<std::logical_not<T> > 71 { enum { Cost = 1, PacketAccess = false }; }; 72 73 template<typename T> 74 struct functor_traits<std::greater<T> > 75 { enum { Cost = 1, PacketAccess = false }; }; 76 77 template<typename T> 78 struct functor_traits<std::less<T> > 79 { enum { Cost = 1, PacketAccess = false }; }; 80 81 template<typename T> 82 struct functor_traits<std::greater_equal<T> > 83 { enum { Cost = 1, PacketAccess = false }; }; 84 85 template<typename T> 86 struct functor_traits<std::less_equal<T> > 87 { enum { Cost = 1, PacketAccess = false }; }; 88 89 template<typename T> 90 struct functor_traits<std::equal_to<T> > 91 { enum { Cost = 1, PacketAccess = false }; }; 92 93 template<typename T> 94 struct functor_traits<numext::equal_to<T> > 95 : functor_traits<std::equal_to<T> > {}; 96 97 template<typename T> 98 struct functor_traits<std::not_equal_to<T> > 99 { enum { Cost = 1, PacketAccess = false }; }; 100 101 template<typename T> 102 struct functor_traits<numext::not_equal_to<T> > 103 : functor_traits<std::not_equal_to<T> > {}; 104 105 #if (EIGEN_COMP_CXXVER < 11) 106 // std::binder* are deprecated since c++11 and will be removed in c++17 107 template<typename T> 108 struct functor_traits<std::binder2nd<T> > 109 { enum { Cost = functor_traits<T>::Cost, PacketAccess = false }; }; 110 111 template<typename T> 112 struct functor_traits<std::binder1st<T> > 113 { enum { Cost = functor_traits<T>::Cost, PacketAccess = false }; }; 114 #endif 115 116 #if (EIGEN_COMP_CXXVER < 17) 117 // std::unary_negate is deprecated since c++17 and will be removed in c++20 118 template<typename T> 119 struct functor_traits<std::unary_negate<T> > 120 { enum { Cost = 1 + functor_traits<T>::Cost, PacketAccess = false }; }; 121 122 // std::binary_negate is deprecated since c++17 and will be removed in c++20 123 template<typename T> 124 struct functor_traits<std::binary_negate<T> > 125 { enum { Cost = 1 + functor_traits<T>::Cost, PacketAccess = false }; }; 126 #endif 127 128 #ifdef EIGEN_STDEXT_SUPPORT 129 130 template<typename T0,typename T1> 131 struct functor_traits<std::project1st<T0,T1> > 132 { enum { Cost = 0, PacketAccess = false }; }; 133 134 template<typename T0,typename T1> 135 struct functor_traits<std::project2nd<T0,T1> > 136 { enum { Cost = 0, PacketAccess = false }; }; 137 138 template<typename T0,typename T1> 139 struct functor_traits<std::select2nd<std::pair<T0,T1> > > 140 { enum { Cost = 0, PacketAccess = false }; }; 141 142 template<typename T0,typename T1> 143 struct functor_traits<std::select1st<std::pair<T0,T1> > > 144 { enum { Cost = 0, PacketAccess = false }; }; 145 146 template<typename T0,typename T1> 147 struct functor_traits<std::unary_compose<T0,T1> > 148 { enum { Cost = functor_traits<T0>::Cost + functor_traits<T1>::Cost, PacketAccess = false }; }; 149 150 template<typename T0,typename T1,typename T2> 151 struct functor_traits<std::binary_compose<T0,T1,T2> > 152 { enum { Cost = functor_traits<T0>::Cost + functor_traits<T1>::Cost + functor_traits<T2>::Cost, PacketAccess = false }; }; 153 154 #endif // EIGEN_STDEXT_SUPPORT 155 156 // allow to add new functors and specializations of functor_traits from outside Eigen. 157 // this macro is really needed because functor_traits must be specialized after it is declared but before it is used... 158 #ifdef EIGEN_FUNCTORS_PLUGIN 159 #include EIGEN_FUNCTORS_PLUGIN 160 #endif 161 162 } // end namespace internal 163 164 } // end namespace Eigen 165 166 #endif // EIGEN_STL_FUNCTORS_H 167