Mirror reflection library 0.5.13
|
00001 00010 #ifndef MIRROR_STREAM_STRUCTURED_1102141318_HPP 00011 #define MIRROR_STREAM_STRUCTURED_1102141318_HPP 00012 00013 #include <mirror/stream/base.hpp> 00014 #include <mirror/cntnr_kind_tags.hpp> 00015 #include <type_traits> 00016 00017 MIRROR_NAMESPACE_BEGIN 00018 namespace stream { 00019 00021 00025 struct to_simple_struct : _target<to_simple_struct> { }; 00026 00027 template <typename T> 00028 class _writer<T, to_simple_struct> 00029 { 00030 private: 00031 // helper functor executed on all members 00032 struct write_x 00033 { 00034 std::ostream& out; 00035 const _wrap<T, to_simple_struct>& obj; 00036 00037 inline write_x( 00038 std::ostream& os, 00039 const _wrap<T, to_simple_struct>& ob 00040 ): out(os) 00041 , obj(ob) 00042 { } 00043 00044 static bool is_escaped_char(char c) 00045 { 00046 return (c == '"') || 00047 (c == '\\') || 00048 (c == '\b') || 00049 (c == '\f') || 00050 (c == '\n') || 00051 (c == '\r') || 00052 (c == '\t'); 00053 } 00054 00055 static char translate_esc_char(char c) 00056 { 00057 switch(c) 00058 { 00059 case '\b': return 'b'; 00060 case '\f': return 'f'; 00061 case '\n': return 'n'; 00062 case '\r': return 'r'; 00063 case '\t': return 't'; 00064 default:; 00065 } 00066 return c; 00067 } 00068 00069 void wr_val(bool x) 00070 { 00071 out << (x ? "true" : "false"); 00072 } 00073 00074 void do_wr_val(char x) 00075 { 00076 if(is_escaped_char(x)) 00077 out << '\\' << translate_esc_char(x); 00078 else out << x; 00079 } 00080 00081 void wr_val(char x) 00082 { 00083 out << '"'; 00084 do_wr_val(x); 00085 out << '"'; 00086 } 00087 00088 void wr_val(unsigned char x) 00089 { 00090 out << int(x); 00091 } 00092 00093 void wr_val(const std::string& x) 00094 { 00095 out << '"'; 00096 std::string::const_iterator i = x.begin(), e = x.end(); 00097 while(i != e) do_wr_val(*i++); 00098 out << '"'; 00099 } 00100 00101 template <typename X> 00102 void wr_val( 00103 const X& x, 00104 typename std::enable_if< 00105 std::is_arithmetic<X>::value 00106 >::type* = nullptr 00107 ) 00108 { 00109 out << x; 00110 } 00111 00112 template <typename X> 00113 void wr_val( 00114 const X& x, 00115 typename std::enable_if< 00116 !std::is_arithmetic<X>::value && 00117 !std::is_enum<X>::value 00118 >::type* = nullptr 00119 ) 00120 { 00121 out << to_simple_struct::from(x, obj); 00122 } 00123 00124 template <typename X> 00125 void wr_val( 00126 X x, 00127 typename std::enable_if< 00128 std::is_enum<X>::value 00129 >::type* = nullptr 00130 ) 00131 { 00132 out << MIRRORED_ENUM(X)::name_by_value(x); 00133 } 00134 }; 00135 00136 struct write_mem : write_x 00137 { 00138 inline write_mem( 00139 std::ostream& os, 00140 const _wrap<T, to_simple_struct>& ob 00141 ): write_x(os, ob) 00142 { } 00143 00144 template <typename IterInfo> 00145 void operator()(IterInfo) 00146 { 00147 typedef typename IterInfo::type meta_member; 00148 // write the separator if necessary 00149 if(!IterInfo::is_first::value) this->out << ", "; 00150 // write the value 00151 wr_val(meta_member::get(this->obj.value)); 00152 } 00153 }; 00154 00155 // write a structure 00156 template <typename MetaT> 00157 void write( 00158 MetaT, 00159 std::ostream& out, 00160 const _wrap<T, to_simple_struct>& obj, 00161 non_container_tag& 00162 ) 00163 { 00164 static_assert( 00165 mp::empty<all_containers<MetaT> >::value, 00166 "Non-container types should not have containers" 00167 ); 00168 out << "{"; 00169 mp::for_each_ii<all_member_variables<MetaT> >(write_mem(out, obj)); 00170 out << "}"; 00171 } 00172 00173 // helper functor executed on all elements 00174 struct write_elem : write_x 00175 { 00176 inline write_elem( 00177 std::ostream& os, 00178 const _wrap<T, to_simple_struct>& ob 00179 ): write_x(os, ob) 00180 { } 00181 00182 template <typename Locator> 00183 void operator()(Locator loc, bool first = true) 00184 { 00185 if(loc) 00186 { 00187 // write the separator if necessary 00188 if(!first) this->out << ", "; 00189 // write the value 00190 wr_val(loc.get()); 00191 } 00192 } 00193 }; 00194 00195 // write a simple container 00196 template <typename MetaT> 00197 void write( 00198 MetaT, 00199 std::ostream& out, 00200 const _wrap<T, to_simple_struct>& obj, 00201 simple_container_tag& 00202 ) 00203 { 00204 out << "["; 00205 typedef typename default_traversal< 00206 mp::front<all_containers<MetaT> > 00207 >::type meta_trav; 00208 // 00209 write_elem do_write(out, obj); 00210 auto trav=meta_trav::start(obj.value); 00211 if(!trav.done()) 00212 { 00213 do_write(trav.front(), true); 00214 trav.step_front(); 00215 while(!trav.done()) 00216 { 00217 do_write(trav.front(), false); 00218 trav.step_front(); 00219 } 00220 } 00221 out << "]"; 00222 } 00223 00224 // write an optional/container 00225 template <typename MetaT> 00226 void write( 00227 MetaT, 00228 std::ostream& out, 00229 const _wrap<T, to_simple_struct>& obj, 00230 optional_container_tag& 00231 ) 00232 { 00233 typedef typename mp::front<all_containers<MetaT> >::type 00234 meta_cnt; 00235 if(meta_cnt::empty(obj.value)) 00236 { 00237 out << "nil"; 00238 } 00239 else 00240 { 00241 auto tr = meta_cnt::default_traversal::start(obj.value); 00242 assert(!tr.done()); 00243 write_elem do_write(out, obj); 00244 do_write(tr.front()); 00245 } 00246 } 00247 00248 struct write_var 00249 { 00250 write_elem do_write; 00251 00252 inline write_var( 00253 std::ostream& os, 00254 const _wrap<T, to_simple_struct>& ob 00255 ): do_write(os, ob) 00256 { } 00257 00258 template <typename MetaCntnr> 00259 void operator()(MetaCntnr) 00260 { 00261 // write the value 00262 if(!MetaCntnr::empty(do_write.obj.value)) 00263 { 00264 do_write( 00265 MetaCntnr:: 00266 default_traversal:: 00267 start(do_write.obj.value). 00268 front() 00269 ); 00270 } 00271 } 00272 }; 00273 00274 // write an variant/container 00275 template <typename MetaT> 00276 void write( 00277 MetaT, 00278 std::ostream& out, 00279 const _wrap<T, to_simple_struct>& obj, 00280 variant_container_tag& 00281 ) 00282 { 00283 write_var do_write(out, obj); 00284 mp::for_each<all_containers<MetaT> >(do_write); 00285 } 00286 00287 // other containers are not supported 00288 template <typename MetaT> 00289 void write( 00290 MetaT, 00291 std::ostream& out, 00292 const _wrap<T, to_simple_struct>& obj, 00293 container_tag& 00294 ); 00295 00296 public: 00297 std::ostream& operator()( 00298 std::ostream& out, 00299 const _wrap<T, to_simple_struct>& obj 00300 ) 00301 { 00302 typedef MIRRORED_CLASS(T) meta_T; 00303 typename container_kind<meta_T>::type kind; 00304 write(meta_T(), out, obj, kind); 00305 return out; 00306 } 00307 00308 std::ostream& operator()( 00309 std::ostream& out, 00310 const _wrap<T, to_simple_struct>& obj, 00311 const name_proc& namer 00312 ) 00313 { 00314 typedef MIRRORED_CLASS(T) meta_T; 00315 typename container_kind<meta_T>::type kind; 00316 out << '"'; namer(out); out << '"' << " = "; 00317 write(meta_T(), out, obj, kind); 00318 return out; 00319 } 00320 }; 00321 00322 } // namespace stream 00323 MIRROR_NAMESPACE_END 00324 00325 #endif //include guard 00326