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

meta_function.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_META_FUNCTION_HH
00027 # define MLN_CORE_CONCEPT_META_FUNCTION_HH
00028 
00032 
00033 # include <mln/core/concept/object.hh>
00034 # include <mln/core/concept/function.hh>
00035 
00036 # define mln_fun_with(F, T) \
00037 typename F::template with< T >::ret
00038 
00039 # define mln_fun_with_(F, T) \
00040 F::with< T >::ret
00041 
00042 # define mln_fun_withbin(F, T1, T2) \
00043 typename F::template with< T1, T2 >::ret
00044 
00045 # define mln_fun_withbin_(F, T1, T2) \
00046 F::with< T1, T2 >::ret
00047 
00048 # define mln_fun_result(F, T) \
00049 typename F::template with< T >::ret::result
00050 
00051 # define mln_fun_result_(F, T) \
00052 F::with< T >::ret::result
00053 
00054 namespace mln
00055 {
00056 
00057   // Fwd decl.
00058   template <typename E> struct Meta_Function;
00059   template <typename E> struct Meta_Function_v2v;
00060   template <typename E> struct Meta_Function_vv2v;
00061 
00062   // Meta_Function category flag type.
00063   template <>
00064   struct Meta_Function<void>
00065   {
00066     typedef Object<void> super;
00067   };
00068 
00069 
00077   template <typename E>
00078   struct Meta_Function : public Object<E>
00079   {
00080     typedef Meta_Function<void> category;
00081   protected:
00082     Meta_Function();
00083   };
00084 
00085   /*----------------------.
00086   | Unary meta function.  |
00087   `----------------------*/
00088 
00089   template <>
00090   struct Meta_Function_v2v<void> { typedef Meta_Function<void> super; };
00091 
00097   template <typename E>
00098   struct Meta_Function_v2v : public Meta_Function<E>
00099   {
00100     typedef Meta_Function_v2v<void> category;
00101 
00102     protected:
00103       Meta_Function_v2v();
00104       Meta_Function_v2v(const Meta_Function_v2v&);
00105   };
00106 
00107   /*-----------------------.
00108   | Binary meta function.  |
00109   `-----------------------*/
00110 
00111   template <>
00112   struct Meta_Function_vv2v<void> { typedef Meta_Function<void> super; };
00113 
00119   template <typename E>
00120   struct Meta_Function_vv2v : public Meta_Function<E>
00121   {
00122     typedef Meta_Function_vv2v<void> category;
00123 
00124     protected:
00125       Meta_Function_vv2v();
00126       Meta_Function_vv2v(const Meta_Function_vv2v&);
00127   };
00128 
00129   namespace fun
00130   {
00131 
00132     // To be specialized when some state (attributes) have to be transfered
00133     // from the meta-function to the function.
00134     // Warning: the first argument has to be an object with the exact type.
00135     template <typename M, typename T>
00136     mln_fun_with(M, T)
00137     unmeta(const M&, T);
00138 
00139     template <typename M, typename T>
00140     void
00141     unmeta(const Meta_Function<M>&, T); // Safety.
00142 
00143   } // end of namespace mln::fun
00144 
00145 
00146 
00147 # ifndef MLN_INCLUDE_ONLY
00148 
00149   template <typename E>
00150   inline
00151   Meta_Function<E>::Meta_Function()
00152   {
00153     // FIXME: Check "with" on E.
00154   }
00155 
00156   template <typename E>
00157   inline
00158   Meta_Function_v2v<E>::Meta_Function_v2v()
00159   {
00160   }
00161 
00162   template <typename E>
00163   inline
00164   Meta_Function_v2v<E>::Meta_Function_v2v(const Meta_Function_v2v<E>& rhs)
00165   : Meta_Function<E>(rhs)
00166   {
00167   }
00168 
00169   template <typename E>
00170   inline
00171   Meta_Function_vv2v<E>::Meta_Function_vv2v()
00172   {
00173   }
00174 
00175   template <typename E>
00176   inline
00177   Meta_Function_vv2v<E>::Meta_Function_vv2v(const Meta_Function_vv2v<E>& rhs)
00178   : Meta_Function<E>(rhs)
00179   {
00180   }
00181 
00182   namespace fun
00183   {
00184 
00185     template <typename M, typename T>
00186     inline
00187     mln_fun_with(M, T)
00188     unmeta(const M&, T)
00189     {
00190       mlc_is_a(M, Meta_Function)::check();
00191       mln_fun_with(M, T) a;
00192       return a;
00193     }
00194 
00195   } // end of namespace mln::fun
00196 
00197 # endif // ! MLN_INCLUDE_ONLY
00198 
00199 } // end of namespace mln
00200 
00201 
00202 #endif // ! MLN_CORE_CONCEPT_META_FUNCTION_HH

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