1 // -*- C++ -*- 2 /** @file */ 3 #pragma once 4 5 /** \addtogroup FUSION 6 * @{ 7 */ 8 9 /** 10 * @brief Unary operator 11 * 12 * @tparam Scalar Datatype for scalar 13 * @tparam Derived Datatype representing the operator expression 14 * 15 */ 16 template<typename Scalar,typename Derived> 17 struct _UnaryOperator{ derived_UnaryOperator18 Derived& derived() {return(static_cast<Derived&>(*this));} 19 derived_UnaryOperator20 Derived const& derived() const {return(static_cast<Derived const&>(*this));} 21 operator ()_UnaryOperator22 Scalar const operator()(const Scalar lhs) const 23 { 24 return(this->derived()(lhs)); 25 } 26 27 #if defined(HAS_VECTOR) 28 using Vector= typename vector_traits<Scalar>::vector ; 29 using pred_t = typename vector_traits<Scalar>::predicate_t; 30 operator ()_UnaryOperator31 Vector const operator()(const Vector lhs) const 32 { 33 return(this->derived()(lhs)); 34 } 35 36 /* 37 38 Predicated operation when exists (Helium) 39 40 */ 41 template<typename T=Scalar, 42 typename std::enable_if<vector_traits<T>::has_predicate,bool>::type = true> operator ()_UnaryOperator43 Vector const operator()(const Vector lhs,const pred_t p0) const 44 { 45 return(this->derived()(lhs,p0)); 46 } 47 48 /* 49 Vector const to_vector(const Scalar lhs) const 50 { 51 return(this->derived().to_vector(lhs)); 52 } 53 */ 54 #endif 55 }; 56 57 /** 58 * @brief Unary operator 59 * 60 * @tparam Scalar Datatype for scalar 61 * @tparam Derived Datatype representing the operator expression 62 * 63 */ 64 template<typename Scalar,typename Derived> 65 struct _BinaryOperator{ derived_BinaryOperator66 Derived& derived() {return(static_cast<Derived&>(*this));} 67 derived_BinaryOperator68 Derived const& derived() const {return(static_cast<Derived const&>(*this));} 69 operator ()_BinaryOperator70 Scalar const operator()(const Scalar lhs, 71 const Scalar rhs) const 72 { 73 return(this->derived()(lhs,rhs)); 74 } 75 76 #if defined(HAS_VECTOR) 77 using Vector= typename vector_traits<Scalar>::vector ; 78 using pred_t = typename vector_traits<Scalar>::predicate_t; 79 80 operator ()_BinaryOperator81 Vector const operator()(const Vector lhs, 82 const Vector rhs) const 83 { 84 return(this->derived()(lhs,rhs)); 85 } 86 operator ()_BinaryOperator87 Vector const operator()(const Vector lhs, 88 const Scalar rhs) const 89 { 90 return(this->derived()(lhs,rhs)); 91 } 92 operator ()_BinaryOperator93 Vector const operator()(const Scalar lhs, 94 const Vector rhs) const 95 { 96 return(this->derived()(lhs,rhs)); 97 } 98 99 template<typename T=Scalar, 100 typename std::enable_if<vector_traits<T>::has_predicate,bool>::type = true> operator ()_BinaryOperator101 Vector const operator()(const Vector lhs, 102 const Vector rhs, 103 const pred_t p0) const 104 { 105 return(this->derived()(lhs,rhs,p0)); 106 } 107 108 template<typename T=Scalar, 109 typename std::enable_if<vector_traits<T>::has_predicate,bool>::type = true> operator ()_BinaryOperator110 Vector const operator()(const Vector lhs, 111 const Scalar rhs, 112 const pred_t p0) const 113 { 114 return(this->derived()(lhs,rhs,p0)); 115 } 116 117 template<typename T=Scalar, 118 typename std::enable_if<vector_traits<T>::has_predicate,bool>::type = true> operator ()_BinaryOperator119 Vector const operator()(const Scalar lhs, 120 const Vector rhs, 121 const pred_t p0) const 122 { 123 return(this->derived()(lhs,rhs,p0)); 124 } 125 #endif 126 }; 127 128 /* 129 * 130 * BINARY 131 * 132 */ 133 134 /** 135 * @brief Add operator 136 * 137 * @tparam Scalar Datatype for scalar 138 * 139 */ 140 template<typename Scalar> 141 struct _AddOp:_BinaryOperator<Scalar,_AddOp<Scalar>> 142 { operator ()_AddOp143 Scalar const operator()(const Scalar lhs, 144 const Scalar rhs) const { 145 return(lhs + rhs); 146 } 147 148 #if defined(HAS_VECTOR) 149 using Vector=typename vector_traits<Scalar>::vector ; 150 using pred_t = typename vector_traits<Scalar>::predicate_t; 151 operator ()_AddOp152 Vector const operator()(const Vector lhs, 153 const Vector rhs) const 154 { 155 return(inner::vadd(lhs,rhs)); 156 } 157 operator ()_AddOp158 Vector const operator()(const Vector lhs, 159 const Scalar rhs) const 160 { 161 return(inner::vadd(lhs,rhs)); 162 } 163 operator ()_AddOp164 Vector const operator()(const Scalar lhs, 165 const Vector rhs) const 166 { 167 return(inner::vadd(lhs,rhs)); 168 } 169 170 template<typename T=Scalar, 171 typename std::enable_if<vector_traits<T>::has_predicate,bool>::type = true> operator ()_AddOp172 Vector const operator()(const Vector lhs, 173 const Vector rhs, 174 const pred_t p0) const 175 { 176 return(inner::vadd(lhs,rhs,p0)); 177 } 178 179 template<typename T=Scalar, 180 typename std::enable_if<vector_traits<T>::has_predicate,bool>::type = true> operator ()_AddOp181 Vector const operator()(const Vector lhs, 182 const Scalar rhs, 183 const pred_t p0) const 184 { 185 return(inner::vadd(lhs,rhs,p0)); 186 } 187 188 template<typename T=Scalar, 189 typename std::enable_if<vector_traits<T>::has_predicate,bool>::type = true> operator ()_AddOp190 Vector const operator()(const Scalar lhs, 191 const Vector rhs, 192 const pred_t p0) const 193 { 194 return(inner::vadd(lhs,rhs,p0)); 195 } 196 #endif 197 }; 198 199 /** 200 * @brief Sub operator 201 * 202 * @tparam Scalar Datatype for scalar 203 * 204 */ 205 template<typename Scalar> 206 struct _SubOp:_BinaryOperator<Scalar,_SubOp<Scalar>> 207 { operator ()_SubOp208 Scalar const operator()(const Scalar lhs, 209 const Scalar rhs) const { 210 return(lhs - rhs); 211 } 212 213 #if defined(HAS_VECTOR) 214 using Vector=typename vector_traits<Scalar>::vector ; 215 using pred_t = typename vector_traits<Scalar>::predicate_t; 216 operator ()_SubOp217 Vector const operator()(const Vector lhs, 218 const Vector rhs) const 219 { 220 return(inner::vsub(lhs,rhs)); 221 } 222 operator ()_SubOp223 Vector const operator()(const Vector lhs, 224 const Scalar rhs) const 225 { 226 return(inner::vsub(lhs,rhs)); 227 } 228 operator ()_SubOp229 Vector const operator()(const Scalar lhs, 230 const Vector rhs) const 231 { 232 return(inner::vsub(lhs,rhs)); 233 } 234 235 template<typename T=Scalar, 236 typename std::enable_if<vector_traits<T>::has_predicate,bool>::type = true> operator ()_SubOp237 Vector const operator()(const Vector lhs, 238 const Vector rhs, 239 const pred_t p0) const 240 { 241 return(inner::vsub(lhs,rhs,p0)); 242 } 243 244 template<typename T=Scalar, 245 typename std::enable_if<vector_traits<T>::has_predicate,bool>::type = true> operator ()_SubOp246 Vector const operator()(const Vector lhs, 247 const Scalar rhs, 248 const pred_t p0) const 249 { 250 return(inner::vsub(lhs,rhs,p0)); 251 } 252 253 template<typename T=Scalar, 254 typename std::enable_if<vector_traits<T>::has_predicate,bool>::type = true> operator ()_SubOp255 Vector const operator()(const Scalar lhs, 256 const Vector rhs, 257 const pred_t p0) const 258 { 259 return(inner::vsub(lhs,rhs,p0)); 260 } 261 #endif 262 }; 263 264 265 /** 266 * @brief Mul operator 267 * 268 * @tparam Scalar Datatype for scalar 269 * 270 */ 271 template<typename Scalar> 272 struct _MulOp:_BinaryOperator<Scalar,_MulOp<Scalar>> 273 { operator ()_MulOp274 Scalar const operator()(const Scalar lhs, 275 const Scalar rhs) const { 276 return(lhs * rhs); 277 } 278 279 #if defined(HAS_VECTOR) 280 using Vector= typename vector_traits<Scalar>::vector ; 281 using pred_t = typename vector_traits<Scalar>::predicate_t; 282 operator ()_MulOp283 Vector const operator()(const Vector lhs, 284 const Vector rhs) const 285 { 286 return(inner::vmul(lhs,rhs)); 287 } 288 operator ()_MulOp289 Vector const operator()(const Vector lhs, 290 const Scalar rhs) const 291 { 292 return(inner::vmul(lhs,rhs)); 293 } 294 operator ()_MulOp295 Vector const operator()(const Scalar lhs, 296 const Vector rhs) const 297 { 298 return(inner::vmul(lhs,rhs)); 299 } 300 301 template<typename T=Scalar, 302 typename std::enable_if<vector_traits<T>::has_predicate,bool>::type = true> operator ()_MulOp303 Vector const operator()(const Vector lhs, 304 const Vector rhs, 305 const pred_t p0) const 306 { 307 return(inner::vmul(lhs,rhs,p0)); 308 } 309 310 template<typename T=Scalar, 311 typename std::enable_if<vector_traits<T>::has_predicate,bool>::type = true> operator ()_MulOp312 Vector const operator()(const Vector lhs, 313 const Scalar rhs, 314 const pred_t p0) const 315 { 316 return(inner::vmul(lhs,rhs,p0)); 317 } 318 319 template<typename T=Scalar, 320 typename std::enable_if<vector_traits<T>::has_predicate,bool>::type = true> operator ()_MulOp321 Vector const operator()(const Scalar lhs, 322 const Vector rhs, 323 const pred_t p0) const 324 { 325 return(inner::vmul(lhs,rhs,p0)); 326 } 327 #endif 328 }; 329 330 /* 331 * 332 * UNARY 333 * 334 */ 335 336 /** 337 * @brief Neg operator 338 * 339 * @tparam Scalar Datatype for scalar 340 * 341 */ 342 template<typename Scalar> 343 struct _NegOp:_UnaryOperator<Scalar,_NegOp<Scalar>> 344 { operator ()_NegOp345 Scalar const operator()(const Scalar lhs) const { 346 return(-lhs); 347 } 348 349 #if defined(HAS_VECTOR) 350 using Vector= typename vector_traits<Scalar>::vector ; 351 using pred_t = typename vector_traits<Scalar>::predicate_t; 352 operator ()_NegOp353 Vector const operator()(const Vector lhs) const 354 { 355 return(inner::vneg(lhs)); 356 } 357 358 template<typename T=Scalar, 359 typename std::enable_if<vector_traits<T>::has_predicate,bool>::type = true> operator ()_NegOp360 Vector const operator()(const Vector lhs, 361 const pred_t p0) const 362 { 363 return(inner::vneg(lhs,p0)); 364 } 365 366 367 #endif 368 }; 369 370 371 /** 372 * @brief No operator 373 * 374 * @tparam Scalar Datatype for scalar 375 * 376 */ 377 template<typename Scalar> 378 struct _NoOp:_UnaryOperator<Scalar,_NoOp<Scalar>> 379 { operator ()_NoOp380 Scalar const operator()(const Scalar lhs) const { 381 return(lhs); 382 } 383 384 #if defined(HAS_VECTOR) 385 using Vector= typename vector_traits<Scalar>::vector ; 386 using pred_t = typename vector_traits<Scalar>::predicate_t; 387 operator ()_NoOp388 Vector const operator()(const Vector lhs) const 389 { 390 return(lhs); 391 } 392 393 template<typename T=Scalar, 394 typename std::enable_if<vector_traits<T>::has_predicate,bool>::type = true> operator ()_NoOp395 Vector const operator()(const Vector lhs, 396 const pred_t p0) const 397 { 398 (void)p0; 399 return(lhs); 400 } 401 402 #endif 403 }; 404 405 /*! @} */