00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef MLN_FUN_P2P_FOLD_HH
00027 # define MLN_FUN_P2P_FOLD_HH
00028
00032
00033 # include <mln/core/concept/function.hh>
00034 # include <mln/core/site_set/box.hh>
00035
00036
00037 namespace mln
00038 {
00039
00040 namespace fun
00041 {
00042
00043 namespace p2p
00044 {
00045
00046
00047 namespace internal {
00048 template <typename F, typename P>
00049 P do_fold(const P& p, const box<P>& b);
00050 }
00051
00052
00053 template < typename P,
00054 int dir_0 = -1,
00055 int dir_1 = -1,
00056 int dir_2 = -1 >
00057 struct fold : Function_v2v< fold<P,dir_0,dir_1,dir_2> >
00058 {
00059 fold();
00060 fold(const box<P>& b);
00061
00062 typedef P result;
00063 P operator()(const P& p) const;
00064
00065 box<P> b;
00066 };
00067
00068
00069 # ifndef MLN_INCLUDE_ONLY
00070
00071 namespace internal
00072 {
00073
00074 template <int dim, typename F>
00075 struct do_fold_helper;
00076
00077 template <typename P>
00078 struct do_fold_helper< 1, fold< P, -1, -1, -1 > >
00079 {
00080 static P run(const P& p, const box<P>& b)
00081 {
00082 P tmp(p[0] % b.len(0));
00083 return tmp;
00084 }
00085 };
00086
00087 template <typename P, int dir_0, int dir_1>
00088 struct do_fold_helper< 2, fold< P, dir_0, dir_1, -1 > >
00089 {
00090 static P run(const P& p, const box<P>& b)
00091 {
00092 P tmp(dir_0 ? p[0] % b.len(0) : p[0],
00093 dir_1 ? p[1] % b.len(1) : p[1]);
00094 return tmp;
00095 }
00096 };
00097
00098 template <typename P, int dir_0, int dir_1, int dir_2>
00099 struct do_fold_helper< 3, fold< P, dir_0, dir_1, dir_2 > >
00100 {
00101 static P run(const P& p, const box<P>& b)
00102 {
00103 P tmp(dir_0 ? p[0] % b.len(0) : p[0],
00104 dir_1 ? p[1] % b.len(1) : p[1],
00105 dir_2 ? p[2] % b.len(2) : p[2]);
00106 return tmp;
00107 }
00108 };
00109
00110 template <typename F, typename P>
00111 inline
00112 P
00113 do_fold(const F&, const P& p, const box<P>& b)
00114 {
00115 return do_fold_helper<P::dim, F>::run(p, b);
00116 }
00117
00118 }
00119
00120
00121
00122
00123 template <typename P, int dir_0, int dir_1, int dir_2>
00124 inline
00125 fold<P,dir_0,dir_1,dir_2>::fold()
00126 {
00127 }
00128
00129 template <typename P, int dir_0, int dir_1, int dir_2>
00130 inline
00131 fold<P,dir_0,dir_1,dir_2>::fold(const box<P>& b)
00132 : b(b)
00133 {
00134 }
00135
00136 template <typename P, int dir_0, int dir_1, int dir_2>
00137 inline
00138 P
00139 fold<P,dir_0,dir_1,dir_2>::operator()(const P& p) const
00140 {
00141 return internal::do_fold(*this, p, b);
00142 }
00143
00144 # endif // ! MLN_INCLUDE_ONLY
00145
00146 }
00147
00148 }
00149
00150 }
00151
00152
00153 #endif // ! MLN_FUN_P2P_FOLD_HH