aboutsummaryrefslogtreecommitdiffstats
path: root/include/mapbox/geometry/feature.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'include/mapbox/geometry/feature.hpp')
-rw-r--r--include/mapbox/geometry/feature.hpp81
1 files changed, 81 insertions, 0 deletions
diff --git a/include/mapbox/geometry/feature.hpp b/include/mapbox/geometry/feature.hpp
new file mode 100644
index 0000000..3bdd484
--- /dev/null
+++ b/include/mapbox/geometry/feature.hpp
@@ -0,0 +1,81 @@
+#pragma once
+
+#include <mapbox/geometry/geometry.hpp>
+
+#include <mapbox/variant.hpp>
+
+#include <cstdint>
+#include <string>
+#include <vector>
+#include <unordered_map>
+#include <experimental/optional>
+
+namespace mapbox {
+namespace geometry {
+
+struct value;
+
+struct null_value_t
+{
+ constexpr null_value_t() {}
+ constexpr null_value_t(std::nullptr_t) {}
+};
+
+constexpr bool operator==(const null_value_t&, const null_value_t&) { return true; }
+constexpr bool operator!=(const null_value_t&, const null_value_t&) { return false; }
+
+constexpr null_value_t null_value = null_value_t();
+
+// Multiple numeric types (uint64_t, int64_t, double) are present in order to support
+// the widest possible range of JSON numbers, which do not have a maximum range.
+// Implementations that produce `value`s should use that order for type preference,
+// 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>>>;
+
+struct value : value_base
+{
+ using value_base::value_base;
+};
+
+using property_map = std::unordered_map<std::string, value>;
+
+// The same considerations and requirement for numeric types apply as for `value_base`.
+using identifier = mapbox::util::variant<uint64_t, int64_t, double, std::string>;
+
+template <class T>
+struct feature
+{
+ using coordinate_type = T;
+ using geometry_type = mapbox::geometry::geometry<T>; // Fully qualified to avoid GCC -fpermissive error.
+
+ geometry_type geometry;
+ property_map properties {};
+ std::experimental::optional<identifier> id {};
+};
+
+template <class T>
+constexpr bool operator==(feature<T> const& lhs, feature<T> const& rhs)
+{
+ return lhs.id == rhs.id && lhs.geometry == rhs.geometry && lhs.properties == rhs.properties;
+}
+
+template <class T>
+constexpr bool operator!=(feature<T> const& lhs, feature<T> const& rhs)
+{
+ return !(lhs == rhs);
+}
+
+template <class T, template <typename...> class Cont = std::vector>
+struct feature_collection : Cont<feature<T>>
+{
+ using coordinate_type = T;
+ using feature_type = feature<T>;
+ using container_type = Cont<feature_type>;
+ using container_type::container_type;
+};
+
+} // namespace geometry
+} // namespace mapbox