diff --git a/dlib/matrix/matrix_assign_fwd.h b/dlib/matrix/matrix_assign_fwd.h index f38e18783..f61b1780e 100644 --- a/dlib/matrix/matrix_assign_fwd.h +++ b/dlib/matrix/matrix_assign_fwd.h @@ -31,6 +31,12 @@ namespace dlib struct is_small_matrix=1 && EXP::NC>=1 && EXP::NR<=17 && EXP::NC<=17 && (EXP::cost <= 70)>::type> { static const bool value = true; }; + template < typename EXP, typename enable = void > + struct is_very_small_matrix { static const bool value = false; }; + template < typename EXP > + struct is_very_small_matrix=1 && EXP::NC>=1 && + (EXP::NR*EXP::NC<=16) && (EXP::cost <= 70)>::type> { static const bool value = true; }; + template < typename EXP, typename enable = void > struct has_column_major_layout { static const bool value = false; }; @@ -300,13 +306,51 @@ namespace dlib matrix_assign_big(dest,src.ref()); } +// ---------------------------------------------------------------------------------------- +// ---------------------------------------------------------------------------------------- + +// this code is here to perform an unrolled version of the matrix_assign() function + template < typename DEST, typename SRC, long NR, long NC, + long R = 0, long C = 0, bool base_case = (R==NR) > + struct matrix_unroll_helper + { + inline static void go ( DEST& dest, const SRC& src) + { + dest(R,C) = src(R,C); + matrix_unroll_helper::go(dest,src); + } + }; + + template < typename DEST, typename SRC, long NR, long NC, long R, long C > + struct matrix_unroll_helper + { inline static void go ( DEST& , const SRC& ) {} }; + + template + inline void matrix_assign_unrolled ( + DEST& dest, + const SRC& src + ) + /*! + requires + - src.destructively_aliases(dest) == false + - dest.nr() == src.nr() + - dest.nc() == src.nc() + ensures + - #dest == src + !*/ + { + COMPILE_TIME_ASSERT(SRC::NR*SRC::NC != 0); + matrix_unroll_helper::go(dest,src); + } + +// ---------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------- template < typename matrix_dest_type, typename src_exp > - inline typename enable_if >::type matrix_assign ( + inline typename enable_if_c::value && ma::is_very_small_matrix::value==false >::type matrix_assign ( matrix_dest_type& dest, const matrix_exp& src ) @@ -322,6 +366,28 @@ namespace dlib matrix_assign_default(dest,src.ref()); } +// ---------------------------------------------------------------------------------------- + + template < + typename matrix_dest_type, + typename src_exp + > + inline typename enable_if_c::value && ma::is_very_small_matrix::value==true >::type matrix_assign ( + matrix_dest_type& dest, + const matrix_exp& src + ) + /*! + requires + - src.destructively_aliases(dest) == false + - dest.nr() == src.nr() + - dest.nc() == src.nc() + ensures + - #dest == src + !*/ + { + matrix_assign_unrolled(dest,src.ref()); + } + // ---------------------------------------------------------------------------------------- }