/***************************************************************************** * * This file is part of Mapnik (c++ mapping toolkit) * * Copyright (C) 2015 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *****************************************************************************/ #ifndef MAPNIK_XML_ATTRIBUTE_CAST_HPP #define MAPNIK_XML_ATTRIBUTE_CAST_HPP //mapnik #include #include #include #include #include #include #include #include #include #include #include #pragma GCC diagnostic push #include #include #pragma GCC diagnostic pop // stl #include #include #include #include #include namespace mapnik { namespace detail { template struct do_xml_attribute_cast { static inline boost::optional xml_attribute_cast_impl(xml_tree const& /*tree*/, std::string const& /*source*/) { std::string err_msg("No conversion from std::string to "); err_msg += std::string(typeid(T).name()); throw std::runtime_error(err_msg); } }; // specialization for mapnik::boolean_type template <> struct do_xml_attribute_cast { static inline boost::optional xml_attribute_cast_impl(xml_tree const& /*tree*/, std::string const& source) { bool result; if (mapnik::util::string2bool(source, result)) return boost::optional(result); return boost::optional(); } }; // specialization for mapnik::value_bool template <> struct do_xml_attribute_cast { static inline boost::optional xml_attribute_cast_impl(xml_tree const& /*tree*/, std::string const& source) { bool result; if (mapnik::util::string2bool(source, result)) return boost::optional(result); return boost::optional(); } }; // specialization for int template <> struct do_xml_attribute_cast { static inline boost::optional xml_attribute_cast_impl(xml_tree const& /*tree*/, std::string const& source) { int result; if (mapnik::util::string2int(source, result)) return boost::optional(result); return boost::optional(); } }; #ifdef BIGINT // specialization for long long template <> struct do_xml_attribute_cast { static inline boost::optional xml_attribute_cast_impl(xml_tree const& /*tree*/, std::string const& source) { int result; if (mapnik::util::string2int(source, result)) return boost::optional(result); return boost::optional(); } }; #endif // specialization for unsigned template <> struct do_xml_attribute_cast { static inline boost::optional xml_attribute_cast_impl(xml_tree const& /*tree*/, std::string const& source) { int result; if (mapnik::util::string2int(source, result) && result >= 0) return boost::optional(static_cast(result)); return boost::optional(); } }; // specialization for float template <> struct do_xml_attribute_cast { static inline boost::optional xml_attribute_cast_impl(xml_tree const& /*tree*/, std::string const& source) { float result; if (mapnik::util::string2float(source, result)) return boost::optional(result); return boost::optional(); } }; // specialization for double template <> struct do_xml_attribute_cast { static inline boost::optional xml_attribute_cast_impl(xml_tree const& /*tree*/, std::string const& source) { double result; if (mapnik::util::string2double(source, result)) return boost::optional(result); return boost::optional(); } }; // specialization for mapnik::enumeration template struct do_xml_attribute_cast > { static inline boost::optional > xml_attribute_cast_impl(xml_tree const& /*tree*/, std::string const& source) { using result_type = typename boost::optional >; try { mapnik::enumeration e; e.from_string(source); return result_type(e); } catch (illegal_enum_value const& ex) { MAPNIK_LOG_ERROR(do_xml_attribute_cast) << ex.what(); return result_type(); } } }; // specialization for mapnik::color template <> struct do_xml_attribute_cast { static inline boost::optional xml_attribute_cast_impl(xml_tree const&, std::string const& source) { return parse_color(source); } }; // specialization for std::string template <> struct do_xml_attribute_cast { static inline boost::optional xml_attribute_cast_impl(xml_tree const&, std::string const& source) { return boost::optional(source); } }; // specialization for mapnik::expression_ptr template <> struct do_xml_attribute_cast { static inline boost::optional xml_attribute_cast_impl(xml_tree const& tree, std::string const& source) { std::map::const_iterator itr = tree.expr_cache_.find(source); if (itr != tree.expr_cache_.end()) { return itr->second; } else { mapnik::expression_ptr expr = parse_expression(source); tree.expr_cache_.emplace(source,expr); return expr; } } }; // specialization for mapnik::font_feature_settings template <> struct do_xml_attribute_cast { static inline boost::optional xml_attribute_cast_impl(xml_tree const&, std::string const& source) { return mapnik::font_feature_settings(source); } }; } // end namespace detail template boost::optional xml_attribute_cast(xml_tree const& tree, std::string const& source) { return detail::do_xml_attribute_cast::xml_attribute_cast_impl(tree, source); } } // end namespace mapnik #endif // MAPNIK_XML_ATTRIBUTE_CAST_HPP