/* This file is part of Mapnik (c++ mapping toolkit) * Copyright (C) 2005 Artem Pavlenko * * Mapnik is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ //$Id$ #ifndef VALUE_HPP #define VALUE_HPP #include #include #include using namespace boost; namespace mapnik { typedef variant value_base; namespace impl { struct equals : public boost::static_visitor { template bool operator() (const T &, const U & ) const { return false; } template bool operator() (T lhs, T rhs) const { return lhs == rhs; } bool operator() (int lhs, double rhs) const { return lhs == rhs; } bool operator() (double lhs, int rhs) const { return lhs == rhs; } bool operator() (std::string const& lhs, std::string const& rhs) const { return lhs == rhs; } }; struct greater_than : public boost::static_visitor { template bool operator()( const T &, const U & ) const { return false; } template bool operator()( T lhs, T rhs ) const { return lhs > rhs; } bool operator() (int lhs, double rhs) const { return lhs > rhs; } bool operator() (double lhs, int rhs) const { return lhs > rhs; } bool operator() (std::string const& lhs, std::string const& rhs) const { return lhs > rhs; } }; struct greater_or_equal : public boost::static_visitor { template bool operator()( const T &, const U & ) const { return false; } template bool operator() (T lhs, T rhs) const { return lhs >= rhs; } bool operator() (int lhs, double rhs) const { return lhs >= rhs; } bool operator() (double lhs, int rhs) const { return lhs >= rhs; } bool operator() (std::string const& lhs, std::string const& rhs ) const { return lhs >= rhs; } }; struct less_than : public boost::static_visitor { template bool operator()( const T &, const U & ) const { return false; } template bool operator()( T lhs,T rhs) const { return lhs < rhs; } bool operator() (int lhs, double rhs) const { return lhs < rhs; } bool operator() (double lhs, int rhs) const { return lhs < rhs; } bool operator()( std::string const& lhs, std::string const& rhs ) const { return lhs < rhs; } }; struct less_or_equal : public boost::static_visitor { template bool operator()( const T &, const U & ) const { return false; } template bool operator()(T lhs, T rhs ) const { return lhs <= rhs; } bool operator() (int lhs, double rhs) const { return lhs <= rhs; } bool operator() (double lhs, int rhs) const { return lhs <= rhs; } template bool operator()( std::string const& lhs, std::string const& rhs ) const { return lhs <= rhs; } }; template struct add : public boost::static_visitor { typedef V value_type; template value_type operator() (T1 const& lhs, T2 const&) const { return lhs; } template value_type operator() (T lhs, T rhs) const { return lhs + rhs ; } value_type operator() (std::string const& lhs,std::string const& rhs ) const { return lhs + rhs; } value_type operator() (double lhs, int rhs) const { return lhs + rhs; } value_type operator() (int lhs, double rhs) const { return lhs + rhs; } }; template struct sub : public boost::static_visitor { typedef V value_type; template value_type operator() (T1 const& lhs, T2 const&) const { return lhs; } template value_type operator() (T lhs, T rhs) const { return lhs - rhs ; } value_type operator() (std::string const& lhs,std::string const& ) const { return lhs; } value_type operator() (double lhs, int rhs) const { return lhs - rhs; } value_type operator() (int lhs, double rhs) const { return lhs - rhs; } }; template struct mult : public boost::static_visitor { typedef V value_type; template value_type operator() (T1 const& lhs , T2 const& ) const { return lhs; } template value_type operator() (T lhs, T rhs) const { return lhs * rhs; } value_type operator() (std::string const& lhs,std::string const& ) const { return lhs; } value_type operator() (double lhs, int rhs) const { return lhs * rhs; } value_type operator() (int lhs, double rhs) const { return lhs * rhs; } }; template struct div: public boost::static_visitor { typedef V value_type; template value_type operator() (T1 const& lhs, T2 const&) const { return lhs; } template value_type operator() (T lhs, T rhs) const { return lhs / rhs; } value_type operator() (std::string const& lhs,std::string const&) const { return lhs; } value_type operator() (double lhs, int rhs) const { return lhs / rhs; } value_type operator() (int lhs, double rhs) const { return lhs / rhs; } }; struct to_string : public boost::static_visitor { template std::string operator() (T val) const { std::stringstream ss; ss << val; return ss.str(); } std::string const& operator() (std::string const& val) const { return val; } }; struct to_expression_string : public boost::static_visitor { template std::string operator() (T val) const { std::stringstream ss; ss << val; return ss.str(); } std::string operator() (std::string const& val) const { return "'" + val + "'"; } }; } class value { value_base base_; friend const value operator+(value const&,value const&); friend const value operator-(value const&,value const&); friend const value operator*(value const&,value const&); friend const value operator/(value const&,value const&); //friend template // std::basic_ostream& operator << (std::basic_ostream&, // value const& ); public: value () : base_(0) {} template value(T _val_) : base_(_val_) {} //value (std::string const& str) // : base(str) {} //value& operator=(value const& rhs) //{ // if (this == &rhs) // return *this; // //TODO!!!!! // return *this; //} bool operator==(value const& other) const { return boost::apply_visitor(impl::equals(),base_,other.base_); } bool operator!=(value const& other) const { return !(boost::apply_visitor(impl::equals(),base_,other.base_)); } bool operator>(value const& other) const { return boost::apply_visitor(impl::greater_than(),base_,other.base_); } bool operator>=(value const& other) const { return boost::apply_visitor(impl::greater_or_equal(),base_,other.base_); } bool operator<(value const& other) const { return boost::apply_visitor(impl::less_than(),base_,other.base_); } bool operator<=(value const& other) const { return boost::apply_visitor(impl::less_or_equal(),base_,other.base_); } value_base const& base() const { return base_; } /* value& operator+=(value const& other) { *this = boost::apply_visitor(impl::add(),*this,other); return *this; } value& operator-=(value const& other) { *this = boost::apply_visitor(impl::sub(),*this,other); return *this; } value& operator*=(value const& other) { *this = boost::apply_visitor(impl::mult(),*this,other); return *this; } value& operator/=(value const& other) { *this = boost::apply_visitor(impl::div(),*this,other); return *this; } */ std::string to_expression_string() const { return boost::apply_visitor(impl::to_expression_string(),base_); } std::string to_string() const { return boost::apply_visitor(impl::to_string(),base_); } }; inline const value operator+(value const& p1,value const& p2) { //value tmp(p1); //tmp+=p2; //return tmp; return value(boost::apply_visitor(impl::add(),p1.base_, p2.base_)); } inline const value operator-(value const& p1,value const& p2) { //value tmp(p1); //tmp-=p2; //return tmp; return value(boost::apply_visitor(impl::sub(),p1.base_, p2.base_)); } inline const value operator*(value const& p1,value const& p2) { //value tmp(p1); //tmp*=p2; //return tmp; return value(boost::apply_visitor(impl::mult(),p1.base_, p2.base_)); } inline const value operator/(value const& p1,value const& p2) { //value tmp(p1); //tmp/=p2; //return tmp; return value(boost::apply_visitor(impl::div(),p1.base_, p2.base_)); } template inline std::basic_ostream& operator << (std::basic_ostream& out, value const& v) { out << v.base(); return out; } } #endif //VALUE_HPP