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 <mapnik/unicode.hpp>
00029 #include <mapnik/config_error.hpp>
00030
00031 #include <boost/variant.hpp>
00032
00033 #include <iostream>
00034 #include <string>
00035 #include <sstream>
00036 #include <iomanip>
00037
00038 #include <unicode/unistr.h>
00039
00040 namespace mapnik {
00041
00042 struct value_null
00043 {
00044 };
00045
00046 typedef boost::variant<value_null,bool,int,double,UnicodeString> value_base;
00047
00048 namespace impl {
00049 struct equals
00050 : public boost::static_visitor<bool>
00051 {
00052 template <typename T, typename U>
00053 bool operator() (const T &, const U &) const
00054 {
00055 return false;
00056 }
00057
00058 template <typename T>
00059 bool operator() (T lhs, T rhs) const
00060 {
00061 return lhs == rhs;
00062 }
00063
00064 bool operator() (int lhs, double rhs) const
00065 {
00066 return lhs == rhs;
00067 }
00068
00069 bool operator() (double lhs, int rhs) const
00070 {
00071 return lhs == rhs;
00072 }
00073
00074 bool operator() (UnicodeString const& lhs,
00075 UnicodeString const& rhs) const
00076 {
00077 return lhs == rhs;
00078 }
00079
00080 bool operator() (value_null, value_null) const
00081 {
00082 return false;
00083 }
00084 };
00085
00086 struct not_equals
00087 : public boost::static_visitor<bool>
00088 {
00089 template <typename T, typename U>
00090 bool operator() (const T &, const U &) const
00091 {
00092 return true;
00093 }
00094
00095 template <typename T>
00096 bool operator() (T lhs, T rhs) const
00097 {
00098 return lhs != rhs;
00099 }
00100
00101 bool operator() (int lhs, double rhs) const
00102 {
00103 return lhs != rhs;
00104 }
00105
00106 bool operator() (double lhs, int rhs) const
00107 {
00108 return lhs != rhs;
00109 }
00110
00111 bool operator() (UnicodeString const& lhs,
00112 UnicodeString const& rhs) const
00113 {
00114 return lhs != rhs;
00115 }
00116
00117 bool operator() (value_null, value_null) const
00118 {
00119 return false;
00120 }
00121
00122 template <typename T>
00123 bool operator() (value_null, const T &) const
00124 {
00125 return false;
00126 }
00127
00128 template <typename T>
00129 bool operator() (const T &, value_null) const
00130 {
00131 return false;
00132 }
00133 };
00134
00135 struct greater_than
00136 : public boost::static_visitor<bool>
00137 {
00138 template <typename T, typename U>
00139 bool operator()(const T &, const U &) const
00140 {
00141 return false;
00142 }
00143
00144 template <typename T>
00145 bool operator()(T lhs, T rhs) const
00146 {
00147 return lhs > rhs;
00148 }
00149
00150 bool operator() (int lhs, double rhs) const
00151 {
00152 return lhs > rhs;
00153 }
00154
00155 bool operator() (double lhs, int rhs) const
00156 {
00157 return lhs > rhs;
00158 }
00159
00160 bool operator() (UnicodeString const& lhs, UnicodeString const& rhs) const
00161 {
00162 return lhs > rhs;
00163 }
00164
00165 bool operator() (value_null, value_null) const
00166 {
00167 return false;
00168 }
00169 };
00170
00171 struct greater_or_equal
00172 : public boost::static_visitor<bool>
00173 {
00174 template <typename T, typename U>
00175 bool operator()(const T &, const U &) const
00176 {
00177 return false;
00178 }
00179
00180 template <typename T>
00181 bool operator() (T lhs, T rhs) const
00182 {
00183 return lhs >= rhs;
00184 }
00185
00186 bool operator() (int lhs, double rhs) const
00187 {
00188 return lhs >= rhs;
00189 }
00190
00191 bool operator() (double lhs, int rhs) const
00192 {
00193 return lhs >= rhs;
00194 }
00195
00196 bool operator() (UnicodeString const& lhs, UnicodeString const& rhs) const
00197 {
00198 return lhs >= rhs;
00199 }
00200
00201 bool operator() (value_null, value_null) const
00202 {
00203 return false;
00204 }
00205 };
00206
00207 struct less_than
00208 : public boost::static_visitor<bool>
00209 {
00210 template <typename T, typename U>
00211 bool operator()(const T &, const U &) const
00212 {
00213 return false;
00214 }
00215
00216 template <typename T>
00217 bool operator()(T lhs, T rhs) const
00218 {
00219 return lhs < rhs;
00220 }
00221
00222 bool operator() (int lhs, double rhs) const
00223 {
00224 return lhs < rhs;
00225 }
00226
00227 bool operator() (double lhs, int rhs) const
00228 {
00229 return lhs < rhs;
00230 }
00231
00232 bool operator()(UnicodeString const& lhs,
00233 UnicodeString const& rhs ) const
00234 {
00235 return lhs < rhs;
00236 }
00237
00238 bool operator() (value_null, value_null) const
00239 {
00240 return false;
00241 }
00242 };
00243
00244 struct less_or_equal
00245 : public boost::static_visitor<bool>
00246 {
00247 template <typename T, typename U>
00248 bool operator()(const T &, const U &) const
00249 {
00250 return false;
00251 }
00252
00253 template <typename T>
00254 bool operator()(T lhs, T rhs) const
00255 {
00256 return lhs <= rhs;
00257 }
00258
00259 bool operator() (int lhs, double rhs) const
00260 {
00261 return lhs <= rhs;
00262 }
00263
00264 bool operator() (double lhs, int rhs) const
00265 {
00266 return lhs <= rhs;
00267 }
00268
00269 template <typename T>
00270 bool operator()(UnicodeString const& lhs,
00271 UnicodeString const& rhs ) const
00272 {
00273 return lhs <= rhs;
00274 }
00275
00276 bool operator() (value_null, value_null) const
00277 {
00278 return false;
00279 }
00280 };
00281
00282 template <typename V>
00283 struct add : public boost::static_visitor<V>
00284 {
00285 typedef V value_type;
00286 template <typename T1, typename T2>
00287 value_type operator() (T1 const& lhs, T2 const&) const
00288 {
00289 return lhs;
00290 }
00291 template <typename T>
00292 value_type operator() (T lhs, T rhs) const
00293 {
00294 return lhs + rhs ;
00295 }
00296
00297 value_type operator() (UnicodeString const& lhs ,
00298 UnicodeString const& rhs ) const
00299 {
00300 return lhs + rhs;
00301 }
00302
00303 value_type operator() (double lhs, int rhs) const
00304 {
00305 return lhs + rhs;
00306 }
00307
00308 value_type operator() (int lhs, double rhs) const
00309 {
00310 return lhs + rhs;
00311 }
00312 };
00313 template <typename V>
00314 struct sub : public boost::static_visitor<V>
00315 {
00316 typedef V value_type;
00317 template <typename T1, typename T2>
00318 value_type operator() (T1 const& lhs, T2 const&) const
00319 {
00320 return lhs;
00321 }
00322
00323 template <typename T>
00324 value_type operator() (T lhs, T rhs) const
00325 {
00326 return lhs - rhs ;
00327 }
00328
00329 value_type operator() (UnicodeString const& lhs,
00330 UnicodeString const& ) const
00331 {
00332 return lhs;
00333 }
00334
00335 value_type operator() (double lhs, int rhs) const
00336 {
00337 return lhs - rhs;
00338 }
00339
00340 value_type operator() (int lhs, double rhs) const
00341 {
00342 return lhs - rhs;
00343 }
00344 };
00345
00346 template <typename V>
00347 struct mult : public boost::static_visitor<V>
00348 {
00349 typedef V value_type;
00350 template <typename T1, typename T2>
00351 value_type operator() (T1 const& lhs , T2 const& ) const
00352 {
00353 return lhs;
00354 }
00355 template <typename T>
00356 value_type operator() (T lhs, T rhs) const
00357 {
00358 return lhs * rhs;
00359 }
00360
00361 value_type operator() (UnicodeString const& lhs,
00362 UnicodeString const& ) const
00363 {
00364 return lhs;
00365 }
00366
00367 value_type operator() (double lhs, int rhs) const
00368 {
00369 return lhs * rhs;
00370 }
00371
00372 value_type operator() (int lhs, double rhs) const
00373 {
00374 return lhs * rhs;
00375 }
00376 };
00377
00378 template <typename V>
00379 struct div: public boost::static_visitor<V>
00380 {
00381 typedef V value_type;
00382 template <typename T1, typename T2>
00383 value_type operator() (T1 const& lhs, T2 const&) const
00384 {
00385 return lhs;
00386 }
00387
00388 template <typename T>
00389 value_type operator() (T lhs, T rhs) const
00390 {
00391 return lhs / rhs;
00392 }
00393
00394 value_type operator() (UnicodeString const& lhs,
00395 UnicodeString const&) const
00396 {
00397 return lhs;
00398 }
00399
00400 value_type operator() (double lhs, int rhs) const
00401 {
00402 return lhs / rhs;
00403 }
00404
00405 value_type operator() (int lhs, double rhs) const
00406 {
00407 return lhs / rhs;
00408 }
00409 };
00410
00411 struct to_bool : public boost::static_visitor<bool>
00412 {
00413
00414 template <typename T>
00415 bool operator() (T val) const
00416 {
00417 throw config_error("Boolean value expected");
00418 }
00419
00420 bool operator() (bool val) const
00421 {
00422 return val;
00423 }
00424 };
00425
00426 struct to_string : public boost::static_visitor<std::string>
00427 {
00428
00429 template <typename T>
00430 std::string operator() (T val) const
00431 {
00432 std::stringstream ss;
00433 ss << val;
00434 return ss.str();
00435 }
00436
00437 std::string operator() (UnicodeString const& val) const
00438 {
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458 return "TODO";
00459 }
00460
00461 std::string operator() (double val) const
00462 {
00463 std::stringstream ss;
00464 ss << std::setprecision(16) << val;
00465 return ss.str();
00466 }
00467
00468 std::string operator() (value_null const& val) const
00469 {
00470 return "";
00471 }
00472 };
00473
00474 struct to_unicode : public boost::static_visitor<UnicodeString>
00475 {
00476
00477 template <typename T>
00478 UnicodeString operator() (T val) const
00479 {
00480 std::basic_ostringstream<char> out;
00481 out << val;
00482 return UnicodeString(out.str().c_str());
00483 }
00484
00485
00486 UnicodeString const& operator() (UnicodeString const& val) const
00487 {
00488 return val;
00489 }
00490
00491 UnicodeString operator() (double val) const
00492 {
00493 std::basic_ostringstream<char> out;
00494 out << std::setprecision(16) << val;
00495 return UnicodeString(out.str().c_str());
00496 }
00497
00498 UnicodeString operator() (value_null const& val) const
00499 {
00500 return UnicodeString("");
00501 }
00502 };
00503
00504 struct to_expression_string : public boost::static_visitor<std::string>
00505 {
00506 std::string operator() (UnicodeString const& val) const
00507 {
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529 return "TODO";
00530 }
00531
00532 template <typename T>
00533 std::string operator() (T val) const
00534 {
00535 std::stringstream ss;
00536 ss << val;
00537 return ss.str();
00538 }
00539
00540 std::string operator() (double val) const
00541 {
00542 std::stringstream ss;
00543 ss << std::setprecision(16) << val;
00544 return ss.str();
00545 }
00546
00547 std::string operator() (value_null const& val) const
00548 {
00549 return "null";
00550 }
00551 };
00552 }
00553
00554 class value
00555 {
00556 value_base base_;
00557 friend const value operator+(value const&,value const&);
00558 friend const value operator-(value const&,value const&);
00559 friend const value operator*(value const&,value const&);
00560 friend const value operator/(value const&,value const&);
00561
00562 public:
00563 value ()
00564 : base_(value_null()) {}
00565
00566 template <typename T> value(T _val_)
00567 : base_(_val_) {}
00568
00569 bool operator==(value const& other) const
00570 {
00571 return boost::apply_visitor(impl::equals(),base_,other.base_);
00572 }
00573
00574 bool operator!=(value const& other) const
00575 {
00576 return boost::apply_visitor(impl::not_equals(),base_,other.base_);
00577 }
00578
00579 bool operator>(value const& other) const
00580 {
00581 return boost::apply_visitor(impl::greater_than(),base_,other.base_);
00582 }
00583
00584 bool operator>=(value const& other) const
00585 {
00586 return boost::apply_visitor(impl::greater_or_equal(),base_,other.base_);
00587 }
00588
00589 bool operator<(value const& other) const
00590 {
00591 return boost::apply_visitor(impl::less_than(),base_,other.base_);
00592 }
00593
00594 bool operator<=(value const& other) const
00595 {
00596 return boost::apply_visitor(impl::less_or_equal(),base_,other.base_);
00597 }
00598
00599 value_base const& base() const
00600 {
00601 return base_;
00602 }
00603
00604 bool to_bool() const
00605 {
00606 return boost::apply_visitor(impl::to_bool(),base_);
00607 }
00608
00609 std::string to_expression_string() const
00610 {
00611 return boost::apply_visitor(impl::to_expression_string(),base_);
00612 }
00613
00614 std::string to_string() const
00615 {
00616 return boost::apply_visitor(impl::to_string(),base_);
00617 }
00618
00619 UnicodeString to_unicode() const
00620 {
00621 return boost::apply_visitor(impl::to_unicode(),base_);
00622 }
00623 };
00624
00625 inline const value operator+(value const& p1,value const& p2)
00626 {
00627
00628 return value(boost::apply_visitor(impl::add<value>(),p1.base_, p2.base_));
00629 }
00630
00631 inline const value operator-(value const& p1,value const& p2)
00632 {
00633
00634 return value(boost::apply_visitor(impl::sub<value>(),p1.base_, p2.base_));
00635 }
00636
00637 inline const value operator*(value const& p1,value const& p2)
00638 {
00639
00640 return value(boost::apply_visitor(impl::mult<value>(),p1.base_, p2.base_));
00641 }
00642
00643 inline const value operator/(value const& p1,value const& p2)
00644 {
00645
00646 return value(boost::apply_visitor(impl::div<value>(),p1.base_, p2.base_));
00647 }
00648
00649 template <typename charT, typename traits>
00650 inline std::basic_ostream<charT,traits>&
00651 operator << (std::basic_ostream<charT,traits>& out,
00652 value const& v)
00653 {
00654 out << v.to_string();
00655 return out;
00656 }
00657 }
00658
00659 #endif //VALUE_HPP