00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifndef OLENA_CONVERT_ABSTRACT_CONVERSION_HH
00029 # define OLENA_CONVERT_ABSTRACT_CONVERSION_HH
00030
00031 # include <mlc/type.hh>
00032 # include <ntg/utils/debug.hh>
00033 # include <functional>
00034
00035 namespace oln {
00036 namespace convert {
00040 namespace abstract {
00041
00042
00043 template <class Exact, class Base>
00044 class conversion;
00045
00046 template<class Result_Type,
00047 class Exact, class Base>
00048 struct conversion_to_type;
00049
00050 template<class Argument_Type, class Result_Type,
00051 class Exact, class Base>
00052 struct conversion_from_type_to_type;
00053
00054 template<class Conv>
00055 struct conversion_traits;
00056
00059 namespace internal {
00061 template <class Base, class T>
00062 struct output {};
00063
00064 template <class Argument_Type, class Result_Type,
00065 class Exact, class Base>
00066 struct output<conversion_from_type_to_type<Argument_Type, Result_Type, Exact, Base >, Argument_Type>
00067 {
00068 typedef Result_Type ret;
00069 };
00070
00071 template <class Result_Type,
00072 class Exact, class Base, class T>
00073 struct output<conversion_to_type<Result_Type, Exact, Base >, T>
00074 {
00075 typedef Result_Type ret;
00076 };
00077 }
00078
00079 }
00080
00081 namespace abstract {
00087 template<class Exact, class Base>
00088 struct conversion : public mlc_hierarchy::any< Exact >
00089 {
00090 static std::string
00091 name()
00092 {
00093 return std::string("conversion<") + Exact::name() + ">";
00094 }
00095
00096 public:
00097 template<class T>
00098 struct output
00099 {
00100 typedef typename internal::output<Base, T>::ret ret;
00101 };
00102
00104 template <class T>
00105 typename output<T>::ret
00106 operator()(const T& in) const
00107 {
00108 return this->exact().doit(in);
00109 }
00110
00111 protected:
00112 conversion() {}
00113 };
00114
00116 template<class Result_Type, class Exact = mlc::final, class Base = mlc::final>
00117 struct conversion_to_type :
00118 public conversion< typename mlc::exact_vt<conversion_to_type< Result_Type, Exact >, Exact>::ret,
00119 typename mlc::exact_vt<conversion_to_type< Result_Type, Exact >, Base>::ret >
00120 {
00121
00122
00123
00124
00125
00126
00127
00128 typedef Result_Type result_type;
00129
00130 static std::string
00131 name()
00132 {
00133
00134 return std::string("conversion_to_type<")
00135 + ntg_name(Result_Type) + ", "
00136 + Exact::name() + ">";
00137 }
00138
00139 protected:
00140 conversion_to_type() {}
00141 };
00142
00144 template<class Argument_Type, class Result_Type,
00145 class Exact = mlc::final, class Base = mlc::final>
00146 struct conversion_from_type_to_type:
00147 public conversion_to_type< Result_Type,
00148 typename mlc::exact_vt<conversion_from_type_to_type< Argument_Type, Result_Type, Base, Exact>, Exact>::ret,
00149 typename mlc::exact_vt<conversion_from_type_to_type< Argument_Type, Result_Type, Base, Exact>, Base>::ret >
00150 {
00151
00152
00153
00154
00155 typedef Argument_Type argument_type;
00156
00157 static std::string
00158 name()
00159 {
00160
00161 return std::string("conversion_from_type_to_type<")
00162 + ntg_name(Argument_Type) + ", "
00163 + ntg_name(Result_Type) + ", "
00164 + "FIXME: ntg_name(Exact)" + ">";
00165 }
00166
00167 protected :
00168 conversion_from_type_to_type() {}
00169 };
00170 }
00171
00172 }
00173
00174 }
00175
00176
00177 #endif // OLENA_CONVERT_ABSTRACT_CONVERSION_HH