• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List

accumulator.hh

00001 // Copyright (C) 2007, 2008, 2009 EPITA Research and Development Laboratory (LRDE)
00002 //
00003 // This file is part of Olena.
00004 //
00005 // Olena is free software: you can redistribute it and/or modify it under
00006 // the terms of the GNU General Public License as published by the Free
00007 // Software Foundation, version 2 of the License.
00008 //
00009 // Olena is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012 // General Public License for more details.
00013 //
00014 // You should have received a copy of the GNU General Public License
00015 // along with Olena.  If not, see <http://www.gnu.org/licenses/>.
00016 //
00017 // As a special exception, you may use this file as part of a free
00018 // software project without restriction.  Specifically, if other files
00019 // instantiate templates or use macros or inline functions from this
00020 // file, or you compile this file and link it with other files to produce
00021 // an executable, this file does not by itself cause the resulting
00022 // executable to be covered by the GNU General Public License.  This
00023 // exception does not however invalidate any other reasons why the
00024 // executable file might be covered by the GNU General Public License.
00025 
00026 #ifndef MLN_CORE_CONCEPT_ACCUMULATOR_HH
00027 # define MLN_CORE_CONCEPT_ACCUMULATOR_HH
00028 
00032 
00033 # include <mln/core/concept/proxy.hh>
00034 # include <mln/metal/fix_return.hh>
00035 # include <mln/metal/const.hh>
00036 # include <mln/trait/accumulators.hh>
00037 
00038 
00039 namespace mln
00040 {
00041 
00042   // Forward declaration.
00043   template <typename E> struct Accumulator;
00044 
00045 
00046   namespace convert
00047   {
00048 
00049     namespace over_load
00050     {
00051 
00052       template <typename A>
00053       void
00054       from_to_(const Accumulator<A>& from, mln_result(A)& to);
00055 
00056     } // end of namespace mln::convert::over_load
00057 
00058   } // end of namespace mln::convert
00059 
00060 
00061   // Accumulator category flag type.
00062   template <>
00063   struct Accumulator<void>
00064   {
00065     typedef Proxy<void> super;
00066   };
00067 
00068 
00069 
00077   template <typename E>
00078   struct Accumulator : public Proxy<E>
00079   {
00080     typedef Accumulator<void> category;
00081 
00082     /*
00083       typedef argument;
00084       typedef result;
00085       typedef q_result;
00086 
00087       void init();
00088       void take(const argument& t);
00089       void take(const E& other);
00090 
00091       q_result to_result() const;
00092       operator q_result const;
00093 
00094       bool is_valid() const;
00095      */
00096 
00101     template <typename T>
00102     void take_as_init(const T& t); // 't' is either argument or E.
00103 
00105     template <typename T>
00106     void take_as_init_(const T& t);
00107 
00108 
00113     template <typename T>
00114     void take_n_times(unsigned n, const T& t);
00115 
00117     template <typename T>
00118     void take_n_times_(unsigned n, const T& t);
00119 
00120     
00121   protected:
00122     Accumulator();
00123   };
00124 
00125 
00126 # ifndef MLN_INCLUDE_ONLY
00127 
00128 
00129   // convert::from_to_
00130 
00131   namespace convert
00132   {
00133 
00134     namespace over_load
00135     {
00136 
00137       template <typename A>
00138       void
00139       from_to_(const Accumulator<A>& from_, mln_result(A)& to)
00140       {
00141         const A& from = exact(from_);
00142         if (from.is_valid())
00143           to = from.to_result();
00144         else
00145           to = mln_result(A)();
00146       }
00147 
00148     } // end of namespace mln::convert::over_load
00149 
00150   } // end of namespace mln::convert
00151 
00152 
00153 
00154   // Accumulator<E>
00155 
00156   template <typename E>
00157   inline
00158   Accumulator<E>::Accumulator()
00159   {
00160     typedef mln_argument(E) argument;
00161     typedef mln_result(E)   result;
00162     typedef mln_q_result(E) q_result;
00163 
00164     void (E::*m1)() = & E::init;
00165     m1 = 0;
00166     void (E::*m2)(const argument&) = & E::take;
00167     m2 = 0;
00168     void (E::*m3)(const E&) = & E::take;
00169     m3 = 0;
00170 
00171     q_result (E::*m4)() const = & E::to_result;
00172     m4 = 0;
00173     q_result (E::*m5)() const = & E::operator q_result;
00174     m5 = 0;
00175 
00176     bool (E::*m6)() const = & E::is_valid;
00177     m6 = 0;
00178   }
00179 
00180 
00181   // take_as_init
00182 
00183   template <typename E>
00184   template <typename T>
00185   void
00186   Accumulator<E>::take_as_init(const T& t)
00187   {
00188     typedef mln_exact(T) T_;
00189     typedef mlc_converts_to(T_, mln_argument(E)) t_is_argument;
00190     typedef mlc_converts_to(T_, E)               t_is_accumulator;
00191     mlc_or(t_is_argument, t_is_accumulator)::check();
00192 
00193     // Dispatch.
00194     exact(this)->take_as_init_(t);
00195   }
00196 
00197   template <typename E>
00198   template <typename T>
00199   void
00200   Accumulator<E>::take_as_init_(const T& t)
00201   {
00202     // Default impl.
00203     exact(this)->init();
00204     exact(this)->take(t);
00205   }
00206 
00207 
00208   // take n times
00209 
00210   template <typename E>
00211   template <typename T>
00212   void
00213   Accumulator<E>::take_n_times(unsigned n, const T& t)
00214   {
00215     typedef mln_exact(T) T_;
00216     typedef mlc_converts_to(T_, mln_argument(E)) t_is_argument;
00217     typedef mlc_converts_to(T_, E)               t_is_accumulator;
00218     mlc_or(t_is_argument, t_is_accumulator)::check();
00219 
00220     if (n == 0u)
00221       return;
00222 
00223     // Dispatch.
00224     exact(this)->take_n_times_(n, t);
00225   }
00226 
00227   template <typename E>
00228   template <typename T>
00229   void
00230   Accumulator<E>::take_n_times_(unsigned n, const T& t)
00231   {
00232     // Default impl.
00233     for (unsigned i = 0; i < n; ++i)
00234       exact(this)->take(t);
00235   }
00236 
00237 # endif // ! MLN_INCLUDE_ONLY
00238 
00239 } // end of namespace mln
00240 
00241 
00242 #endif // ! MLN_CORE_CONCEPT_ACCUMULATOR_HH

Generated on Tue Oct 4 2011 15:23:23 for Milena (Olena) by  doxygen 1.7.1