00001
00008 #ifndef _TYPING_1
00009 #define _TYPING_1
00010
00011 #include <boost/type_traits.hpp>
00012 #include <boost/utility/enable_if.hpp>
00013
00014 #include "eleve/src/typing0.hpp"
00015 #include "eleve/src/scal0.hpp"
00016
00017 namespace eepgwde { namespace detail {
00018
00021
00028 struct Renderer {
00029
00034 virtual std::string ys(const boost::any & o) const
00035 throw (std::domain_error) = 0;
00036
00038 virtual std::string null() const
00039 throw (std::domain_error) = 0;
00040
00044 virtual std::string name() const = 0;
00045
00046 virtual ~Renderer() {}
00047 };
00048
00062 template <typename T>
00063 struct null0 : public boost::is_object<T>,
00064 public boost::is_stateless<T>,
00065 public boost::has_trivial_assign<T>,
00066 public boost::has_trivial_copy_constructor<T>,
00067 public boost::has_trivial_default_constructor<T>,
00068 public virtual Renderer {
00069 typedef null0<T> type;
00070 typedef T result_type;
00071
00075 virtual const result_type operator() () {
00076 return i0::null1<result_type>();
00077 }
00078
00080 virtual operator const boost::any & () const {
00081 static const result_type a = (null0<result_type>())();
00082 static const boost::any baa(a);
00083 return baa;
00084 }
00085
00089 virtual std::string name() const {
00090 static const std::string s =
00091 boost::any( i0::null1<result_type>() ).type().name();
00092 return s;
00093 }
00094
00098 virtual bool operator==(const boost::any & b) const {
00099 static const boost::any ba = *this;
00100 boost::any bb = b;
00101 return ba.type() == bb.type();
00102 }
00103
00104 virtual bool operator!=(const boost::any & b) const {
00105 return ! (*this == b);
00106 }
00107
00113 std::string ys(const boost::any & o) const
00114 throw (std::domain_error) {
00115 static const result_type a = (null0<result_type>())();
00116 boost::any me = *this;
00117 if ( me.type() != o.type())
00118 throw std::domain_error(std::string("null0: ys: mismatch: ") +
00119 me.type().name() + " " + o.type().name());
00120 return i0::ys<result_type>(a, o);
00121 }
00122
00126 std::string null() const
00127 throw (std::domain_error) {
00128 static const result_type a = (null0<result_type>())();
00129 static const boost::any o(a);
00130 return i0::ys<result_type>(a, o);
00131 }
00132
00140 virtual result_type xs(const std::string & o) const
00141 throw (std::domain_error) {
00142 static const result_type a = (null0<result_type>())();
00143 return i0::xs<result_type>(a, o);
00144 }
00145
00146 };
00147
00150
00151 }}
00152
00153 namespace eepgwde { namespace detail {
00154
00155 namespace i0 {
00156
00161
00163 template <typename T>
00164 T * zs0(T *v, const boost::any & o, dummy<0> = 0 )
00165 throw (std::exception) {
00166 static const boost::any nullT = (null0<T>())();
00167
00168 if (o.empty()) return 0;
00169
00170 if (o.type() == nullT.type()) {
00171 *v = any_cast<T>(o);
00172 return v;
00173 }
00174
00175 try {
00176 *v = any_cast<T>(o);
00177 return v;
00178 } catch(const boost::bad_any_cast &) {
00179 }
00180 return 0;
00181 }
00182
00187 template <typename T>
00188 T * zs0(T *v, const boost::any & o, dummy<1> = 1 )
00189 throw (std::exception) {
00190 static const boost::any nullS = (null0<std::string>())();
00191
00192 if (o.type() != nullS.type()) {
00193 return 0;
00194 }
00195
00196 std::string s("");
00197 try {
00198 s = any_cast<std::string>(o);
00199 *v = lexical_cast<T>(s);
00200 return v;
00201 } catch(const boost::bad_lexical_cast & e0) {
00202 return 0;
00203 } catch(const boost::bad_any_cast & e1) {
00204 std::cerr << "zs0: " << e1.what()
00205 << " : " << o.type().name() << std::endl;
00206 }
00207
00208 return 0;
00209 }
00210
00220 template <typename T>
00221 T * zs0(T *v, const boost::any & o, dummy<2> = 2 )
00222 throw (std::exception) {
00223 static const null0<T> nullT = null0<T>();
00224 static const boost::any nullS = (null0<std::string>())();
00225
00226 boost::any o1(o);
00227 if (o1.type() != nullS.type()) {
00228
00229
00230 Typing::types0_t types0_ = eepgwde::daemon::Q::instance().types0();
00231 std::string tname = o.type().name();
00232 Typing::types0_t::const_iterator i = types0_.find(tname);
00233
00234 if (i == types0_.end()) {
00235
00236 return 0;
00237 }
00238
00239 Renderer const * p = i->second;
00240
00241 o1 = boost::any(p->ys(o));
00242 }
00243
00244 std::string s("");
00245 try {
00246 s = boost::any_cast<std::string>(o1);
00247 *v = nullT.xs(s);
00248 return v;
00249 } catch(const boost::bad_lexical_cast & e0) {
00250 return 0;
00251 } catch(const boost::bad_any_cast & e1) {
00252 std::cerr << "zs0: " << e1.what()
00253 << " : " << o.type().name() << std::endl;
00254 }
00255
00256 return 0;
00257 }
00258
00259 }
00260
00261 template<typename T> T * as(T *v, const boost::any & o)
00262 throw (std::domain_error) {
00263
00264 if (!v) return v;
00265
00266 try {
00268 if ( i0::zs0<T>(v, o, i0::dummy<0>(0)) )
00269 return v;
00270
00272 if ( i0::zs0<T>(v, o, i0::dummy<2>(2)) )
00273 return v;
00274
00275 } catch(std::exception & e0) {
00276 throw std::domain_error(e0.what());
00277 }
00278
00279 return 0;
00280 };
00281
00283 template<typename T> bool is(const boost::any & o)
00284 throw (std::domain_error) {
00285 static null0<T> nullT;
00286 return (nullT == o);
00287 }
00288
00290 template <>
00291 const char ** as<const char *>(const char **v, const boost::any & operand);
00292
00297 std::string as(const boost::any &o);
00298
00301
00302 }}
00303
00304 namespace eepgwde { namespace detail {
00305
00314
00321 template<typename T>
00322 int count(const std::list<boost::any> * values) {
00323 static null0<T> nullT = null0<T>();
00324 return std::count_if(values->begin(), values->end(),
00325 (boost::bind(&null0<T>::operator==,nullT,_1)));
00326 }
00327
00329
00330 }}
00331
00332 namespace eepgwde { namespace detail {
00333
00336
00344 template<typename T>
00345 T renderer(const boost::any & o, const T & null_, int fatal)
00346 throw (const boost::bad_any_cast &) {
00347 T t;
00348 if (as<T>(&t, o)) {
00349 return t;
00350 }
00351 if (fatal) {
00352 int i = boost::any_cast<int>(boost::any());
00353 }
00354 return null_;
00355 }
00356
00370
00371 template<typename T>
00372 std::vector<T> * render(std::vector<T> *r,
00373 const std::list<boost::any> *l, int & fails,
00374 const T null_ = (eepgwde::detail::null0<T>())() )
00375 throw (const boost::bad_any_cast &) {
00376 fails = l->size();
00377
00378 if (! (l && r && l->size()) ) return 0;
00379
00380 int fatal = 0;
00381
00382 fails = fails - count<T>(l);
00383 r->clear();
00384 r->resize(l->size(), null_ );
00385 transform(l->begin(), l->end(),
00386 r->begin(),
00387 (boost::bind(&eepgwde::detail::renderer<T>,_1,null_,fatal)));
00388 return r;
00389 }
00390
00401
00402 template<typename T> void
00403 renderer(boost::any & o, const boost::any & null_,
00404 int is_overwrite, int fatal)
00405 throw (const boost::bad_any_cast &) {
00406 try {
00407 o = boost::any(renderer<T>(o, (null0<T>())(), 1));
00408 } catch (const boost::bad_any_cast &e) {
00409 if (fatal) throw e;
00410 if (is_overwrite) o = null_;
00411 }
00412 }
00413
00434
00435 template<typename T>
00436 std::list<boost::any> * render(std::list<boost::any> *l,
00437 int & fails,
00438 const boost::any
00439 null_ = (eepgwde::detail::null0<boost::any>())() )
00440 throw (const boost::bad_any_cast &) {
00441 fails = l->size();
00442 if (!(l && l->size())) return 0;
00443 fails = fails - count<T>(l);
00444 int fatal = 0;
00445 int is_overwrite = null_.type() != (eepgwde::detail::null0<boost::any>())().type();
00446 for_each(l->begin(), l->end(),
00447 (boost::bind(&eepgwde::detail::renderer<T>,_1,null_,is_overwrite,fatal)));
00448 return l;
00449 }
00450
00453
00454 }}
00455
00456 #endif