12#ifndef NDARRAY_operators_h_INCLUDED
13#define NDARRAY_operators_h_INCLUDED
20#include <boost/call_traits.hpp>
21#include <boost/utility/enable_if.hpp>
38template <
typename A,
typename B>
39struct PromotingBinaryFunction {
42 typedef A first_argument_type;
43 typedef B second_argument_type;
44 typedef typename boost::call_traits<A>::param_type ParamA;
45 typedef typename boost::call_traits<B>::param_type ParamB;
46 typedef typename Promote<A,B>::Type result_type;
55template <
typename A,
typename B>
56struct BinaryPredicate {
59 typedef A first_argument_type;
60 typedef B second_argument_type;
61 typedef typename boost::call_traits<A>::param_type ParamA;
62 typedef typename boost::call_traits<B>::param_type ParamB;
63 typedef bool result_type;
72template <
class Operation>
75 typedef Operation function_type;
76 typedef const function_type & param_type;
77 typedef typename Operation::result_type result_type;
78 typedef typename Operation::first_argument_type first_argument_type;
79 typedef typename Operation::second_argument_type second_argument_type;
82template<
class Operation>
85 using result_type =
typename binary_traits<Operation>::result_type;
87 _binder1st(
typename binary_traits<Operation>::param_type x,
88 typename boost::call_traits<
typename binary_traits<Operation>::first_argument_type>::param_type y)
92 typename binary_traits<Operation>::result_type
94 typename boost::call_traits<
typename binary_traits<Operation>::second_argument_type>::param_type x)
const {
99 typename binary_traits<Operation>::function_type op;
100 typename binary_traits<Operation>::first_argument_type value;
103template<
class Operation>
106 using result_type =
typename binary_traits<Operation>::result_type;
108 _binder2nd(
typename binary_traits<Operation>::param_type x,
109 typename boost::call_traits<
typename binary_traits<Operation>::second_argument_type>::param_type y)
113 typename binary_traits<Operation>::result_type
115 typename boost::call_traits<
typename binary_traits<Operation>::first_argument_type>::param_type x)
const {
120 typename binary_traits<Operation>::function_type op;
121 typename binary_traits<Operation>::second_argument_type value;
130template <
typename Derived>
131struct AdaptableFunctionTag {
133 template <
typename OperandB,
typename A>
135 typedef typename Derived::template ScalarFunction<
136 A,
typename ExpressionTraits<OperandB>::Element
138 typedef _binder1st<BinaryFunction> Bound;
139 static Bound bind(A
const & scalar) {
140 return Bound(BinaryFunction(),scalar);
144 template <
typename OperandA,
typename B>
146 typedef typename Derived::template ScalarFunction<
147 typename ExpressionTraits<OperandA>::Element, B
149 typedef _binder2nd<BinaryFunction> Bound;
150 static Bound bind(B
const & scalar) {
151 return Bound(BinaryFunction(),scalar);
155 template <
typename OperandA,
typename OperandB>
157 typedef typename Derived::template ScalarFunction<
158 typename ExpressionTraits<OperandA>::Element,
159 typename ExpressionTraits<OperandB>::Element
172 typedef T argument_type;
173 typedef T result_type;
175 result_type operator()(argument_type arg)
const {
return ~arg; }
179 struct PlusTag :
public AdaptableFunctionTag<PlusTag> {
180 template <
typename A,
typename B>
181 struct ScalarFunction :
public PromotingBinaryFunction<A,B> {
182 typename PromotingBinaryFunction<A,B>::result_type operator()(
183 typename PromotingBinaryFunction<A,B>::ParamA a,
184 typename PromotingBinaryFunction<A,B>::ParamB b
191 struct MinusTag :
public AdaptableFunctionTag<MinusTag> {
192 template <
typename A,
typename B>
193 struct ScalarFunction :
public PromotingBinaryFunction<A,B> {
194 typename PromotingBinaryFunction<A,B>::result_type operator()(
195 typename PromotingBinaryFunction<A,B>::ParamA a,
196 typename PromotingBinaryFunction<A,B>::ParamB b
203 struct MultipliesTag :
public AdaptableFunctionTag<MultipliesTag> {
204 template <
typename A,
typename B>
205 struct ScalarFunction :
public PromotingBinaryFunction<A,B> {
206 typename PromotingBinaryFunction<A,B>::result_type operator()(
207 typename PromotingBinaryFunction<A,B>::ParamA a,
208 typename PromotingBinaryFunction<A,B>::ParamB b
215 struct DividesTag :
public AdaptableFunctionTag<DividesTag> {
216 template <
typename A,
typename B>
217 struct ScalarFunction :
public PromotingBinaryFunction<A,B> {
218 typename PromotingBinaryFunction<A,B>::result_type operator()(
219 typename PromotingBinaryFunction<A,B>::ParamA a,
220 typename PromotingBinaryFunction<A,B>::ParamB b
227 struct ModulusTag :
public AdaptableFunctionTag<ModulusTag> {
228 template <
typename A,
typename B>
229 struct ScalarFunction :
public PromotingBinaryFunction<A,B> {
230 typename PromotingBinaryFunction<A,B>::result_type operator()(
231 typename PromotingBinaryFunction<A,B>::ParamA a,
232 typename PromotingBinaryFunction<A,B>::ParamB b
239 struct BitwiseXorTag :
public AdaptableFunctionTag<BitwiseXorTag> {
240 template <
typename A,
typename B>
241 struct ScalarFunction :
public PromotingBinaryFunction<A,B> {
242 typename PromotingBinaryFunction<A,B>::result_type operator()(
243 typename PromotingBinaryFunction<A,B>::ParamA a,
244 typename PromotingBinaryFunction<A,B>::ParamB b
251 struct BitwiseOrTag :
public AdaptableFunctionTag<BitwiseOrTag> {
252 template <
typename A,
typename B>
253 struct ScalarFunction :
public PromotingBinaryFunction<A,B> {
254 typename PromotingBinaryFunction<A,B>::result_type operator()(
255 typename PromotingBinaryFunction<A,B>::ParamA a,
256 typename PromotingBinaryFunction<A,B>::ParamB b
263 struct BitwiseAndTag :
public AdaptableFunctionTag<BitwiseAndTag> {
264 template <
typename A,
typename B>
265 struct ScalarFunction :
public PromotingBinaryFunction<A,B> {
266 typename PromotingBinaryFunction<A,B>::result_type operator()(
267 typename PromotingBinaryFunction<A,B>::ParamA a,
268 typename PromotingBinaryFunction<A,B>::ParamB b
275 struct BitwiseLeftShiftTag :
public AdaptableFunctionTag<BitwiseLeftShiftTag> {
276 template <
typename A,
typename B>
277 struct ScalarFunction :
public PromotingBinaryFunction<A,B> {
278 typename PromotingBinaryFunction<A,B>::result_type operator()(
279 typename PromotingBinaryFunction<A,B>::ParamA a,
280 typename PromotingBinaryFunction<A,B>::ParamB b
287 struct BitwiseRightShiftTag :
public AdaptableFunctionTag<BitwiseRightShiftTag> {
288 template <
typename A,
typename B>
289 struct ScalarFunction :
public PromotingBinaryFunction<A,B> {
290 typename PromotingBinaryFunction<A,B>::result_type operator()(
291 typename PromotingBinaryFunction<A,B>::ParamA a,
292 typename PromotingBinaryFunction<A,B>::ParamB b
300 struct EqualToTag :
public AdaptableFunctionTag<EqualToTag> {
301 template <
typename A,
typename B>
302 struct ScalarFunction :
public BinaryPredicate<A,B> {
303 typename BinaryPredicate<A,B>::result_type operator()(
304 typename BinaryPredicate<A,B>::ParamA a,
305 typename BinaryPredicate<A,B>::ParamB b
312 struct NotEqualToTag :
public AdaptableFunctionTag<NotEqualToTag> {
313 template <
typename A,
typename B>
314 struct ScalarFunction :
public BinaryPredicate<A,B> {
315 typename BinaryPredicate<A,B>::result_type operator()(
316 typename BinaryPredicate<A,B>::ParamA a,
317 typename BinaryPredicate<A,B>::ParamB b
324 struct LessTag :
public AdaptableFunctionTag<LessTag> {
325 template <
typename A,
typename B>
326 struct ScalarFunction :
public BinaryPredicate<A,B> {
327 typename BinaryPredicate<A,B>::result_type operator()(
328 typename BinaryPredicate<A,B>::ParamA a,
329 typename BinaryPredicate<A,B>::ParamB b
336 struct GreaterTag :
public AdaptableFunctionTag<GreaterTag> {
337 template <
typename A,
typename B>
338 struct ScalarFunction :
public BinaryPredicate<A,B> {
339 typename BinaryPredicate<A,B>::result_type operator()(
340 typename BinaryPredicate<A,B>::ParamA a,
341 typename BinaryPredicate<A,B>::ParamB b
348 struct LessEqualTag :
public AdaptableFunctionTag<LessEqualTag> {
349 template <
typename A,
typename B>
350 struct ScalarFunction :
public BinaryPredicate<A,B> {
351 typename BinaryPredicate<A,B>::result_type operator()(
352 typename BinaryPredicate<A,B>::ParamA a,
353 typename BinaryPredicate<A,B>::ParamB b
360 struct GreaterEqualTag :
public AdaptableFunctionTag<GreaterEqualTag> {
361 template <
typename A,
typename B>
362 struct ScalarFunction :
public BinaryPredicate<A,B> {
363 typename BinaryPredicate<A,B>::result_type operator()(
364 typename BinaryPredicate<A,B>::ParamA a,
365 typename BinaryPredicate<A,B>::ParamB b
372 struct LogicalAnd :
public AdaptableFunctionTag<LogicalAnd> {
373 template <
typename A,
typename B>
374 struct ScalarFunction :
public BinaryPredicate<A,B> {
375 typename BinaryPredicate<A,B>::result_type operator()(
376 typename BinaryPredicate<A,B>::ParamA a,
377 typename BinaryPredicate<A,B>::ParamB b
384 struct LogicalOr :
public AdaptableFunctionTag<LogicalOr> {
385 template <
typename A,
typename B>
386 struct ScalarFunction :
public BinaryPredicate<A,B> {
387 typename BinaryPredicate<A,B>::result_type operator()(
388 typename BinaryPredicate<A,B>::ParamA a,
389 typename BinaryPredicate<A,B>::ParamB b
402 template <
typename Operand,
typename Scalar>
404 typename boost::enable_if<
405 typename ExpressionTraits<Scalar>::IsScalar,
406 detail::UnaryOpExpression< Operand, typename detail::PlusTag::template ExprScalar<Operand,Scalar>::Bound >
409 <unspecified-expression-type>
411 operator+(ExpressionBase<Operand>
const & operand, Scalar
const & scalar) {
412 return vectorize(detail::PlusTag::template ExprScalar<Operand,Scalar>::bind(scalar),operand);
415 template <
typename Operand,
typename Scalar>
417 typename boost::enable_if<
418 typename ExpressionTraits<Scalar>::IsScalar,
419 detail::UnaryOpExpression< Operand, typename detail::PlusTag::template ScalarExpr<Operand,Scalar>::Bound >
422 <unspecified-expression-type>
424 operator+(Scalar
const & scalar, ExpressionBase<Operand>
const & operand) {
425 return vectorize(detail::PlusTag::template ScalarExpr<Operand,Scalar>::bind(scalar),operand);
428 template <
typename Operand1,
typename Operand2>
430 detail::BinaryOpExpression<
432 typename detail::PlusTag::template ExprExpr<Operand1,Operand2>::BinaryFunction
435 <unspecified-expression-type>
437 operator+(ExpressionBase<Operand1>
const & operand1, ExpressionBase<Operand2>
const & operand2) {
439 typename detail::PlusTag::template ExprExpr<Operand1,Operand2>::BinaryFunction(),
445 template <
typename Operand,
typename Scalar>
447 typename boost::enable_if<
448 typename ExpressionTraits<Scalar>::IsScalar,
449 detail::UnaryOpExpression< Operand, typename detail::MinusTag::template ExprScalar<Operand,Scalar>::Bound >
452 <unspecified-expression-type>
454 operator-(ExpressionBase<Operand>
const & operand, Scalar
const & scalar) {
455 return vectorize(detail::MinusTag::template ExprScalar<Operand,Scalar>::bind(scalar),operand);
458 template <
typename Operand,
typename Scalar>
460 typename boost::enable_if<
461 typename ExpressionTraits<Scalar>::IsScalar,
462 detail::UnaryOpExpression< Operand, typename detail::MinusTag::template ScalarExpr<Operand,Scalar>::Bound >
465 <unspecified-expression-type>
467 operator-(Scalar
const & scalar, ExpressionBase<Operand>
const & operand) {
468 return vectorize(detail::MinusTag::template ScalarExpr<Operand,Scalar>::bind(scalar),operand);
471 template <
typename Operand1,
typename Operand2>
473 detail::BinaryOpExpression<
475 typename detail::MinusTag::template ExprExpr<Operand1,Operand2>::BinaryFunction
478 <unspecified-expression-type>
480 operator-(ExpressionBase<Operand1>
const & operand1, ExpressionBase<Operand2>
const & operand2) {
482 typename detail::MinusTag::template ExprExpr<Operand1,Operand2>::BinaryFunction(),
488 template <
typename Operand,
typename Scalar>
490 typename boost::enable_if<
491 typename ExpressionTraits<Scalar>::IsScalar,
492 detail::UnaryOpExpression< Operand, typename detail::MultipliesTag::template ExprScalar<Operand,Scalar>::Bound >
495 <unspecified-expression-type>
497 operator*(ExpressionBase<Operand>
const & operand, Scalar
const & scalar) {
498 return vectorize(detail::MultipliesTag::template ExprScalar<Operand,Scalar>::bind(scalar),operand);
501 template <
typename Operand,
typename Scalar>
503 typename boost::enable_if<
504 typename ExpressionTraits<Scalar>::IsScalar,
505 detail::UnaryOpExpression< Operand, typename detail::MultipliesTag::template ScalarExpr<Operand,Scalar>::Bound >
508 <unspecified-expression-type>
510 operator*(Scalar
const & scalar, ExpressionBase<Operand>
const & operand) {
511 return vectorize(detail::MultipliesTag::template ScalarExpr<Operand,Scalar>::bind(scalar),operand);
514 template <
typename Operand1,
typename Operand2>
516 detail::BinaryOpExpression<
518 typename detail::MultipliesTag::template ExprExpr<Operand1,Operand2>::BinaryFunction
521 <unspecified-expression-type>
523 operator*(ExpressionBase<Operand1>
const & operand1, ExpressionBase<Operand2>
const & operand2) {
525 typename detail::MultipliesTag::template ExprExpr<Operand1,Operand2>::BinaryFunction(),
531 template <
typename Operand,
typename Scalar>
533 typename boost::enable_if<
534 typename ExpressionTraits<Scalar>::IsScalar,
535 detail::UnaryOpExpression< Operand, typename detail::DividesTag::template ExprScalar<Operand,Scalar>::Bound >
538 <unspecified-expression-type>
540 operator/(ExpressionBase<Operand>
const & operand, Scalar
const & scalar) {
541 return vectorize(detail::DividesTag::template ExprScalar<Operand,Scalar>::bind(scalar),operand);
544 template <
typename Operand,
typename Scalar>
546 typename boost::enable_if<
547 typename ExpressionTraits<Scalar>::IsScalar,
548 detail::UnaryOpExpression< Operand, typename detail::DividesTag::template ScalarExpr<Operand,Scalar>::Bound >
551 <unspecified-expression-type>
553 operator/(Scalar
const & scalar, ExpressionBase<Operand>
const & operand) {
554 return vectorize(detail::DividesTag::template ScalarExpr<Operand,Scalar>::bind(scalar),operand);
557 template <
typename Operand1,
typename Operand2>
559 detail::BinaryOpExpression<
561 typename detail::DividesTag::template ExprExpr<Operand1,Operand2>::BinaryFunction
564 <unspecified-expression-type>
566 operator/(ExpressionBase<Operand1>
const & operand1, ExpressionBase<Operand2>
const & operand2) {
568 typename detail::DividesTag::template ExprExpr<Operand1,Operand2>::BinaryFunction(),
574 template <
typename Operand,
typename Scalar>
576 typename boost::enable_if<
577 typename ExpressionTraits<Scalar>::IsScalar,
578 detail::UnaryOpExpression< Operand, typename detail::ModulusTag::template ExprScalar<Operand,Scalar>::Bound >
581 <unspecified-expression-type>
583 operator%(ExpressionBase<Operand>
const & operand, Scalar
const & scalar) {
584 return vectorize(detail::ModulusTag::template ExprScalar<Operand,Scalar>::bind(scalar),operand);
587 template <
typename Operand,
typename Scalar>
589 typename boost::enable_if<
590 typename ExpressionTraits<Scalar>::IsScalar,
591 detail::UnaryOpExpression< Operand, typename detail::ModulusTag::template ScalarExpr<Operand,Scalar>::Bound >
594 <unspecified-expression-type>
596 operator%(Scalar
const & scalar, ExpressionBase<Operand>
const & operand) {
597 return vectorize(detail::ModulusTag::template ScalarExpr<Operand,Scalar>::bind(scalar),operand);
600 template <
typename Operand1,
typename Operand2>
602 detail::BinaryOpExpression<
604 typename detail::ModulusTag::template ExprExpr<Operand1,Operand2>::BinaryFunction
607 <unspecified-expression-type>
609 operator%(ExpressionBase<Operand1>
const & operand1, ExpressionBase<Operand2>
const & operand2) {
611 typename detail::ModulusTag::template ExprExpr<Operand1,Operand2>::BinaryFunction(),
617 template <
typename Operand,
typename Scalar>
619 typename boost::enable_if<
620 typename ExpressionTraits<Scalar>::IsScalar,
621 detail::UnaryOpExpression< Operand, typename detail::BitwiseXorTag::template ExprScalar<Operand,Scalar>::Bound >
624 <unspecified-expression-type>
626 operator^(ExpressionBase<Operand>
const & operand, Scalar
const & scalar) {
627 return vectorize(detail::BitwiseXorTag::template ExprScalar<Operand,Scalar>::bind(scalar),operand);
630 template <
typename Operand,
typename Scalar>
632 typename boost::enable_if<
633 typename ExpressionTraits<Scalar>::IsScalar,
634 detail::UnaryOpExpression< Operand, typename detail::BitwiseXorTag::template ScalarExpr<Operand,Scalar>::Bound >
637 <unspecified-expression-type>
639 operator^(Scalar
const & scalar, ExpressionBase<Operand>
const & operand) {
640 return vectorize(detail::BitwiseXorTag::template ScalarExpr<Operand,Scalar>::bind(scalar),operand);
643 template <
typename Operand1,
typename Operand2>
645 detail::BinaryOpExpression<
647 typename detail::BitwiseXorTag::template ExprExpr<Operand1,Operand2>::BinaryFunction
650 <unspecified-expression-type>
652 operator^(ExpressionBase<Operand1>
const & operand1, ExpressionBase<Operand2>
const & operand2) {
654 typename detail::BitwiseXorTag::template ExprExpr<Operand1,Operand2>::BinaryFunction(),
660 template <
typename Operand,
typename Scalar>
662 typename boost::enable_if<
663 typename ExpressionTraits<Scalar>::IsScalar,
664 detail::UnaryOpExpression< Operand, typename detail::BitwiseOrTag::template ExprScalar<Operand,Scalar>::Bound >
667 <unspecified-expression-type>
669 operator|(ExpressionBase<Operand>
const & operand, Scalar
const & scalar) {
670 return vectorize(detail::BitwiseOrTag::template ExprScalar<Operand,Scalar>::bind(scalar),operand);
673 template <
typename Operand,
typename Scalar>
675 typename boost::enable_if<
676 typename ExpressionTraits<Scalar>::IsScalar,
677 detail::UnaryOpExpression< Operand, typename detail::BitwiseOrTag::template ScalarExpr<Operand,Scalar>::Bound >
680 <unspecified-expression-type>
682 operator|(Scalar
const & scalar, ExpressionBase<Operand>
const & operand) {
683 return vectorize(detail::BitwiseOrTag::template ScalarExpr<Operand,Scalar>::bind(scalar),operand);
686 template <
typename Operand1,
typename Operand2>
688 detail::BinaryOpExpression<
690 typename detail::BitwiseOrTag::template ExprExpr<Operand1,Operand2>::BinaryFunction
693 <unspecified-expression-type>
695 operator|(ExpressionBase<Operand1>
const & operand1, ExpressionBase<Operand2>
const & operand2) {
697 typename detail::BitwiseOrTag::template ExprExpr<Operand1,Operand2>::BinaryFunction(),
703 template <
typename Operand,
typename Scalar>
705 typename boost::enable_if<
706 typename ExpressionTraits<Scalar>::IsScalar,
707 detail::UnaryOpExpression< Operand, typename detail::BitwiseAndTag::template ExprScalar<Operand,Scalar>::Bound >
710 <unspecified-expression-type>
712 operator&(ExpressionBase<Operand>
const & operand, Scalar
const & scalar) {
713 return vectorize(detail::BitwiseAndTag::template ExprScalar<Operand,Scalar>::bind(scalar),operand);
716 template <
typename Operand,
typename Scalar>
718 typename boost::enable_if<
719 typename ExpressionTraits<Scalar>::IsScalar,
720 detail::UnaryOpExpression< Operand, typename detail::BitwiseAndTag::template ScalarExpr<Operand,Scalar>::Bound >
723 <unspecified-expression-type>
725 operator&(Scalar
const & scalar, ExpressionBase<Operand>
const & operand) {
726 return vectorize(detail::BitwiseAndTag::template ScalarExpr<Operand,Scalar>::bind(scalar),operand);
729 template <
typename Operand1,
typename Operand2>
731 detail::BinaryOpExpression<
733 typename detail::BitwiseAndTag::template ExprExpr<Operand1,Operand2>::BinaryFunction
736 <unspecified-expression-type>
738 operator&(ExpressionBase<Operand1>
const & operand1, ExpressionBase<Operand2>
const & operand2) {
740 typename detail::BitwiseAndTag::template ExprExpr<Operand1,Operand2>::BinaryFunction(),
746 template <
typename Operand,
typename Scalar>
748 typename boost::enable_if<
749 typename ExpressionTraits<Scalar>::IsScalar,
750 detail::UnaryOpExpression< Operand, typename detail::BitwiseLeftShiftTag::template ExprScalar<Operand,Scalar>::Bound >
753 <unspecified-expression-type>
755 operator<<(ExpressionBase<Operand>
const & operand, Scalar
const & scalar) {
756 return vectorize(detail::BitwiseLeftShiftTag::template ExprScalar<Operand,Scalar>::bind(scalar),operand);
759 template <
typename Operand,
typename Scalar>
761 typename boost::enable_if<
762 typename ExpressionTraits<Scalar>::IsScalar,
763 detail::UnaryOpExpression< Operand, typename detail::BitwiseLeftShiftTag::template ScalarExpr<Operand,Scalar>::Bound >
766 <unspecified-expression-type>
768 operator<<(Scalar
const & scalar, ExpressionBase<Operand>
const & operand) {
769 return vectorize(detail::BitwiseLeftShiftTag::template ScalarExpr<Operand,Scalar>::bind(scalar),operand);
772 template <
typename Operand1,
typename Operand2>
774 detail::BinaryOpExpression<
776 typename detail::BitwiseLeftShiftTag::template ExprExpr<Operand1,Operand2>::BinaryFunction
779 <unspecified-expression-type>
781 operator<<(ExpressionBase<Operand1>
const & operand1, ExpressionBase<Operand2>
const & operand2) {
783 typename detail::BitwiseLeftShiftTag::template ExprExpr<Operand1,Operand2>::BinaryFunction(),
789 template <
typename Operand,
typename Scalar>
791 typename boost::enable_if<
792 typename ExpressionTraits<Scalar>::IsScalar,
793 detail::UnaryOpExpression< Operand, typename detail::BitwiseRightShiftTag::template ExprScalar<Operand,Scalar>::Bound >
796 <unspecified-expression-type>
798 operator>>(ExpressionBase<Operand>
const & operand, Scalar
const & scalar) {
799 return vectorize(detail::BitwiseRightShiftTag::template ExprScalar<Operand,Scalar>::bind(scalar),operand);
802 template <
typename Operand,
typename Scalar>
804 typename boost::enable_if<
805 typename ExpressionTraits<Scalar>::IsScalar,
806 detail::UnaryOpExpression< Operand, typename detail::BitwiseRightShiftTag::template ScalarExpr<Operand,Scalar>::Bound >
809 <unspecified-expression-type>
811 operator>>(Scalar
const & scalar, ExpressionBase<Operand>
const & operand) {
812 return vectorize(detail::BitwiseRightShiftTag::template ScalarExpr<Operand,Scalar>::bind(scalar),operand);
815 template <
typename Operand1,
typename Operand2>
817 detail::BinaryOpExpression<
819 typename detail::BitwiseRightShiftTag::template ExprExpr<Operand1,Operand2>::BinaryFunction
822 <unspecified-expression-type>
824 operator>>(ExpressionBase<Operand1>
const & operand1, ExpressionBase<Operand2>
const & operand2) {
826 typename detail::BitwiseRightShiftTag::template ExprExpr<Operand1,Operand2>::BinaryFunction(),
833 template <
typename Operand,
typename Scalar>
835 typename boost::enable_if<
836 typename ExpressionTraits<Scalar>::IsScalar,
837 detail::UnaryOpExpression< Operand, typename detail::EqualToTag::template ExprScalar<Operand,Scalar>::Bound >
840 <unspecified-expression-type>
842 equal(ExpressionBase<Operand>
const & operand, Scalar
const & scalar) {
843 return vectorize(detail::EqualToTag::template ExprScalar<Operand,Scalar>::bind(scalar),operand);
846 template <
typename Operand,
typename Scalar>
848 typename boost::enable_if<
849 typename ExpressionTraits<Scalar>::IsScalar,
850 detail::UnaryOpExpression< Operand, typename detail::EqualToTag::template ScalarExpr<Operand,Scalar>::Bound >
853 <unspecified-expression-type>
855 equal(Scalar
const & scalar, ExpressionBase<Operand>
const & operand) {
856 return vectorize(detail::EqualToTag::template ScalarExpr<Operand,Scalar>::bind(scalar),operand);
859 template <
typename Operand1,
typename Operand2>
861 detail::BinaryOpExpression<
863 typename detail::EqualToTag::template ExprExpr<Operand1,Operand2>::BinaryFunction
866 <unspecified-expression-type>
868 equal(ExpressionBase<Operand1>
const & operand1, ExpressionBase<Operand2>
const & operand2) {
870 typename detail::EqualToTag::template ExprExpr<Operand1,Operand2>::BinaryFunction(),
876 template <
typename Operand,
typename Scalar>
878 typename boost::enable_if<
879 typename ExpressionTraits<Scalar>::IsScalar,
880 detail::UnaryOpExpression< Operand, typename detail::NotEqualToTag::template ExprScalar<Operand,Scalar>::Bound >
883 <unspecified-expression-type>
885 not_equal(ExpressionBase<Operand>
const & operand, Scalar
const & scalar) {
886 return vectorize(detail::NotEqualToTag::template ExprScalar<Operand,Scalar>::bind(scalar),operand);
889 template <
typename Operand,
typename Scalar>
891 typename boost::enable_if<
892 typename ExpressionTraits<Scalar>::IsScalar,
893 detail::UnaryOpExpression< Operand, typename detail::NotEqualToTag::template ScalarExpr<Operand,Scalar>::Bound >
896 <unspecified-expression-type>
898 not_equal(Scalar
const & scalar, ExpressionBase<Operand>
const & operand) {
899 return vectorize(detail::NotEqualToTag::template ScalarExpr<Operand,Scalar>::bind(scalar),operand);
902 template <
typename Operand1,
typename Operand2>
904 detail::BinaryOpExpression<
906 typename detail::NotEqualToTag::template ExprExpr<Operand1,Operand2>::BinaryFunction
909 <unspecified-expression-type>
911 not_equal(ExpressionBase<Operand1>
const & operand1, ExpressionBase<Operand2>
const & operand2) {
913 typename detail::NotEqualToTag::template ExprExpr<Operand1,Operand2>::BinaryFunction(),
919 template <
typename Operand,
typename Scalar>
921 typename boost::enable_if<
922 typename ExpressionTraits<Scalar>::IsScalar,
923 detail::UnaryOpExpression< Operand, typename detail::LessTag::template ExprScalar<Operand,Scalar>::Bound >
926 <unspecified-expression-type>
928 less(ExpressionBase<Operand>
const & operand, Scalar
const & scalar) {
929 return vectorize(detail::LessTag::template ExprScalar<Operand,Scalar>::bind(scalar),operand);
932 template <
typename Operand,
typename Scalar>
934 typename boost::enable_if<
935 typename ExpressionTraits<Scalar>::IsScalar,
936 detail::UnaryOpExpression< Operand, typename detail::LessTag::template ScalarExpr<Operand,Scalar>::Bound >
939 <unspecified-expression-type>
941 less(Scalar
const & scalar, ExpressionBase<Operand>
const & operand) {
942 return vectorize(detail::LessTag::template ScalarExpr<Operand,Scalar>::bind(scalar),operand);
945 template <
typename Operand1,
typename Operand2>
947 detail::BinaryOpExpression<
949 typename detail::LessTag::template ExprExpr<Operand1,Operand2>::BinaryFunction
952 <unspecified-expression-type>
954 less(ExpressionBase<Operand1>
const & operand1, ExpressionBase<Operand2>
const & operand2) {
956 typename detail::LessTag::template ExprExpr<Operand1,Operand2>::BinaryFunction(),
962 template <
typename Operand,
typename Scalar>
964 typename boost::enable_if<
965 typename ExpressionTraits<Scalar>::IsScalar,
966 detail::UnaryOpExpression< Operand, typename detail::GreaterTag::template ExprScalar<Operand,Scalar>::Bound >
969 <unspecified-expression-type>
971 greater(ExpressionBase<Operand>
const & operand, Scalar
const & scalar) {
972 return vectorize(detail::GreaterTag::template ExprScalar<Operand,Scalar>::bind(scalar),operand);
975 template <
typename Operand,
typename Scalar>
977 typename boost::enable_if<
978 typename ExpressionTraits<Scalar>::IsScalar,
979 detail::UnaryOpExpression< Operand, typename detail::GreaterTag::template ScalarExpr<Operand,Scalar>::Bound >
982 <unspecified-expression-type>
984 greater(Scalar
const & scalar, ExpressionBase<Operand>
const & operand) {
985 return vectorize(detail::GreaterTag::template ScalarExpr<Operand,Scalar>::bind(scalar),operand);
988 template <
typename Operand1,
typename Operand2>
990 detail::BinaryOpExpression<
992 typename detail::GreaterTag::template ExprExpr<Operand1,Operand2>::BinaryFunction
995 <unspecified-expression-type>
997 greater(ExpressionBase<Operand1>
const & operand1, ExpressionBase<Operand2>
const & operand2) {
999 typename detail::GreaterTag::template ExprExpr<Operand1,Operand2>::BinaryFunction(),
1005 template <
typename Operand,
typename Scalar>
1007 typename boost::enable_if<
1008 typename ExpressionTraits<Scalar>::IsScalar,
1009 detail::UnaryOpExpression< Operand, typename detail::LessEqualTag::template ExprScalar<Operand,Scalar>::Bound >
1012 <unspecified-expression-type>
1014 less_equal(ExpressionBase<Operand>
const & operand, Scalar
const & scalar) {
1015 return vectorize(detail::LessEqualTag::template ExprScalar<Operand,Scalar>::bind(scalar),operand);
1018 template <
typename Operand,
typename Scalar>
1020 typename boost::enable_if<
1021 typename ExpressionTraits<Scalar>::IsScalar,
1022 detail::UnaryOpExpression< Operand, typename detail::LessEqualTag::template ScalarExpr<Operand,Scalar>::Bound >
1025 <unspecified-expression-type>
1027 less_equal(Scalar
const & scalar, ExpressionBase<Operand>
const & operand) {
1028 return vectorize(detail::LessEqualTag::template ScalarExpr<Operand,Scalar>::bind(scalar),operand);
1031 template <
typename Operand1,
typename Operand2>
1033 detail::BinaryOpExpression<
1035 typename detail::LessEqualTag::template ExprExpr<Operand1,Operand2>::BinaryFunction
1038 <unspecified-expression-type>
1040 less_equal(ExpressionBase<Operand1>
const & operand1, ExpressionBase<Operand2>
const & operand2) {
1042 typename detail::LessEqualTag::template ExprExpr<Operand1,Operand2>::BinaryFunction(),
1048 template <
typename Operand,
typename Scalar>
1050 typename boost::enable_if<
1051 typename ExpressionTraits<Scalar>::IsScalar,
1052 detail::UnaryOpExpression< Operand, typename detail::GreaterEqualTag::template ExprScalar<Operand,Scalar>::Bound >
1055 <unspecified-expression-type>
1057 great_equal(ExpressionBase<Operand>
const & operand, Scalar
const & scalar) {
1058 return vectorize(detail::GreaterEqualTag::template ExprScalar<Operand,Scalar>::bind(scalar),operand);
1061 template <
typename Operand,
typename Scalar>
1063 typename boost::enable_if<
1064 typename ExpressionTraits<Scalar>::IsScalar,
1065 detail::UnaryOpExpression< Operand, typename detail::GreaterEqualTag::template ScalarExpr<Operand,Scalar>::Bound >
1068 <unspecified-expression-type>
1070 great_equal(Scalar
const & scalar, ExpressionBase<Operand>
const & operand) {
1071 return vectorize(detail::GreaterEqualTag::template ScalarExpr<Operand,Scalar>::bind(scalar),operand);
1074 template <
typename Operand1,
typename Operand2>
1076 detail::BinaryOpExpression<
1078 typename detail::GreaterEqualTag::template ExprExpr<Operand1,Operand2>::BinaryFunction
1081 <unspecified-expression-type>
1083 great_equal(ExpressionBase<Operand1>
const & operand1, ExpressionBase<Operand2>
const & operand2) {
1085 typename detail::GreaterEqualTag::template ExprExpr<Operand1,Operand2>::BinaryFunction(),
1091 template <
typename Operand,
typename Scalar>
1093 typename boost::enable_if<
1094 typename ExpressionTraits<Scalar>::IsScalar,
1095 detail::UnaryOpExpression< Operand, typename detail::LogicalAnd::template ExprScalar<Operand,Scalar>::Bound >
1098 <unspecified-expression-type>
1100 logical_and(ExpressionBase<Operand>
const & operand, Scalar
const & scalar) {
1101 return vectorize(detail::LogicalAnd::template ExprScalar<Operand,Scalar>::bind(scalar),operand);
1104 template <
typename Operand,
typename Scalar>
1106 typename boost::enable_if<
1107 typename ExpressionTraits<Scalar>::IsScalar,
1108 detail::UnaryOpExpression< Operand, typename detail::LogicalAnd::template ScalarExpr<Operand,Scalar>::Bound >
1111 <unspecified-expression-type>
1113 logical_and(Scalar
const & scalar, ExpressionBase<Operand>
const & operand) {
1114 return vectorize(detail::LogicalAnd::template ScalarExpr<Operand,Scalar>::bind(scalar),operand);
1117 template <
typename Operand1,
typename Operand2>
1119 detail::BinaryOpExpression<
1121 typename detail::LogicalAnd::template ExprExpr<Operand1,Operand2>::BinaryFunction
1124 <unspecified-expression-type>
1126 logical_and(ExpressionBase<Operand1>
const & operand1, ExpressionBase<Operand2>
const & operand2) {
1128 typename detail::LogicalAnd::template ExprExpr<Operand1,Operand2>::BinaryFunction(),
1134 template <
typename Operand,
typename Scalar>
1136 typename boost::enable_if<
1137 typename ExpressionTraits<Scalar>::IsScalar,
1138 detail::UnaryOpExpression< Operand, typename detail::LogicalOr::template ExprScalar<Operand,Scalar>::Bound >
1141 <unspecified-expression-type>
1143 logical_or(ExpressionBase<Operand>
const & operand, Scalar
const & scalar) {
1144 return vectorize(detail::LogicalOr::template ExprScalar<Operand,Scalar>::bind(scalar),operand);
1147 template <
typename Operand,
typename Scalar>
1149 typename boost::enable_if<
1150 typename ExpressionTraits<Scalar>::IsScalar,
1151 detail::UnaryOpExpression< Operand, typename detail::LogicalOr::template ScalarExpr<Operand,Scalar>::Bound >
1154 <unspecified-expression-type>
1156 logical_or(Scalar
const & scalar, ExpressionBase<Operand>
const & operand) {
1157 return vectorize(detail::LogicalOr::template ScalarExpr<Operand,Scalar>::bind(scalar),operand);
1160 template <
typename Operand1,
typename Operand2>
1162 detail::BinaryOpExpression<
1164 typename detail::LogicalOr::template ExprExpr<Operand1,Operand2>::BinaryFunction
1167 <unspecified-expression-type>
1169 logical_or(ExpressionBase<Operand1>
const & operand1, ExpressionBase<Operand2>
const & operand2) {
1171 typename detail::LogicalOr::template ExprExpr<Operand1,Operand2>::BinaryFunction(),
1178 template <
typename Operand>
1180 detail::UnaryOpExpression< Operand, std::negate<typename ExpressionTraits<Operand>::Element> >
1182 <unspecified-expression-type>
1184 operator-(ExpressionBase<Operand>
const & operand) {
1185 return vectorize(std::negate<
typename ExpressionTraits<Operand>::Element>(),operand);
1188 template <
typename Operand>
1190 detail::UnaryOpExpression< Operand, std::logical_not<typename ExpressionTraits<Operand>::Element> >
1192 <unspecified-expression-type>
1194 logical_not(ExpressionBase<Operand>
const & operand) {
1195 return vectorize(std::logical_not<
typename ExpressionTraits<Operand>::Element>(),operand);
1198 template <
typename Operand>
1200 detail::UnaryOpExpression< Operand, detail::BitwiseNot<typename ExpressionTraits<Operand>::Element> >
1202 <unspecified-expression-type>
1204 operator~(ExpressionBase<Operand>
const & operand) {
1205 return vectorize(detail::BitwiseNot<
typename ExpressionTraits<Operand>::Element>(),operand);
1209template <
typename Scalar>
1210inline typename boost::enable_if<typename ExpressionTraits<Scalar>::IsScalar,
bool>::type
1211any(Scalar
const & scalar) {
1212 return bool(scalar);
1220template <
typename Derived>
1223 typename Derived::Iterator
const i_end = expr.
end();
1224 for (
typename Derived::Iterator i = expr.
begin(); i != i_end; ++i) {
1225 if (any(*i))
return true;
1230template <
typename Scalar>
1231inline typename boost::enable_if<typename ExpressionTraits<Scalar>::IsScalar,
bool>::type
1232all(Scalar
const & scalar) {
1233 return bool(scalar);
1241template <
typename Derived>
1244 typename Derived::Iterator
const i_end = expr.
end();
1245 for (
typename Derived::Iterator i = expr.
begin(); i != i_end; ++i) {
1246 if (!all(*i))
return false;
1251template <
typename Scalar1,
typename Scalar2>
1252inline typename boost::enable_if<
1254 typename ExpressionTraits<Scalar1>::IsScalar,
1255 typename ExpressionTraits<Scalar2>::IsScalar
1259allclose(Scalar1
const & scalar1, Scalar2
const & scalar2,
double tol=1E-8) {
1260 ApproximatelyEqual<Scalar1,Scalar2> func(tol);
1261 return func(scalar1, scalar2);
1264template <
typename Scalar,
typename Derived>
1265inline typename boost::enable_if<typename ExpressionTraits<Scalar>::IsScalar,
bool>::type
1266allclose(Scalar
const & scalar, ExpressionBase<Derived>
const & expr,
double tol=1E-8) {
1267 ApproximatelyEqual<Scalar,typename Derived::Element> func(tol);
1268 typename Derived::Iterator
const i_end = expr.end();
1269 for (
typename Derived::Iterator i = expr.begin(); i != i_end; ++i) {
1270 if (!allclose(scalar, *i, tol))
return false;
1275template <
typename Scalar,
typename Derived>
1276inline typename boost::enable_if<typename ExpressionTraits<Scalar>::IsScalar,
bool>::type
1277allclose(ExpressionBase<Derived>
const & expr, Scalar
const & scalar,
double tol=1E-8) {
1278 return allclose(scalar, expr, tol);
1281template <
typename Derived1,
typename Derived2>
1283allclose(ExpressionBase<Derived1>
const & expr1, ExpressionBase<Derived2>
const & expr2,
double tol=1E-8) {
1284 typename Derived1::Iterator
const i_end = expr1.end();
1285 typename Derived1::Iterator i = expr1.begin();
1286 typename Derived2::Iterator j = expr2.begin();
1287 for (; i != i_end; ++i, ++j) {
1288 if (!allclose(*i, *j, tol))
return false;
1294template <
typename Scalar>
1295inline typename boost::enable_if<typename ExpressionTraits<Scalar>::IsScalar, Scalar>::type
1296sum(Scalar
const & scalar) {
return scalar; }
1304template <
typename Derived>
1305inline typename Derived::Element
1307 typename Derived::Iterator
const i_end = expr.
end();
1308 typename Derived::Element total =
static_cast<typename Derived::Element
>(0);
1309 for (
typename Derived::Iterator i = expr.
begin(); i != i_end; ++i) {
Lazy binary expression templates.
Lazy unary expression templates.
CRTP base class for all multidimensional expressions.
Definition ExpressionBase.h:40
Iterator end() const
Return an Iterator to one past the end of the expression.
Definition ExpressionBase.h:70
Iterator begin() const
Return an Iterator to the beginning of the expression.
Definition ExpressionBase.h:67
boost::enable_if< typenameExpressionTraits< Scalar >::IsScalar, typenameUnaryFunction::result_type >::type vectorize(UnaryFunction const &functor, Scalar const &scalar)
Apply a non-mutating unary function object to a scalar.
Definition vectorize.h:73