44 static constexpr bool DEFINE_RHS_LHS_OPERATOR = !has_addition_operator<Rhs, Lhs, Lhs>::value && !has_addition_operator<Rhs, Lhs, Rhs>::value;
49 static_assert(std::is_default_constructible<Lhs>::value,
"Lhs must have a default constructor");
50 static_assert(std::is_base_of<BufferBase<Lhs, LhsData>, Lhs>::value,
"Lhs must derive from BufferBase<Lhs, LhsData>");
52 std::is_base_of<BufferBase<Rhs, RhsData>, Rhs>::value || std::is_same<Rhs, RhsData>::value,
53 "Rhs must derive from BufferBase<Rhs, RhsData> or RhsData must be the same type as Rhs"
56 has_addition_operator<LhsData, RhsData>::value && has_addition_assignment_operator<LhsData, RhsData>::value,
57 "LhsData must have operator+(RhsData) and operator+=(RhsData)"
64 friend inline Lhs operator+(
const Lhs& lhs,
const Rhs& rhs)
66 return Impl<Rhs, RhsData>(lhs, rhs);
69 friend inline Lhs& operator+=(Lhs& lhs,
const Rhs& rhs)
71 return ImplAssign<Rhs, RhsData>(lhs, rhs);
74 template<
typename Ret = Lhs>
75 friend inline typename std::enable_if<DEFINE_RHS_LHS_OPERATOR, Ret>::type operator+(
const Rhs& rhs,
const Lhs& lhs)
80 template<
typename Ret>
81 friend inline typename std::enable_if<!DEFINE_RHS_LHS_OPERATOR, Ret>::type operator+(
const Rhs& rhs,
const Lhs& lhs);
84 template<
typename U = Rhs,
typename V = RhsData>
85 static inline typename std::enable_if<std::is_same<U, V>::value, Lhs>::type Impl(
const Lhs& lhs,
const U& rhs)
95 const size_t size = lhs.Size();
96 for (
size_t i = 0; i < size; ++i)
98 result.begin()[i] = lhs.begin()[i] + rhs;
103 template<
typename U = Rhs,
typename V = RhsData>
104 static inline typename std::enable_if<std::is_same<U, V>::value, Lhs&>::type ImplAssign(Lhs& lhs,
const U& rhs)
106 const size_t size = lhs.Size();
107 for (
size_t i = 0; i < size; ++i)
109 lhs.begin()[i] += rhs;
114 template<
typename U = Rhs,
typename V = RhsData>
115 static inline typename std::enable_if<std::is_base_of<BufferBase<U, V>, U>::value, Lhs>::type Impl(
const Lhs& lhs,
const U& rhs)
117 if (lhs.Size() != rhs.Size())
127 "BufferOperatorEvents::OnResultCreated event must be handled"));
131 const size_t size = lhs.Size();
132 for (
size_t i = 0; i < size; ++i)
134 result.begin()[i] = lhs.begin()[i] + rhs.begin()[i];
139 template<
typename U = Rhs,
typename V = RhsData>
140 static inline typename std::enable_if<std::is_base_of<BufferBase<U, V>, U>::value, Lhs&>::type ImplAssign(Lhs& lhs,
const U& rhs)
142 const size_t minSize =
HEPH_MATH_MIN(lhs.Size(), rhs.Size());
143 for (
size_t i = 0; i < minSize; ++i)
145 lhs.begin()[i] += rhs.begin()[i];
159 static constexpr bool DEFINE_RHS_LHS_OPERATOR = !has_subtraction_operator<Rhs, Lhs, Lhs>::value && !has_subtraction_operator<Rhs, Lhs, Rhs>::value;
164 static_assert(std::is_default_constructible<Lhs>::value,
"Lhs must have a default constructor");
165 static_assert(std::is_base_of<BufferBase<Lhs, LhsData>, Lhs>::value,
"Lhs must derive from BufferBase<Lhs, LhsData>");
167 std::is_base_of<BufferBase<Rhs, RhsData>, Rhs>::value || std::is_same<Rhs, RhsData>::value,
168 "Rhs must derive from BufferBase<Rhs, RhsData> or RhsData must be the same type as Rhs"
171 has_subtraction_operator<LhsData, RhsData>::value && has_subtraction_assignment_operator<LhsData, RhsData>::value,
172 "LhsData must have operator-(RhsData) and operator-=(RhsData)"
179 friend inline Lhs operator-(
const Lhs& lhs,
const Rhs& rhs)
181 return Impl<Rhs, RhsData>(lhs, rhs);
184 friend inline Lhs& operator-=(Lhs& lhs,
const Rhs& rhs)
186 return ImplAssign<Rhs, RhsData>(lhs, rhs);
189 template<
typename Ret = Lhs>
190 friend inline typename std::enable_if<DEFINE_RHS_LHS_OPERATOR, Ret>::type operator-(
const Rhs& rhs,
const Lhs& lhs)
192 return ImplRhs<Rhs, RhsData>(rhs, lhs);
195 template<
typename Ret>
196 friend inline typename std::enable_if<!DEFINE_RHS_LHS_OPERATOR, Ret>::type operator-(
const Rhs& rhs,
const Lhs& lhs);
199 template<
typename U = Rhs,
typename V = RhsData>
200 static inline typename std::enable_if<std::is_same<U, V>::value, Lhs>::type Impl(
const Lhs& lhs,
const U& rhs)
210 const size_t size = lhs.Size();
211 for (
size_t i = 0; i < size; ++i)
213 result.begin()[i] = lhs.begin()[i] - rhs;
218 template<
typename U = Rhs,
typename V = RhsData>
219 static inline typename std::enable_if<DEFINE_RHS_LHS_OPERATOR&& std::is_same<U, V>::value, Lhs>::type ImplRhs(
const U& rhs,
const Lhs& lhs)
229 const size_t size = lhs.Size();
230 for (
size_t i = 0; i < size; ++i)
232 result.begin()[i] = rhs - lhs.begin()[i];
237 template<
typename U = Rhs,
typename V = RhsData>
238 static inline typename std::enable_if<std::is_same<U, V>::value, Lhs&>::type ImplAssign(Lhs& lhs,
const U& rhs)
240 const size_t size = lhs.Size();
241 for (
size_t i = 0; i < size; ++i)
243 lhs.begin()[i] -= rhs;
248 template<
typename U = Rhs,
typename V = RhsData>
249 static inline typename std::enable_if<std::is_base_of<BufferBase<U, V>, U>::value, Lhs>::type Impl(
const Lhs& lhs,
const U& rhs)
251 if (lhs.Size() != rhs.Size())
261 "BufferOperatorEvents::OnResultCreated event must be handled"));
265 const size_t size = lhs.Size();
266 for (
size_t i = 0; i < size; ++i)
268 result.begin()[i] = lhs.begin()[i] - rhs.begin()[i];
273 template<
typename U = Rhs,
typename V = RhsData>
274 static inline typename std::enable_if<DEFINE_RHS_LHS_OPERATOR&& std::is_base_of<BufferBase<U, V>, U>::value, Lhs>::type ImplRhs(
const U& rhs,
const Lhs& lhs)
276 if (lhs.Size() != rhs.Size())
286 "BufferOperatorEvents::OnResultCreated event must be handled"));
290 const size_t size = lhs.Size();
291 for (
size_t i = 0; i < size; ++i)
293 result.begin()[i] = rhs.begin()[i] - lhs.begin()[i];
298 template<
typename U = Rhs,
typename V = RhsData>
299 static inline typename std::enable_if<std::is_base_of<BufferBase<U, V>, U>::value, Lhs&>::type ImplAssign(Lhs& lhs,
const U& rhs)
301 const size_t minSize =
HEPH_MATH_MIN(lhs.Size(), rhs.Size());
302 for (
size_t i = 0; i < minSize; ++i)
304 lhs.begin()[i] -= rhs.begin()[i];
318 static constexpr bool DEFINE_RHS_LHS_OPERATOR = !has_multiplication_operator<Rhs, Lhs, Lhs>::value && !has_multiplication_operator<Rhs, Lhs, Rhs>::value;
323 static_assert(std::is_default_constructible<Lhs>::value,
"Lhs must have a default constructor");
324 static_assert(std::is_base_of<BufferBase<Lhs, LhsData>, Lhs>::value,
"Lhs must derive from BufferBase<Lhs, LhsData>");
326 std::is_base_of<BufferBase<Rhs, RhsData>, Rhs>::value || std::is_same<Rhs, RhsData>::value,
327 "Rhs must derive from BufferBase<Rhs, RhsData> or RhsData must be the same type as Rhs"
330 has_multiplication_operator<LhsData, RhsData>::value && has_multiplication_operator<LhsData, RhsData>::value,
331 "LhsData must have operator*(RhsData) and operator*=(RhsData)"
338 friend inline Lhs operator*(
const Lhs& lhs,
const Rhs& rhs)
340 return Impl<Rhs, RhsData>(lhs, rhs);
343 friend inline Lhs& operator*=(Lhs& lhs,
const Rhs& rhs)
345 return ImplAssign<Rhs, RhsData>(lhs, rhs);
348 template<
typename Ret = Lhs>
349 friend inline typename std::enable_if<DEFINE_RHS_LHS_OPERATOR, Ret>::type operator*(
const Rhs& rhs,
const Lhs& lhs)
354 template<
typename Ret>
355 friend inline typename std::enable_if<!DEFINE_RHS_LHS_OPERATOR, Ret>::type operator*(
const Rhs& rhs,
const Lhs& lhs);
358 template<
typename U = Rhs,
typename V = RhsData>
359 static inline typename std::enable_if<std::is_same<U, V>::value, Lhs>::type Impl(
const Lhs& lhs,
const U& rhs)
369 const size_t size = lhs.Size();
370 for (
size_t i = 0; i < size; ++i)
372 result.begin()[i] = lhs.begin()[i] * rhs;
377 template<
typename U = Rhs,
typename V = RhsData>
378 static inline typename std::enable_if<std::is_same<U, V>::value, Lhs&>::type ImplAssign(Lhs& lhs,
const U& rhs)
380 const size_t size = lhs.Size();
381 for (
size_t i = 0; i < size; ++i)
383 lhs.begin()[i] *= rhs;
388 template<
typename U = Rhs,
typename V = RhsData>
389 static inline typename std::enable_if<std::is_base_of<BufferBase<U, V>, U>::value, Lhs>::type Impl(
const Lhs& lhs,
const U& rhs)
391 if (lhs.Size() != rhs.Size())
401 "BufferOperatorEvents::OnResultCreated event must be handled"));
405 const size_t size = lhs.Size();
406 for (
size_t i = 0; i < size; ++i)
408 result.begin()[i] = lhs.begin()[i] * rhs.begin()[i];
413 template<
typename U = Rhs,
typename V = RhsData>
414 static inline typename std::enable_if<std::is_base_of<BufferBase<U, V>, U>::value, Lhs&>::type ImplAssign(Lhs& lhs,
const U& rhs)
416 const size_t minSize =
HEPH_MATH_MIN(lhs.Size(), rhs.Size());
417 for (
size_t i = 0; i < minSize; ++i)
419 lhs.begin()[i] *= rhs.begin()[i];
433 static constexpr bool DEFINE_RHS_LHS_OPERATOR = !has_division_operator<Rhs, Lhs, Lhs>::value && !has_division_operator<Rhs, Lhs, Rhs>::value;
438 static_assert(std::is_default_constructible<Lhs>::value,
"Lhs must have a default constructor");
439 static_assert(std::is_base_of<BufferBase<Lhs, LhsData>, Lhs>::value,
"Lhs must derive from BufferBase<Lhs, LhsData>");
441 std::is_base_of<BufferBase<Rhs, RhsData>, Rhs>::value || std::is_same<Rhs, RhsData>::value,
442 "Rhs must derive from BufferBase<Rhs, RhsData> or RhsData must be the same type as Rhs"
445 has_division_operator<LhsData, RhsData>::value && has_division_assignment_operator<LhsData, RhsData>::value,
446 "LhsData must have operator/(RhsData) and operator/=(RhsData)"
453 friend inline Lhs operator/(
const Lhs& lhs,
const Rhs& rhs)
455 return Impl<Rhs, RhsData>(lhs, rhs);
458 friend inline Lhs& operator/=(Lhs& lhs,
const Rhs& rhs)
460 return ImplAssign<Rhs, RhsData>(lhs, rhs);
463 template<
typename Ret = Lhs>
464 friend inline typename std::enable_if<DEFINE_RHS_LHS_OPERATOR, Ret>::type operator/(
const Rhs& rhs,
const Lhs& lhs)
466 return ImplRhs<Rhs, RhsData>(rhs, lhs);
469 template<
typename Ret>
470 friend inline typename std::enable_if<!DEFINE_RHS_LHS_OPERATOR, Ret>::type operator/(
const Rhs& rhs,
const Lhs& lhs);
473 template<
typename U = Rhs,
typename V = RhsData>
474 static inline typename std::enable_if<std::is_same<U, V>::value, Lhs>::type Impl(
const Lhs& lhs,
const U& rhs)
484 const size_t size = lhs.Size();
485 for (
size_t i = 0; i < size; ++i)
487 result.begin()[i] = lhs.begin()[i] / rhs;
492 template<
typename U = Rhs,
typename V = RhsData>
493 static inline typename std::enable_if<DEFINE_RHS_LHS_OPERATOR&& std::is_same<U, V>::value, Lhs>::type ImplRhs(
const U& rhs,
const Lhs& lhs)
503 const size_t size = lhs.Size();
504 for (
size_t i = 0; i < size; ++i)
506 result.begin()[i] = rhs / lhs.begin()[i];
511 template<
typename U = Rhs,
typename V = RhsData>
512 static inline typename std::enable_if<std::is_same<U, V>::value, Lhs&>::type ImplAssign(Lhs& lhs,
const U& rhs)
514 const size_t size = lhs.Size();
515 for (
size_t i = 0; i < size; ++i)
517 lhs.begin()[i] /= rhs;
522 template<
typename U = Rhs,
typename V = RhsData>
523 static inline typename std::enable_if<std::is_base_of<BufferBase<U, V>, U>::value, Lhs>::type Impl(
const Lhs& lhs,
const U& rhs)
525 if (lhs.Size() != rhs.Size())
535 "BufferOperatorEvents::OnResultCreated event must be handled"));
539 const size_t size = lhs.Size();
540 for (
size_t i = 0; i < size; ++i)
542 result.begin()[i] = lhs.begin()[i] / rhs.begin()[i];
547 template<
typename U = Rhs,
typename V = RhsData>
548 static inline typename std::enable_if<DEFINE_RHS_LHS_OPERATOR&& std::is_base_of<BufferBase<U, V>, U>::value, Lhs>::type ImplRhs(
const U& rhs,
const Lhs& lhs)
550 if (lhs.Size() != rhs.Size())
560 "BufferOperatorEvents::OnResultCreated event must be handled"));
564 const size_t size = lhs.Size();
565 for (
size_t i = 0; i < size; ++i)
567 result.begin()[i] = rhs.begin()[i] / lhs.begin()[i];
572 template<
typename U = Rhs,
typename V = RhsData>
573 static inline typename std::enable_if<std::is_base_of<BufferBase<U, V>, U>::value, Lhs&>::type ImplAssign(Lhs& lhs,
const U& rhs)
575 const size_t minSize =
HEPH_MATH_MIN(lhs.Size(), rhs.Size());
576 for (
size_t i = 0; i < minSize; ++i)
578 lhs.begin()[i] /= rhs.begin()[i];