Created
May 5, 2017 03:16
-
-
Save EricCousineau-TRI/fe73d760ab3f1d1a79c7de72649d33a1 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/eigen_scratch/matrix_hstack_vstack_xpr_tpl_cxx11.cc b/eigen_scratch/matrix_hstack_vstack_xpr_tpl_cxx11.cc | |
index 18ec6ea..d390ebb 100644 | |
--- a/eigen_scratch/matrix_hstack_vstack_xpr_tpl_cxx11.cc | |
+++ b/eigen_scratch/matrix_hstack_vstack_xpr_tpl_cxx11.cc | |
@@ -1,9 +1,33 @@ | |
/* | |
-Purpose: sAme as the other matrix_stack* attempts, but this time, use tuples and explicit calling out of | |
+Purpose: Same as the other matrix_stack* attempts, but this time, use tuples and explicit calling out of | |
hstack() and vstack() for concatenation. | |
*/ | |
-#include "cpp_quick/name_trait.h" | |
+ | |
+#include <utility> | |
+ | |
+namespace std { | |
+ | |
+template <size_t... Is> | |
+struct index_sequence{ }; | |
+ | |
+template <size_t I, size_t... Is> | |
+struct make_index_sequence : public make_index_sequence<I-1, I-1, Is...> { }; | |
+ | |
+template<size_t... Is> | |
+struct make_index_sequence<0, Is...> : public index_sequence<Is...> { }; | |
+ | |
+template<typename T> | |
+using decay_t = typename decay<T>::type; | |
+ | |
+template<typename T> | |
+using remove_cv_t = typename remove_cv<T>::type; | |
+ | |
+} // namespace std | |
+ | |
+ | |
+ | |
+ | |
#include "cpp_quick/tuple_iter.h" | |
#include <string> | |
@@ -168,7 +192,7 @@ struct stack_detail { | |
using SubXprAlias = SubXpr<bare<T>, type_index<bare<T>>::value>; | |
template<typename T> | |
- static auto get_subxpr_helper(T&& x) { | |
+ static SubXprAlias<T> get_subxpr_helper(T&& x) { | |
return SubXprAlias<T>(std::forward<T>(x)); | |
} | |
}; | |
@@ -223,16 +247,27 @@ struct hstack_tuple : public stack_tuple<Args...> { | |
// Need Derived type before use. Will defer until we | |
m_cols = 0; | |
m_rows = -1; | |
- auto f = [&](auto&& cur) { | |
+ | |
+ InitFunctor<Derived> f {m_rows, m_cols}; | |
+ Base::visit(f); | |
+ } | |
+ | |
+ template <typename Derived> | |
+ struct InitFunctor { | |
+ // Context | |
+ int& m_rows; | |
+ int& m_cols; | |
+ // Method | |
+ template <typename T> | |
+ void operator()(T&& cur) { | |
auto subxpr = stack_detail<Derived>::get_subxpr_helper(cur); | |
if (m_rows == -1) | |
m_rows = subxpr.rows(); | |
else | |
eigen_assert(subxpr.rows() == m_rows); | |
m_cols += subxpr.cols(); | |
- }; | |
- Base::visit(f); | |
- } | |
+ } | |
+ }; | |
template< | |
typename XprType, | |
@@ -243,13 +278,23 @@ struct hstack_tuple : public stack_tuple<Args...> { | |
Base::check_size(xpr, allow_resize); | |
int col = 0; | |
- auto f = [&](auto&& cur) { | |
+ AssignFunctor<XprType, Derived> f {std::forward<XprType>(xpr), col}; | |
+ Base::visit(f); | |
+ } | |
+ | |
+ template <typename XprType, typename Derived> | |
+ struct AssignFunctor { | |
+ // Context | |
+ XprType&& xpr; | |
+ int& col; | |
+ // Method | |
+ template <typename T> | |
+ void operator()(T&& cur) { | |
auto subxpr = stack_detail<Derived>::get_subxpr_helper(cur); | |
subxpr.assign(xpr.middleCols(col, subxpr.cols())); | |
col += subxpr.cols(); | |
- }; | |
- Base::visit(f); | |
- } | |
+ } | |
+ }; | |
}; | |
template<typename... Args> | |
@@ -268,16 +313,27 @@ struct vstack_tuple : public stack_tuple<Args...> { | |
// Need Derived type before use. Will defer until we | |
m_cols = -1; | |
m_rows = 0; | |
- auto f = [&](auto&& cur) { | |
+ | |
+ InitFunctor<Derived> f {m_rows, m_cols}; | |
+ Base::visit(f); | |
+ } | |
+ | |
+ template <typename Derived> | |
+ struct InitFunctor { | |
+ // Context | |
+ int& m_rows; | |
+ int& m_cols; | |
+ // Method | |
+ template <typename T> | |
+ void operator()(T&& cur) { | |
auto subxpr = stack_detail<Derived>::get_subxpr_helper(cur); | |
if (m_cols == -1) | |
m_cols = subxpr.cols(); | |
else | |
eigen_assert(subxpr.cols() == m_cols); | |
m_rows += subxpr.rows(); | |
- }; | |
- Base::visit(f); | |
- } | |
+ } | |
+ }; | |
template< | |
typename XprType, | |
@@ -288,22 +344,32 @@ struct vstack_tuple : public stack_tuple<Args...> { | |
Base::check_size(xpr, allow_resize); | |
int row = 0; | |
- auto f = [&](auto&& cur) { | |
+ AssignFunctor<XprType, Derived> f {std::forward<XprType>(xpr), row}; | |
+ Base::visit(f); | |
+ } | |
+ | |
+ template <typename XprType, typename Derived> | |
+ struct AssignFunctor { | |
+ // Context | |
+ XprType&& xpr; | |
+ int& row; | |
+ // Method | |
+ template <typename T> | |
+ void operator()(T&& cur) { | |
auto subxpr = stack_detail<Derived>::get_subxpr_helper(cur); | |
subxpr.assign(xpr.middleRows(row, subxpr.rows())); | |
row += subxpr.rows(); | |
- }; | |
- Base::visit(f); | |
- } | |
+ } | |
+ }; | |
}; | |
// Actually leveraging std::forward_as_tuple | |
template<typename... Args> | |
-auto hstack(Args&&... args) { | |
+hstack_tuple<Args&&...> hstack(Args&&... args) { | |
return hstack_tuple<Args&&...>(std::forward<Args>(args)...); | |
} | |
template<typename... Args> | |
-auto vstack(Args&&... args) { | |
+vstack_tuple<Args&&...> vstack(Args&&... args) { | |
return vstack_tuple<Args&&...>(std::forward<Args>(args)...); | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment