/home/andreas/src/svn/mapnik/include/mapnik/value.hpp

Go to the documentation of this file.
00001 /*****************************************************************************
00002  * 
00003  * This file is part of Mapnik (c++ mapping toolkit)
00004  *
00005  * Copyright (C) 2006 Artem Pavlenko
00006  *
00007  * This library is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2.1 of the License, or (at your option) any later version.
00011  *
00012  * This library is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with this library; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00020  *
00021  *****************************************************************************/
00022 //$Id$
00023 
00024 #ifndef VALUE_HPP
00025 #define VALUE_HPP
00026 
00027 // stl
00028 #include <iostream>
00029 #include <string>
00030 #include <sstream>
00031 #include <iomanip>
00032 
00033 // boost
00034 #include <boost/variant.hpp>
00035 // mapnik
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             // specializations 
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             // specializations 
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

Generated on Thu Jul 19 17:59:27 2007 for Mapnik by  doxygen 1.4.7