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