Milena (Olena)
User documentation 2.0a Id
|
00001 // Copyright (C) 2006, 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_TRAIT_SOLVE_UNARY_HH 00027 # define MLN_TRAIT_SOLVE_UNARY_HH 00028 00037 # include <mln/core/category.hh> 00038 # include <mln/core/routine/exact.hh> 00039 # include <mln/metal/equal.hh> 00040 # include <mln/metal/if.hh> 00041 # include <mln/metal/ret.hh> 00042 00043 00044 // FIXME: Just for the record (use it...) 00045 00046 # ifndef MLN_DEBUG_TRAITS 00047 # endif // ! MLN_DEBUG_TRAITS 00048 00049 00050 00051 namespace mln 00052 { 00053 00054 namespace trait 00055 { 00056 00057 namespace internal 00058 { 00059 00060 00061 template < template <class> class Name, 00062 typename Category, 00063 typename T > 00064 struct trait_set_unary_; 00065 00066 template < template <class> class Name, 00067 template <class> class Category, typename _, 00068 typename T > 00069 struct trait_set_unary_< Name, Category<_>, T > 00070 { 00071 typedef typename mln::trait::set_unary_<Name, Category, T>::ret ret; 00072 }; 00073 00074 00075 // Fwd decls. 00076 template < template <class> class Name, 00077 typename Category, typename T > 00078 struct get_unary_; 00079 00080 00081 template < typename user_ret, /* != not_found and != undefined */ 00082 template <class> class Name, 00083 typename Category, typename T > 00084 struct helper_get_unary_ 00085 { 00086 typedef user_ret ret; // The user has defined 'ret' so we return it. 00087 }; 00088 00089 00090 template < template <class> class Name, 00091 typename Category, typename T > 00092 struct helper_get_unary_< /* user_ret == */ not_found, 00093 Name, Category, T > 00094 { 00095 typedef not_found ret; // End of search due to a blocker; 'ret' is not found. 00096 }; 00097 00098 00099 template < template <class> class Name, 00100 typename Category, typename T > 00101 struct helper_get_unary_< /* user_ret == */ undefined, 00102 Name, Category, T > 00103 { 00104 typedef typename mln::internal::super_category_< Category, T >::ret Super_Category; 00105 typedef typename get_unary_<Name, Super_Category, T>::ret ret; // No user ret definition => Recursion. 00106 }; 00107 00108 00109 template < template <class> class Name, 00110 typename Category, typename T > 00111 struct get_unary_ 00112 { 00113 typedef typename trait_set_unary_<Name, Category, T>::ret user_ret; // First get 'user_ret' 00114 typedef helper_get_unary_<user_ret, Name, Category, T> helper; // Set the helper to make a decision. 00115 typedef mlc_ret(helper) ret; // Return. 00116 }; 00117 00118 00119 template < typename precise_ret, 00120 template <class> class Name, 00121 typename Category, typename T > 00122 struct helper_choose_unary_wrt_ /* precise_ret != undefined */ 00123 { 00124 typedef precise_ret ret; // -> A precise ret has been defined so it is it. 00125 }; 00126 00127 template < template <class> class Name, 00128 typename Category, typename T > 00129 struct helper_choose_unary_wrt_< /* precise_ret == */ undefined, 00130 Name, Category, T > 00131 { 00132 typedef typename get_unary_<Name, Category, T>::ret ret; // -> Go up into the category inheritance 00133 // to fetch a ret from 'set_unary_'s. 00134 }; 00135 00136 template < template <class> class Name, 00137 typename Category, typename T > 00138 struct helper_solve_unary_ 00139 { 00140 typedef typename set_precise_unary_<Name, T>::ret precise_ret; 00141 typedef helper_choose_unary_wrt_< precise_ret, /* undefined or not (?) */ 00142 Name, Category, T> helper; 00143 typedef mlc_ret(helper) ret; 00144 }; 00145 00146 } // end of namespace mln::trait::internal 00147 00148 00149 template < template <class> class Name, 00150 typename T_ > 00151 struct solve_unary 00152 { 00153 typedef mln_exact(T_) T; 00154 typedef typename mln::category<T>::ret Category; 00155 typedef internal::helper_solve_unary_< Name, Category, T > meta_code; 00156 typedef typename meta_code::ret ret; 00157 }; 00158 00159 } // end of namespace mln::trait 00160 00161 } // end of namespace mln 00162 00163 00164 #endif // ! MLN_TRAIT_SOLVE_UNARY_HH