Milena (Olena)
User documentation 2.0a Id
|
00001 // Copyright (C) 2007, 2008, 2009, 2011 EPITA Research and Development 00002 // Laboratory (LRDE) 00003 // 00004 // This file is part of Olena. 00005 // 00006 // Olena is free software: you can redistribute it and/or modify it under 00007 // the terms of the GNU General Public License as published by the Free 00008 // Software Foundation, version 2 of the License. 00009 // 00010 // Olena is distributed in the hope that it will be useful, 00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 // General Public License for more details. 00014 // 00015 // You should have received a copy of the GNU General Public License 00016 // along with Olena. If not, see <http://www.gnu.org/licenses/>. 00017 // 00018 // As a special exception, you may use this file as part of a free 00019 // software project without restriction. Specifically, if other files 00020 // instantiate templates or use macros or inline functions from this 00021 // file, or you compile this file and link it with other files to produce 00022 // an executable, this file does not by itself cause the resulting 00023 // executable to be covered by the GNU General Public License. This 00024 // exception does not however invalidate any other reasons why the 00025 // executable file might be covered by the GNU General Public License. 00026 00027 #ifndef MLN_VALUE_EQUIV_HH 00028 # define MLN_VALUE_EQUIV_HH 00029 00039 # include <mln/core/concept/value.hh> 00040 00041 00042 # define mln_value_equiv(V) typename mln::value::internal::equiv_<V>::ret 00043 # define mln_value_equiv_(V) mln::value::internal::equiv_<V>::ret 00044 00045 00046 00047 namespace mln 00048 { 00049 00050 namespace value 00051 { 00052 00053 // Fwd decl. 00054 namespace internal { template <typename T> struct equiv_; } 00055 00056 00057 00059 template <typename V> 00060 typename internal::equiv_<V>::ret 00061 equiv(const mln::Value<V>& v); 00062 00063 00064 00065 # ifndef MLN_INCLUDE_ONLY 00066 00067 namespace internal 00068 { 00069 00070 typedef char yes_; 00071 struct no_ { char dummy[2]; }; 00072 00073 template <typename T> 00074 struct make_ 00075 { 00076 static T* ptr(); 00077 }; 00078 00079 00080 // Fwd decl. 00081 template <unsigned id, typename T> 00082 struct equiv_ret_; 00083 00084 // Fwd decl. 00085 template <typename V> 00086 typename internal::equiv_<V>::ret 00087 run_equiv_(const V& v); 00088 00089 00090 template <typename V, typename T> 00091 inline 00092 typename internal::equiv_<V>::ret 00093 run_equiv_(const Value<V>* v, const T*) 00094 { 00095 return run_equiv_(exact(v)->to_equiv()); // Rec. 00096 } 00097 00098 template <typename V> 00099 inline 00100 V 00101 run_equiv_(const void*, const V* v) 00102 { 00103 return *v; // Stop rec. 00104 } 00105 00106 template <typename V> 00107 inline 00108 typename internal::equiv_<V>::ret 00109 run_equiv_(const V& v) 00110 { 00111 return run_equiv_(&v, &v); 00112 } 00113 00114 00115 template <typename T> 00116 struct equiv_ret_< 1, T > // Rec. 00117 { 00118 typedef typename T::equiv V; 00119 typedef typename equiv_<V>::ret ret; 00120 }; 00121 00122 template <typename T> 00123 struct equiv_ret_< 2, T > // Stop rec. 00124 { 00125 typedef T ret; 00126 }; 00127 00128 template <typename V> 00129 yes_ equiv_selector_(Value<V>*); 00130 00131 no_ equiv_selector_(void*); 00132 00133 template <typename T> 00134 struct equiv_ 00135 { 00136 enum { id = sizeof(equiv_selector_(make_<T>::ptr())) }; 00137 typedef typename equiv_ret_<id, T>::ret ret; 00138 00139 inline 00140 static ret run(const T& t) 00141 { 00142 return ret::run(t); 00143 } 00144 }; 00145 00146 } // end of namespace mln::value::internal 00147 00148 00149 00150 template <typename V> 00151 inline 00152 typename internal::equiv_<V>::ret 00153 equiv(const mln::Value<V>& v) 00154 { 00155 return internal::run_equiv_(exact(v)); 00156 } 00157 00158 00159 # endif // ! MLN_INCLUDE_ONLY 00160 00161 } // end of namespace mln::value 00162 00163 } // end of namespace mln 00164 00165 # include <mln/value/cast.hh> 00166 00167 #endif // ! MLN_VALUE_EQUIV_HH