00001
00011 #include "eleve/config.hpp"
00012
00013 #include <limits>
00014 #include <string>
00015 #include <locale>
00016 #include <locale.h>
00017
00018 #include <boost/array.hpp>
00019 #include <boost/lexical_cast.hpp>
00020
00021 #include "runtime2.hpp"
00022 #include "typing0.hpp"
00023
00024 #include "typing3.hpp"
00025
00026 #include "typing1.hpp"
00027
00028 #include <ql/utilities/tracing.hpp>
00029
00030 #include <iostream>
00031
00032 namespace eepgwde { namespace detail {
00033
00034 static std::vector<Renderer const *> null_types;
00035
00036 typedef struct type_t {
00037 std::string name0;
00038 Renderer * p;
00039 } type_t;
00040
00041 #if 0
00042
00046
00047 static Renderer * s_0(new null0<std::string>());
00048
00049 static Renderer * ch_0(new null0<char>());
00050 static Renderer * uch_0(new null0<unsigned char>());
00051 static Renderer * sh_0(new null0<short>());
00052 static Renderer * ush_0(new null0<unsigned short>());
00053
00054 static Renderer * usdt_0(new null0<usdate>());
00055 static Renderer * eudt_0(new null0<eudate>());
00056 static Renderer * psxdt_0(new null0<posixdate>());
00057
00058 static Renderer * i_0(new null0<int>());
00059 static Renderer * ul_0(new null0<unsigned long>());
00060 static Renderer * l_0(new null0<long>());
00061 static Renderer * ll_0(new null0<long long>());
00062 static Renderer * ull_0(new null0<unsigned long long>());
00063
00064 static Renderer * d_0(new null0<double>());
00065 static Renderer * ld_0(new null0<long double>());
00066 static Renderer * f_0(new null0<float>());
00067
00068 static Renderer * rate_0(new null0<rate>());
00069 static Renderer * bps_0(new null0<bps>());
00070
00071 type_t types_0[] = {
00072 { psxdt_0->name(), psxdt_0 },
00073 { usdt_0->name(), usdt_0 },
00074 { eudt_0->name(), eudt_0 },
00075 { s_0->name(), s_0 },
00076 { ch_0->name(), ch_0 },
00077 { uch_0->name(), uch_0 },
00078 { sh_0->name(), sh_0 },
00079 { ush_0->name(), ush_0 },
00080 { i_0->name(), i_0 },
00081 { ul_0->name(), ul_0 },
00082 { l_0->name(), l_0 },
00083 { ll_0->name(), ll_0 },
00084 { ull_0->name(), ull_0 },
00085 { f_0->name(), f_0 },
00086 { ld_0->name(), ld_0 },
00087 { d_0->name(), d_0 },
00088 { rate_0->name(), rate_0 },
00089 { bps_0->name(), bps_0 }
00090 };
00091 #else
00092 type_t types_0[] = {};
00093 #endif
00094
00095 static std::vector<type_t>
00096 types_1(types_0,
00097 types_0 + (sizeof(types_0)/sizeof(types_0[0])));
00098
00099 class Typing::Impl {
00100 public:
00101 Typing::mappings_t mappings;
00102 Typing::types0_t types0;
00103
00104 Impl() throw() {
00105 for(std::vector<type_t>::iterator i=types_1.begin();
00106 i!=types_1.end(); ++i) {
00107 types0[i->name0] = i->p;
00108 }
00109 }
00110
00111 ~Impl() throw() {}
00112 Typing *owner;
00113 };
00114
00116 Typing::Typing() throw(std::exception) :
00117 impl(new Typing::Impl) {
00118 impl->owner = this;
00119 }
00120
00121 Typing::~Typing() throw(std::exception) {}
00122
00123 Typing::types0_t & Typing::types0() {
00124 return impl->types0;
00125 }
00126
00132 Renderer const * Typing::add(Renderer *p) {
00133 std::string s = p->name();
00134 types0_t::const_iterator i;
00135 if ( (i = impl->types0.find(s)) != impl->types0.end())
00136 return i->second;
00137
00138 impl->types0[s] = p;
00139 return p;
00140 }
00141
00142 Typing::mappings_t & Typing::mappings() {
00143 return impl->mappings;
00144 }
00145
00146 void Typing::mappings(const Typing::mapping_t p[]) {
00147 for (int i=0; p[i].old_.size() > 0; i++) {
00148 impl->mappings[ p[i].old_ ] = p[i].new_;
00149 }
00150 }
00151
00152 const locale Typing::posix = locale(locale::classic(), locale("POSIX"), locale::time);
00153 const locale Typing::us = locale(locale::classic(), locale("en_US"), locale::time);
00154 const locale Typing::uk = locale(locale::classic(), locale("en_GB"), locale::time);
00155
00156 typedef boost::array<const std::locale, 3> locales_t;
00157 static locales_t locales = { Typing::posix, Typing::us, Typing::uk };
00158
00165 const locale * dating(const std::locale & ours) {
00166 locale ours0 = locale(locale::classic(), ours, locale::time);
00167
00168 locales_t::iterator theirs;
00169 if ( (theirs = find(locales.begin(), locales.end(), ours0) ) != locales.end() )
00170 return & *theirs;
00171 return 0;
00172 }
00174
00176 void Typing::set(const std::locale & ours) throw (std::domain_error) {
00177 locale loc0 = locale();
00178 locale loc2 = locale(loc0, ours, locale::time);
00179 locale::global(loc2);
00180 }
00181
00187 const std::locale & Typing::get() throw (std::domain_error) {
00188 locale ours = locale();
00189 const locale * p;
00190 if ( (p = dating(ours) ))
00191 return *p;
00192 throw std::domain_error("unknown locale");
00193 }
00194
00198 boost::gregorian::date locale_trier(const std::string & sdt) throw (std::domain_error) {
00199
00200 static boost::gregorian::date bdt(boost::gregorian::not_a_date_time);
00201
00202 boost::gregorian::date psxdt(bdt);
00203 try {
00204 psxdt = boost::gregorian::from_simple_string(sdt);
00205 } catch (...) {
00206 }
00207
00208 boost::gregorian::date usdt(bdt);
00209 try {
00210 usdt = boost::gregorian::from_us_string(sdt);
00211 } catch (...) {
00212 }
00213
00214 boost::gregorian::date ukdt(bdt);
00215 try {
00216 ukdt = boost::gregorian::from_uk_string(sdt);
00217 } catch (...) {
00218 }
00219
00220 const locale * known = dating(locale());
00221
00222 if (known && *known == Typing::posix) {
00223 return psxdt;
00224 }
00225
00226 if (known && *known == Typing::uk) {
00227 return ukdt;
00228 }
00229
00230 if (known && *known == Typing::us) {
00231 return usdt;
00232 }
00233
00234
00235 if (psxdt != bdt && usdt == bdt && ukdt == bdt) return psxdt;
00236 if (psxdt == bdt && usdt != bdt && ukdt == bdt) return usdt;
00237 if (psxdt == bdt && usdt == bdt && ukdt != bdt) return ukdt;
00238
00239 throw std::domain_error("unknown locale");
00240
00241 return bdt;
00242 }
00243
00245 template <>
00246 const char ** as<const char *>(const char **v, const boost::any & operand)
00247 {
00248 try {
00249 *v = any_cast<const char *>(operand);
00250 return v;
00251 } catch(const boost::bad_any_cast &) {
00252 ;
00253 }
00254 return 0;
00255 }
00256
00259
00262 std::string as(const boost::any & operand) {
00263 std::string result("");
00264
00265 if (operand.empty()) return result;
00266
00267 if (as(&result, operand))
00268 return result;
00269
00270 int iresult;
00271 if (as(&iresult, operand))
00272 return lexical_cast<std::string>(iresult);
00273
00274 {
00275 rate dresult;
00276 if (as(&dresult, operand)) {
00277 return lexical_cast<std::string>(dresult);
00278 }
00279 }
00280
00281 {
00282 bps dresult;
00283 if (as(&dresult, operand))
00284 return lexical_cast<std::string>(dresult);
00285 }
00286
00287 {
00288 double dresult;
00289 if (as(&dresult, operand))
00290 return lexical_cast<std::string>(dresult);
00291 }
00292
00293 {
00294 std::string dresult;
00295 if (as(&dresult, operand))
00296 return lexical_cast<std::string>(dresult);
00297 }
00298
00299 {
00300 posixdate dtresult;
00301 if (as(&dtresult, operand))
00302 return lexical_cast<std::string>(dtresult);
00303 }
00304
00305 {
00306 usdate dtresult;
00307 if (as(&dtresult, operand))
00308 return lexical_cast<std::string>(dtresult);
00309 }
00310
00311 {
00312 eudate dtresult;
00313 if (as(&dtresult, operand))
00314 return lexical_cast<std::string>(dtresult);
00315 }
00316
00317 return result;
00318 }
00319
00321 std::string Typing::as(const boost::any & operand) const
00322 throw (std::exception) {
00323 return eepgwde::detail::as(operand);
00324 }
00325
00326 std::ostream& operator<< (std::ostream& o, const usdate & t) {
00327 std::string s = boost::gregorian::to_us_string(t);
00328 return o << s;
00329 }
00330
00331 std::istream& operator>> (std::istream& i, usdate & t) {
00332 std::string s;
00333 i >> s;
00334 t = boost::gregorian::from_us_string(s);
00335 return i;
00336 }
00337
00338 std::ostream& operator<< (std::ostream& o, const eudate & t) {
00339 std::string s = boost::gregorian::to_uk_string(t);
00340 return o << s;
00341 }
00342
00343 std::istream& operator>> (std::istream& i, eudate & t) {
00344 std::string s;
00345 i >> s;
00346 t = boost::gregorian::from_uk_string(s);
00347 return i;
00348 }
00349
00350 std::ostream& operator<< (std::ostream& o, const posixdate & t) {
00351 std::string s = boost::gregorian::to_simple_string(t);
00352 return o << s;
00353 }
00354
00355 std::istream& operator>> (std::istream& i, posixdate & t) {
00356 std::string s;
00357 i >> s;
00358 try {
00359 t = boost::gregorian::from_simple_string(s);
00360 } catch (...) {
00361 t = boost::gregorian::from_undelimited_string(s);
00362 }
00363 return i;
00364 }
00365
00366 }}
00367