diff --git a/include/rotgen/common/ref.hpp b/include/rotgen/common/ref.hpp index 72e4822..ffde241 100644 --- a/include/rotgen/common/ref.hpp +++ b/include/rotgen/common/ref.hpp @@ -30,6 +30,7 @@ namespace rotgen static constexpr int RowsAtCompileTime = T::RowsAtCompileTime; static constexpr int ColsAtCompileTime = T::ColsAtCompileTime; static constexpr bool IsVectorAtCompileTime = T::IsVectorAtCompileTime; + static constexpr bool is_immutable = T::is_immutable; using parent::evaluate; using parent::noalias; @@ -120,14 +121,16 @@ namespace rotgen class ref : private map { public: - using parent = map; - using value_type = typename T::value_type; - using rotgen_tag = void; + using parent = map; + using value_type = typename T::value_type; + using rotgen_tag = void; + using rotgen_ref_tag = void; static constexpr int storage_order = T::storage_order; static constexpr int RowsAtCompileTime = T::RowsAtCompileTime; static constexpr int ColsAtCompileTime = T::ColsAtCompileTime; static constexpr bool IsVectorAtCompileTime = T::IsVectorAtCompileTime; + static constexpr bool is_immutable = T::is_immutable; using parent::evaluate; using parent::noalias; diff --git a/include/rotgen/detail/helpers.hpp b/include/rotgen/detail/helpers.hpp index 6f267d2..dd17f40 100644 --- a/include/rotgen/detail/helpers.hpp +++ b/include/rotgen/detail/helpers.hpp @@ -22,6 +22,9 @@ namespace rotgen::detail return false; }(); + template + using propagate_const = std::conditional_t, std::add_const_t, T>; + template inline constexpr auto select_static = (M==rotgen::Dynamic || N==rotgen::Dynamic) ? rotgen::Dynamic : M; diff --git a/include/rotgen/dynamic/matrix.hpp b/include/rotgen/dynamic/matrix.hpp index 6d8d208..46c785e 100644 --- a/include/rotgen/dynamic/matrix.hpp +++ b/include/rotgen/dynamic/matrix.hpp @@ -35,6 +35,7 @@ namespace rotgen static constexpr bool IsRowMajor = (Opts & RowMajor) == RowMajor; static constexpr bool is_defined_static = false; static constexpr bool has_static_storage = false; + static constexpr bool is_immutable = false; using transposed_type = matrix; diff --git a/include/rotgen/extract.hpp b/include/rotgen/extract.hpp index 02186a4..d2b4fc7 100644 --- a/include/rotgen/extract.hpp +++ b/include/rotgen/extract.hpp @@ -6,6 +6,7 @@ */ //================================================================================================== #pragma once +#include namespace rotgen { @@ -28,13 +29,10 @@ namespace rotgen auto extract(Entity& e, Index i0, Index j0, Index ni, Index nj) { detail::validate_extract(e,i0,j0,ni,nj); - return block(e, i0, j0, ni, nj); - } - template - auto extract(Entity const& e, Index i0, Index j0, Index ni, Index nj) - { - detail::validate_extract(e,i0,j0,ni,nj); - return block(e, i0, j0, ni, nj); + if constexpr(concepts::reference) + return extract(e.base(), i0, j0, ni, nj); + else + return block>(e, i0, j0, ni, nj); } template @@ -42,7 +40,10 @@ namespace rotgen auto extract(Entity& e, Index i0, Index j0) { detail::validate_extract(e,i0,j0,NI,NJ); - return block(e, i0, j0); + if constexpr(concepts::reference) + return extract(e.base(), i0, j0); + else + return block ,NI,NJ>(e, i0, j0); } template @@ -50,7 +51,10 @@ namespace rotgen auto extract(Entity& e, Index i0, Index j0, Index ni, Index nj) { detail::validate_extract(e,i0,j0,ni,nj); - return block(e, i0, j0, ni, nj); + if constexpr(concepts::reference) + return extract(e.base(), i0, j0, ni, nj); + else + return block,NI,NJ>(e, i0, j0, ni, nj); } //======================== TOP LEFT CORNER ======================== diff --git a/include/rotgen/fixed/block.hpp b/include/rotgen/fixed/block.hpp index d16b6df..ded13ce 100644 --- a/include/rotgen/fixed/block.hpp +++ b/include/rotgen/fixed/block.hpp @@ -74,54 +74,31 @@ namespace rotgen static constexpr bool has_static_storage = storage_status; public: - block(const block& other) = default; block(block&& other) = default; block& operator=(const block&) = default; block& operator=(block&&) = default; - // Constructs from regular Ref block(Ref const& r, std::size_t i0, std::size_t j0, std::size_t ni, std::size_t nj) - requires(is_immutable && !concepts::reference) + requires(is_immutable) : parent(r.base(),i0,j0,ni,nj) {} block(Ref const& r, std::size_t i0, std::size_t j0) - requires(Rows != -1 && Cols != -1 && is_immutable && !concepts::reference) + requires(Rows != -1 && Cols != -1 && is_immutable) : parent(r.base(),i0,j0,Rows,Cols) {} block(Ref& r, std::size_t i0, std::size_t j0, std::size_t ni, std::size_t nj) - requires(!is_immutable && !concepts::reference) + requires(!is_immutable) : parent(r.base(),i0,j0,ni,nj) {} block(Ref& r, std::size_t i0, std::size_t j0) - requires(Rows != -1 && Cols != -1 && !is_immutable && !concepts::reference) + requires(Rows != -1 && Cols != -1 && !is_immutable) : parent(r.base(),i0,j0,Rows,Cols) {} - // Constructs from rotgen::ref - block(Ref const& r, std::size_t i0, std::size_t j0, std::size_t ni, std::size_t nj) - requires(is_immutable && concepts::reference) - : parent(r.base().base(),i0,j0,ni,nj) - {} - - block(Ref const& r, std::size_t i0, std::size_t j0) - requires(Rows != -1 && Cols != -1 && is_immutable && concepts::reference) - : parent(r.base().base(),i0,j0,Rows,Cols) - {} - - block(Ref& r, std::size_t i0, std::size_t j0, std::size_t ni, std::size_t nj) - requires(!is_immutable && concepts::reference) - : parent(r.base().base(),i0,j0,ni,nj) - {} - - block(Ref& r, std::size_t i0, std::size_t j0) - requires(Rows != -1 && Cols != -1 && !is_immutable && concepts::reference) - : parent(r.base().base(),i0,j0,Rows,Cols) - {} - template block(block const& other) : parent(other.base()) {} diff --git a/include/rotgen/fixed/matrix.hpp b/include/rotgen/fixed/matrix.hpp index a9fea82..71741c9 100644 --- a/include/rotgen/fixed/matrix.hpp +++ b/include/rotgen/fixed/matrix.hpp @@ -48,6 +48,7 @@ namespace rotgen template using as_concrete_type = as_concrete_t; + static constexpr bool is_immutable = false; static constexpr bool is_defined_static = Rows!=-1 && Cols!=-1; static constexpr bool has_static_storage = storage_status; diff --git a/include/rotgen/functions.hpp b/include/rotgen/functions.hpp index 6e43082..786bf0c 100644 --- a/include/rotgen/functions.hpp +++ b/include/rotgen/functions.hpp @@ -131,7 +131,7 @@ namespace rotgen auto trace(concepts::entity auto const& arg) { return arg.trace(); } auto squaredNorm(concepts::entity auto const& arg) { return arg.squaredNorm(); } auto norm(concepts::entity auto const& arg) { return arg.norm(); } - auto sum(concepts::entity auto const& arg) { return arg.sum(); } + auto sum(auto const& arg) requires requires{ arg.sum(); } { return arg.sum(); } auto prod(concepts::entity auto const& arg) { return arg.prod(); } auto mean(concepts::entity auto const& arg) { return arg.mean(); } diff --git a/include/rotgen/impl/block.hpp b/include/rotgen/impl/block.hpp index 1834c3b..0682a9f 100644 --- a/include/rotgen/impl/block.hpp +++ b/include/rotgen/impl/block.hpp @@ -25,15 +25,19 @@ namespace rotgen #define USE_CONST #define CONST const #define BASENAME block_const_impl + #define BASEMAP map_const_impl #include #undef BASENAME + #undef BASEMAP #undef CONST #undef USE_CONST #define CONST #define BASENAME block_impl + #define BASEMAP map_impl #include #undef BASENAME + #undef BASEMAP #undef CONST template struct find_block_impl; diff --git a/include/rotgen/impl/block_indirect.hpp b/include/rotgen/impl/block_indirect.hpp index 382f602..f612cc1 100644 --- a/include/rotgen/impl/block_indirect.hpp +++ b/include/rotgen/impl/block_indirect.hpp @@ -4,7 +4,7 @@ #define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME,SIZE,_col) #define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl,SIZE,_col) #define TRANSSOURCENAME ROTGEN_MATRIX_NAME(matrix_impl,SIZE,_row) - #define MAPNAME ROTGEN_MATRIX_NAME(map_impl,SIZE,_col) + #define MAPNAME ROTGEN_MATRIX_NAME(BASEMAP,SIZE,_col) #include #undef CLASSNAME #undef TRANSSOURCENAME @@ -14,7 +14,7 @@ #define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME,SIZE,_row) #define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl,SIZE,_row) #define TRANSSOURCENAME ROTGEN_MATRIX_NAME(matrix_impl,SIZE,_col) - #define MAPNAME ROTGEN_MATRIX_NAME(map_impl,SIZE,_row) + #define MAPNAME ROTGEN_MATRIX_NAME(BASEMAP,SIZE,_row) #include #undef CLASSNAME #undef TRANSSOURCENAME @@ -30,7 +30,7 @@ #define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME,SIZE,_col) #define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl,SIZE,_col) #define TRANSSOURCENAME ROTGEN_MATRIX_NAME(matrix_impl,SIZE,_row) - #define MAPNAME ROTGEN_MATRIX_NAME(map_impl,SIZE,_col) + #define MAPNAME ROTGEN_MATRIX_NAME(BASEMAP,SIZE,_col) #include #undef CLASSNAME #undef TRANSSOURCENAME @@ -40,7 +40,7 @@ #define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME,SIZE,_row) #define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl,SIZE,_row) #define TRANSSOURCENAME ROTGEN_MATRIX_NAME(matrix_impl,SIZE,_col) - #define MAPNAME ROTGEN_MATRIX_NAME(map_impl,SIZE,_row) + #define MAPNAME ROTGEN_MATRIX_NAME(BASEMAP,SIZE,_row) #include #undef CLASSNAME #undef TRANSSOURCENAME diff --git a/src/block.cpp b/src/block.cpp index cc183bf..8cae7d6 100644 --- a/src/block.cpp +++ b/src/block.cpp @@ -16,14 +16,18 @@ namespace rotgen #define USE_CONST #define CONST const #define BASENAME block_const_impl + #define BASEMAP map_const_impl #include "block_indirect.cpp" #undef BASENAME + #undef BASEMAP #undef USE_CONST #undef CONST #define CONST #define BASENAME block_impl + #define BASEMAP map_impl #include "block_indirect.cpp" #undef BASENAME + #undef BASEMAP #undef CONST } diff --git a/src/block_indirect.cpp b/src/block_indirect.cpp index c31622c..283ff16 100644 --- a/src/block_indirect.cpp +++ b/src/block_indirect.cpp @@ -5,7 +5,7 @@ #define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME,SIZE,_col) #define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl,SIZE,_col) #define TRANSSOURCENAME ROTGEN_MATRIX_NAME(matrix_impl,SIZE,_row) - #define MAPNAME ROTGEN_MATRIX_NAME(map_impl,SIZE,_col) + #define MAPNAME ROTGEN_MATRIX_NAME(BASEMAP,SIZE,_col) #include "block_model.cpp" #undef CLASSNAME #undef TRANSSOURCENAME @@ -17,7 +17,7 @@ #define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME,SIZE,_row) #define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl,SIZE,_row) #define TRANSSOURCENAME ROTGEN_MATRIX_NAME(matrix_impl,SIZE,_col) - #define MAPNAME ROTGEN_MATRIX_NAME(map_impl,SIZE,_row) + #define MAPNAME ROTGEN_MATRIX_NAME(BASEMAP,SIZE,_row) #include "block_model.cpp" #undef CLASSNAME #undef TRANSSOURCENAME @@ -35,7 +35,7 @@ #define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME,SIZE,_col) #define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl,SIZE,_col) #define TRANSSOURCENAME ROTGEN_MATRIX_NAME(matrix_impl,SIZE,_row) - #define MAPNAME ROTGEN_MATRIX_NAME(map_impl,SIZE,_col) + #define MAPNAME ROTGEN_MATRIX_NAME(BASEMAP,SIZE,_col) #include "block_model.cpp" #undef CLASSNAME #undef TRANSSOURCENAME @@ -47,7 +47,7 @@ #define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME,SIZE,_row) #define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl,SIZE,_row) #define TRANSSOURCENAME ROTGEN_MATRIX_NAME(matrix_impl,SIZE,_col) - #define MAPNAME ROTGEN_MATRIX_NAME(map_impl,SIZE,_row) + #define MAPNAME ROTGEN_MATRIX_NAME(BASEMAP,SIZE,_row) #include "block_model.cpp" #undef CLASSNAME #undef TRANSSOURCENAME diff --git a/src/block_model.cpp b/src/block_model.cpp index c5be597..6ca61e2 100644 --- a/src/block_model.cpp +++ b/src/block_model.cpp @@ -21,7 +21,7 @@ struct CLASSNAME::payload using matrix_type = Eigen::Matrix; using matrix_block_type = Eigen::Block; using matrix_storage_t = std::pair; - using map_type = Eigen::Map; + using map_type = Eigen::Map; using map_block_type = Eigen::Block; using map_storage_t = std::pair; using data_type = std::variant; diff --git a/test/integration/extract.cpp b/test/integration/extract.cpp index 93da720..864213a 100644 --- a/test/integration/extract.cpp +++ b/test/integration/extract.cpp @@ -17,7 +17,7 @@ TTS_CASE_TPL("Chains of extraction", rotgen::tests::types) auto b = topLeftCorner(a,5,5); TTS_EQUAL(b.startRow(), 0); TTS_EQUAL(b.startCol(), 0); - b.setConstant(-7); + setConstant(b,-7); for(rotgen::Index r=0;r<5;r++) for(rotgen::Index c=0;c<5;c++) @@ -26,7 +26,7 @@ TTS_CASE_TPL("Chains of extraction", rotgen::tests::types) auto bb = bottomRightCorner(b,3,3); TTS_EQUAL(bb.startRow(), 2); TTS_EQUAL(bb.startCol(), 2); - bb.setConstant(42); + setConstant(bb,42); for(rotgen::Index r=2;r<5;r++) for(rotgen::Index c=2;c<5;c++) @@ -35,7 +35,7 @@ TTS_CASE_TPL("Chains of extraction", rotgen::tests::types) auto bbb = row(bb,1); TTS_EQUAL(bbb.startRow(), 1); TTS_EQUAL(bbb.startCol(), 0); - bbb.setConstant(99.5); + setConstant(bbb,99.5); for(rotgen::Index c=3;c<5;c++) TTS_EQUAL(a(3,c), 99.5); @@ -43,9 +43,28 @@ TTS_CASE_TPL("Chains of extraction", rotgen::tests::types) auto bbbb = col(bbb,1); TTS_EQUAL(bbbb.startRow(), 0); TTS_EQUAL(bbbb.startCol(), 1); - bbbb.setConstant(0.125); + setConstant(bbbb,0.125); TTS_EQUAL(a(3,3), 0.125); +}; - std::cout << "a: \n" << a << std::endl; +auto ref_extract ( rotgen::ref > m) { return rotgen::extract(m,0,0,3,4); } +auto ref_cextract( rotgen::ref > m) { return rotgen::extract(m,3,4,4,3); } + +TTS_CASE("Extraction of ref/ref const") +{ + auto m = rotgen::setRandom>(); + + auto extracted = ref_extract(m); + extracted = rotgen::setOnes>(); + + for(rotgen::Index r=0;r<3;r++) + for(rotgen::Index c=0;c<4;c++) + TTS_EQUAL(m(r,c), 1.f); + + auto sliced = ref_cextract(m); + rotgen::extract(m,3,4,4,3) = rotgen::setConstant>(5); + for(rotgen::Index r=0;r<4;r++) + for(rotgen::Index c=0;c<3;c++) + TTS_EQUAL(sliced(r,c), 5.f); }; \ No newline at end of file