Eigen  5.0.1
 
Loading...
Searching...
No Matches
CwiseTernaryOp.h
1// This file is part of Eigen, a lightweight C++ template library
2// for linear algebra.
3//
4// Copyright (C) 2008-2014 Gael Guennebaud <gael.guennebaud@inria.fr>
5// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
6// Copyright (C) 2016 Eugene Brevdo <ebrevdo@gmail.com>
7//
8// This Source Code Form is subject to the terms of the Mozilla
9// Public License v. 2.0. If a copy of the MPL was not distributed
10// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
11// SPDX-License-Identifier: MPL-2.0
12
13#ifndef EIGEN_CWISE_TERNARY_OP_H
14#define EIGEN_CWISE_TERNARY_OP_H
15
16// IWYU pragma: private
17#include "./InternalHeaderCheck.h"
18
19namespace Eigen {
20
21namespace internal {
22template <typename TernaryOp, typename Arg1, typename Arg2, typename Arg3>
23struct traits<CwiseTernaryOp<TernaryOp, Arg1, Arg2, Arg3>> {
24 // we must not inherit from traits<Arg1> since it has
25 // the potential to cause problems with MSVC
26 using Ancestor = remove_all_t<Arg1>;
27 using XprKind = typename traits<Ancestor>::XprKind;
28 enum {
29 RowsAtCompileTime = traits<Ancestor>::RowsAtCompileTime,
30 ColsAtCompileTime = traits<Ancestor>::ColsAtCompileTime,
31 MaxRowsAtCompileTime = traits<Ancestor>::MaxRowsAtCompileTime,
32 MaxColsAtCompileTime = traits<Ancestor>::MaxColsAtCompileTime
33 };
34
35 // even though we require Arg1, Arg2, and Arg3 to have the same scalar type
36 // (see CwiseTernaryOp constructor),
37 // we still want to handle the case when the result type is different.
38 using Scalar = typename result_of<TernaryOp(const typename Arg1::Scalar&, const typename Arg2::Scalar&,
39 const typename Arg3::Scalar&)>::type;
40
41 using StorageKind = typename internal::traits<Arg1>::StorageKind;
42 using StorageIndex = typename internal::traits<Arg1>::StorageIndex;
43
44 using Arg1Nested = typename Arg1::Nested;
45 using Arg2Nested = typename Arg2::Nested;
46 using Arg3Nested = typename Arg3::Nested;
47 using Arg1Nested_ = std::remove_reference_t<Arg1Nested>;
48 using Arg2Nested_ = std::remove_reference_t<Arg2Nested>;
49 using Arg3Nested_ = std::remove_reference_t<Arg3Nested>;
50 enum { Flags = Arg1Nested_::Flags & RowMajorBit };
51};
52} // end namespace internal
53
54template <typename TernaryOp, typename Arg1, typename Arg2, typename Arg3, typename StorageKind>
55class CwiseTernaryOpImpl;
56
84template <typename TernaryOp, typename Arg1Type, typename Arg2Type, typename Arg3Type>
85class CwiseTernaryOp : public CwiseTernaryOpImpl<TernaryOp, Arg1Type, Arg2Type, Arg3Type,
86 typename internal::traits<Arg1Type>::StorageKind>,
87 internal::no_assignment_operator {
88 public:
89 using Arg1 = internal::remove_all_t<Arg1Type>;
90 using Arg2 = internal::remove_all_t<Arg2Type>;
91 using Arg3 = internal::remove_all_t<Arg3Type>;
92
93 // require the sizes to match
94 EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(Arg1, Arg2)
95 EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(Arg1, Arg3)
96
97 // The index types should match
98 EIGEN_STATIC_ASSERT((std::is_same<typename internal::traits<Arg1Type>::StorageKind,
99 typename internal::traits<Arg2Type>::StorageKind>::value),
100 STORAGE_KIND_MUST_MATCH)
101 EIGEN_STATIC_ASSERT((std::is_same<typename internal::traits<Arg1Type>::StorageKind,
102 typename internal::traits<Arg3Type>::StorageKind>::value),
103 STORAGE_KIND_MUST_MATCH)
104
105 using Base = typename CwiseTernaryOpImpl<TernaryOp, Arg1Type, Arg2Type, Arg3Type,
106 typename internal::traits<Arg1Type>::StorageKind>::Base;
107 EIGEN_GENERIC_PUBLIC_INTERFACE(CwiseTernaryOp)
108
109 using Arg1Nested = typename internal::ref_selector<Arg1Type>::type;
110 using Arg2Nested = typename internal::ref_selector<Arg2Type>::type;
111 using Arg3Nested = typename internal::ref_selector<Arg3Type>::type;
112 using Arg1Nested_ = std::remove_reference_t<Arg1Nested>;
113 using Arg2Nested_ = std::remove_reference_t<Arg2Nested>;
114 using Arg3Nested_ = std::remove_reference_t<Arg3Nested>;
115
116 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE CwiseTernaryOp(const Arg1& a1, const Arg2& a2, const Arg3& a3,
117 const TernaryOp& func = TernaryOp())
118 : m_arg1(a1), m_arg2(a2), m_arg3(a3), m_functor(func) {
119 eigen_assert(a1.rows() == a2.rows() && a1.cols() == a2.cols() && a1.rows() == a3.rows() && a1.cols() == a3.cols());
120 }
121
122 EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE Index rows() const {
123 // return the fixed size type if available to enable compile time
124 // optimizations
125 EIGEN_IF_CONSTEXPR (internal::traits<internal::remove_all_t<Arg1Nested>>::RowsAtCompileTime == Dynamic &&
126 internal::traits<internal::remove_all_t<Arg2Nested>>::RowsAtCompileTime == Dynamic) {
127 return m_arg3.rows();
128 } else EIGEN_IF_CONSTEXPR (internal::traits<internal::remove_all_t<Arg1Nested>>::RowsAtCompileTime == Dynamic &&
129 internal::traits<internal::remove_all_t<Arg3Nested>>::RowsAtCompileTime == Dynamic) {
130 return m_arg2.rows();
131 } else {
132 return m_arg1.rows();
133 }
134 }
135 EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE Index cols() const {
136 // return the fixed size type if available to enable compile time
137 // optimizations
138 EIGEN_IF_CONSTEXPR (internal::traits<internal::remove_all_t<Arg1Nested>>::ColsAtCompileTime == Dynamic &&
139 internal::traits<internal::remove_all_t<Arg2Nested>>::ColsAtCompileTime == Dynamic) {
140 return m_arg3.cols();
141 } else EIGEN_IF_CONSTEXPR (internal::traits<internal::remove_all_t<Arg1Nested>>::ColsAtCompileTime == Dynamic &&
142 internal::traits<internal::remove_all_t<Arg3Nested>>::ColsAtCompileTime == Dynamic) {
143 return m_arg2.cols();
144 } else {
145 return m_arg1.cols();
146 }
147 }
148
150 EIGEN_DEVICE_FUNC constexpr const Arg1Nested_& arg1() const { return m_arg1; }
152 EIGEN_DEVICE_FUNC constexpr const Arg2Nested_& arg2() const { return m_arg2; }
154 EIGEN_DEVICE_FUNC constexpr const Arg3Nested_& arg3() const { return m_arg3; }
156 EIGEN_DEVICE_FUNC constexpr const TernaryOp& functor() const { return m_functor; }
157
158 protected:
159 Arg1Nested m_arg1;
160 Arg2Nested m_arg2;
161 Arg3Nested m_arg3;
162 const TernaryOp m_functor;
163};
164
165// Generic API dispatcher
166template <typename TernaryOp, typename Arg1, typename Arg2, typename Arg3, typename StorageKind>
167class CwiseTernaryOpImpl : public internal::generic_xpr_base<CwiseTernaryOp<TernaryOp, Arg1, Arg2, Arg3>>::type {
168 public:
169 using Base = typename internal::generic_xpr_base<CwiseTernaryOp<TernaryOp, Arg1, Arg2, Arg3>>::type;
170};
171
172} // end namespace Eigen
173
174#endif // EIGEN_CWISE_TERNARY_OP_H
constexpr const Arg1Nested_ & arg1() const
Definition CwiseTernaryOp.h:150
constexpr const TernaryOp & functor() const
Definition CwiseTernaryOp.h:156
constexpr const Arg2Nested_ & arg2() const
Definition CwiseTernaryOp.h:152
constexpr const Arg3Nested_ & arg3() const
Definition CwiseTernaryOp.h:154
constexpr unsigned int RowMajorBit
Definition Constants.h:71