Milena (Olena)
User documentation 2.0a Id
|
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