10#ifndef INCGa4e6283ee2844d93bc9772c830f33b2d
11#define INCGa4e6283ee2844d93bc9772c830f33b2d
12#include <lf/base/base.h>
15#include <boost/fusion/include/adapt_struct.hpp>
16#include <boost/fusion/iterator.hpp>
17#include <boost/fusion/support/category_of.hpp>
18#include <boost/fusion/support/iterator_base.hpp>
19#include <boost/fusion/support/tag_of.hpp>
20#include <boost/fusion/support/tag_of_fwd.hpp>
30template <
class MATRIX>
31struct FusionMatrixTag;
33template <
class MATRIX>
34struct FusionIteratorTag;
36template <
class STRUCT,
int POS>
38 : boost::fusion::iterator_base<FusionIterator<STRUCT, POS>> {
39 static_assert(STRUCT::SizeAtCompileTime != Eigen::Dynamic,
40 "Dynamic matrices are not yet supported.");
41 static_assert(POS >= 0 & POS <= STRUCT::SizeAtCompileTime,
42 "POS has wrong value.");
43 using struct_type = STRUCT;
44 using index = boost::mpl::int_<POS>;
45 using category = boost::fusion::random_access_traversal_tag;
47 explicit FusionIterator(STRUCT& str) : struct_(str) {}
52namespace boost::fusion::traits {
53template <
class STRUCT,
int POS>
54struct tag_of<Eigen::FusionIterator<STRUCT, POS>> {
55 using type = Eigen::FusionIteratorTag<STRUCT>;
58template <
class T,
int ROWS,
int COLS,
int OPTIONS,
int MAX_ROWS,
int MAX_COLS>
59struct tag_of<Eigen::Matrix<T, ROWS, COLS, OPTIONS, MAX_ROWS, MAX_COLS>> {
60 using type = Eigen::FusionMatrixTag<
61 Eigen::Matrix<T, ROWS, COLS, OPTIONS, MAX_ROWS, MAX_COLS>>;
65namespace boost::fusion::extension {
66template <
class MATRIX>
67struct value_of_impl<Eigen::FusionIteratorTag<MATRIX>> {
68 template <
class ITERATOR>
70 template <
class STRUCT,
int N>
71 struct apply<Eigen::FusionIterator<STRUCT, N>> {
72 using type =
typename STRUCT::Scalar;
76template <
class MATRIX>
77struct deref_impl<Eigen::FusionIteratorTag<MATRIX>> {
78 template <
class ITERATOR>
81 template <
class STRUCT,
int N>
82 struct apply<Eigen::FusionIterator<STRUCT, N>> {
84 typename mpl::if_<is_const<STRUCT>,
const typename STRUCT::Scalar&,
85 typename STRUCT::Scalar&>::type;
86 static type call(Eigen::FusionIterator<STRUCT, N>
const& it) {
92template <
class MATRIX>
93struct next_impl<Eigen::FusionIteratorTag<MATRIX>> {
94 template <
class ITERATOR>
96 using struct_type =
typename ITERATOR::struct_type;
97 using index =
typename ITERATOR::index;
98 using type = Eigen::FusionIterator<struct_type, index::value + 1>;
100 static type call(ITERATOR
const& i) {
return type(i.struct_); }
104template <
class MATRIX>
105struct prior_impl<Eigen::FusionIteratorTag<MATRIX>> {
106 template <
class ITERATOR>
108 using struct_type =
typename ITERATOR::struct_type;
109 using index =
typename ITERATOR::index;
110 using type = Eigen::FusionIterator<struct_type, index::value - 1>;
112 static type call(ITERATOR
const& i) {
return type(i.struct_); }
116template <
class MATRIX>
117struct advance_impl<Eigen::FusionIteratorTag<MATRIX>> {
118 template <
class ITERATOR,
class N>
120 using struct_type =
typename ITERATOR::struct_type;
121 using index =
typename ITERATOR::index;
122 using type = Eigen::FusionIterator<struct_type, index::value + N::value>;
124 static type call(ITERATOR
const& i) {
return type(i.struct_); }
128template <
class MATRIX>
129struct distance_impl<Eigen::FusionIteratorTag<MATRIX>> {
130 template <
class FIRST,
class LAST>
131 struct apply : mpl::minus<typename LAST::index, typename FIRST::index> {
132 using self = apply<FIRST, LAST>;
134 static typename self::type call(FIRST
const& ,
136 return typename self::type();
141template <
class MATRIX>
142struct equal_to_impl<Eigen::FusionIteratorTag<MATRIX>> {
143 template <
class IT1,
class IT2>
144 struct apply : mpl::equal_to<typename IT1::index, typename IT2::index> {};
147template <
class MATRIX>
148struct begin_impl<Eigen::FusionMatrixTag<MATRIX>> {
149 template <
class SEQUENCE>
151 using type = Eigen::FusionIterator<SEQUENCE, 0>;
153 static type call(SEQUENCE& seq) {
return type(seq); }
157template <
class MATRIX>
158struct end_impl<Eigen::FusionMatrixTag<MATRIX>> {
159 template <
class SEQUENCE>
161 using type = Eigen::FusionIterator<SEQUENCE, MATRIX::SizeAtCompileTime>;
162 static type call(SEQUENCE& seq) {
return type(seq); }
166template <
class MATRIX>
167struct at_impl<Eigen::FusionMatrixTag<MATRIX>> {
168 template <
class SEQUENCE,
class KEY>
170 template <
class SEQUENCE,
int N>
171 struct apply<SEQUENCE, mpl::int_<N>> {
173 typename mpl::if_<is_const<SEQUENCE>,
const typename MATRIX::Scalar&,
174 typename MATRIX::Scalar&>::type;
176 static type call(SEQUENCE& seq) {
return seq(N); }
180template <
class MATRIX>
181struct value_at_impl<Eigen::FusionMatrixTag<MATRIX>> {
182 template <
typename Sequence,
typename N>
185 template <
class SEQUENCE,
int N>
186 struct apply<SEQUENCE, mpl::int_<N>> {
187 using type =
typename MATRIX::Scalar;
191template <
class MATRIX>
192struct size_impl<Eigen::FusionMatrixTag<MATRIX>> {
193 template <
class SEQUENCE>
194 struct apply : mpl::int_<MATRIX::SizeAtCompileTime> {};
197template <
class MATRIX>
198struct category_of_impl<Eigen::FusionMatrixTag<MATRIX>> {
199 template <
class SEQUENCE>
201 struct type : random_access_traversal_tag {};
205template <
class MATRIX>
206struct is_sequence_impl<Eigen::FusionMatrixTag<MATRIX>> {
208 struct apply : mpl::true_ {};
211template <
class MATRIX>
212struct is_view_impl<Eigen::FusionMatrixTag<MATRIX>> {
214 struct apply : boost::mpl::false_ {};