00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef VALUE_HPP
00025 #define VALUE_HPP
00026
00027
00028 #include <iostream>
00029 #include <string>
00030 #include <sstream>
00031 #include <iomanip>
00032
00033
00034 #include <boost/variant.hpp>
00035
00036 #include <mapnik/unicode.hpp>
00037
00038 namespace mapnik {
00039
00040 typedef boost::variant<int,double,std::wstring> value_base;
00041
00042 namespace impl {
00043 struct equals
00044 : public boost::static_visitor<bool>
00045 {
00046 template <typename T, typename U>
00047 bool operator() (const T &, const U & ) const
00048 {
00049 return false;
00050 }
00051
00052 template <typename T>
00053 bool operator() (T lhs, T rhs) const
00054 {
00055 return lhs == rhs;
00056 }
00057
00058 bool operator() (int lhs, double rhs) const
00059 {
00060 return lhs == rhs;
00061 }
00062
00063 bool operator() (double lhs, int rhs) const
00064 {
00065 return lhs == rhs;
00066 }
00067
00068 bool operator() (std::wstring const& lhs,
00069 std::wstring const& rhs) const
00070 {
00071 return lhs == rhs;
00072 }
00073 };
00074
00075 struct greater_than
00076 : public boost::static_visitor<bool>
00077 {
00078 template <typename T, typename U>
00079 bool operator()( const T &, const U & ) const
00080 {
00081 return false;
00082 }
00083
00084 template <typename T>
00085 bool operator()( T lhs, T rhs ) const
00086 {
00087 return lhs > rhs;
00088 }
00089
00090 bool operator() (int lhs, double rhs) const
00091 {
00092 return lhs > rhs;
00093 }
00094
00095 bool operator() (double lhs, int rhs) const
00096 {
00097 return lhs > rhs;
00098 }
00099
00100 bool operator() (std::wstring const& lhs, std::wstring const& rhs) const
00101 {
00102 return lhs > rhs;
00103 }
00104 };
00105
00106 struct greater_or_equal
00107 : public boost::static_visitor<bool>
00108 {
00109 template <typename T, typename U>
00110 bool operator()( const T &, const U & ) const
00111 {
00112 return false;
00113 }
00114
00115 template <typename T>
00116 bool operator() (T lhs, T rhs) const
00117 {
00118 return lhs >= rhs;
00119 }
00120
00121 bool operator() (int lhs, double rhs) const
00122 {
00123 return lhs >= rhs;
00124 }
00125
00126 bool operator() (double lhs, int rhs) const
00127 {
00128 return lhs >= rhs;
00129 }
00130
00131 bool operator() (std::wstring const& lhs, std::wstring const& rhs ) const
00132 {
00133 return lhs >= rhs;
00134 }
00135 };
00136
00137 struct less_than
00138 : public boost::static_visitor<bool>
00139 {
00140 template <typename T, typename U>
00141 bool operator()( const T &, const U & ) const
00142 {
00143 return false;
00144 }
00145
00146 template <typename T>
00147 bool operator()( T lhs,T rhs) const
00148 {
00149 return lhs < rhs;
00150 }
00151
00152 bool operator() (int lhs, double rhs) const
00153 {
00154 return lhs < rhs;
00155 }
00156
00157 bool operator() (double lhs, int rhs) const
00158 {
00159 return lhs < rhs;
00160 }
00161
00162 bool operator()( std::wstring const& lhs,
00163 std::wstring const& rhs ) const
00164 {
00165 return lhs < rhs;
00166 }
00167 };
00168
00169 struct less_or_equal
00170 : public boost::static_visitor<bool>
00171 {
00172 template <typename T, typename U>
00173 bool operator()( const T &, const U & ) const
00174 {
00175 return false;
00176 }
00177
00178 template <typename T>
00179 bool operator()(T lhs, T rhs ) const
00180 {
00181 return lhs <= rhs;
00182 }
00183
00184 bool operator() (int lhs, double rhs) const
00185 {
00186 return lhs <= rhs;
00187 }
00188
00189 bool operator() (double lhs, int rhs) const
00190 {
00191 return lhs <= rhs;
00192 }
00193
00194 template <typename T>
00195 bool operator()( std::wstring const& lhs,
00196 std::wstring const& rhs ) const
00197 {
00198 return lhs <= rhs;
00199 }
00200 };
00201
00202 template <typename V>
00203 struct add : public boost::static_visitor<V>
00204 {
00205 typedef V value_type;
00206 template <typename T1, typename T2>
00207 value_type operator() (T1 const& lhs, T2 const&) const
00208 {
00209 return lhs;
00210 }
00211 template <typename T>
00212 value_type operator() (T lhs, T rhs) const
00213 {
00214 return lhs + rhs ;
00215 }
00216
00217 value_type operator() (std::wstring const& lhs ,
00218 std::wstring const& rhs ) const
00219 {
00220 return lhs + rhs;
00221 }
00222
00223 value_type operator() (double lhs, int rhs) const
00224 {
00225 return lhs + rhs;
00226 }
00227
00228 value_type operator() (int lhs, double rhs) const
00229 {
00230 return lhs + rhs;
00231 }
00232 };
00233 template <typename V>
00234 struct sub : public boost::static_visitor<V>
00235 {
00236 typedef V value_type;
00237 template <typename T1, typename T2>
00238 value_type operator() (T1 const& lhs, T2 const&) const
00239 {
00240 return lhs;
00241 }
00242
00243 template <typename T>
00244 value_type operator() (T lhs, T rhs) const
00245 {
00246 return lhs - rhs ;
00247 }
00248
00249 value_type operator() (std::wstring const& lhs,
00250 std::wstring const& ) const
00251 {
00252 return lhs;
00253 }
00254
00255 value_type operator() (double lhs, int rhs) const
00256 {
00257 return lhs - rhs;
00258 }
00259
00260 value_type operator() (int lhs, double rhs) const
00261 {
00262 return lhs - rhs;
00263 }
00264 };
00265
00266 template <typename V>
00267 struct mult : public boost::static_visitor<V>
00268 {
00269 typedef V value_type;
00270 template <typename T1, typename T2>
00271 value_type operator() (T1 const& lhs , T2 const& ) const
00272 {
00273 return lhs;
00274 }
00275 template <typename T>
00276 value_type operator() (T lhs, T rhs) const
00277 {
00278 return lhs * rhs;
00279 }
00280
00281 value_type operator() (std::wstring const& lhs,
00282 std::wstring const& ) const
00283 {
00284 return lhs;
00285 }
00286
00287 value_type operator() (double lhs, int rhs) const
00288 {
00289 return lhs * rhs;
00290 }
00291
00292 value_type operator() (int lhs, double rhs) const
00293 {
00294 return lhs * rhs;
00295 }
00296 };
00297
00298 template <typename V>
00299 struct div: public boost::static_visitor<V>
00300 {
00301 typedef V value_type;
00302 template <typename T1, typename T2>
00303 value_type operator() (T1 const& lhs, T2 const&) const
00304 {
00305 return lhs;
00306 }
00307
00308 template <typename T>
00309 value_type operator() (T lhs, T rhs) const
00310 {
00311 return lhs / rhs;
00312 }
00313
00314 value_type operator() (std::wstring const& lhs,
00315 std::wstring const&) const
00316 {
00317 return lhs;
00318 }
00319
00320 value_type operator() (double lhs, int rhs) const
00321 {
00322 return lhs / rhs;
00323 }
00324
00325 value_type operator() (int lhs, double rhs) const
00326 {
00327 return lhs / rhs;
00328 }
00329 };
00330
00331 struct to_string : public boost::static_visitor<std::string>
00332 {
00333
00334 template <typename T>
00335 std::string operator() (T val) const
00336 {
00337 std::stringstream ss;
00338 ss << val;
00339 return ss.str();
00340 }
00341
00342 std::string operator() (std::wstring const& val) const
00343 {
00344 std::stringstream ss;
00345 std::wstring::const_iterator pos = val.begin();
00346 ss << std::hex ;
00347 for (;pos!=val.end();++pos)
00348 {
00349 wchar_t c = *pos;
00350 if (c < 0x80)
00351 {
00352 ss << char(c);
00353 }
00354 else
00355 {
00356 ss << "\\x";
00357 unsigned c0 = (c >> 8) & 0xff;
00358 if (c0) ss << c0;
00359 ss << (c & 0xff);
00360 }
00361 }
00362 return ss.str();
00363 }
00364
00365 std::string operator() (double val) const
00366 {
00367 std::stringstream ss;
00368 ss << std::setprecision(16) << val;
00369 return ss.str();
00370 }
00371 };
00372
00373 struct to_unicode : public boost::static_visitor<std::wstring>
00374 {
00375
00376 template <typename T>
00377 std::wstring operator() (T val) const
00378 {
00379 std::basic_ostringstream<wchar_t> out;
00380 out << val;
00381 return out.str();
00382 }
00383
00384
00385 std::wstring const& operator() (std::wstring const& val) const
00386 {
00387 return val;
00388 }
00389
00390 std::wstring operator() (double val) const
00391 {
00392 std::basic_ostringstream<wchar_t> out;
00393 out << std::setprecision(16) << val;
00394 return out.str();
00395 }
00396 };
00397
00398 struct to_expression_string : public boost::static_visitor<std::string>
00399 {
00400 std::string operator() (std::wstring const& val) const
00401 {
00402 std::stringstream ss;
00403 std::wstring::const_iterator pos = val.begin();
00404 ss << std::hex ;
00405 for (;pos!=val.end();++pos)
00406 {
00407 wchar_t c = *pos;
00408 if (c < 0x80)
00409 {
00410 ss << char(c);
00411 }
00412 else
00413 {
00414 ss << "\\x";
00415 unsigned c0 = (c >> 8) & 0xff;
00416 if (c0) ss << c0;
00417 ss << (c & 0xff);
00418 }
00419 }
00420 return "\'" + ss.str() + "\'";
00421 }
00422
00423 template <typename T>
00424 std::string operator() (T val) const
00425 {
00426 std::stringstream ss;
00427 ss << val;
00428 return ss.str();
00429 }
00430
00431 std::string operator() (double val) const
00432 {
00433 std::stringstream ss;
00434 ss << std::setprecision(16) << val;
00435 return ss.str();
00436 }
00437 };
00438 }
00439
00440 class value
00441 {
00442 value_base base_;
00443 friend const value operator+(value const&,value const&);
00444 friend const value operator-(value const&,value const&);
00445 friend const value operator*(value const&,value const&);
00446 friend const value operator/(value const&,value const&);
00447
00448 public:
00449 value ()
00450 : base_(0) {}
00451
00452 template <typename T> value(T _val_)
00453 : base_(_val_) {}
00454
00455 bool operator==(value const& other) const
00456 {
00457 return boost::apply_visitor(impl::equals(),base_,other.base_);
00458 }
00459
00460 bool operator!=(value const& other) const
00461 {
00462 return !(boost::apply_visitor(impl::equals(),base_,other.base_));
00463 }
00464
00465 bool operator>(value const& other) const
00466 {
00467 return boost::apply_visitor(impl::greater_than(),base_,other.base_);
00468 }
00469
00470 bool operator>=(value const& other) const
00471 {
00472 return boost::apply_visitor(impl::greater_or_equal(),base_,other.base_);
00473 }
00474
00475 bool operator<(value const& other) const
00476 {
00477 return boost::apply_visitor(impl::less_than(),base_,other.base_);
00478 }
00479
00480 bool operator<=(value const& other) const
00481 {
00482 return boost::apply_visitor(impl::less_or_equal(),base_,other.base_);
00483 }
00484
00485 value_base const& base() const
00486 {
00487 return base_;
00488 }
00489
00490 std::string to_expression_string() const
00491 {
00492 return boost::apply_visitor(impl::to_expression_string(),base_);
00493 }
00494
00495 std::string to_string() const
00496 {
00497 return boost::apply_visitor(impl::to_string(),base_);
00498 }
00499
00500 std::wstring to_unicode() const
00501 {
00502 return boost::apply_visitor(impl::to_unicode(),base_);
00503 }
00504 };
00505
00506 inline const value operator+(value const& p1,value const& p2)
00507 {
00508
00509 return value(boost::apply_visitor(impl::add<value>(),p1.base_, p2.base_));
00510 }
00511
00512 inline const value operator-(value const& p1,value const& p2)
00513 {
00514
00515 return value(boost::apply_visitor(impl::sub<value>(),p1.base_, p2.base_));
00516 }
00517
00518 inline const value operator*(value const& p1,value const& p2)
00519 {
00520
00521 return value(boost::apply_visitor(impl::mult<value>(),p1.base_, p2.base_));
00522 }
00523
00524 inline const value operator/(value const& p1,value const& p2)
00525 {
00526
00527 return value(boost::apply_visitor(impl::div<value>(),p1.base_, p2.base_));
00528 }
00529
00530 template <typename charT, typename traits>
00531 inline std::basic_ostream<charT,traits>&
00532 operator << (std::basic_ostream<charT,traits>& out,
00533 value const& v)
00534 {
00535 out << v.to_string();
00536 return out;
00537 }
00538 }
00539
00540 #endif //VALUE_HPP