Mirror reflection library 0.5.13
|
00001 00010 #ifndef MIRROR_STREAM_META_XML_1011291729_HPP 00011 #define MIRROR_STREAM_META_XML_1011291729_HPP 00012 00013 #include <mirror/stream/base.hpp> 00014 #include <type_traits> 00015 00016 MIRROR_NAMESPACE_BEGIN 00017 namespace stream { 00018 00020 00024 struct to_meta_xml : _target<to_meta_xml> { }; 00025 00026 template <typename T> 00027 class _writer<T, to_meta_xml> 00028 { 00029 private: 00030 static std::ostream& indent(std::ostream& out, int depth) 00031 { 00032 while(depth--) out << " "; 00033 return out; 00034 } 00035 00036 // helper functor executed on all members 00037 struct write_mem 00038 { 00039 std::ostream& out; 00040 const _wrap<T, to_meta_xml>& obj; 00041 00042 inline write_mem( 00043 std::ostream& os, 00044 const _wrap<T, to_meta_xml>& ob 00045 ): out(os) 00046 , obj(ob) 00047 { } 00048 00049 void wr_val(bool x) 00050 { 00051 out << x ? "true" : "false"; 00052 } 00053 00054 void wr_val(const std::string& x) 00055 { 00056 // TODO: xml string escaping 00057 out << x; 00058 } 00059 00060 template <typename X> 00061 void wr_val( 00062 const X& x, 00063 typename std::enable_if< 00064 std::is_arithmetic<X>::value 00065 >::type* = nullptr 00066 ) 00067 { 00068 out << x; 00069 } 00070 00071 template <typename X> 00072 void wr_val( 00073 const X& x, 00074 typename std::enable_if< 00075 !std::is_arithmetic<X>::value && 00076 !std::is_enum<X>::value 00077 >::type* = nullptr 00078 ) 00079 { 00080 out << std::endl << to_meta_xml::from(x, obj); 00081 indent(out, obj.depth()+1); 00082 } 00083 00084 template <typename X> 00085 void wr_val( 00086 X x, 00087 typename std::enable_if< 00088 std::is_enum<X>::value 00089 >::type* = nullptr 00090 ) 00091 { 00092 out << MIRRORED_ENUM(X)::name_by_value(x); 00093 } 00094 00095 template <typename IterInfo> 00096 void operator()(IterInfo) 00097 { 00098 typedef typename IterInfo::type meta_member; 00099 // write the separator if necessary 00100 // write the member name and the separating ':' 00101 indent(out, obj.depth()+1) 00102 << "<member name='" 00103 << meta_member::base_name() 00104 << "' type='" 00105 << meta_member::type::full_name() 00106 << "'>"; 00107 // write the value 00108 wr_val(meta_member::get(obj.value)); 00109 out << "<member/>" 00110 << std::endl; 00111 } 00112 }; 00113 public: 00114 std::ostream& operator()( 00115 std::ostream& out, 00116 const _wrap<T, to_meta_xml>& obj 00117 ) 00118 { 00119 typedef MIRRORED_CLASS(T) meta_T; 00120 mp::for_each_ii<members<meta_T> >(write_mem(out, obj)); 00121 return out; 00122 } 00123 00124 std::ostream& operator()( 00125 std::ostream& out, 00126 const _wrap<T, to_meta_xml>& obj, 00127 const name_proc& namer 00128 ) 00129 { 00130 typedef MIRRORED_CLASS(T) meta_T; 00131 out << "<object name='"; 00132 namer(out); 00133 out << "' type='" 00134 << meta_T::full_name() 00135 << "'>" 00136 << std::endl; 00137 mp::for_each_ii<members<meta_T> >(write_mem(out, obj)); 00138 out << "<object/>"; 00139 return out; 00140 } 00141 }; 00142 00143 } // namespace stream 00144 MIRROR_NAMESPACE_END 00145 00146 #endif //include guard 00147