ivl 679
ivl/details/array/impl/specialization_details/subarray/subarray_tools.hpp
00001 /* This file is part of the ivl C++ library <http://image.ntua.gr/ivl>.
00002    A C++ template library extending syntax towards mathematical notation.
00003 
00004    Copyright (C) 2012 Yannis Avrithis <iavr@image.ntua.gr>
00005    Copyright (C) 2012 Kimon Kontosis <kimonas@image.ntua.gr>
00006 
00007    ivl is free software; you can redistribute it and/or modify
00008    it under the terms of the GNU Lesser General Public License 
00009    version 3 as published by the Free Software Foundation.
00010 
00011    Alternatively, you can redistribute it and/or modify it under the terms 
00012    of the GNU General Public License version 2 as published by the Free 
00013    Software Foundation.
00014 
00015    ivl is distributed in the hope that it will be useful,
00016    but WITHOUT ANY WARRANTY; without even the implied warranty of
00017    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
00018    See the GNU General Public License for more details.
00019 
00020    You should have received a copy of the GNU General Public License 
00021    and a copy of the GNU Lesser General Public License along 
00022    with ivl. If not, see <http://www.gnu.org/licenses/>. */
00023 
00024 #ifndef IVL_ARRAY_SPECIALIZATION_DETAILS_SUBARRAY_TOOLS_HPP
00025 #define IVL_ARRAY_SPECIALIZATION_DETAILS_SUBARRAY_TOOLS_HPP
00026 
00027 namespace ivl {
00028 
00029 namespace array_details {
00030 
00031 template <class REF_ITER_IS_ND, class IT>
00032 struct subarray_tools
00033 {
00034 };
00035 
00036 template <class IT>
00037 struct subarray_tools<types::t_true, IT>
00038 {
00039         template <class A, class IDX>
00040         static IT begin(A& a, size_t dim, const IDX& i)
00041                         { return a._iter(dim, i); }
00042 
00043         template <class A>
00044         static IT rend_base(A& a, size_t dim) { return a._rend(dim).base(); }
00045 
00046         template <class A>
00047         static IT end(A& a, size_t dim) { return a._end(dim); }
00048 
00049         template <class A>
00050         static IT last(A& a, size_t dim) { return a._last(dim); }
00051 
00052         template <class A>
00053         static IT //todo names..
00054                 iter(A& a, size_t dim, const IT& x)
00055                         { return a._begin(dim, x); }
00056 
00057         template <class A>
00058         static inline size_t stride(A& a, size_t dim) { return 1; }
00059 
00060 };
00061 
00062 template <class IT>
00063 struct subarray_tools<types::t_false, IT>
00064 {
00065         template <class A, class IDX>
00066         static IT begin(A& a, size_t dim, const IDX& i)
00067                         { return a.begin() + sub2ind(a, i); }
00068 
00069         template <class A>
00070         static IT rend_base(A& a, size_t dim) { return a.rend().base(); }
00071 
00072         template <class A>
00073         static IT end(A& a, size_t dim) { return a.end(); }
00074 
00075         template <class A>
00076         static IT iter(A& a, size_t dim, const IT& x) { return x; }
00077 
00078         template <class A>
00079         static inline size_t stride(A& a, size_t dim) { return a.stride(dim); }
00080 
00081 };
00082 
00083 struct subarray_common_tools
00084 {
00085         struct add_op
00086         {
00087                 template<class X, class Y>
00088                 static inline void operate(X& a, const Y& b) { a += b; }
00089         };
00090         struct sub_op
00091         {
00092                 template<class X, class Y>
00093                 static inline void operate(X& a, const Y& b) { a -= b; }
00094         };
00095 
00096         template<class OP, class IT>
00097         static inline void inc_along(IT& ir, const IT& d,
00098                 const ptrdiff_t* diff, size_t pos, size_t str)
00099         {
00100                 if(diff)
00101                         ir.inc_along(d, diff[pos]);
00102                 else
00103                         ir.inc_along(d, str);
00104         };
00105 
00106         template<class OP, class IT>
00107         static inline void dec_along(IT& ir, const IT& d,
00108                 const ptrdiff_t* diff, size_t pos, size_t str)
00109         {
00110                 if(diff)
00111                         ir.dec_along(d, diff[pos]);
00112                 else
00113                         ir.dec_along(d, str);
00114         };
00115 
00116         // TODO:: possible speed improvement is:
00117         // do not use pos0 at all in the array specialized case, and
00118         // use a ptrdiff_t + length as barrier.
00119         // make also a specialized function that controls the pos0++ and
00120         // the ending condition.
00121         // However, when copying from an iterator<2> to an iterator<0>
00122         // it will be needed to generate pos0 from diff0 - start_diff0_border
00123         // and to reset diff0 = start_diff0_border, and
00124         // when copying from an iterator<0> to an iterator<2> do:
00125         // diff0 += pos
00126 
00127         template<int SP = 0> // generic case operator. slower
00128         struct inner_dim_adder
00129         {
00130                 template<class OP, class IT>
00131                 static inline void operate(IT& ir, const ptrdiff_t* diff0,
00132                         size_t pos, size_t str)
00133                 {
00134                         if(diff0)
00135                                 OP::operate(ir, diff0[pos]);
00136                         else
00137                                 OP::operate(ir, str);
00138                 }
00139         };
00140 };
00141 
00142 template<>
00143 struct subarray_common_tools::inner_dim_adder<1> // special case 1: index 0 is all or range.
00144 {
00145         template<class OP, class IT>
00146         static inline void operate(IT& ir, const ptrdiff_t* diff0,
00147                 size_t pos, size_t str)
00148         {
00149                 OP::operate(ir, str);
00150         }
00151 };
00152 template<>
00153 struct subarray_common_tools::inner_dim_adder<2> // special case 2: index 0 is array.
00154 {
00155         template<class OP, class IT>
00156         static inline void operate(IT& ir, const ptrdiff_t* diff0,
00157                 size_t pos, size_t str)
00158         {
00159                 OP::operate(ir, diff0[pos]);
00160         }
00161 };
00162 
00163 }; /*namespace array_details*/
00164 
00165 }; /*namespace ivl*/
00166 
00167 
00168 #endif // IVL_ARRAY_SPECIALIZATION_DETAILS_SUBARRAY_TOOLS_HPP
 All Classes Namespaces Files Functions Variables Typedefs Enumerations