[Git][debian-gis-team/mapbox-geometry][upstream] New upstream version 2.0.3

Bas Couwenberg (@sebastic) gitlab at salsa.debian.org
Tue Apr 16 07:26:08 BST 2024



Bas Couwenberg pushed to branch upstream at Debian GIS Project / mapbox-geometry


Commits:
f05110c6 by Bas Couwenberg at 2024-04-16T08:09:30+02:00
New upstream version 2.0.3
- - - - -


4 changed files:

- include/mapbox/feature.hpp
- include/mapbox/geometry_io.hpp
- test/feature.cpp
- test/io.cpp


Changes:

=====================================
include/mapbox/feature.hpp
=====================================
@@ -7,11 +7,36 @@
 #include <cstdint>
 #include <string>
 #include <vector>
+#include <memory>
 #include <unordered_map>
 
 namespace mapbox {
 namespace feature {
 
+// comparator functors
+struct equal_comp_shared_ptr
+{
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+    template <typename T>
+    bool operator()(T const& lhs, T const& rhs) const
+    {
+        return lhs == rhs;
+    }
+#pragma GCC diagnostic pop
+
+    template <typename T>
+    bool operator()(std::shared_ptr<T> const& lhs, std::shared_ptr<T> const& rhs) const
+    {
+        if (lhs == rhs)
+        {
+            return true;
+        }
+        return *lhs == *rhs;
+    }
+};
+
 struct value;
 
 struct null_value_t
@@ -41,13 +66,17 @@ constexpr null_value_t null_value = null_value_t();
 // using uint64_t for positive integers, int64_t for negative integers, and double
 // for non-integers and integers outside the range of 64 bits.
 using value_base = mapbox::util::variant<null_value_t, bool, uint64_t, int64_t, double, std::string,
-                                         mapbox::util::recursive_wrapper<std::vector<value>>,
-                                         mapbox::util::recursive_wrapper<std::unordered_map<std::string, value>>>;
+                                         std::shared_ptr<std::vector<value>>,
+                                         std::shared_ptr<std::unordered_map<std::string, value>>>;
 
 struct value : public value_base
 {
     using array_type = std::vector<value>;
+    using array_ptr_type = std::shared_ptr<std::vector<value>>;
+    using const_array_ptr_type = std::shared_ptr<const std::vector<value>>;
     using object_type = std::unordered_map<std::string, value>;
+    using object_ptr_type = std::shared_ptr<std::unordered_map<std::string, value>>;
+    using const_object_ptr_type = std::shared_ptr<const std::unordered_map<std::string, value>>;
 
     value() : value_base(null_value) {}
     value(null_value_t) : value_base(null_value) {}
@@ -71,8 +100,21 @@ struct value : public value_base
     value(T t) : value_base(double(t))
     {
     }
-    value(array_type array) : value_base(std::move(array)) {}
-    value(object_type object) : value_base(std::move(object)) {}
+    value(array_type array) : value_base(std::make_shared<array_type>(std::forward<array_type>(array))) {}
+    value(array_ptr_type array) : value_base(array) {}
+    value(object_type object) : value_base(std::make_shared<object_type>(std::forward<object_type>(object))) {}
+    value(object_ptr_type object) : value_base(object) {}
+
+    bool operator==(value const& rhs) const
+    {
+        assert(valid() && rhs.valid());
+        if (this->which() != rhs.which())
+        {
+            return false;
+        }
+        mapbox::util::detail::comparer<value, equal_comp_shared_ptr> visitor(*this);
+        return visit(rhs, visitor);
+    }
 
     explicit operator bool() const { return !is<null_value_t>(); }
 
@@ -80,9 +122,29 @@ struct value : public value_base
     DECLARE_VALUE_TYPE_ACCESOR(Uint, uint64_t)
     DECLARE_VALUE_TYPE_ACCESOR(Bool, bool)
     DECLARE_VALUE_TYPE_ACCESOR(Double, double)
-    DECLARE_VALUE_TYPE_ACCESOR(Array, array_type)
-    DECLARE_VALUE_TYPE_ACCESOR(Object, object_type)
     DECLARE_VALUE_TYPE_ACCESOR(String, std::string)
+
+    array_ptr_type getArray() noexcept
+    {
+        return match(
+            [](array_ptr_type& val) -> array_ptr_type { return val; },
+            [](auto&) -> array_ptr_type { return nullptr; });
+    }
+    const_array_ptr_type getArray() const noexcept
+    {
+        return const_cast<value*>(this)->getArray();
+    }
+
+    object_ptr_type getObject() noexcept
+    {
+        return match(
+            [](object_ptr_type& val) -> object_ptr_type { return val; },
+            [](auto&) -> object_ptr_type { return nullptr; });
+    }
+    const_object_ptr_type getObject() const noexcept
+    {
+        return const_cast<value*>(this)->getObject();
+    }
 };
 
 #undef DECLARE_VALUE_TYPE_ACCESOR


=====================================
include/mapbox/geometry_io.hpp
=====================================
@@ -3,13 +3,14 @@
 #include <mapbox/geometry/empty.hpp>
 #include <mapbox/feature.hpp>
 
+#include <algorithm>
 #include <iostream>
 #include <string>
 
 namespace mapbox {
 namespace geometry {
 
-std::ostream& operator<<(std::ostream& os, const empty&)
+inline std::ostream& operator<<(std::ostream& os, const empty&)
 {
     return os << "[]";
 }
@@ -17,13 +18,13 @@ std::ostream& operator<<(std::ostream& os, const empty&)
 template <typename T>
 std::ostream& operator<<(std::ostream& os, const point<T>& point)
 {
-    return os << "[" << point.x << "," << point.y << "]";
+    return os << '[' << point.x << ',' << point.y << ']';
 }
 
 template <typename T, template <class, class...> class C, class... Args>
 std::ostream& operator<<(std::ostream& os, const C<T, Args...>& cont)
 {
-    os << "[";
+    os << '[';
     for (auto it = cont.cbegin();;)
     {
         os << *it;
@@ -31,9 +32,9 @@ std::ostream& operator<<(std::ostream& os, const C<T, Args...>& cont)
         {
             break;
         }
-        os << ",";
+        os << ',';
     }
-    return os << "]";
+    return os << ']';
 }
 
 template <typename T>
@@ -89,9 +90,149 @@ std::ostream& operator<<(std::ostream& os, const geometry_collection<T>& geom)
 
 namespace feature {
 
-std::ostream& operator<<(std::ostream& os, const null_value_t&)
+inline std::ostream& operator<<(std::ostream& os, const null_value_t&)
 {
-    return os << "[]";
+    return os << "null";
+}
+
+void to_stream(mapbox::feature::property_map const&, std::ostream& dest);
+
+void to_stream(std::vector<mapbox::feature::value> const&, std::ostream& dest);
+
+inline void quote_string(std::string const& in, std::ostream& dest)
+{
+    dest << '\"';
+    for (char c : in)
+    {
+        if (c == '"' || c == '\\')
+        {
+            dest << '\\';
+        }
+        dest << c;
+    }
+    dest << '\"';
+}
+
+struct value_to_stream_visitor
+{
+
+    std::ostream& out;
+
+    template <typename T>
+    void operator()(T val)
+    {
+        out << val;
+    }
+
+    void operator()(std::string const& val)
+    {
+        quote_string(val, out);
+    }
+
+    void operator()(bool val)
+    {
+        out << (val ? "true" : "false");
+    }
+
+    void operator()(std::vector<mapbox::feature::value> const& vec)
+    {
+        out << '[';
+        bool first = true;
+        for (auto const& item : vec)
+        {
+            if (first)
+            {
+                first = false;
+            }
+            else
+            {
+                out << ',';
+            }
+            mapbox::util::apply_visitor(*this, item);
+        }
+        out << ']';
+    }
+
+    void operator()(std::shared_ptr<std::vector<mapbox::feature::value>> const& vec)
+    {
+        (*this)(*vec);
+    }
+
+    void operator()(std::unordered_map<std::string, mapbox::feature::value> const& map)
+    {
+        out << '{';
+        std::vector<std::string> keys;
+        for (auto const& p : map)
+        {
+            keys.push_back(p.first);
+        }
+        std::sort(keys.begin(), keys.end());
+        bool first = true;
+        for (auto const& k : keys)
+        {
+            if (first)
+            {
+                first = false;
+            }
+            else
+            {
+                out << ',';
+            }
+            auto const val = map.find(k);
+            quote_string(k, out);
+            out << ':';
+            mapbox::util::apply_visitor(*this, val->second);
+        }
+        out << '}';
+    }
+
+    void operator()(std::shared_ptr<std::unordered_map<std::string, mapbox::feature::value>> const& map)
+    {
+        (*this)(*map);
+    }
+};
+
+inline std::ostream& operator<<(std::ostream& os, std::unordered_map<std::string, mapbox::feature::value> const& map)
+{
+    value_to_stream_visitor vis{os};
+    vis(map);
+    return os;
+}
+
+inline std::ostream& operator<<(std::ostream& os, std::vector<mapbox::feature::value> const& vec)
+{
+    value_to_stream_visitor vis{os};
+    vis(vec);
+    return os;
+}
+
+inline std::ostream& operator<<(std::ostream& os, mapbox::feature::value const& val)
+{
+    mapbox::util::apply_visitor(value_to_stream_visitor{os}, val);
+    return os;
+}
+
+struct identifier_to_stream_visitor
+{
+
+    std::ostream& out;
+
+    template <typename T>
+    void operator()(T val)
+    {
+        out << val;
+    }
+
+    void operator()(std::string const& val)
+    {
+        quote_string(val, out);
+    }
+};
+
+inline std::ostream& operator<<(std::ostream& os, mapbox::feature::identifier const& val)
+{
+    mapbox::util::apply_visitor(identifier_to_stream_visitor{os}, val);
+    return os;
 }
 
 } // namespace feature


=====================================
test/feature.cpp
=====================================
@@ -12,9 +12,9 @@ using mapbox::feature::value;
 namespace {
 
 template <typename T, typename U>
-void checkType(U&& arg) try
+void checkType(U arg) try
 {
-    value v{std::forward<U>(arg)};
+    value v{arg};
     CHECK(v);
     CHECK(v.template is<T>());
     CHECK(v.template get<T>() == arg);
@@ -24,6 +24,32 @@ catch (...)
     FAIL();
 }
 
+template <typename T, typename U>
+void checkPtrType(U arg) try
+{
+    value v{arg};
+    CHECK(v);
+    CHECK(v.template is<T>());
+    CHECK(*(v.template get<T>()) == *arg);
+}
+catch (...)
+{
+    FAIL();
+}
+
+template <typename T, typename U>
+void checkPtrType2(U arg) try
+{
+    value v{arg};
+    CHECK(v);
+    CHECK(v.template is<T>());
+    CHECK(*(v.template get<T>()) == arg);
+}
+catch (...)
+{
+    FAIL();
+}
+
 } // namespace
 
 TEST_CASE("test value")
@@ -34,6 +60,15 @@ TEST_CASE("test value")
     checkType<bool>(false);
     checkType<std::string>("hello");
 
+    value::array_type vec;
+    vec.emplace_back(value(32));
+    checkPtrType<value::array_ptr_type>(std::make_shared<value::array_type>(vec));
+    checkPtrType2<value::array_ptr_type>(vec);
+    value::object_type map;
+    map.emplace("a", value(33));
+    checkPtrType<value::object_ptr_type>(std::make_shared<value::object_type>(map));
+    checkPtrType2<value::object_ptr_type>(map);
+
     value intV{32};
     CHECK_THROWS(intV.get<uint64_t>());
 


=====================================
test/io.cpp
=====================================
@@ -5,8 +5,6 @@
 
 TEST_CASE("operator<<")
 {
-    mapbox::feature::null_value_t null;
-
     mapbox::geometry::empty empty;
     mapbox::geometry::point<double> point{10, 20};
     mapbox::geometry::point<double> point2{30, 40};
@@ -18,7 +16,6 @@ TEST_CASE("operator<<")
     mapbox::geometry::geometry_collection<double> collection{multiPolygon};
 
     std::stringstream stream;
-    stream << null << std::endl;
     stream << empty << std::endl;
     stream << point << std::endl;
     stream << lineString << std::endl;
@@ -34,9 +31,6 @@ TEST_CASE("operator<<")
     std::getline(stream, line);
     CHECK(line == std::string("[]"));
 
-    std::getline(stream, line);
-    CHECK(line == std::string("[]"));
-
     std::getline(stream, line);
     CHECK(line == std::string("[10,20]"));
 
@@ -61,3 +55,124 @@ TEST_CASE("operator<<")
     std::getline(stream, line);
     CHECK(line == std::string("[[[[[10,20],[30,40]]]]]"));
 }
+
+TEST_CASE("operator<< feature value")
+{
+    mapbox::feature::null_value_t null;
+    mapbox::feature::value val_null{};
+    mapbox::feature::value val_int{1};
+    mapbox::feature::value val_uint{1U};
+    mapbox::feature::value val_double{1.2};
+    mapbox::feature::value val_str{"foo"};
+    mapbox::feature::value val_str_quote{"\"foo\""};
+    mapbox::feature::value val_str_backslash{"\\"};
+    mapbox::feature::value val_bool_true{true};
+    mapbox::feature::value val_bool_false{false};
+    std::vector<mapbox::feature::value> vec = {1, "fee", true, "\"faa\"", "\\"};
+    mapbox::feature::value val_vec{vec};
+    std::unordered_map<std::string, mapbox::feature::value> map = {{"fee", "foo"}, {"blah\"", 12}};
+    mapbox::feature::value val_map{map};
+
+    std::stringstream stream;
+    stream << null << std::endl;
+    stream << val_null << std::endl;
+    stream << val_int << std::endl;
+    stream << val_uint << std::endl;
+    stream << val_double << std::endl;
+    stream << val_str << std::endl;
+    stream << val_str_quote << std::endl;
+    stream << val_str_backslash << std::endl;
+    stream << val_bool_true << std::endl;
+    stream << val_bool_false << std::endl;
+    stream << vec << std::endl;
+    stream << val_vec << std::endl;
+    stream << map << std::endl;
+    stream << val_map << std::endl;
+
+    std::string line;
+
+    std::getline(stream, line);
+    CHECK(line == std::string("null"));
+
+    std::getline(stream, line);
+    CHECK(line == std::string("null"));
+
+    std::getline(stream, line);
+    CHECK(line == std::string("1"));
+
+    std::getline(stream, line);
+    CHECK(line == std::string("1"));
+
+    std::getline(stream, line);
+    CHECK(line == std::string("1.2"));
+
+    std::getline(stream, line);
+    CHECK(line == std::string("\"foo\""));
+
+    std::getline(stream, line);
+    CHECK(line == std::string("\"\\\"foo\\\"\""));
+
+    std::getline(stream, line);
+    CHECK(line == std::string("\"\\\\\""));
+
+    std::getline(stream, line);
+    CHECK(line == std::string("true"));
+
+    std::getline(stream, line);
+    CHECK(line == std::string("false"));
+
+    std::getline(stream, line);
+    CHECK(line == std::string("[1,\"fee\",true,\"\\\"faa\\\"\",\"\\\\\"]"));
+
+    std::getline(stream, line);
+    CHECK(line == std::string("[1,\"fee\",true,\"\\\"faa\\\"\",\"\\\\\"]"));
+
+    std::getline(stream, line);
+    CHECK(line == std::string("{\"blah\\\"\":12,\"fee\":\"foo\"}"));
+
+    std::getline(stream, line);
+    CHECK(line == std::string("{\"blah\\\"\":12,\"fee\":\"foo\"}"));
+}
+
+TEST_CASE("operator<< feature identifier")
+{
+    mapbox::feature::identifier id_null{};
+    mapbox::feature::identifier id_int{static_cast<std::int64_t>(1)};
+    mapbox::feature::identifier id_uint{static_cast<std::uint64_t>(1U)};
+    mapbox::feature::identifier id_double{static_cast<double>(1.2)};
+    mapbox::feature::identifier id_str{"foo"};
+    mapbox::feature::identifier id_str_quote{"\"foo\""};
+    mapbox::feature::identifier id_str_backslash{"\\"};
+
+    std::stringstream stream;
+    stream << id_null << std::endl;
+    stream << id_int << std::endl;
+    stream << id_uint << std::endl;
+    stream << id_double << std::endl;
+    stream << id_str << std::endl;
+    stream << id_str_quote << std::endl;
+    stream << id_str_backslash << std::endl;
+
+    std::string line;
+
+    std::getline(stream, line);
+    CHECK(line == std::string("null"));
+
+    std::getline(stream, line);
+    CHECK(line == std::string("1"));
+
+    std::getline(stream, line);
+    CHECK(line == std::string("1"));
+
+    std::getline(stream, line);
+    CHECK(line == std::string("1.2"));
+
+    std::getline(stream, line);
+    CHECK(line == std::string("\"foo\""));
+
+    std::getline(stream, line);
+    CHECK(line == std::string("\"\\\"foo\\\"\""));
+
+    std::getline(stream, line);
+    CHECK(line == std::string("\"\\\\\""));
+}



View it on GitLab: https://salsa.debian.org/debian-gis-team/mapbox-geometry/-/commit/f05110c68e414b2bbbde355426486d24de1b7836

-- 
View it on GitLab: https://salsa.debian.org/debian-gis-team/mapbox-geometry/-/commit/f05110c68e414b2bbbde355426486d24de1b7836
You're receiving this email because of your account on salsa.debian.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-grass-devel/attachments/20240416/e19c31b2/attachment-0001.htm>


More information about the Pkg-grass-devel mailing list