From 73572f7ba6049b4730f68ace2faad50025e458ef Mon Sep 17 00:00:00 2001 From: Andreas Tille Date: Sat, 16 Jan 2021 16:30:37 +0000 Subject: [PATCH 1/1] Import r-cran-s2_1.0.4.orig.tar.gz [dgit import orig r-cran-s2_1.0.4.orig.tar.gz] --- DESCRIPTION | 44 + MD5 | 395 +++ NAMESPACE | 123 + NEWS.md | 31 + R/RcppExports.R | 263 ++ R/data.R | 72 + R/s2-accessors.R | 136 + R/s2-bounds.R | 35 + R/s2-constructors-formatters.R | 139 + R/s2-earth.R | 23 + R/s2-geography.R | 151 + R/s2-lnglat.R | 113 + R/s2-matrix.R | 170 ++ R/s2-options.R | 142 + R/s2-package.R | 10 + R/s2-point.R | 89 + R/s2-predicates.R | 171 ++ R/s2-transformers.R | 208 ++ R/s2-xptr.R | 80 + R/utils.R | 27 + R/vctrs.R | 36 + R/zzz.R | 72 + README.md | 180 ++ build/partial.rdb | Bin 0 -> 2930 bytes cleanup | 3 + configure | 117 + configure.win | 0 data/s2_data_tbl_cities.rda | Bin 0 -> 7074 bytes data/s2_data_tbl_countries.rda | Bin 0 -> 132764 bytes data/s2_data_tbl_timezones.rda | Bin 0 -> 488748 bytes inst/include/cpp-compat.h | 16 + inst/include/s2/_fp_contract_off.h | 60 + inst/include/s2/base/casts.h | 318 +++ inst/include/s2/base/commandlineflags.h | 51 + inst/include/s2/base/integral_types.h | 31 + inst/include/s2/base/log_severity.h | 40 + inst/include/s2/base/logging.h | 177 ++ inst/include/s2/base/mutex.h | 61 + inst/include/s2/base/port.h | 1013 +++++++ inst/include/s2/base/spinlock.h | 60 + inst/include/s2/base/stringprintf.h | 53 + inst/include/s2/base/strtoint.h | 106 + inst/include/s2/base/timer.h | 50 + inst/include/s2/encoded_s2cell_id_vector.h | 110 + inst/include/s2/encoded_s2point_vector.h | 149 + inst/include/s2/encoded_s2shape_index.h | 276 ++ inst/include/s2/encoded_string_vector.h | 164 ++ inst/include/s2/encoded_uint_vector.h | 299 ++ inst/include/s2/id_set_lexicon.h | 199 ++ inst/include/s2/mutable_s2shape_index.h | 600 ++++ inst/include/s2/r1interval.h | 220 ++ inst/include/s2/r2.h | 26 + inst/include/s2/r2rect.h | 234 ++ inst/include/s2/s1angle.h | 336 +++ inst/include/s2/s1chord_angle.h | 369 +++ inst/include/s2/s1interval.h | 266 ++ inst/include/s2/s2boolean_operation.h | 501 ++++ inst/include/s2/s2builder.h | 1057 +++++++ inst/include/s2/s2builder_graph.h | 799 ++++++ inst/include/s2/s2builder_layer.h | 50 + .../s2/s2builderutil_closed_set_normalizer.h | 221 ++ .../s2builderutil_find_polygon_degeneracies.h | 86 + inst/include/s2/s2builderutil_graph_shape.h | 57 + .../s2/s2builderutil_lax_polygon_layer.h | 218 ++ .../s2/s2builderutil_s2point_vector_layer.h | 122 + .../s2/s2builderutil_s2polygon_layer.h | 211 ++ .../s2/s2builderutil_s2polyline_layer.h | 174 ++ .../s2builderutil_s2polyline_vector_layer.h | 292 ++ .../include/s2/s2builderutil_snap_functions.h | 239 ++ inst/include/s2/s2builderutil_testing.h | 100 + inst/include/s2/s2cap.h | 286 ++ inst/include/s2/s2cell.h | 249 ++ inst/include/s2/s2cell_id.h | 705 +++++ inst/include/s2/s2cell_index.h | 660 +++++ inst/include/s2/s2cell_union.h | 399 +++ inst/include/s2/s2centroids.h | 87 + inst/include/s2/s2closest_cell_query.h | 385 +++ inst/include/s2/s2closest_cell_query_base.h | 842 ++++++ inst/include/s2/s2closest_edge_query.h | 421 +++ inst/include/s2/s2closest_edge_query_base.h | 946 +++++++ .../include/s2/s2closest_edge_query_testing.h | 91 + inst/include/s2/s2closest_point_query.h | 465 ++++ inst/include/s2/s2closest_point_query_base.h | 767 +++++ inst/include/s2/s2contains_point_query.h | 328 +++ inst/include/s2/s2contains_vertex_query.h | 66 + inst/include/s2/s2convex_hull_query.h | 110 + inst/include/s2/s2coords.h | 459 +++ inst/include/s2/s2coords_internal.h | 71 + inst/include/s2/s2crossing_edge_query.h | 220 ++ inst/include/s2/s2debug.h | 69 + inst/include/s2/s2distance_target.h | 165 ++ inst/include/s2/s2earth.h | 268 ++ inst/include/s2/s2edge_clipping.h | 183 ++ inst/include/s2/s2edge_crosser.h | 343 +++ inst/include/s2/s2edge_crossings.h | 138 + inst/include/s2/s2edge_crossings_internal.h | 59 + inst/include/s2/s2edge_distances.h | 192 ++ inst/include/s2/s2edge_tessellator.h | 101 + inst/include/s2/s2edge_vector_shape.h | 85 + inst/include/s2/s2error.h | 147 + inst/include/s2/s2furthest_edge_query.h | 439 +++ inst/include/s2/s2latlng.h | 234 ++ inst/include/s2/s2latlng_rect.h | 434 +++ inst/include/s2/s2latlng_rect_bounder.h | 89 + inst/include/s2/s2lax_loop_shape.h | 153 + inst/include/s2/s2lax_polygon_shape.h | 183 ++ inst/include/s2/s2lax_polyline_shape.h | 124 + inst/include/s2/s2loop.h | 711 +++++ inst/include/s2/s2loop_measures.h | 280 ++ inst/include/s2/s2max_distance_targets.h | 241 ++ inst/include/s2/s2measures.h | 78 + inst/include/s2/s2metrics.h | 199 ++ inst/include/s2/s2min_distance_targets.h | 273 ++ inst/include/s2/s2padded_cell.h | 108 + inst/include/s2/s2point.h | 38 + inst/include/s2/s2point_compression.h | 78 + inst/include/s2/s2point_index.h | 345 +++ inst/include/s2/s2point_region.h | 76 + inst/include/s2/s2point_span.h | 57 + inst/include/s2/s2point_vector_shape.h | 127 + inst/include/s2/s2pointutil.h | 139 + inst/include/s2/s2polygon.h | 934 +++++++ inst/include/s2/s2polyline.h | 379 +++ inst/include/s2/s2polyline_alignment.h | 245 ++ .../s2/s2polyline_alignment_internal.h | 158 ++ inst/include/s2/s2polyline_measures.h | 53 + inst/include/s2/s2polyline_simplifier.h | 109 + inst/include/s2/s2predicates.h | 282 ++ inst/include/s2/s2predicates_internal.h | 135 + inst/include/s2/s2projections.h | 161 ++ inst/include/s2/s2r2rect.h | 292 ++ inst/include/s2/s2region.h | 142 + inst/include/s2/s2region_coverer.h | 356 +++ inst/include/s2/s2region_intersection.h | 79 + inst/include/s2/s2region_term_indexer.h | 299 ++ inst/include/s2/s2region_union.h | 83 + inst/include/s2/s2shape.h | 283 ++ inst/include/s2/s2shape_index.h | 781 ++++++ .../s2/s2shape_index_buffered_region.h | 135 + inst/include/s2/s2shape_index_measures.h | 100 + inst/include/s2/s2shape_index_region.h | 350 +++ inst/include/s2/s2shape_measures.h | 95 + .../s2/s2shapeutil_build_polygon_boundaries.h | 66 + inst/include/s2/s2shapeutil_coding.h | 283 ++ .../s2/s2shapeutil_contains_brute_force.h | 41 + inst/include/s2/s2shapeutil_count_edges.h | 57 + inst/include/s2/s2shapeutil_edge_iterator.h | 72 + .../s2/s2shapeutil_get_reference_point.h | 48 + inst/include/s2/s2shapeutil_range_iterator.h | 65 + inst/include/s2/s2shapeutil_shape_edge.h | 58 + inst/include/s2/s2shapeutil_shape_edge_id.h | 97 + inst/include/s2/s2shapeutil_testing.h | 36 + .../s2shapeutil_visit_crossing_edge_pairs.h | 72 + inst/include/s2/s2testing.h | 386 +++ inst/include/s2/s2text_format.h | 289 ++ inst/include/s2/s2wedge_relations.h | 64 + inst/include/s2/sequence_lexicon.h | 296 ++ inst/include/s2/strings/ostringstream.h | 105 + inst/include/s2/strings/serialize.h | 40 + .../s2/third_party/absl/algorithm/algorithm.h | 187 ++ .../s2/third_party/absl/base/attributes.h | 666 +++++ inst/include/s2/third_party/absl/base/casts.h | 189 ++ .../include/s2/third_party/absl/base/config.h | 462 +++ .../absl/base/dynamic_annotations.h | 391 +++ .../absl/base/internal/atomic_hook.h | 168 ++ .../third_party/absl/base/internal/identity.h | 33 + .../absl/base/internal/inline_variable.h | 117 + .../third_party/absl/base/internal/invoke.h | 188 ++ .../absl/base/internal/raw_logging.h | 205 ++ .../absl/base/internal/throw_delegate.h | 71 + .../absl/base/internal/unaligned_access.h | 322 +++ .../s2/third_party/absl/base/log_severity.h | 77 + .../include/s2/third_party/absl/base/macros.h | 237 ++ .../s2/third_party/absl/base/optimization.h | 177 ++ .../s2/third_party/absl/base/policy_checks.h | 124 + inst/include/s2/third_party/absl/base/port.h | 97 + .../absl/base/thread_annotations.h | 277 ++ .../third_party/absl/container/fixed_array.h | 523 ++++ .../absl/container/inlined_vector.h | 1453 ++++++++++ .../container/internal/compressed_tuple.h | 191 ++ .../container/internal/container_memory.h | 424 +++ .../absl/container/internal/layout.h | 739 +++++ .../s2/third_party/absl/memory/memory.h | 755 +++++ .../s2/third_party/absl/meta/type_traits.h | 436 +++ .../s2/third_party/absl/numeric/int128.h | 656 +++++ .../absl/numeric/int128_have_intrinsic.inc | 3 + .../absl/numeric/int128_no_intrinsic.inc | 3 + .../s2/third_party/absl/strings/ascii.h | 239 ++ .../s2/third_party/absl/strings/ascii_ctype.h | 66 + .../third_party/absl/strings/internal/bits.h | 53 + .../absl/strings/internal/memutil.h | 146 + .../strings/internal/resize_uninitialized.h | 72 + .../s2/third_party/absl/strings/match.h | 89 + .../s2/third_party/absl/strings/numbers.h | 187 ++ .../s2/third_party/absl/strings/str_cat.h | 398 +++ .../s2/third_party/absl/strings/str_join.h | 22 + .../s2/third_party/absl/strings/str_split.h | 43 + .../s2/third_party/absl/strings/string_view.h | 602 ++++ .../s2/third_party/absl/strings/strip.h | 130 + inst/include/s2/third_party/absl/types/span.h | 793 ++++++ .../s2/third_party/absl/utility/utility.h | 299 ++ inst/include/s2/util/bits/bit-interleave.h | 53 + inst/include/s2/util/bits/bits.h | 745 +++++ inst/include/s2/util/coding/coder.h | 562 ++++ inst/include/s2/util/coding/nth-derivative.h | 134 + inst/include/s2/util/coding/transforms.h | 62 + inst/include/s2/util/coding/varint.h | 476 ++++ inst/include/s2/util/endian/endian.h | 861 ++++++ inst/include/s2/util/gtl/btree.h | 2471 +++++++++++++++++ inst/include/s2/util/gtl/btree_container.h | 411 +++ inst/include/s2/util/gtl/btree_map.h | 79 + inst/include/s2/util/gtl/btree_set.h | 73 + inst/include/s2/util/gtl/compact_array.h | 661 +++++ inst/include/s2/util/gtl/container_logging.h | 291 ++ inst/include/s2/util/gtl/dense_hash_set.h | 358 +++ inst/include/s2/util/gtl/densehashtable.h | 1493 ++++++++++ inst/include/s2/util/gtl/hashtable_common.h | 253 ++ inst/include/s2/util/gtl/layout.h | 28 + .../s2/util/gtl/legacy_random_shuffle.h | 77 + inst/include/s2/util/hash/mix.h | 76 + .../s2/util/math/exactfloat/exactfloat.h | 646 +++++ inst/include/s2/util/math/mathutil.h | 189 ++ inst/include/s2/util/math/matrix3x3.h | 574 ++++ inst/include/s2/util/math/vector.h | 569 ++++ inst/include/s2/util/math/vector3_hash.h | 54 + inst/include/s2/util/units/length-units.h | 135 + inst/include/s2/util/units/physical-units.h | 313 +++ inst/include/s2/value_lexicon.h | 234 ++ man/as_s2_geography.Rd | 77 + man/figures/rc300.png | Bin 0 -> 15702 bytes man/s2-package.Rd | 41 + man/s2_boundary.Rd | 190 ++ man/s2_bounds_cap.Rd | 41 + man/s2_closest_feature.Rd | 107 + man/s2_contains.Rd | 170 ++ man/s2_data_tbl_countries.Rd | 59 + man/s2_earth_radius_meters.Rd | 25 + man/s2_geog_point.Rd | 117 + man/s2_is_collection.Rd | 106 + man/s2_lnglat.Rd | 55 + man/s2_options.Rd | 104 + man/s2_point.Rd | 48 + src/Makevars.in | 128 + src/Makevars.win | 139 + src/RcppExports.cpp | 879 ++++++ src/cpp-compat.cpp | 40 + src/geography-collection.h | 224 ++ src/geography-operator.h | 69 + src/geography.h | 88 + src/init.cpp | 14 + src/point-geography.h | 163 ++ src/polygon-geography.h | 322 +++ src/polyline-geography.h | 194 ++ src/s2-accessors.cpp | 171 ++ src/s2-bounds.cpp | 68 + src/s2-constructors-formatters.cpp | 76 + src/s2-geography.cpp | 123 + src/s2-lnglat.cpp | 62 + src/s2-matrix.cpp | 623 +++++ src/s2-options.h | 309 +++ src/s2-point.cpp | 60 + src/s2-predicates.cpp | 231 ++ src/s2-transformers.cpp | 442 +++ src/s2-xptr.cpp | 50 + src/s2/base/stringprintf.cc | 107 + src/s2/base/strtoint.cc | 65 + src/s2/encoded_s2cell_id_vector.cc | 164 ++ src/s2/encoded_s2point_vector.cc | 838 ++++++ src/s2/encoded_s2shape_index.cc | 181 ++ src/s2/encoded_string_vector.cc | 66 + src/s2/id_set_lexicon.cc | 81 + src/s2/mutable_s2shape_index.cc | 1585 +++++++++++ src/s2/r2rect.cc | 93 + src/s2/s1angle.cc | 54 + src/s2/s1chord_angle.cc | 159 ++ src/s2/s1interval.cc | 296 ++ src/s2/s2boolean_operation.cc | 2392 ++++++++++++++++ src/s2/s2builder.cc | 1829 ++++++++++++ src/s2/s2builder_graph.cc | 1084 ++++++++ src/s2/s2builderutil_closed_set_normalizer.cc | 313 +++ ...s2builderutil_find_polygon_degeneracies.cc | 392 +++ src/s2/s2builderutil_lax_polygon_layer.cc | 212 ++ src/s2/s2builderutil_s2point_vector_layer.cc | 74 + src/s2/s2builderutil_s2polygon_layer.cc | 191 ++ src/s2/s2builderutil_s2polyline_layer.cc | 105 + .../s2builderutil_s2polyline_vector_layer.cc | 98 + src/s2/s2builderutil_snap_functions.cc | 354 +++ src/s2/s2builderutil_testing.cc | 37 + src/s2/s2cap.cc | 347 +++ src/s2/s2cell.cc | 552 ++++ src/s2/s2cell_id.cc | 619 +++++ src/s2/s2cell_index.cc | 149 + src/s2/s2cell_union.cc | 515 ++++ src/s2/s2centroids.cc | 84 + src/s2/s2closest_cell_query.cc | 123 + src/s2/s2closest_edge_query.cc | 106 + src/s2/s2closest_point_query.cc | 66 + src/s2/s2contains_vertex_query.cc | 39 + src/s2/s2convex_hull_query.cc | 198 ++ src/s2/s2coords.cc | 146 + src/s2/s2crossing_edge_query.cc | 380 +++ src/s2/s2debug.cc | 23 + src/s2/s2earth.cc | 52 + src/s2/s2edge_clipping.cc | 462 +++ src/s2/s2edge_crosser.cc | 85 + src/s2/s2edge_crossings.cc | 515 ++++ src/s2/s2edge_distances.cc | 419 +++ src/s2/s2edge_tessellator.cc | 276 ++ src/s2/s2error.cc | 29 + src/s2/s2furthest_edge_query.cc | 117 + src/s2/s2latlng.cc | 90 + src/s2/s2latlng_rect.cc | 727 +++++ src/s2/s2latlng_rect_bounder.cc | 344 +++ src/s2/s2lax_loop_shape.cc | 104 + src/s2/s2lax_polygon_shape.cc | 348 +++ src/s2/s2lax_polyline_shape.cc | 118 + src/s2/s2loop.cc | 1509 ++++++++++ src/s2/s2loop_measures.cc | 313 +++ src/s2/s2max_distance_targets.cc | 265 ++ src/s2/s2measures.cc | 128 + src/s2/s2metrics.cc | 122 + src/s2/s2min_distance_targets.cc | 295 ++ src/s2/s2padded_cell.cc | 162 ++ src/s2/s2point_compression.cc | 388 +++ src/s2/s2point_region.cc | 72 + src/s2/s2pointutil.cc | 131 + src/s2/s2polygon.cc | 1564 +++++++++++ src/s2/s2polyline.cc | 645 +++++ src/s2/s2polyline_alignment.cc | 414 +++ src/s2/s2polyline_measures.cc | 42 + src/s2/s2polyline_simplifier.cc | 187 ++ src/s2/s2predicates.cc | 1486 ++++++++++ src/s2/s2projections.cc | 109 + src/s2/s2r2rect.cc | 88 + src/s2/s2region.cc | 26 + src/s2/s2region_coverer.cc | 514 ++++ src/s2/s2region_intersection.cc | 84 + src/s2/s2region_term_indexer.cc | 270 ++ src/s2/s2region_union.cc | 90 + src/s2/s2shape_index.cc | 321 +++ src/s2/s2shape_index_buffered_region.cc | 113 + src/s2/s2shape_index_measures.cc | 92 + src/s2/s2shape_measures.cc | 138 + .../s2shapeutil_build_polygon_boundaries.cc | 120 + src/s2/s2shapeutil_coding.cc | 253 ++ src/s2/s2shapeutil_contains_brute_force.cc | 40 + src/s2/s2shapeutil_edge_iterator.cc | 45 + src/s2/s2shapeutil_get_reference_point.cc | 107 + src/s2/s2shapeutil_range_iterator.cc | 58 + .../s2shapeutil_visit_crossing_edge_pairs.cc | 440 +++ src/s2/s2testing.cc | 465 ++++ src/s2/s2text_format.cc | 506 ++++ src/s2/s2wedge_relations.cc | 80 + src/s2/strings/ostringstream.cc | 35 + src/s2/strings/serialize.cc | 46 + .../absl/base/dynamic_annotations.cc | 129 + .../absl/base/internal/raw_logging.cc | 255 ++ .../absl/base/internal/throw_delegate.cc | 107 + src/s2/third_party/absl/numeric/int128.cc | 232 ++ src/s2/third_party/absl/strings/ascii.cc | 198 ++ .../absl/strings/internal/memutil.cc | 110 + src/s2/third_party/absl/strings/match.cc | 38 + src/s2/third_party/absl/strings/numbers.cc | 909 ++++++ src/s2/third_party/absl/strings/str_cat.cc | 240 ++ src/s2/third_party/absl/strings/str_split.cc | 47 + .../third_party/absl/strings/string_view.cc | 245 ++ src/s2/third_party/absl/strings/strip.cc | 42 + src/s2/util/bits/bit-interleave.cc | 274 ++ src/s2/util/bits/bits.cc | 155 ++ src/s2/util/coding/coder.cc | 83 + src/s2/util/coding/varint.cc | 289 ++ src/s2/util/math/exactfloat/exactfloat.cc | 832 ++++++ src/s2/util/math/mathutil.cc | 75 + src/s2/util/units/length-units.cc | 21 + src/tests/soname.h | 9 + src/wk-geography.h | 133 + tests/area.R | 23 + tests/area.Rout | 29 + tests/testthat.R | 4 + tests/testthat/test-data.R | 30 + tests/testthat/test-s2-accessors.R | 135 + tests/testthat/test-s2-bounds.R | 44 + .../test-s2-constructors-formatters.R | 171 ++ tests/testthat/test-s2-earth.R | 5 + tests/testthat/test-s2-geography.R | 222 ++ tests/testthat/test-s2-lnglat.R | 92 + tests/testthat/test-s2-matrix.R | 219 ++ tests/testthat/test-s2-options.R | 11 + tests/testthat/test-s2-point.R | 57 + tests/testthat/test-s2-predicates.R | 165 ++ tests/testthat/test-s2-transformers.R | 499 ++++ tests/testthat/test-s2-xptr.R | 36 + tests/testthat/test-utils.R | 18 + tests/testthat/test-vctrs.R | 24 + tools/version.c | 4 + tools/winlibs.R | 8 + 396 files changed, 99068 insertions(+) create mode 100644 DESCRIPTION create mode 100644 MD5 create mode 100644 NAMESPACE create mode 100644 NEWS.md create mode 100644 R/RcppExports.R create mode 100644 R/data.R create mode 100644 R/s2-accessors.R create mode 100644 R/s2-bounds.R create mode 100644 R/s2-constructors-formatters.R create mode 100644 R/s2-earth.R create mode 100644 R/s2-geography.R create mode 100644 R/s2-lnglat.R create mode 100644 R/s2-matrix.R create mode 100644 R/s2-options.R create mode 100644 R/s2-package.R create mode 100644 R/s2-point.R create mode 100644 R/s2-predicates.R create mode 100644 R/s2-transformers.R create mode 100644 R/s2-xptr.R create mode 100644 R/utils.R create mode 100644 R/vctrs.R create mode 100644 R/zzz.R create mode 100644 README.md create mode 100644 build/partial.rdb create mode 100755 cleanup create mode 100755 configure create mode 100755 configure.win create mode 100644 data/s2_data_tbl_cities.rda create mode 100644 data/s2_data_tbl_countries.rda create mode 100644 data/s2_data_tbl_timezones.rda create mode 100644 inst/include/cpp-compat.h create mode 100644 inst/include/s2/_fp_contract_off.h create mode 100644 inst/include/s2/base/casts.h create mode 100644 inst/include/s2/base/commandlineflags.h create mode 100644 inst/include/s2/base/integral_types.h create mode 100644 inst/include/s2/base/log_severity.h create mode 100644 inst/include/s2/base/logging.h create mode 100644 inst/include/s2/base/mutex.h create mode 100644 inst/include/s2/base/port.h create mode 100644 inst/include/s2/base/spinlock.h create mode 100644 inst/include/s2/base/stringprintf.h create mode 100644 inst/include/s2/base/strtoint.h create mode 100644 inst/include/s2/base/timer.h create mode 100644 inst/include/s2/encoded_s2cell_id_vector.h create mode 100644 inst/include/s2/encoded_s2point_vector.h create mode 100644 inst/include/s2/encoded_s2shape_index.h create mode 100644 inst/include/s2/encoded_string_vector.h create mode 100644 inst/include/s2/encoded_uint_vector.h create mode 100644 inst/include/s2/id_set_lexicon.h create mode 100644 inst/include/s2/mutable_s2shape_index.h create mode 100644 inst/include/s2/r1interval.h create mode 100644 inst/include/s2/r2.h create mode 100644 inst/include/s2/r2rect.h create mode 100644 inst/include/s2/s1angle.h create mode 100644 inst/include/s2/s1chord_angle.h create mode 100644 inst/include/s2/s1interval.h create mode 100644 inst/include/s2/s2boolean_operation.h create mode 100644 inst/include/s2/s2builder.h create mode 100644 inst/include/s2/s2builder_graph.h create mode 100644 inst/include/s2/s2builder_layer.h create mode 100644 inst/include/s2/s2builderutil_closed_set_normalizer.h create mode 100644 inst/include/s2/s2builderutil_find_polygon_degeneracies.h create mode 100644 inst/include/s2/s2builderutil_graph_shape.h create mode 100644 inst/include/s2/s2builderutil_lax_polygon_layer.h create mode 100644 inst/include/s2/s2builderutil_s2point_vector_layer.h create mode 100644 inst/include/s2/s2builderutil_s2polygon_layer.h create mode 100644 inst/include/s2/s2builderutil_s2polyline_layer.h create mode 100644 inst/include/s2/s2builderutil_s2polyline_vector_layer.h create mode 100644 inst/include/s2/s2builderutil_snap_functions.h create mode 100644 inst/include/s2/s2builderutil_testing.h create mode 100644 inst/include/s2/s2cap.h create mode 100644 inst/include/s2/s2cell.h create mode 100644 inst/include/s2/s2cell_id.h create mode 100644 inst/include/s2/s2cell_index.h create mode 100644 inst/include/s2/s2cell_union.h create mode 100644 inst/include/s2/s2centroids.h create mode 100644 inst/include/s2/s2closest_cell_query.h create mode 100644 inst/include/s2/s2closest_cell_query_base.h create mode 100644 inst/include/s2/s2closest_edge_query.h create mode 100644 inst/include/s2/s2closest_edge_query_base.h create mode 100644 inst/include/s2/s2closest_edge_query_testing.h create mode 100644 inst/include/s2/s2closest_point_query.h create mode 100644 inst/include/s2/s2closest_point_query_base.h create mode 100644 inst/include/s2/s2contains_point_query.h create mode 100644 inst/include/s2/s2contains_vertex_query.h create mode 100644 inst/include/s2/s2convex_hull_query.h create mode 100644 inst/include/s2/s2coords.h create mode 100644 inst/include/s2/s2coords_internal.h create mode 100644 inst/include/s2/s2crossing_edge_query.h create mode 100644 inst/include/s2/s2debug.h create mode 100644 inst/include/s2/s2distance_target.h create mode 100644 inst/include/s2/s2earth.h create mode 100644 inst/include/s2/s2edge_clipping.h create mode 100644 inst/include/s2/s2edge_crosser.h create mode 100644 inst/include/s2/s2edge_crossings.h create mode 100644 inst/include/s2/s2edge_crossings_internal.h create mode 100644 inst/include/s2/s2edge_distances.h create mode 100644 inst/include/s2/s2edge_tessellator.h create mode 100644 inst/include/s2/s2edge_vector_shape.h create mode 100644 inst/include/s2/s2error.h create mode 100644 inst/include/s2/s2furthest_edge_query.h create mode 100644 inst/include/s2/s2latlng.h create mode 100644 inst/include/s2/s2latlng_rect.h create mode 100644 inst/include/s2/s2latlng_rect_bounder.h create mode 100644 inst/include/s2/s2lax_loop_shape.h create mode 100644 inst/include/s2/s2lax_polygon_shape.h create mode 100644 inst/include/s2/s2lax_polyline_shape.h create mode 100644 inst/include/s2/s2loop.h create mode 100644 inst/include/s2/s2loop_measures.h create mode 100644 inst/include/s2/s2max_distance_targets.h create mode 100644 inst/include/s2/s2measures.h create mode 100644 inst/include/s2/s2metrics.h create mode 100644 inst/include/s2/s2min_distance_targets.h create mode 100644 inst/include/s2/s2padded_cell.h create mode 100644 inst/include/s2/s2point.h create mode 100644 inst/include/s2/s2point_compression.h create mode 100644 inst/include/s2/s2point_index.h create mode 100644 inst/include/s2/s2point_region.h create mode 100644 inst/include/s2/s2point_span.h create mode 100644 inst/include/s2/s2point_vector_shape.h create mode 100644 inst/include/s2/s2pointutil.h create mode 100644 inst/include/s2/s2polygon.h create mode 100644 inst/include/s2/s2polyline.h create mode 100644 inst/include/s2/s2polyline_alignment.h create mode 100644 inst/include/s2/s2polyline_alignment_internal.h create mode 100644 inst/include/s2/s2polyline_measures.h create mode 100644 inst/include/s2/s2polyline_simplifier.h create mode 100644 inst/include/s2/s2predicates.h create mode 100644 inst/include/s2/s2predicates_internal.h create mode 100644 inst/include/s2/s2projections.h create mode 100644 inst/include/s2/s2r2rect.h create mode 100644 inst/include/s2/s2region.h create mode 100644 inst/include/s2/s2region_coverer.h create mode 100644 inst/include/s2/s2region_intersection.h create mode 100644 inst/include/s2/s2region_term_indexer.h create mode 100644 inst/include/s2/s2region_union.h create mode 100644 inst/include/s2/s2shape.h create mode 100644 inst/include/s2/s2shape_index.h create mode 100644 inst/include/s2/s2shape_index_buffered_region.h create mode 100644 inst/include/s2/s2shape_index_measures.h create mode 100644 inst/include/s2/s2shape_index_region.h create mode 100644 inst/include/s2/s2shape_measures.h create mode 100644 inst/include/s2/s2shapeutil_build_polygon_boundaries.h create mode 100644 inst/include/s2/s2shapeutil_coding.h create mode 100644 inst/include/s2/s2shapeutil_contains_brute_force.h create mode 100644 inst/include/s2/s2shapeutil_count_edges.h create mode 100644 inst/include/s2/s2shapeutil_edge_iterator.h create mode 100644 inst/include/s2/s2shapeutil_get_reference_point.h create mode 100644 inst/include/s2/s2shapeutil_range_iterator.h create mode 100644 inst/include/s2/s2shapeutil_shape_edge.h create mode 100644 inst/include/s2/s2shapeutil_shape_edge_id.h create mode 100644 inst/include/s2/s2shapeutil_testing.h create mode 100644 inst/include/s2/s2shapeutil_visit_crossing_edge_pairs.h create mode 100644 inst/include/s2/s2testing.h create mode 100644 inst/include/s2/s2text_format.h create mode 100644 inst/include/s2/s2wedge_relations.h create mode 100644 inst/include/s2/sequence_lexicon.h create mode 100644 inst/include/s2/strings/ostringstream.h create mode 100644 inst/include/s2/strings/serialize.h create mode 100644 inst/include/s2/third_party/absl/algorithm/algorithm.h create mode 100644 inst/include/s2/third_party/absl/base/attributes.h create mode 100644 inst/include/s2/third_party/absl/base/casts.h create mode 100644 inst/include/s2/third_party/absl/base/config.h create mode 100644 inst/include/s2/third_party/absl/base/dynamic_annotations.h create mode 100644 inst/include/s2/third_party/absl/base/internal/atomic_hook.h create mode 100644 inst/include/s2/third_party/absl/base/internal/identity.h create mode 100644 inst/include/s2/third_party/absl/base/internal/inline_variable.h create mode 100644 inst/include/s2/third_party/absl/base/internal/invoke.h create mode 100644 inst/include/s2/third_party/absl/base/internal/raw_logging.h create mode 100644 inst/include/s2/third_party/absl/base/internal/throw_delegate.h create mode 100644 inst/include/s2/third_party/absl/base/internal/unaligned_access.h create mode 100644 inst/include/s2/third_party/absl/base/log_severity.h create mode 100644 inst/include/s2/third_party/absl/base/macros.h create mode 100644 inst/include/s2/third_party/absl/base/optimization.h create mode 100644 inst/include/s2/third_party/absl/base/policy_checks.h create mode 100644 inst/include/s2/third_party/absl/base/port.h create mode 100644 inst/include/s2/third_party/absl/base/thread_annotations.h create mode 100644 inst/include/s2/third_party/absl/container/fixed_array.h create mode 100644 inst/include/s2/third_party/absl/container/inlined_vector.h create mode 100644 inst/include/s2/third_party/absl/container/internal/compressed_tuple.h create mode 100644 inst/include/s2/third_party/absl/container/internal/container_memory.h create mode 100644 inst/include/s2/third_party/absl/container/internal/layout.h create mode 100644 inst/include/s2/third_party/absl/memory/memory.h create mode 100644 inst/include/s2/third_party/absl/meta/type_traits.h create mode 100644 inst/include/s2/third_party/absl/numeric/int128.h create mode 100644 inst/include/s2/third_party/absl/numeric/int128_have_intrinsic.inc create mode 100644 inst/include/s2/third_party/absl/numeric/int128_no_intrinsic.inc create mode 100644 inst/include/s2/third_party/absl/strings/ascii.h create mode 100644 inst/include/s2/third_party/absl/strings/ascii_ctype.h create mode 100644 inst/include/s2/third_party/absl/strings/internal/bits.h create mode 100644 inst/include/s2/third_party/absl/strings/internal/memutil.h create mode 100644 inst/include/s2/third_party/absl/strings/internal/resize_uninitialized.h create mode 100644 inst/include/s2/third_party/absl/strings/match.h create mode 100644 inst/include/s2/third_party/absl/strings/numbers.h create mode 100644 inst/include/s2/third_party/absl/strings/str_cat.h create mode 100644 inst/include/s2/third_party/absl/strings/str_join.h create mode 100644 inst/include/s2/third_party/absl/strings/str_split.h create mode 100644 inst/include/s2/third_party/absl/strings/string_view.h create mode 100644 inst/include/s2/third_party/absl/strings/strip.h create mode 100644 inst/include/s2/third_party/absl/types/span.h create mode 100644 inst/include/s2/third_party/absl/utility/utility.h create mode 100644 inst/include/s2/util/bits/bit-interleave.h create mode 100644 inst/include/s2/util/bits/bits.h create mode 100644 inst/include/s2/util/coding/coder.h create mode 100644 inst/include/s2/util/coding/nth-derivative.h create mode 100644 inst/include/s2/util/coding/transforms.h create mode 100644 inst/include/s2/util/coding/varint.h create mode 100644 inst/include/s2/util/endian/endian.h create mode 100644 inst/include/s2/util/gtl/btree.h create mode 100644 inst/include/s2/util/gtl/btree_container.h create mode 100644 inst/include/s2/util/gtl/btree_map.h create mode 100644 inst/include/s2/util/gtl/btree_set.h create mode 100644 inst/include/s2/util/gtl/compact_array.h create mode 100644 inst/include/s2/util/gtl/container_logging.h create mode 100644 inst/include/s2/util/gtl/dense_hash_set.h create mode 100644 inst/include/s2/util/gtl/densehashtable.h create mode 100644 inst/include/s2/util/gtl/hashtable_common.h create mode 100644 inst/include/s2/util/gtl/layout.h create mode 100644 inst/include/s2/util/gtl/legacy_random_shuffle.h create mode 100644 inst/include/s2/util/hash/mix.h create mode 100644 inst/include/s2/util/math/exactfloat/exactfloat.h create mode 100644 inst/include/s2/util/math/mathutil.h create mode 100644 inst/include/s2/util/math/matrix3x3.h create mode 100644 inst/include/s2/util/math/vector.h create mode 100644 inst/include/s2/util/math/vector3_hash.h create mode 100644 inst/include/s2/util/units/length-units.h create mode 100644 inst/include/s2/util/units/physical-units.h create mode 100644 inst/include/s2/value_lexicon.h create mode 100644 man/as_s2_geography.Rd create mode 100644 man/figures/rc300.png create mode 100644 man/s2-package.Rd create mode 100644 man/s2_boundary.Rd create mode 100644 man/s2_bounds_cap.Rd create mode 100644 man/s2_closest_feature.Rd create mode 100644 man/s2_contains.Rd create mode 100644 man/s2_data_tbl_countries.Rd create mode 100644 man/s2_earth_radius_meters.Rd create mode 100644 man/s2_geog_point.Rd create mode 100644 man/s2_is_collection.Rd create mode 100644 man/s2_lnglat.Rd create mode 100644 man/s2_options.Rd create mode 100644 man/s2_point.Rd create mode 100644 src/Makevars.in create mode 100644 src/Makevars.win create mode 100644 src/RcppExports.cpp create mode 100644 src/cpp-compat.cpp create mode 100644 src/geography-collection.h create mode 100644 src/geography-operator.h create mode 100644 src/geography.h create mode 100644 src/init.cpp create mode 100644 src/point-geography.h create mode 100644 src/polygon-geography.h create mode 100644 src/polyline-geography.h create mode 100644 src/s2-accessors.cpp create mode 100644 src/s2-bounds.cpp create mode 100644 src/s2-constructors-formatters.cpp create mode 100644 src/s2-geography.cpp create mode 100644 src/s2-lnglat.cpp create mode 100644 src/s2-matrix.cpp create mode 100644 src/s2-options.h create mode 100644 src/s2-point.cpp create mode 100644 src/s2-predicates.cpp create mode 100644 src/s2-transformers.cpp create mode 100644 src/s2-xptr.cpp create mode 100644 src/s2/base/stringprintf.cc create mode 100644 src/s2/base/strtoint.cc create mode 100644 src/s2/encoded_s2cell_id_vector.cc create mode 100644 src/s2/encoded_s2point_vector.cc create mode 100644 src/s2/encoded_s2shape_index.cc create mode 100644 src/s2/encoded_string_vector.cc create mode 100644 src/s2/id_set_lexicon.cc create mode 100644 src/s2/mutable_s2shape_index.cc create mode 100644 src/s2/r2rect.cc create mode 100644 src/s2/s1angle.cc create mode 100644 src/s2/s1chord_angle.cc create mode 100644 src/s2/s1interval.cc create mode 100644 src/s2/s2boolean_operation.cc create mode 100644 src/s2/s2builder.cc create mode 100644 src/s2/s2builder_graph.cc create mode 100644 src/s2/s2builderutil_closed_set_normalizer.cc create mode 100644 src/s2/s2builderutil_find_polygon_degeneracies.cc create mode 100644 src/s2/s2builderutil_lax_polygon_layer.cc create mode 100644 src/s2/s2builderutil_s2point_vector_layer.cc create mode 100644 src/s2/s2builderutil_s2polygon_layer.cc create mode 100644 src/s2/s2builderutil_s2polyline_layer.cc create mode 100644 src/s2/s2builderutil_s2polyline_vector_layer.cc create mode 100644 src/s2/s2builderutil_snap_functions.cc create mode 100644 src/s2/s2builderutil_testing.cc create mode 100644 src/s2/s2cap.cc create mode 100644 src/s2/s2cell.cc create mode 100644 src/s2/s2cell_id.cc create mode 100644 src/s2/s2cell_index.cc create mode 100644 src/s2/s2cell_union.cc create mode 100644 src/s2/s2centroids.cc create mode 100644 src/s2/s2closest_cell_query.cc create mode 100644 src/s2/s2closest_edge_query.cc create mode 100644 src/s2/s2closest_point_query.cc create mode 100644 src/s2/s2contains_vertex_query.cc create mode 100644 src/s2/s2convex_hull_query.cc create mode 100644 src/s2/s2coords.cc create mode 100644 src/s2/s2crossing_edge_query.cc create mode 100644 src/s2/s2debug.cc create mode 100644 src/s2/s2earth.cc create mode 100644 src/s2/s2edge_clipping.cc create mode 100644 src/s2/s2edge_crosser.cc create mode 100644 src/s2/s2edge_crossings.cc create mode 100644 src/s2/s2edge_distances.cc create mode 100644 src/s2/s2edge_tessellator.cc create mode 100644 src/s2/s2error.cc create mode 100644 src/s2/s2furthest_edge_query.cc create mode 100644 src/s2/s2latlng.cc create mode 100644 src/s2/s2latlng_rect.cc create mode 100644 src/s2/s2latlng_rect_bounder.cc create mode 100644 src/s2/s2lax_loop_shape.cc create mode 100644 src/s2/s2lax_polygon_shape.cc create mode 100644 src/s2/s2lax_polyline_shape.cc create mode 100644 src/s2/s2loop.cc create mode 100644 src/s2/s2loop_measures.cc create mode 100644 src/s2/s2max_distance_targets.cc create mode 100644 src/s2/s2measures.cc create mode 100644 src/s2/s2metrics.cc create mode 100644 src/s2/s2min_distance_targets.cc create mode 100644 src/s2/s2padded_cell.cc create mode 100644 src/s2/s2point_compression.cc create mode 100644 src/s2/s2point_region.cc create mode 100644 src/s2/s2pointutil.cc create mode 100644 src/s2/s2polygon.cc create mode 100644 src/s2/s2polyline.cc create mode 100644 src/s2/s2polyline_alignment.cc create mode 100644 src/s2/s2polyline_measures.cc create mode 100644 src/s2/s2polyline_simplifier.cc create mode 100644 src/s2/s2predicates.cc create mode 100644 src/s2/s2projections.cc create mode 100644 src/s2/s2r2rect.cc create mode 100644 src/s2/s2region.cc create mode 100644 src/s2/s2region_coverer.cc create mode 100644 src/s2/s2region_intersection.cc create mode 100644 src/s2/s2region_term_indexer.cc create mode 100644 src/s2/s2region_union.cc create mode 100644 src/s2/s2shape_index.cc create mode 100644 src/s2/s2shape_index_buffered_region.cc create mode 100644 src/s2/s2shape_index_measures.cc create mode 100644 src/s2/s2shape_measures.cc create mode 100644 src/s2/s2shapeutil_build_polygon_boundaries.cc create mode 100644 src/s2/s2shapeutil_coding.cc create mode 100644 src/s2/s2shapeutil_contains_brute_force.cc create mode 100644 src/s2/s2shapeutil_edge_iterator.cc create mode 100644 src/s2/s2shapeutil_get_reference_point.cc create mode 100644 src/s2/s2shapeutil_range_iterator.cc create mode 100644 src/s2/s2shapeutil_visit_crossing_edge_pairs.cc create mode 100644 src/s2/s2testing.cc create mode 100644 src/s2/s2text_format.cc create mode 100644 src/s2/s2wedge_relations.cc create mode 100644 src/s2/strings/ostringstream.cc create mode 100644 src/s2/strings/serialize.cc create mode 100644 src/s2/third_party/absl/base/dynamic_annotations.cc create mode 100644 src/s2/third_party/absl/base/internal/raw_logging.cc create mode 100644 src/s2/third_party/absl/base/internal/throw_delegate.cc create mode 100644 src/s2/third_party/absl/numeric/int128.cc create mode 100644 src/s2/third_party/absl/strings/ascii.cc create mode 100644 src/s2/third_party/absl/strings/internal/memutil.cc create mode 100644 src/s2/third_party/absl/strings/match.cc create mode 100644 src/s2/third_party/absl/strings/numbers.cc create mode 100644 src/s2/third_party/absl/strings/str_cat.cc create mode 100644 src/s2/third_party/absl/strings/str_split.cc create mode 100644 src/s2/third_party/absl/strings/string_view.cc create mode 100644 src/s2/third_party/absl/strings/strip.cc create mode 100644 src/s2/util/bits/bit-interleave.cc create mode 100644 src/s2/util/bits/bits.cc create mode 100644 src/s2/util/coding/coder.cc create mode 100644 src/s2/util/coding/varint.cc create mode 100644 src/s2/util/math/exactfloat/exactfloat.cc create mode 100644 src/s2/util/math/mathutil.cc create mode 100644 src/s2/util/units/length-units.cc create mode 100644 src/tests/soname.h create mode 100644 src/wk-geography.h create mode 100644 tests/area.R create mode 100644 tests/area.Rout create mode 100644 tests/testthat.R create mode 100644 tests/testthat/test-data.R create mode 100644 tests/testthat/test-s2-accessors.R create mode 100644 tests/testthat/test-s2-bounds.R create mode 100644 tests/testthat/test-s2-constructors-formatters.R create mode 100644 tests/testthat/test-s2-earth.R create mode 100644 tests/testthat/test-s2-geography.R create mode 100644 tests/testthat/test-s2-lnglat.R create mode 100644 tests/testthat/test-s2-matrix.R create mode 100644 tests/testthat/test-s2-options.R create mode 100644 tests/testthat/test-s2-point.R create mode 100644 tests/testthat/test-s2-predicates.R create mode 100644 tests/testthat/test-s2-transformers.R create mode 100644 tests/testthat/test-s2-xptr.R create mode 100644 tests/testthat/test-utils.R create mode 100644 tests/testthat/test-vctrs.R create mode 100644 tools/version.c create mode 100644 tools/winlibs.R diff --git a/DESCRIPTION b/DESCRIPTION new file mode 100644 index 0000000..5aec611 --- /dev/null +++ b/DESCRIPTION @@ -0,0 +1,44 @@ +Package: s2 +Title: Spherical Geometry Operators Using the S2 Geometry Library +Version: 1.0.4 +Authors@R: c( + person(given = "Dewey", + family = "Dunnington", + role = c("aut"), + email = "dewey@fishandwhistle.net", + comment = c(ORCID = "0000-0002-9415-4582")), + person(given = "Edzer", + family = "Pebesma", + role = c("aut", "cre"), + email = "edzer.pebesma@uni-muenster.de", + comment = c(ORCID = "0000-0001-8049-7069")), + person("Ege", "Rubak", email="rubak@math.aau.dk", role = c("aut")), + person("Jeroen", "Ooms", , "jeroen.ooms@stat.ucla.edu", role = "ctb", comment = "configure script"), + person(family = "Google, Inc.", role = "cph", comment = "Original s2geometry.io source code") + ) +Description: Provides R bindings for Google's s2 library for geometric calculations on + the sphere. High-performance constructors and exporters provide high compatibility + with existing spatial packages, transformers construct new geometries from existing + geometries, predicates provide a means to select geometries based on spatial + relationships, and accessors extract information about geometries. +License: Apache License (== 2.0) +Encoding: UTF-8 +LazyData: true +RoxygenNote: 7.1.1 +LinkingTo: Rcpp, wk +Imports: Rcpp, wk +Suggests: testthat, vctrs +URL: https://r-spatial.github.io/s2/, https://github.com/r-spatial/s2, + https://s2geometry.io/ +BugReports: https://github.com/r-spatial/s2/issues +Depends: R (>= 3.0.0) +NeedsCompilation: yes +Packaged: 2021-01-04 15:35:03 UTC; edzer +Author: Dewey Dunnington [aut] (), + Edzer Pebesma [aut, cre] (), + Ege Rubak [aut], + Jeroen Ooms [ctb] (configure script), + Google, Inc. [cph] (Original s2geometry.io source code) +Maintainer: Edzer Pebesma +Repository: CRAN +Date/Publication: 2021-01-05 05:10:02 UTC diff --git a/MD5 b/MD5 new file mode 100644 index 0000000..d3156d0 --- /dev/null +++ b/MD5 @@ -0,0 +1,395 @@ +b0d140c3a6a007b1192cae3e0569df2f *DESCRIPTION +5129788c48d634be1089286a041d824a *NAMESPACE +458d1fd3761859921eb8b30d0a27fd3b *NEWS.md +49c283041cce525dd99897186dcc8584 *R/RcppExports.R +8567a6b7a3c75cad01a581303546fced *R/data.R +8aa358cca3ffcc922b9bde02ef1accd4 *R/s2-accessors.R +4ba8ec7d16efeadbc21c3ab5ac3dc6a6 *R/s2-bounds.R +a9b85fd1af5d8ffba7f46f9d16b333ee *R/s2-constructors-formatters.R +0968515e318a2c7a7372bddad1be6c23 *R/s2-earth.R +f29b8dcf891e34b8feae519619914151 *R/s2-geography.R +f7370a030a2faf0fb9a79166fc012ea2 *R/s2-lnglat.R +11b87d96773046950186957f2af9478b *R/s2-matrix.R +e10121cec72be69c2500e9121fcc128e *R/s2-options.R +1bab90d590a0e66114c86739ba0d6ce4 *R/s2-package.R +e78c2f5f3bc790e3fa91d3f5e037754e *R/s2-point.R +447d319c0cbec576de0695a518292089 *R/s2-predicates.R +382b5047b50a837dee2795239ec216ad *R/s2-transformers.R +28d0bdc778944f01d0203a6083305b1a *R/s2-xptr.R +4e8bc5586b795db8a2f8e65074ad05c1 *R/utils.R +514ae694f7596f697979c5cbce1fbc37 *R/vctrs.R +474285eb7c0d146036962c8f7248d1bb *R/zzz.R +27f780fb97d6a58b2b6453c28ab740df *README.md +a1c350c18af8b26ad476e0bee45ce1d3 *build/partial.rdb +cc6eebf14a3f516ec74168f3ea416fb2 *cleanup +9401515addc6f00f403443fd0715fcf9 *configure +d41d8cd98f00b204e9800998ecf8427e *configure.win +6d0a8453b0e12b4654d468d1e7248961 *data/s2_data_tbl_cities.rda +b0b89f3499ca649d9a78f77096e4f5da *data/s2_data_tbl_countries.rda +5bbeed937d4c3e766c02ce396f77cefc *data/s2_data_tbl_timezones.rda +afabc65ce7a01abdb14efb1abccd7247 *inst/include/cpp-compat.h +8428235fc1165d0c32375e2e21a686fe *inst/include/s2/_fp_contract_off.h +782cb0deddf3125910ebf4b02a8efc46 *inst/include/s2/base/casts.h +4c10c37f35c3ea32da84e18e427e0a8f *inst/include/s2/base/commandlineflags.h +95d68a4bda8ac1ed1238c06999c7fe8f *inst/include/s2/base/integral_types.h +ab21c7db7743b7fbef680e8edd02c198 *inst/include/s2/base/log_severity.h +23e37fa14dfbbf7e1e232816f351d7cd *inst/include/s2/base/logging.h +84003e3ea7ed2316b94891afd7d425f0 *inst/include/s2/base/mutex.h +2dca5b2433d232fc5fd572920892de77 *inst/include/s2/base/port.h +7217ae2988c45fe3c657a6fbb5a01334 *inst/include/s2/base/spinlock.h +c71fa2b58596fe3acc23b3191fb30c01 *inst/include/s2/base/stringprintf.h +a5325b3b1a8569a91a072858d9961a76 *inst/include/s2/base/strtoint.h +8a23b88128feaefecac82381870b7e1b *inst/include/s2/base/timer.h +5c886186eca3428ebe67594a29a43066 *inst/include/s2/encoded_s2cell_id_vector.h +f20c096d5c4d4272d6160b94321986e8 *inst/include/s2/encoded_s2point_vector.h +8c71134bbac741ab14ad58645c587efd *inst/include/s2/encoded_s2shape_index.h +90dca9b7842ad1910d1de858afad423c *inst/include/s2/encoded_string_vector.h +40708275f82de6dd1d212c57c36ecee8 *inst/include/s2/encoded_uint_vector.h +e7cbe5a6c88b9a286b17adb5e690286f *inst/include/s2/id_set_lexicon.h +d1d7c273710a5a6dccb132f810f2ed53 *inst/include/s2/mutable_s2shape_index.h +a5fd0e84e01c56c79c50f208ae1b08b9 *inst/include/s2/r1interval.h +e363bde392175774fc26dcde1c3b5076 *inst/include/s2/r2.h +4b12844b6a0327fbc6f0488b4fbea0b3 *inst/include/s2/r2rect.h +279bd4aa8ae3c5f5a5b71cd8e4b66c2c *inst/include/s2/s1angle.h +c3c25817e0a471da972a15c3a4ce8da0 *inst/include/s2/s1chord_angle.h +2a46bfae65f4a24dbbc0c8a7df478c4c *inst/include/s2/s1interval.h +99423d6009cb68d7879793f9311e1bb7 *inst/include/s2/s2boolean_operation.h +f0e436fe4992a1c5f451c08e7be373e8 *inst/include/s2/s2builder.h +cc61ae8fff8370c728bf6de7513e06d9 *inst/include/s2/s2builder_graph.h +0558b2bb40025b583974ac1a5d2b5857 *inst/include/s2/s2builder_layer.h +4b17df092dd21d0d5b22499a7a0d8d63 *inst/include/s2/s2builderutil_closed_set_normalizer.h +dc965c407adeb3070db3510de3b1f0bd *inst/include/s2/s2builderutil_find_polygon_degeneracies.h +59390c82ae51ffd8dc8a2154c7f5cc6b *inst/include/s2/s2builderutil_graph_shape.h +66c64baff11d7ed56ac3e7f93fdd5ac0 *inst/include/s2/s2builderutil_lax_polygon_layer.h +40506cccfe04e37e54a5bc8f1bde6023 *inst/include/s2/s2builderutil_s2point_vector_layer.h +cbbba4e593a1ec4c5554b1021939548a *inst/include/s2/s2builderutil_s2polygon_layer.h +9a36a2942ed405fe0b4b9b2e81bf0a65 *inst/include/s2/s2builderutil_s2polyline_layer.h +929a066a7fd622cbc8f1a41b2d579962 *inst/include/s2/s2builderutil_s2polyline_vector_layer.h +14fae38b064b536a50fd99090bf2bb80 *inst/include/s2/s2builderutil_snap_functions.h +464db150b43db1a4a05c4aef25f9fdb1 *inst/include/s2/s2builderutil_testing.h +1aaf20b1794973131d85bbd6d16fc296 *inst/include/s2/s2cap.h +cc050d60fc6b31479ad2cfc444aebc2b *inst/include/s2/s2cell.h +2ee5d8157ce731621c92127411af51dc *inst/include/s2/s2cell_id.h +c967db283c31cf3b04720da4aaf951be *inst/include/s2/s2cell_index.h +ca583789e8fe43d4acea37b55e0f5930 *inst/include/s2/s2cell_union.h +b0e46b1f9b0302bf28993c83b1c29952 *inst/include/s2/s2centroids.h +1022d523b50d2186b166ca68dc0deb11 *inst/include/s2/s2closest_cell_query.h +15e3edaba2c2363568b38435c1ccb49e *inst/include/s2/s2closest_cell_query_base.h +dca82b1156a1a4c8f587ded132c2f253 *inst/include/s2/s2closest_edge_query.h +283c65cbbae272d89e5c311ea02297cd *inst/include/s2/s2closest_edge_query_base.h +0974a6dabc5a7541eebf0e81656e522c *inst/include/s2/s2closest_edge_query_testing.h +e982b798e56156c65fb5ddf919a0520c *inst/include/s2/s2closest_point_query.h +838bd8a8fe4cbc3f4828e024d8dc6bae *inst/include/s2/s2closest_point_query_base.h +c5ac9b7327a1f2eb8c9b8683973bc48c *inst/include/s2/s2contains_point_query.h +9d28d2f3379f7dea949e76b5e82a3ac9 *inst/include/s2/s2contains_vertex_query.h +7c2da76e9c9917194d48939ee919f088 *inst/include/s2/s2convex_hull_query.h +e2a5abdcf611242bdf5cf0edf0eea5ad *inst/include/s2/s2coords.h +28c4af3631469e232aab685be3e33122 *inst/include/s2/s2coords_internal.h +3e4f0adaabe0eca3bc103088214106ad *inst/include/s2/s2crossing_edge_query.h +12e9446c9a552088c70b7b3062c1ba5b *inst/include/s2/s2debug.h +7298228fc7e23751181ad62e211a81b8 *inst/include/s2/s2distance_target.h +b90e02812e7d1afa32d15de3a0245dd8 *inst/include/s2/s2earth.h +5f01c8ad544b54056e6291838925512a *inst/include/s2/s2edge_clipping.h +91b536b7351c85048ac5f4fc8f9c36f3 *inst/include/s2/s2edge_crosser.h +a9ac7f4dd56aff0550689af376c3438f *inst/include/s2/s2edge_crossings.h +482bff39a41ea67b1073b9cfdc11400b *inst/include/s2/s2edge_crossings_internal.h +525ad6e536828fd0f783a532962bde59 *inst/include/s2/s2edge_distances.h +0f223cfa5b4b1153617bd64d47f68212 *inst/include/s2/s2edge_tessellator.h +99195e00ed62fc8127a6de6305730930 *inst/include/s2/s2edge_vector_shape.h +131a6fb00a28c854c2baadce7716e20e *inst/include/s2/s2error.h +89b12540c5e64ede6c1101f9d62da052 *inst/include/s2/s2furthest_edge_query.h +2a746c7606baf6562e51ed195e282afd *inst/include/s2/s2latlng.h +bd642eda609967162d94ac500632e454 *inst/include/s2/s2latlng_rect.h +486a11f20722a978644e99ec990516ad *inst/include/s2/s2latlng_rect_bounder.h +6aaf1e13f42ac06794d6179a45992a12 *inst/include/s2/s2lax_loop_shape.h +fdd99751ecd044e5de5cbebfb4eca06c *inst/include/s2/s2lax_polygon_shape.h +4d4f60c49166c8657258de45884c4087 *inst/include/s2/s2lax_polyline_shape.h +14cced4195983265280bfdbca39b9047 *inst/include/s2/s2loop.h +eef153a4e7bb190f620c250f78ac7c1c *inst/include/s2/s2loop_measures.h +ad2641cab77de9fe057639d5afdf4edd *inst/include/s2/s2max_distance_targets.h +b230afb1b144cfe2dfa5241d0d935cc1 *inst/include/s2/s2measures.h +c974a90f9d2ed8199af139ad33147aa4 *inst/include/s2/s2metrics.h +49d8a47ed9a0f58dd97b2258b1764e77 *inst/include/s2/s2min_distance_targets.h +b2841070cce458abff94905776f74eae *inst/include/s2/s2padded_cell.h +af4bfede404056bb6ecc81a6ec4ed141 *inst/include/s2/s2point.h +07518908a403a0b2a797c207fbf41e86 *inst/include/s2/s2point_compression.h +5fdf216ef50d1d05028f2506491342a5 *inst/include/s2/s2point_index.h +762457ccfc48a099fb96c63eb2db4829 *inst/include/s2/s2point_region.h +660d207e2a9aa481fecafd94e234ea6b *inst/include/s2/s2point_span.h +7d75a6945e15b9c78a713a59bd85f199 *inst/include/s2/s2point_vector_shape.h +6f748c0d5c03c3eaa0fecab91579975a *inst/include/s2/s2pointutil.h +cfec075841d3e7114220ef9e0d69e0c3 *inst/include/s2/s2polygon.h +0a0f0cfcdac7b7dea18ccf795c3c8e11 *inst/include/s2/s2polyline.h +c0f9b77a9439bc0c84d9dfe2dcbcc25b *inst/include/s2/s2polyline_alignment.h +eff6795f7a30bf765249022e2fdbab30 *inst/include/s2/s2polyline_alignment_internal.h +3b78b40b711bc148a7cc8f01f044d9a7 *inst/include/s2/s2polyline_measures.h +a12b87a494ef6e98dd8b19091ebf8cd8 *inst/include/s2/s2polyline_simplifier.h +3e580e8e5db3954a6918420df5d50630 *inst/include/s2/s2predicates.h +e819c0019ab31b8a7772353a762f6439 *inst/include/s2/s2predicates_internal.h +fa7c158fb73fced84c86e73bc40a4215 *inst/include/s2/s2projections.h +eef1eb7446a79b5b6430af8eede7a698 *inst/include/s2/s2r2rect.h +2234c6d0d865cc61ca6959c01e0015e4 *inst/include/s2/s2region.h +64f8f1de545faf4dcafdb206cfca2bf6 *inst/include/s2/s2region_coverer.h +bc10b64ffa44cbe8566d7daf5fb025b8 *inst/include/s2/s2region_intersection.h +24e9c6bee5ce52ebbf1307333d70301a *inst/include/s2/s2region_term_indexer.h +05b971668fa80d8d89579ad964aa7f27 *inst/include/s2/s2region_union.h +9e0666e7c03402dbf71fec6da5aa9244 *inst/include/s2/s2shape.h +5a143a135855c6c2a43d687cedbbc837 *inst/include/s2/s2shape_index.h +2f6f557e792611c362fee453ca16eb88 *inst/include/s2/s2shape_index_buffered_region.h +1caf918a11c8bafc0835861870fbd0ea *inst/include/s2/s2shape_index_measures.h +b095a57fa9ad2adfa3cc31f6b8d6fffd *inst/include/s2/s2shape_index_region.h +ce9d81e0539f9c3a136e07d12c46cb05 *inst/include/s2/s2shape_measures.h +36f49316d02ac4f5c1124d7a3365419f *inst/include/s2/s2shapeutil_build_polygon_boundaries.h +3c7dde9ddf64c467729e08fb30741bbe *inst/include/s2/s2shapeutil_coding.h +f6d89268f04abb12ccd63236d4362060 *inst/include/s2/s2shapeutil_contains_brute_force.h +1344b756712c76ac8c390abdb5a5886e *inst/include/s2/s2shapeutil_count_edges.h +e0937ffaeaa73535cb291409f285f2e3 *inst/include/s2/s2shapeutil_edge_iterator.h +53160e1333206256c06775aceb56ff6e *inst/include/s2/s2shapeutil_get_reference_point.h +d12c9628c73beb0f42bb462060facbe7 *inst/include/s2/s2shapeutil_range_iterator.h +a249fc71604963665d21c311c0e1c391 *inst/include/s2/s2shapeutil_shape_edge.h +bdf516e73992d5a15fdaa074596f8d6f *inst/include/s2/s2shapeutil_shape_edge_id.h +007fda069d8144645da7f2c7462a8359 *inst/include/s2/s2shapeutil_testing.h +f21bfbc04ce2d1d819512176b45954bb *inst/include/s2/s2shapeutil_visit_crossing_edge_pairs.h +d2af245ac0b0cff65e44c8b28a0c3451 *inst/include/s2/s2testing.h +388d47b1e65b685972ca35be834ce2c4 *inst/include/s2/s2text_format.h +3c1f74157144820e8e5008fdc433e018 *inst/include/s2/s2wedge_relations.h +d3ffa54eb4cab5a70d23bee5cbc17b3e *inst/include/s2/sequence_lexicon.h +5660849c05e4728e74114429b9b28339 *inst/include/s2/strings/ostringstream.h +5e58c81561186cabf746091253ece578 *inst/include/s2/strings/serialize.h +4774a2d59a247bb335bacbe5eb6eb265 *inst/include/s2/third_party/absl/algorithm/algorithm.h +c5c22df9e5ec5e04e0085325f30268b7 *inst/include/s2/third_party/absl/base/attributes.h +9055c69eff1250d7b55406f466283b45 *inst/include/s2/third_party/absl/base/casts.h +e153758883f2d0704a42a3791a7092bd *inst/include/s2/third_party/absl/base/config.h +5fced460e821fb0e729790dedee70978 *inst/include/s2/third_party/absl/base/dynamic_annotations.h +b942c8aeb47262065298f7c84599f8ae *inst/include/s2/third_party/absl/base/internal/atomic_hook.h +0132a8836d59bbc8ebbfd499bced5e57 *inst/include/s2/third_party/absl/base/internal/identity.h +cacec291159c34faf2124f02ae587149 *inst/include/s2/third_party/absl/base/internal/inline_variable.h +215c83c3b57dc7299452971b5751111b *inst/include/s2/third_party/absl/base/internal/invoke.h +a1544a26ecf4f13213df38bfa8ca2ec1 *inst/include/s2/third_party/absl/base/internal/raw_logging.h +95a923cf95eb8115790ea3aa39ba4544 *inst/include/s2/third_party/absl/base/internal/throw_delegate.h +2eb0626e04425567d155077fd975f454 *inst/include/s2/third_party/absl/base/internal/unaligned_access.h +c3dcb836940be43411fd4c4890bc649e *inst/include/s2/third_party/absl/base/log_severity.h +ae09d12a126842ad529872c06130bd23 *inst/include/s2/third_party/absl/base/macros.h +2de40013561322141fd61eb7f8e7939f *inst/include/s2/third_party/absl/base/optimization.h +a62aa9b3fa1d55d8e959929984065260 *inst/include/s2/third_party/absl/base/policy_checks.h +4ec15da9fbdf62615835e19927c81c9d *inst/include/s2/third_party/absl/base/port.h +c1eef28bafed8aea62144ee837a81c7d *inst/include/s2/third_party/absl/base/thread_annotations.h +ba3327fbea8fed70386f15a0e898a3fa *inst/include/s2/third_party/absl/container/fixed_array.h +e12a61a76d8ed6380d17d3c6293dfb5d *inst/include/s2/third_party/absl/container/inlined_vector.h +4fa2041669639f60524e2191a528b058 *inst/include/s2/third_party/absl/container/internal/compressed_tuple.h +720e6131f877ba385b4174e4e3ca5a95 *inst/include/s2/third_party/absl/container/internal/container_memory.h +c8d7b706e67864565bc035dfe6735d2c *inst/include/s2/third_party/absl/container/internal/layout.h +c3e6cf276acd1ac325e8d5f5134511c5 *inst/include/s2/third_party/absl/memory/memory.h +cf8a2d3e5aea9659c5cda43962a5bda9 *inst/include/s2/third_party/absl/meta/type_traits.h +a429f3aaa1ed1c847ea9c9ae7530ec0e *inst/include/s2/third_party/absl/numeric/int128.h +95dc4b1604f6514051107ef12c4084cd *inst/include/s2/third_party/absl/numeric/int128_have_intrinsic.inc +0af74de0605ecb52abf0a99f6c4f375c *inst/include/s2/third_party/absl/numeric/int128_no_intrinsic.inc +90d00026063ac43ffbc93066ff6df857 *inst/include/s2/third_party/absl/strings/ascii.h +5261e3adf5c680466c5c8099fb515cec *inst/include/s2/third_party/absl/strings/ascii_ctype.h +a3c35c225cf76eaabcee8b7f24f72a7c *inst/include/s2/third_party/absl/strings/internal/bits.h +e8699c817825346c1d849332fd3ccdb2 *inst/include/s2/third_party/absl/strings/internal/memutil.h +c2f0428da28989afc38bc590bbacb2ef *inst/include/s2/third_party/absl/strings/internal/resize_uninitialized.h +14f2714ff679c7ef2777b7021290c7af *inst/include/s2/third_party/absl/strings/match.h +4f3281e25b414a4b244835e228173c36 *inst/include/s2/third_party/absl/strings/numbers.h +408b2c9f4079600fd721ceb4ad1a4403 *inst/include/s2/third_party/absl/strings/str_cat.h +20d77d9f1d45146178390b640f963653 *inst/include/s2/third_party/absl/strings/str_join.h +af303dc872a7afff5c4b7d9213609ecc *inst/include/s2/third_party/absl/strings/str_split.h +58505d1fe7175e0ec054c0bf8c9e7417 *inst/include/s2/third_party/absl/strings/string_view.h +27833d1d0b3809492956eaab1f767c08 *inst/include/s2/third_party/absl/strings/strip.h +ff057e84f9c7d95441204c08a99b6624 *inst/include/s2/third_party/absl/types/span.h +4b112f693a7fe580bfdcc0294bdaa16d *inst/include/s2/third_party/absl/utility/utility.h +3bfcb45aa9bfa89827d30afba984f79c *inst/include/s2/util/bits/bit-interleave.h +01651f0b0520524dbb4584decd493d3b *inst/include/s2/util/bits/bits.h +5f6a88e3427ce3578a61423ab34608d5 *inst/include/s2/util/coding/coder.h +c4fe67fd8a294e03bfc46ce9fb1134d1 *inst/include/s2/util/coding/nth-derivative.h +2e711fab16d3ec015ecc12d522b8b0ae *inst/include/s2/util/coding/transforms.h +c5e3e09198b1b08e701f3776454f01dd *inst/include/s2/util/coding/varint.h +d02fbefd15c14ec0bd673853a526bfc8 *inst/include/s2/util/endian/endian.h +0d177612b828c957b49d097e94a28b32 *inst/include/s2/util/gtl/btree.h +fb878c4cc124f8cd73ff043b9fe9e278 *inst/include/s2/util/gtl/btree_container.h +52e6fdc3fa81363e043d7e5a35a697ef *inst/include/s2/util/gtl/btree_map.h +81e2de007193adce24cd9d5f5739bf5e *inst/include/s2/util/gtl/btree_set.h +29d3a30325dc78051b3aa1b812fb71c7 *inst/include/s2/util/gtl/compact_array.h +a05aa6118ec536e2715ce0089096d564 *inst/include/s2/util/gtl/container_logging.h +524152483057734236c014aaf39cabe3 *inst/include/s2/util/gtl/dense_hash_set.h +e6d5083ac705a0300e77fe096a7a0589 *inst/include/s2/util/gtl/densehashtable.h +fa56660fc40be26b3dbfc7115c56674e *inst/include/s2/util/gtl/hashtable_common.h +a899a9f61f6eff376a230da0cf6ed16a *inst/include/s2/util/gtl/layout.h +f1dc5e28aa905fbf4af9530f7cf14111 *inst/include/s2/util/gtl/legacy_random_shuffle.h +a36fbccb7e3c064e5a16b4ac1e7842f3 *inst/include/s2/util/hash/mix.h +b0a3631c4d2beb9b19d9e3a0639c0cf0 *inst/include/s2/util/math/exactfloat/exactfloat.h +0c3be461d027e0cccb9c0facb12cd046 *inst/include/s2/util/math/mathutil.h +160830f8d1d1983f1b773f953abff72d *inst/include/s2/util/math/matrix3x3.h +54ea617707ee52e966ce4e475067ec28 *inst/include/s2/util/math/vector.h +5b091051cad1329e1e2b535e40e9c142 *inst/include/s2/util/math/vector3_hash.h +1bdf37d9bef7eba2b40d5baad2403f8d *inst/include/s2/util/units/length-units.h +a5add3e948f775d2f77331e97b5398ea *inst/include/s2/util/units/physical-units.h +400af05643ac08d897c2100a0a68f1aa *inst/include/s2/value_lexicon.h +3c3a7db94dc9033c9c0c6ef7d6d0c8a4 *man/as_s2_geography.Rd +ed01c59b91c1a9c3382d1f2ab67e60cc *man/figures/rc300.png +0d32af4cce70305a4ad68adb26e7c89f *man/s2-package.Rd +0814caa3efd1d23d1a02cd3da15d3424 *man/s2_boundary.Rd +a906d7f9956940ceebe0bd879c14e5f2 *man/s2_bounds_cap.Rd +74e5a897578b3e75ccafbd46bcd3e2fa *man/s2_closest_feature.Rd +d96650f409fa8eb02fe4d5f54d00eb7d *man/s2_contains.Rd +addd614791ada510339317f68202d348 *man/s2_data_tbl_countries.Rd +d7a1ee72a69458a577921e02c2f4142f *man/s2_earth_radius_meters.Rd +b1c82724ddfd755007942e7763d7b333 *man/s2_geog_point.Rd +022dbf15f8934cc4accf0c41a55a4a44 *man/s2_is_collection.Rd +e1a47506a896f0144af3c34265fef2b1 *man/s2_lnglat.Rd +22b3d3bc9001655c786bd6515fe874d2 *man/s2_options.Rd +a86f2581e1af6031167a29956341993c *man/s2_point.Rd +7928b4cf96caa1ee6349d575e7d5899f *src/Makevars.in +c7a379bba69903eac2145a7b5e0b7be1 *src/Makevars.win +294dd54a661879e3713ca07fff5dc459 *src/RcppExports.cpp +5f46d29bc94bcdfc28e2a4df442310de *src/cpp-compat.cpp +fdce8bafee6053b81f1b8c8039b41493 *src/geography-collection.h +8f89404ccd6210e21b6b5b29867597ab *src/geography-operator.h +a7705e137e495ff2a4e380556763c555 *src/geography.h +0365ec85c22784d83cce5b84d71d794a *src/init.cpp +e2fbee45aca698d82ddac432ada8b39a *src/point-geography.h +82b010ba5876d13494164c57f7125a03 *src/polygon-geography.h +025a71734811c66df0767952306ff45b *src/polyline-geography.h +5ad00dddb331ad9ab3528b330c3e9a05 *src/s2-accessors.cpp +40989d3a6148de2a42117013f098d21c *src/s2-bounds.cpp +fb1fff2046ade79c266428478bceb49b *src/s2-constructors-formatters.cpp +bc596d9aaa251dd5884d1537b0630fc6 *src/s2-geography.cpp +2a18a33f6a16832c371549cee3ef1829 *src/s2-lnglat.cpp +27938e376941d899bf9052fcfe51e366 *src/s2-matrix.cpp +3faf84f0e15b9e9807e2c13d7a81a031 *src/s2-options.h +26da724d2fb9ccb3b7579e9a7f49001e *src/s2-point.cpp +980e286c3b8ad05def8cb5729e83a98f *src/s2-predicates.cpp +e66dde63f2c8c100f82291f25712bc9e *src/s2-transformers.cpp +2a3ac9aacf9ff1513a19f70b91902c83 *src/s2-xptr.cpp +5870223619be64e10cd385cd100ba1e0 *src/s2/base/stringprintf.cc +c10c3c7ca58239c0915bacffc70e37e1 *src/s2/base/strtoint.cc +a85315a801220cea6aedb7545bed0675 *src/s2/encoded_s2cell_id_vector.cc +46fc24762b4540e4fca69d7ae755de0c *src/s2/encoded_s2point_vector.cc +ef7ca1699c3646abc615e0fdf400f10d *src/s2/encoded_s2shape_index.cc +2a2a38594d08c617c2b2a277e278e320 *src/s2/encoded_string_vector.cc +788f48e5bbfca22ed1e396d4bd675ad3 *src/s2/id_set_lexicon.cc +e77194370c1950bc155ee61708af57b0 *src/s2/mutable_s2shape_index.cc +da84b9bfc2aeabd4f8ae0f84343623e7 *src/s2/r2rect.cc +e7ca7f23a7e8fe6f707e4169f1aadb77 *src/s2/s1angle.cc +d9387a9af7477f6b82ec73d206cfd8d9 *src/s2/s1chord_angle.cc +34874873bee5edbf9af38cd7692ab3ae *src/s2/s1interval.cc +511d35103ca70d436f998e8a02aac9c5 *src/s2/s2boolean_operation.cc +451752fc8769396106cc1a751942673a *src/s2/s2builder.cc +13695f3a4b75e18becb5d3828e81da65 *src/s2/s2builder_graph.cc +840316e7a7b185fc36824c2fefdce8d3 *src/s2/s2builderutil_closed_set_normalizer.cc +af468682dc5753112e46f2ace3393cb7 *src/s2/s2builderutil_find_polygon_degeneracies.cc +93c788e6753481cf0ac93247a1349b62 *src/s2/s2builderutil_lax_polygon_layer.cc +6c0c3e9f73a2d693d25392a6f053cca9 *src/s2/s2builderutil_s2point_vector_layer.cc +d38e7886a72b3ddceec6fe97cbe020b0 *src/s2/s2builderutil_s2polygon_layer.cc +bc24648fc1ba139430b08df68cc45004 *src/s2/s2builderutil_s2polyline_layer.cc +9ed299b94f9fd05d3b228cbbb77a29e9 *src/s2/s2builderutil_s2polyline_vector_layer.cc +0db1a581191eee0bdbbb3f889994453d *src/s2/s2builderutil_snap_functions.cc +0e7eb31b407e02950751a990c528833d *src/s2/s2builderutil_testing.cc +15661d854ecdbd9b5adb37f4fa38e7fd *src/s2/s2cap.cc +d89508276ed169153d1e80d85989bfd5 *src/s2/s2cell.cc +593d094df40de93980e92961647b8660 *src/s2/s2cell_id.cc +b77c66885dd9ce9decb058448a53bf2b *src/s2/s2cell_index.cc +2df8fa84fabd7e103ecbcf3dddec4ab7 *src/s2/s2cell_union.cc +cf1a07e72197832f2b1302f7b3630f98 *src/s2/s2centroids.cc +247c9902f0b40b738f8636d6436fbdb6 *src/s2/s2closest_cell_query.cc +bed4f6b983774f4c6b4a6596ad46ee08 *src/s2/s2closest_edge_query.cc +09e2f693ad6e491a4d50eb8b5d966840 *src/s2/s2closest_point_query.cc +8cea937d5d1881cdb71d1287f5474cff *src/s2/s2contains_vertex_query.cc +6122ec2910ab45960634d81f2058a9e0 *src/s2/s2convex_hull_query.cc +effdbbf64bb7f235381201657e021ea6 *src/s2/s2coords.cc +48655b45fa96f0da0b234ca68fe4b54d *src/s2/s2crossing_edge_query.cc +cbeeb65a7261dc8430dcf6edc24deb94 *src/s2/s2debug.cc +a863fc668a334819762480cc0646c898 *src/s2/s2earth.cc +d58b020152efbe99f672b8952460d2ce *src/s2/s2edge_clipping.cc +c5fd68f5fab9c30285a9d1995be3ddde *src/s2/s2edge_crosser.cc +69bb6ff8072fe88be08b2e693071ea65 *src/s2/s2edge_crossings.cc +2afc2b3b5d5c5eee69d662c490aeac3a *src/s2/s2edge_distances.cc +75acbcdde0e718a3a990fa63c78c3423 *src/s2/s2edge_tessellator.cc +483c797be9c9eb4b9a9059577e548e7b *src/s2/s2error.cc +fe0c39101c8c58f45b75fc4c36261a82 *src/s2/s2furthest_edge_query.cc +8f0404619c8c69989e81a9eafb8abe68 *src/s2/s2latlng.cc +e42ec23a4fdf8b6aea983db2ca3cc4d9 *src/s2/s2latlng_rect.cc +f8689b6a3eef9053601d310ca6146f5c *src/s2/s2latlng_rect_bounder.cc +6ea59dae602c6e87765068c7c4357baf *src/s2/s2lax_loop_shape.cc +fc760f9c0ff8545929b4a1e0da1e6ff5 *src/s2/s2lax_polygon_shape.cc +56c7b3c6c942d0cffe353b03ee605a8f *src/s2/s2lax_polyline_shape.cc +e9089ad010d3996decf00ad060e2c9b1 *src/s2/s2loop.cc +436911cd7d5a6dcc5fd8b5415c6e0603 *src/s2/s2loop_measures.cc +ca46f698320fb52b1a5a963c3dda9584 *src/s2/s2max_distance_targets.cc +66d7e4a5a3700d4b5a8c7e013fcfc370 *src/s2/s2measures.cc +b70ef8989674552ca3d0e0c9fcb754a8 *src/s2/s2metrics.cc +03adc6de0eef0e8578423e8fadd5542f *src/s2/s2min_distance_targets.cc +94bd23bc709062647f0bdc993dfc7933 *src/s2/s2padded_cell.cc +ebcad838fe84cee7d007143e3cbac687 *src/s2/s2point_compression.cc +7b88d7113b91cd8d5f0c1ad5bbacc7c4 *src/s2/s2point_region.cc +0475a05e50a35ca03b06e084178cd31a *src/s2/s2pointutil.cc +eacacbc76f611ff5f249666746bb414a *src/s2/s2polygon.cc +4a91c95c87427a46f759ca2f469f38b5 *src/s2/s2polyline.cc +52d66d8e55dab56d35a33029e25182ce *src/s2/s2polyline_alignment.cc +c206c2fa52e4a5588b1024f45c63595b *src/s2/s2polyline_measures.cc +eab00b14b7643e320f8044521eaa16e4 *src/s2/s2polyline_simplifier.cc +ff7549a0d6195b34b24867fff4cc6d06 *src/s2/s2predicates.cc +7478e1714d9dcaf520159458d10e383b *src/s2/s2projections.cc +8baa87c45aa11148a5207f367237e753 *src/s2/s2r2rect.cc +57778c7c84ae75e67ed68e76f9026ec0 *src/s2/s2region.cc +cfc92b8d78c68ae15377d9e1c5a8df13 *src/s2/s2region_coverer.cc +f622c31665d97c607e1cb5106c295959 *src/s2/s2region_intersection.cc +b41c960fdbefe867c01ee524e3929d3f *src/s2/s2region_term_indexer.cc +f8232c70a590ed11666c93181c9d7343 *src/s2/s2region_union.cc +25ac091ec0963d3216b86e86a050eae9 *src/s2/s2shape_index.cc +906e1e16bc8aa9f5d4e99651a6cdf0fe *src/s2/s2shape_index_buffered_region.cc +c0543285953743a9605aa3ef63ad6127 *src/s2/s2shape_index_measures.cc +23c94c388142e68594cbf29b677d2bbc *src/s2/s2shape_measures.cc +a71d6a318728f4f4d425a283fe298eb2 *src/s2/s2shapeutil_build_polygon_boundaries.cc +dbe0790cef156dde776484cacc699485 *src/s2/s2shapeutil_coding.cc +afd2720bf07ba0aa5f94dfe9ba0c4d3a *src/s2/s2shapeutil_contains_brute_force.cc +5c5fc095963d0f42ddbb64977d5d267f *src/s2/s2shapeutil_edge_iterator.cc +ae2b2addb5cb94cd24c57c195e1b0b49 *src/s2/s2shapeutil_get_reference_point.cc +6d1353bb32206db05048ee50a073c0e7 *src/s2/s2shapeutil_range_iterator.cc +2d43581ce7e9638ee9d4390016d422df *src/s2/s2shapeutil_visit_crossing_edge_pairs.cc +969daf687171d174fbe727b6727f65bb *src/s2/s2testing.cc +40f4712317f6b98e06a78be740f60409 *src/s2/s2text_format.cc +518f25738bd53f6439d3708f56a85435 *src/s2/s2wedge_relations.cc +9b6952846f960ce7c8f86d425a6cfc53 *src/s2/strings/ostringstream.cc +eca9409a0404788acbef02f2fd4f51df *src/s2/strings/serialize.cc +ed362e76c37bc3b132df67914ff1ae63 *src/s2/third_party/absl/base/dynamic_annotations.cc +1bf91ab480aa123b927f4b3873f3cb82 *src/s2/third_party/absl/base/internal/raw_logging.cc +c894340e8006bfa71425539409d16115 *src/s2/third_party/absl/base/internal/throw_delegate.cc +238a3a6f859b344e23ebf1e8215d2824 *src/s2/third_party/absl/numeric/int128.cc +d87d99e4a3010c3ada6f90dcd0f9610f *src/s2/third_party/absl/strings/ascii.cc +77bb965ed3aca0c14e26b379046729ac *src/s2/third_party/absl/strings/internal/memutil.cc +918e0ac8d6b33177ac95bb9cbddb8ffe *src/s2/third_party/absl/strings/match.cc +07e47a54105f2a19e1955ecbc10f8ba3 *src/s2/third_party/absl/strings/numbers.cc +b2ded99aff2adda60c7936c80e01580e *src/s2/third_party/absl/strings/str_cat.cc +b022ff16e439872f0bb3a608194481c4 *src/s2/third_party/absl/strings/str_split.cc +4877473e8e04e7f4c25a0c7dda833641 *src/s2/third_party/absl/strings/string_view.cc +04a1c7524bf937976acbdd7a63a298b9 *src/s2/third_party/absl/strings/strip.cc +c90e431dac905cc9e596e1b1071b7ea1 *src/s2/util/bits/bit-interleave.cc +7fce87b2c7658b46bea4fd2096c902fb *src/s2/util/bits/bits.cc +c0d70edbf2ac3f698c17d89959e326f9 *src/s2/util/coding/coder.cc +b1348c0fb971b3302725b248a6299581 *src/s2/util/coding/varint.cc +2fc5ca8d2efaf82b72d5120a102e1aa0 *src/s2/util/math/exactfloat/exactfloat.cc +2037118f434c6f41bc8014de2eb18c92 *src/s2/util/math/mathutil.cc +2aba55dd12417d944cd91a2f02b1d946 *src/s2/util/units/length-units.cc +4495750656420f7cd041bf0bf27ec020 *src/tests/soname.h +d105b4c3460bf21c7c7ef886eaaa29d2 *src/wk-geography.h +a9ffa55303a6dcba9c5c9c9d322e2009 *tests/area.R +960ec65d25d1018d2084d81ed3324fdd *tests/area.Rout +6a0d9b8264490c375aab2554285f41ec *tests/testthat.R +2852576d235eb67783d7b1118d8d9800 *tests/testthat/test-data.R +5515aee1bf7a1360c0f1de84a6b58eeb *tests/testthat/test-s2-accessors.R +1047ccf796c487587c03286eb8ad3eb2 *tests/testthat/test-s2-bounds.R +cfb96b2f1b55571dd58adcbeb254950f *tests/testthat/test-s2-constructors-formatters.R +75ad7009cf6227ca8239c31198787956 *tests/testthat/test-s2-earth.R +7a6af524d3f7aadc667753dd5eea7548 *tests/testthat/test-s2-geography.R +adfd5e8008ceeea58ba3ee5e71ca040b *tests/testthat/test-s2-lnglat.R +7b587e0c348fd70e7f1308e33f48aac9 *tests/testthat/test-s2-matrix.R +589616aabb1c291a3984f521274815bf *tests/testthat/test-s2-options.R +9be8d6955daa3c211af562f4f41c639a *tests/testthat/test-s2-point.R +0688d88be5a5f999507d227ee30c99dc *tests/testthat/test-s2-predicates.R +b7505b66cb1b1b254137ebd00c86c225 *tests/testthat/test-s2-transformers.R +e0de43269c8f8eb622ef3aa6c6d6f01a *tests/testthat/test-s2-xptr.R +28f67bf7ece751b0003f0cb923fefa24 *tests/testthat/test-utils.R +960c0d7e6a792c605d49ccfe2ac6a968 *tests/testthat/test-vctrs.R +0ec27c181a66ce5b72bc8c3940e9e00e *tools/version.c +c649ea1343c76b81870be0fa55f6feb3 *tools/winlibs.R diff --git a/NAMESPACE b/NAMESPACE new file mode 100644 index 0000000..19a5329 --- /dev/null +++ b/NAMESPACE @@ -0,0 +1,123 @@ +# Generated by roxygen2: do not edit by hand + +S3method("[",s2_xptr) +S3method("[<-",s2_geography) +S3method("[<-",s2_lnglat) +S3method("[<-",s2_point) +S3method("[[",s2_xptr) +S3method("[[<-",s2_geography) +S3method("[[<-",s2_lnglat) +S3method("[[<-",s2_point) +S3method(as.character,s2_geography) +S3method(as.data.frame,s2_lnglat) +S3method(as.data.frame,s2_point) +S3method(as.matrix,s2_lnglat) +S3method(as.matrix,s2_point) +S3method(as_s2_geography,WKB) +S3method(as_s2_geography,blob) +S3method(as_s2_geography,character) +S3method(as_s2_geography,default) +S3method(as_s2_geography,logical) +S3method(as_s2_geography,s2_geography) +S3method(as_s2_geography,s2_lnglat) +S3method(as_s2_geography,s2_point) +S3method(as_s2_geography,wk_wkb) +S3method(as_s2_geography,wk_wkt) +S3method(as_s2_lnglat,character) +S3method(as_s2_lnglat,matrix) +S3method(as_s2_lnglat,s2_geography) +S3method(as_s2_lnglat,s2_lnglat) +S3method(as_s2_lnglat,s2_point) +S3method(as_s2_lnglat,wk_wkb) +S3method(as_s2_lnglat,wk_wkt) +S3method(as_s2_point,matrix) +S3method(as_s2_point,s2_geography) +S3method(as_s2_point,s2_lnglat) +S3method(as_s2_point,s2_point) +S3method(as_wkb,s2_geography) +S3method(as_wkb,s2_lnglat) +S3method(as_wkt,s2_geography) +S3method(as_wkt,s2_lnglat) +S3method(c,s2_xptr) +S3method(format,s2_geography) +S3method(format,s2_lnglat) +S3method(format,s2_point) +S3method(print,s2_xptr) +S3method(rep,s2_xptr) +S3method(rep_len,s2_xptr) +export(as_s2_geography) +export(as_s2_lnglat) +export(as_s2_point) +export(s2_area) +export(s2_as_binary) +export(s2_as_text) +export(s2_boundary) +export(s2_bounds_cap) +export(s2_bounds_rect) +export(s2_buffer_cells) +export(s2_centroid) +export(s2_centroid_agg) +export(s2_closest_feature) +export(s2_closest_point) +export(s2_contains) +export(s2_contains_matrix) +export(s2_covered_by) +export(s2_covered_by_matrix) +export(s2_covers) +export(s2_covers_matrix) +export(s2_data_cities) +export(s2_data_countries) +export(s2_data_timezones) +export(s2_difference) +export(s2_dimension) +export(s2_disjoint) +export(s2_disjoint_matrix) +export(s2_distance) +export(s2_distance_matrix) +export(s2_dwithin) +export(s2_dwithin_matrix) +export(s2_earth_radius_meters) +export(s2_equals) +export(s2_equals_matrix) +export(s2_farthest_feature) +export(s2_geog_from_text) +export(s2_geog_from_wkb) +export(s2_geog_point) +export(s2_intersection) +export(s2_intersects) +export(s2_intersects_box) +export(s2_intersects_matrix) +export(s2_is_collection) +export(s2_is_empty) +export(s2_length) +export(s2_lnglat) +export(s2_make_line) +export(s2_make_polygon) +export(s2_max_distance) +export(s2_max_distance_matrix) +export(s2_may_intersect_matrix) +export(s2_minimum_clearance_line_between) +export(s2_num_points) +export(s2_options) +export(s2_perimeter) +export(s2_point) +export(s2_rebuild) +export(s2_simplify) +export(s2_snap_distance) +export(s2_snap_identity) +export(s2_snap_level) +export(s2_snap_precision) +export(s2_snap_to_grid) +export(s2_sym_difference) +export(s2_touches) +export(s2_touches_matrix) +export(s2_union) +export(s2_union_agg) +export(s2_within) +export(s2_within_matrix) +export(s2_x) +export(s2_y) +importFrom(Rcpp,sourceCpp) +importFrom(wk,as_wkb) +importFrom(wk,as_wkt) +useDynLib(s2, .registration = TRUE) diff --git a/NEWS.md b/NEWS.md new file mode 100644 index 0000000..8f3f650 --- /dev/null +++ b/NEWS.md @@ -0,0 +1,31 @@ +# s2 1.0.4 + +* Fixed errors that resulted from compilation on clang 12.2 (#88, #89). + +# s2 1.0.3 + +* Fixed CRAN check errors (#80). + +# s2 1.0.2 + +* Fixed CRAN check errors (#71, #75, #72). + +# s2 1.0.1 + +* Added layer creation options to `s2_options()`, which now uses strings + rather than numeric codes to specify boolean operation options, geography + construction options, and builder options (#70). +* Added `s2_rebuild()` and `s2_simplify()`, which wrap the S2 C++ `S2Builder` + class to provide simplification and fixing of invalid geographies (#70). +* The s2 package now builds and passes the CMD check on Solaris (#66, #67). +* Renamed `s2_latlng()` to `s2_lnglat()` to keep axis order consistent + throughout the package (#69). +* Added `s2_bounds_cap()` and `s2_bounds_rect()` to compute bounding areas + using geographic coordinates (@edzer, #63). +* `s2_*_matrix()` predicates now efficiently use indexing to compute the + results of many predicate comparisons (#61). + +# s2 1.0.0 + +This version is a complete rewrite of the former s2 CRAN package, entirely +backwards incompatible with previous versions. diff --git a/R/RcppExports.R b/R/RcppExports.R new file mode 100644 index 0000000..88a62b8 --- /dev/null +++ b/R/RcppExports.R @@ -0,0 +1,263 @@ +# Generated by using Rcpp::compileAttributes() -> do not edit by hand +# Generator token: 10BE3573-1514-4C36-9D1C-5A225CD40393 + +cpp_s2_init <- function() { + invisible(.Call(`_s2_cpp_s2_init`)) +} + +cpp_s2_is_collection <- function(geog) { + .Call(`_s2_cpp_s2_is_collection`, geog) +} + +cpp_s2_dimension <- function(geog) { + .Call(`_s2_cpp_s2_dimension`, geog) +} + +cpp_s2_num_points <- function(geog) { + .Call(`_s2_cpp_s2_num_points`, geog) +} + +cpp_s2_is_empty <- function(geog) { + .Call(`_s2_cpp_s2_is_empty`, geog) +} + +cpp_s2_area <- function(geog) { + .Call(`_s2_cpp_s2_area`, geog) +} + +cpp_s2_length <- function(geog) { + .Call(`_s2_cpp_s2_length`, geog) +} + +cpp_s2_perimeter <- function(geog) { + .Call(`_s2_cpp_s2_perimeter`, geog) +} + +cpp_s2_x <- function(geog) { + .Call(`_s2_cpp_s2_x`, geog) +} + +cpp_s2_y <- function(geog) { + .Call(`_s2_cpp_s2_y`, geog) +} + +cpp_s2_distance <- function(geog1, geog2) { + .Call(`_s2_cpp_s2_distance`, geog1, geog2) +} + +cpp_s2_max_distance <- function(geog1, geog2) { + .Call(`_s2_cpp_s2_max_distance`, geog1, geog2) +} + +cpp_s2_bounds_cap <- function(geog) { + .Call(`_s2_cpp_s2_bounds_cap`, geog) +} + +cpp_s2_bounds_rect <- function(geog) { + .Call(`_s2_cpp_s2_bounds_rect`, geog) +} + +cpp_s2_geog_point <- function(x, y) { + .Call(`_s2_cpp_s2_geog_point`, x, y) +} + +cpp_s2_make_line <- function(x, y, featureId) { + .Call(`_s2_cpp_s2_make_line`, x, y, featureId) +} + +cpp_s2_make_polygon <- function(x, y, featureId, ringId, oriented, check) { + .Call(`_s2_cpp_s2_make_polygon`, x, y, featureId, ringId, oriented, check) +} + +s2_geography_from_wkb <- function(wkb, oriented, check) { + .Call(`_s2_s2_geography_from_wkb`, wkb, oriented, check) +} + +s2_geography_from_wkt <- function(wkt, oriented, check) { + .Call(`_s2_s2_geography_from_wkt`, wkt, oriented, check) +} + +s2_geography_full <- function(x) { + .Call(`_s2_s2_geography_full`, x) +} + +s2_geography_to_wkt <- function(s2_geography, precision, trim) { + .Call(`_s2_s2_geography_to_wkt`, s2_geography, precision, trim) +} + +s2_geography_to_wkb <- function(s2_geography, endian) { + .Call(`_s2_s2_geography_to_wkb`, s2_geography, endian) +} + +s2_geography_format <- function(s2_geography, maxCoords, precision, trim) { + .Call(`_s2_s2_geography_format`, s2_geography, maxCoords, precision, trim) +} + +s2_lnglat_from_numeric <- function(lng, lat) { + .Call(`_s2_s2_lnglat_from_numeric`, lng, lat) +} + +s2_lnglat_from_s2_point <- function(s2_point) { + .Call(`_s2_s2_lnglat_from_s2_point`, s2_point) +} + +data_frame_from_s2_lnglat <- function(xptr) { + .Call(`_s2_data_frame_from_s2_lnglat`, xptr) +} + +cpp_s2_closest_feature <- function(geog1, geog2) { + .Call(`_s2_cpp_s2_closest_feature`, geog1, geog2) +} + +cpp_s2_farthest_feature <- function(geog1, geog2) { + .Call(`_s2_cpp_s2_farthest_feature`, geog1, geog2) +} + +cpp_s2_may_intersect_matrix <- function(geog1, geog2, maxEdgesPerCell, maxFeatureCells, s2options) { + .Call(`_s2_cpp_s2_may_intersect_matrix`, geog1, geog2, maxEdgesPerCell, maxFeatureCells, s2options) +} + +cpp_s2_contains_matrix <- function(geog1, geog2, s2options) { + .Call(`_s2_cpp_s2_contains_matrix`, geog1, geog2, s2options) +} + +cpp_s2_within_matrix <- function(geog1, geog2, s2options) { + .Call(`_s2_cpp_s2_within_matrix`, geog1, geog2, s2options) +} + +cpp_s2_intersects_matrix <- function(geog1, geog2, s2options) { + .Call(`_s2_cpp_s2_intersects_matrix`, geog1, geog2, s2options) +} + +cpp_s2_equals_matrix <- function(geog1, geog2, s2options) { + .Call(`_s2_cpp_s2_equals_matrix`, geog1, geog2, s2options) +} + +cpp_s2_touches_matrix <- function(geog1, geog2, s2options) { + .Call(`_s2_cpp_s2_touches_matrix`, geog1, geog2, s2options) +} + +cpp_s2_dwithin_matrix <- function(geog1, geog2, distance) { + .Call(`_s2_cpp_s2_dwithin_matrix`, geog1, geog2, distance) +} + +cpp_s2_distance_matrix <- function(geog1, geog2) { + .Call(`_s2_cpp_s2_distance_matrix`, geog1, geog2) +} + +cpp_s2_max_distance_matrix <- function(geog1, geog2) { + .Call(`_s2_cpp_s2_max_distance_matrix`, geog1, geog2) +} + +cpp_s2_contains_matrix_brute_force <- function(geog1, geog2, s2options) { + .Call(`_s2_cpp_s2_contains_matrix_brute_force`, geog1, geog2, s2options) +} + +cpp_s2_within_matrix_brute_force <- function(geog1, geog2, s2options) { + .Call(`_s2_cpp_s2_within_matrix_brute_force`, geog1, geog2, s2options) +} + +cpp_s2_intersects_matrix_brute_force <- function(geog1, geog2, s2options) { + .Call(`_s2_cpp_s2_intersects_matrix_brute_force`, geog1, geog2, s2options) +} + +cpp_s2_disjoint_matrix_brute_force <- function(geog1, geog2, s2options) { + .Call(`_s2_cpp_s2_disjoint_matrix_brute_force`, geog1, geog2, s2options) +} + +cpp_s2_equals_matrix_brute_force <- function(geog1, geog2, s2options) { + .Call(`_s2_cpp_s2_equals_matrix_brute_force`, geog1, geog2, s2options) +} + +s2_point_from_numeric <- function(x, y, z) { + .Call(`_s2_s2_point_from_numeric`, x, y, z) +} + +s2_point_from_s2_lnglat <- function(s2_lnglat) { + .Call(`_s2_s2_point_from_s2_lnglat`, s2_lnglat) +} + +data_frame_from_s2_point <- function(s2_point) { + .Call(`_s2_data_frame_from_s2_point`, s2_point) +} + +cpp_s2_intersects <- function(geog1, geog2, s2options) { + .Call(`_s2_cpp_s2_intersects`, geog1, geog2, s2options) +} + +cpp_s2_equals <- function(geog1, geog2, s2options) { + .Call(`_s2_cpp_s2_equals`, geog1, geog2, s2options) +} + +cpp_s2_contains <- function(geog1, geog2, s2options) { + .Call(`_s2_cpp_s2_contains`, geog1, geog2, s2options) +} + +cpp_s2_touches <- function(geog1, geog2, s2options) { + .Call(`_s2_cpp_s2_touches`, geog1, geog2, s2options) +} + +cpp_s2_dwithin <- function(geog1, geog2, distance) { + .Call(`_s2_cpp_s2_dwithin`, geog1, geog2, distance) +} + +cpp_s2_intersects_box <- function(geog, lng1, lat1, lng2, lat2, detail, s2options) { + .Call(`_s2_cpp_s2_intersects_box`, geog, lng1, lat1, lng2, lat2, detail, s2options) +} + +cpp_s2_intersection <- function(geog1, geog2, s2options) { + .Call(`_s2_cpp_s2_intersection`, geog1, geog2, s2options) +} + +cpp_s2_union <- function(geog1, geog2, s2options) { + .Call(`_s2_cpp_s2_union`, geog1, geog2, s2options) +} + +cpp_s2_difference <- function(geog1, geog2, s2options) { + .Call(`_s2_cpp_s2_difference`, geog1, geog2, s2options) +} + +cpp_s2_sym_difference <- function(geog1, geog2, s2options) { + .Call(`_s2_cpp_s2_sym_difference`, geog1, geog2, s2options) +} + +cpp_s2_union_agg <- function(geog, s2options, naRm) { + .Call(`_s2_cpp_s2_union_agg`, geog, s2options, naRm) +} + +cpp_s2_centroid_agg <- function(geog, naRm) { + .Call(`_s2_cpp_s2_centroid_agg`, geog, naRm) +} + +cpp_s2_closest_point <- function(geog1, geog2) { + .Call(`_s2_cpp_s2_closest_point`, geog1, geog2) +} + +cpp_s2_minimum_clearance_line_between <- function(geog1, geog2) { + .Call(`_s2_cpp_s2_minimum_clearance_line_between`, geog1, geog2) +} + +cpp_s2_centroid <- function(geog) { + .Call(`_s2_cpp_s2_centroid`, geog) +} + +cpp_s2_boundary <- function(geog) { + .Call(`_s2_cpp_s2_boundary`, geog) +} + +cpp_s2_rebuild <- function(geog, s2options) { + .Call(`_s2_cpp_s2_rebuild`, geog, s2options) +} + +cpp_s2_buffer_cells <- function(geog, distance, maxCells, minLevel) { + .Call(`_s2_cpp_s2_buffer_cells`, geog, distance, maxCells, minLevel) +} + +s2_xptr_test <- function(size) { + .Call(`_s2_s2_xptr_test`, size) +} + +s2_xptr_test_op <- function(s2_xptr_test) { + invisible(.Call(`_s2_s2_xptr_test_op`, s2_xptr_test)) +} + diff --git a/R/data.R b/R/data.R new file mode 100644 index 0000000..80afa35 --- /dev/null +++ b/R/data.R @@ -0,0 +1,72 @@ + +#' Low-resolution world boundaries, timezones, and cities +#' +#' Well-known binary versions of the [Natural Earth](https://www.naturalearthdata.com/) +#' low-resolution world boundaries and timezone boundaries. +#' +#' @param name The name of a country, continent, city, or `NULL` +#' for all features. +#' @param utc_offset_min,utc_offset_max Minimum and/or maximum timezone +#' offsets. +#' +#' @format A data.frame with columns `name` (character), and +#' `geometry` (wk_wkb) +#' @source [Natural Earth Data](https://www.naturalearthdata.com/) +#' @examples +#' head(s2_data_countries()) +#' s2_data_countries("Germany") +#' s2_data_countries("Europe") +#' +#' head(s2_data_timezones()) +#' s2_data_timezones(-4) +#' +#' head(s2_data_cities()) +#' s2_data_cities("Cairo") +#' +"s2_data_tbl_countries" + +#' @rdname s2_data_tbl_countries +"s2_data_tbl_timezones" + +#' @rdname s2_data_tbl_countries +"s2_data_tbl_cities" + +#' @rdname s2_data_tbl_countries +#' @export +s2_data_countries <- function(name = NULL) { + df <- s2::s2_data_tbl_countries + if (is.null(name)) { + wkb <- df$geometry + } else { + wkb <- structure(df$geometry[(df$name %in% name) | (df$continent %in% name)], class = "wk_wkb") + } + + as_s2_geography(wkb) +} + +#' @rdname s2_data_tbl_countries +#' @export +s2_data_timezones <- function(utc_offset_min = NULL, utc_offset_max = utc_offset_min) { + df <- s2::s2_data_tbl_timezones + if (is.null(utc_offset_min)) { + wkb <- df$geometry + } else { + matches <- (df$utc_offset >= utc_offset_min) & (df$utc_offset <= utc_offset_max) + wkb <- structure(df$geometry[matches], class = "wk_wkb") + } + + as_s2_geography(wkb) +} + +#' @rdname s2_data_tbl_countries +#' @export +s2_data_cities <- function(name = NULL) { + df <- s2::s2_data_tbl_cities + if (is.null(name)) { + wkb <- df$geometry + } else { + wkb <- structure(df$geometry[(df$name %in% name)], class = "wk_wkb") + } + + as_s2_geography(wkb) +} diff --git a/R/s2-accessors.R b/R/s2-accessors.R new file mode 100644 index 0000000..c987f7a --- /dev/null +++ b/R/s2-accessors.R @@ -0,0 +1,136 @@ + +#' S2 Geography Accessors +#' +#' Accessors extract information about [geography vectors][as_s2_geography]. +#' +#' @param x,y [geography vectors][as_s2_geography]. These inputs +#' are passed to [as_s2_geography()], so you can pass other objects +#' (e.g., character vectors of well-known text) directly. +#' @param radius Radius of the earth. Defaults to the average radius of +#' the earth in meters as defined by [s2_earth_radius_meters()]. +#' +#' @export +#' +#' @seealso +#' BigQuery's geography function reference: +#' +#' - [ST_ISCOLLECTION](https://cloud.google.com/bigquery/docs/reference/standard-sql/geography_functions#st_iscollection) +#' - [ST_DIMENSION](https://cloud.google.com/bigquery/docs/reference/standard-sql/geography_functions#st_dimension) +#' - [ST_NUMPOINTS](https://cloud.google.com/bigquery/docs/reference/standard-sql/geography_functions#st_numpoints) +#' - [ST_ISEMPTY](https://cloud.google.com/bigquery/docs/reference/standard-sql/geography_functions#st_isempty) +#' - [ST_AREA](https://cloud.google.com/bigquery/docs/reference/standard-sql/geography_functions#st_area) +#' - [ST_LENGTH](https://cloud.google.com/bigquery/docs/reference/standard-sql/geography_functions#st_length) +#' - [ST_PERIMETER](https://cloud.google.com/bigquery/docs/reference/standard-sql/geography_functions#st_perimeter) +#' - [ST_X](https://cloud.google.com/bigquery/docs/reference/standard-sql/geography_functions#st_x) +#' - [ST_Y](https://cloud.google.com/bigquery/docs/reference/standard-sql/geography_functions#st_y) +#' - [ST_DISTANCE](https://cloud.google.com/bigquery/docs/reference/standard-sql/geography_functions#st_distance) +#' - [ST_MAXDISTANCE](https://cloud.google.com/bigquery/docs/reference/standard-sql/geography_functions#st_maxdistance) +#' +#' @examples +#' # s2_is_collection() tests for multiple geometries in one feature +#' s2_is_collection(c("POINT (-64 45)", "MULTIPOINT ((-64 45), (8 72))")) +#' +#' # s2_dimension() returns 0 for point, 1 for line, 2 for polygon +#' s2_dimension( +#' c( +#' "GEOMETRYCOLLECTION EMPTY", +#' "POINT (-64 45)", +#' "LINESTRING (-64 45, 8 72)", +#' "POLYGON ((0 0, 0 10, 10 10, 10 0, 0 0))", +#' "GEOMETRYCOLLECTION (POINT (-64 45), LINESTRING (-64 45, 8 72))" +#' ) +#' ) +#' +#' # s2_num_points() counts points +#' s2_num_points(c("POINT (-64 45)", "LINESTRING (-64 45, 8 72)")) +#' +#' # s2_is_empty tests for emptiness +#' s2_is_empty(c("POINT (-64 45)", "POINT EMPTY")) +#' +#' # calculate area, length, and perimeter +#' s2_area("POLYGON ((0 0, 0 10, 10 10, 10 0, 0 0))") +#' s2_perimeter("POLYGON ((0 0, 0 10, 10 10, 10 0, 0 0))") +#' s2_length(s2_boundary("POLYGON ((0 0, 0 10, 10 10, 10 0, 0 0))")) +#' +#' # extract x and y coordinates from points +#' s2_x(c("POINT (-64 45)", "POINT EMPTY")) +#' s2_y(c("POINT (-64 45)", "POINT EMPTY")) +#' +#' # calculate minimum and maximum distance between two geometries +#' s2_distance( +#' "POLYGON ((0 0, 0 10, 10 10, 10 0, 0 0))", +#' "POINT (-64 45)" +#' ) +#' s2_max_distance( +#' "POLYGON ((0 0, 0 10, 10 10, 10 0, 0 0))", +#' "POINT (-64 45)" +#' ) +#' +s2_is_collection <- function(x) { + cpp_s2_is_collection(as_s2_geography(x)) +} + +#' @rdname s2_is_collection +#' @export +s2_dimension <- function(x) { + cpp_s2_dimension(as_s2_geography(x)) +} + +#' @rdname s2_is_collection +#' @export +s2_num_points <- function(x) { + cpp_s2_num_points(as_s2_geography(x)) +} + +#' @rdname s2_is_collection +#' @export +s2_is_empty <- function(x) { + cpp_s2_is_empty(as_s2_geography(x)) +} + +#' @rdname s2_is_collection +#' @export +s2_area <- function(x, radius = s2_earth_radius_meters()) { + recycled <- recycle_common(as_s2_geography(x), radius) + cpp_s2_area(recycled[[1]]) * radius ^ 2 +} + +#' @rdname s2_is_collection +#' @export +s2_length <- function(x, radius = s2_earth_radius_meters()) { + recycled <- recycle_common(as_s2_geography(x), radius) + cpp_s2_length(recycled[[1]]) * radius +} + +#' @rdname s2_is_collection +#' @export +s2_perimeter <- function(x, radius = s2_earth_radius_meters()) { + recycled <- recycle_common(as_s2_geography(x), radius) + cpp_s2_perimeter(recycled[[1]]) * radius +} + +#' @rdname s2_is_collection +#' @export +s2_x <- function(x) { + cpp_s2_x(as_s2_geography(x)) +} + +#' @rdname s2_is_collection +#' @export +s2_y <- function(x) { + cpp_s2_y(as_s2_geography(x)) +} + +#' @rdname s2_is_collection +#' @export +s2_distance <- function(x, y, radius = s2_earth_radius_meters()) { + recycled <- recycle_common(as_s2_geography(x), as_s2_geography(y), radius) + cpp_s2_distance(recycled[[1]], recycled[[2]]) * radius +} + +#' @rdname s2_is_collection +#' @export +s2_max_distance <- function(x, y, radius = s2_earth_radius_meters()) { + recycled <- recycle_common(as_s2_geography(x), as_s2_geography(y), radius) + cpp_s2_max_distance(recycled[[1]], recycled[[2]]) * radius +} diff --git a/R/s2-bounds.R b/R/s2-bounds.R new file mode 100644 index 0000000..6c4f792 --- /dev/null +++ b/R/s2-bounds.R @@ -0,0 +1,35 @@ + +#' Compute feature-wise and aggregate bounds +#' +#' [s2_bounds_rect()] returns a bounding latitude-longitude +#' rectangle that contains the region; [s2_bounds_cap()] returns a bounding circle +#' represented by a centre point (lat, lng) and an angle. The bound may not be tight +#' for points, polylines and geometry collections. The rectangle returned may depend on +#' the order of points or polylines. `lng_lo` values larger than `lng_hi` indicate +#' regions that span the antimeridian, see the Fiji example. +#' +#' @inheritParams s2_is_collection +#' @export +#' @return Both functions return a `data.frame`: +#' +#' - [s2_bounds_rect()]: Columns `minlng`, `minlat`, `maxlng`, `maxlat` (degrees) +#' - [s2_bounds_cap()]: Columns `lng`, `lat`, `angle` (degrees) +#' +#' @examples +#' s2_bounds_cap(s2_data_countries("Antarctica")) +#' s2_bounds_cap(s2_data_countries("Netherlands")) +#' s2_bounds_cap(s2_data_countries("Fiji")) +#' +#' s2_bounds_rect(s2_data_countries("Antarctica")) +#' s2_bounds_rect(s2_data_countries("Netherlands")) +#' s2_bounds_rect(s2_data_countries("Fiji")) +#' +s2_bounds_cap <- function(x) { + cpp_s2_bounds_cap(as_s2_geography(x)) +} + +#' @rdname s2_bounds_cap +#' @export +s2_bounds_rect <- function(x) { + cpp_s2_bounds_rect(as_s2_geography(x)) +} diff --git a/R/s2-constructors-formatters.R b/R/s2-constructors-formatters.R new file mode 100644 index 0000000..46c1496 --- /dev/null +++ b/R/s2-constructors-formatters.R @@ -0,0 +1,139 @@ + +#' Create and Format Geography Vectors +#' +#' These functions create and export [geography vectors][as_s2_geography]. +#' Unlike the BigQuery geography constructors, these functions do not sanitize +#' invalid or redundant input using [s2_union()]. Note that when creating polygons +#' using [s2_make_polygon()], rings can be open or closed. +#' +#' @inheritParams s2_is_collection +#' @inheritParams as_s2_geography +#' @param precision The number of significant digits to export when +#' writing well-known text. If `trim = FALSE`, the number of +#' digits after the decimal place. +#' @param trim Should trailing zeroes be included after the decimal place? +#' @param endian The endian-ness of the well-known binary. See [wk::wkb_translate_wkb()]. +#' @param longitude,latitude Vectors of latitude and longitude +#' @param wkt_string Well-known text +#' @param wkb_bytes A `list()` of `raw()` +#' @param feature_id,ring_id Vectors for which a change in +#' sequential values indicates a new feature or ring. Use [factor()] +#' to convert from a character vector. +#' +#' @export +#' +#' @seealso +#' See [as_s2_geography()] for other ways to construct geography vectors. +#' +#' BigQuery's geography function reference: +#' +#' - [ST_GEOGPOINT](https://cloud.google.com/bigquery/docs/reference/standard-sql/geography_functions#st_geogpoint) +#' - [ST_MAKELINE](https://cloud.google.com/bigquery/docs/reference/standard-sql/geography_functions#st_makeline) +#' - [ST_MAKEPOLYGON](https://cloud.google.com/bigquery/docs/reference/standard-sql/geography_functions#st_makepolygon) +#' - [ST_GEOGFROMTEXT](https://cloud.google.com/bigquery/docs/reference/standard-sql/geography_functions#st_geogfromtext) +#' - [ST_GEOGFROMWKB](https://cloud.google.com/bigquery/docs/reference/standard-sql/geography_functions#st_geogfromwkb) +#' - [ST_ASTEXT](https://cloud.google.com/bigquery/docs/reference/standard-sql/geography_functions#st_astext) +#' - [ST_ASBINARY](https://cloud.google.com/bigquery/docs/reference/standard-sql/geography_functions#st_asbinary) +#' +#' @examples +#' # create point geographies using coordinate values: +#' s2_geog_point(-64, 45) +#' +#' # create line geographies using coordinate values: +#' s2_make_line(c(-64, 8), c(45, 71)) +#' +#' # optionally, separate features using feature_id: +#' s2_make_line( +#' c(-64, 8, -27, -27), c(45, 71, 0, 45), +#' feature_id = c(1, 1, 2, 2) +#' ) +#' +#' # create polygon geographies using coordinate values: +#' # (rings can be open or closed) +#' s2_make_polygon(c(-45, 8, 0), c(64, 71, 90)) +#' +#' # optionally, separate rings and/or features using +#' # ring_id and/or feature_id +#' s2_make_polygon( +#' c(20, 10, 10, 30, 45, 30, 20, 20, 40, 20, 45), +#' c(35, 30, 10, 5, 20, 20, 15, 25, 40, 45, 30), +#' feature_id = c(rep(1, 8), rep(2, 3)), +#' ring_id = c(1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1) +#' ) +#' +#' # import and export well-known text +#' (geog <- s2_geog_from_text("POINT (-64 45)")) +#' s2_as_text(geog) +#' +#' # import and export well-known binary +#' (geog <- s2_geog_from_wkb(wk::as_wkb("POINT (-64 45)"))) +#' s2_as_binary(geog) +#' +s2_geog_point <- function(longitude, latitude) { + recycled <- recycle_common(longitude, latitude) + new_s2_xptr(cpp_s2_geog_point(recycled[[1]], recycled[[2]]), "s2_geography") +} + +#' @rdname s2_geog_point +#' @export +s2_make_line <- function(longitude, latitude, feature_id = 1L) { + recycled <- recycle_common(longitude, latitude, feature_id) + new_s2_xptr(cpp_s2_make_line(recycled[[1]], recycled[[2]], featureId = recycled[[3]]), "s2_geography") +} + +#' @rdname s2_geog_point +#' @export +s2_make_polygon <- function(longitude, latitude, feature_id = 1L, ring_id = 1L, + oriented = FALSE, check = TRUE) { + recycled <- recycle_common(longitude, latitude, feature_id, ring_id) + new_s2_xptr( + cpp_s2_make_polygon( + recycled[[1]], recycled[[2]], + featureId = recycled[[3]], + ringId = recycled[[4]], + oriented = oriented, + check = check + ), + "s2_geography" + ) +} + +#' @rdname s2_geog_point +#' @export +s2_geog_from_text <- function(wkt_string, oriented = FALSE, check = TRUE) { + wk::validate_wk_wkt(wkt_string) + new_s2_xptr( + s2_geography_from_wkt( + wkt_string, + oriented = oriented, + check = check + ), + "s2_geography" + ) +} + +#' @rdname s2_geog_point +#' @export +s2_geog_from_wkb <- function(wkb_bytes, oriented = FALSE, check = TRUE) { + wk::validate_wk_wkb(wkb_bytes) + new_s2_xptr( + s2_geography_from_wkb( + wkb_bytes, + oriented = oriented, + check = check + ), + "s2_geography" + ) +} + +#' @rdname s2_geog_point +#' @export +s2_as_text <- function(x, precision = 16, trim = TRUE) { + s2_geography_to_wkt(as_s2_geography(x), precision = precision, trim = trim) +} + +#' @rdname s2_geog_point +#' @export +s2_as_binary <- function(x, endian = wk::wk_platform_endian()) { + structure(s2_geography_to_wkb(as_s2_geography(x), endian = endian), class = "blob") +} diff --git a/R/s2-earth.R b/R/s2-earth.R new file mode 100644 index 0000000..4814130 --- /dev/null +++ b/R/s2-earth.R @@ -0,0 +1,23 @@ + +#' Earth Constants +#' +#' According to Yoder (1995), the radius of the earth is +#' 6371.01 km. These functions are used to set the +#' default radis for functions that return a distance +#' or accept a distance as input +#' (e.g., [s2_distance()] and [s2_dwithin()]). +#' +#' @export +#' +#' @references +#' Yoder, C.F. 1995. "Astrometric and Geodetic Properties of Earth and the +#' Solar System" in Global Earth Physics, A Handbook of Physical Constants, +#' AGU Reference Shelf 1, American Geophysical Union, Table 2. +#' \doi{10.1029/RF001p0001} +#' +#' @examples +#' s2_earth_radius_meters() +#' +s2_earth_radius_meters <- function() { + 6371.01 * 1000 +} diff --git a/R/s2-geography.R b/R/s2-geography.R new file mode 100644 index 0000000..6f39d44 --- /dev/null +++ b/R/s2-geography.R @@ -0,0 +1,151 @@ + +#' Create an S2 Geography Vector +#' +#' Geography vectors are arrays of points, lines, polygons, and/or collections +#' of these. Geography vectors assume coordinates are longitude and latitude +#' on a perfect sphere. +#' +#' The coercion function [as_s2_geography()] is used to wrap the input +#' of most functions in the s2 package so that you can use other objects with +#' an unambiguious interpretation as a geography vector. Geography vectors +#' have a minimal [vctrs][vctrs::vctrs-package] implementation, so you can +#' use these objects in tibble, dplyr, and other packages that use the vctrs +#' framework. +#' +#' @param x An object that can be converted to an s2_geography vector +#' @param oriented TRUE if polygon ring directions are known to be correct +#' (i.e., exterior rings are defined counter clockwise and interior +#' rings are defined clockwise). +#' @param check Use `check = FALSE` to skip error on invalid geometries +#' @param ... Unused +#' +#' @return An object with class s2_geography +#' @export +#' +#' @seealso +#' [s2_geog_from_wkb()], [s2_geog_from_text()], [s2_geog_point()], +#' [s2_make_line()], [s2_make_polygon()] for other ways to +#' create geography vectors, and [s2_as_binary()] and [s2_as_text()] +#' for other ways to export them. +#' +as_s2_geography <- function(x, ...) { + UseMethod("as_s2_geography") +} + +#' @rdname as_s2_geography +#' @export +as_s2_geography.default <- function(x, ...) { + as_s2_geography(wk::as_wkb(x)) +} + +#' @rdname as_s2_geography +#' @export +as_s2_geography.s2_geography <- function(x, ...) { + x +} + +#' @rdname as_s2_geography +#' @export +as_s2_geography.s2_lnglat <- function(x, ...) { + df <- data_frame_from_s2_lnglat(x) + new_s2_xptr(cpp_s2_geog_point(df[[1]], df[[2]]), "s2_geography") +} + +#' @rdname as_s2_geography +#' @export +as_s2_geography.s2_point <- function(x, ...) { + as_s2_geography(as_s2_lnglat(x)) +} + +#' @rdname as_s2_geography +#' @export +as_s2_geography.wk_wkb <- function(x, ..., oriented = FALSE, check = TRUE) { + new_s2_xptr( + s2_geography_from_wkb(x, oriented = oriented, check = check), + "s2_geography" + ) +} + +#' @rdname as_s2_geography +#' @export +as_s2_geography.WKB <- function(x, ..., oriented = FALSE, check = TRUE) { + new_s2_xptr( + s2_geography_from_wkb(x, oriented = oriented, check = check), + "s2_geography" + ) +} + +#' @rdname as_s2_geography +#' @export +as_s2_geography.blob <- function(x, ..., oriented = FALSE, check = TRUE) { + new_s2_xptr( + s2_geography_from_wkb(x, oriented = oriented, check = check), + "s2_geography" + ) +} + +#' @rdname as_s2_geography +#' @export +as_s2_geography.wk_wkt <- function(x, ..., oriented = FALSE, check = TRUE) { + new_s2_xptr( + s2_geography_from_wkt(x, oriented = oriented, check = check), + "s2_geography" + ) +} + +#' @rdname as_s2_geography +#' @export +as_s2_geography.character <- function(x, ..., oriented = FALSE, check = TRUE) { + new_s2_xptr( + s2_geography_from_wkt(x, oriented = oriented, check = check), + "s2_geography" + ) +} + +#' @rdname as_s2_geography +#' @export +as_s2_geography.logical <- function(x, ...) { + stopifnot(isTRUE(x)) + new_s2_xptr(s2_geography_full(TRUE), "s2_geography") +} + +#' @importFrom wk as_wkb +#' @rdname as_s2_geography +#' @export +as_wkb.s2_geography <- function(x, ...) { + wk::new_wk_wkb(s2_geography_to_wkb(x, wk::wk_platform_endian())) +} + +#' @importFrom wk as_wkt +#' @rdname as_s2_geography +#' @export +as_wkt.s2_geography <- function(x, ...) { + wk::new_wk_wkt(s2_geography_to_wkt(x, precision = 16, trim = TRUE)) +} + + +#' @export +`[<-.s2_geography` <- function(x, i, value) { + x <- unclass(x) + x[i] <- as_s2_geography(value) + new_s2_xptr(x, "s2_geography") +} + +#' @export +`[[<-.s2_geography` <- function(x, i, value) { + x <- unclass(x) + x[i] <- as_s2_geography(value) + new_s2_xptr(x, "s2_geography") +} + +#' @export +format.s2_geography <- function(x, ..., max_coords = 5, precision = 9, trim = TRUE) { + paste0("<", s2_geography_format(x, max_coords, precision, trim), ">") +} + +# this is what gets called by the RStudio viewer, for which +# format() is best suited (s2_as_text() is more explicit for WKT output) +#' @export +as.character.s2_geography <- function(x, ..., max_coords = 5, precision = 9, trim = TRUE) { + format(x, ..., max_coords = max_coords, precision = precision, trim = trim) +} diff --git a/R/s2-lnglat.R b/R/s2-lnglat.R new file mode 100644 index 0000000..59ceaad --- /dev/null +++ b/R/s2-lnglat.R @@ -0,0 +1,113 @@ + +#' Create an S2 LngLat Vector +#' +#' This class represents a latitude and longitude on the Earth's surface. +#' Most calculations in S2 convert this to a [as_s2_point()], which is a +#' unit vector representation of this value. +#' +#' @param lat,lng Vectors of latitude and longitude values in degrees. +#' @param x A [s2_lnglat()] vector or an object that can be coerced to one. +#' @param ... Unused +#' +#' @return An object with class s2_lnglat +#' @export +#' +#' @examples +#' s2_lnglat(45, -64) # Halifax, Nova Scotia! +#' as.data.frame(s2_lnglat(45, -64)) +#' +s2_lnglat <- function(lng, lat) { + recycled <- recycle_common(as.double(lng), as.double(lat)) + new_s2_xptr(s2_lnglat_from_numeric(recycled[[1]], recycled[[2]]), "s2_lnglat") +} + +#' @rdname s2_lnglat +#' @export +as_s2_lnglat <- function(x, ...) { + UseMethod("as_s2_lnglat") +} + +#' @rdname s2_lnglat +#' @export +as_s2_lnglat.s2_lnglat <- function(x, ...) { + x +} + +#' @rdname s2_lnglat +#' @export +as_s2_lnglat.s2_point <- function(x, ...) { + new_s2_xptr(s2_lnglat_from_s2_point(x), "s2_lnglat") +} + +#' @rdname s2_lnglat +#' @export +as_s2_lnglat.s2_geography <- function(x, ...) { + new_s2_xptr(s2_lnglat_from_numeric(cpp_s2_x(x), cpp_s2_y(x)), "s2_lnglat") +} + +#' @rdname s2_lnglat +#' @export +as_s2_lnglat.matrix <- function(x, ...) { + s2_lnglat(x[, 1, drop = TRUE], x[, 2, drop = TRUE]) +} + +#' @export +as_s2_lnglat.character <- function(x, ...) { + as_s2_lnglat.wk_wkt(x) +} + +#' @export +as_s2_lnglat.wk_wkt <- function(x, ...) { + as_s2_lnglat(as_s2_geography(x), ...) +} + +#' @export +as_s2_lnglat.wk_wkb <- function(x, ...) { + as_s2_lnglat(as_s2_geography(x), ...) +} + +#' @rdname s2_lnglat +#' @export +as.data.frame.s2_lnglat <- function(x, ...) { + as.data.frame(data_frame_from_s2_lnglat(x)) +} + +#' @rdname s2_lnglat +#' @export +as.matrix.s2_lnglat <- function(x, ...) { + as.matrix(as.data.frame(data_frame_from_s2_lnglat(x))) +} + +#' @rdname s2_lnglat +#' @importFrom wk as_wkb +#' @export +as_wkb.s2_lnglat <- function(x, ...) { + as_wkb(as_s2_geography(x), ...) +} + +#' @rdname s2_lnglat +#' @importFrom wk as_wkt +#' @export +as_wkt.s2_lnglat <- function(x, ...) { + as_wkt(as_s2_geography(x), ...) +} + +#' @export +`[<-.s2_lnglat` <- function(x, i, value) { + x <- unclass(x) + x[i] <- as_s2_lnglat(value) + new_s2_xptr(x, "s2_lnglat") +} + +#' @export +`[[<-.s2_lnglat` <- function(x, i, value) { + x <- unclass(x) + x[i] <- as_s2_lnglat(value) + new_s2_xptr(x, "s2_lnglat") +} + +#' @export +format.s2_lnglat <- function(x, ...) { + df <- as.data.frame(x) + sprintf("(%s, %s)", format(df$lng, trim = TRUE), format(df$lat, trim = TRUE)) +} diff --git a/R/s2-matrix.R b/R/s2-matrix.R new file mode 100644 index 0000000..83388fe --- /dev/null +++ b/R/s2-matrix.R @@ -0,0 +1,170 @@ + +#' Matrix Functions +#' +#' These functions are similar to accessors and predicates, but instead of +#' recycling `x` and `y` to a common length and returning a vector of that +#' length, these functions return a vector of length `x` with each element +#' `i` containing information about how the entire vector `y` relates to +#' the feature at `x[i]`. +#' +#' @inheritParams s2_is_collection +#' @inheritParams s2_contains +#' @param x,y Geography vectors, coerced using [as_s2_geography()]. +#' `x` is considered the source, where as `y` is considered the target. +#' @param max_edges_per_cell For [s2_may_intersect_matrix()], +#' this values controls the nature of the index on `y`, with higher values +#' leading to coarser index. Values should be between 10 and 50; the default +#' of 50 is adequate for most use cases, but for specialized operations users +#' may wish to use a lower value to increase performance. +#' @param max_feature_cells For [s2_may_intersect_matrix()], this value +#' controls the approximation of `x` used to identify potential intersections +#' on `y`. The default value of 4 gives the best performance for most operations, +#' but for specialized operations users may wish to use a higher value to increase +#' performance. +#' +#' @return A vector of length `x`. +#' @export +#' +#' @seealso +#' See pairwise predicate functions (e.g., [s2_intersects()]). +#' +#' @examples +#' city_names <- c("Vatican City", "San Marino", "Luxembourg") +#' cities <- s2_data_cities(city_names) +#' country_names <- s2_data_tbl_countries$name +#' countries <- s2_data_countries() +#' +#' # closest feature returns y indices of the closest feature +#' # for each feature in x +#' country_names[s2_closest_feature(cities, countries)] +#' +#' # farthest feature returns y indices of the farthest feature +#' # for each feature in x +#' country_names[s2_farthest_feature(cities, countries)] +#' +#' # predicate matrices +#' country_names[s2_intersects_matrix(cities, countries)[[1]]] +#' +#' # distance matrices +#' s2_distance_matrix(cities, cities) +#' s2_max_distance_matrix(cities, countries[1:4]) +#' +s2_closest_feature <- function(x, y) { + cpp_s2_closest_feature(as_s2_geography(x), as_s2_geography(y)) +} + +#' @rdname s2_closest_feature +#' @export +s2_farthest_feature <- function(x, y) { + cpp_s2_farthest_feature(as_s2_geography(x), as_s2_geography(y)) +} + +#' @rdname s2_closest_feature +#' @export +s2_distance_matrix <- function(x, y, radius = s2_earth_radius_meters()) { + cpp_s2_distance_matrix(as_s2_geography(x), as_s2_geography(y)) * radius +} + +#' @rdname s2_closest_feature +#' @export +s2_max_distance_matrix <- function(x, y, radius = s2_earth_radius_meters()) { + cpp_s2_max_distance_matrix(as_s2_geography(x), as_s2_geography(y)) * radius +} + +#' @rdname s2_closest_feature +#' @export +s2_contains_matrix <- function(x, y, options = s2_options(model = "open")) { + cpp_s2_contains_matrix(as_s2_geography(x), as_s2_geography(y), options) +} + +#' @rdname s2_closest_feature +#' @export +s2_within_matrix <- function(x, y, options = s2_options(model = "open")) { + cpp_s2_within_matrix(as_s2_geography(x), as_s2_geography(y), options) +} + +#' @rdname s2_closest_feature +#' @export +s2_covers_matrix <- function(x, y, options = s2_options(model = "closed")) { + cpp_s2_contains_matrix(as_s2_geography(x), as_s2_geography(y), options) +} + +#' @rdname s2_closest_feature +#' @export +s2_covered_by_matrix <- function(x, y, options = s2_options(model = "closed")) { + cpp_s2_within_matrix(as_s2_geography(x), as_s2_geography(y), options) +} + +#' @rdname s2_closest_feature +#' @export +s2_intersects_matrix <- function(x, y, options = s2_options()) { + cpp_s2_intersects_matrix(as_s2_geography(x), as_s2_geography(y), options) +} + +#' @rdname s2_closest_feature +#' @export +s2_disjoint_matrix <- function(x, y, options = s2_options()) { + # disjoint is the odd one out, in that it requires a negation of intersects + # this is inconvenient to do on the C++ level, and is easier to maintain + # with setdiff() here (unless somebody complains that this is slow) + intersection <- cpp_s2_intersects_matrix(as_s2_geography(x), as_s2_geography(y), options) + Map(setdiff, list(seq_along(y)), intersection) +} + +#' @rdname s2_closest_feature +#' @export +s2_equals_matrix <- function(x, y, options = s2_options()) { + cpp_s2_equals_matrix(as_s2_geography(x), as_s2_geography(y), options) +} + +#' @rdname s2_closest_feature +#' @export +s2_touches_matrix <- function(x, y, options = s2_options()) { + cpp_s2_touches_matrix(as_s2_geography(x), as_s2_geography(y), options) +} + +#' @rdname s2_closest_feature +#' @export +s2_dwithin_matrix <- function(x, y, distance, radius = s2_earth_radius_meters()) { + cpp_s2_dwithin_matrix(as_s2_geography(x), as_s2_geography(y), distance / radius) +} + +#' @rdname s2_closest_feature +#' @export +s2_may_intersect_matrix <- function(x, y, max_edges_per_cell = 50, max_feature_cells = 4) { + cpp_s2_may_intersect_matrix( + as_s2_geography(x), as_s2_geography(y), + max_edges_per_cell, max_feature_cells, + s2_options() + ) +} + +# ------- for testing, non-indexed versions of matrix operators ------- + +s2_contains_matrix_brute_force <- function(x, y, options = s2_options()) { + cpp_s2_contains_matrix_brute_force(as_s2_geography(x), as_s2_geography(y), options) +} + +s2_within_matrix_brute_force <- function(x, y, options = s2_options()) { + cpp_s2_within_matrix_brute_force(as_s2_geography(x), as_s2_geography(y), options) +} + +s2_covers_matrix_brute_force <- function(x, y, options = s2_options(model = "closed")) { + cpp_s2_contains_matrix_brute_force(as_s2_geography(x), as_s2_geography(y), options) +} + +s2_covered_by_matrix_brute_force <- function(x, y, options = s2_options(model = "closed")) { + cpp_s2_within_matrix_brute_force(as_s2_geography(x), as_s2_geography(y), options) +} + +s2_intersects_matrix_brute_force <- function(x, y, options = s2_options()) { + cpp_s2_intersects_matrix_brute_force(as_s2_geography(x), as_s2_geography(y), options) +} + +s2_disjoint_matrix_brute_force <- function(x, y, options = s2_options()) { + cpp_s2_disjoint_matrix_brute_force(as_s2_geography(x), as_s2_geography(y), options) +} + +s2_equals_matrix_brute_force <- function(x, y, options = s2_options()) { + cpp_s2_equals_matrix_brute_force(as_s2_geography(x), as_s2_geography(y), options) +} diff --git a/R/s2-options.R b/R/s2-options.R new file mode 100644 index 0000000..6cfc266 --- /dev/null +++ b/R/s2-options.R @@ -0,0 +1,142 @@ + +#' Geography Operation Options +#' +#' These functions specify defaults for options used to perform operations +#' and construct geometries. These are used in predicates (e.g., [s2_intersects()]), +#' and boolean operations (e.g., [s2_intersection()]) to specify the model for +#' containment and how new geometries should be constructed. +#' +#' @param model One of 'open', 'semi-open' (default for polygons), +#' or 'closed' (default for polylines). See section 'Model' +#' @param snap Use `s2_snap_identity()`, `s2_snap_distance()`, `s2_snap_level()`, +#' or `s2_snap_precision()` to specify how or if coordinate rounding should +#' occur. +#' @param snap_radius As opposed to the snap function, which specifies +#' the maximum distance a vertex should move, the snap radius (in radians) sets +#' the minimum distance between vertices of the output that don't cause vertices +#' to move more than the distance specified by the snap function. This can be used +#' to simplify the result of a boolean operation. Use -1 to specify that any +#' minimum distance is acceptable. +#' @param duplicate_edges Use `TRUE` to keep duplicate edges (e.g., duplicate +#' points). +#' @param edge_type One of 'directed' (default) or 'undirected'. +#' @param polyline_type One of 'path' (default) or 'walk'. If 'walk', +#' polylines that backtrack are preserved. +#' @param polyline_sibling_pairs One of 'discard' (default) or 'keep'. +#' @param simplify_edge_chains Use `TRUE` to remove vertices that are within +#' `snap_radius` of the original vertex. +#' @param split_crossing_edges Use `TRUE` to split crossing polyline edges +#' when creating geometries. +#' @param idempotent Use `FALSE` to apply snap even if snapping is not necessary +#' to satisfy vertex constraints. +#' @param validate Use `TRUE` to validate the result from the builder. +#' @param level A value from 0 to 30 corresponding to the cell level +#' at which snapping should occur. +#' @param distance A distance (in radians) denoting the maximum +#' distance a vertex should move in the snapping process. +#' @param precision A number by which coordinates should be multiplied +#' before being rounded. Rounded to the nearest exponent of 10. +#' +#' @section Model: +#' The geometry model indicates whether or not a geometry includes its boundaries. +#' Boundaries of line geometries are its end points. +#' OPEN geometries do not contain their boundary (`model = "open"`); CLOSED +#' geometries (`model = "closed"`) contain their boundary; SEMI-OPEN geometries +#' (`model = "semi-open"`) contain half of their boundaries, such that when two polygons +#' do not overlap or two lines do not cross, no point exist that belong to +#' more than one of the geometries. (This latter form, half-closed, is +#' not present in the OpenGIS "simple feature access" (SFA) standard nor DE9-IM on +#' which that is based). The default values for [s2_contains()] (open) +#' and covers/covered_by (closed) correspond to the SFA standard specification +#' of these operators. +#' +#' @export +#' +#' @examples +#' # use s2_options() to specify containment models, snap level +#' # layer creation options, and builder options +#' s2_options(model = "closed", snap = s2_snap_level(30)) +#' +s2_options <- function(model = NULL, + snap = s2_snap_identity(), + snap_radius = -1, + duplicate_edges = FALSE, + edge_type = "directed", + validate = FALSE, + polyline_type = "path", + polyline_sibling_pairs = "keep", + simplify_edge_chains = FALSE, + split_crossing_edges = FALSE, + idempotent = FALSE) { + # check snap radius (passing in a huge snap radius can cause problems) + if (snap_radius > 3) { + stop( + "Snap radius is too large. Did you pass in a snap radius in meters instead of radians?", + call. = FALSE + ) + } + + structure( + list( + # model needs to be "unset" by default because there are differences in polygon + # and polyline handling by default that are good defaults to preserve + model = if (is.null(model)) -1 else match_option(model, c("open", "semi-open", "closed"), "model"), + snap = snap, + snap_radius = snap_radius, + duplicate_edges = duplicate_edges, + edge_type = match_option(edge_type, c("directed", "undirected"), "edge_type"), + validate = validate, + polyline_type = match_option(polyline_type, c("path", "walk"), "polyline_type"), + polyline_sibling_pairs = match_option( + polyline_sibling_pairs, + c("discard", "keep"), + "polyline_sibling_pairs" + ), + simplify_edge_chains = simplify_edge_chains, + split_crossing_edges = split_crossing_edges, + idempotent = idempotent + ), + class = "s2_options" + ) +} + +#' @rdname s2_options +#' @export +s2_snap_identity <- function() { + structure(list(), class = "snap_identity") +} + +#' @rdname s2_options +#' @export +s2_snap_level <- function(level) { + if (level > 30) { + stop("`level` must be an intger between 1 and 30", call. = FALSE) + } + + structure(list(level = level), class = "snap_level") +} + +#' @rdname s2_options +#' @export +s2_snap_precision <- function(precision) { + structure(list(exponent = round(log10(precision))), class = "snap_precision") +} + +#' @rdname s2_options +#' @export +s2_snap_distance <- function(distance) { + structure(list(distance = distance), class = "snap_distance") +} + + +match_option <- function(x, options, arg) { + result <- match(x, options) + if (identical(result, NA_integer_)) { + stop( + sprintf("`%s` must be one of %s", arg, paste0('"', options, '"', collapse = ", ")), + call. = FALSE + ) + } + + result +} diff --git a/R/s2-package.R b/R/s2-package.R new file mode 100644 index 0000000..6c757a5 --- /dev/null +++ b/R/s2-package.R @@ -0,0 +1,10 @@ +#' @keywords internal +"_PACKAGE" + +# The following block is used by usethis to automatically manage +# roxygen namespace tags. Modify with care! +## usethis namespace: start +#' @useDynLib s2, .registration = TRUE +#' @importFrom Rcpp sourceCpp +## usethis namespace: end +NULL diff --git a/R/s2-point.R b/R/s2-point.R new file mode 100644 index 0000000..681f3ba --- /dev/null +++ b/R/s2-point.R @@ -0,0 +1,89 @@ + +#' Create an S2 Point Vector +#' +#' In S2 terminology, a "point" is a 3-dimensional unit vector representation +#' of an [s2_lnglat()]. Internally, all s2 objects are stored as +#' 3-dimensional unit vectors. +#' +#' @param x,y,z Vectors of latitude and longitude values in degrees. +#' @param ... Unused +#' +#' @return An object with class s2_point +#' @export +#' +#' @examples +#' lnglat <- s2_lnglat(-64, 45) # Halifax, Nova Scotia! +#' as_s2_point(lnglat) +#' as.data.frame(as_s2_point(lnglat)) +#' +s2_point <- function(x, y, z) { + recycled <- recycle_common(as.double(x), as.double(y), as.double(z)) + new_s2_xptr(s2_point_from_numeric(recycled[[1]], recycled[[2]], recycled[[3]]), "s2_point") +} + +#' @rdname s2_point +#' @export +as_s2_point <- function(x, ...) { + UseMethod("as_s2_point") +} + +#' @rdname s2_point +#' @export +as_s2_point.s2_point <- function(x, ...) { + x +} + +#' @rdname s2_point +#' @export +as_s2_point.s2_lnglat <- function(x, ...) { + new_s2_xptr(s2_point_from_s2_lnglat(x), "s2_point") +} + +#' @rdname s2_point +#' @export +as_s2_point.s2_geography <- function(x, ...) { + as_s2_point(as_s2_lnglat(x)) +} + +#' @rdname s2_point +#' @export +as_s2_point.matrix <- function(x, ...) { + s2_point(x[, 1, drop = TRUE], x[, 2, drop = TRUE], x[, 3, drop = TRUE]) +} + +#' @rdname s2_point +#' @export +as.data.frame.s2_point <- function(x, ...) { + as.data.frame(data_frame_from_s2_point(x)) +} + +#' @rdname s2_point +#' @export +as.matrix.s2_point <- function(x, ...) { + as.matrix(as.data.frame(data_frame_from_s2_point(x))) +} + +#' @export +`[<-.s2_point` <- function(x, i, value) { + x <- unclass(x) + x[i] <- as_s2_point(value) + new_s2_xptr(x, "s2_point") +} + +#' @export +`[[<-.s2_point` <- function(x, i, value) { + x <- unclass(x) + x[i] <- as_s2_point(value) + new_s2_xptr(x, "s2_point") +} + +#' @export +format.s2_point <- function(x, ...) { + df <- as.data.frame(x) + sprintf( + "[%s %s %s]", + format(df$x, trim = TRUE), + format(df$y, trim = TRUE), + format(df$z, trim = TRUE) + ) +} diff --git a/R/s2-predicates.R b/R/s2-predicates.R new file mode 100644 index 0000000..45701f0 --- /dev/null +++ b/R/s2-predicates.R @@ -0,0 +1,171 @@ + +#' S2 Geography Predicates +#' +#' These functions operate two geography vectors (pairwise), and return +#' a logical vector. +#' +#' @inheritParams s2_is_collection +#' @inheritParams s2_boundary +#' @param distance A distance on the surface of the earth in the same units +#' as `radius`. +#' @param lng1,lat1,lng2,lat2 A latitude/longitude range +#' @param detail The number of points with which to approximate +#' non-geodesic edges. +#' +#' @inheritSection s2_options Model +#' +#' @export +#' +#' @seealso +#' Matrix versions of these predicates (e.g., [s2_intersects_matrix()]). +#' +#' BigQuery's geography function reference: +#' +#' - [ST_CONTAINS](https://cloud.google.com/bigquery/docs/reference/standard-sql/geography_functions#st_contains) +#' - [ST_COVEREDBY](https://cloud.google.com/bigquery/docs/reference/standard-sql/geography_functions#st_coveredby) +#' - [ST_COVERS](https://cloud.google.com/bigquery/docs/reference/standard-sql/geography_functions#st_covers) +#' - [ST_DISJOINT](https://cloud.google.com/bigquery/docs/reference/standard-sql/geography_functions#st_disjoint) +#' - [ST_EQUALS](https://cloud.google.com/bigquery/docs/reference/standard-sql/geography_functions#st_equals) +#' - [ST_INTERSECTS](https://cloud.google.com/bigquery/docs/reference/standard-sql/geography_functions#st_intersects) +#' - [ST_INTERSECTSBOX](https://cloud.google.com/bigquery/docs/reference/standard-sql/geography_functions#st_intersectsbox) +#' - [ST_TOUCHES](https://cloud.google.com/bigquery/docs/reference/standard-sql/geography_functions#st_touches) +#' - [ST_WITHIN](https://cloud.google.com/bigquery/docs/reference/standard-sql/geography_functions#st_within) +#' - [ST_DWITHIN](https://cloud.google.com/bigquery/docs/reference/standard-sql/geography_functions#st_dwithin) +#' +#' @examples +#' s2_contains( +#' "POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0))", +#' c("POINT (5 5)", "POINT (-1 1)") +#' ) +#' +#' s2_within( +#' c("POINT (5 5)", "POINT (-1 1)"), +#' "POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0))" +#' ) +#' +#' s2_covered_by( +#' "POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0))", +#' c("POINT (5 5)", "POINT (-1 1)") +#' ) +#' +#' s2_covers( +#' "POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0))", +#' c("POINT (5 5)", "POINT (-1 1)") +#' ) +#' +#' s2_disjoint( +#' "POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0))", +#' c("POINT (5 5)", "POINT (-1 1)") +#' ) +#' +#' s2_intersects( +#' "POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0))", +#' c("POINT (5 5)", "POINT (-1 1)") +#' ) +#' +#' s2_equals( +#' "POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0))", +#' c( +#' "POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0))", +#' "POLYGON ((10 0, 10 10, 0 10, 0 0, 10 0))", +#' "POLYGON ((-1 -1, 10 0, 10 10, 0 10, -1 -1))" +#' ) +#' ) +#' +#' s2_intersects( +#' "POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0))", +#' c("POINT (5 5)", "POINT (-1 1)") +#' ) +#' +#' s2_intersects_box( +#' c("POINT (5 5)", "POINT (-1 1)"), +#' 0, 0, 10, 10 +#' ) +#' +#' s2_touches( +#' "POLYGON ((0 0, 0 1, 1 1, 0 0))", +#' c("POINT (0 0)", "POINT (0.5 0.75)", "POINT (0 0.5)") +#' ) +#' +#' s2_dwithin( +#' "POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0))", +#' c("POINT (5 5)", "POINT (-1 1)"), +#' 0 # distance in meters +#' ) +#' +#' s2_dwithin( +#' "POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0))", +#' c("POINT (5 5)", "POINT (-1 1)"), +#' 1e6 # distance in meters +#' ) +#' +s2_contains <- function(x, y, options = s2_options(model = "open")) { + recycled <- recycle_common(as_s2_geography(x), as_s2_geography(y)) + cpp_s2_contains(recycled[[1]], recycled[[2]], options) +} + +#' @rdname s2_contains +#' @export +s2_within <- function(x, y, options = s2_options(model = "open")) { + s2_contains(y, x, options) +} + +#' @rdname s2_contains +#' @export +s2_covered_by <- function(x, y, options = s2_options(model = "closed")) { + s2_covers(y, x, options) +} + +#' @rdname s2_contains +#' @export +s2_covers <- function(x, y, options = s2_options(model = "closed")) { + recycled <- recycle_common(as_s2_geography(x), as_s2_geography(y)) + cpp_s2_contains(recycled[[1]], recycled[[2]], options) +} + +#' @rdname s2_contains +#' @export +s2_disjoint <- function(x, y, options = s2_options()) { + !s2_intersects(x, y, options) +} + +#' @rdname s2_contains +#' @export +s2_intersects <- function(x, y, options = s2_options()) { + recycled <- recycle_common(as_s2_geography(x), as_s2_geography(y)) + cpp_s2_intersects(recycled[[1]], recycled[[2]], options) +} + +#' @rdname s2_contains +#' @export +s2_equals <- function(x, y, options = s2_options()) { + recycled <- recycle_common(as_s2_geography(x), as_s2_geography(y)) + cpp_s2_equals(recycled[[1]], recycled[[2]], options) +} + +#' @rdname s2_contains +#' @export +s2_intersects_box <- function(x, lng1, lat1, lng2, lat2, detail = 1000, options = s2_options()) { + recycled <- recycle_common(as_s2_geography(x), lng1, lat1, lng2, lat2, detail) + cpp_s2_intersects_box( + recycled[[1]], + recycled[[2]], recycled[[3]], + recycled[[4]], recycled[[5]], + detail = recycled[[6]], + s2options = options + ) +} + +#' @rdname s2_contains +#' @export +s2_touches <- function(x, y, options = s2_options()) { + recycled <- recycle_common(as_s2_geography(x), as_s2_geography(y)) + cpp_s2_touches(recycled[[1]], recycled[[2]], options) +} + +#' @rdname s2_contains +#' @export +s2_dwithin <- function(x, y, distance, radius = s2_earth_radius_meters()) { + recycled <- recycle_common(as_s2_geography(x), as_s2_geography(y), distance / radius) + cpp_s2_dwithin(recycled[[1]], recycled[[2]], recycled[[3]]) +} diff --git a/R/s2-transformers.R b/R/s2-transformers.R new file mode 100644 index 0000000..2ee380f --- /dev/null +++ b/R/s2-transformers.R @@ -0,0 +1,208 @@ + +#' S2 Geography Transformations +#' +#' These functions operate on one or more geography vectors and +#' return a geography vector. +#' +#' @inheritParams s2_is_collection +#' @param na.rm For aggregate calculations use `na.rm = TRUE` +#' to drop missing values. +#' @param grid_size The grid size to which coordinates should be snapped; +#' will be rounded to the nearest power of 10. +#' @param options An [s2_options()] object describing the polygon/polyline +#' model to use and the snap level. +#' @param distance The distance to buffer, in units of `radius`. +#' @param max_cells The maximum number of cells to approximate a buffer. +#' @param min_level The minimum cell level used to approximate a buffer +#' (1 - 30). Setting this value too high will result in unnecessarily +#' large geographies, but may help improve buffers along long, narrow +#' regions. +#' @param tolerance The minimum distance between vertexes to use when +#' simplifying a geography. +#' +#' @inheritSection s2_options Model +#' +#' @export +#' +#' @seealso +#' BigQuery's geography function reference: +#' +#' - [ST_BOUNDARY](https://cloud.google.com/bigquery/docs/reference/standard-sql/geography_functions#st_boundary) +#' - [ST_CENTROID](https://cloud.google.com/bigquery/docs/reference/standard-sql/geography_functions#st_centroid) +#' - [ST_CLOSESTPOINT](https://cloud.google.com/bigquery/docs/reference/standard-sql/geography_functions#st_closestpoint) +#' - [ST_DIFFERENCE](https://cloud.google.com/bigquery/docs/reference/standard-sql/geography_functions#st_difference) +#' - [ST_INTERSECTION](https://cloud.google.com/bigquery/docs/reference/standard-sql/geography_functions#st_intersection) +#' - [ST_UNION](https://cloud.google.com/bigquery/docs/reference/standard-sql/geography_functions#st_union) +#' - [ST_SNAPTOGRID](https://cloud.google.com/bigquery/docs/reference/standard-sql/geography_functions#st_snaptogrid) +#' - [ST_SIMPLIFY](https://cloud.google.com/bigquery/docs/reference/standard-sql/geography_functions#st_simplify) +#' - [ST_UNION_AGG](https://cloud.google.com/bigquery/docs/reference/standard-sql/geography_functions#st_union_agg) +#' - [ST_CENTROID_AGG](https://cloud.google.com/bigquery/docs/reference/standard-sql/geography_functions#s2_centroid_agg) +#' +#' @examples +#' # returns the boundary: +#' # empty for point, endpoints of a linestring, +#' # perimeter of a polygon +#' s2_boundary("POINT (-64 45)") +#' s2_boundary("LINESTRING (0 0, 10 0)") +#' s2_boundary("POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0))") +#' +#' # returns the area-weighted centroid, element-wise +#' s2_centroid("POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0))") +#' s2_centroid("LINESTRING (0 0, 10 0)") +#' +#' # returns the unweighted centroid of the entire input +#' s2_centroid_agg(c("POINT (0 0)", "POINT (10 0)")) +#' +#' # returns the closest point on x to y +#' s2_closest_point( +#' "POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0))", +#' "POINT (0 90)" # north pole! +#' ) +#' +#' # returns the shortest possible line between x and y +#' s2_minimum_clearance_line_between( +#' "POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0))", +#' "POINT (0 90)" # north pole! +#' ) +#' +#' # binary operations: difference, symmetric difference, intersection and union +#' s2_difference( +#' "POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0))", +#' "POLYGON ((5 5, 15 5, 15 15, 5 15, 5 5))", +#' # 32 bit platforms may need to set snap rounding +#' s2_options(snap = s2_snap_level(30)) +#' ) +#' +#' s2_sym_difference( +#' "POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0))", +#' "POLYGON ((5 5, 15 5, 15 15, 5 15, 5 5))", +#' # 32 bit platforms may need to set snap rounding +#' s2_options(snap = s2_snap_level(30)) +#' ) +#' +#' s2_intersection( +#' "POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0))", +#' "POLYGON ((5 5, 15 5, 15 15, 5 15, 5 5))", +#' # 32 bit platforms may need to set snap rounding +#' s2_options(snap = s2_snap_level(30)) +#' ) +#' +#' s2_union( +#' "POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0))", +#' "POLYGON ((5 5, 15 5, 15 15, 5 15, 5 5))", +#' # 32 bit platforms may need to set snap rounding +#' s2_options(snap = s2_snap_level(30)) +#' ) +#' +#' # use s2_union_agg() to aggregate geographies in a vector +#' s2_union_agg( +#' c( +#' "POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0))", +#' "POLYGON ((5 5, 15 5, 15 15, 5 15, 5 5))" +#' ), +#' # 32 bit platforms may need to set snap rounding +#' s2_options(snap = s2_snap_level(30)) +#' ) +#' +#' # snap to grid rounds coordinates to a specified grid size +#' s2_snap_to_grid("POINT (0.333333333333 0.666666666666)", 1e-2) +#' +s2_boundary <- function(x) { + new_s2_xptr(cpp_s2_boundary(as_s2_geography(x)), "s2_geography") +} + +#' @rdname s2_boundary +#' @export +s2_centroid <- function(x) { + new_s2_xptr(cpp_s2_centroid(as_s2_geography(x)), "s2_geography") +} + +#' @rdname s2_boundary +#' @export +s2_closest_point <- function(x, y) { + recycled <- recycle_common(as_s2_geography(x), as_s2_geography(y)) + new_s2_xptr(cpp_s2_closest_point(recycled[[1]], recycled[[2]]), "s2_geography") +} + +#' @rdname s2_boundary +#' @export +s2_minimum_clearance_line_between <- function(x, y) { + recycled <- recycle_common(as_s2_geography(x), as_s2_geography(y)) + new_s2_xptr(cpp_s2_minimum_clearance_line_between(recycled[[1]], recycled[[2]]), "s2_geography") +} + +#' @rdname s2_boundary +#' @export +s2_difference <- function(x, y, options = s2_options()) { + recycled <- recycle_common(as_s2_geography(x), as_s2_geography(y)) + new_s2_xptr(cpp_s2_difference(recycled[[1]], recycled[[2]], options), "s2_geography") +} + +#' @rdname s2_boundary +#' @export +s2_sym_difference <- function(x, y, options = s2_options()) { + recycled <- recycle_common(as_s2_geography(x), as_s2_geography(y)) + new_s2_xptr(cpp_s2_sym_difference(recycled[[1]], recycled[[2]], options), "s2_geography") +} + +#' @rdname s2_boundary +#' @export +s2_intersection <- function(x, y, options = s2_options()) { + recycled <- recycle_common(as_s2_geography(x), as_s2_geography(y)) + new_s2_xptr(cpp_s2_intersection(recycled[[1]], recycled[[2]], options), "s2_geography") +} + +#' @rdname s2_boundary +#' @export +s2_union <- function(x, y = NULL, options = s2_options()) { + if (is.null(y)) { + y <- as_s2_geography("POINT EMPTY") + } + + recycled <- recycle_common(as_s2_geography(x), as_s2_geography(y)) + new_s2_xptr(cpp_s2_union(recycled[[1]], recycled[[2]], options), "s2_geography") +} + +#' @rdname s2_boundary +#' @export +s2_snap_to_grid <- function(x, grid_size) { + s2_rebuild( + x, + options = s2_options( + snap = s2_snap_precision(10^(-log10(grid_size))), + duplicate_edges = TRUE + ) + ) +} + +#' @rdname s2_boundary +#' @export +s2_simplify <- function(x, tolerance, radius = s2_earth_radius_meters()) { + s2_rebuild(x, options = s2_options(snap_radius = tolerance / radius, simplify_edge_chains = TRUE)) +} + +#' @rdname s2_boundary +#' @export +s2_rebuild <- function(x, options = s2_options()) { + new_s2_xptr(cpp_s2_rebuild(as_s2_geography(x), options), "s2_geography") +} + +#' @rdname s2_boundary +#' @export +s2_buffer_cells <- function(x, distance, max_cells = 1000, min_level = -1, + radius = s2_earth_radius_meters()) { + recycled <- recycle_common(as_s2_geography(x), distance / radius) + new_s2_xptr(cpp_s2_buffer_cells(recycled[[1]], recycled[[2]], max_cells, min_level), "s2_geography") +} + +#' @rdname s2_boundary +#' @export +s2_centroid_agg <- function(x, na.rm = FALSE) { + new_s2_xptr(cpp_s2_centroid_agg(as_s2_geography(x), naRm = na.rm), "s2_geography") +} + +#' @rdname s2_boundary +#' @export +s2_union_agg <- function(x, options = s2_options(), na.rm = FALSE) { + new_s2_xptr(cpp_s2_union_agg(as_s2_geography(x), options, na.rm), "s2_geography") +} diff --git a/R/s2-xptr.R b/R/s2-xptr.R new file mode 100644 index 0000000..1d1d8f3 --- /dev/null +++ b/R/s2-xptr.R @@ -0,0 +1,80 @@ + +#' Create vectors of XPtr objects +#' +#' @param x A bare `list()` of external pointers +#' @param class A character vector subclass +#' @param ... Unused +#' +#' @return An object of class s2_xptr +#' @noRd +#' +new_s2_xptr <- function(x = list(), class = character()) { + if (!is.list(x) || is.object(x)) { + stop("x must be a bare list of 'externalptr' objects") + } + + class(x) <- union(class, "s2_xptr") + x +} + +validate_s2_xptr <- function(x) { + type <- vapply(unclass(x), typeof, character(1)) + valid_items <- type %in% c("externalptr", "NULL") + if (any(!valid_items)) { + stop("Items must be externalptr objects or NULL") + } + + invisible(x) +} + +#' @export +`[.s2_xptr` <- function(x, i) { + new_s2_xptr(NextMethod(), class(x)) +} + +# makes lapply() along these vectors possible +#' @export +`[[.s2_xptr` <- function(x, i) { + x[i] +} + +#' @export +`c.s2_xptr` <- function(...) { + # make sure all items inherit the same top-level class + dots <- list(...) + inherits_first <- vapply(dots, inherits, class(dots[[1]])[1], FUN.VALUE = logical(1)) + if (!all(inherits_first)) { + stop(sprintf("All items must inherit from '%s'", class(dots[[1]])[1])) + } + + xptr <- new_s2_xptr(NextMethod(), class(dots[[1]])) + validate_s2_xptr(xptr) + xptr +} + +#' @export +rep.s2_xptr <- function(x, ...) { + if (length(x) == 0) { + new_s2_xptr(list(), class(x)) + } else { + new_s2_xptr(NextMethod(), class(x)) + } +} + +#' @method rep_len s2_xptr +#' @export +rep_len.s2_xptr <- function(x, length.out) { + rep(x, length.out = length.out) +} + +#' @export +print.s2_xptr <- function(x, ...) { + cat(sprintf("<%s[%s]>\n", class(x)[1], length(x))) + if (length(x) == 0) { + return(invisible(x)) + } + + out <- stats::setNames(format(x, ...), names(x)) + print(out, quote = FALSE) + invisible(x) +} diff --git a/R/utils.R b/R/utils.R new file mode 100644 index 0000000..ffb3f1a --- /dev/null +++ b/R/utils.R @@ -0,0 +1,27 @@ + +recycle_common <- function(...) { + dots <- list(...) + lengths <- vapply(dots, length, integer(1)) + non_constant_lengths <- unique(lengths[lengths != 1]) + if (length(non_constant_lengths) == 0) { + final_length <- 1 + } else if(length(non_constant_lengths) == 1) { + final_length <- non_constant_lengths + } else { + lengths_label <- paste0(non_constant_lengths, collapse = ", ") + stop(sprintf("Incompatible lengths: %s", lengths_label)) + } + + lapply(dots, rep_len, final_length) +} + +expect_wkt_equal <- function(x, y, precision = 16) { + testthat::expect_equal( + s2_geography_to_wkt(as_s2_geography(x), precision = precision, trim = TRUE), + s2_geography_to_wkt(as_s2_geography(y), precision = precision, trim = TRUE) + ) +} + +expect_near <- function(x, y, epsilon) { + testthat::expect_true(abs(y - x) < epsilon) +} diff --git a/R/vctrs.R b/R/vctrs.R new file mode 100644 index 0000000..0097ed9 --- /dev/null +++ b/R/vctrs.R @@ -0,0 +1,36 @@ + +vec_proxy.s2_geography <- function(x, ...) { + unclass(x) +} + +vec_restore.s2_geography <- function(x, ...) { + new_s2_xptr(x, "s2_geography") +} + +vec_ptype_abbr.s2_geography <- function(x, ...) { + "s2_geography" +} + +vec_proxy.s2_point <- function(x, ...) { + unclass(x) +} + +vec_restore.s2_point <- function(x, ...) { + new_s2_xptr(x, "s2_point") +} + +vec_ptype_abbr.s2_point <- function(x, ...) { + "s2_point" +} + +vec_proxy.s2_lnglat <- function(x, ...) { + unclass(x) +} + +vec_restore.s2_lnglat <- function(x, ...) { + new_s2_xptr(x, "s2_lnglat") +} + +vec_ptype_abbr.s2_lnglat <- function(x, ...) { + "s2_lnglat" +} diff --git a/R/zzz.R b/R/zzz.R new file mode 100644 index 0000000..2c83c3d --- /dev/null +++ b/R/zzz.R @@ -0,0 +1,72 @@ + +# nocov start +.onLoad <- function(...) { + # call c++ init + cpp_s2_init() + + # dynamically register vctrs dependencies + for (cls in c("s2_geography", "s2_point", "s2_lnglat")) { + s3_register("vctrs::vec_proxy", cls) + s3_register("vctrs::vec_restore", cls) + s3_register("vctrs::vec_ptype_abbr", cls) + } +} + +s3_register <- function(generic, class, method = NULL) { + stopifnot(is.character(generic), length(generic) == 1) + stopifnot(is.character(class), length(class) == 1) + + pieces <- strsplit(generic, "::")[[1]] + stopifnot(length(pieces) == 2) + package <- pieces[[1]] + generic <- pieces[[2]] + + caller <- parent.frame() + + get_method_env <- function() { + top <- topenv(caller) + if (isNamespace(top)) { + asNamespace(environmentName(top)) + } else { + caller + } + } + get_method <- function(method, env) { + if (is.null(method)) { + get(paste0(generic, ".", class), envir = get_method_env()) + } else { + method + } + } + + method_fn <- get_method(method) + stopifnot(is.function(method_fn)) + + # Always register hook in case package is later unloaded & reloaded + setHook( + packageEvent(package, "onLoad"), + function(...) { + ns <- asNamespace(package) + + # Refresh the method, it might have been updated by `devtools::load_all()` + method_fn <- get_method(method) + + registerS3method(generic, class, method_fn, envir = ns) + } + ) + + # Avoid registration failures during loading (pkgload or regular) + if (!isNamespaceLoaded(package)) { + return(invisible()) + } + + envir <- asNamespace(package) + + # Only register if generic can be accessed + if (exists(generic, envir)) { + registerS3method(generic, class, method_fn, envir = envir) + } + + invisible() +} +# nocov end diff --git a/README.md b/README.md new file mode 100644 index 0000000..0a9bf7b --- /dev/null +++ b/README.md @@ -0,0 +1,180 @@ + + + +# s2 + + + +[![Lifecycle: +experimental](https://img.shields.io/badge/lifecycle-experimental-orange.svg)](https://www.tidyverse.org/lifecycle/#experimental) +![R-CMD-check](https://github.com/r-spatial/s2/workflows/R-CMD-check/badge.svg) +[![codecov](https://codecov.io/gh/r-spatial/s2/branch/master/graph/badge.svg)](https://codecov.io/gh/r-spatial/s2) +[![CRAN](http://www.r-pkg.org/badges/version/s2)](https://cran.r-project.org/package=s2) + + +The goal of s2 is to provide R bindings to Google’s +[S2Geometry](https://s2geometry.io) library. The package exposes an API +similar to Google’s [BigQuery Geography +API](https://cloud.google.com/bigquery/docs/reference/standard-sql/geography_functions), +whose functions also operate on spherical geometries. This package is a +complete rewrite of an earlier CRAN package s2 with versions up to +0.4-2, for which the sources are found +[here](https://github.com/spatstat/s2/). + +## Installation + +You can install the released version of s2 from +[CRAN](https://CRAN.R-project.org) with: + +``` r +install.packages("s2") +``` + +And the development version from [GitHub](https://github.com/) with: + +``` r +# install.packages("remotes") +remotes::install_github("r-spatial/s2") +``` + +## Example + +The s2 package provides geometry transformers and predicates similar to +those found in [GEOS](https://trac.osgeo.org/geos/), except instead of +assuming a planar geometry, s2’s functions work in latitude and +longitude and assume a spherical geometry: + +``` r +library(s2) + +s2_contains( + # polygon containing much of the northern hemisphere + "POLYGON ((-63.5 44.6, -149.75 61.20, 116.4 40.2, 13.5 52.51, -63.5 44.6))", + # ...should contain the north pole + "POINT (0 90)" +) +#> [1] TRUE +``` + +The [sf package](https://r-spatial.github.io/sf/) uses s2 for geographic +coordinates with `sf::sf_use_s2(TRUE)`, and will become the default +after sf version 1.0.0. The sf package also supports creating s2 vectors +using `as_s2_geography()`: + +``` r +library(dplyr) +library(sf) + +nc_s2 <- read_sf(system.file("shape/nc.shp", package = "sf")) %>% + mutate(geometry = as_s2_geography(geometry)) %>% + as_tibble() %>% + select(NAME, geometry) + +nc_s2 +#> # A tibble: 100 x 2 +#> NAME geometry +#> +#> 1 Ashe 2 Alleghany 3 Surry 4 Currituck 5 Northampton 6 Hertford 7 Camden 8 Gates 9 Warren 10 Stokes # … with 90 more rows +``` + +Use accessors to extract information about geometries: + +``` r +nc_s2 %>% + mutate( + area = s2_area(geometry), + perimeter = s2_perimeter(geometry) + ) +#> # A tibble: 100 x 4 +#> NAME geometry area perimeter +#> +#> 1 Ashe 2 Alleghany 3 Surry 4 Currituck 5 Northamp… 6 Hertford 7 Camden 8 Gates 9 Warren 10 Stokes # … with 90 more rows +``` + +Use predicates to subset vectors: + +``` r +nc_s2 %>% + filter(s2_contains(geometry, "POINT (-80.9313 35.6196)")) +#> # A tibble: 1 x 2 +#> NAME geometry +#> +#> 1 Catawba % + mutate(geometry = s2_boundary(geometry)) +#> # A tibble: 100 x 2 +#> NAME geometry +#> +#> 1 Ashe 2 Alleghany 3 Surry 4 Currituck 5 Northampton 6 Hertford 7 Camden 8 Gates 9 Warren 10 Stokes # … with 90 more rows +``` + +Finally, use the WKB or WKT exporters to export to sf or some other +package: + +``` r +nc_s2 %>% + mutate(geometry = st_as_sfc(s2_as_binary(geometry))) %>% + st_as_sf() +#> Simple feature collection with 100 features and 1 field +#> geometry type: GEOMETRY +#> dimension: XY +#> bbox: xmin: -84.32385 ymin: 33.88199 xmax: -75.45698 ymax: 36.58965 +#> CRS: NA +#> # A tibble: 100 x 2 +#> NAME geometry +#> +#> 1 Ashe POLYGON ((-81.45289 36.23959, -81.43104 36.26072, -81.41233 36.26… +#> 2 Alleghany POLYGON ((-81.17667 36.41544, -81.15337 36.42474, -81.1384 36.417… +#> 3 Surry POLYGON ((-80.45301 36.25709, -80.43531 36.55104, -80.61105 36.55… +#> 4 Currituck MULTIPOLYGON (((-75.94193 36.29434, -75.95751 36.25945, -75.91376… +#> 5 Northampt… POLYGON ((-77.14196 36.41706, -77.13932 36.45648, -77.12733 36.47… +#> 6 Hertford POLYGON ((-76.7075 36.26613, -76.74135 36.31517, -76.92408 36.392… +#> 7 Camden POLYGON ((-76.01735 36.33773, -76.03288 36.33598, -76.04395 36.35… +#> 8 Gates POLYGON ((-76.46035 36.3739, -76.50246 36.45229, -76.49834 36.503… +#> 9 Warren POLYGON ((-78.13472 36.23658, -78.10963 36.21351, -78.05835 36.21… +#> 10 Stokes POLYGON ((-80.02406 36.54502, -80.0481 36.54713, -80.43531 36.551… +#> # … with 90 more rows +``` + +## Acknowledgment + +This project gratefully acknowledges financial +[support](https://www.r-consortium.org/projects) from the + + + diff --git a/build/partial.rdb b/build/partial.rdb new file mode 100644 index 0000000000000000000000000000000000000000..c16aa9b07305a629b06a20910805f7f25cc86764 GIT binary patch literal 2930 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 literal 0 HcmV?d00001 diff --git a/cleanup b/cleanup new file mode 100755 index 0000000..3fd9cd2 --- /dev/null +++ b/cleanup @@ -0,0 +1,3 @@ +#!/bin/sh +rm -f src/Makevars configure.log autobrew +rm `find src -name *.o` diff --git a/configure b/configure new file mode 100755 index 0000000..bf20a71 --- /dev/null +++ b/configure @@ -0,0 +1,117 @@ +# Anticonf (tm) script by Jeroen Ooms (2020) +# This script will query 'pkg-config' for the required cflags and ldflags. +# If pkg-config is unavailable or does not find the library, try setting +# INCLUDE_DIR and LIB_DIR manually via e.g: +# R CMD INSTALL --configure-vars='INCLUDE_DIR=/.../include LIB_DIR=/.../lib' + +# Library settings +PKG_CONFIG_NAME="openssl" +PKG_DEB_NAME="libssl-dev" +PKG_RPM_NAME="openssl-devel" +PKG_CSW_NAME="libssl_dev" +PKG_BREW_NAME="openssl@1.1" +PKG_TEST_FILE="tools/version.c" +PKG_LIBS="-lssl -lcrypto" +PKG_CFLAGS="" + +# Use pkg-config if available +pkg-config ${PKG_CONFIG_NAME} --atleast-version=1.0 2>/dev/null +if [ $? -eq 0 ]; then + PKGCONFIG_CFLAGS=`pkg-config --cflags ${PKG_CONFIG_NAME}` + PKGCONFIG_LIBS=`pkg-config --libs ${PKG_CONFIG_NAME}` +fi + +# Note that cflags may be empty in case of success +if [ "$INCLUDE_DIR" ] || [ "$LIB_DIR" ]; then + echo "Found INCLUDE_DIR and/or LIB_DIR!" + PKG_CFLAGS="-I$INCLUDE_DIR $PKG_CFLAGS" + PKG_LIBS="-L$LIB_DIR $PKG_LIBS" +elif [ "$PKGCONFIG_CFLAGS" ] || [ "$PKGCONFIG_LIBS" ]; then + echo "Found pkg-config cflags and libs!" + PKG_CFLAGS=${PKGCONFIG_CFLAGS} + PKG_LIBS=${PKGCONFIG_LIBS} +elif [ `uname` = "Darwin" ]; then + brew --version 2>/dev/null + if [ $? -eq 0 ]; then + BREWDIR=`brew --prefix` + PKG_CFLAGS="-I$BREWDIR/opt/openssl/include" + PKG_LIBS="-L$BREWDIR/opt/openssl/lib $PKG_LIBS" + else + curl -sfL "https://autobrew.github.io/scripts/$PKG_BREW_NAME" > autobrew + . autobrew + fi +fi + +# Find compiler +CC=`${R_HOME}/bin/R CMD config CC` +CFLAGS=`${R_HOME}/bin/R CMD config CFLAGS` +CPPFLAGS=`${R_HOME}/bin/R CMD config CPPFLAGS` + +# For debugging +echo "Testing compiler using PKG_CFLAGS=$PKG_CFLAGS" + +# Test configuration +${CC} ${CPPFLAGS} ${PKG_CFLAGS} ${CFLAGS} -E ${PKG_TEST_FILE} >/dev/null 2>configure.log + +# Customize the error +if [ $? -ne 0 ]; then + echo "--------------------------- [ANTICONF] --------------------------------" + echo "Configuration failed because $PKG_CONFIG_NAME was not found. Try installing:" + echo " * deb: $PKG_DEB_NAME (Debian, Ubuntu, etc)" + echo " * rpm: $PKG_RPM_NAME (Fedora, CentOS, RHEL)" + echo " * csw: $PKG_CSW_NAME (Solaris)" + echo " * brew: $PKG_BREW_NAME (Mac OSX)" + echo "If $PKG_CONFIG_NAME is already installed, check that 'pkg-config' is in your" + echo "PATH and PKG_CONFIG_PATH contains a $PKG_CONFIG_NAME.pc file. If pkg-config" + echo "is unavailable you can set INCLUDE_DIR and LIB_DIR manually via:" + echo "R CMD INSTALL --configure-vars='INCLUDE_DIR=... LIB_DIR=...'" + echo "-------------------------- [ERROR MESSAGE] ---------------------------" + cat configure.log + echo "--------------------------------------------------------------------" + exit 1 +fi + +# Try to link against the correct OpenSSL version +if [ -z "$AUTOBREW" ]; then +SONAME=`${CC} -E ${PKG_CFLAGS} src/tests/soname.h | sh | xargs` +if [ "$SONAME" ]; then +if [ `uname` = "Darwin" ]; then + PKG_LIBS_VERSIONED=`echo "${PKG_LIBS}" | sed "s/-lssl/-lssl.${SONAME}/" | sed "s/-lcrypto/-lcrypto.${SONAME}/"` +else + PKG_LIBS_VERSIONED=`echo "${PKG_LIBS}" | sed "s/-lssl/-l:libssl.so.${SONAME}/" | sed "s/-lcrypto/-l:libcrypto.so.${SONAME}/"` +fi + +# Test if versioned linking works +${CC} ${PKG_CFLAGS} src/tests/main.c ${PKG_LIBS_VERSIONED} -o src/main.exe 2>/dev/null +if [ $? -eq 0 ]; then PKG_LIBS="${PKG_LIBS_VERSIONED}"; fi + +# Suppress opensslv3 warnings for now +if [ "$SONAME" = "3" ]; then +PKG_CFLAGS="$PKG_CFLAGS -DOPENSSL_SUPPRESS_DEPRECATED" +fi + +fi #SONAME +fi #AUTOBREW + +# Define system endianness (compile-time endianness using system/compiler +# defines isn't detected on Solaris) +# based on endian detection from the feather package by @hadley +R_ENDIAN=`${R_HOME}/bin/Rscript -e 'cat(.Platform$endian)'` +# Trim off any warning messages that Rscript appends in front of the platform endianness +R_ENDIAN=`expr "$R_ENDIAN" : '.*\(little\)$'` +SYS_ENDIAN="" +if [ "$R_ENDIAN" = "little" ]; then + PKG_CFLAGS="$PKG_CFLAGS -DIS_LITTLE_ENDIAN" +else + PKG_CFLAGS="$PKG_CFLAGS -DIS_BIG_ENDIAN" +fi + +echo "Using PKG_LIBS=$PKG_LIBS" +echo "Using PKG_CFLAGS=$PKG_CFLAGS" + + +# Write to Makevars +sed -e "s|@cflags@|$PKG_CFLAGS|" -e "s|@libs@|$PKG_LIBS|" src/Makevars.in > src/Makevars + +# Success +exit 0 diff --git a/configure.win b/configure.win new file mode 100755 index 0000000..e69de29 diff --git a/data/s2_data_tbl_cities.rda b/data/s2_data_tbl_cities.rda new file mode 100644 index 0000000000000000000000000000000000000000..317ea50460e058aa54ed4c376c73dbaf6f94a86e GIT binary patch literal 7074 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 M$rRy2LfrE5#EXDphX4Qo literal 0 HcmV?d00001 diff --git a/data/s2_data_tbl_countries.rda b/data/s2_data_tbl_countries.rda new file mode 100644 index 0000000000000000000000000000000000000000..a94b448af10f4dada259311bbdd058c46359abc9 GIT binary patch literal 132764 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 literal 0 HcmV?d00001 diff --git a/data/s2_data_tbl_timezones.rda b/data/s2_data_tbl_timezones.rda new file mode 100644 index 0000000000000000000000000000000000000000..1d96a0beefe1f22d5c8f1c8a9986a6b73798fa60 GIT binary patch literal 488748 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

ut>B`V~jRXq|e29qg; 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

1N`0+Jd5ik^rN3oKU|%Tz>i*0u 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

Z9snQ`Y70rp$VXr~J=GdFr|v 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

i#5+J)i!6ARx& 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%0DJ)KKY^})|O%MC@h;B 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

1#>6W$Nn7FwaqvV3X&CwRe-{fi9zM-N#+f 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
F%gyrm7nZC(ZiyJFb%OZIcrWOW&n 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%0DZ|X6pop9%Opc!eTl=O`jFG))o^2$1aqdesw+eY zIc(bQ)hP@!w%aYQAwqCdEF=(r6Xf|L%$d|^U1#NUK@)0n95+3DMASS8K3m`;;x0uv z&#weN_k(zI9*O?31QQx9hL}NLiTWQuUKmP(U6-{!p@SaLSI}2#|Mj{mc7le%E2`7} zSru=xWwSvSbywsN@oP%5j*0RRcM-qy(e)5aJshUa(#j%X;{SaIs-CloDs_)p_z*8> zAz&)M1K`f1(;rR<%0EV#)mz@1Wb#}0 zWjm&+YbrS^w!H>Xefj-{+4C;w*VgGKj`~sZw+*YN;VW(vp{8!6QcvNVX4?jV{4=%n zu9o!I1wlhcy7zxcQ_a3LiG@Lkb>EB5eb4-?t7!zLH9bpGUlOjPGj>;$qQxwU`YEJw zk*d4?a9atJKEu4n%S}~WD2sdHdT)i|cdc(x-+3()2K80g_Pv5jrIaVg!>UVDsP$B3 zQh1^y(W(FTtfbl$Y7?7Gx}sW!O50s=)o&RzRo;Rrq|lb`G9@6x)?d27t*-RHH`Vp$ zxGx=p;YloVKN4SO<|d3a<7T&|o28`|wlCRMeHfxFEdyTGK1;4qwth+rSfRb%+BLdJ zGz=5YRhjlR?>(mFI^MbpnrO8@g`s;?7o;R|O?P6GmeC2+QL$ZxZWBuT-1WhrY10a0 zKAOJ9SK4+O)DO*ic)f&EM27j1jI9MYTNTIH_uopW_m}2*J$I0u#{o!uFWKy)*@dyy zO;Qc*CyMuSRoVJ*=&-Ge?o=HY%$u(-IXPBUTvAy)kfkR#2d(m9m=hE9fRmo9T860Y?xv$Im zHQjXHt4hPFjM~1Xz7|;&{$JA=p}Vb`i0ayUtRq;kGbKsSVr^@~7>s)8)Y+mZ?GhzH zeTz?Eihoc*}Dzt3UFH z$Ulryl9*H9^J2d(8%f)+vNn&Y5ldaF=;tNImhK?EL|t7*6*@Z)i5BuqG!--#1P-%Q zup#Z#t#Sp4yG1f9a}cOK1Zz%=Uf}gxMysMS%X8#WnZ9Nn%N+O_!tKOi+xr~x-|=hP zZ7n5-v7)c#=po&;rQ`2ut503HI7NQvSd%w#%o4cdX{cv!A@{0wj@FqK#f{tmqjsbwx#AH(M!^1{H5BO5-sD@Zl%;j0`uCtQtk*6$KPCff`FIB<&ukj1zMyXYu>mZ49RhCgZP;43obrRj^ z;!*Dv0wTPnXQ0l~;QJO=%U}*Gw?*?|V$-G4IcHq-G`4oo>m2g}^LHLiGs)|&3rKSk ztOx7bK?`z@JZ7O!W#7IP2K_XWi2NDa%Y=m!a9OU1YBT;fW^B_{bU(@IKxW8x)jkvg^+Qu=YuDOQ7+}E#>Zg#u-cb9^iD_Tr5$(8%yD~(i zRUa{UQ=2wfH1(5>Y|RlP%0cBjiyM6*vp)B@>s{j&d|l8s&Z$>z*|k;INQOlVh
_ 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

oqtMXxCR})0DviTi(RcY^6ljSMzHLNA=1V#hz zN~KtIipbWdiDa7>V@^>mEB<1a{{jjmc}$ag2$Xv8nW*Y3pq@VzjiJg>Bwq72&^VXY z#WG4Y>Knvh((*@=&n4XsI&6zo5F?!Q`Px<+#@%jjUz_Ax>TKf{#HMX>b2xpAyQ=b# zk_DBkUR8xT>pjM4XJ+#sraHP&lIkj9c1O&bh8bK!Y3gelIoMqlXCJdupSsZO=8AcMyK5SDpMnqPF8d)b)dbM{O1r z4WDki2Qr!rfYHQc|kOxmMyXrIz_x~-0cN6NCO zw$;%b!??F@-_qSonYih~ zlHw(sbzOFF?T(5S{I_jY{Bqw7`@d%Kdw%!CntY%C+c;36Vmw3=OHzFD-fB&CanmP( zQBzT=>i)bv#r2SBT%^gIV5n@+7Y3rPr5>x=m3=5#^^a)CIEU@^ep#88S6yljrL^apQ*W5A=E7#r{(a8A&s{t- zC$l`4+117k3!H?-sWBNh@YnO2w@-5f9nW9!QCxN_*WO)Fp~I%Tc05bKwJcAiQBI$x zep&j%gBFReC@M3}Kh_PyHcrylhscwc;`CBWXHlS~!icT+>GZR&n*cD2|#r!cD(~ zTYuMs@N3`NEyYgv^==Y?)>yI?jY6-b@gyFK;q8BoOC%QBiiXBJsxm>9ULNX>ovR9SGKqUx_aRsLpX%49RjMdHq|Jy?WN|6o(QkBj zO)a<8Lsl7tf;xctU(S6_n>-4{yu**Cf2@o4qSwe0-=kEU#d!+YXtx(kuXWT&BKZgnLJS*?Smup^|*=_Y{o8nW{1(tnoO(hjY zEh??Df4kLuPoc4A+UMHu*FN^W-e}jgb&XpaH_pi_PhIw{sseKQ*mQzw%j{m$BJ&

A7eW+hg^bHc~A@Nxwwzl4$gLY?Vl(SLp_6 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 LrwS4R=j$=Rc8_&l literal 0 HcmV?d00001 diff --git a/inst/include/cpp-compat.h b/inst/include/cpp-compat.h new file mode 100644 index 0000000..7e18796 --- /dev/null +++ b/inst/include/cpp-compat.h @@ -0,0 +1,16 @@ + +#ifndef CPP_COMPAT_H +#define CPP_COMPAT_H + +#include + +void cpp_compat_printf(const char* fmt, ...); +[[ noreturn ]] void cpp_compat_abort(); +[[ noreturn ]] void cpp_compat_exit(int code); +int cpp_compat_random(); +void cpp_compat_srandom(int seed); + +extern std::ostream& cpp_compat_cerr; +extern std::ostream& cpp_compat_cout; + +#endif diff --git a/inst/include/s2/_fp_contract_off.h b/inst/include/s2/_fp_contract_off.h new file mode 100644 index 0000000..a053c7a --- /dev/null +++ b/inst/include/s2/_fp_contract_off.h @@ -0,0 +1,60 @@ +// Copyright 2015 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS-IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +// Author: ericv@google.com (Eric Veach) + +#ifndef S2__FP_CONTRACT_OFF_H_ +#define S2__FP_CONTRACT_OFF_H_ + +// Turn off the fused multiply-add optimization ("fp-contract"). With +// fp-contract on, any expression of the form "a * b + c" has two possible +// results, and the compiler is free to choose either of them. Effectively +// this makes it impossible to write deterministic functions that involve +// floating-point math. +// +// S2 requires deterministic arithmetic for correctness. We need to turn off +// fp-contract for the entire compilation unit, because S2 has public inline +// functions, and the optimization is controlled by the setting in effect when +// inline functions are instantiated (not when they are defined). +// +// Note that there is a standard C pragma to turn off FP contraction: +// #pragma STDC FP_CONTRACT OFF +// but it is not implemented in GCC because the standard pragma allows control +// at the level of compound statements rather than entire functions. +// +// This file may be included with other files in any order, as long as it +// appears before the first non-inline function definition. It is +// named with an underscore so that it is included first among the S2 headers. + +// TODO(compiler-team): Figure out how to do this in a portable way. +#if defined(HAVE_ARMEABI_V7A) +// Some android builds use a buggy compiler that runs out of memory while +// parsing the pragma (--cpu=armeabi-v7a). + +#elif defined(__ANDROID__) +// Other android builds use a buggy compiler that crashes with an internal +// error (Android NDK R9). + +#elif defined(__clang__) +// Clang supports the standard C++ pragma for turning off this optimization. +#pragma STDC FP_CONTRACT OFF + +#elif defined(__GNUC__) +// GCC defines its own pragma that operates at the function level rather than +// the statement level. +#pragma GCC optimize("fp-contract=off") +#endif + +#endif // S2__FP_CONTRACT_OFF_H_ diff --git a/inst/include/s2/base/casts.h b/inst/include/s2/base/casts.h new file mode 100644 index 0000000..dae1516 --- /dev/null +++ b/inst/include/s2/base/casts.h @@ -0,0 +1,318 @@ +// Copyright 2009 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS-IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + + +// +// Various Google-specific casting templates. +// +// This code is compiled directly on many platforms, including client +// platforms like Windows, Mac, and embedded systems. Before making +// any changes here, make sure that you're not breaking any platforms. +// + +#ifndef S2_BASE_CASTS_H_ +#define S2_BASE_CASTS_H_ + +#include // for use with down_cast<> +#include // for enumeration casts and tests +#include + +#include "s2/third_party/absl/base/casts.h" +#include "s2/third_party/absl/base/macros.h" + +// An "upcast", i.e. a conversion from a pointer to an object to a pointer to a +// base subobject, always succeeds if the base is unambiguous and accessible, +// and so it's fine to use implicit_cast. +// +// A "downcast", i.e. a conversion from a pointer to an object to a pointer +// to a more-derived object that may contain the original object as a base +// subobject, cannot safely be done using static_cast, because you do not +// generally know whether the source object is really the base subobject of +// a containing, more-derived object of the target type. Thus, when you +// downcast in a polymorphic type hierarchy, you should use the following +// function template. +// +// In debug mode, we use dynamic_cast to double-check whether the downcast is +// legal (we die if it's not). In normal mode, we do the efficient static_cast +// instead. Thus, it's important to test in debug mode to make sure the cast is +// legal! +// +// This is the only place in the codebase we should use dynamic_cast. +// In particular, you should NOT use dynamic_cast for RTTI, e.g. for +// code like this: +// if (auto* p = dynamic_cast(foo)) HandleASubclass1Object(p); +// if (auto* p = dynamic_cast(foo)) HandleASubclass2Object(p); +// You should design the code some other way not to need this. + +template // use like this: down_cast(foo); +inline To down_cast(From* f) { // so we only accept pointers + static_assert( + (std::is_base_of::type>::value), + "target type not derived from source type"); + + // We skip the assert and hence the dynamic_cast if RTTI is disabled. +#if !defined(__GNUC__) || defined(__GXX_RTTI) + // Uses RTTI in dbg and fastbuild. asserts are disabled in opt builds. + assert(f == nullptr || dynamic_cast(f) != nullptr); +#endif // !defined(__GNUC__) || defined(__GXX_RTTI) + + return static_cast(f); +} + +// Overload of down_cast for references. Use like this: down_cast(foo). +// The code is slightly convoluted because we're still using the pointer +// form of dynamic cast. (The reference form throws an exception if it +// fails.) +// +// There's no need for a special const overload either for the pointer +// or the reference form. If you call down_cast with a const T&, the +// compiler will just bind From to const T. +template +inline To down_cast(From& f) { + static_assert( + std::is_lvalue_reference::value, "target type not a reference"); + static_assert( + (std::is_base_of::type>::value), + "target type not derived from source type"); + + // We skip the assert and hence the dynamic_cast if RTTI is disabled. +#if !defined(__GNUC__) || defined(__GXX_RTTI) + // RTTI: debug mode only + assert(dynamic_cast::type*>(&f) != + nullptr); +#endif // !defined(__GNUC__) || defined(__GXX_RTTI) + + return static_cast(f); +} + +// **** Enumeration Casts and Tests +// +// C++ requires that the value of an integer that is converted to an +// enumeration be within the value bounds of the enumeration. Modern +// compilers can and do take advantage of this requirement to optimize +// programs. So, using a raw static_cast with enums can be bad. See +// +// The following templates and macros enable casting from an int to an enum +// with checking against the appropriate bounds. First, when defining an +// enumeration, identify the limits of the values of its enumerators. +// +// enum A { A_min = -18, A_max = 33 }; +// MAKE_ENUM_LIMITS(A, A_min, A_max) +// +// Convert an int to an enum in one of two ways. The prefered way is a +// tight conversion, which ensures that A_min <= value <= A_max. +// +// A var = tight_enum_cast(3); +// +// However, the C++ language defines the set of possible values for an +// enumeration to be essentially the range of a bitfield that can represent +// all the enumerators, i.e. those within the nearest containing power +// of two. In the example above, the nearest positive power of two is 64, +// and so the upper bound is 63. The nearest negative power of two is +// -32 and so the lower bound is -32 (two's complement), which is upgraded +// to match the upper bound, becoming -64. The values within this range +// of -64 to 63 are valid, according to the C++ standard. You can cast +// values within this range as follows. +// +// A var = loose_enum_cast(45); +// +// These casts will log a message if the value does not reside within the +// specified range, and will be fatal when in debug mode. +// +// For those times when an assert too strong, there are test functions. +// +// bool var = tight_enum_test(3); +// bool var = loose_enum_test(45); +// +// For code that needs to use the enumeration value if and only if +// it is good, there is a function that both tests and casts. +// +// int i = ....; +// A var; +// if (tight_enum_test_cast(i, &var)) +// .... // use valid var with value as indicated by i +// else +// .... // handle invalid enum cast +// +// The enum test/cast facility is currently limited to enumerations that +// fit within an int. It is also limited to two's complement ints. + +// ** Implementation Description +// +// The enum_limits template class captures the minimum and maximum +// enumerator. All uses of this template are intended to be of +// specializations, so the generic has a field to identify itself as +// not specialized. The test/cast templates assert specialization. + +template +class enum_limits { + public: + static const Enum min_enumerator = 0; + static const Enum max_enumerator = 0; + static const bool is_specialized = false; +}; + +// Now we define the macro to define the specialization for enum_limits. +// The specialization checks that the enumerators fit within an int. +// This checking relies on integral promotion. + +#define MAKE_ENUM_LIMITS(ENUM_TYPE, ENUM_MIN, ENUM_MAX) \ +template <> \ +class enum_limits { \ +public: \ + static const ENUM_TYPE min_enumerator = ENUM_MIN; \ + static const ENUM_TYPE max_enumerator = ENUM_MAX; \ + static const bool is_specialized = true; \ + static_assert(ENUM_MIN >= INT_MIN, "enumerator too negative for int"); \ + static_assert(ENUM_MAX <= INT_MAX, "enumerator too positive for int"); \ +}; + +// The loose enum test/cast is actually the more complicated one, +// because of the problem of finding the bounds. +// +// The unary upper bound, ub, on a positive number is its positive +// saturation, i.e. for a value v within pow(2,k-1) <= v < pow(2,k), +// the upper bound is pow(2,k)-1. +// +// The unary lower bound, lb, on a negative number is its negative +// saturation, i.e. for a value v within -pow(2,k) <= v < -pow(2,k-1), +// the lower bound is -pow(2,k). +// +// The actual bounds are (1) the binary upper bound over the maximum +// enumerator and the one's complement of a negative minimum enumerator +// and (2) the binary lower bound over the minimum enumerator and the +// one's complement of the positive maximum enumerator, except that if no +// enumerators are negative, the lower bound is zero. +// +// The algorithm relies heavily on the observation that +// +// a,b>0 then ub(a,b) == ub(a) | ub(b) == ub(a|b) +// a,b<0 then lb(a,b) == lb(a) & lb(b) == lb(a&b) +// +// Note that the compiler will boil most of this code away +// because of value propagation on the constant enumerator bounds. + +template +inline bool loose_enum_test(int e_val) { + static_assert(enum_limits::is_specialized, "missing MAKE_ENUM_LIMITS"); + const Enum e_min = enum_limits::min_enumerator; + const Enum e_max = enum_limits::max_enumerator; + static_assert(sizeof(e_val) == 4 || sizeof(e_val) == 8, + "unexpected int size"); + + // Find the unary bounding negative number of e_min and e_max. + + // Find the unary bounding negative number of e_max. + // This would be b_min = e_max < 0 ? e_max : ~e_max, + // but we want to avoid branches to help the compiler. + int e_max_sign = e_max >> (sizeof(e_val)*8 - 1); + int b_min = ~e_max_sign ^ e_max; + + // Find the binary bounding negative of both e_min and e_max. + b_min &= e_min; + + // However, if e_min is positive, the result will be positive. + // Now clear all bits right of the most significant clear bit, + // which is a negative saturation for negative numbers. + // In the case of positive numbers, this is flush to zero. + b_min &= b_min >> 1; + b_min &= b_min >> 2; + b_min &= b_min >> 4; + b_min &= b_min >> 8; + b_min &= b_min >> 16; +#if INT_MAX > 2147483647 + b_min &= b_min >> 32; +#endif + + // Find the unary bounding positive number of e_max. + int b_max = e_max_sign ^ e_max; + + // Find the binary bounding positive number of that + // and the unary bounding positive number of e_min. + int e_min_sign = e_min >> (sizeof(e_val)*8 - 1); + b_max |= e_min_sign ^ e_min; + + // Now set all bits right of the most significant set bit, + // which is a positive saturation for positive numbers. + b_max |= b_max >> 1; + b_max |= b_max >> 2; + b_max |= b_max >> 4; + b_max |= b_max >> 8; + b_max |= b_max >> 16; +#if INT_MAX > 2147483647 + b_max |= b_max >> 32; +#endif + + // Finally test the bounds. + return b_min <= e_val && e_val <= b_max; +} + +template +inline bool tight_enum_test(int e_val) { + static_assert(enum_limits::is_specialized, "missing MAKE_ENUM_LIMITS"); + const Enum e_min = enum_limits::min_enumerator; + const Enum e_max = enum_limits::max_enumerator; + return e_min <= e_val && e_val <= e_max; +} + +template +inline bool loose_enum_test_cast(int e_val, Enum* e_var) { + if (loose_enum_test(e_val)) { + *e_var = static_cast(e_val); + return true; + } else { + return false; + } +} + +template +inline bool tight_enum_test_cast(int e_val, Enum* e_var) { + if (tight_enum_test(e_val)) { + *e_var = static_cast(e_val); + return true; + } else { + return false; + } +} + +// The plain casts require logging, and we get header recursion if +// it is done directly. So, we do it indirectly. +// The following function is defined in logging.cc. + +namespace base { +namespace internal { + +void WarnEnumCastError(int value_of_int); + +} // namespace internal +} // namespace base + +template +inline Enum loose_enum_cast(int e_val) { + if (!loose_enum_test(e_val)) { + base::internal::WarnEnumCastError(e_val); + } + return static_cast(e_val); +} + +template +inline Enum tight_enum_cast(int e_val) { + if (!tight_enum_test(e_val)) { + base::internal::WarnEnumCastError(e_val); + } + return static_cast(e_val); +} + +#endif // S2_BASE_CASTS_H_ diff --git a/inst/include/s2/base/commandlineflags.h b/inst/include/s2/base/commandlineflags.h new file mode 100644 index 0000000..1763be0 --- /dev/null +++ b/inst/include/s2/base/commandlineflags.h @@ -0,0 +1,51 @@ +// Copyright Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS-IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#ifndef S2_BASE_COMMANDLINEFLAGS_H_ +#define S2_BASE_COMMANDLINEFLAGS_H_ + +#ifdef S2_USE_GFLAGS + +#include + +#else // !defined(S2_USE_GFLAGS) + +#include + +#include "s2/base/integral_types.h" + +#define DEFINE_bool(name, default_value, description) \ + bool FLAGS_##name = default_value +#define DECLARE_bool(name) \ + extern bool FLAGS_##name + +#define DEFINE_double(name, default_value, description) \ + double FLAGS_##name = default_value +#define DECLARE_double(name) \ + extern double FLAGS_##name + +#define DEFINE_int32(name, default_value, description) \ + int32 FLAGS_##name = default_value +#define DECLARE_int32(name) \ + extern int32 FLAGS_##name + +#define DEFINE_string(name, default_value, description) \ + std::string FLAGS_##name = default_value +#define DECLARE_string(name) \ + extern std::string FLAGS_##name + +#endif // !defined(S2_USE_GFLAGS) + +#endif // S2_BASE_COMMANDLINEFLAGS_H_ diff --git a/inst/include/s2/base/integral_types.h b/inst/include/s2/base/integral_types.h new file mode 100644 index 0000000..d20f35f --- /dev/null +++ b/inst/include/s2/base/integral_types.h @@ -0,0 +1,31 @@ +// Copyright 2018 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS-IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#ifndef S2_BASE_INTEGRAL_TYPES_H_ +#define S2_BASE_INTEGRAL_TYPES_H_ + +using int8 = signed char; +using int16 = short; +using int32 = int; +using int64 = long long; + +using uint8 = unsigned char; +using uint16 = unsigned short; +using uint32 = unsigned int; +using uint64 = unsigned long long; + +using uword_t = unsigned long; + +#endif // S2_BASE_INTEGRAL_TYPES_H_ diff --git a/inst/include/s2/base/log_severity.h b/inst/include/s2/base/log_severity.h new file mode 100644 index 0000000..57095ff --- /dev/null +++ b/inst/include/s2/base/log_severity.h @@ -0,0 +1,40 @@ +// Copyright Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS-IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#ifndef S2_BASE_LOG_SEVERITY_H_ +#define S2_BASE_LOG_SEVERITY_H_ + +#ifdef S2_USE_GLOG + +#include + +#else // !defined(S2_USE_GLOG) + +#include "s2/third_party/absl/base/log_severity.h" + +// Stay compatible with glog. +namespace google { + +#ifdef NDEBUG +constexpr bool DEBUG_MODE = false; +#else +constexpr bool DEBUG_MODE = true; +#endif + +} // namespace google + +#endif // !defined(S2_USE_GLOG) + +#endif // S2_BASE_LOG_SEVERITY_H_ diff --git a/inst/include/s2/base/logging.h b/inst/include/s2/base/logging.h new file mode 100644 index 0000000..07feb5e --- /dev/null +++ b/inst/include/s2/base/logging.h @@ -0,0 +1,177 @@ +// Copyright Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS-IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#ifndef S2_BASE_LOGGING_H_ +#define S2_BASE_LOGGING_H_ +#include "cpp-compat.h" + +#ifdef S2_USE_GLOG + +#include + +// The names CHECK, etc. are too common and may conflict with other +// packages. We use S2_CHECK to make it easier to switch to +// something other than GLOG for logging. + +#define S2_LOG LOG +#define S2_LOG_IF LOG_IF +#define S2_DLOG_IF DLOG_IF + +#define S2_CHECK CHECK +#define S2_CHECK_EQ CHECK_EQ +#define S2_CHECK_NE CHECK_NE +#define S2_CHECK_LT CHECK_LT +#define S2_CHECK_LE CHECK_LE +#define S2_CHECK_GT CHECK_GT +#define S2_CHECK_GE CHECK_GE + +#define S2_DCHECK DCHECK +#define S2_DCHECK_EQ DCHECK_EQ +#define S2_DCHECK_NE DCHECK_NE +#define S2_DCHECK_LT DCHECK_LT +#define S2_DCHECK_LE DCHECK_LE +#define S2_DCHECK_GT DCHECK_GT +#define S2_DCHECK_GE DCHECK_GE + +#define S2_VLOG VLOG +#define S2_VLOG_IS_ON VLOG_IS_ON + +#else // !defined(S2_USE_GLOG) + +#include + +#include "s2/base/log_severity.h" +#include "s2/third_party/absl/base/attributes.h" +#include "s2/third_party/absl/base/log_severity.h" + +class S2LogMessage { + public: + S2LogMessage(const char* file, int line, + absl::LogSeverity severity, std::ostream& stream) + : severity_(severity), stream_(stream) { + if (enabled()) { + stream_ << file << ":" << line << " " + << absl::LogSeverityName(severity) << " "; + } + } + ~S2LogMessage() { if (enabled()) stream_ << std::endl; } + + std::ostream& stream() { return stream_; } + + // silences an 'unused member' compiler warning + absl::LogSeverity severity() { return severity_; } + + private: + bool enabled() const { +#ifdef ABSL_MIN_LOG_LEVEL + return (static_cast(severity_) >= ABSL_MIN_LOG_LEVEL || + severity_ >= absl::LogSeverity::kFatal); +#else + return true; +#endif + } + + absl::LogSeverity severity_; + std::ostream& stream_; +}; + +// Same as S2LogMessage, but destructor is marked no-return to avoid +// "no return value warnings" in functions that return non-void. +class S2FatalLogMessage : public S2LogMessage { + public: + S2FatalLogMessage(const char* file, int line, + absl::LogSeverity severity, std::ostream& stream) + ABSL_ATTRIBUTE_COLD + : S2LogMessage(file, line, severity, stream) {} + ABSL_ATTRIBUTE_NORETURN ~S2FatalLogMessage() { cpp_compat_abort(); } +}; + +// Logging stream that does nothing. +struct S2NullStream { + template + S2NullStream& operator<<(const T& v) { return *this; } +}; + +// Used to suppress "unused value" warnings. +struct S2LogMessageVoidify { + // Must have precedence lower than << but higher than ?:. + void operator&(std::ostream&) {} +}; + +#define S2_LOG_MESSAGE_(LogMessageClass, log_severity) \ + LogMessageClass(__FILE__, __LINE__, log_severity, cpp_compat_cerr) +#define S2_LOG_INFO \ + S2_LOG_MESSAGE_(S2LogMessage, absl::LogSeverity::kInfo) +#define S2_LOG_WARNING \ + S2_LOG_MESSAGE_(S2LogMessage, absl::LogSeverity::kWarning) +#define S2_LOG_ERROR \ + S2_LOG_MESSAGE_(S2LogMessage, absl::LogSeverity::kError) +#define S2_LOG_FATAL \ + S2_LOG_MESSAGE_(S2FatalLogMessage, absl::LogSeverity::kFatal) +#ifndef NDEBUG +#define S2_LOG_DFATAL S2_LOG_FATAL +#else +#define S2_LOG_DFATAL S2_LOG_ERROR +#endif + +#define S2_LOG(severity) S2_LOG_##severity.stream() + +// Implementing this as if (...) {} else S2_LOG(...) will cause dangling else +// warnings when someone does if (...) S2_LOG_IF(...), so do this tricky +// thing instead. +#define S2_LOG_IF(severity, condition) \ + !(condition) ? (void)0 : S2LogMessageVoidify() & S2_LOG(severity) + +#define S2_CHECK(condition) \ + S2_LOG_IF(FATAL, ABSL_PREDICT_FALSE(!(condition))) \ + << ("Check failed: " #condition " ") + +#ifndef NDEBUG + +#define S2_DLOG_IF S2_LOG_IF +#define S2_DCHECK S2_CHECK + +#else // defined(NDEBUG) + +#define S2_DLOG_IF(severity, condition) \ + while (false && (condition)) S2NullStream() +#define S2_DCHECK(condition) \ + while (false && (condition)) S2NullStream() + +#endif // defined(NDEBUG) + +#define S2_CHECK_OP(op, val1, val2) S2_CHECK((val1) op (val2)) +#define S2_CHECK_EQ(val1, val2) S2_CHECK_OP(==, val1, val2) +#define S2_CHECK_NE(val1, val2) S2_CHECK_OP(!=, val1, val2) +#define S2_CHECK_LT(val1, val2) S2_CHECK_OP(<, val1, val2) +#define S2_CHECK_LE(val1, val2) S2_CHECK_OP(<=, val1, val2) +#define S2_CHECK_GT(val1, val2) S2_CHECK_OP(>, val1, val2) +#define S2_CHECK_GE(val1, val2) S2_CHECK_OP(>=, val1, val2) + +#define S2_DCHECK_OP(op, val1, val2) S2_DCHECK((val1) op (val2)) +#define S2_DCHECK_EQ(val1, val2) S2_DCHECK_OP(==, val1, val2) +#define S2_DCHECK_NE(val1, val2) S2_DCHECK_OP(!=, val1, val2) +#define S2_DCHECK_LT(val1, val2) S2_DCHECK_OP(<, val1, val2) +#define S2_DCHECK_LE(val1, val2) S2_DCHECK_OP(<=, val1, val2) +#define S2_DCHECK_GT(val1, val2) S2_DCHECK_OP(>, val1, val2) +#define S2_DCHECK_GE(val1, val2) S2_DCHECK_OP(>=, val1, val2) + +// We don't support VLOG. +#define S2_VLOG(verbose_level) S2NullStream() +#define S2_VLOG_IS_ON(verbose_level) (false) + +#endif // !defined(S2_USE_GLOG) + +#endif // S2_BASE_LOGGING_H_ diff --git a/inst/include/s2/base/mutex.h b/inst/include/s2/base/mutex.h new file mode 100644 index 0000000..031d21e --- /dev/null +++ b/inst/include/s2/base/mutex.h @@ -0,0 +1,61 @@ +// Copyright Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS-IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#ifndef S2_BASE_MUTEX_H_ +#define S2_BASE_MUTEX_H_ + +#include +#include + +namespace absl { + +class Mutex { + public: + Mutex() = default; + ~Mutex() = default; + Mutex(Mutex const&) = delete; + Mutex& operator=(Mutex const&) = delete; + + inline void Lock() { mutex_.lock(); } + inline void Unlock() { mutex_.unlock(); } + + private: + std::mutex mutex_; + + friend class CondVar; +}; + +class CondVar { + public: + CondVar() = default; + ~CondVar() = default; + CondVar(CondVar const&) = delete; + CondVar& operator=(CondVar const&) = delete; + + inline void Wait(Mutex* mu) { + std::unique_lock lock(mu->mutex_, std::adopt_lock); + cond_var_.wait(lock); + lock.release(); + } + inline void Signal() { cond_var_.notify_one(); } + inline void SignalAll() { cond_var_.notify_all(); } + + private: + std::condition_variable cond_var_; +}; + +} // namespace absl + +#endif // S2_BASE_MUTEX_H_ diff --git a/inst/include/s2/base/port.h b/inst/include/s2/base/port.h new file mode 100644 index 0000000..70d6675 --- /dev/null +++ b/inst/include/s2/base/port.h @@ -0,0 +1,1013 @@ +// Copyright Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS-IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#ifndef S2_BASE_PORT_H_ +#define S2_BASE_PORT_H_ + +// This file contains things that are not used in third_party/absl but needed by +// - Platform specific requirement +// - MSVC +// - Utility macros +// - Endianness +// - Hash +// - Global variables +// - Type alias +// - Predefined system/language macros +// - Predefined system/language functions +// - Performance optimization (alignment) +// - Obsolete + +#include +#include +#include +#include + +#include "s2/base/integral_types.h" +#include "s2/third_party/absl/base/config.h" +#include "s2/third_party/absl/base/port.h" + +#ifdef SWIG +%include "third_party/absl/base/port.h" +#endif + +// ----------------------------------------------------------------------------- +// MSVC Specific Requirements +// ----------------------------------------------------------------------------- + +#ifdef _MSC_VER /* if Visual C++ */ + +#include // Must come before +#include +#include // _getpid() +#include +#undef ERROR +#undef DELETE +#undef DIFFERENCE +#define STDIN_FILENO 0 +#define STDOUT_FILENO 1 +#define STDERR_FILENO 2 +#define S_IRUSR 00400 +#define S_IWUSR 00200 +#define S_IXUSR 00100 +#define S_IRGRP 00040 +#define S_IWGRP 00020 +#define S_IXGRP 00010 +#define S_IROTH 00004 +#define S_IWOTH 00002 +#define S_IXOTH 00001 + +// This compiler flag can be easily overlooked on MSVC. +// _CHAR_UNSIGNED gets set with the /J flag. +#ifndef _CHAR_UNSIGNED +#error chars must be unsigned! Use the /J flag on the compiler command line. // NOLINT +#endif + +// Allow comparisons between signed and unsigned values. +// +// Lots of Google code uses this pattern: +// for (int i = 0; i < container.size(); ++i) +// Since size() returns an unsigned value, this warning would trigger +// frequently. Very few of these instances are actually bugs since containers +// rarely exceed MAX_INT items. Unfortunately, there are bugs related to +// signed-unsigned comparisons that have been missed because we disable this +// warning. For example: +// const long stop_time = os::GetMilliseconds() + kWaitTimeoutMillis; +// while (os::GetMilliseconds() <= stop_time) { ... } +#pragma warning(disable : 4018) // level 3 +#pragma warning(disable : 4267) // level 3 + +// Don't warn about unused local variables. +// +// extension to silence particular instances of this warning. There's no way +// to define ABSL_ATTRIBUTE_UNUSED to quiet particular instances of this warning +// in VC++, so we disable it globally. Currently, there aren't many false +// positives, so perhaps we can address those in the future and re-enable these +// warnings, which sometimes catch real bugs. +#pragma warning(disable : 4101) // level 3 + +// Allow initialization and assignment to a smaller type without warnings about +// possible loss of data. +// +// There is a distinct warning, 4267, that warns about size_t conversions to +// smaller types, but we don't currently disable that warning. +// +// Correct code can be written in such a way as to avoid false positives +// by making the conversion explicit, but Google code isn't usually that +// verbose. There are too many false positives to address at this time. Note +// that this warning triggers at levels 2, 3, and 4 depending on the specific +// type of conversion. By disabling it, we not only silence minor narrowing +// conversions but also serious ones. +#pragma warning(disable : 4244) // level 2, 3, and 4 + +// Allow silent truncation of double to float. +// +// Silencing this warning has caused us to miss some subtle bugs. +#pragma warning(disable : 4305) // level 1 + +// Allow a constant to be assigned to a type that is too small. +// +// I don't know why we allow this at all. I can't think of a case where this +// wouldn't be a bug, but enabling the warning breaks many builds today. +#pragma warning(disable : 4307) // level 2 + +// Allow passing the this pointer to an initializer even though it refers +// to an uninitialized object. +// +// Some observer implementations rely on saving the this pointer. Those are +// safe because the pointer is not dereferenced until after the object is fully +// constructed. This could however, obscure other instances. In the future, we +// should look into disabling this warning locally rather globally. +#pragma warning(disable : 4355) // level 1 and 4 + +// Allow implicit coercion from an integral type to a bool. +// +// These could be avoided by making the code more explicit, but that's never +// been the style here, so there would be many false positives. It's not +// obvious if a true positive would ever help to find an actual bug. +#pragma warning(disable : 4800) // level 3 + +#endif // _MSC_VER + +// ----------------------------------------------------------------------------- +// Utility Macros +// ----------------------------------------------------------------------------- + +// OS_IOS +#if defined(__APPLE__) +// Currently, blaze supports iOS yet doesn't define a flag. Mac users have +// traditionally defined OS_IOS themselves via other build systems, since mac +// hasn't been supported by blaze. +// TODO(user): Remove this when all toolchains make the proper defines. +#include +#if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE +#ifndef OS_IOS +#define OS_IOS 1 +#endif +#endif // defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE +#endif // defined(__APPLE__) + +// __GLIBC_PREREQ +#if defined __linux__ +// GLIBC-related macros. +#include + +#ifndef __GLIBC_PREREQ +#define __GLIBC_PREREQ(a, b) 0 // not a GLIBC system +#endif +#endif // __linux__ + +// STATIC_ANALYSIS +// Klocwork static analysis tool's C/C++ complier kwcc +#if defined(__KLOCWORK__) +#define STATIC_ANALYSIS +#endif // __KLOCWORK__ + +// SIZEOF_MEMBER, OFFSETOF_MEMBER +#define SIZEOF_MEMBER(t, f) sizeof(reinterpret_cast(4096)->f) + +#define OFFSETOF_MEMBER(t, f) \ + (reinterpret_cast(&(reinterpret_cast(16)->f)) - \ + reinterpret_cast(16)) + +// LANG_CXX11 +// GXX_EXPERIMENTAL_CXX0X is defined by gcc and clang up to at least +// gcc-4.7 and clang-3.1 (2011-12-13). __cplusplus was defined to 1 +// in gcc before 4.7 (Crosstool 16) and clang before 3.1, but is +// defined according to the language version in effect thereafter. +// Microsoft Visual Studio 14 (2015) sets __cplusplus==199711 despite +// reasonably good C++11 support, so we set LANG_CXX for it and +// newer versions (_MSC_VER >= 1900). +#if (defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L || \ + (defined(_MSC_VER) && _MSC_VER >= 1900)) +// DEPRECATED: Do not key off LANG_CXX11. Instead, write more accurate condition +// that checks whether the C++ feature you need is available or missing, and +// define a more specific feature macro (GOOGLE_HAVE_FEATURE_FOO). You can check +// http://en.cppreference.com/w/cpp/compiler_support for compiler support on C++ +// features. +// Define this to 1 if the code is compiled in C++11 mode; leave it +// undefined otherwise. Do NOT define it to 0 -- that causes +// '#ifdef LANG_CXX11' to behave differently from '#if LANG_CXX11'. +#define LANG_CXX11 1 +#endif + +// This sanity check can be removed when all references to +// LANG_CXX11 is removed from the code base. +#if defined(__cplusplus) && !defined(LANG_CXX11) && !defined(SWIG) +#error "LANG_CXX11 is required." +#endif + +// GOOGLE_OBSCURE_SIGNAL +#if defined(__APPLE__) +// No SIGPWR on MacOSX. SIGINFO seems suitably obscure. +#define GOOGLE_OBSCURE_SIGNAL SIGINFO +#else +/* We use SIGPWR since that seems unlikely to be used for other reasons. */ +#define GOOGLE_OBSCURE_SIGNAL SIGPWR +#endif + +// ABSL_FUNC_PTR_TO_CHAR_PTR +// On some platforms, a "function pointer" points to a function descriptor +// rather than directly to the function itself. +// Use ABSL_FUNC_PTR_TO_CHAR_PTR(func) to get a char-pointer to the first +// instruction of the function func. +// TODO(b/30407660): Move this macro into Abseil when symbolizer is released in +// Abseil. +#if defined(__cplusplus) +#if (defined(__powerpc__) && !(_CALL_ELF > 1)) || defined(__ia64) +// use opd section for function descriptors on these platforms, the function +// address is the first word of the descriptor +namespace absl { +enum { kPlatformUsesOPDSections = 1 }; +} // namespace absl +#define ABSL_FUNC_PTR_TO_CHAR_PTR(func) (reinterpret_cast(func)[0]) +#else // not PPC or IA64 +namespace absl { +enum { kPlatformUsesOPDSections = 0 }; +} // namespace absl +#define ABSL_FUNC_PTR_TO_CHAR_PTR(func) (reinterpret_cast(func)) +#endif // PPC or IA64 +#endif // __cplusplus + +// ----------------------------------------------------------------------------- +// Utility Functions +// ----------------------------------------------------------------------------- + +// sized_delete +#ifdef __cplusplus +namespace base { +// We support C++14's sized deallocation for all C++ builds, +// though for other toolchains, we fall back to using delete. +inline void sized_delete(void *ptr, size_t size) { +#ifdef GOOGLE_HAVE_SIZED_DELETE + ::operator delete(ptr, size); +#else + (void)size; + ::operator delete(ptr); +#endif // GOOGLE_HAVE_SIZED_DELETE +} + +inline void sized_delete_array(void *ptr, size_t size) { +#ifdef GOOGLE_HAVE_SIZED_DELETEARRAY + ::operator delete[](ptr, size); +#else + (void) size; + ::operator delete[](ptr); +#endif +} +} // namespace base +#endif // __cplusplus + +// ----------------------------------------------------------------------------- +// Endianness +// ----------------------------------------------------------------------------- + +// IS_LITTLE_ENDIAN, IS_BIG_ENDIAN + +// Allow compiler -D defines to override detection here +// which occasionally fails (e.g., on CRAN Solaris) +#if defined(IS_LITTLE_ENDIAN) +#undef IS_BIG_ENDIAN +#elif defined(IS_BIG_ENDIAN) +#undef IS_LITTLE_ENDIAN +#else + +#if defined __linux__ || defined OS_ANDROID || defined(__ANDROID__) +// TODO(user): http://b/21460321; use one of OS_ANDROID or __ANDROID__. +// _BIG_ENDIAN +#include + +#elif defined(__APPLE__) + +// BIG_ENDIAN +#include // NOLINT(build/include) +/* Let's try and follow the Linux convention */ +#define __BYTE_ORDER BYTE_ORDER +#define __LITTLE_ENDIAN LITTLE_ENDIAN +#define __BIG_ENDIAN BIG_ENDIAN + +#endif + +// defines __BYTE_ORDER for MSVC +#ifdef _MSC_VER +#define __BYTE_ORDER __LITTLE_ENDIAN +#define IS_LITTLE_ENDIAN +#else + +// define the macros IS_LITTLE_ENDIAN or IS_BIG_ENDIAN +// using the above endian definitions from endian.h if +// endian.h was included +#ifdef __BYTE_ORDER +#if __BYTE_ORDER == __LITTLE_ENDIAN +#define IS_LITTLE_ENDIAN +#endif + +#if __BYTE_ORDER == __BIG_ENDIAN +#define IS_BIG_ENDIAN +#endif + +#else // __BYTE_ORDER + +#if defined(__LITTLE_ENDIAN__) +#define IS_LITTLE_ENDIAN +#elif defined(__BIG_ENDIAN__) +#define IS_BIG_ENDIAN +#endif + +#endif // __BYTE_ORDER +#endif // _MSC_VER +#endif // #if defined(IS_LITTLE_ENDIAN) ... #else + +// byte swap functions (bswap_16, bswap_32, bswap_64). + +// The following guarantees declaration of the byte swap functions +#ifdef _MSC_VER +#include // NOLINT(build/include) +#define bswap_16(x) _byteswap_ushort(x) +#define bswap_32(x) _byteswap_ulong(x) +#define bswap_64(x) _byteswap_uint64(x) + +#elif defined(__APPLE__) +// Mac OS X / Darwin features +#include +#define bswap_16(x) OSSwapInt16(x) +#define bswap_32(x) OSSwapInt32(x) +#define bswap_64(x) OSSwapInt64(x) + +#elif defined(__GLIBC__) || defined(__BIONIC__) || defined(__ASYLO__) +#include // IWYU pragma: export + +#else + +static inline uint16 bswap_16(uint16 x) { +#ifdef __cplusplus + return static_cast(((x & 0xFF) << 8) | ((x & 0xFF00) >> 8)); +#else + return (uint16)(((x & 0xFF) << 8) | ((x & 0xFF00) >> 8)); // NOLINT +#endif // __cplusplus +} +#define bswap_16(x) bswap_16(x) +static inline uint32 bswap_32(uint32 x) { + return (((x & 0xFF) << 24) | + ((x & 0xFF00) << 8) | + ((x & 0xFF0000) >> 8) | + ((x & 0xFF000000) >> 24)); +} +#define bswap_32(x) bswap_32(x) +static inline uint64 bswap_64(uint64 x) { + return (((x & 0xFFULL) << 56) | + ((x & 0xFF00ULL) << 40) | + ((x & 0xFF0000ULL) << 24) | + ((x & 0xFF000000ULL) << 8) | + ((x & 0xFF00000000ULL) >> 8) | + ((x & 0xFF0000000000ULL) >> 24) | + ((x & 0xFF000000000000ULL) >> 40) | + ((x & 0xFF00000000000000ULL) >> 56)); +} +#define bswap_64(x) bswap_64(x) + +#endif + +// ----------------------------------------------------------------------------- +// Hash +// ----------------------------------------------------------------------------- + +#ifdef __cplusplus +#ifdef STL_MSVC // not always the same as _MSC_VER +#include "s2/third_party/absl/base/internal/port_hash.inc" +#else +struct PortableHashBase {}; +#endif // STL_MSVC +#endif // __cplusplus + +// ----------------------------------------------------------------------------- +// Global Variables +// ----------------------------------------------------------------------------- + +// PATH_SEPARATOR +// Define the OS's path separator +// +// NOTE: Assuming the path separator at compile time is discouraged. +// Prefer instead to be tolerant of both possible separators whenever possible. +#ifdef __cplusplus // C won't merge duplicate const variables at link time +// Some headers provide a macro for this (GCC's system.h), remove it so that we +// can use our own. +#undef PATH_SEPARATOR +#if defined(_WIN32) +const char PATH_SEPARATOR = '\\'; +#else +const char PATH_SEPARATOR = '/'; +#endif // _WIN32 +#endif // __cplusplus + +// ----------------------------------------------------------------------------- +// Type Alias +// ----------------------------------------------------------------------------- + +// uint, ushort, ulong +#if defined __linux__ +// The uint mess: +// mysql.h sets _GNU_SOURCE which sets __USE_MISC in +// sys/types.h typedefs uint if __USE_MISC +// mysql typedefs uint if HAVE_UINT not set +// The following typedef is carefully considered, and should not cause +// any clashes +#if !defined(__USE_MISC) +#if !defined(HAVE_UINT) +#define HAVE_UINT 1 +typedef unsigned int uint; +#endif // !HAVE_UINT +#if !defined(HAVE_USHORT) +#define HAVE_USHORT 1 +typedef unsigned short ushort; // NOLINT +#endif // !HAVE_USHORT +#if !defined(HAVE_ULONG) +#define HAVE_ULONG 1 +typedef unsigned long ulong; // NOLINT +#endif // !HAVE_ULONG +#endif // !__USE_MISC + +#endif // __linux__ + +#ifdef _MSC_VER /* if Visual C++ */ +// VC++ doesn't understand "uint" +#ifndef HAVE_UINT +#define HAVE_UINT 1 +typedef unsigned int uint; +#endif // !HAVE_UINT +#endif // _MSC_VER + +#ifdef _MSC_VER +// uid_t +// MSVC doesn't have uid_t +typedef int uid_t; + +// pid_t +// Defined all over the place. +typedef int pid_t; +#endif // _MSC_VER + +// mode_t +#ifdef _MSC_VER +// From stat.h +typedef unsigned int mode_t; +#endif // _MSC_VER + +// sig_t +#ifdef _MSC_VER +typedef void (*sig_t)(int); +#endif // _MSC_VER + +// u_int16_t, int16_t +#ifdef _MSC_VER +// u_int16_t, int16_t don't exist in MSVC +typedef unsigned short u_int16_t; // NOLINT +typedef short int16_t; // NOLINT +#endif // _MSC_VER + +// using std::hash +#ifdef _MSC_VER +#ifdef __cplusplus +// Define a minimal set of things typically available in the global +// namespace in Google code. ::string is handled elsewhere, and uniformly +// for all targets. +#include +using std::hash; +#endif // __cplusplus +#endif // _MSC_VER + +// printf macros +// __STDC_FORMAT_MACROS must be defined before inttypes.h inclusion */ +#if defined(__APPLE__) +/* From MacOSX's inttypes.h: + * "C++ implementations should define these macros only when + * __STDC_FORMAT_MACROS is defined before is included." */ +#ifndef __STDC_FORMAT_MACROS +#define __STDC_FORMAT_MACROS +#endif /* __STDC_FORMAT_MACROS */ +#endif /* __APPLE__ */ + +// printf macros for size_t, in the style of inttypes.h +#if defined(_LP64) || defined(__APPLE__) +#define __PRIS_PREFIX "z" +#else +#define __PRIS_PREFIX +#endif + +// Use these macros after a % in a printf format string +// to get correct 32/64 bit behavior, like this: +// size_t size = records.size(); +// printf("%" PRIuS "\n", size); +#define PRIdS __PRIS_PREFIX "d" +#define PRIxS __PRIS_PREFIX "x" +#define PRIuS __PRIS_PREFIX "u" +#define PRIXS __PRIS_PREFIX "X" +#define PRIoS __PRIS_PREFIX "o" + +#define GPRIuPTHREAD "lu" +#define GPRIxPTHREAD "lx" +#if defined(__APPLE__) +#define PRINTABLE_PTHREAD(pthreadt) reinterpret_cast(pthreadt) +#else +#define PRINTABLE_PTHREAD(pthreadt) pthreadt +#endif + +#ifdef PTHREADS_REDHAT_WIN32 +#include // NOLINT(build/include) +#include // NOLINT(build/include) +// pthread_t is not a simple integer or pointer on Win32 +std::ostream &operator<<(std::ostream &out, const pthread_t &thread_id); +#endif + +// ----------------------------------------------------------------------------- +// Predefined System/Language Macros +// ----------------------------------------------------------------------------- + +// EXFULL +#if defined(__APPLE__) +// Linux has this in +#define EXFULL ENOMEM // not really that great a translation... +#endif // __APPLE__ +#ifdef _MSC_VER +// This actually belongs in errno.h but there's a name conflict in errno +// on WinNT. They (and a ton more) are also found in Winsock2.h, but +// if'd out under NT. We need this subset at minimum. +#define EXFULL ENOMEM // not really that great a translation... +#endif // _MSC_VER + +// MSG_NOSIGNAL +#if defined(__APPLE__) +// Doesn't exist on OSX. +#define MSG_NOSIGNAL 0 +#endif // __APPLE__ + +// __ptr_t +#if defined(__APPLE__) +// Linux has this in +#define __ptr_t void * +#endif // __APPLE__ +#ifdef _MSC_VER +// From glob.h +#define __ptr_t void * +#endif + +// HUGE_VALF +#ifdef _MSC_VER +#include // for HUGE_VAL + +#ifndef HUGE_VALF +#define HUGE_VALF (static_cast(HUGE_VAL)) +#endif +#endif // _MSC_VER + +// MAP_ANONYMOUS +#if defined(__APPLE__) +// For mmap, Linux defines both MAP_ANONYMOUS and MAP_ANON and says MAP_ANON is +// deprecated. In Darwin, MAP_ANON is all there is. +#if !defined MAP_ANONYMOUS +#define MAP_ANONYMOUS MAP_ANON +#endif // !MAP_ANONYMOUS +#endif // __APPLE__ + +// PATH_MAX +// You say tomato, I say atotom +#ifdef _MSC_VER +#define PATH_MAX MAX_PATH +#endif + +// ----------------------------------------------------------------------------- +// Predefined System/Language Functions +// ----------------------------------------------------------------------------- + +// strtoq, strtouq, atoll +#ifdef _MSC_VER +#define strtoq _strtoi64 +#define strtouq _strtoui64 +#define atoll _atoi64 +#endif // _MSC_VER + +#ifdef _MSC_VER +// You say tomato, I say _tomato +#define strcasecmp _stricmp +#define strncasecmp _strnicmp +#define strdup _strdup +#define tempnam _tempnam +#define chdir _chdir +#define getpid _getpid +#define getcwd _getcwd +#define putenv _putenv +#define timezone _timezone +#define tzname _tzname +#endif // _MSC_VER + +// random, srandom +#ifdef _MSC_VER +// You say tomato, I say toma +inline int random() { return rand(); } +inline void srandom(unsigned int seed) { srand(seed); } +#endif // _MSC_VER + +// bcopy, bzero +#ifdef _MSC_VER +// You say juxtapose, I say transpose +#define bcopy(s, d, n) memcpy(d, s, n) +// Really from +inline void bzero(void *s, int n) { memset(s, 0, n); } +#endif // _MSC_VER + +// gethostbyname +#if defined(_WIN32) || defined(__APPLE__) +// gethostbyname() *is* thread-safe for Windows native threads. It is also +// safe on Mac OS X and iOS, where it uses thread-local storage, even though the +// manpages claim otherwise. For details, see +// http://lists.apple.com/archives/Darwin-dev/2006/May/msg00008.html +#else +// gethostbyname() is not thread-safe. So disallow its use. People +// should either use the HostLookup::Lookup*() methods, or gethostbyname_r() +#define gethostbyname gethostbyname_is_not_thread_safe_DO_NOT_USE +#endif + +// ----------------------------------------------------------------------------- +// Performance Optimization +// ----------------------------------------------------------------------------- + +// Alignment + +// Unaligned APIs + +// Portable handling of unaligned loads, stores, and copies. +// On some platforms, like ARM, the copy functions can be more efficient +// then a load and a store. +// +// It is possible to implement all of these these using constant-length memcpy +// calls, which is portable and will usually be inlined into simple loads and +// stores if the architecture supports it. However, such inlining usually +// happens in a pass that's quite late in compilation, which means the resulting +// loads and stores cannot participate in many other optimizations, leading to +// overall worse code. +// TODO(user): These APIs are forked in Abseil, see +// LLVM, we should reimplement these APIs with functions calling memcpy(), and +// maybe publish them in Abseil. + +// The unaligned API is C++ only. The declarations use C++ features +// (namespaces, inline) which are absent or incompatible in C. +#if defined(__cplusplus) + +#if defined(ADDRESS_SANITIZER) || defined(THREAD_SANITIZER) || \ + defined(MEMORY_SANITIZER) +// Consider we have an unaligned load/store of 4 bytes from address 0x...05. +// AddressSanitizer will treat it as a 3-byte access to the range 05:07 and +// will miss a bug if 08 is the first unaddressable byte. +// ThreadSanitizer will also treat this as a 3-byte access to 05:07 and will +// miss a race between this access and some other accesses to 08. +// MemorySanitizer will correctly propagate the shadow on unaligned stores +// and correctly report bugs on unaligned loads, but it may not properly +// update and report the origin of the uninitialized memory. +// For all three tools, replacing an unaligned access with a tool-specific +// callback solves the problem. + +// Make sure uint16_t/uint32_t/uint64_t are defined. +#include + +extern "C" { +uint16_t __sanitizer_unaligned_load16(const void *p); +uint32_t __sanitizer_unaligned_load32(const void *p); +uint64_t __sanitizer_unaligned_load64(const void *p); +void __sanitizer_unaligned_store16(void *p, uint16_t v); +void __sanitizer_unaligned_store32(void *p, uint32_t v); +void __sanitizer_unaligned_store64(void *p, uint64_t v); +} // extern "C" + +inline uint16 UNALIGNED_LOAD16(const void *p) { + return __sanitizer_unaligned_load16(p); +} + +inline uint32 UNALIGNED_LOAD32(const void *p) { + return __sanitizer_unaligned_load32(p); +} + +inline uint64 UNALIGNED_LOAD64(const void *p) { + return __sanitizer_unaligned_load64(p); +} + +inline void UNALIGNED_STORE16(void *p, uint16 v) { + __sanitizer_unaligned_store16(p, v); +} + +inline void UNALIGNED_STORE32(void *p, uint32 v) { + __sanitizer_unaligned_store32(p, v); +} + +inline void UNALIGNED_STORE64(void *p, uint64 v) { + __sanitizer_unaligned_store64(p, v); +} + +#elif defined(UNDEFINED_BEHAVIOR_SANITIZER) + +inline uint16 UNALIGNED_LOAD16(const void *p) { + uint16 t; + memcpy(&t, p, sizeof t); + return t; +} + +inline uint32 UNALIGNED_LOAD32(const void *p) { + uint32 t; + memcpy(&t, p, sizeof t); + return t; +} + +inline uint64 UNALIGNED_LOAD64(const void *p) { + uint64 t; + memcpy(&t, p, sizeof t); + return t; +} + +inline void UNALIGNED_STORE16(void *p, uint16 v) { memcpy(p, &v, sizeof v); } + +inline void UNALIGNED_STORE32(void *p, uint32 v) { memcpy(p, &v, sizeof v); } + +inline void UNALIGNED_STORE64(void *p, uint64 v) { memcpy(p, &v, sizeof v); } + +#elif defined(__x86_64__) || defined(_M_X64) || defined(__i386) || \ + defined(_M_IX86) || defined(__ppc__) || defined(__PPC__) || \ + defined(__ppc64__) || defined(__PPC64__) + +// x86 and x86-64 can perform unaligned loads/stores directly; +// modern PowerPC hardware can also do unaligned integer loads and stores; +// but note: the FPU still sends unaligned loads and stores to a trap handler! + +#define UNALIGNED_LOAD16(_p) (*reinterpret_cast(_p)) +#define UNALIGNED_LOAD32(_p) (*reinterpret_cast(_p)) +#define UNALIGNED_LOAD64(_p) (*reinterpret_cast(_p)) + +#define UNALIGNED_STORE16(_p, _val) (*reinterpret_cast(_p) = (_val)) +#define UNALIGNED_STORE32(_p, _val) (*reinterpret_cast(_p) = (_val)) +#define UNALIGNED_STORE64(_p, _val) (*reinterpret_cast(_p) = (_val)) + +#elif defined(__arm__) && !defined(__ARM_ARCH_5__) && \ + !defined(__ARM_ARCH_5T__) && !defined(__ARM_ARCH_5TE__) && \ + !defined(__ARM_ARCH_5TEJ__) && !defined(__ARM_ARCH_6__) && \ + !defined(__ARM_ARCH_6J__) && !defined(__ARM_ARCH_6K__) && \ + !defined(__ARM_ARCH_6Z__) && !defined(__ARM_ARCH_6ZK__) && \ + !defined(__ARM_ARCH_6T2__) + +// ARMv7 and newer support native unaligned accesses, but only of 16-bit +// and 32-bit values (not 64-bit); older versions either raise a fatal signal, +// do an unaligned read and rotate the words around a bit, or do the reads very +// slowly (trip through kernel mode). There's no simple #define that says just +// “ARMv7 or higher”, so we have to filter away all ARMv5 and ARMv6 +// sub-architectures. Newer gcc (>= 4.6) set an __ARM_FEATURE_ALIGNED #define, +// so in time, maybe we can move on to that. +// +// This is a mess, but there's not much we can do about it. +// +// To further complicate matters, only LDR instructions (single reads) are +// allowed to be unaligned, not LDRD (two reads) or LDM (many reads). Unless we +// explicitly tell the compiler that these accesses can be unaligned, it can and +// will combine accesses. On armcc, the way to signal this is done by accessing +// through the type (uint32 __packed *), but GCC has no such attribute +// (it ignores __attribute__((packed)) on individual variables). However, +// we can tell it that a _struct_ is unaligned, which has the same effect, +// so we do that. + +namespace base { +namespace internal { + +struct Unaligned16Struct { + uint16 value; + uint8 dummy; // To make the size non-power-of-two. +} ABSL_ATTRIBUTE_PACKED; + +struct Unaligned32Struct { + uint32 value; + uint8 dummy; // To make the size non-power-of-two. +} ABSL_ATTRIBUTE_PACKED; + +} // namespace internal +} // namespace base + +#define UNALIGNED_LOAD16(_p) \ + ((reinterpret_cast(_p))->value) +#define UNALIGNED_LOAD32(_p) \ + ((reinterpret_cast(_p))->value) + +#define UNALIGNED_STORE16(_p, _val) \ + ((reinterpret_cast< ::base::internal::Unaligned16Struct *>(_p))->value = \ + (_val)) +#define UNALIGNED_STORE32(_p, _val) \ + ((reinterpret_cast< ::base::internal::Unaligned32Struct *>(_p))->value = \ + (_val)) + +// TODO(user): NEON supports unaligned 64-bit loads and stores. +// See if that would be more efficient on platforms supporting it, +// at least for copies. + +inline uint64 UNALIGNED_LOAD64(const void *p) { + uint64 t; + memcpy(&t, p, sizeof t); + return t; +} + +inline void UNALIGNED_STORE64(void *p, uint64 v) { memcpy(p, &v, sizeof v); } + +#else + +#define NEED_ALIGNED_LOADS + +// These functions are provided for architectures that don't support +// unaligned loads and stores. + +inline uint16 UNALIGNED_LOAD16(const void *p) { + uint16 t; + memcpy(&t, p, sizeof t); + return t; +} + +inline uint32 UNALIGNED_LOAD32(const void *p) { + uint32 t; + memcpy(&t, p, sizeof t); + return t; +} + +inline uint64 UNALIGNED_LOAD64(const void *p) { + uint64 t; + memcpy(&t, p, sizeof t); + return t; +} + +inline void UNALIGNED_STORE16(void *p, uint16 v) { memcpy(p, &v, sizeof v); } + +inline void UNALIGNED_STORE32(void *p, uint32 v) { memcpy(p, &v, sizeof v); } + +inline void UNALIGNED_STORE64(void *p, uint64 v) { memcpy(p, &v, sizeof v); } + +#endif + +// The UNALIGNED_LOADW and UNALIGNED_STOREW macros load and store values +// of type uword_t. +#ifdef _LP64 +#define UNALIGNED_LOADW(_p) UNALIGNED_LOAD64(_p) +#define UNALIGNED_STOREW(_p, _val) UNALIGNED_STORE64(_p, _val) +#else +#define UNALIGNED_LOADW(_p) UNALIGNED_LOAD32(_p) +#define UNALIGNED_STOREW(_p, _val) UNALIGNED_STORE32(_p, _val) +#endif + +inline void UnalignedCopy16(const void *src, void *dst) { + UNALIGNED_STORE16(dst, UNALIGNED_LOAD16(src)); +} + +inline void UnalignedCopy32(const void *src, void *dst) { + UNALIGNED_STORE32(dst, UNALIGNED_LOAD32(src)); +} + +inline void UnalignedCopy64(const void *src, void *dst) { + if (sizeof(void *) == 8) { + UNALIGNED_STORE64(dst, UNALIGNED_LOAD64(src)); + } else { + const char *src_char = reinterpret_cast(src); + char *dst_char = reinterpret_cast(dst); + + UNALIGNED_STORE32(dst_char, UNALIGNED_LOAD32(src_char)); + UNALIGNED_STORE32(dst_char + 4, UNALIGNED_LOAD32(src_char + 4)); + } +} + +#endif // defined(__cplusplus), end of unaligned API + +// aligned_malloc, aligned_free +#if defined(__ANDROID__) || defined(__ASYLO__) || defined(_WIN32) +#include // for memalign() +#endif + +// __ASYLO__ platform uses newlib without an underlying OS, which provides +// memalign, but not posix_memalign. +#if defined(__cplusplus) && \ + (((defined(__GNUC__) || defined(__APPLE__) || \ + defined(__NVCC__)) && \ + !defined(SWIG)) || \ + ((__GNUC__ >= 3 || defined(__clang__)) && defined(__ANDROID__)) || \ + defined(__ASYLO__)) +inline void *aligned_malloc(size_t size, size_t minimum_alignment) { +#if defined(__ANDROID__) || defined(OS_ANDROID) || defined(__ASYLO__) || defined(_WIN32) || defined(__sun) || defined(sun) +# if defined(_WIN32) + return _aligned_malloc(size, minimum_alignment); +# else + return memalign(minimum_alignment, size); +# endif +#else // !__ANDROID__ && !OS_ANDROID && !__ASYLO__ + // posix_memalign requires that the requested alignment be at least + // sizeof(void*). In this case, fall back on malloc which should return memory + // aligned to at least the size of a pointer. + const size_t required_alignment = sizeof(void*); + if (minimum_alignment < required_alignment) + return malloc(size); + void *ptr = nullptr; + if (posix_memalign(&ptr, minimum_alignment, size) == 0) + return ptr; + return nullptr; +#endif +} + +inline void aligned_free(void *aligned_memory) { + free(aligned_memory); +} + +#elif defined(_MSC_VER) // MSVC + +inline void *aligned_malloc(size_t size, size_t minimum_alignment) { + return _aligned_malloc(size, minimum_alignment); +} + +inline void aligned_free(void *aligned_memory) { + _aligned_free(aligned_memory); +} + +#endif // aligned_malloc, aligned_free + +// ALIGNED_CHAR_ARRAY +// +// Provides a char array with the exact same alignment as another type. The +// first parameter must be a complete type, the second parameter is how many +// of that type to provide space for. +// +// ALIGNED_CHAR_ARRAY(struct stat, 16) storage_; +// +#if defined(__cplusplus) +#undef ALIGNED_CHAR_ARRAY +// Because MSVC and older GCCs require that the argument to their alignment +// construct to be a literal constant integer, we use a template instantiated +// at all the possible powers of two. +#ifndef SWIG +template struct AlignType { }; +template struct AlignType<0, size> { typedef char result[size]; }; +#if defined(_MSC_VER) +#define BASE_PORT_H_ALIGN_ATTRIBUTE(X) __declspec(align(X)) +#define BASE_PORT_H_ALIGN_OF(T) __alignof(T) +#elif defined(__GNUC__) || defined(__INTEL_COMPILER) +#define BASE_PORT_H_ALIGN_ATTRIBUTE(X) __attribute__((aligned(X))) +#define BASE_PORT_H_ALIGN_OF(T) __alignof__(T) +#endif + +#if defined(BASE_PORT_H_ALIGN_ATTRIBUTE) + +#define BASE_PORT_H_ALIGNTYPE_TEMPLATE(X) \ + template struct AlignType { \ + typedef BASE_PORT_H_ALIGN_ATTRIBUTE(X) char result[size]; \ + } + +BASE_PORT_H_ALIGNTYPE_TEMPLATE(1); +BASE_PORT_H_ALIGNTYPE_TEMPLATE(2); +BASE_PORT_H_ALIGNTYPE_TEMPLATE(4); +BASE_PORT_H_ALIGNTYPE_TEMPLATE(8); +BASE_PORT_H_ALIGNTYPE_TEMPLATE(16); +BASE_PORT_H_ALIGNTYPE_TEMPLATE(32); +BASE_PORT_H_ALIGNTYPE_TEMPLATE(64); +BASE_PORT_H_ALIGNTYPE_TEMPLATE(128); +BASE_PORT_H_ALIGNTYPE_TEMPLATE(256); +BASE_PORT_H_ALIGNTYPE_TEMPLATE(512); +BASE_PORT_H_ALIGNTYPE_TEMPLATE(1024); +BASE_PORT_H_ALIGNTYPE_TEMPLATE(2048); +BASE_PORT_H_ALIGNTYPE_TEMPLATE(4096); +BASE_PORT_H_ALIGNTYPE_TEMPLATE(8192); +// Any larger and MSVC++ will complain. + +#define ALIGNED_CHAR_ARRAY(T, Size) \ + typename AlignType::result + +#undef BASE_PORT_H_ALIGNTYPE_TEMPLATE +#undef BASE_PORT_H_ALIGN_ATTRIBUTE + +#else // defined(BASE_PORT_H_ALIGN_ATTRIBUTE) +#define ALIGNED_CHAR_ARRAY \ + you_must_define_ALIGNED_CHAR_ARRAY_for_your_compiler_in_base_port_h +#endif // defined(BASE_PORT_H_ALIGN_ATTRIBUTE) + +#else // !SWIG + +// SWIG can't represent alignment and doesn't care about alignment on data +// members (it works fine without it). +template +struct AlignType { typedef char result[Size]; }; +#define ALIGNED_CHAR_ARRAY(T, Size) AlignType::result + +// Enough to parse with SWIG, will never be used by running code. +#define BASE_PORT_H_ALIGN_OF(Type) 16 + +#endif // !SWIG +#else // __cplusplus +#define ALIGNED_CHAR_ARRAY ALIGNED_CHAR_ARRAY_is_not_available_without_Cplusplus +#endif // __cplusplus + +#endif // S2_BASE_PORT_H_ diff --git a/inst/include/s2/base/spinlock.h b/inst/include/s2/base/spinlock.h new file mode 100644 index 0000000..5a5a36f --- /dev/null +++ b/inst/include/s2/base/spinlock.h @@ -0,0 +1,60 @@ +// Copyright Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS-IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#ifndef S2_BASE_SPINLOCK_H_ +#define S2_BASE_SPINLOCK_H_ + +#include + + +class SpinLock { + public: + SpinLock() = default; + ~SpinLock() = default; + SpinLock(SpinLock const&) = delete; + SpinLock& operator=(SpinLock const&) = delete; + + inline void Lock() { + while (locked_.exchange(true, std::memory_order_acquire)) { + // Spin. + continue; + } + } + + inline void Unlock() { + locked_.store(false, std::memory_order_release); + } + + inline bool IsHeld() const { + return locked_.load(std::memory_order_relaxed); + } + + private: + std::atomic_bool locked_{false}; +}; + +class SpinLockHolder { + public: + inline explicit SpinLockHolder(SpinLock* l) : lock_(l) { lock_->Lock(); } + inline ~SpinLockHolder() { lock_->Unlock(); } + + SpinLockHolder(const SpinLockHolder&) = delete; + SpinLockHolder& operator=(const SpinLockHolder&) = delete; + + private: + SpinLock* lock_; +}; + +#endif // S2_BASE_SPINLOCK_H_ diff --git a/inst/include/s2/base/stringprintf.h b/inst/include/s2/base/stringprintf.h new file mode 100644 index 0000000..cb8e775 --- /dev/null +++ b/inst/include/s2/base/stringprintf.h @@ -0,0 +1,53 @@ +// Copyright Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS-IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +// NOTE: See third_party/absl/strings for more options. +// +// As of 2017q4, most use of these routines is considered legacy: use +// of absl::StrCat, absl::Substitute, or absl::StrFormat is preferred for +// performance and safety reasons. + +#ifndef S2_BASE_STRINGPRINTF_H_ +#define S2_BASE_STRINGPRINTF_H_ + +#include +#include +#include + +#include "s2/base/port.h" + +// Return a C++ string +extern string StringPrintf(const char* format, ...) + // Tell the compiler to do printf format string checking. + ABSL_PRINTF_ATTRIBUTE(1, 2); + +// Store result into a supplied string and return it +extern const string& SStringPrintf(string* dst, const char* format, ...) + // Tell the compiler to do printf format string checking. + ABSL_PRINTF_ATTRIBUTE(2, 3); + +// Append result to a supplied string +extern void StringAppendF(string* dst, const char* format, ...) + // Tell the compiler to do printf format string checking. + ABSL_PRINTF_ATTRIBUTE(2, 3); + +// Lower-level routine that takes a va_list and appends to a specified +// string. All other routines are just convenience wrappers around it. +// +// Implementation note: the va_list is never modified, this implementation +// always operates on copies. +extern void StringAppendV(string* dst, const char* format, va_list ap); + +#endif // S2_BASE_STRINGPRINTF_H_ diff --git a/inst/include/s2/base/strtoint.h b/inst/include/s2/base/strtoint.h new file mode 100644 index 0000000..20aeda7 --- /dev/null +++ b/inst/include/s2/base/strtoint.h @@ -0,0 +1,106 @@ +// Copyright 2008 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS-IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +// +// Architecture-neutral plug compatible replacements for strtol() friends. +// +// Long's have different lengths on ILP-32 and LP-64 platforms, and so overflow +// behavior across the two varies when strtol() and similar are used to parse +// 32-bit integers. Similar problems exist with atoi(), because although it +// has an all-integer interface, it uses strtol() internally, and so suffers +// from the same narrowing problems on assignments to int. +// +// Examples: +// errno = 0; +// i = strtol("3147483647", nullptr, 10); +// printf("%d, errno %d\n", i, errno); +// // 32-bit platform: 2147483647, errno 34 +// // 64-bit platform: -1147483649, errno 0 +// +// printf("%d\n", atoi("3147483647")); +// // 32-bit platform: 2147483647 +// // 64-bit platform: -1147483649 +// +// A way round this is to define local replacements for these, and use them +// instead of the standard libc functions. +// +// In most 32-bit cases the replacements can be inlined away to a call to the +// libc function. In a couple of 64-bit cases, however, adapters are required, +// to provide the right overflow and errno behavior. +// + +#ifndef S2_BASE_STRTOINT_H_ +#define S2_BASE_STRTOINT_H_ + +#include // For strtol* functions. +#include +#include "s2/base/integral_types.h" +#include "s2/base/port.h" +#include "s2/third_party/absl/base/macros.h" + +// Adapter functions for handling overflow and errno. +int32 strto32_adapter(const char *nptr, char **endptr, int base); +uint32 strtou32_adapter(const char *nptr, char **endptr, int base); + +// Conversions to a 32-bit integer can pass the call to strto[u]l on 32-bit +// platforms, but need a little extra work on 64-bit platforms. +inline int32 strto32(const char *nptr, char **endptr, int base) { + if (sizeof(int32) == sizeof(long)) + return static_cast(strtol(nptr, endptr, base)); + else + return strto32_adapter(nptr, endptr, base); +} + +inline uint32 strtou32(const char *nptr, char **endptr, int base) { + if (sizeof(uint32) == sizeof(unsigned long)) + return static_cast(strtoul(nptr, endptr, base)); + else + return strtou32_adapter(nptr, endptr, base); +} + +// For now, long long is 64-bit on all the platforms we care about, so these +// functions can simply pass the call to strto[u]ll. +inline int64 strto64(const char *nptr, char **endptr, int base) { + static_assert(sizeof(int64) == sizeof(long long), + "sizeof int64 is not sizeof long long"); + return strtoll(nptr, endptr, base); +} + +inline uint64 strtou64(const char *nptr, char **endptr, int base) { + static_assert(sizeof(uint64) == sizeof(unsigned long long), + "sizeof uint64 is not sizeof long long"); + return strtoull(nptr, endptr, base); +} + +// Although it returns an int, atoi() is implemented in terms of strtol, and +// so has differing overflow and underflow behavior. atol is the same. +inline int32 atoi32(const char *nptr) { + return strto32(nptr, nullptr, 10); +} + +inline int64 atoi64(const char *nptr) { + return strto64(nptr, nullptr, 10); +} + +// Convenience versions of the above that take a string argument. +inline int32 atoi32(const string &s) { + return atoi32(s.c_str()); +} + +inline int64 atoi64(const string &s) { + return atoi64(s.c_str()); +} + +#endif // S2_BASE_STRTOINT_H_ diff --git a/inst/include/s2/base/timer.h b/inst/include/s2/base/timer.h new file mode 100644 index 0000000..90419c5 --- /dev/null +++ b/inst/include/s2/base/timer.h @@ -0,0 +1,50 @@ +// Copyright Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS-IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#ifndef S2_BASE_TIMER_H_ +#define S2_BASE_TIMER_H_ + +#include + +#include "s2/base/integral_types.h" + +class CycleTimer { + public: + CycleTimer() = default; + + void Start() { + start_ = Now(); + } + + int64 GetInMs() const { + using msec = std::chrono::milliseconds; + return std::chrono::duration_cast(GetDuration()).count(); + } + + private: + using Clock = std::chrono::high_resolution_clock; + + static Clock::time_point Now() { + return Clock::now(); + } + + Clock::duration GetDuration() const { + return Now() - start_; + } + + Clock::time_point start_; +}; + +#endif // S2_BASE_TIMER_H_ diff --git a/inst/include/s2/encoded_s2cell_id_vector.h b/inst/include/s2/encoded_s2cell_id_vector.h new file mode 100644 index 0000000..afc738c --- /dev/null +++ b/inst/include/s2/encoded_s2cell_id_vector.h @@ -0,0 +1,110 @@ +// Copyright 2018 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS-IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +// Author: ericv@google.com (Eric Veach) + +#ifndef S2_ENCODED_S2CELL_ID_VECTOR_H_ +#define S2_ENCODED_S2CELL_ID_VECTOR_H_ + +#include "s2/third_party/absl/types/span.h" +#include "s2/encoded_uint_vector.h" +#include "s2/s2cell_id.h" + +namespace s2coding { + +// Encodes a vector of S2CellIds in a format that can later be decoded as an +// EncodedS2CellIdVector. The S2CellIds do not need to be valid. +// +// REQUIRES: "encoder" uses the default constructor, so that its buffer +// can be enlarged as necessary by calling Ensure(int). +void EncodeS2CellIdVector(absl::Span v, Encoder* encoder); + +// This class represents an encoded vector of S2CellIds. Values are decoded +// only when they are accessed. This allows for very fast initialization and +// no additional memory use beyond the encoded data. The encoded data is not +// owned by this class; typically it points into a large contiguous buffer +// that contains other encoded data as well. +// +// This is one of several helper classes that allow complex data structures to +// be initialized from an encoded format in constant time and then decoded on +// demand. This can be a big performance advantage when only a small part of +// the data structure is actually used. +// +// The S2CellIds do not need to be sorted or at the same level. The +// implementation is biased towards minimizing decoding times rather than +// space usage. +// +// NOTE: If your S2CellIds represent S2Points that have been snapped to +// S2CellId centers, then EncodedS2PointVector is both faster and smaller. +class EncodedS2CellIdVector { + public: + // Constructs an uninitialized object; requires Init() to be called. + EncodedS2CellIdVector() {} + + // Initializes the EncodedS2CellIdVector. + // + // REQUIRES: The Decoder data buffer must outlive this object. + bool Init(Decoder* decoder); + + // Returns the size of the original vector. + size_t size() const; + + // Returns the element at the given index. + S2CellId operator[](int i) const; + + // Returns the index of the first element x such that (x >= target), or + // size() if no such element exists. + // + // REQUIRES: The vector elements are sorted in non-decreasing order. + size_t lower_bound(S2CellId target) const; + + // Decodes and returns the entire original vector. + std::vector Decode() const; + + private: + // Values are decoded as (base_ + (deltas_[i] << shift_)). + EncodedUintVector deltas_; + uint64 base_; + uint8 shift_; +}; + + +////////////////// Implementation details follow //////////////////// + + +inline size_t EncodedS2CellIdVector::size() const { + return deltas_.size(); +} + +inline S2CellId EncodedS2CellIdVector::operator[](int i) const { + return S2CellId((deltas_[i] << shift_) + base_); +} + +inline size_t EncodedS2CellIdVector::lower_bound(S2CellId target) const { + // We optimize the search by converting "target" to the corresponding delta + // value and then searching directly in the deltas_ vector. + // + // To invert operator[], we essentially compute ((target - base_) >> shift_) + // except that we also need to round up when shifting. The first two cases + // ensure that "target" doesn't wrap around past zero when we do this. + if (target.id() <= base_) return 0; + if (target >= S2CellId::End(S2CellId::kMaxLevel)) return size(); + return deltas_.lower_bound( + (target.id() - base_ + (1ULL << shift_) - 1) >> shift_); +} + +} // namespace s2coding + +#endif // S2_ENCODED_S2CELL_ID_VECTOR_H_ diff --git a/inst/include/s2/encoded_s2point_vector.h b/inst/include/s2/encoded_s2point_vector.h new file mode 100644 index 0000000..c692cd7 --- /dev/null +++ b/inst/include/s2/encoded_s2point_vector.h @@ -0,0 +1,149 @@ +// Copyright 2018 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS-IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +// Author: ericv@google.com (Eric Veach) + +#ifndef S2_ENCODED_S2POINT_VECTOR_H_ +#define S2_ENCODED_S2POINT_VECTOR_H_ + +#include +#include "s2/third_party/absl/types/span.h" +#include "s2/encoded_string_vector.h" +#include "s2/encoded_uint_vector.h" +#include "s2/s2point.h" + +namespace s2coding { + +// Controls whether to optimize for speed or size when encoding points. (Note +// that encoding is always lossless, and that currently compact encodings are +// only possible when points have been snapped to S2CellId centers.) +enum class CodingHint : uint8 { FAST, COMPACT }; + +// Encodes a vector of S2Points in a format that can later be decoded as an +// EncodedS2PointVector. +// +// REQUIRES: "encoder" uses the default constructor, so that its buffer +// can be enlarged as necessary by calling Ensure(int). +void EncodeS2PointVector(absl::Span points, CodingHint hint, + Encoder* encoder); + +// This class represents an encoded vector of S2Points. Values are decoded +// only when they are accessed. This allows for very fast initialization and +// no additional memory use beyond the encoded data. The encoded data is not +// owned by this class; typically it points into a large contiguous buffer +// that contains other encoded data as well. +// +// This is one of several helper classes that allow complex data structures to +// be initialized from an encoded format in constant time and then decoded on +// demand. This can be a big performance advantage when only a small part of +// the data structure is actually used. +class EncodedS2PointVector { + public: + // Constructs an uninitialized object; requires Init() to be called. + EncodedS2PointVector() {} + + // Initializes the EncodedS2PointVector. + // + // REQUIRES: The Decoder data buffer must outlive this object. + bool Init(Decoder* decoder); + + // Returns the size of the original vector. + size_t size() const; + + // Returns the element at the given index. + S2Point operator[](int i) const; + + // Decodes and returns the entire original vector. + std::vector Decode() const; + + // TODO(ericv): Consider adding a method that returns an adjacent pair of + // points. This would save some decoding overhead. + + private: + friend void EncodeS2PointVector(absl::Span, CodingHint, + Encoder*); + friend void EncodeS2PointVectorFast(absl::Span, Encoder*); + friend void EncodeS2PointVectorCompact(absl::Span, Encoder*); + + bool InitUncompressedFormat(Decoder* decoder); + bool InitCellIdsFormat(Decoder* decoder); + S2Point DecodeCellIdsFormat(int i) const; + + // We use a tagged union to represent multiple formats, as opposed to an + // abstract base class or templating. This represents the best compromise + // between performance, space, and convenience. Note that the overhead of + // checking the tag is trivial and will typically be branch-predicted + // perfectly. + // + // TODO(ericv): Once additional formats have been implemented, consider + // using std::variant<> instead. It's unclear whether this would have + // better or worse performance than the current approach. + + // dd: These structs are anonymous in the upstream S2 code; however, + // this generates CMD-check failure due to the [-Wnested-anon-types] + // (anonymous types declared in an anonymous union are an extension) + // The approach here just names the types. + struct CellIDStruct { + EncodedStringVector blocks; + uint64 base; + uint8 level; + bool have_exceptions; + + // TODO(ericv): Use std::atomic_flag to cache the last point decoded in + // a thread-safe way. This reduces benchmark times for actual polygon + // operations (e.g. S2ClosestEdgeQuery) by about 15%. + }; + + struct UncompressedStruct { + const S2Point* points; + }; + + enum Format : uint8 { + UNCOMPRESSED = 0, + CELL_IDS = 1, + }; + Format format_; + uint32 size_; + union { + struct UncompressedStruct uncompressed_; + struct CellIDStruct cell_ids_; + }; +}; + + +////////////////// Implementation details follow //////////////////// + + +inline size_t EncodedS2PointVector::size() const { + return size_; +} + +inline S2Point EncodedS2PointVector::operator[](int i) const { + switch (format_) { + case Format::UNCOMPRESSED: + return uncompressed_.points[i]; + + case Format::CELL_IDS: + return DecodeCellIdsFormat(i); + + default: + S2_LOG(DFATAL) << "Unrecognized format"; + return S2Point(); + } +} + +} // namespace s2coding + +#endif // S2_ENCODED_S2POINT_VECTOR_H_ diff --git a/inst/include/s2/encoded_s2shape_index.h b/inst/include/s2/encoded_s2shape_index.h new file mode 100644 index 0000000..3232474 --- /dev/null +++ b/inst/include/s2/encoded_s2shape_index.h @@ -0,0 +1,276 @@ +// Copyright 2018 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS-IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +// Author: ericv@google.com (Eric Veach) + +#ifndef S2_ENCODED_S2SHAPE_INDEX_H_ +#define S2_ENCODED_S2SHAPE_INDEX_H_ + +#include "s2/encoded_s2cell_id_vector.h" +#include "s2/encoded_string_vector.h" +#include "s2/mutable_s2shape_index.h" + +class EncodedS2ShapeIndex final : public S2ShapeIndex { + public: + using Options = MutableS2ShapeIndex::Options; + using ShapeFactory = S2ShapeIndex::ShapeFactory; + + // Creates an index that must be initialized by calling Init(). + EncodedS2ShapeIndex(); + + ~EncodedS2ShapeIndex() override; + + // Initializes the EncodedS2ShapeIndex, returning true on success. + // + // This method does not decode the S2Shape objects in the index; this is + // the responsibility of the client-provided function "shape_factory" + // (see s2shapeutil_coding.h). Example usage: + // + // index.Init(decoder, s2shapeutil::LazyDecodeShapeFactory(decoder)); + // + // Note that the encoded shape vector must *precede* the encoded S2ShapeIndex + // in the Decoder's data buffer in this example. + bool Init(Decoder* decoder, const ShapeFactory& shape_factory); + + const Options& options() const { return options_; } + + // The number of distinct shape ids in the index. This equals the number of + // shapes in the index provided that no shapes have ever been removed. + // (Shape ids are not reused.) + int num_shape_ids() const override { return shapes_.size(); } + + // Return a pointer to the shape with the given id, or nullptr if the shape + // has been removed from the index. + S2Shape* shape(int id) const override; + + // Minimizes memory usage by requesting that any data structures that can be + // rebuilt should be discarded. This method invalidates all iterators. + // + // Like all non-const methods, this method is not thread-safe. + void Minimize() override; + + class Iterator final : public IteratorBase { + public: + // Default constructor; must be followed by a call to Init(). + Iterator(); + + // Constructs an iterator positioned as specified. By default iterators + // are unpositioned, since this avoids an extra seek in this situation + // where one of the seek methods (such as Locate) is immediately called. + // + // If you want to position the iterator at the beginning, e.g. in order to + // loop through the entire index, do this instead: + // + // for (EncodedS2ShapeIndex::Iterator it(&index, S2ShapeIndex::BEGIN); + // !it.done(); it.Next()) { ... } + explicit Iterator(const EncodedS2ShapeIndex* index, + InitialPosition pos = UNPOSITIONED); + + // Initializes an iterator for the given EncodedS2ShapeIndex. + void Init(const EncodedS2ShapeIndex* index, + InitialPosition pos = UNPOSITIONED); + + // Inherited non-virtual methods: + // S2CellId id() const; + // const S2ShapeIndexCell& cell() const; + // bool done() const; + // S2Point center() const; + + // IteratorBase API: + void Begin() override; + void Finish() override; + void Next() override; + bool Prev() override; + void Seek(S2CellId target) override; + bool Locate(const S2Point& target) override; + CellRelation Locate(S2CellId target) override; + + protected: + const S2ShapeIndexCell* GetCell() const override; + std::unique_ptr Clone() const override; + void Copy(const IteratorBase& other) override; + + private: + void Refresh(); // Updates the IteratorBase fields. + const EncodedS2ShapeIndex* index_; + int32 cell_pos_; // Current position in the vector of index cells. + int32 num_cells_; + }; + + // Returns the number of bytes currently occupied by the index (including any + // unused space at the end of vectors, etc). It has the same thread safety + // as the other "const" methods (see introduction). + size_t SpaceUsed() const override; + + protected: + std::unique_ptr NewIterator(InitialPosition pos) const override; + + private: + friend class Iterator; + + // Returns a value indicating that a shape has not been decoded yet. + inline static S2Shape* kUndecodedShape() { + return reinterpret_cast(1); + } + + // Like std::atomic, but defaults to kUndecodedShape(). + class AtomicShape : public std::atomic { + public: + AtomicShape() : std::atomic(kUndecodedShape()) {} + }; + + S2Shape* GetShape(int id) const; + const S2ShapeIndexCell* GetCell(int i) const; + bool cell_decoded(int i) const; + bool test_and_set_cell_decoded(int i) const; + int max_cell_cache_size() const; + + std::unique_ptr shape_factory_; + + // The options specified for this index. + Options options_; + + // A vector containing all shapes in the index. Initially all shapes are + // set to kUndecodedShape(); as shapes are decoded, they are added to the + // vector using std::atomic::compare_exchange_strong. + mutable std::vector shapes_; + + // A vector containing the S2CellIds of each cell in the index. + s2coding::EncodedS2CellIdVector cell_ids_; + + // A vector containing the encoded contents of each cell in the index. + s2coding::EncodedStringVector encoded_cells_; + + // A raw array containing the decoded contents of each cell in the index. + // Initially all values are *uninitialized memory*. The cells_decoded_ + // field below keeps track of which elements are present. + mutable std::unique_ptr[]> cells_; + + // A bit vector indicating which elements of cells_ have been decoded. + // All other elements of cells_ contain uninitialized (random) memory. + mutable std::vector> cells_decoded_; + + // In order to minimize destructor time when very few cells of a large + // S2ShapeIndex are needed, we keep track of the indices of the first few + // cells to be decoded. This lets us avoid scanning the cells_decoded_ + // vector when the number of cells decoded is very small. + mutable std::vector cell_cache_; + + // Protects all updates to cells_ and cells_decoded_. + mutable SpinLock cells_lock_; + + EncodedS2ShapeIndex(const EncodedS2ShapeIndex&) = delete; + void operator=(const EncodedS2ShapeIndex&) = delete; +}; + + +////////////////// Implementation details follow //////////////////// + + +inline EncodedS2ShapeIndex::Iterator::Iterator() : index_(nullptr) { +} + +inline EncodedS2ShapeIndex::Iterator::Iterator( + const EncodedS2ShapeIndex* index, InitialPosition pos) { + Init(index, pos); +} + +inline void EncodedS2ShapeIndex::Iterator::Init( + const EncodedS2ShapeIndex* index, InitialPosition pos) { + index_ = index; + num_cells_ = index->cell_ids_.size(); + cell_pos_ = (pos == BEGIN) ? 0 : num_cells_; + Refresh(); +} + +inline void EncodedS2ShapeIndex::Iterator::Refresh() { + if (cell_pos_ == num_cells_) { + set_finished(); + } else { + // It's faster to initialize the cell to nullptr even if it has already + // been decoded, since algorithms frequently don't need it (i.e., based on + // the S2CellId they might not need to look at the cell contents). + set_state(index_->cell_ids_[cell_pos_], nullptr); + } +} + +inline void EncodedS2ShapeIndex::Iterator::Begin() { + cell_pos_ = 0; + Refresh(); +} + +inline void EncodedS2ShapeIndex::Iterator::Finish() { + cell_pos_ = num_cells_; + Refresh(); +} + +inline void EncodedS2ShapeIndex::Iterator::Next() { + S2_DCHECK(!done()); + ++cell_pos_; + Refresh(); +} + +inline bool EncodedS2ShapeIndex::Iterator::Prev() { + if (cell_pos_ == 0) return false; + --cell_pos_; + Refresh(); + return true; +} + +inline void EncodedS2ShapeIndex::Iterator::Seek(S2CellId target) { + cell_pos_ = index_->cell_ids_.lower_bound(target); + Refresh(); +} + +inline std::unique_ptr +EncodedS2ShapeIndex::NewIterator(InitialPosition pos) const { + return absl::make_unique(this, pos); +} + +inline S2Shape* EncodedS2ShapeIndex::shape(int id) const { + S2Shape* shape = shapes_[id].load(std::memory_order_relaxed); + if (shape != kUndecodedShape()) return shape; + return GetShape(id); +} + +// Returns true if the given cell has been decoded yet. +inline bool EncodedS2ShapeIndex::cell_decoded(int i) const { + uint64 group_bits = cells_decoded_[i >> 6].load(std::memory_order_relaxed); + return (group_bits & (1ULL << (i & 63))) != 0; +} + +// Marks the given cell as decoded and returns true if it was already marked. +inline bool EncodedS2ShapeIndex::test_and_set_cell_decoded(int i) const { + std::atomic* group = &cells_decoded_[i >> 6]; + uint64 group_bits = group->load(std::memory_order_relaxed); + uint64 test_bit = 1ULL << (i & 63); + group->store(group_bits | test_bit, std::memory_order_relaxed); + return (group_bits & test_bit) != 0; +} + +inline int EncodedS2ShapeIndex::max_cell_cache_size() const { + // The cell cache is sized so that scanning decoded_cells_ in the destructor + // costs about 30 cycles per decoded cell in the worst case. (This overhead + // is acceptable relative to the other costs of decoding each cell.) + // + // For example, if there are 65,536 cells then we won't need to scan + // encoded_cells_ unless we decode at least (65536/2048) == 32 cells. It + // takes about 1 cycle per 64 cells to scan encoded_cells_, so that works + // out to (65536/64) == 1024 cycles. However this cost is amortized over + // the 32 cells decoded, which works out to 32 cycles per cell. + return cell_ids_.size() >> 11; +} + +#endif // S2_ENCODED_S2SHAPE_INDEX_H_ diff --git a/inst/include/s2/encoded_string_vector.h b/inst/include/s2/encoded_string_vector.h new file mode 100644 index 0000000..bd6984c --- /dev/null +++ b/inst/include/s2/encoded_string_vector.h @@ -0,0 +1,164 @@ +// Copyright 2018 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS-IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +// Author: ericv@google.com (Eric Veach) + +#ifndef S2_ENCODED_STRING_VECTOR_H_ +#define S2_ENCODED_STRING_VECTOR_H_ + +#include +#include +#include "s2/third_party/absl/strings/string_view.h" +#include "s2/third_party/absl/types/span.h" +#include "s2/encoded_uint_vector.h" + +namespace s2coding { + +// This class allows an EncodedStringVector to be created by adding strings +// incrementally. It also supports adding strings that are the output of +// another Encoder. For example, to create a vector of encoded S2Polygons, +// you can do this: +// +// void EncodePolygons(const vector& polygons, Encoder* encoder) { +// StringVectorEncoder encoded_polygons; +// for (auto polygon : polygons) { +// polygon->Encode(encoded_polygons.AddViaEncoder()); +// } +// encoded_polygons.Encode(encoder); +// } +class StringVectorEncoder { + public: + StringVectorEncoder(); + + // Adds a string to the encoded vector. + void Add(const string& str); + + // Adds a string to the encoded vector by means of the given Encoder. The + // string consists of all output added to the encoder before the next call + // to any method of this class (after which the encoder is no longer valid). + Encoder* AddViaEncoder(); + + // Appends the EncodedStringVector representation to the given Encoder. + // + // REQUIRES: "encoder" uses the default constructor, so that its buffer + // can be enlarged as necessary by calling Ensure(int). + void Encode(Encoder* encoder); + + // Encodes a vector of strings in a format that can later be decoded as an + // EncodedStringVector. + // + // REQUIRES: "encoder" uses the default constructor, so that its buffer + // can be enlarged as necessary by calling Ensure(int). + static void Encode(absl::Span v, Encoder* encoder); + + private: + // A vector consisting of the starting offset of each string in the + // encoder's data buffer, plus a final entry pointing just past the end of + // the last string. + std::vector offsets_; + Encoder data_; +}; + +// This class represents an encoded vector of strings. Values are decoded +// only when they are accessed. This allows for very fast initialization and +// no additional memory use beyond the encoded data. The encoded data is not +// owned by this class; typically it points into a large contiguous buffer +// that contains other encoded data as well. +// +// This is one of several helper classes that allow complex data structures to +// be initialized from an encoded format in constant time and then decoded on +// demand. This can be a big performance advantage when only a small part of +// the data structure is actually used. +class EncodedStringVector { + public: + // Constructs an uninitialized object; requires Init() to be called. + EncodedStringVector() {} + + // Initializes the EncodedStringVector. Returns false on errors, leaving + // the vector in an unspecified state. + // + // REQUIRES: The Decoder data buffer must outlive this object. + bool Init(Decoder* decoder); + + // Resets the vector to be empty. + void Clear(); + + // Returns the size of the original vector. + size_t size() const; + + // Returns the string at the given index. + absl::string_view operator[](int i) const; + + // Returns a Decoder initialized with the string at the given index. + Decoder GetDecoder(int i) const; + + // Returns a pointer to the start of the string at the given index. This is + // faster than operator[] but returns an unbounded string. + const char* GetStart(int i) const; + + // Returns the entire vector of original strings. Requires that the + // data buffer passed to the constructor persists until the result vector is + // no longer needed. + std::vector Decode() const; + + private: + EncodedUintVector offsets_; + const char* data_; +}; + + +////////////////// Implementation details follow //////////////////// + + +inline void StringVectorEncoder::Add(const string& str) { + offsets_.push_back(data_.length()); + data_.Ensure(str.size()); + data_.putn(str.data(), str.size()); +} + +inline Encoder* StringVectorEncoder::AddViaEncoder() { + offsets_.push_back(data_.length()); + return &data_; +} + +inline void EncodedStringVector::Clear() { + offsets_.Clear(); + data_ = nullptr; +} + +inline size_t EncodedStringVector::size() const { + return offsets_.size(); +} + +inline absl::string_view EncodedStringVector::operator[](int i) const { + uint64 start = (i == 0) ? 0 : offsets_[i - 1]; + uint64 limit = offsets_[i]; + return absl::string_view(data_ + start, limit - start); +} + +inline Decoder EncodedStringVector::GetDecoder(int i) const { + uint64 start = (i == 0) ? 0 : offsets_[i - 1]; + uint64 limit = offsets_[i]; + return Decoder(data_ + start, limit - start); +} + +inline const char* EncodedStringVector::GetStart(int i) const { + uint64 start = (i == 0) ? 0 : offsets_[i - 1]; + return data_ + start; +} + +} // namespace s2coding + +#endif // S2_ENCODED_STRING_VECTOR_H_ diff --git a/inst/include/s2/encoded_uint_vector.h b/inst/include/s2/encoded_uint_vector.h new file mode 100644 index 0000000..e0daf7e --- /dev/null +++ b/inst/include/s2/encoded_uint_vector.h @@ -0,0 +1,299 @@ +// Copyright 2018 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS-IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +// Author: ericv@google.com (Eric Veach) + +#ifndef S2_ENCODED_UINT_VECTOR_H_ +#define S2_ENCODED_UINT_VECTOR_H_ + +#include +#include +#include "s2/third_party/absl/base/internal/unaligned_access.h" +#include "s2/third_party/absl/types/span.h" +#include "s2/util/coding/coder.h" + +namespace s2coding { + +// Encodes a vector of unsigned integers in a format that can later be +// decoded as an EncodedUintVector. +// +// REQUIRES: T is an unsigned integer type. +// REQUIRES: 2 <= sizeof(T) <= 8 +// REQUIRES: "encoder" uses the default constructor, so that its buffer +// can be enlarged as necessary by calling Ensure(int). +template +void EncodeUintVector(absl::Span v, Encoder* encoder); + +// This class represents an encoded vector of unsigned integers of type T. +// Values are decoded only when they are accessed. This allows for very fast +// initialization and no additional memory use beyond the encoded data. +// The encoded data is not owned by this class; typically it points into a +// large contiguous buffer that contains other encoded data as well. +// +// This is one of several helper classes that allow complex data structures to +// be initialized from an encoded format in constant time and then decoded on +// demand. This can be a big performance advantage when only a small part of +// the data structure is actually used. +// +// Values are encoded using a fixed number of bytes per value, where the +// number of bytes depends on the largest value present. +// +// REQUIRES: T is an unsigned integer type. +// REQUIRES: 2 <= sizeof(T) <= 8 +template +class EncodedUintVector { + public: + static_assert(std::is_unsigned::value, "Unsupported signed integer"); + static_assert(sizeof(T) & 0xe, "Unsupported integer length"); + + // Constructs an uninitialized object; requires Init() to be called. + EncodedUintVector() {} + + // Initializes the EncodedUintVector. Returns false on errors, leaving the + // vector in an unspecified state. + // + // REQUIRES: The Decoder data buffer must outlive this object. + bool Init(Decoder* decoder); + + // Resets the vector to be empty. + void Clear(); + + // Returns the size of the original vector. + size_t size() const; + + // Returns the element at the given index. + T operator[](int i) const; + + // Returns the index of the first element x such that (x >= target), or + // size() if no such element exists. + // + // REQUIRES: The vector elements are sorted in non-decreasing order. + size_t lower_bound(T target) const; + + // Decodes and returns the entire original vector. + std::vector Decode() const; + + private: + template size_t lower_bound(T target) const; + + const char* data_; + uint32 size_; + uint8 len_; +}; + +// Encodes an unsigned integer in little-endian format using "length" bytes. +// (The client must ensure that the encoder's buffer is large enough.) +// +// REQUIRES: T is an unsigned integer type. +// REQUIRES: 2 <= sizeof(T) <= 8 +// REQUIRES: 0 <= length <= sizeof(T) +// REQUIRES: value < 256 ** length +// REQUIRES: encoder->avail() >= length +template +void EncodeUintWithLength(T value, int length, Encoder* encoder); + +// Decodes a variable-length integer consisting of "length" bytes starting at +// "ptr" in little-endian format. +// +// REQUIRES: T is an unsigned integer type. +// REQUIRES: 2 <= sizeof(T) <= 8 +// REQUIRES: 0 <= length <= sizeof(T) +template +T GetUintWithLength(const void* ptr, int length); + +// Decodes and consumes a variable-length integer consisting of "length" bytes +// in little-endian format. Returns false if not enough bytes are available. +// +// REQUIRES: T is an unsigned integer type. +// REQUIRES: 2 <= sizeof(T) <= 8 +// REQUIRES: 0 <= length <= sizeof(T) +template +bool DecodeUintWithLength(int length, Decoder* decoder, T* result); + + +////////////////// Implementation details follow //////////////////// + + +template +inline void EncodeUintWithLength(T value, int length, Encoder* encoder) { + static_assert(std::is_unsigned::value, "Unsupported signed integer"); + static_assert(sizeof(T) & 0xe, "Unsupported integer length"); + S2_DCHECK(length >= 0 && length <= sizeof(T)); + S2_DCHECK_GE(encoder->avail(), length); + + while (--length >= 0) { + encoder->put8(value); + value >>= 8; + } + S2_DCHECK_EQ(value, 0); +} + +template +inline T GetUintWithLength(const char* ptr, int length) { + static_assert(std::is_unsigned::value, "Unsupported signed integer"); + static_assert(sizeof(T) & 0xe, "Unsupported integer length"); + S2_DCHECK(length >= 0 && length <= sizeof(T)); + + // Note that the following code is faster than any of the following: + // + // - A loop that repeatedly loads and shifts one byte. + // - memcpying "length" bytes to a local variable of type T. + // - A switch statement that handles each length optimally. + // + // The following code is slightly faster: + // + // T mask = (length == 0) ? 0 : ~T{0} >> 8 * (sizeof(T) - length); + // return *reinterpret_cast(ptr) & mask; + // + // However this technique is unsafe because in extremely rare cases it might + // access out-of-bounds heap memory. (This can only happen if "ptr" is + // within (sizeof(T) - length) bytes of the end of a memory page and the + // following page in the address space is unmapped.) + + if (length & sizeof(T)) { + if (sizeof(T) == 8) return ABSL_INTERNAL_UNALIGNED_LOAD64(ptr); + if (sizeof(T) == 4) return ABSL_INTERNAL_UNALIGNED_LOAD32(ptr); + if (sizeof(T) == 2) return ABSL_INTERNAL_UNALIGNED_LOAD16(ptr); + S2_DCHECK_EQ(sizeof(T), 1); + return *ptr; + } + T x = 0; + ptr += length; + if (sizeof(T) > 4 && (length & 4)) { + x = ABSL_INTERNAL_UNALIGNED_LOAD32(ptr -= sizeof(uint32)); + } + if (sizeof(T) > 2 && (length & 2)) { + x = (x << 16) + ABSL_INTERNAL_UNALIGNED_LOAD16(ptr -= sizeof(uint16)); + } + if (sizeof(T) > 1 && (length & 1)) { + x = (x << 8) + static_cast(*--ptr); + } + return x; +} + +template +bool DecodeUintWithLength(int length, Decoder* decoder, T* result) { + if (decoder->avail() < length) return false; + const char* ptr = reinterpret_cast(decoder->ptr()); + *result = GetUintWithLength(ptr, length); + decoder->skip(length); + return true; +} + +template +void EncodeUintVector(absl::Span v, Encoder* encoder) { + // The encoding is as follows: + // + // varint64: (v.size() * sizeof(T)) | (len - 1) + // array of v.size() elements ["len" bytes each] + // + // Note that we don't allow (len == 0) since this would require an extra bit + // to encode the length. + + T one_bits = 1; // Ensures len >= 1. + for (auto x : v) one_bits |= x; + int len = (Bits::FindMSBSetNonZero64(one_bits) >> 3) + 1; + S2_DCHECK(len >= 1 && len <= 8); + + // Note that the multiplication is optimized into a bit shift. + encoder->Ensure(Varint::kMax64 + v.size() * len); + uint64 size_len = (uint64{v.size()} * sizeof(T)) | (len - 1); + encoder->put_varint64(size_len); + for (auto x : v) { + EncodeUintWithLength(x, len, encoder); + } +} + +template +bool EncodedUintVector::Init(Decoder* decoder) { + uint64 size_len; + if (!decoder->get_varint64(&size_len)) return false; + size_ = size_len / sizeof(T); // Optimized into bit shift. + len_ = (size_len & (sizeof(T) - 1)) + 1; + if (size_ > std::numeric_limits::max() / sizeof(T)) return false; + size_t bytes = size_ * len_; + if (decoder->avail() < bytes) return false; + data_ = reinterpret_cast(decoder->ptr()); + decoder->skip(bytes); + return true; +} + +template +void EncodedUintVector::Clear() { + size_ = 0; + data_ = nullptr; +} + +template +inline size_t EncodedUintVector::size() const { + return size_; +} + +template +inline T EncodedUintVector::operator[](int i) const { + S2_DCHECK(i >= 0 && i < size_); + return GetUintWithLength(data_ + i * len_, len_); +} + +template +size_t EncodedUintVector::lower_bound(T target) const { + static_assert(sizeof(T) & 0xe, "Unsupported integer length"); + S2_DCHECK(len_ >= 1 && len_ <= sizeof(T)); + + // TODO(ericv): Consider using the unused 28 bits of "len_" to store the + // last result of lower_bound() to be used as a hint. This should help in + // common situation where the same element is looked up repeatedly. This + // would require declaring the new field (length_lower_bound_hint_) as + // mutable std::atomic (accessed using std::memory_order_relaxed) + // with a custom copy constructor that resets the hint component to zero. + switch (len_) { + case 1: return lower_bound<1>(target); + case 2: return lower_bound<2>(target); + case 3: return lower_bound<3>(target); + case 4: return lower_bound<4>(target); + case 5: return lower_bound<5>(target); + case 6: return lower_bound<6>(target); + case 7: return lower_bound<7>(target); + default: return lower_bound<8>(target); + } +} + +template template +inline size_t EncodedUintVector::lower_bound(T target) const { + size_t lo = 0, hi = size_; + while (lo < hi) { + size_t mid = (lo + hi) >> 1; + T value = GetUintWithLength(data_ + mid * length, length); + if (value < target) { + lo = mid + 1; + } else { + hi = mid; + } + } + return lo; +} + +template +std::vector EncodedUintVector::Decode() const { + std::vector result(size_); + for (int i = 0; i < size_; ++i) { + result[i] = (*this)[i]; + } + return result; +} + +} // namespace s2coding + +#endif // S2_ENCODED_UINT_VECTOR_H_ diff --git a/inst/include/s2/id_set_lexicon.h b/inst/include/s2/id_set_lexicon.h new file mode 100644 index 0000000..25ace84 --- /dev/null +++ b/inst/include/s2/id_set_lexicon.h @@ -0,0 +1,199 @@ +// Copyright 2016 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS-IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +// Author: ericv@google.com (Eric Veach) + +#ifndef S2_ID_SET_LEXICON_H_ +#define S2_ID_SET_LEXICON_H_ + +#include +#include + +#include "s2/base/integral_types.h" +#include "s2/base/logging.h" +#include "s2/sequence_lexicon.h" + +// IdSetLexicon is a class for compactly representing sets of non-negative +// integers such as array indices ("id sets"). It is especially suitable when +// either (1) there are many duplicate sets, or (2) there are many singleton +// or empty sets. See also ValueLexicon and SequenceLexicon. +// +// Each distinct id set is mapped to a 32-bit integer. Empty and singleton +// sets take up no additional space whatsoever; the set itself is represented +// by the unique id assigned to the set. Sets of size 2 or more occupy about +// 11 bytes per set plus 4 bytes per element (as compared to 24 bytes per set +// plus 4 bytes per element for std::vector). Duplicate sets are +// automatically eliminated. Note also that id sets are referred to using +// 32-bit integers rather than 64-bit pointers. +// +// This class is especially useful in conjunction with ValueLexicon. For +// example, suppose that you want to label objects with a set of strings. You +// could use a ValueLexicon to map the strings to "label ids" (32-bit +// integers), and then use IdSetLexicon to map each set of labels to a "label +// set id". Each reference to that label set then takes up only 4 bytes. +// +// Example usage: +// +// ValueLexicon labels_; +// IdSetLexicon label_sets_; +// +// int32 GetLabelSet(const vector& label_strings) { +// vector label_ids; +// for (const auto& str : label_strings) { +// label_ids.push_back(labels_.Add(str)); +// } +// return label_sets_.Add(label_ids); +// } +// +// int label_set_id = GetLabelSet(...); +// for (auto id : label_sets_.id_set(label_set_id)) { +// S2_LOG(INFO) << id; +// } +// +// This class is similar to SequenceLexicon, except: +// +// 1. Empty and singleton sets are represented implicitly; they use no space. +// 2. Sets are represented rather than sequences; the ordering of values is +// not important and duplicates are removed. +// 3. The values must be 32-bit non-negative integers (only). +class IdSetLexicon { + public: + IdSetLexicon(); + ~IdSetLexicon(); + + // IdSetLexicon is movable and copyable. + IdSetLexicon(const IdSetLexicon&); + IdSetLexicon& operator=(const IdSetLexicon&); + IdSetLexicon(IdSetLexicon&&); + IdSetLexicon& operator=(IdSetLexicon&&); + + // Clears all data from the lexicon. + void Clear(); + + // Add the given set of integers to the lexicon if it is not already + // present, and return the unique id for this set. "begin" and "end" are + // forward iterators over a sequence of values that can be converted to + // non-negative 32-bit integers. The values are automatically sorted and + // duplicates are removed. Returns a signed integer representing this set. + // + // REQUIRES: All values in [begin, end) are non-negative 32-bit integers. + template + int32 Add(FwdIterator begin, FwdIterator end); + + // Add the given set of integers to the lexicon if it is not already + // present, and return the unique id for this set. This is a convenience + // method equivalent to Add(std::begin(container), std::end(container)). + template + int32 Add(const Container& container); + + // Convenience method that returns the unique id for a singleton set. + // Note that because singleton sets take up no space, this method is + // const. Equivalent to calling Add(&id, &id + 1). + int32 AddSingleton(int32 id) const; + + // Convenience method that returns the unique id for the empty set. Note + // that because the empty set takes up no space and has a fixed id, this + // method is static. Equivalent to calling Add() with an empty container. + static int32 EmptySetId(); + + // Iterator type; please treat this as an opaque forward iterator. + using Iterator = const int32*; + + // This class represents a set of integers stored in the IdSetLexicon. + class IdSet { + public: + Iterator begin() const; + Iterator end() const; + size_t size() const; + + private: + friend class IdSetLexicon; + IdSet(); + IdSet(Iterator begin, Iterator end); + explicit IdSet(int32 singleton_id); + Iterator begin_, end_; + int32 singleton_id_; + }; + // Return the set of integers corresponding to an id returned by Add(). + IdSet id_set(int32 set_id) const; + + private: + // Choose kEmptySetId to be the last id that will ever be generated. + // (Non-negative ids are reserved for singleton sets.) + static const int32 kEmptySetId = std::numeric_limits::min(); + int32 AddInternal(std::vector* ids); + + SequenceLexicon id_sets_; + + std::vector tmp_; // temporary storage used during Add() +}; + + +////////////////// Implementation details follow //////////////////// + + +inline IdSetLexicon::Iterator IdSetLexicon::IdSet::begin() const { + return begin_; +} + +inline IdSetLexicon::Iterator IdSetLexicon::IdSet::end() const { + return end_; +} + +inline size_t IdSetLexicon::IdSet::size() const { + return end_ - begin_; +} + +inline IdSetLexicon::IdSet::IdSet() + : begin_(&singleton_id_), end_(begin_) { +} + +inline IdSetLexicon::IdSet::IdSet(Iterator begin, Iterator end) + : begin_(begin), end_(end) { +} + +inline IdSetLexicon::IdSet::IdSet(int32 singleton_id) + : begin_(&singleton_id_), end_(&singleton_id_ + 1), + singleton_id_(singleton_id) { +} + +inline int32 IdSetLexicon::AddSingleton(int32 id) const { + S2_DCHECK_GE(id, 0); + S2_DCHECK_LE(id, std::numeric_limits::max()); + // Singleton sets are represented by their element. + return id; +} + +/*static*/ inline int32 IdSetLexicon::EmptySetId() { + return kEmptySetId; +} + +template +int32 IdSetLexicon::Add(FwdIterator begin, FwdIterator end) { + tmp_.clear(); + for (; begin != end; ++begin) { + S2_DCHECK_GE(*begin, 0); + S2_DCHECK_LE(*begin, std::numeric_limits::max()); + tmp_.push_back(*begin); + } + return AddInternal(&tmp_); +} + +template +int32 IdSetLexicon::Add(const Container& container) { + return Add(std::begin(container), std::end(container)); +} + +#endif // S2_ID_SET_LEXICON_H_ diff --git a/inst/include/s2/mutable_s2shape_index.h b/inst/include/s2/mutable_s2shape_index.h new file mode 100644 index 0000000..e65363b --- /dev/null +++ b/inst/include/s2/mutable_s2shape_index.h @@ -0,0 +1,600 @@ +// Copyright 2012 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS-IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +// Author: ericv@google.com (Eric Veach) + +#ifndef S2_MUTABLE_S2SHAPE_INDEX_H_ +#define S2_MUTABLE_S2SHAPE_INDEX_H_ + +#include +#include +#include +#include +#include +#include + + +#include "s2/base/integral_types.h" +#include "s2/base/logging.h" +#include "s2/base/mutex.h" +#include "s2/base/spinlock.h" +#include "s2/_fp_contract_off.h" +#include "s2/s2cell_id.h" +#include "s2/s2pointutil.h" +#include "s2/s2shape.h" +#include "s2/s2shape_index.h" +#include "s2/third_party/absl/base/macros.h" +#include "s2/third_party/absl/base/thread_annotations.h" +#include "s2/third_party/absl/memory/memory.h" +#include "s2/util/gtl/btree_map.h" + +// MutableS2ShapeIndex is a class for in-memory indexing of polygonal geometry. +// The objects in the index are known as "shapes", and may consist of points, +// polylines, and/or polygons, possibly overlapping. The index makes it very +// fast to answer queries such as finding nearby shapes, measuring distances, +// testing for intersection and containment, etc. +// +// MutableS2ShapeIndex allows not only building an index, but also updating it +// incrementally by adding or removing shapes (hence its name). It is one of +// several implementations of the S2ShapeIndex interface. MutableS2ShapeIndex +// is designed to be compact; usually it is smaller than the underlying +// geometry being indexed. It is capable of indexing up to hundreds of +// millions of edges. The index is also fast to construct. +// +// There are a number of built-in classes that work with S2ShapeIndex objects. +// Generally these classes accept any collection of geometry that can be +// represented by an S2ShapeIndex, i.e. any combination of points, polylines, +// and polygons. Such classes include: +// +// - S2ContainsPointQuery: returns the shape(s) that contain a given point. +// +// - S2ClosestEdgeQuery: returns the closest edge(s) to a given point, edge, +// S2CellId, or S2ShapeIndex. +// +// - S2CrossingEdgeQuery: returns the edge(s) that cross a given edge. +// +// - S2BooleanOperation: computes boolean operations such as union, +// and boolean predicates such as containment. +// +// - S2ShapeIndexRegion: computes approximations for a collection of geometry. +// +// - S2ShapeIndexBufferedRegion: computes approximations that have been +// expanded by a given radius. +// +// Here is an example showing how to build an index for a set of polygons, and +// then then determine which polygon(s) contain each of a set of query points: +// +// void TestContainment(const vector& points, +// const vector& polygons) { +// MutableS2ShapeIndex index; +// for (auto polygon : polygons) { +// index.Add(absl::make_unique(polygon)); +// } +// auto query = MakeS2ContainsPointQuery(&index); +// for (const auto& point : points) { +// for (S2Shape* shape : query.GetContainingShapes(point)) { +// S2Polygon* polygon = polygons[shape->id()]; +// ... do something with (point, polygon) ... +// } +// } +// } +// +// This example uses S2Polygon::Shape, which is one example of an S2Shape +// object. S2Polyline and S2Loop also have nested Shape classes, and there are +// additional S2Shape types defined in *_shape.h. +// +// Internally, MutableS2ShapeIndex is essentially a map from S2CellIds to the +// set of shapes that intersect each S2CellId. It is adaptively refined to +// ensure that no cell contains more than a small number of edges. +// +// For efficiency, updates are batched together and applied lazily on the +// first subsequent query. Locking is used to ensure that MutableS2ShapeIndex +// has the same thread-safety properties as "vector": const methods are +// thread-safe, while non-const methods are not thread-safe. This means that +// if one thread updates the index, you must ensure that no other thread is +// reading or updating the index at the same time. +// +// TODO(ericv): MutableS2ShapeIndex has an Encode() method that allows the +// index to be serialized. An encoded S2ShapeIndex can be decoded either into +// its original form (MutableS2ShapeIndex) or into an EncodedS2ShapeIndex. +// The key property of EncodedS2ShapeIndex is that it can be constructed +// instantaneously, since the index is kept in its original encoded form. +// Data is decoded only when an operation needs it. For example, to determine +// which shapes(s) contain a given query point only requires decoding the data +// in the S2ShapeIndexCell that contains that point. +class MutableS2ShapeIndex final : public S2ShapeIndex { + private: + using CellMap = gtl::btree_map; + + public: + // Options that affect construction of the MutableS2ShapeIndex. + class Options { + public: + Options(); + + // The maximum number of edges per cell. If a cell has more than this + // many edges that are not considered "long" relative to the cell size, + // then it is subdivided. (Whether an edge is considered "long" is + // controlled by --s2shape_index_cell_size_to_long_edge_ratio flag.) + // + // Values between 10 and 50 represent a reasonable balance between memory + // usage, construction time, and query time. Small values make queries + // faster, while large values make construction faster and use less memory. + // Values higher than 50 do not save significant additional memory, and + // query times can increase substantially, especially for algorithms that + // visit all pairs of potentially intersecting edges (such as polygon + // validation), since this is quadratic in the number of edges per cell. + // + // Note that the *average* number of edges per cell is generally slightly + // less than half of the maximum value defined here. + // + // Defaults to value given by --s2shape_index_default_max_edges_per_cell. + int max_edges_per_cell() const { return max_edges_per_cell_; } + void set_max_edges_per_cell(int max_edges_per_cell); + + private: + int max_edges_per_cell_; + }; + + // Creates a MutableS2ShapeIndex that uses the default option settings. + // Option values may be changed by calling Init(). + MutableS2ShapeIndex(); + + // Create a MutableS2ShapeIndex with the given options. + explicit MutableS2ShapeIndex(const Options& options); + + ~MutableS2ShapeIndex() override; + + // Initialize a MutableS2ShapeIndex with the given options. This method may + // only be called when the index is empty (i.e. newly created or Reset() has + // just been called). + void Init(const Options& options); + + const Options& options() const { return options_; } + + // The number of distinct shape ids that have been assigned. This equals + // the number of shapes in the index provided that no shapes have ever been + // removed. (Shape ids are not reused.) + int num_shape_ids() const override { + return static_cast(shapes_.size()); + } + + // Returns a pointer to the shape with the given id, or nullptr if the shape + // has been removed from the index. + S2Shape* shape(int id) const override { return shapes_[id].get(); } + + // Minimizes memory usage by requesting that any data structures that can be + // rebuilt should be discarded. This method invalidates all iterators. + // + // Like all non-const methods, this method is not thread-safe. + void Minimize() override; + + // Appends an encoded representation of the S2ShapeIndex to "encoder". + // + // This method does not encode the S2Shapes in the index; it is the client's + // responsibility to encode them separately. For example: + // + // s2shapeutil::CompactEncodeTaggedShapes(index, encoder); + // index.Encode(encoder); + // + // REQUIRES: "encoder" uses the default constructor, so that its buffer + // can be enlarged as necessary by calling Ensure(int). + void Encode(Encoder* encoder) const; + + // Decodes an S2ShapeIndex, returning true on success. + // + // This method does not decode the S2Shape objects in the index; this is + // the responsibility of the client-provided function "shape_factory" + // (see s2shapeutil_coding.h). Example usage: + // + // index.Init(decoder, s2shapeutil::LazyDecodeShapeFactory(decoder)); + // + // Note that the S2Shape vector must be encoded *before* the S2ShapeIndex in + // this example. + bool Init(Decoder* decoder, const ShapeFactory& shape_factory); + + class Iterator final : public IteratorBase { + public: + // Default constructor; must be followed by a call to Init(). + Iterator(); + + // Constructs an iterator positioned as specified. By default iterators + // are unpositioned, since this avoids an extra seek in this situation + // where one of the seek methods (such as Locate) is immediately called. + // + // If you want to position the iterator at the beginning, e.g. in order to + // loop through the entire index, do this instead: + // + // for (MutableS2ShapeIndex::Iterator it(&index, S2ShapeIndex::BEGIN); + // !it.done(); it.Next()) { ... } + explicit Iterator(const MutableS2ShapeIndex* index, + InitialPosition pos = UNPOSITIONED); + + // Initializes an iterator for the given MutableS2ShapeIndex. This method + // may also be called in order to restore an iterator to a valid state + // after the underlying index has been updated (although it is usually + // easier just to declare a new iterator whenever required, since iterator + // construction is cheap). + void Init(const MutableS2ShapeIndex* index, + InitialPosition pos = UNPOSITIONED); + + // Initialize an iterator for the given MutableS2ShapeIndex without + // applying any pending updates. This can be used to observe the actual + // current state of the index without modifying it in any way. + void InitStale(const MutableS2ShapeIndex* index, + InitialPosition pos = UNPOSITIONED); + + // Inherited non-virtual methods: + // S2CellId id() const; + // bool done() const; + // S2Point center() const; + const S2ShapeIndexCell& cell() const; + + // IteratorBase API: + void Begin() override; + void Finish() override; + void Next() override; + bool Prev() override; + void Seek(S2CellId target) override; + bool Locate(const S2Point& target) override; + CellRelation Locate(S2CellId target) override; + + protected: + const S2ShapeIndexCell* GetCell() const override; + std::unique_ptr Clone() const override; + void Copy(const IteratorBase& other) override; + + private: + void Refresh(); // Updates the IteratorBase fields. + const MutableS2ShapeIndex* index_; + CellMap::const_iterator iter_, end_; + }; + + // Takes ownership of the given shape and adds it to the index. Also + // assigns a unique id to the shape (shape->id()) and returns that id. + // Shape ids are assigned sequentially starting from 0 in the order shapes + // are added. Invalidates all iterators and their associated data. + int Add(std::unique_ptr shape); + + // Removes the given shape from the index and return ownership to the caller. + // Invalidates all iterators and their associated data. + std::unique_ptr Release(int shape_id); + + // Resets the index to its original state and returns ownership of all + // shapes to the caller. This method is much more efficient than removing + // all shapes one at a time. + std::vector> ReleaseAll(); + + // Resets the index to its original state and deletes all shapes. Any + // options specified via Init() are preserved. + void Clear(); + + // Returns the number of bytes currently occupied by the index (including any + // unused space at the end of vectors, etc). It has the same thread safety + // as the other "const" methods (see introduction). + size_t SpaceUsed() const override; + + // Calls to Add() and Release() are normally queued and processed on the + // first subsequent query (in a thread-safe way). This has many advantages, + // the most important of which is that sometimes there *is* no subsequent + // query, which lets us avoid building the index completely. + // + // This method forces any pending updates to be applied immediately. + // Calling this method is rarely a good idea. (One valid reason is to + // exclude the cost of building the index from benchmark results.) + void ForceBuild(); + + // Returns true if there are no pending updates that need to be applied. + // This can be useful to avoid building the index unnecessarily, or for + // choosing between two different algorithms depending on whether the index + // is available. + // + // The returned index status may be slightly out of date if the index was + // built in a different thread. This is fine for the intended use (as an + // efficiency hint), but it should not be used by internal methods (see + // MaybeApplyUpdates). + bool is_fresh() const; + + protected: + std::unique_ptr NewIterator(InitialPosition pos) const override; + + private: + friend class EncodedS2ShapeIndex; + friend class Iterator; + friend class MutableS2ShapeIndexTest; + friend class S2Stats; + + struct BatchDescriptor; + struct ClippedEdge; + class EdgeAllocator; + struct FaceEdge; + class InteriorTracker; + struct RemovedShape; + + using ShapeIdSet = std::vector; + + // When adding a new encoding, be aware that old binaries will not be able + // to decode it. + static const unsigned char kCurrentEncodingVersionNumber = 0; + + // Internal methods are documented with their definitions. + bool is_first_update() const; + bool is_shape_being_removed(int shape_id) const; + void MaybeApplyUpdates() const; + void ApplyUpdatesThreadSafe(); + void ApplyUpdatesInternal(); + void GetUpdateBatches(std::vector* batches) const; + static void GetBatchSizes(int num_items, int max_batches, + double final_bytes_per_item, + double high_water_bytes_per_item, + double preferred_max_bytes_per_batch, + std::vector* batch_sizes); + void ReserveSpace(const BatchDescriptor& batch, + std::vector all_edges[6]) const; + void AddShape(int id, std::vector all_edges[6], + InteriorTracker* tracker) const; + void RemoveShape(const RemovedShape& removed, + std::vector all_edges[6], + InteriorTracker* tracker) const; + void AddFaceEdge(FaceEdge* edge, std::vector all_edges[6]) const; + void UpdateFaceEdges(int face, const std::vector& face_edges, + InteriorTracker* tracker); + S2CellId ShrinkToFit(const S2PaddedCell& pcell, const R2Rect& bound) const; + void SkipCellRange(S2CellId begin, S2CellId end, InteriorTracker* tracker, + EdgeAllocator* alloc, bool disjoint_from_index); + void UpdateEdges(const S2PaddedCell& pcell, + std::vector* edges, + InteriorTracker* tracker, EdgeAllocator* alloc, + bool disjoint_from_index); + void AbsorbIndexCell(const S2PaddedCell& pcell, + const Iterator& iter, + std::vector* edges, + InteriorTracker* tracker, + EdgeAllocator* alloc); + int GetEdgeMaxLevel(const S2Shape::Edge& edge) const; + static int CountShapes(const std::vector& edges, + const ShapeIdSet& cshape_ids); + bool MakeIndexCell(const S2PaddedCell& pcell, + const std::vector& edges, + InteriorTracker* tracker); + static void TestAllEdges(const std::vector& edges, + InteriorTracker* tracker); + inline static const ClippedEdge* UpdateBound(const ClippedEdge* edge, + int u_end, double u, + int v_end, double v, + EdgeAllocator* alloc); + static const ClippedEdge* ClipUBound(const ClippedEdge* edge, + int u_end, double u, + EdgeAllocator* alloc); + static const ClippedEdge* ClipVBound(const ClippedEdge* edge, + int v_end, double v, + EdgeAllocator* alloc); + static void ClipVAxis(const ClippedEdge* edge, const R1Interval& middle, + std::vector child_edges[2], + EdgeAllocator* alloc); + + // The amount by which cells are "padded" to compensate for numerical errors + // when clipping line segments to cell boundaries. + static const double kCellPadding; + + // The shapes in the index, accessed by their shape id. Removed shapes are + // replaced by nullptr pointers. + std::vector> shapes_; + + // A map from S2CellId to the set of clipped shapes that intersect that + // cell. The cell ids cover a set of non-overlapping regions on the + // sphere. Note that this field is updated lazily (see below). Const + // methods *must* call MaybeApplyUpdates() before accessing this field. + // (The easiest way to achieve this is simply to use an Iterator.) + CellMap cell_map_; + + // The options supplied for this index. + Options options_; + + // The id of the first shape that has been queued for addition but not + // processed yet. + int pending_additions_begin_ = 0; + + // The representation of an edge that has been queued for removal. + struct RemovedShape { + int32 shape_id; + bool has_interior; // Belongs to a shape of dimension 2. + bool contains_tracker_origin; + std::vector edges; + }; + + // The set of shapes that have been queued for removal but not processed + // yet. Note that we need to copy the edge data since the caller is free to + // destroy the shape once Release() has been called. This field is present + // only when there are removed shapes to process (to save memory). + std::unique_ptr> pending_removals_; + + // Additions and removals are queued and processed on the first subsequent + // query. There are several reasons to do this: + // + // - It is significantly more efficient to process updates in batches. + // - Often the index will never be queried, in which case we can save both + // the time and memory required to build it. Examples: + // + S2Loops that are created simply to pass to an S2Polygon. (We don't + // need the S2Loop index, because S2Polygon builds its own index.) + // + Applications that load a database of geometry and then query only + // a small fraction of it. + // + Applications that only read and write geometry (Decode/Encode). + // + // The main drawback is that we need to go to some extra work to ensure that + // "const" methods are still thread-safe. Note that the goal is *not* to + // make this class thread-safe in general, but simply to hide the fact that + // we defer some of the indexing work until query time. + // + // The textbook approach to this problem would be to use a mutex and a + // condition variable. Unfortunately pthread mutexes are huge (40 bytes). + // Instead we use spinlock (which is only 4 bytes) to guard a few small + // fields representing the current update status, and only create additional + // state while the update is actually occurring. + mutable SpinLock lock_; + + enum IndexStatus { + STALE, // There are pending updates. + UPDATING, // Updates are currently being applied. + FRESH, // There are no pending updates. + }; + // Reads and writes to this field are guarded by "lock_". + std::atomic index_status_; + + // UpdateState holds temporary data related to thread synchronization. It + // is only allocated while updates are being applied. + struct UpdateState { + // This mutex is used as a condition variable. It is locked by the + // updating thread for the entire duration of the update; other threads + // lock it in order to wait until the update is finished. + absl::Mutex wait_mutex; + + // The number of threads currently waiting on "wait_mutex_". The + // UpdateState can only be freed when this number reaches zero. + // + // Reads and writes to this field are guarded by "lock_". + int num_waiting; + + UpdateState() : num_waiting(0) { + } + + ~UpdateState() { + S2_DCHECK_EQ(0, num_waiting); + } + }; + std::unique_ptr update_state_; + + // Documented in the .cc file. + void UnlockAndSignal() + UNLOCK_FUNCTION(lock_) + UNLOCK_FUNCTION(update_state_->wait_mutex); + + MutableS2ShapeIndex(const MutableS2ShapeIndex&) = delete; + void operator=(const MutableS2ShapeIndex&) = delete; +}; + + +////////////////// Implementation details follow //////////////////// + + +inline MutableS2ShapeIndex::Iterator::Iterator() : index_(nullptr) { +} + +inline MutableS2ShapeIndex::Iterator::Iterator( + const MutableS2ShapeIndex* index, InitialPosition pos) { + Init(index, pos); +} + +inline void MutableS2ShapeIndex::Iterator::Init( + const MutableS2ShapeIndex* index, InitialPosition pos) { + index->MaybeApplyUpdates(); + InitStale(index, pos); +} + +inline void MutableS2ShapeIndex::Iterator::InitStale( + const MutableS2ShapeIndex* index, InitialPosition pos) { + index_ = index; + end_ = index_->cell_map_.end(); + if (pos == BEGIN) { + iter_ = index_->cell_map_.begin(); + } else { + iter_ = end_; + } + Refresh(); +} + +inline const S2ShapeIndexCell& MutableS2ShapeIndex::Iterator::cell() const { + // Since MutableS2ShapeIndex always sets the "cell_" field, we can skip the + // logic in the base class that conditionally calls GetCell(). + return *raw_cell(); +} + +inline void MutableS2ShapeIndex::Iterator::Refresh() { + if (iter_ == end_) { + set_finished(); + } else { + set_state(iter_->first, iter_->second); + } +} + +inline void MutableS2ShapeIndex::Iterator::Begin() { + // Make sure that the index has not been modified since Init() was called. + S2_DCHECK(index_->is_fresh()); + iter_ = index_->cell_map_.begin(); + Refresh(); +} + +inline void MutableS2ShapeIndex::Iterator::Finish() { + iter_ = end_; + Refresh(); +} + +inline void MutableS2ShapeIndex::Iterator::Next() { + S2_DCHECK(!done()); + ++iter_; + Refresh(); +} + +inline bool MutableS2ShapeIndex::Iterator::Prev() { + if (iter_ == index_->cell_map_.begin()) return false; + --iter_; + Refresh(); + return true; +} + +inline void MutableS2ShapeIndex::Iterator::Seek(S2CellId target) { + iter_ = index_->cell_map_.lower_bound(target); + Refresh(); +} + +inline std::unique_ptr +MutableS2ShapeIndex::NewIterator(InitialPosition pos) const { + return absl::make_unique(this, pos); +} + +inline bool MutableS2ShapeIndex::is_fresh() const { + return index_status_.load(std::memory_order_relaxed) == FRESH; +} + +// Return true if this is the first update to the index. +inline bool MutableS2ShapeIndex::is_first_update() const { + // Note that it is not sufficient to check whether cell_map_ is empty, since + // entries are added during the update process. + return pending_additions_begin_ == 0; +} + +// Given that the given shape is being updated, return true if it is being +// removed (as opposed to being added). +inline bool MutableS2ShapeIndex::is_shape_being_removed(int shape_id) const { + // All shape ids being removed are less than all shape ids being added. + return shape_id < pending_additions_begin_; +} + +// Ensure that any pending updates have been applied. This method must be +// called before accessing the cell_map_ field, even if the index_status_ +// appears to be FRESH, because a memory barrier is required in order to +// ensure that all the index updates are visible if the updates were done in +// another thread. +inline void MutableS2ShapeIndex::MaybeApplyUpdates() const { + // To avoid acquiring and releasing the spinlock on every query, we use + // atomic operations when testing whether the status is FRESH and when + // updating the status to be FRESH. This guarantees that any thread that + // sees a status of FRESH will also see the corresponding index updates. + if (index_status_.load(std::memory_order_acquire) != FRESH) { + const_cast(this)->ApplyUpdatesThreadSafe(); + } +} + +#endif // S2_MUTABLE_S2SHAPE_INDEX_H_ diff --git a/inst/include/s2/r1interval.h b/inst/include/s2/r1interval.h new file mode 100644 index 0000000..f120803 --- /dev/null +++ b/inst/include/s2/r1interval.h @@ -0,0 +1,220 @@ +// Copyright 2005 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS-IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +// Author: ericv@google.com (Eric Veach) + +#ifndef S2_R1INTERVAL_H_ +#define S2_R1INTERVAL_H_ + +#include +#include +#include +#include + +#include "s2/base/logging.h" +#include "s2/_fp_contract_off.h" +#include "s2/util/math/vector.h" // IWYU pragma: export + +// An R1Interval represents a closed, bounded interval on the real line. +// It is capable of representing the empty interval (containing no points) +// and zero-length intervals (containing a single point). +// +// This class is intended to be copied by value as desired. It uses +// the default copy constructor and assignment operator. +class R1Interval { + public: + // Constructor. If lo > hi, the interval is empty. + R1Interval(double lo, double hi) : bounds_(lo, hi) {} + + // The default constructor creates an empty interval. (Any interval where + // lo > hi is considered to be empty.) + // + // Note: Don't construct an interval using the default constructor and + // set_lo()/set_hi(), since this technique doesn't work with S1Interval and + // is bad programming style anyways. If you need to set both endpoints, use + // the constructor above: + // + // lat_bounds_ = R1Interval(lat_lo, lat_hi); + R1Interval() : bounds_(1, 0) {} + + // Returns an empty interval. + static R1Interval Empty() { return R1Interval(); } + + // Convenience method to construct an interval containing a single point. + static R1Interval FromPoint(double p) { return R1Interval(p, p); } + + // Convenience method to construct the minimal interval containing + // the two given points. This is equivalent to starting with an empty + // interval and calling AddPoint() twice, but it is more efficient. + static R1Interval FromPointPair(double p1, double p2) { + if (p1 <= p2) { + return R1Interval(p1, p2); + } else { + return R1Interval(p2, p1); + } + } + + // Accessors methods. + double lo() const { return bounds_[0]; } + double hi() const { return bounds_[1]; } + + // Methods to modify one endpoint of an existing R1Interval. Do not use + // these methods if you want to replace both endpoints of the interval; use + // a constructor instead. For example: + // + // *lat_bounds = R1Interval(lat_lo, lat_hi); + void set_lo(double p) { bounds_[0] = p; } + void set_hi(double p) { bounds_[1] = p; } + + // Methods that allow the R1Interval to be accessed as a vector. (The + // recommended style is to use lo() and hi() whenever possible, but these + // methods are useful when the endpoint to be selected is not constant.) + double operator[](int i) const { return bounds_[i]; } + double& operator[](int i) { return bounds_[i]; } + const Vector2_d& bounds() const { return bounds_; } + Vector2_d* mutable_bounds() { return &bounds_; } + + // Return true if the interval is empty, i.e. it contains no points. + bool is_empty() const { return lo() > hi(); } + + // Return the center of the interval. For empty intervals, + // the result is arbitrary. + double GetCenter() const { return 0.5 * (lo() + hi()); } + + // Return the length of the interval. The length of an empty interval + // is negative. + double GetLength() const { return hi() - lo(); } + + bool Contains(double p) const { + return p >= lo() && p <= hi(); + } + + bool InteriorContains(double p) const { + return p > lo() && p < hi(); + } + + // Return true if this interval contains the interval 'y'. + bool Contains(const R1Interval& y) const { + if (y.is_empty()) return true; + return y.lo() >= lo() && y.hi() <= hi(); + } + + // Return true if the interior of this interval contains the entire + // interval 'y' (including its boundary). + bool InteriorContains(const R1Interval& y) const { + if (y.is_empty()) return true; + return y.lo() > lo() && y.hi() < hi(); + } + + // Return true if this interval intersects the given interval, + // i.e. if they have any points in common. + bool Intersects(const R1Interval& y) const { + if (lo() <= y.lo()) { + return y.lo() <= hi() && y.lo() <= y.hi(); + } else { + return lo() <= y.hi() && lo() <= hi(); + } + } + + // Return true if the interior of this interval intersects + // any point of the given interval (including its boundary). + bool InteriorIntersects(const R1Interval& y) const { + return y.lo() < hi() && lo() < y.hi() && lo() < hi() && y.lo() <= y.hi(); + } + + // Return the Hausdorff distance to the given interval 'y'. For two + // R1Intervals x and y, this distance is defined as + // h(x, y) = max_{p in x} min_{q in y} d(p, q). + double GetDirectedHausdorffDistance(const R1Interval& y) const { + if (is_empty()) return 0.0; + if (y.is_empty()) return HUGE_VAL; + return std::max(0.0, std::max(hi() - y.hi(), y.lo() - lo())); + } + + // Expand the interval so that it contains the given point "p". + void AddPoint(double p) { + if (is_empty()) { set_lo(p); set_hi(p); } + else if (p < lo()) { set_lo(p); } // NOLINT + else if (p > hi()) { set_hi(p); } // NOLINT + } + + // Expand the interval so that it contains the given interval "y". + void AddInterval(const R1Interval& y) { + if (y.is_empty()) return; + if (is_empty()) { *this = y; return; } + if (y.lo() < lo()) set_lo(y.lo()); + if (y.hi() > hi()) set_hi(y.hi()); + } + + // Return the closest point in the interval to the given point "p". + // The interval must be non-empty. + double Project(double p) const { + S2_DCHECK(!is_empty()); + return std::max(lo(), std::min(hi(), p)); + } + + // Return an interval that has been expanded on each side by the given + // distance "margin". If "margin" is negative, then shrink the interval on + // each side by "margin" instead. The resulting interval may be empty. Any + // expansion of an empty interval remains empty. + R1Interval Expanded(double margin) const { + if (is_empty()) return *this; + return R1Interval(lo() - margin, hi() + margin); + } + + // Return the smallest interval that contains this interval and the + // given interval "y". + R1Interval Union(const R1Interval& y) const { + if (is_empty()) return y; + if (y.is_empty()) return *this; + return R1Interval(std::min(lo(), y.lo()), std::max(hi(), y.hi())); + } + + // Return the intersection of this interval with the given interval. + // Empty intervals do not need to be special-cased. + R1Interval Intersection(const R1Interval& y) const { + return R1Interval(std::max(lo(), y.lo()), std::min(hi(), y.hi())); + } + + // Return true if two intervals contain the same set of points. + bool operator==(const R1Interval& y) const { + return (lo() == y.lo() && hi() == y.hi()) || (is_empty() && y.is_empty()); + } + + // Return true if two intervals do not contain the same set of points. + bool operator!=(const R1Interval& y) const { + return !operator==(y); + } + + // Return true if this interval can be transformed into the given interval + // by moving each endpoint by at most "max_error". The empty interval is + // considered to be positioned arbitrarily on the real line, thus any + // interval with (length <= 2*max_error) matches the empty interval. + bool ApproxEquals(const R1Interval& y, double max_error = 1e-15) const { + if (is_empty()) return y.GetLength() <= 2 * max_error; + if (y.is_empty()) return GetLength() <= 2 * max_error; + return (std::fabs(y.lo() - lo()) <= max_error && + std::fabs(y.hi() - hi()) <= max_error); + } + + private: + Vector2_d bounds_; +}; + +inline std::ostream& operator<<(std::ostream& os, const R1Interval& x) { + return os << "[" << x.lo() << ", " << x.hi() << "]"; +} + +#endif // S2_R1INTERVAL_H_ diff --git a/inst/include/s2/r2.h b/inst/include/s2/r2.h new file mode 100644 index 0000000..9336e14 --- /dev/null +++ b/inst/include/s2/r2.h @@ -0,0 +1,26 @@ +// Copyright 2012 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS-IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +// Author: ericv@google.com (Eric Veach) + +#ifndef S2_R2_H_ +#define S2_R2_H_ + +#include "s2/_fp_contract_off.h" +#include "s2/util/math/vector.h" // IWYU pragma: export + +using R2Point = Vector2_d; + +#endif // S2_R2_H_ diff --git a/inst/include/s2/r2rect.h b/inst/include/s2/r2rect.h new file mode 100644 index 0000000..7700fae --- /dev/null +++ b/inst/include/s2/r2rect.h @@ -0,0 +1,234 @@ +// Copyright 2012 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS-IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +// Author: ericv@google.com (Eric Veach) + +#ifndef S2_R2RECT_H_ +#define S2_R2RECT_H_ + +#include + +#include "s2/base/logging.h" +#include "s2/_fp_contract_off.h" +#include "s2/r1interval.h" +#include "s2/r2.h" + +// An R2Rect represents a closed axis-aligned rectangle in the (x,y) plane. +// +// This class is intended to be copied by value as desired. It uses +// the default copy constructor and assignment operator, however it is +// not a "plain old datatype" (POD) because it has virtual functions. +class R2Rect { + public: + // Construct a rectangle from the given lower-left and upper-right points. + R2Rect(const R2Point& lo, const R2Point& hi); + + // Construct a rectangle from the given intervals in x and y. The two + // intervals must either be both empty or both non-empty. + R2Rect(const R1Interval& x, const R1Interval& y); + + // The default constructor creates an empty R2Rect. + R2Rect(); + + // The canonical empty rectangle. Use is_empty() to test for empty + // rectangles, since they have more than one representation. + static R2Rect Empty(); + + // Construct a rectangle from a center point and size in each dimension. + // Both components of size should be non-negative, i.e. this method cannot + // be used to create an empty rectangle. + static R2Rect FromCenterSize(const R2Point& center, const R2Point& size); + + // Convenience method to construct a rectangle containing a single point. + static R2Rect FromPoint(const R2Point& p); + + // Convenience method to construct the minimal bounding rectangle containing + // the two given points. This is equivalent to starting with an empty + // rectangle and calling AddPoint() twice. Note that it is different than + // the R2Rect(lo, hi) constructor, where the first point is always + // used as the lower-left corner of the resulting rectangle. + static R2Rect FromPointPair(const R2Point& p1, const R2Point& p2); + + // Accessor methods. + const R1Interval& x() const { return bounds_[0]; } + const R1Interval& y() const { return bounds_[1]; } + R2Point lo() const { return R2Point(x().lo(), y().lo()); } + R2Point hi() const { return R2Point(x().hi(), y().hi()); } + + // Methods that allow the R2Rect to be accessed as a vector. + const R1Interval& operator[](int i) const { return bounds_[i]; } + R1Interval& operator[](int i) { return bounds_[i]; } + + // Return true if the rectangle is valid, which essentially just means + // that if the bound for either axis is empty then both must be. + bool is_valid() const; + + // Return true if the rectangle is empty, i.e. it contains no points at all. + bool is_empty() const; + + // Return the k-th vertex of the rectangle (k = 0,1,2,3) in CCW order. + // Vertex 0 is in the lower-left corner. For convenience, the argument is + // reduced modulo 4 to the range [0..3]. + R2Point GetVertex(int k) const; + + // Return the vertex in direction "i" along the x-axis (0=left, 1=right) and + // direction "j" along the y-axis (0=down, 1=up). Equivalently, return the + // vertex constructed by selecting endpoint "i" of the x-interval (0=lo, + // 1=hi) and vertex "j" of the y-interval. + R2Point GetVertex(int i, int j) const; + + // Return the center of the rectangle in (x,y)-space. + R2Point GetCenter() const; + + // Return the width and height of this rectangle in (x,y)-space. Empty + // rectangles have a negative width and height. + R2Point GetSize() const; + + // Return true if the rectangle contains the given point. Note that + // rectangles are closed regions, i.e. they contain their boundary. + bool Contains(const R2Point& p) const; + + // Return true if and only if the given point is contained in the interior + // of the region (i.e. the region excluding its boundary). + bool InteriorContains(const R2Point& p) const; + + // Return true if and only if the rectangle contains the given other + // rectangle. + bool Contains(const R2Rect& other) const; + + // Return true if and only if the interior of this rectangle contains all + // points of the given other rectangle (including its boundary). + bool InteriorContains(const R2Rect& other) const; + + // Return true if this rectangle and the given other rectangle have any + // points in common. + bool Intersects(const R2Rect& other) const; + + // Return true if and only if the interior of this rectangle intersects + // any point (including the boundary) of the given other rectangle. + bool InteriorIntersects(const R2Rect& other) const; + + // Expand the rectangle to include the given point. The rectangle is + // expanded by the minimum amount possible. + void AddPoint(const R2Point& p); + + // Expand the rectangle to include the given other rectangle. This is the + // same as replacing the rectangle by the union of the two rectangles, but + // is somewhat more efficient. + void AddRect(const R2Rect& other); + + // Return the closest point in the rectangle to the given point "p". + // The rectangle must be non-empty. + R2Point Project(const R2Point& p) const; + + // Return a rectangle that has been expanded on each side in the x-direction + // by margin.x(), and on each side in the y-direction by margin.y(). If + // either margin is empty, then shrink the interval on the corresponding + // sides instead. The resulting rectangle may be empty. Any expansion of + // an empty rectangle remains empty. + R2Rect Expanded(const R2Point& margin) const; + R2Rect Expanded(double margin) const; + + // Return the smallest rectangle containing the union of this rectangle and + // the given rectangle. + R2Rect Union(const R2Rect& other) const; + + // Return the smallest rectangle containing the intersection of this + // rectangle and the given rectangle. + R2Rect Intersection(const R2Rect& other) const; + + // Return true if two rectangles contains the same set of points. + bool operator==(const R2Rect& other) const; + + // Return true if the x- and y-intervals of the two rectangles are the same + // up to the given tolerance (see r1interval.h for details). + bool ApproxEquals(const R2Rect& other, double max_error = 1e-15) const; + + private: + R1Interval bounds_[2]; +}; + +inline R2Rect::R2Rect(const R2Point& lo, const R2Point& hi) { + bounds_[0] = R1Interval(lo.x(), hi.x()); + bounds_[1] = R1Interval(lo.y(), hi.y()); + S2_DCHECK(is_valid()); +} + +inline R2Rect::R2Rect(const R1Interval& x, const R1Interval& y) { + bounds_[0] = x; + bounds_[1] = y; + S2_DCHECK(is_valid()); +} + +inline R2Rect::R2Rect() { + // The default R1Interval constructor creates an empty interval. + S2_DCHECK(is_valid()); +} + +inline R2Rect R2Rect::Empty() { + return R2Rect(R1Interval::Empty(), R1Interval::Empty()); +} + +inline bool R2Rect::is_valid() const { + // The x/y ranges must either be both empty or both non-empty. + return x().is_empty() == y().is_empty(); +} + +inline bool R2Rect::is_empty() const { + return x().is_empty(); +} + +inline R2Rect R2Rect::FromPoint(const R2Point& p) { + return R2Rect(p, p); +} + +inline R2Point R2Rect::GetVertex(int k) const { + // Twiddle bits to return the points in CCW order (lower left, lower right, + // upper right, upper left). + int j = (k >> 1) & 1; + return GetVertex(j ^ (k & 1), j); +} + +inline R2Point R2Rect::GetVertex(int i, int j) const { + return R2Point(bounds_[0][i], bounds_[1][j]); +} + +inline R2Point R2Rect::GetCenter() const { + return R2Point(x().GetCenter(), y().GetCenter()); +} + +inline R2Point R2Rect::GetSize() const { + return R2Point(x().GetLength(), y().GetLength()); +} + +inline bool R2Rect::Contains(const R2Point& p) const { + return x().Contains(p.x()) && y().Contains(p.y()); +} + +inline bool R2Rect::InteriorContains(const R2Point& p) const { + return x().InteriorContains(p.x()) && y().InteriorContains(p.y()); +} + +inline R2Rect R2Rect::Expanded(double margin) const { + return Expanded(R2Point(margin, margin)); +} + +inline bool R2Rect::operator==(const R2Rect& other) const { + return x() == other.x() && y() == other.y(); +} + +std::ostream& operator<<(std::ostream& os, const R2Rect& r); + +#endif // S2_R2RECT_H_ diff --git a/inst/include/s2/s1angle.h b/inst/include/s2/s1angle.h new file mode 100644 index 0000000..32f36a4 --- /dev/null +++ b/inst/include/s2/s1angle.h @@ -0,0 +1,336 @@ +// Copyright 2005 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS-IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +// Author: ericv@google.com (Eric Veach) + +#ifndef S2_S1ANGLE_H_ +#define S2_S1ANGLE_H_ + +#include +#include +#include +#include + +#include "s2/base/integral_types.h" +#include "s2/_fp_contract_off.h" +#include "s2/s2point.h" +#include "s2/util/math/mathutil.h" +#include "s2/util/math/vector.h" + +class S2LatLng; + +#ifndef SWIG +#define IFNDEF_SWIG(x) x +#else +#define IFNDEF_SWIG(x) +#endif + +// This class represents a one-dimensional angle (as opposed to a +// two-dimensional solid angle). It has methods for converting angles to +// or from radians, degrees, and the E5/E6/E7 representations (i.e. degrees +// multiplied by 1e5/1e6/1e7 and rounded to the nearest integer). +// +// The internal representation is a double-precision value in radians, so +// conversion to and from radians is exact. Conversions between E5, E6, E7, +// and Degrees are not always exact; for example, Degrees(3.1) is different +// from E6(3100000) or E7(310000000). However, the following properties are +// guaranteed for any integer "n", provided that "n" is in the input range of +// both functions: +// +// Degrees(n) == E6(1000000 * n) +// Degrees(n) == E7(10000000 * n) +// E6(n) == E7(10 * n) +// +// The corresponding properties are *not* true for E5, so if you use E5 then +// don't test for exact equality when comparing to other formats such as +// Degrees or E7. +// +// The following conversions between degrees and radians are exact: +// +// Degrees(180) == Radians(M_PI) +// Degrees(45 * k) == Radians(k * M_PI / 4) for k == 0..8 +// +// These identities also hold when the arguments are scaled up or down by any +// power of 2. Some similar identities are also true, for example, +// Degrees(60) == Radians(M_PI / 3), but be aware that this type of identity +// does not hold in general. For example, Degrees(3) != Radians(M_PI / 60). +// +// Similarly, the conversion to radians means that Angle::Degrees(x).degrees() +// does not always equal "x". For example, +// +// S1Angle::Degrees(45 * k).degrees() == 45 * k for k == 0..8 +// but S1Angle::Degrees(60).degrees() != 60. +// +// This means that when testing for equality, you should allow for numerical +// errors (EXPECT_DOUBLE_EQ) or convert to discrete E5/E6/E7 values first. +// +// CAVEAT: All of the above properties depend on "double" being the usual +// 64-bit IEEE 754 type (which is true on almost all modern platforms). +// +// This class is intended to be copied by value as desired. It uses +// the default copy constructor and assignment operator. +class S1Angle { + public: + // These methods construct S1Angle objects from their measure in radians + // or degrees. + static constexpr S1Angle Radians(double radians); + static constexpr S1Angle Degrees(double degrees); + static constexpr S1Angle E5(int32 e5); + static constexpr S1Angle E6(int32 e6); + static constexpr S1Angle E7(int32 e7); + + // Convenience functions -- to use when args have been fixed32s in protos. + // + // The arguments are static_cast into int32, so very large unsigned values + // are treated as negative numbers. + static constexpr S1Angle UnsignedE6(uint32 e6); + static constexpr S1Angle UnsignedE7(uint32 e7); + + // The default constructor yields a zero angle. This is useful for STL + // containers and class methods with output arguments. + IFNDEF_SWIG(constexpr) S1Angle() : radians_(0) {} + + // Return an angle larger than any finite angle. + static constexpr S1Angle Infinity(); + + // A explicit shorthand for the default constructor. + static constexpr S1Angle Zero(); + + // Return the angle between two points, which is also equal to the distance + // between these points on the unit sphere. The points do not need to be + // normalized. This function has a maximum error of 3.25 * DBL_EPSILON (or + // 2.5 * DBL_EPSILON for angles up to 1 radian). If either point is + // zero-length (e.g. an uninitialized S2Point), or almost zero-length, the + // resulting angle will be zero. + S1Angle(const S2Point& x, const S2Point& y); + + // Like the constructor above, but return the angle (i.e., distance) between + // two S2LatLng points. This function has about 15 digits of accuracy for + // small distances but only about 8 digits of accuracy as the distance + // approaches 180 degrees (i.e., nearly-antipodal points). + S1Angle(const S2LatLng& x, const S2LatLng& y); + + constexpr double radians() const; + constexpr double degrees() const; + + int32 e5() const; + int32 e6() const; + int32 e7() const; + + // Return the absolute value of an angle. + S1Angle abs() const; + + // Comparison operators. + friend bool operator==(S1Angle x, S1Angle y); + friend bool operator!=(S1Angle x, S1Angle y); + friend bool operator<(S1Angle x, S1Angle y); + friend bool operator>(S1Angle x, S1Angle y); + friend bool operator<=(S1Angle x, S1Angle y); + friend bool operator>=(S1Angle x, S1Angle y); + + // Simple arithmetic operators for manipulating S1Angles. + friend S1Angle operator-(S1Angle a); + friend S1Angle operator+(S1Angle a, S1Angle b); + friend S1Angle operator-(S1Angle a, S1Angle b); + friend S1Angle operator*(double m, S1Angle a); + friend S1Angle operator*(S1Angle a, double m); + friend S1Angle operator/(S1Angle a, double m); + friend double operator/(S1Angle a, S1Angle b); + S1Angle& operator+=(S1Angle a); + S1Angle& operator-=(S1Angle a); + S1Angle& operator*=(double m); + S1Angle& operator/=(double m); + + // Trigonmetric functions (not necessary but slightly more convenient). + friend double sin(S1Angle a); + friend double cos(S1Angle a); + friend double tan(S1Angle a); + + // Return the angle normalized to the range (-180, 180] degrees. + S1Angle Normalized() const; + + // Normalize this angle to the range (-180, 180] degrees. + void Normalize(); + + // When S1Angle is used as a key in one of the btree container types + // (util/btree), indicate that linear rather than binary search should be + // used. This is much faster when the comparison function is cheap. + typedef std::true_type goog_btree_prefer_linear_node_search; + + private: + explicit IFNDEF_SWIG(constexpr) S1Angle(double radians) : radians_(radians) {} + double radians_; +}; + + +////////////////// Implementation details follow //////////////////// + + +inline constexpr S1Angle S1Angle::Infinity() { + return S1Angle(std::numeric_limits::infinity()); +} + +inline constexpr S1Angle S1Angle::Zero() { + return S1Angle(0); +} + +inline constexpr double S1Angle::radians() const { + return radians_; +} + +inline constexpr double S1Angle::degrees() const { + return (180 / M_PI) * radians_; +} + +// Note that the E5, E6, and E7 conversion involve two multiplications rather +// than one. This is mainly for backwards compatibility (changing this would +// break many tests), but it does have the nice side effect that conversions +// between Degrees, E6, and E7 are exact when the arguments are integers. + +inline int32 S1Angle::e5() const { + return MathUtil::FastIntRound(1e5 * degrees()); +} + +inline int32 S1Angle::e6() const { + return MathUtil::FastIntRound(1e6 * degrees()); +} + +inline int32 S1Angle::e7() const { + return MathUtil::FastIntRound(1e7 * degrees()); +} + +inline S1Angle S1Angle::abs() const { + return S1Angle(std::fabs(radians_)); +} + +inline bool operator==(S1Angle x, S1Angle y) { + return x.radians() == y.radians(); +} + +inline bool operator!=(S1Angle x, S1Angle y) { + return x.radians() != y.radians(); +} + +inline bool operator<(S1Angle x, S1Angle y) { + return x.radians() < y.radians(); +} + +inline bool operator>(S1Angle x, S1Angle y) { + return x.radians() > y.radians(); +} + +inline bool operator<=(S1Angle x, S1Angle y) { + return x.radians() <= y.radians(); +} + +inline bool operator>=(S1Angle x, S1Angle y) { + return x.radians() >= y.radians(); +} + +inline S1Angle operator-(S1Angle a) { + return S1Angle::Radians(-a.radians()); +} + +inline S1Angle operator+(S1Angle a, S1Angle b) { + return S1Angle::Radians(a.radians() + b.radians()); +} + +inline S1Angle operator-(S1Angle a, S1Angle b) { + return S1Angle::Radians(a.radians() - b.radians()); +} + +inline S1Angle operator*(double m, S1Angle a) { + return S1Angle::Radians(m * a.radians()); +} + +inline S1Angle operator*(S1Angle a, double m) { + return S1Angle::Radians(m * a.radians()); +} + +inline S1Angle operator/(S1Angle a, double m) { + return S1Angle::Radians(a.radians() / m); +} + +inline double operator/(S1Angle a, S1Angle b) { + return a.radians() / b.radians(); +} + +inline S1Angle& S1Angle::operator+=(S1Angle a) { + radians_ += a.radians(); + return *this; +} + +inline S1Angle& S1Angle::operator-=(S1Angle a) { + radians_ -= a.radians(); + return *this; +} + +inline S1Angle& S1Angle::operator*=(double m) { + radians_ *= m; + return *this; +} + +inline S1Angle& S1Angle::operator/=(double m) { + radians_ /= m; + return *this; +} + +inline double sin(S1Angle a) { + return sin(a.radians()); +} + +inline double cos(S1Angle a) { + return cos(a.radians()); +} + +inline double tan(S1Angle a) { + return tan(a.radians()); +} + +inline constexpr S1Angle S1Angle::Radians(double radians) { + return S1Angle(radians); +} + +inline constexpr S1Angle S1Angle::Degrees(double degrees) { + return S1Angle((M_PI / 180) * degrees); +} + +inline constexpr S1Angle S1Angle::E5(int32 e5) { + return Degrees(1e-5 * e5); +} + +inline constexpr S1Angle S1Angle::E6(int32 e6) { + return Degrees(1e-6 * e6); +} + +inline constexpr S1Angle S1Angle::E7(int32 e7) { + return Degrees(1e-7 * e7); +} + +inline constexpr S1Angle S1Angle::UnsignedE6(uint32 e6) { + return E6(static_cast(e6)); +} + +inline constexpr S1Angle S1Angle::UnsignedE7(uint32 e7) { + return E7(static_cast(e7)); +} + +// Writes the angle in degrees with 7 digits of precision after the +// decimal point, e.g. "17.3745904". +std::ostream& operator<<(std::ostream& os, S1Angle a); + +#undef IFNDEF_SWIG + +#endif // S2_S1ANGLE_H_ diff --git a/inst/include/s2/s1chord_angle.h b/inst/include/s2/s1chord_angle.h new file mode 100644 index 0000000..84abffd --- /dev/null +++ b/inst/include/s2/s1chord_angle.h @@ -0,0 +1,369 @@ +// Copyright 2013 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS-IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +// Author: ericv@google.com (Eric Veach) + +#ifndef S2_S1CHORD_ANGLE_H_ +#define S2_S1CHORD_ANGLE_H_ + +#include +#include +#include +#include + +#include "s2/_fp_contract_off.h" +#include "s2/s1angle.h" +#include "s2/s2pointutil.h" + +// S1ChordAngle represents the angle subtended by a chord (i.e., the straight +// line segment connecting two points on the sphere). Its representation +// makes it very efficient for computing and comparing distances, but unlike +// S1Angle it is only capable of representing angles between 0 and Pi radians. +// Generally, S1ChordAngle should only be used in loops where many angles need +// to be calculated and compared. Otherwise it is simpler to use S1Angle. +// +// S1ChordAngle also loses some accuracy as the angle approaches Pi radians. +// Specifically, the representation of (Pi - x) radians has an error of about +// (1e-15 / x), with a maximum error of about 2e-8 radians (about 13cm on the +// Earth's surface). For comparison, for angles up to 90 degrees (10000km) +// the worst-case representation error is about 2e-16 radians (1 nanometer), +// which is about the same as S1Angle. +// +// This class is intended to be copied by value as desired. It uses +// the default copy constructor and assignment operator. +class S1ChordAngle { + public: + // The default constructor yields a zero angle. This is useful for STL + // containers and class methods with output arguments. + S1ChordAngle() : length2_(0) {} + + // Construct the S1ChordAngle corresponding to the distance between the two + // given points. The points must be unit length. + S1ChordAngle(const S2Point& x, const S2Point& y); + + // Return the zero chord angle. + static S1ChordAngle Zero(); + + // Return a chord angle of 90 degrees (a "right angle"). + static S1ChordAngle Right(); + + // Return a chord angle of 180 degrees (a "straight angle"). This is the + // maximum finite chord angle. + static S1ChordAngle Straight(); + + // Return a chord angle larger than any finite chord angle. The only valid + // operations on Infinity() are comparisons, S1Angle conversions, and + // Successor() / Predecessor(). + static S1ChordAngle Infinity(); + + // Return a chord angle smaller than Zero(). The only valid operations on + // Negative() are comparisons, S1Angle conversions, and Successor() / + // Predecessor(). + static S1ChordAngle Negative(); + + // Conversion from an S1Angle. Angles outside the range [0, Pi] are handled + // as follows: Infinity() is mapped to Infinity(), negative angles are + // mapped to Negative(), and finite angles larger than Pi are mapped to + // Straight(). + // + // Note that this operation is relatively expensive and should be avoided. + // To use S1ChordAngle effectively, you should structure your code so that + // input arguments are converted to S1ChordAngles at the beginning of your + // algorithm, and results are converted back to S1Angles only at the end. + explicit S1ChordAngle(S1Angle angle); + + // Convenience methods implemented by converting from an S1Angle. + static S1ChordAngle Radians(double radians); + static S1ChordAngle Degrees(double degrees); + static S1ChordAngle E5(int32 e5); + static S1ChordAngle E6(int32 e6); + static S1ChordAngle E7(int32 e7); + + // Construct an S1ChordAngle that is an upper bound on the given S1Angle, + // i.e. such that FastUpperBoundFrom(x).ToAngle() >= x. Unlike the S1Angle + // constructor above, this method is very fast, and the bound is accurate to + // within 1% for distances up to about 3100km on the Earth's surface. + static S1ChordAngle FastUpperBoundFrom(S1Angle angle); + + // Construct an S1ChordAngle from the squared chord length. Note that the + // argument is automatically clamped to a maximum of 4.0 to handle possible + // roundoff errors. The argument must be non-negative. + static S1ChordAngle FromLength2(double length2); + + // Converts to an S1Angle. Can be used just like an S1Angle constructor: + // + // S1ChordAngle x = ...; + // return S1Angle(x); + // + // Infinity() is converted to S1Angle::Infinity(), and Negative() is + // converted to an unspecified negative S1Angle. + // + // Note that the conversion uses trigonometric functions and therefore + // should be avoided in inner loops. + explicit operator S1Angle() const; + + // Converts to an S1Angle (equivalent to the operator above). + S1Angle ToAngle() const; + + // Convenience methods implemented by calling ToAngle() first. Note that + // because of the S1Angle conversion these methods are relatively expensive + // (despite their lowercase names), so the results should be cached if they + // are needed inside loops. + double radians() const; + double degrees() const; + int32 e5() const; + int32 e6() const; + int32 e7() const; + + // All operators and functions are declared here so that we can put them all + // in one place. (The compound assignment operators must be put here.) + + // Comparison operators. + friend bool operator==(S1ChordAngle x, S1ChordAngle y); + friend bool operator!=(S1ChordAngle x, S1ChordAngle y); + friend bool operator<(S1ChordAngle x, S1ChordAngle y); + friend bool operator>(S1ChordAngle x, S1ChordAngle y); + friend bool operator<=(S1ChordAngle x, S1ChordAngle y); + friend bool operator>=(S1ChordAngle x, S1ChordAngle y); + + // Comparison predicates. + bool is_zero() const; + bool is_negative() const; + bool is_infinity() const; + bool is_special() const; // Negative or infinity. + + // Only addition and subtraction of S1ChordAngles is supported. These + // methods add or subtract the corresponding S1Angles, and clamp the result + // to the range [0, Pi]. Both arguments must be non-negative and + // non-infinite. + // + // REQUIRES: !a.is_special() && !b.is_special() + friend S1ChordAngle operator+(S1ChordAngle a, S1ChordAngle b); + friend S1ChordAngle operator-(S1ChordAngle a, S1ChordAngle b); + S1ChordAngle& operator+=(S1ChordAngle a); + S1ChordAngle& operator-=(S1ChordAngle a); + + // Trigonmetric functions. It is more accurate and efficient to call these + // rather than first converting to an S1Angle. + friend double sin(S1ChordAngle a); + friend double cos(S1ChordAngle a); + friend double tan(S1ChordAngle a); + + // Returns sin(a)**2, but computed more efficiently. + friend double sin2(S1ChordAngle a); + + // The squared length of the chord. (Most clients will not need this.) + double length2() const { return length2_; } + + // Returns the smallest representable S1ChordAngle larger than this object. + // This can be used to convert a "<" comparison to a "<=" comparison. For + // example: + // + // S2ClosestEdgeQuery query(...); + // S1ChordAngle limit = ...; + // if (query.IsDistanceLess(target, limit.Successor())) { + // // Distance to "target" is less than or equal to "limit". + // } + // + // Note the following special cases: + // Negative().Successor() == Zero() + // Straight().Successor() == Infinity() + // Infinity().Successor() == Infinity() + S1ChordAngle Successor() const; + + // Like Successor(), but returns the largest representable S1ChordAngle less + // than this object. + // + // Note the following special cases: + // Infinity().Predecessor() == Straight() + // Zero().Predecessor() == Negative() + // Negative().Predecessor() == Negative() + S1ChordAngle Predecessor() const; + + // Returns a new S1ChordAngle that has been adjusted by the given error + // bound (which can be positive or negative). "error" should be the value + // returned by one of the error bound methods below. For example: + // S1ChordAngle a(x, y); + // S1ChordAngle a1 = a.PlusError(a.GetS2PointConstructorMaxError()); + S1ChordAngle PlusError(double error) const; + + // Return the maximum error in length2() for the S1ChordAngle(x, y) + // constructor, assuming that "x" and "y" are normalized to within the + // bounds guaranteed by S2Point::Normalize(). (The error is defined with + // respect to the true distance after the points are projected to lie + // exactly on the sphere.) + double GetS2PointConstructorMaxError() const; + + // Return the maximum error in length2() for the S1Angle constructor. + double GetS1AngleConstructorMaxError() const; + + // Return true if the internal representation is valid. Negative() and + // Infinity() are both considered valid. + bool is_valid() const; + + // When S1ChordAngle is used as a key in one of the btree container types + // (util/btree), indicate that linear rather than binary search should be + // used. This is much faster when the comparison function is cheap. + typedef std::true_type goog_btree_prefer_linear_node_search; + + private: + // S1ChordAngles are represented by the squared chord length, which can + // range from 0 to 4. Infinity() uses an infinite squared length. + explicit S1ChordAngle(double length2) : length2_(length2) { + S2_DCHECK(is_valid()); + } + double length2_; +}; + + +////////////////// Implementation details follow //////////////////// + + +inline S1ChordAngle::S1ChordAngle(const S2Point& x, const S2Point& y) { + S2_DCHECK(S2::IsUnitLength(x)); + S2_DCHECK(S2::IsUnitLength(y)); + // The squared distance may slightly exceed 4.0 due to roundoff errors. + // The maximum error in the result is 2 * DBL_EPSILON * length2_. + length2_ = std::min(4.0, (x - y).Norm2()); + S2_DCHECK(is_valid()); +} + +inline S1ChordAngle S1ChordAngle::FromLength2(double length2) { + return S1ChordAngle(std::min(4.0, length2)); +} + +inline S1ChordAngle S1ChordAngle::Zero() { + return S1ChordAngle(0); +} + +inline S1ChordAngle S1ChordAngle::Right() { + return S1ChordAngle(2); +} + +inline S1ChordAngle S1ChordAngle::Straight() { + return S1ChordAngle(4); +} + +inline S1ChordAngle S1ChordAngle::Infinity() { + return S1ChordAngle(std::numeric_limits::infinity()); +} + +inline S1ChordAngle S1ChordAngle::Negative() { + return S1ChordAngle(-1); +} + +inline S1ChordAngle S1ChordAngle::Radians(double radians) { + return S1ChordAngle(S1Angle::Radians(radians)); +} + +inline S1ChordAngle S1ChordAngle::Degrees(double degrees) { + return S1ChordAngle(S1Angle::Degrees(degrees)); +} + +inline S1ChordAngle S1ChordAngle::E5(int32 e5) { + return S1ChordAngle(S1Angle::E5(e5)); +} + +inline S1ChordAngle S1ChordAngle::E6(int32 e6) { + return S1ChordAngle(S1Angle::E6(e6)); +} + +inline S1ChordAngle S1ChordAngle::E7(int32 e7) { + return S1ChordAngle(S1Angle::E7(e7)); +} + +inline S1ChordAngle S1ChordAngle::FastUpperBoundFrom(S1Angle angle) { + // This method uses the distance along the surface of the sphere as an upper + // bound on the distance through the sphere's interior. + return S1ChordAngle::FromLength2(angle.radians() * angle.radians()); +} + +inline S1ChordAngle::operator S1Angle() const { + return ToAngle(); +} + +inline double S1ChordAngle::radians() const { + return ToAngle().radians(); +} + +inline double S1ChordAngle::degrees() const { + return ToAngle().degrees(); +} + +inline int32 S1ChordAngle::e5() const { + return ToAngle().e5(); +} + +inline int32 S1ChordAngle::e6() const { + return ToAngle().e6(); +} + +inline int32 S1ChordAngle::e7() const { + return ToAngle().e7(); +} + +inline bool S1ChordAngle::is_zero() const { + return length2_ == 0; +} + +inline bool S1ChordAngle::is_negative() const { + // TODO(ericv): Consider stricter check here -- only allow Negative(). + return length2_ < 0; +} + +inline bool S1ChordAngle::is_infinity() const { + return length2_ == std::numeric_limits::infinity(); +} + +inline bool S1ChordAngle::is_special() const { + return is_negative() || is_infinity(); +} + +inline bool operator==(S1ChordAngle x, S1ChordAngle y) { + return x.length2() == y.length2(); +} + +inline bool operator!=(S1ChordAngle x, S1ChordAngle y) { + return x.length2() != y.length2(); +} + +inline bool operator<(S1ChordAngle x, S1ChordAngle y) { + return x.length2() < y.length2(); +} + +inline bool operator>(S1ChordAngle x, S1ChordAngle y) { + return x.length2() > y.length2(); +} + +inline bool operator<=(S1ChordAngle x, S1ChordAngle y) { + return x.length2() <= y.length2(); +} + +inline bool operator>=(S1ChordAngle x, S1ChordAngle y) { + return x.length2() >= y.length2(); +} + +inline S1ChordAngle& S1ChordAngle::operator+=(S1ChordAngle a) { + return (*this = *this + a); +} + +inline S1ChordAngle& S1ChordAngle::operator-=(S1ChordAngle a) { + return (*this = *this - a); +} + +// Outputs the chord angle as the equivalent S1Angle. +std::ostream& operator<<(std::ostream& os, S1ChordAngle a); + +#endif // S2_S1CHORD_ANGLE_H_ diff --git a/inst/include/s2/s1interval.h b/inst/include/s2/s1interval.h new file mode 100644 index 0000000..b37471a --- /dev/null +++ b/inst/include/s2/s1interval.h @@ -0,0 +1,266 @@ +// Copyright 2005 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS-IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +// Author: ericv@google.com (Eric Veach) + +#ifndef S2_S1INTERVAL_H_ +#define S2_S1INTERVAL_H_ + +#include +#include +#include + +#include "s2/base/logging.h" +#include "s2/_fp_contract_off.h" +#include "s2/util/math/vector.h" // IWYU pragma: export + +// An S1Interval represents a closed interval on a unit circle (also known +// as a 1-dimensional sphere). It is capable of representing the empty +// interval (containing no points), the full interval (containing all +// points), and zero-length intervals (containing a single point). +// +// Points are represented by the angle they make with the positive x-axis in +// the range [-Pi, Pi]. An interval is represented by its lower and upper +// bounds (both inclusive, since the interval is closed). The lower bound may +// be greater than the upper bound, in which case the interval is "inverted" +// (i.e. it passes through the point (-1, 0)). +// +// Note that the point (-1, 0) has two valid representations, Pi and -Pi. +// The normalized representation of this point internally is Pi, so that +// endpoints of normal intervals are in the range (-Pi, Pi]. However, we +// take advantage of the point -Pi to construct two special intervals: +// the Full() interval is [-Pi, Pi], and the Empty() interval is [Pi, -Pi]. +// +// This class is intended to be copied by value as desired. It uses +// the default copy constructor and assignment operator. +class S1Interval { + public: + // Constructor. Both endpoints must be in the range -Pi to Pi inclusive. + // The value -Pi is converted internally to Pi except for the Full() + // and Empty() intervals. + S1Interval(double lo, double hi); + + // The default constructor creates an empty interval. + // + // Note: Don't construct an interval using the default constructor and + // set_lo()/set_hi(). If you need to set both endpoints, use the + // constructor above: + // + // lng_bounds_ = S1Interval(lng_lo, lng_hi); + S1Interval(); + + // Returns the empty interval. + static S1Interval Empty(); + + // Returns the full interval. + static S1Interval Full(); + + // Convenience method to construct an interval containing a single point. + static S1Interval FromPoint(double p); + + // Convenience method to construct the minimal interval containing + // the two given points. This is equivalent to starting with an empty + // interval and calling AddPoint() twice, but it is more efficient. + static S1Interval FromPointPair(double p1, double p2); + + // Accessors methods. + double lo() const { return bounds_[0]; } + double hi() const { return bounds_[1]; } + + // Methods that allow the S1Interval to be accessed as a vector. (The + // recommended style is to use lo() and hi() whenever possible, but these + // methods are useful when the endpoint to be selected is not constant.) + // + // Only const versions of these methods are provided, since S1Interval + // has invariants that must be maintained after each update. + double operator[](int i) const { return bounds_[i]; } + const Vector2_d& bounds() const { return bounds_; } + + // An interval is valid if neither bound exceeds Pi in absolute value, + // and the value -Pi appears only in the Empty() and Full() intervals. + bool is_valid() const; + + // Return true if the interval contains all points on the unit circle. + bool is_full() const { return lo() == -M_PI && hi() == M_PI; } + + // Return true if the interval is empty, i.e. it contains no points. + bool is_empty() const { return lo() == M_PI && hi() == -M_PI; } + + // Return true if lo() > hi(). (This is true for empty intervals.) + bool is_inverted() const { return lo() > hi(); } + + // Return the midpoint of the interval. For full and empty intervals, + // the result is arbitrary. + double GetCenter() const; + + // Return the length of the interval. The length of an empty interval + // is negative. + double GetLength() const; + + // Return the complement of the interior of the interval. An interval and + // its complement have the same boundary but do not share any interior + // values. The complement operator is not a bijection, since the complement + // of a singleton interval (containing a single value) is the same as the + // complement of an empty interval. + S1Interval Complement() const; + + // Return the midpoint of the complement of the interval. For full and empty + // intervals, the result is arbitrary. For a singleton interval (containing a + // single point), the result is its antipodal point on S1. + double GetComplementCenter() const; + + // Return true if the interval (which is closed) contains the point 'p'. + bool Contains(double p) const; + + // Return true if the interior of the interval contains the point 'p'. + bool InteriorContains(double p) const; + + // Return true if the interval contains the given interval 'y'. + // Works for empty, full, and singleton intervals. + bool Contains(const S1Interval& y) const; + + // Returns true if the interior of this interval contains the entire + // interval 'y'. Note that x.InteriorContains(x) is true only when + // x is the empty or full interval, and x.InteriorContains(S1Interval(p,p)) + // is equivalent to x.InteriorContains(p). + bool InteriorContains(const S1Interval& y) const; + + // Return true if the two intervals contain any points in common. + // Note that the point +/-Pi has two representations, so the intervals + // [-Pi,-3] and [2,Pi] intersect, for example. + bool Intersects(const S1Interval& y) const; + + // Return true if the interior of this interval contains any point of the + // interval 'y' (including its boundary). Works for empty, full, and + // singleton intervals. + bool InteriorIntersects(const S1Interval& y) const; + + // Return the Hausdorff distance to the given interval 'y'. For two + // S1Intervals x and y, this distance is defined by + // h(x, y) = max_{p in x} min_{q in y} d(p, q), + // where d(.,.) is measured along S1. + double GetDirectedHausdorffDistance(const S1Interval& y) const; + + // Expand the interval by the minimum amount necessary so that it + // contains the given point "p" (an angle in the range [-Pi, Pi]). + void AddPoint(double p); + + // Return the closest point in the interval to the given point "p". + // The interval must be non-empty. + double Project(double p) const; + + // Return an interval that has been expanded on each side by the given + // distance "margin". If "margin" is negative, then shrink the interval on + // each side by "margin" instead. The resulting interval may be empty or + // full. Any expansion (positive or negative) of a full interval remains + // full, and any expansion of an empty interval remains empty. + S1Interval Expanded(double margin) const; + + // Return the smallest interval that contains this interval and the + // given interval "y". + S1Interval Union(const S1Interval& y) const; + + // Return the smallest interval that contains the intersection of this + // interval with "y". Note that the region of intersection may + // consist of two disjoint intervals. + S1Interval Intersection(const S1Interval& y) const; + + // Return true if two intervals contains the same set of points. + bool operator==(const S1Interval& y) const; + + // Return true if this interval can be transformed into the given interval by + // moving each endpoint by at most "max_error" (and without the endpoints + // crossing, which would invert the interval). Empty and full intervals are + // considered to start at an arbitrary point on the unit circle, thus any + // interval with (length <= 2*max_error) matches the empty interval, and any + // interval with (length >= 2*Pi - 2*max_error) matches the full interval. + bool ApproxEquals(const S1Interval& y, double max_error = 1e-15) const; + + // Low-level methods to modify one endpoint of an existing S1Interval. + // These methods should really be private because setting just one endpoint + // can violate the invariants maintained by S1Interval. In particular: + // + // - It is not valid to call these methods on an Empty() or Full() + // interval, since these intervals do not have any endpoints. + // + // - It is not allowed to set an endpoint to -Pi. (When these methods are + // used internally, values of -Pi have already been normalized to Pi.) + // + // The preferred way to modify both endpoints of an interval is to use a + // constructor, e.g. lng = S1Interval(lng_lo, lng_hi). + void set_lo(double p); + void set_hi(double p); + + private: + enum ArgsChecked { ARGS_CHECKED }; + + // Internal constructor that assumes that both arguments are in the + // correct range, i.e. normalization from -Pi to Pi is already done. + S1Interval(double lo, double hi, ArgsChecked dummy); + + // Return true if the interval (which is closed) contains the point 'p'. + // Skips the normalization of 'p' from -Pi to Pi. + bool FastContains(double p) const; + + Vector2_d bounds_; +}; + +inline S1Interval::S1Interval(double lo, double hi) : bounds_(lo, hi) { + if (lo == -M_PI && hi != M_PI) set_lo(M_PI); + if (hi == -M_PI && lo != M_PI) set_hi(M_PI); + S2_DCHECK(is_valid()); +} + +inline S1Interval::S1Interval(double lo, double hi, ArgsChecked dummy) + : bounds_(lo, hi) { + S2_DCHECK(is_valid()); +} + +inline S1Interval::S1Interval() : bounds_(M_PI, -M_PI) { +} + +inline S1Interval S1Interval::Empty() { + return S1Interval(); +} + +inline S1Interval S1Interval::Full() { + return S1Interval(-M_PI, M_PI, ARGS_CHECKED); +} + +inline bool S1Interval::is_valid() const { + return (std::fabs(lo()) <= M_PI && std::fabs(hi()) <= M_PI && + !(lo() == -M_PI && hi() != M_PI) && + !(hi() == -M_PI && lo() != M_PI)); +} + +inline bool S1Interval::operator==(const S1Interval& y) const { + return lo() == y.lo() && hi() == y.hi(); +} + +inline void S1Interval::set_lo(double p) { + bounds_[0] = p; + S2_DCHECK(is_valid()); +} + +inline void S1Interval::set_hi(double p) { + bounds_[1] = p; + S2_DCHECK(is_valid()); +} + +inline std::ostream& operator<<(std::ostream& os, const S1Interval& x) { + return os << "[" << x.lo() << ", " << x.hi() << "]"; +} + +#endif // S2_S1INTERVAL_H_ diff --git a/inst/include/s2/s2boolean_operation.h b/inst/include/s2/s2boolean_operation.h new file mode 100644 index 0000000..acceb06 --- /dev/null +++ b/inst/include/s2/s2boolean_operation.h @@ -0,0 +1,501 @@ +// Copyright 2017 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS-IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +// Author: ericv@google.com (Eric Veach) + +#ifndef S2_S2BOOLEAN_OPERATION_H_ +#define S2_S2BOOLEAN_OPERATION_H_ + +#include +#include +#include +#include "s2/s2builder.h" +#include "s2/s2builder_graph.h" +#include "s2/s2builder_layer.h" +#include "s2/value_lexicon.h" + +// This class implements boolean operations (intersection, union, difference, +// and symmetric difference) for regions whose boundaries are defined by +// geodesic edges. +// +// S2BooleanOperation operates on exactly two input regions at a time. Each +// region is represented as an S2ShapeIndex and may contain any number of +// points, polylines, and polygons. The region is essentially the union of +// these objects, except that polygon interiors must be disjoint from all +// other geometry (including other polygon interiors). If the input geometry +// for a region does not meet this condition, it can be normalized by +// computing its union first. Note that points or polylines are allowed to +// coincide with the boundaries of polygons. +// +// Degeneracies are supported. A polygon loop or polyline may consist of a +// single edge from a vertex to itself, and polygons may contain "sibling +// pairs" consisting of an edge and its corresponding reverse edge. Polygons +// must not have any duplicate edges (due to the requirement that polygon +// interiors are disjoint), but polylines may have duplicate edges or can even +// be self-intersecting. +// +// Points and polyline edges are treated as multisets: if the same point or +// polyline edge appears multiple times in the input, it will appear multiple +// times in the output. For example, the union of a point with an identical +// point consists of two points. This feature is useful for modeling large +// sets of points or polylines as a single region while maintaining their +// distinct identities, even when the points or polylines intersect each +// other. It is also useful for reconstructing polylines that loop back on +// themselves. If duplicate geometry is not desired, it can be merged by +// GraphOptions::DuplicateEdges::MERGE in the S2Builder output layer. +// +// Polylines are always considered to be directed. Polyline edges between the +// same pair of vertices are defined to intersect even if the two edges are in +// opposite directions. (Undirected polylines can be modeled by specifying +// GraphOptions::EdgeType::UNDIRECTED in the S2Builder output layer.) +// +// The output of each operation is sent to an S2Builder::Layer provided by the +// client. This allows clients to build any representation of the geometry +// they choose. It also allows the client to do additional postprocessing of +// the output before building data structures; for example, the client can +// easily discard degeneracies or convert them to another data type. +// +// The boundaries of polygons and polylines can be modeled as open, semi-open, +// or closed. Polyline boundaries are controlled by the PolylineModel class, +// whose options are as follows: +// +// - In the OPEN model, polylines do not contain their first or last vertex +// except for one special case: namely, if the polyline forms a loop and +// the polyline_loops_have_boundaries() option is set to false, then the +// first/last vertex is contained. +// +// - In the SEMI_OPEN model, polylines contain all vertices except the last. +// Therefore if one polyline starts where another polyline stops, the two +// polylines do not intersect. +// +// - In the CLOSED model, polylines contain all of their vertices. +// +// When multiple polylines are present, they are processed independently and +// have no effect on each other. For example, in the OPEN boundary model the +// polyline ABC contains the vertex B, while set of polylines {AB, BC} does +// not. (If you want to treat the polylines as a union instead, with +// boundaries merged according to the "mod 2" rule, this can be achieved by +// reassembling the edges into maximal polylines using S2PolylineVectorLayer +// with EdgeType::UNDIRECTED, DuplicateEdges::MERGE, and PolylineType::WALK.) +// +// Polygon boundaries are controlled by the PolygonModel class, which has the +// following options: +// +// - In the OPEN model, polygons do not contain their vertices or edges. +// This implies that a polyline that follows the boundary of a polygon will +// not intersect it. +// +// - In the SEMI_OPEN model, polygon point containment is defined such that +// if several polygons tile the region around a vertex, then exactly one of +// those polygons contains that vertex. Similarly polygons contain all of +// their edges, but none of their reversed edges. This implies that a +// polyline and polygon edge with the same endpoints intersect if and only +// if they are in the same direction. (This rule ensures that if a +// polyline is intersected with a polygon and its complement, the two +// resulting polylines do not have any edges in common.) +// +// - In the CLOSED model, polygons contain all their vertices, edges, and +// reversed edges. This implies that a polyline that shares an edge (in +// either direction) with a polygon is defined to intersect it. Similarly, +// this is the only model where polygons that touch at a vertex or along an +// edge intersect. +// +// Note that PolylineModel and PolygonModel are defined as separate classes in +// order to allow for possible future extensions. +// +// Operations between geometry of different dimensions are defined as follows: +// +// - For UNION, the higher-dimensional shape always wins. For example the +// union of a closed polygon A with a polyline B that coincides with the +// boundary of A consists only of the polygon A. +// +// - For INTERSECTION, the lower-dimensional shape always wins. For example, +// the intersection of a closed polygon A with a point B that coincides +// with a vertex of A consists only of the point B. +// +// - For DIFFERENCE, higher-dimensional shapes are not affected by +// subtracting lower-dimensional shapes. For example, subtracting a point +// or polyline from a polygon A yields the original polygon A. This rule +// exists because in general, it is impossible to represent the output +// using the specified boundary model(s). (Consider subtracting one vertex +// from a PolylineModel::CLOSED polyline, or subtracting one edge from a +// PolygonModel::CLOSED polygon.) If you want to perform operations like +// this, consider representing all boundaries explicitly (topological +// boundaries) using OPEN boundary models. Another option for polygons is +// to subtract a degenerate loop, which yields a polygon with a degenerate +// hole (see S2LaxPolygonShape). +// +// Note that in the case of Precision::EXACT operations, the above remarks +// only apply to the output before snapping. Snapping may cause nearby +// distinct edges to become coincident, e.g. a polyline may become coincident +// with a polygon boundary. However also note that S2BooleanOperation is +// perfectly happy to accept such geometry as input. +// +// Note the following differences between S2BooleanOperation and the similar +// S2MultiBooleanOperation class: +// +// - S2BooleanOperation operates on exactly two regions at a time, whereas +// S2MultiBooleanOperation operates on any number of regions. +// +// - S2BooleanOperation is potentially much faster when the input is already +// represented as S2ShapeIndexes. The algorithm is output sensitive and is +// often sublinear in the input size. This can be a big advantage if, say, +// +// - S2BooleanOperation supports exact predicates and the corresponding +// exact operations (i.e., operations that are equivalent to computing the +// exact result and then snap rounding it). +// +// - S2MultiBooleanOperation has better error guarantees when there are many +// regions, since it requires only one snapping operation for any number of +// input regions. +// +// Example usage: +// S2ShapeIndex a, b; // Input geometry, e.g. containing polygons. +// S2Polygon polygon; // Output geometry. +// S2BooleanOperation::Options options; +// options.set_snap_function(snap_function); +// S2BooleanOperation op(S2BooleanOperation::OpType::INTERSECTION, +// absl::make_unique(&polygon), +// options); +// S2Error error; +// if (!op.Build(a, b, &error)) { +// S2_LOG(ERROR) << error; +// ... +// } +// +// If the output includes objects of different dimensions, they can be +// assembled into different layers with code like this: +// +// vector points; +// vector> polylines; +// S2Polygon polygon; +// S2BooleanOperation op( +// S2BooleanOperation::OpType::UNION, +// absl::make_unique(&points), +// absl::make_unique(&polylines), +// absl::make_unique(&polygon)); + +class S2BooleanOperation { + public: + // The supported operation types. + enum class OpType { + UNION, // Contained by either region. + INTERSECTION, // Contained by both regions. + DIFFERENCE, // Contained by the first region but not the second. + SYMMETRIC_DIFFERENCE // Contained by one region but not the other. + }; + // Translates OpType to one of the strings above. + static const char* OpTypeToString(OpType op_type); + + // Defines whether polygons are considered to contain their vertices and/or + // edges (see definitions above). + enum class PolygonModel { OPEN, SEMI_OPEN, CLOSED }; + + // Defines whether polylines are considered to contain their endpoints + // (see definitions above). + enum class PolylineModel { OPEN, SEMI_OPEN, CLOSED }; + + // With Precision::EXACT, the operation is evaluated using the exact input + // geometry. Predicates that use this option will produce exact results; + // for example, they can distinguish between a polyline that barely + // intersects a polygon from one that barely misses it. Constructive + // operations (ones that yield new geometry, as opposed to predicates) are + // implemented by computing the exact result and then snap rounding it + // according to the given snap_function() (see below). This is as close as + // it is possible to get to the exact result while requiring that vertex + // coordinates have type "double". + // + // With Precision::SNAPPED, the input regions are snapped together *before* + // the operation is evaluated. So for example, two polygons that overlap + // slightly will be treated as though they share a common boundary, and + // similarly two polygons that are slightly separated from each other will + // be treated as though they share a common boundary. Snapped results are + // useful for dealing with points, since in S2 the only points that lie + // exactly on a polyline or polygon edge are the endpoints of that edge. + // + // Conceptually, the difference between these two options is that with + // Precision::SNAPPED, the inputs are snap rounded (together), whereas with + // Precision::EXACT only the result is snap rounded. + enum class Precision { EXACT, SNAPPED }; + + // SourceId identifies an edge from one of the two input S2ShapeIndexes. + // It consists of a region id (0 or 1), a shape id within that region's + // S2ShapeIndex, and an edge id within that shape. + class SourceId { + public: + SourceId(); + SourceId(int region_id, int32 shape_id, int32 edge_id); + explicit SourceId(int32 special_edge_id); + int region_id() const { return region_id_; } + int32 shape_id() const { return shape_id_; } + int32 edge_id() const { return edge_id_; } + // TODO(ericv): Convert to functions, define all 6 comparisons. + bool operator==(SourceId other) const; + bool operator<(SourceId other) const; + + private: + uint32 region_id_ : 1; + uint32 shape_id_ : 31; + int32 edge_id_; + }; + + class Options { + public: + Options(); + + // Convenience constructor that calls set_snap_function(). + explicit Options(const S2Builder::SnapFunction& snap_function); + + // Specifies the function to be used for snap rounding. + // + // DEFAULT: s2builderutil::IdentitySnapFunction(S1Angle::Zero()) + // - This does no snapping and preserves all input vertices exactly unless + // there are crossing edges, in which case the snap radius is increased + // to the maximum intersection point error (S2::kIntersectionError). + const S2Builder::SnapFunction& snap_function() const; + void set_snap_function(const S2Builder::SnapFunction& snap_function); + + // Defines whether polygons are considered to contain their vertices + // and/or edges (see comments above). + // + // DEFAULT: PolygonModel::SEMI_OPEN + PolygonModel polygon_model() const; + void set_polygon_model(PolygonModel model); + + // Defines whether polylines are considered to contain their vertices (see + // comments above). + // + // DEFAULT: PolylineModel::CLOSED + PolylineModel polyline_model() const; + void set_polyline_model(PolylineModel model); + + // Specifies whether a polyline loop is considered to have a non-empty + // boundary. By default this option is true, meaning that even if the + // first and last vertices of a polyline are the same, the polyline is + // considered to have a well-defined "start" and "end". For example, if + // the polyline boundary model is OPEN then the polyline loop would not + // include the start/end vertices. These are the best semantics for most + // applications, such as GPS tracks or road network segments. + // + // If the polyline forms a loop and this option is set to false, then + // instead the first and last vertices are considered to represent a + // single vertex in the interior of the polyline. In this case the + // boundary of the polyline is empty, meaning that the first/last vertex + // will be contained by the polyline even if the boundary model is OPEN. + // (Note that this option also has a small effect on the CLOSED boundary + // model, because the first/last vertices of a polyline loop are + // considered to represent one vertex rather than two.) + // + // The main reason for this option is to implement the "mod 2 union" + // boundary semantics of the OpenGIS Simple Features spec. This can be + // achieved by making sure that all polylines are constructed using + // S2Builder::Graph::PolylineType::WALK (which ensures that all polylines + // are as long as possible), and then setting this option to false. + // + // DEFAULT: true + bool polyline_loops_have_boundaries() const; + void set_polyline_loops_have_boundaries(bool value); + + // Specifies whether the operation should use the exact input geometry + // (Precision::EXACT), or whether the two input regions should be snapped + // together first (Precision::SNAPPED). + // + // DEFAULT: Precision::EXACT + Precision precision() const; + // void set_precision(Precision precision); + + // If true, the input geometry is interpreted as representing nearby + // geometry that has been snapped or simplified. It then outputs a + // conservative result based on the value of polygon_model() and + // polyline_model(). For the most part, this only affects the handling of + // degeneracies. + // + // - If the model is OPEN, the result is as open as possible. For + // example, the intersection of two identical degenerate shells is empty + // under PolygonModel::OPEN because they could have been disjoint before + // snapping. Similarly, two identical degenerate polylines have an + // empty intersection under PolylineModel::OPEN. + // + // - If the model is CLOSED, the result is as closed as possible. In the + // case of the DIFFERENCE operation, this is equivalent to evaluating + // A - B as Closure(A) - Interior(B). For other operations, it affects + // only the handling of degeneracies. For example, the union of two + // identical degenerate holes is empty under PolygonModel::CLOSED + // (i.e., the hole disappears) because the holes could have been + // disjoint before snapping. + // + // - If the model is SEMI_OPEN, the result is as degenerate as possible. + // New degeneracies will not be created, but all degeneracies that + // coincide with the opposite region's boundary are retained unless this + // would cause a duplicate polygon edge to be created. This model is + // is very useful for working with input data that has both positive and + // negative degeneracies (i.e., degenerate shells and holes). + // + // DEFAULT: false + bool conservative_output() const; + // void set_conservative_output(bool conservative); + + // If specified, then each output edge will be labelled with one or more + // SourceIds indicating which input edge(s) it corresponds to. This + // can be useful if your input geometry has additional data that needs to + // be propagated from the input to the output (e.g., elevations). + // + // You can access the labels by using an S2Builder::Layer type that + // supports labels, such as S2PolygonLayer. The layer outputs a + // "label_set_lexicon" and an "label_set_id" for each edge. You can then + // look up the source information for each edge like this: + // + // for (int32 label : label_set_lexicon.id_set(label_set_id)) { + // const SourceId& src = source_id_lexicon.value(label); + // // region_id() specifies which S2ShapeIndex the edge is from (0 or 1). + // DoSomething(src.region_id(), src.shape_id(), src.edge_id()); + // } + // + // DEFAULT: nullptr + ValueLexicon* source_id_lexicon() const; + // void set_source_id_lexicon(ValueLexicon* source_id_lexicon); + + // Options may be assigned and copied. + Options(const Options& options); + Options& operator=(const Options& options); + + private: + std::unique_ptr snap_function_; + PolygonModel polygon_model_ = PolygonModel::SEMI_OPEN; + PolylineModel polyline_model_ = PolylineModel::CLOSED; + bool polyline_loops_have_boundaries_ = true; + Precision precision_ = Precision::EXACT; + bool conservative_output_ = false; + ValueLexicon* source_id_lexicon_ = nullptr; + }; + + S2BooleanOperation(OpType op_type, + std::unique_ptr layer, + const Options& options = Options()); + + // Specifies that the output boundary edges should be sent to three + // different layers according to their dimension. Points (represented by + // degenerate edges) are sent to layer 0, polyline edges are sent to + // layer 1, and polygon edges are sent to layer 2. + // + // The dimension of an edge is defined as the minimum dimension of the two + // input edges that produced it. For example, the intersection of two + // crossing polyline edges is a considered to be a degenerate polyline + // rather than a point, so it is sent to layer 1. Clients can easily + // reclassify such polylines as points if desired, but this rule makes it + // easier for clients that want to process point, polyline, and polygon + // inputs differently. + // + // The layers are always built in the order 0, 1, 2, and all arguments to + // the Build() calls are guaranteed to be valid until the last call returns. + // All Graph objects have the same set of vertices and the same lexicon + // objects, in order to make it easier to write classes that process all the + // edges in parallel. + S2BooleanOperation(OpType op_type, + std::vector> layers, + const Options& options = Options()); + + OpType op_type() const { return op_type_; } + + // Executes the given operation. Returns true on success, and otherwise + // sets "error" appropriately. (This class does not generate any errors + // itself, but the S2Builder::Layer might.) + bool Build(const S2ShapeIndex& a, const S2ShapeIndex& b, + S2Error* error); + + // Convenience method that returns true if the result of the given operation + // is empty. + static bool IsEmpty(OpType op_type, + const S2ShapeIndex& a, const S2ShapeIndex& b, + const Options& options = Options()); + + // Convenience method that returns true if A intersects B. + static bool Intersects(const S2ShapeIndex& a, const S2ShapeIndex& b, + const Options& options = Options()) { + return !IsEmpty(OpType::INTERSECTION, b, a, options); + } + + // Convenience method that returns true if A contains B, i.e., if the + // difference (B - A) is empty. + static bool Contains(const S2ShapeIndex& a, const S2ShapeIndex& b, + const Options& options = Options()) { + return IsEmpty(OpType::DIFFERENCE, b, a, options); + } + + // Convenience method that returns true if the symmetric difference of A and + // B is empty. (Note that A and B may still not be identical, e.g. A may + // contain two copies of a polyline while B contains one.) + static bool Equals(const S2ShapeIndex& a, const S2ShapeIndex& b, + const Options& options = Options()) { + return IsEmpty(OpType::SYMMETRIC_DIFFERENCE, b, a, options); + } + + private: + class Impl; // The actual implementation. + + // Internal constructor to reduce code duplication. + S2BooleanOperation(OpType op_type, const Options& options); + + // Specifies that "result_empty" should be set to indicate whether the exact + // result of the operation is empty. This constructor is used to efficiently + // test boolean relationships (see IsEmpty above). + S2BooleanOperation(OpType op_type, bool* result_empty, + const Options& options = Options()); + + OpType op_type_; + Options options_; + + // The input regions. + const S2ShapeIndex* regions_[2]; + + // The output consists either of zero layers, one layer, or three layers. + std::vector> layers_; + + // The following field is set if and only if there are no output layers. + bool* result_empty_; +}; + + +////////////////// Implementation details follow //////////////////// + + +inline S2BooleanOperation::SourceId::SourceId() + : region_id_(0), shape_id_(0), edge_id_(-1) { +} + +inline S2BooleanOperation::SourceId::SourceId( + int region_id, int32 shape_id, int32 edge_id) + : region_id_(region_id), shape_id_(shape_id), edge_id_(edge_id) { +} + +inline S2BooleanOperation::SourceId::SourceId(int special_edge_id) + : region_id_(0), shape_id_(0), edge_id_(special_edge_id) { +} + +inline bool S2BooleanOperation::SourceId::operator==(SourceId other) const { + return (region_id_ == other.region_id_ && + shape_id_ == other.shape_id_ && + edge_id_ == other.edge_id_); +} + +inline bool S2BooleanOperation::SourceId::operator<(SourceId other) const { + if (region_id_ < other.region_id_) return true; + if (region_id_ > other.region_id_) return false; + if (shape_id_ < other.shape_id_) return true; + if (shape_id_ > other.shape_id_) return false; + return edge_id_ < other.edge_id_; +} + +#endif // S2_S2BOOLEAN_OPERATION_H_ diff --git a/inst/include/s2/s2builder.h b/inst/include/s2/s2builder.h new file mode 100644 index 0000000..308583e --- /dev/null +++ b/inst/include/s2/s2builder.h @@ -0,0 +1,1057 @@ +// Copyright 2016 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS-IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +// Author: ericv@google.com (Eric Veach) +// +// This class is a replacement for S2PolygonBuilder. Once all clients have +// been updated to use this class, S2PolygonBuilder will be removed. + +#ifndef S2_S2BUILDER_H_ +#define S2_S2BUILDER_H_ + +#include +#include +#include +#include "s2/base/integral_types.h" +#include "s2/third_party/absl/base/macros.h" +#include "s2/_fp_contract_off.h" +#include "s2/id_set_lexicon.h" +#include "s2/mutable_s2shape_index.h" +#include "s2/s1angle.h" +#include "s2/s1chord_angle.h" +#include "s2/s2cell_id.h" +#include "s2/s2error.h" +#include "s2/s2point_index.h" +#include "s2/s2shape_index.h" +#include "s2/util/gtl/compact_array.h" + +class S2Loop; +class S2Polygon; +class S2Polyline; + +// S2Builder is a tool for assembling polygonal geometry from edges. Here are +// some of the things it is designed for: +// +// 1. Building polygons, polylines, and polygon meshes from unsorted +// collections of edges. +// +// 2. Snapping geometry to discrete representations (such as S2CellId centers +// or E7 lat/lng coordinates) while preserving the input topology and with +// guaranteed error bounds. +// +// 3. Simplifying geometry (e.g. for indexing, display, or storage). +// +// 4. Importing geometry from other formats, including repairing geometry +// that has errors. +// +// 5. As a tool for implementing more complex operations such as polygon +// intersections and unions. +// +// The implementation is based on the framework of "snap rounding". Unlike +// most snap rounding implementations, S2Builder defines edges as geodesics on +// the sphere (straight lines) and uses the topology of the sphere (i.e., +// there are no "seams" at the poles or 180th meridian). The algorithm is +// designed to be 100% robust for arbitrary input geometry. It offers the +// following properties: +// +// - Guaranteed bounds on how far input vertices and edges can move during +// the snapping process (i.e., at most the given "snap_radius"). +// +// - Guaranteed minimum separation between edges and vertices other than +// their endpoints (similar to the goals of Iterated Snap Rounding). In +// other words, edges that do not intersect in the output are guaranteed +// to have a minimum separation between them. +// +// - Idempotency (similar to the goals of Stable Snap Rounding), i.e. if the +// input already meets the output criteria then it will not be modified. +// +// - Preservation of the input topology (up to the creation of +// degeneracies). This means that there exists a continuous deformation +// from the input to the output such that no vertex crosses an edge. In +// other words, self-intersections won't be created, loops won't change +// orientation, etc. +// +// - The ability to snap to arbitrary discrete point sets (such as S2CellId +// centers, E7 lat/lng points on the sphere, or simply a subset of the +// input vertices), rather than being limited to an integer grid. +// +// Here are some of its other features: +// +// - It can handle both directed and undirected edges. Undirected edges can +// be useful for importing data from other formats, e.g. where loops have +// unspecified orientations. +// +// - It can eliminate self-intersections by finding all edge pairs that cross +// and adding a new vertex at each intersection point. +// +// - It can simplify polygons to within a specified tolerance. For example, +// if two vertices are close enough they will be merged, and if an edge +// passes nearby a vertex then it will be rerouted through that vertex. +// Optionally, it can also detect nearly straight chains of short edges and +// replace them with a single long edge, while maintaining the same +// accuracy, separation, and topology guarantees ("simplify_edge_chains"). +// +// - It supports many different output types through the concept of "layers" +// (polylines, polygons, polygon meshes, etc). You can build multiple +// layers at once in order to ensure that snapping does not create +// intersections between different objects (for example, you can simplify a +// set of contour lines without the risk of having them cross each other). +// +// - It supports edge labels, which allow you to attach arbitrary information +// to edges and have it preserved during the snapping process. (This can +// also be achieved using layers, at a coarser level of granularity.) +// +// Caveats: +// +// - Because S2Builder only works with edges, it cannot distinguish between +// the empty and full polygons. If your application can generate both the +// empty and full polygons, you must implement logic outside of this class. +// +// Example showing how to snap a polygon to E7 coordinates: +// +// using s2builderutil::IntLatLngSnapFunction; +// S2Builder builder(S2Builder::Options(IntLatLngSnapFunction(7))); +// S2Polygon output; +// builder.StartLayer(absl::make_unique(&output)); +// builder.AddPolygon(input); +// S2Error error; +// if (!builder.Build(&error)) { +// S2_LOG(ERROR) << error; +// ... +// } +class S2Builder { + public: + // Indicates whether the input edges are undirected. Typically this is + // specified for each output layer (e.g., s2builderutil::S2PolygonLayer). + // + // Directed edges are preferred, since otherwise the output is ambiguous. + // For example, output polygons may be the *inverse* of the intended result + // (e.g., a polygon intended to represent the world's oceans may instead + // represent the world's land masses). Directed edges are also somewhat + // more efficient. + // + // However even with undirected edges, most S2Builder layer types try to + // preserve the input edge direction whenever possible. Generally, edges + // are reversed only when it would yield a simpler output. For example, + // S2PolygonLayer assumes that polygons created from undirected edges should + // cover at most half of the sphere. Similarly, S2PolylineVectorLayer + // assembles edges into as few polylines as possible, even if this means + // reversing some of the "undirected" input edges. + // + // For shapes with interiors, directed edges should be oriented so that the + // interior is to the left of all edges. This means that for a polygon with + // holes, the outer loops ("shells") should be directed counter-clockwise + // while the inner loops ("holes") should be directed clockwise. Note that + // S2Builder::AddPolygon() follows this convention automatically. + enum class EdgeType { DIRECTED, UNDIRECTED }; + + // A SnapFunction restricts the locations of the output vertices. For + // example, there are predefined snap functions that require vertices to be + // located at S2CellId centers or at E5/E6/E7 coordinates. The SnapFunction + // can also specify a minimum spacing between vertices (the "snap radius"). + // + // A SnapFunction defines the following methods: + // + // 1. The SnapPoint() method, which snaps a point P to a nearby point (the + // "candidate snap site"). Any point may be returned, including P + // itself (this is the "identity snap function"). + // + // 2. "snap_radius", the maximum distance that vertices can move when + // snapped. The snap_radius must be at least as large as the maximum + // distance between P and SnapPoint(P) for any point P. + // + // 3. "max_edge_deviation", the maximum distance that edges can move when + // snapped. It is slightly larger than "snap_radius" because when a + // geodesic edge is snapped, the center of the edge moves further than + // its endpoints. This value is computed automatically by S2Builder. + // + // 4. "min_vertex_separation", the guaranteed minimum distance between + // vertices in the output. This is generally a fraction of + // "snap_radius" where the fraction depends on the snap function. + // + // 5. A "min_edge_vertex_separation", the guaranteed minimum distance + // between edges and non-incident vertices in the output. This is + // generally a fraction of "snap_radius" where the fraction depends on + // the snap function. + // + // It is important to note that SnapPoint() does not define the actual + // mapping from input vertices to output vertices, since the points it + // returns (the candidate snap sites) are further filtered to ensure that + // they are separated by at least the snap radius. For example, if you + // specify E7 coordinates (2cm resolution) and a snap radius of 10m, then a + // subset of points returned by SnapPoint will be chosen (the "snap sites"), + // and each input vertex will be mapped to the closest site. Therefore you + // cannot assume that P is necessarily snapped to SnapPoint(P). + // + // S2Builder makes the following guarantees: + // + // 1. Every vertex is at a location returned by SnapPoint(). + // + // 2. Vertices are within "snap_radius" of the corresponding input vertex. + // + // 3. Edges are within "max_edge_deviation" of the corresponding input edge + // (a distance slightly larger than "snap_radius"). + // + // 4. Vertices are separated by at least "min_vertex_separation" + // (a fraction of "snap_radius" that depends on the snap function). + // + // 5. Edges and non-incident vertices are separated by at least + // "min_edge_vertex_separation" (a fraction of "snap_radius"). + // + // 6. Vertex and edge locations do not change unless one of the conditions + // above is not already met (idempotency / stability). + // + // 7. The topology of the input geometry is preserved (up to the creation + // of degeneracies). This means that there exists a continuous + // deformation from the input to the output such that no vertex + // crosses an edge. + class SnapFunction { + public: + virtual ~SnapFunction() {} + + // The maximum distance that vertices can move when snapped. + // + // If the snap radius is zero, then vertices are snapped together only if + // they are identical. Edges will not be snapped to any vertices other + // than their endpoints, even if there are vertices whose distance to the + // edge is zero, unless split_crossing_edges() is true. + // + // REQUIRES: snap_radius() <= kMaxSnapRadius + virtual S1Angle snap_radius() const = 0; + + // The maximum supported snap radius (equivalent to about 7800km). + static S1Angle kMaxSnapRadius(); + + // The maximum distance that the center of an edge can move when snapped. + // This is slightly larger than "snap_radius" because when a geodesic edge + // is snapped, the center of the edge moves further than its endpoints. + S1Angle max_edge_deviation() const; + + // The guaranteed minimum distance between vertices in the output. + // This is generally some fraction of "snap_radius". + virtual S1Angle min_vertex_separation() const = 0; + + // The guaranteed minimum spacing between edges and non-incident vertices + // in the output. This is generally some fraction of "snap_radius". + virtual S1Angle min_edge_vertex_separation() const = 0; + + // Returns a candidate snap site for the given point. The final vertex + // locations are a subset of the snap sites returned by this function + // (spaced at least "min_vertex_separation" apart). + // + // The only requirement is that SnapPoint(x) must return a point whose + // distance from "x" is no greater than "snap_radius". + virtual S2Point SnapPoint(const S2Point& point) const = 0; + + // Returns a deep copy of this SnapFunction. + virtual std::unique_ptr Clone() const = 0; + }; + + class Options { + public: + Options(); + + // Convenience constructor that calls set_snap_function(). + explicit Options(const SnapFunction& snap_function); + + // Sets the desired snap function. The snap function is copied + // internally, so you can safely pass a temporary object. + // + // Note that if your input data includes vertices that were created using + // S2::GetIntersection(), then you should use a "snap_radius" of + // at least S2::kIntersectionSnapRadius, e.g. by calling + // + // options.set_snap_function(s2builderutil::IdentitySnapFunction( + // S2::kIntersectionSnapRadius)); + // + // DEFAULT: s2builderutil::IdentitySnapFunction(S1Angle::Zero()) + // [This does no snapping and preserves all input vertices exactly.] + const SnapFunction& snap_function() const; + void set_snap_function(const SnapFunction& snap_function); + + // If true, then detect all pairs of crossing edges and eliminate them by + // adding a new vertex at their intersection point. + // + // When this option is true, the effective snap_radius() for edges is + // increased by S2::kIntersectionError to take into account the + // additional error when computing intersection points. In other words, + // edges may move by up to snap_radius() + S2::kIntersectionError. + // + // Undirected edges should always be used when the output is a polygon, + // since splitting a directed loop at a self-intersection converts it into + // two loops that don't define a consistent interior according to the + // "interior is on the left" rule. (On the other hand, it is fine to use + // directed edges when defining a polygon *mesh* because in that case the + // input consists of sibling edge pairs.) + // + // Self-intersections can also arise when importing data from a 2D + // projection. You can minimize this problem by subdividing the input + // edges so that the S2 edges (which are geodesics) stay close to the + // original projected edges (which are curves on the sphere). This can + // be done using s2builderutil::EdgeSplitter(), for example. + // + // DEFAULT: false + bool split_crossing_edges() const; + void set_split_crossing_edges(bool split_crossing_edges); + + // If true, then simplify the output geometry by replacing nearly straight + // chains of short edges with a single long edge. + // + // The combined effect of snapping and simplifying will not change the + // input by more than the guaranteed tolerances (see the list documented + // with the SnapFunction class). For example, simplified edges are + // guaranteed to pass within snap_radius() of the *original* positions of + // all vertices that were removed from that edge. This is a much tighter + // guarantee than can be achieved by snapping and simplifying separately. + // + // However, note that this option does not guarantee idempotency. In + // other words, simplifying geometry that has already been simplified once + // may simplify it further. (This is unavoidable, since tolerances are + // measured with respect to the original geometry, which is no longer + // available when the geometry is simplified a second time.) + // + // When the output consists of multiple layers, simplification is + // guaranteed to be consistent: for example, edge chains are simplified in + // the same way across layers, and simplification preserves topological + // relationships between layers (e.g., no crossing edges will be created). + // Note that edge chains in different layers do not need to be identical + // (or even have the same number of vertices, etc) in order to be + // simplified together. All that is required is that they are close + // enough together so that the same simplified edge can meet all of their + // individual snapping guarantees. + // + // Note that edge chains are approximated as parametric curves rather than + // point sets. This means that if an edge chain backtracks on itself (for + // example, ABCDEFEDCDEFGH) then such backtracking will be preserved to + // within snap_radius() (for example, if the preceding point were all in a + // straight line then the edge chain would be simplified to ACFCFH, noting + // that C and F have degree > 2 and therefore can't be simplified away). + // + // Simplified edges are assigned all labels associated with the edges of + // the simplified chain. + // + // For this option to have any effect, a SnapFunction with a non-zero + // snap_radius() must be specified. Also note that vertices specified + // using ForceVertex are never simplified away. + // + // DEFAULT: false + bool simplify_edge_chains() const; + void set_simplify_edge_chains(bool simplify_edge_chains); + + // If true, then snapping occurs only when the input geometry does not + // already meet the S2Builder output guarantees (see the SnapFunction + // class description for details). This means that if all input vertices + // are at snapped locations, all vertex pairs are separated by at least + // min_vertex_separation(), and all edge-vertex pairs are separated by at + // least min_edge_vertex_separation(), then no snapping is done. + // + // If false, then all vertex pairs and edge-vertex pairs closer than + // "snap_radius" will be considered for snapping. This can be useful, for + // example, if you know that your geometry contains errors and you want to + // make sure that features closer together than "snap_radius" are merged. + // + // This option is automatically turned off by simplify_edge_chains(), + // since simplifying edge chains is never guaranteed to be idempotent. + // + // DEFAULT: true + bool idempotent() const; + void set_idempotent(bool idempotent); + + // Options may be assigned and copied. + Options(const Options& options); + Options& operator=(const Options& options); + + private: + std::unique_ptr snap_function_; + bool split_crossing_edges_ = false; + bool simplify_edge_chains_ = false; + bool idempotent_ = true; + }; + + // The following classes are only needed by Layer implementations. + class GraphOptions; + class Graph; + + // For output layers that represent polygons, there is an ambiguity inherent + // in spherical geometry that does not exist in planar geometry. Namely, if + // a polygon has no edges, does it represent the empty polygon (containing + // no points) or the full polygon (containing all points)? This ambiguity + // also occurs for polygons that consist only of degeneracies, e.g. a + // degenerate loop with only two edges could be either a degenerate shell in + // the empty polygon or a degenerate hole in the full polygon. + // + // To resolve this ambiguity, an IsFullPolygonPredicate may be specified for + // each output layer (see AddIsFullPolygonPredicate below). If the output + // after snapping consists only of degenerate edges and/or sibling pairs + // (including the case where there are no edges at all), then the layer + // implementation calls the given predicate to determine whether the polygon + // is empty or full except for those degeneracies. The predicate is given + // an S2Builder::Graph containing the output edges, but note that in general + // the predicate must also have knowledge of the input geometry in order to + // determine the correct result. + // + // This predicate is only needed by layers that are assembled into polygons. + // It is not used by other layer types. + using IsFullPolygonPredicate = + std::function; + + // Default constructor; requires Init() to be called. + S2Builder(); + + // Convenience constructor that calls Init(). Note that to use the default + // options, C++ syntax requires an extra layer of parentheses: + // + // S2Builder builder{S2Builder::Options()}; + explicit S2Builder(const Options& options); + + // Initializes an S2Builder with the given options. + void Init(const Options& options); + const Options& options() const { return options_; } + + // Starts a new output layer. This method must be called before adding any + // edges to the S2Builder. You may call this method multiple times to build + // multiple geometric objects that are snapped to the same set of sites. + // + // For example, if you have a set of contour lines, then you could put each + // contour line in a separate layer. This keeps the contour lines separate + // from each other, while also ensuring that no crossing edges are created + // when they are snapped and/or simplified. (This is not true if the + // contour lines are snapped or simplified independently.) + // + // Similarly, if you have a set of polygons that share common boundaries + // (e.g., countries), you can snap and/or simplify them at the same time by + // putting them in different layers, while ensuring that their boundaries + // remain consistent (i.e., no crossing edges or T-vertices are introduced). + // + // Ownership of the layer is transferred to the S2Builder. Example usage: + // + // S2Polyline line1, line2; + // builder.StartLayer(make_unique(&line1))); + // ... Add edges using builder.AddEdge(), etc ... + // builder.StartLayer(make_unique(&line2))); + // ... Add edges using builder.AddEdge(), etc ... + // S2Error error; + // S2_CHECK(builder.Build(&error)) << error; // Builds "line1" & "line2" + class Layer; + void StartLayer(std::unique_ptr layer); + + // Adds a degenerate edge (representing a point) to the current layer. + void AddPoint(const S2Point& v); + + // Adds the given edge to the current layer. + void AddEdge(const S2Point& v0, const S2Point& v1); + + // Adds the edges in the given polyline. (Note that if the polyline + // consists of 0 or 1 vertices, this method does nothing.) + void AddPolyline(const S2Polyline& polyline); + + // Adds the edges in the given loop. If the sign() of the loop is negative + // (i.e. this loop represents a hole within a polygon), the edge directions + // are automatically reversed to ensure that the polygon interior is always + // to the left of every edge. + void AddLoop(const S2Loop& loop); + + // Adds the loops in the given polygon. Loops representing holes have their + // edge directions automatically reversed as described for AddLoop(). Note + // that this method does not distinguish between the empty and full polygons, + // i.e. adding a full polygon has the same effect as adding an empty one. + void AddPolygon(const S2Polygon& polygon); + + // Adds the edges of the given shape to the current layer. + void AddShape(const S2Shape& shape); + + // For layers that are assembled into polygons, this method specifies a + // predicate that is called when the output consists entirely of degenerate + // edges and/or sibling pairs. The predicate is given an S2Builder::Graph + // containing the output edges (if any) and is responsible for deciding + // whether this graph represents the empty polygon (possibly with degenerate + // shells) or the full polygon (possibly with degenerate holes). Note that + // this cannot be determined from the output edges alone; it also requires + // knowledge of the input geometry. (Also see IsFullPolygonPredicate above.) + // + // This method should be called at most once per layer; additional calls + // simply overwrite the previous value for the current layer. + // + // The default predicate simply returns false (i.e., degenerate polygons are + // assumed to be empty). Arguably it would better to return an error in + // this case, but the fact is that relatively few clients need to be able to + // construct full polygons, and it is unreasonable to expect all such + // clients to supply an appropriate predicate. + // + // The reason for having a predicate rather than a boolean value is that the + // predicate is responsible for determining whether the output polygon is + // empty or full. In general the input geometry is not degenerate, but + // rather collapses into a degenerate configuration due to snapping and/or + // simplification. + // + // TODO(ericv): Provide standard predicates to handle common cases, + // e.g. valid input geometry that becomes degenerate due to snapping. + void AddIsFullPolygonPredicate(IsFullPolygonPredicate predicate); + + // A predicate that returns an error indicating that no polygon predicate + // has been specified. + static bool IsFullPolygonUnspecified(const S2Builder::Graph& g, + S2Error* error); + + // Returns a predicate that returns a constant value (true or false); + static IsFullPolygonPredicate IsFullPolygon(bool is_full); + + // Forces a vertex to be located at the given position. This can be used to + // prevent certain input vertices from moving. However if you are trying to + // preserve part of the input boundary, be aware that this option does not + // prevent edges from being split by new vertices. + // + // Forced vertices are never snapped; if this is desired then you need to + // call options().snap_function().SnapPoint() explicitly. Forced vertices + // are also never simplified away (if simplify_edge_chains() is used). + // + // Caveat: Since this method can place vertices arbitrarily close together, + // S2Builder makes no minimum separation guaranteees with forced vertices. + void ForceVertex(const S2Point& vertex); + + // Every edge can have a set of non-negative integer labels attached to it. + // When used with an appropriate layer type, you can then retrieve the + // labels associated with each output edge. This can be useful when merging + // or combining data from several sources. (Note that in many cases it is + // easier to use separate output layers rather than labels.) + // + // Labels are 32-bit non-negative integers. To support other label types, + // you can use ValueLexicon to store the set of unique labels seen so far: + // + // ValueLexicon my_label_lexicon; + // builder.set_label(my_label_lexicon.Add(label)); + // + // The current set of labels is represented as a stack. This makes it easy + // to add and remove labels hierarchically (e.g., polygon 5, loop 2). Use + // set_label() and clear_labels() if you need at most one label per edge. + // + using Label = int32; + + // Clear the stack of labels. + void clear_labels(); + + // Add a label to the stack. + // REQUIRES: label >= 0. + void push_label(Label label); + + // Remove a label from the stack. + void pop_label(); + + // Convenience function that clears the stack and adds a single label. + // REQUIRES: label >= 0. + void set_label(Label label); + + // Performs the requested edge splitting, snapping, simplification, etc, and + // then assembles the resulting edges into the requested output layers. + // + // Returns true if all edges were assembled; otherwise sets "error" + // appropriately. Depending on the error, some or all output layers may + // have been created. Automatically resets the S2Builder state so that it + // can be reused. + // + // REQUIRES: error != nullptr. + bool Build(S2Error* error); + + // Clears all input data and resets the builder state. Any options + // specified are preserved. + void Reset(); + + private: + ////////////////////// Input Types ///////////////////////// + // All types associated with the S2Builder inputs are prefixed with "Input". + + // Identifies an input vertex. + using InputVertexId = int32; + + // Defines an input edge. + using InputEdge = std::pair; + + // Identifies an input edge. + using InputEdgeId = int32; + + // Identifies the set of input edge ids that were snapped to a given edge. + using InputEdgeIdSetId = int32; + + // Sort key for prioritizing input vertices. (Note that keys are *not* + // compared using std::less; see SortInputVertices for details.) + using InputVertexKey = std::pair; + + ////////////////////// Output Types ///////////////////////// + // These types define the output vertices and edges. + + // Identifies a snapped vertex ("snap site"). If there is only one layer, + // than SiteId is the same as Graph::VertexId, but if there are many layers + // then each Graph may contain only a subset of the sites. Also see + // GraphOptions::allow_vertex_filtering(). + using SiteId = int32; + + // Defines an output edge. + using Edge = std::pair; + + // Identifies an output edge. + using EdgeId = int32; + + // Identifies an output edge in a particular layer. + using LayerEdgeId = std::pair; + + class EdgeChainSimplifier; + + InputVertexId AddVertex(const S2Point& v); + void ChooseSites(); + void CopyInputEdges(); + std::vector SortInputVertices(); + void AddEdgeCrossings(const MutableS2ShapeIndex& input_edge_index); + void AddForcedSites(S2PointIndex* site_index); + bool is_forced(SiteId v) const; + void ChooseInitialSites(S2PointIndex* site_index); + S2Point SnapSite(const S2Point& point) const; + void CollectSiteEdges(const S2PointIndex& site_index); + void SortSitesByDistance(const S2Point& x, + gtl::compact_array* sites) const; + void AddExtraSites(const MutableS2ShapeIndex& input_edge_index); + void MaybeAddExtraSites(InputEdgeId edge_id, + InputEdgeId max_edge_id, + const std::vector& chain, + const MutableS2ShapeIndex& input_edge_index, + std::vector* snap_queue); + void AddExtraSite(const S2Point& new_site, + InputEdgeId max_edge_id, + const MutableS2ShapeIndex& input_edge_index, + std::vector* snap_queue); + S2Point GetSeparationSite(const S2Point& site_to_avoid, + const S2Point& v0, const S2Point& v1, + InputEdgeId input_edge_id) const; + S2Point GetCoverageEndpoint(const S2Point& p, const S2Point& x, + const S2Point& y, const S2Point& n) const; + void SnapEdge(InputEdgeId e, std::vector* chain) const; + + void BuildLayers(); + void BuildLayerEdges( + std::vector>* layer_edges, + std::vector>* layer_input_edge_ids, + IdSetLexicon* input_edge_id_set_lexicon); + void AddSnappedEdges( + InputEdgeId begin, InputEdgeId end, const GraphOptions& options, + std::vector* edges, std::vector* input_edge_ids, + IdSetLexicon* input_edge_id_set_lexicon, + std::vector>* site_vertices) const; + void MaybeAddInputVertex( + InputVertexId v, SiteId id, + std::vector>* site_vertices) const; + void AddSnappedEdge(SiteId src, SiteId dst, InputEdgeIdSetId id, + EdgeType edge_type, std::vector* edges, + std::vector* input_edge_ids) const; + void SimplifyEdgeChains( + const std::vector>& site_vertices, + std::vector>* layer_edges, + std::vector>* layer_input_edge_ids, + IdSetLexicon* input_edge_id_set_lexicon) const; + void MergeLayerEdges( + const std::vector>& layer_edges, + const std::vector>& layer_input_edge_ids, + std::vector* edges, + std::vector* input_edge_ids, + std::vector* edge_layers) const; + static bool StableLessThan(const Edge& a, const Edge& b, + const LayerEdgeId& ai, const LayerEdgeId& bi); + + //////////// Parameters ///////////// + + // S2Builder options. + Options options_; + + // The maximum distance (inclusive) that a vertex can move when snapped, + // equal to S1ChordAngle(options_.snap_function().snap_radius()). + S1ChordAngle site_snap_radius_ca_; + + // The maximum distance (inclusive) that an edge can move when snapping to a + // snap site. It can be slightly larger than the site snap radius when + // edges are being split at crossings. + S1ChordAngle edge_snap_radius_ca_; + + S1Angle max_edge_deviation_; + S1ChordAngle edge_site_query_radius_ca_; + S1ChordAngle min_edge_length_to_split_ca_; + + S1Angle min_site_separation_; + S1ChordAngle min_site_separation_ca_; + S1ChordAngle min_edge_site_separation_ca_; + S1ChordAngle min_edge_site_separation_ca_limit_; + + S1ChordAngle max_adjacent_site_separation_ca_; + + // The squared sine of the edge snap radius. This is equivalent to the snap + // radius (squared) for distances measured through the interior of the + // sphere to the plane containing an edge. This value is used only when + // interpolating new points along edges (see GetSeparationSite). + double edge_snap_radius_sin2_; + + // A copy of the argument to Build(). + S2Error* error_; + + // True if snapping was requested. This is true if either snap_radius() is + // positive, or split_crossing_edges() is true (which implicitly requests + // snapping to ensure that both crossing edges are snapped to the + // intersection point). + bool snapping_requested_; + + // Initially false, and set to true when it is discovered that at least one + // input vertex or edge does not meet the output guarantees (e.g., that + // vertices are separated by at least snap_function.min_vertex_separation). + bool snapping_needed_; + + //////////// Input Data ///////////// + + // A flag indicating whether label_set_ has been modified since the last + // time label_set_id_ was computed. + bool label_set_modified_; + + std::vector input_vertices_; + std::vector input_edges_; + + std::vector> layers_; + std::vector layer_options_; + std::vector layer_begins_; + std::vector layer_is_full_polygon_predicates_; + + // Each input edge has "label set id" (an int32) representing the set of + // labels attached to that edge. This vector is populated only if at least + // one label is used. + using LabelSetId = int32; + std::vector label_set_ids_; + IdSetLexicon label_set_lexicon_; + + // The current set of labels (represented as a stack). + std::vector; + // std::iterator_traits isn't guaranteed to be SFINAE-friendly until C++17, + // but this seems to be mostly pedantic. + template + using EnableIfForwardIterator = absl::enable_if_t::iterator_category, + std::forward_iterator_tag>::value>; + static constexpr bool NoexceptCopyable() { + return std::is_nothrow_copy_constructible::value && + absl::allocator_is_nothrow::value; + } + static constexpr bool NoexceptMovable() { + return std::is_nothrow_move_constructible::value && + absl::allocator_is_nothrow::value; + } + static constexpr bool DefaultConstructorIsNonTrivial() { + return !absl::is_trivially_default_constructible::value; + } + + public: + using allocator_type = typename AllocatorTraits::allocator_type; + using value_type = typename allocator_type::value_type; + using pointer = typename allocator_type::pointer; + using const_pointer = typename allocator_type::const_pointer; + using reference = typename allocator_type::reference; + using const_reference = typename allocator_type::const_reference; + using size_type = typename allocator_type::size_type; + using difference_type = typename allocator_type::difference_type; + using iterator = pointer; + using const_iterator = const_pointer; + using reverse_iterator = std::reverse_iterator; + using const_reverse_iterator = std::reverse_iterator; + + static constexpr size_type inline_elements = + (N == kFixedArrayUseDefault ? kInlineBytesDefault / sizeof(value_type) + : static_cast(N)); + + FixedArray( + const FixedArray& other, + const allocator_type& a = allocator_type()) noexcept(NoexceptCopyable()) + : FixedArray(other.begin(), other.end(), a) {} + + FixedArray( + FixedArray&& other, + const allocator_type& a = allocator_type()) noexcept(NoexceptMovable()) + : FixedArray(std::make_move_iterator(other.begin()), + std::make_move_iterator(other.end()), a) {} + + // Creates an array object that can store `n` elements. + // Note that trivially constructible elements will be uninitialized. + explicit FixedArray(size_type n, const allocator_type& a = allocator_type()) + : storage_(n, a) { + if (DefaultConstructorIsNonTrivial()) { + memory_internal::ConstructRange(storage_.alloc(), storage_.begin(), + storage_.end()); + } + } + + // Creates an array initialized with `n` copies of `val`. + FixedArray(size_type n, const value_type& val, + const allocator_type& a = allocator_type()) + : storage_(n, a) { + memory_internal::ConstructRange(storage_.alloc(), storage_.begin(), + storage_.end(), val); + } + + // Creates an array initialized with the size and contents of `init_list`. + FixedArray(std::initializer_list init_list, + const allocator_type& a = allocator_type()) + : FixedArray(init_list.begin(), init_list.end(), a) {} + + // Creates an array initialized with the elements from the input + // range. The array's size will always be `std::distance(first, last)`. + // REQUIRES: Iterator must be a forward_iterator or better. + // TODO(user) The same disambiguation in std::vector requires only + // InputIterator, not ForwardIterator. Investigate this restriction. + template * = nullptr> + FixedArray(Iterator first, Iterator last, + const allocator_type& a = allocator_type()) + : storage_(std::distance(first, last), a) { + memory_internal::CopyRange(storage_.alloc(), storage_.begin(), first, last); + } + + ~FixedArray() noexcept { + for (auto* cur = storage_.begin(); cur != storage_.end(); ++cur) { + AllocatorTraits::destroy(storage_.alloc(), cur); + } + } + + // Assignments are deleted because they break the invariant that the size of a + // `FixedArray` never changes. + void operator=(FixedArray&&) = delete; + void operator=(const FixedArray&) = delete; + + // FixedArray::size() + // + // Returns the length of the fixed array. + size_type size() const { return storage_.size(); } + + // FixedArray::max_size() + // + // Returns the largest possible value of `std::distance(begin(), end())` for a + // `FixedArray`. This is equivalent to the most possible addressable bytes + // over the number of bytes taken by T. + constexpr size_type max_size() const { + return (std::numeric_limits::max)() / sizeof(value_type); + } + + // FixedArray::empty() + // + // Returns whether or not the fixed array is empty. + bool empty() const { return size() == 0; } + + // FixedArray::memsize() + // + // Returns the memory size of the fixed array in bytes. + size_t memsize() const { return size() * sizeof(value_type); } + + // FixedArray::data() + // + // Returns a const T* pointer to elements of the `FixedArray`. This pointer + // can be used to access (but not modify) the contained elements. + const_pointer data() const { return AsValueType(storage_.begin()); } + + // Overload of FixedArray::data() to return a T* pointer to elements of the + // fixed array. This pointer can be used to access and modify the contained + // elements. + pointer data() { return AsValueType(storage_.begin()); } + + // FixedArray::operator[] + // + // Returns a reference the ith element of the fixed array. + // REQUIRES: 0 <= i < size() + reference operator[](size_type i) { + assert(i < size()); + return data()[i]; + } + + // Overload of FixedArray::operator()[] to return a const reference to the + // ith element of the fixed array. + // REQUIRES: 0 <= i < size() + const_reference operator[](size_type i) const { + assert(i < size()); + return data()[i]; + } + + // FixedArray::at + // + // Bounds-checked access. Returns a reference to the ith element of the + // fiexed array, or throws std::out_of_range + reference at(size_type i) { + if (ABSL_PREDICT_FALSE(i >= size())) { + base_internal::ThrowStdOutOfRange("FixedArray::at failed bounds check"); + } + return data()[i]; + } + + // Overload of FixedArray::at() to return a const reference to the ith element + // of the fixed array. + const_reference at(size_type i) const { + if (ABSL_PREDICT_FALSE(i >= size())) { + base_internal::ThrowStdOutOfRange("FixedArray::at failed bounds check"); + } + return data()[i]; + } + + // FixedArray::front() + // + // Returns a reference to the first element of the fixed array. + reference front() { return *begin(); } + + // Overload of FixedArray::front() to return a reference to the first element + // of a fixed array of const values. + const_reference front() const { return *begin(); } + + // FixedArray::back() + // + // Returns a reference to the last element of the fixed array. + reference back() { return *(end() - 1); } + + // Overload of FixedArray::back() to return a reference to the last element + // of a fixed array of const values. + const_reference back() const { return *(end() - 1); } + + // FixedArray::begin() + // + // Returns an iterator to the beginning of the fixed array. + iterator begin() { return data(); } + + // Overload of FixedArray::begin() to return a const iterator to the + // beginning of the fixed array. + const_iterator begin() const { return data(); } + + // FixedArray::cbegin() + // + // Returns a const iterator to the beginning of the fixed array. + const_iterator cbegin() const { return begin(); } + + // FixedArray::end() + // + // Returns an iterator to the end of the fixed array. + iterator end() { return data() + size(); } + + // Overload of FixedArray::end() to return a const iterator to the end of the + // fixed array. + const_iterator end() const { return data() + size(); } + + // FixedArray::cend() + // + // Returns a const iterator to the end of the fixed array. + const_iterator cend() const { return end(); } + + // FixedArray::rbegin() + // + // Returns a reverse iterator from the end of the fixed array. + reverse_iterator rbegin() { return reverse_iterator(end()); } + + // Overload of FixedArray::rbegin() to return a const reverse iterator from + // the end of the fixed array. + const_reverse_iterator rbegin() const { + return const_reverse_iterator(end()); + } + + // FixedArray::crbegin() + // + // Returns a const reverse iterator from the end of the fixed array. + const_reverse_iterator crbegin() const { return rbegin(); } + + // FixedArray::rend() + // + // Returns a reverse iterator from the beginning of the fixed array. + reverse_iterator rend() { return reverse_iterator(begin()); } + + // Overload of FixedArray::rend() for returning a const reverse iterator + // from the beginning of the fixed array. + const_reverse_iterator rend() const { + return const_reverse_iterator(begin()); + } + + // FixedArray::crend() + // + // Returns a reverse iterator from the beginning of the fixed array. + const_reverse_iterator crend() const { return rend(); } + + // FixedArray::fill() + // + // Assigns the given `value` to all elements in the fixed array. + void fill(const value_type& val) { std::fill(begin(), end(), val); } + + // Relational operators. Equality operators are elementwise using + // `operator==`, while order operators order FixedArrays lexicographically. + friend bool operator==(const FixedArray& lhs, const FixedArray& rhs) { + return absl::equal(lhs.begin(), lhs.end(), rhs.begin(), rhs.end()); + } + + friend bool operator!=(const FixedArray& lhs, const FixedArray& rhs) { + return !(lhs == rhs); + } + + friend bool operator<(const FixedArray& lhs, const FixedArray& rhs) { + return std::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), + rhs.end()); + } + + friend bool operator>(const FixedArray& lhs, const FixedArray& rhs) { + return rhs < lhs; + } + + friend bool operator<=(const FixedArray& lhs, const FixedArray& rhs) { + return !(rhs < lhs); + } + + friend bool operator>=(const FixedArray& lhs, const FixedArray& rhs) { + return !(lhs < rhs); + } + + template + friend H AbslHashValue(H h, const FixedArray& v) { + return H::combine(H::combine_contiguous(std::move(h), v.data(), v.size()), + v.size()); + } + + private: + // StorageElement + // + // For FixedArrays with a C-style-array value_type, StorageElement is a POD + // wrapper struct called StorageElementWrapper that holds the value_type + // instance inside. This is needed for construction and destruction of the + // entire array regardless of how many dimensions it has. For all other cases, + // StorageElement is just an alias of value_type. + // + // Maintainer's Note: The simpler solution would be to simply wrap value_type + // in a struct whether it's an array or not. That causes some paranoid + // diagnostics to misfire, believing that 'data()' returns a pointer to a + // single element, rather than the packed array that it really is. + // e.g.: + // + // FixedArray buf(1); + // sprintf(buf.data(), "foo"); + // + // error: call to int __builtin___sprintf_chk(etc...) + // will always overflow destination buffer [-Werror] + // + template , + size_t InnerN = std::extent::value> + struct StorageElementWrapper { + InnerT array[InnerN]; + }; + + using StorageElement = + absl::conditional_t::value, + StorageElementWrapper, value_type>; + using StorageElementBuffer = + absl::aligned_storage_t; + + static pointer AsValueType(pointer ptr) { return ptr; } + static pointer AsValueType(StorageElementWrapper* ptr) { + return std::addressof(ptr->array); + } + + static_assert(sizeof(StorageElement) == sizeof(value_type), ""); + static_assert(alignof(StorageElement) == alignof(value_type), ""); + + struct NonEmptyInlinedStorage { + StorageElement* data() { + return reinterpret_cast(inlined_storage_.data()); + } + +#ifdef ADDRESS_SANITIZER + void* RedzoneBegin() { return &redzone_begin_; } + void* RedzoneEnd() { return &redzone_end_ + 1; } +#endif // ADDRESS_SANITIZER + + void AnnotateConstruct(size_type); + void AnnotateDestruct(size_type); + + ADDRESS_SANITIZER_REDZONE(redzone_begin_); + std::array inlined_storage_; + ADDRESS_SANITIZER_REDZONE(redzone_end_); + }; + + struct EmptyInlinedStorage { + StorageElement* data() { return nullptr; } + void AnnotateConstruct(size_type) {} + void AnnotateDestruct(size_type) {} + }; + + using InlinedStorage = + absl::conditional_t; + + // Storage + // + // An instance of Storage manages the inline and out-of-line memory for + // instances of FixedArray. This guarantees that even when construction of + // individual elements fails in the FixedArray constructor body, the + // destructor for Storage will still be called and out-of-line memory will be + // properly deallocated. + // + class Storage : public InlinedStorage { + public: + Storage(size_type n, const allocator_type& a) + : size_alloc_(n, a), data_(InitializeData()) {} + + ~Storage() noexcept { + if (UsingInlinedStorage(size())) { + InlinedStorage::AnnotateDestruct(size()); + } else { + AllocatorTraits::deallocate(alloc(), AsValueType(begin()), size()); + } + } + + size_type size() const { return size_alloc_.template get<0>(); } + StorageElement* begin() const { return data_; } + StorageElement* end() const { return begin() + size(); } + allocator_type& alloc() { + return size_alloc_.template get<1>(); + } + + private: + static bool UsingInlinedStorage(size_type n) { + return n <= inline_elements; + } + + StorageElement* InitializeData() { + if (UsingInlinedStorage(size())) { + InlinedStorage::AnnotateConstruct(size()); + return InlinedStorage::data(); + } else { + return reinterpret_cast( + AllocatorTraits::allocate(alloc(), size())); + } + } + + // `CompressedTuple` takes advantage of EBCO for stateless `allocator_type`s + container_internal::CompressedTuple size_alloc_; + StorageElement* data_; + }; + + Storage storage_; +}; + +template +constexpr size_t FixedArray::kInlineBytesDefault; + +template +constexpr typename FixedArray::size_type + FixedArray::inline_elements; + +template +void FixedArray::NonEmptyInlinedStorage::AnnotateConstruct( + typename FixedArray::size_type n) { +#ifdef ADDRESS_SANITIZER + if (!n) return; + ANNOTATE_CONTIGUOUS_CONTAINER(data(), RedzoneEnd(), RedzoneEnd(), data() + n); + ANNOTATE_CONTIGUOUS_CONTAINER(RedzoneBegin(), data(), data(), RedzoneBegin()); +#endif // ADDRESS_SANITIZER + static_cast(n); // Mark used when not in asan mode +} + +template +void FixedArray::NonEmptyInlinedStorage::AnnotateDestruct( + typename FixedArray::size_type n) { +#ifdef ADDRESS_SANITIZER + if (!n) return; + ANNOTATE_CONTIGUOUS_CONTAINER(data(), RedzoneEnd(), data() + n, RedzoneEnd()); + ANNOTATE_CONTIGUOUS_CONTAINER(RedzoneBegin(), data(), RedzoneBegin(), data()); +#endif // ADDRESS_SANITIZER + static_cast(n); // Mark used when not in asan mode +} +} // namespace absl + +using absl::FixedArray; + +#endif // S2_THIRD_PARTY_ABSL_CONTAINER_FIXED_ARRAY_H_ diff --git a/inst/include/s2/third_party/absl/container/inlined_vector.h b/inst/include/s2/third_party/absl/container/inlined_vector.h new file mode 100644 index 0000000..2da7934 --- /dev/null +++ b/inst/include/s2/third_party/absl/container/inlined_vector.h @@ -0,0 +1,1453 @@ +// Copyright 2018 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// ----------------------------------------------------------------------------- +// File: inlined_vector.h +// ----------------------------------------------------------------------------- +// +// This header file contains the declaration and definition of an "inlined +// vector" which behaves in an equivalent fashion to a `std::vector`, except +// that storage for small sequences of the vector are provided inline without +// requiring any heap allocation. +// +// An `absl::InlinedVector` specifies the default capacity `N` as one of +// its template parameters. Instances where `size() <= N` hold contained +// elements in inline space. Typically `N` is very small so that sequences that +// are expected to be short do not require allocations. +// +// An `absl::InlinedVector` does not usually require a specific allocator. If +// the inlined vector grows beyond its initial constraints, it will need to +// allocate (as any normal `std::vector` would). This is usually performed with +// the default allocator (defined as `std::allocator`). Optionally, a custom +// allocator type may be specified as `A` in `absl::InlinedVector`. + +#ifndef S2_THIRD_PARTY_ABSL_CONTAINER_INLINED_VECTOR_H_ +#define S2_THIRD_PARTY_ABSL_CONTAINER_INLINED_VECTOR_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "s2/third_party/absl/algorithm/algorithm.h" +#include "s2/third_party/absl/base/internal/throw_delegate.h" +#include "s2/third_party/absl/base/optimization.h" +#include "s2/third_party/absl/base/port.h" +#include "s2/third_party/absl/memory/memory.h" + + +namespace absl { + +// ----------------------------------------------------------------------------- +// InlinedVector +// ----------------------------------------------------------------------------- +// +// An `absl::InlinedVector` is designed to be a drop-in replacement for +// `std::vector` for use cases where the vector's size is sufficiently small +// that it can be inlined. If the inlined vector does grow beyond its estimated +// capacity, it will trigger an initial allocation on the heap, and will behave +// as a `std:vector`. The API of the `absl::InlinedVector` within this file is +// designed to cover the same API footprint as covered by `std::vector`. +template > +class InlinedVector { + static_assert(N > 0, "InlinedVector requires inline capacity greater than 0"); + constexpr static typename A::size_type inlined_capacity() { + return static_cast(N); + } + + template + using DisableIfIntegral = + absl::enable_if_t::value>; + + template + using EnableIfInputIterator = absl::enable_if_t::iterator_category, + std::input_iterator_tag>::value>; + + template + using IteratorCategory = + typename std::iterator_traits::iterator_category; + + using rvalue_reference = typename A::value_type&&; + + public: + using allocator_type = A; + using value_type = typename allocator_type::value_type; + using pointer = typename allocator_type::pointer; + using const_pointer = typename allocator_type::const_pointer; + using reference = typename allocator_type::reference; + using const_reference = typename allocator_type::const_reference; + using size_type = typename allocator_type::size_type; + using difference_type = typename allocator_type::difference_type; + using iterator = pointer; + using const_iterator = const_pointer; + using reverse_iterator = std::reverse_iterator; + using const_reverse_iterator = std::reverse_iterator; + + // --------------------------------------------------------------------------- + // InlinedVector Constructors and Destructor + // --------------------------------------------------------------------------- + + // Creates an empty inlined vector with a default initialized allocator. + InlinedVector() noexcept(noexcept(allocator_type())) + : allocator_and_tag_(allocator_type()) {} + + // Creates an empty inlined vector with a specified allocator. + explicit InlinedVector(const allocator_type& alloc) noexcept + : allocator_and_tag_(alloc) {} + + // Creates an inlined vector with `n` copies of `value_type()`. + explicit InlinedVector(size_type n, + const allocator_type& alloc = allocator_type()) + : allocator_and_tag_(alloc) { + InitAssign(n); + } + + // Creates an inlined vector with `n` copies of `v`. + InlinedVector(size_type n, const_reference v, + const allocator_type& alloc = allocator_type()) + : allocator_and_tag_(alloc) { + InitAssign(n, v); + } + + // Creates an inlined vector of copies of the values in `init_list`. + InlinedVector(std::initializer_list init_list, + const allocator_type& alloc = allocator_type()) + : allocator_and_tag_(alloc) { + AppendRange(init_list.begin(), init_list.end()); + } + + // Creates an inlined vector with elements constructed from the provided + // Iterator range [`first`, `last`). + // + // NOTE: The `enable_if` prevents ambiguous interpretation between a call to + // this constructor with two integral arguments and a call to the above + // `InlinedVector(size_type, const_reference)` constructor. + template * = nullptr> + InlinedVector(InputIterator first, InputIterator last, + const allocator_type& alloc = allocator_type()) + : allocator_and_tag_(alloc) { + AppendRange(first, last); + } + + // Creates a copy of `other` using `other`'s allocator. + InlinedVector(const InlinedVector& other); + + // Creates a copy of `other` but with a specified allocator. + InlinedVector(const InlinedVector& other, const allocator_type& alloc); + + // Creates an inlined vector by moving in the contents of `other`. + // + // NOTE: This move constructor does not allocate and only moves the underlying + // objects, so its `noexcept` specification depends on whether moving the + // underlying objects can throw or not. We assume: + // a) move constructors should only throw due to allocation failure and + // b) if `value_type`'s move constructor allocates, it uses the same + // allocation function as the `InlinedVector`'s allocator, so the move + // constructor is non-throwing if the allocator is non-throwing or + // `value_type`'s move constructor is specified as `noexcept`. + InlinedVector(InlinedVector&& v) noexcept( + absl::allocator_is_nothrow::value || + std::is_nothrow_move_constructible::value); + + // Creates an inlined vector by moving in the contents of `other`. + // + // NOTE: This move constructor allocates and subsequently moves the underlying + // objects, so its `noexcept` specification depends on whether the allocation + // can throw and whether moving the underlying objects can throw. Based on the + // same assumptions as above, the `noexcept` specification is dominated by + // whether the allocation can throw regardless of whether `value_type`'s move + // constructor is specified as `noexcept`. + InlinedVector(InlinedVector&& v, const allocator_type& alloc) noexcept( + absl::allocator_is_nothrow::value); + + ~InlinedVector() { clear(); } + + // --------------------------------------------------------------------------- + // InlinedVector Member Accessors + // --------------------------------------------------------------------------- + + // `InlinedVector::empty()` + // + // Checks if the inlined vector has no elements. + bool empty() const noexcept { return !size(); } + + // `InlinedVector::size()` + // + // Returns the number of elements in the inlined vector. + size_type size() const noexcept { return tag().size(); } + + // `InlinedVector::max_size()` + // + // Returns the maximum number of elements the vector can hold. + size_type max_size() const noexcept { + // One bit of the size storage is used to indicate whether the inlined + // vector is allocated. As a result, the maximum size of the container that + // we can express is half of the max for `size_type`. + return (std::numeric_limits::max)() / 2; + } + + // `InlinedVector::capacity()` + // + // Returns the number of elements that can be stored in the inlined vector + // without requiring a reallocation of underlying memory. + // + // NOTE: For most inlined vectors, `capacity()` should equal + // `inlined_capacity()`. For inlined vectors which exceed this capacity, they + // will no longer be inlined and `capacity()` will equal its capacity on the + // allocated heap. + size_type capacity() const noexcept { + return allocated() ? allocation().capacity() : inlined_capacity(); + } + + // `InlinedVector::data()` + // + // Returns a `pointer` to elements of the inlined vector. This pointer can be + // used to access and modify the contained elements. + // Only results within the range [`0`, `size()`) are defined. + pointer data() noexcept { + return allocated() ? allocated_space() : inlined_space(); + } + + // Overload of `InlinedVector::data()` to return a `const_pointer` to elements + // of the inlined vector. This pointer can be used to access (but not modify) + // the contained elements. + const_pointer data() const noexcept { + return allocated() ? allocated_space() : inlined_space(); + } + + // `InlinedVector::operator[]()` + // + // Returns a `reference` to the `i`th element of the inlined vector using the + // array operator. + reference operator[](size_type i) { + assert(i < size()); + return data()[i]; + } + + // Overload of `InlinedVector::operator[]()` to return a `const_reference` to + // the `i`th element of the inlined vector. + const_reference operator[](size_type i) const { + assert(i < size()); + return data()[i]; + } + + // `InlinedVector::at()` + // + // Returns a `reference` to the `i`th element of the inlined vector. + reference at(size_type i) { + if (ABSL_PREDICT_FALSE(i >= size())) { + base_internal::ThrowStdOutOfRange( + "InlinedVector::at() failed bounds check"); + } + return data()[i]; + } + + // Overload of `InlinedVector::at()` to return a `const_reference` to the + // `i`th element of the inlined vector. + const_reference at(size_type i) const { + if (ABSL_PREDICT_FALSE(i >= size())) { + base_internal::ThrowStdOutOfRange( + "InlinedVector::at() failed bounds check"); + } + return data()[i]; + } + + // `InlinedVector::front()` + // + // Returns a `reference` to the first element of the inlined vector. + reference front() { + assert(!empty()); + return at(0); + } + + // Overload of `InlinedVector::front()` returns a `const_reference` to the + // first element of the inlined vector. + const_reference front() const { + assert(!empty()); + return at(0); + } + + // `InlinedVector::back()` + // + // Returns a `reference` to the last element of the inlined vector. + reference back() { + assert(!empty()); + return at(size() - 1); + } + + // Overload of `InlinedVector::back()` to return a `const_reference` to the + // last element of the inlined vector. + const_reference back() const { + assert(!empty()); + return at(size() - 1); + } + + // `InlinedVector::begin()` + // + // Returns an `iterator` to the beginning of the inlined vector. + iterator begin() noexcept { return data(); } + + // Overload of `InlinedVector::begin()` to return a `const_iterator` to + // the beginning of the inlined vector. + const_iterator begin() const noexcept { return data(); } + + // `InlinedVector::end()` + // + // Returns an `iterator` to the end of the inlined vector. + iterator end() noexcept { return data() + size(); } + + // Overload of `InlinedVector::end()` to return a `const_iterator` to the + // end of the inlined vector. + const_iterator end() const noexcept { return data() + size(); } + + // `InlinedVector::cbegin()` + // + // Returns a `const_iterator` to the beginning of the inlined vector. + const_iterator cbegin() const noexcept { return begin(); } + + // `InlinedVector::cend()` + // + // Returns a `const_iterator` to the end of the inlined vector. + const_iterator cend() const noexcept { return end(); } + + // `InlinedVector::rbegin()` + // + // Returns a `reverse_iterator` from the end of the inlined vector. + reverse_iterator rbegin() noexcept { return reverse_iterator(end()); } + + // Overload of `InlinedVector::rbegin()` to return a + // `const_reverse_iterator` from the end of the inlined vector. + const_reverse_iterator rbegin() const noexcept { + return const_reverse_iterator(end()); + } + + // `InlinedVector::rend()` + // + // Returns a `reverse_iterator` from the beginning of the inlined vector. + reverse_iterator rend() noexcept { return reverse_iterator(begin()); } + + // Overload of `InlinedVector::rend()` to return a `const_reverse_iterator` + // from the beginning of the inlined vector. + const_reverse_iterator rend() const noexcept { + return const_reverse_iterator(begin()); + } + + // `InlinedVector::crbegin()` + // + // Returns a `const_reverse_iterator` from the end of the inlined vector. + const_reverse_iterator crbegin() const noexcept { return rbegin(); } + + // `InlinedVector::crend()` + // + // Returns a `const_reverse_iterator` from the beginning of the inlined + // vector. + const_reverse_iterator crend() const noexcept { return rend(); } + + // `InlinedVector::get_allocator()` + // + // Returns a copy of the allocator of the inlined vector. + allocator_type get_allocator() const { return allocator(); } + + + // --------------------------------------------------------------------------- + // InlinedVector Member Mutators + // --------------------------------------------------------------------------- + + // `InlinedVector::operator=()` + // + // Replaces the contents of the inlined vector with copies of the elements in + // the provided `std::initializer_list`. + InlinedVector& operator=(std::initializer_list init_list) { + AssignRange(init_list.begin(), init_list.end()); + return *this; + } + + // Overload of `InlinedVector::operator=()` to replace the contents of the + // inlined vector with the contents of `other`. + InlinedVector& operator=(const InlinedVector& other) { + if (ABSL_PREDICT_FALSE(this == &other)) return *this; + + // Optimized to avoid reallocation. + // Prefer reassignment to copy construction for elements. + if (size() < other.size()) { // grow + reserve(other.size()); + std::copy(other.begin(), other.begin() + size(), begin()); + std::copy(other.begin() + size(), other.end(), std::back_inserter(*this)); + } else { // maybe shrink + erase(begin() + other.size(), end()); + std::copy(other.begin(), other.end(), begin()); + } + return *this; + } + + // Overload of `InlinedVector::operator=()` to replace the contents of the + // inlined vector with the contents of `other`. + // + // NOTE: As a result of calling this overload, `other` may be empty or it's + // contents may be left in a moved-from state. + InlinedVector& operator=(InlinedVector&& other) { + if (ABSL_PREDICT_FALSE(this == &other)) return *this; + + if (other.allocated()) { + clear(); + tag().set_allocated_size(other.size()); + init_allocation(other.allocation()); + other.tag() = Tag(); + } else { + if (allocated()) clear(); + // Both are inlined now. + if (size() < other.size()) { + auto mid = std::make_move_iterator(other.begin() + size()); + std::copy(std::make_move_iterator(other.begin()), mid, begin()); + UninitializedCopy(mid, std::make_move_iterator(other.end()), end()); + } else { + auto new_end = std::copy(std::make_move_iterator(other.begin()), + std::make_move_iterator(other.end()), begin()); + Destroy(new_end, end()); + } + tag().set_inline_size(other.size()); + } + return *this; + } + + // `InlinedVector::assign()` + // + // Replaces the contents of the inlined vector with `n` copies of `v`. + void assign(size_type n, const_reference v) { + if (n <= size()) { // Possibly shrink + std::fill_n(begin(), n, v); + erase(begin() + n, end()); + return; + } + // Grow + reserve(n); + std::fill_n(begin(), size(), v); + if (allocated()) { + UninitializedFill(allocated_space() + size(), allocated_space() + n, v); + tag().set_allocated_size(n); + } else { + UninitializedFill(inlined_space() + size(), inlined_space() + n, v); + tag().set_inline_size(n); + } + } + + // Overload of `InlinedVector::assign()` to replace the contents of the + // inlined vector with copies of the values in the provided + // `std::initializer_list`. + void assign(std::initializer_list init_list) { + AssignRange(init_list.begin(), init_list.end()); + } + + // Overload of `InlinedVector::assign()` to replace the contents of the + // inlined vector with values constructed from the range [`first`, `last`). + template * = nullptr> + void assign(InputIterator first, InputIterator last) { + AssignRange(first, last); + } + + // `InlinedVector::resize()` + // + // Resizes the inlined vector to contain `n` elements. If `n` is smaller than + // the inlined vector's current size, extra elements are destroyed. If `n` is + // larger than the initial size, new elements are value-initialized. + void resize(size_type n); + + // Overload of `InlinedVector::resize()` to resize the inlined vector to + // contain `n` elements where, if `n` is larger than `size()`, the new values + // will be copy-constructed from `v`. + void resize(size_type n, const_reference v); + + // `InlinedVector::insert()` + // + // Copies `v` into `position`, returning an `iterator` pointing to the newly + // inserted element. + iterator insert(const_iterator position, const_reference v) { + return emplace(position, v); + } + + // Overload of `InlinedVector::insert()` for moving `v` into `position`, + // returning an iterator pointing to the newly inserted element. + iterator insert(const_iterator position, rvalue_reference v) { + return emplace(position, std::move(v)); + } + + // Overload of `InlinedVector::insert()` for inserting `n` contiguous copies + // of `v` starting at `position`. Returns an `iterator` pointing to the first + // of the newly inserted elements. + iterator insert(const_iterator position, size_type n, const_reference v) { + return InsertWithCount(position, n, v); + } + + // Overload of `InlinedVector::insert()` for copying the contents of the + // `std::initializer_list` into the vector starting at `position`. Returns an + // `iterator` pointing to the first of the newly inserted elements. + iterator insert(const_iterator position, + std::initializer_list init_list) { + return insert(position, init_list.begin(), init_list.end()); + } + + // Overload of `InlinedVector::insert()` for inserting elements constructed + // from the range [`first`, `last`). Returns an `iterator` pointing to the + // first of the newly inserted elements. + // + // NOTE: The `enable_if` is intended to disambiguate the two three-argument + // overloads of `insert()`. + template > + iterator insert(const_iterator position, InputIterator first, + InputIterator last) { + return InsertWithRange(position, first, last, + IteratorCategory()); + } + + // `InlinedVector::emplace()` + // + // Constructs and inserts an object in the inlined vector at the given + // `position`, returning an `iterator` pointing to the newly emplaced element. + template + iterator emplace(const_iterator position, Args&&... args); + + // `InlinedVector::emplace_back()` + // + // Constructs and appends a new element to the end of the inlined vector, + // returning a `reference` to the emplaced element. + template + reference emplace_back(Args&&... args) { + size_type s = size(); + assert(s <= capacity()); + if (ABSL_PREDICT_FALSE(s == capacity())) { + return GrowAndEmplaceBack(std::forward(args)...); + } + assert(s < capacity()); + + pointer space; + if (allocated()) { + tag().set_allocated_size(s + 1); + space = allocated_space(); + } else { + tag().set_inline_size(s + 1); + space = inlined_space(); + } + return Construct(space + s, std::forward(args)...); + } + + // `InlinedVector::push_back()` + // + // Appends a copy of `v` to the end of the inlined vector. + void push_back(const_reference v) { static_cast(emplace_back(v)); } + + // Overload of `InlinedVector::push_back()` for moving `v` into a newly + // appended element. + void push_back(rvalue_reference v) { + static_cast(emplace_back(std::move(v))); + } + + // `InlinedVector::pop_back()` + // + // Destroys the element at the end of the inlined vector and shrinks the size + // by `1` (unless the inlined vector is empty, in which case this is a no-op). + void pop_back() noexcept { + assert(!empty()); + size_type s = size(); + if (allocated()) { + Destroy(allocated_space() + s - 1, allocated_space() + s); + tag().set_allocated_size(s - 1); + } else { + Destroy(inlined_space() + s - 1, inlined_space() + s); + tag().set_inline_size(s - 1); + } + } + + // `InlinedVector::erase()` + // + // Erases the element at `position` of the inlined vector, returning an + // `iterator` pointing to the first element following the erased element. + // + // NOTE: May return the end iterator, which is not dereferencable. + iterator erase(const_iterator position) { + assert(position >= begin()); + assert(position < end()); + + iterator pos = const_cast(position); + std::move(pos + 1, end(), pos); + pop_back(); + return pos; + } + + // Overload of `InlinedVector::erase()` for erasing all elements in the + // range [`from`, `to`) in the inlined vector. Returns an `iterator` pointing + // to the first element following the range erased or the end iterator if `to` + // was the end iterator. + iterator erase(const_iterator from, const_iterator to); + + // `InlinedVector::clear()` + // + // Destroys all elements in the inlined vector, sets the size of `0` and + // deallocates the heap allocation if the inlined vector was allocated. + void clear() noexcept { + size_type s = size(); + if (allocated()) { + Destroy(allocated_space(), allocated_space() + s); + allocation().Dealloc(allocator()); + } else if (s != 0) { // do nothing for empty vectors + Destroy(inlined_space(), inlined_space() + s); + } + tag() = Tag(); + } + + // `InlinedVector::reserve()` + // + // Enlarges the underlying representation of the inlined vector so it can hold + // at least `n` elements. This method does not change `size()` or the actual + // contents of the vector. + // + // NOTE: If `n` does not exceed `capacity()`, `reserve()` will have no + // effects. Otherwise, `reserve()` will reallocate, performing an n-time + // element-wise move of everything contained. + void reserve(size_type n) { + if (n > capacity()) { + // Make room for new elements + EnlargeBy(n - size()); + } + } + + // `InlinedVector::shrink_to_fit()` + // + // Reduces memory usage by freeing unused memory. After this call, calls to + // `capacity()` will be equal to `(std::max)(inlined_capacity(), size())`. + // + // If `size() <= inlined_capacity()` and the elements are currently stored on + // the heap, they will be moved to the inlined storage and the heap memory + // will be deallocated. + // + // If `size() > inlined_capacity()` and `size() < capacity()` the elements + // will be moved to a smaller heap allocation. + void shrink_to_fit() { + const auto s = size(); + if (ABSL_PREDICT_FALSE(!allocated() || s == capacity())) return; + + if (s <= inlined_capacity()) { + // Move the elements to the inlined storage. + // We have to do this using a temporary, because `inlined_storage` and + // `allocation_storage` are in a union field. + auto temp = std::move(*this); + assign(std::make_move_iterator(temp.begin()), + std::make_move_iterator(temp.end())); + return; + } + + // Reallocate storage and move elements. + // We can't simply use the same approach as above, because `assign()` would + // call into `reserve()` internally and reserve larger capacity than we need + Allocation new_allocation(allocator(), s); + UninitializedCopy(std::make_move_iterator(allocated_space()), + std::make_move_iterator(allocated_space() + s), + new_allocation.buffer()); + ResetAllocation(new_allocation, s); + } + + // `InlinedVector::swap()` + // + // Swaps the contents of this inlined vector with the contents of `other`. + void swap(InlinedVector& other); + + template + friend Hash AbslHashValue(Hash hash, const InlinedVector& inlined_vector) { + const_pointer p = inlined_vector.data(); + size_type n = inlined_vector.size(); + return Hash::combine(Hash::combine_contiguous(std::move(hash), p, n), n); + } + + private: + // Holds whether the vector is allocated or not in the lowest bit and the size + // in the high bits: + // `size_ = (size << 1) | is_allocated;` + class Tag { + public: + Tag() : size_(0) {} + size_type size() const { return size_ / 2; } + void add_size(size_type n) { size_ += n * 2; } + void set_inline_size(size_type n) { size_ = n * 2; } + void set_allocated_size(size_type n) { size_ = (n * 2) + 1; } + bool allocated() const { return size_ % 2; } + + private: + size_type size_; + }; + + // Derives from `allocator_type` to use the empty base class optimization. + // If the `allocator_type` is stateless, we can store our instance for free. + class AllocatorAndTag : private allocator_type { + public: + explicit AllocatorAndTag(const allocator_type& a) : allocator_type(a) {} + + Tag& tag() { return tag_; } + const Tag& tag() const { return tag_; } + + allocator_type& allocator() { return *this; } + const allocator_type& allocator() const { return *this; } + + private: + Tag tag_; + }; + + class Allocation { + public: + Allocation(allocator_type& a, size_type capacity) + : capacity_(capacity), buffer_(Create(a, capacity)) {} + + void Dealloc(allocator_type& a) { + std::allocator_traits::deallocate(a, buffer_, capacity_); + } + + size_type capacity() const { return capacity_; } + + const_pointer buffer() const { return buffer_; } + + pointer buffer() { return buffer_; } + + private: + static pointer Create(allocator_type& a, size_type n) { + return std::allocator_traits::allocate(a, n); + } + + size_type capacity_; + pointer buffer_; + }; + + const Tag& tag() const { return allocator_and_tag_.tag(); } + + Tag& tag() { return allocator_and_tag_.tag(); } + + Allocation& allocation() { + return reinterpret_cast(rep_.allocation_storage.allocation); + } + + const Allocation& allocation() const { + return reinterpret_cast( + rep_.allocation_storage.allocation); + } + + void init_allocation(const Allocation& allocation) { + new (&rep_.allocation_storage.allocation) Allocation(allocation); + } + + // TODO(absl-team): investigate whether the reinterpret_cast is appropriate. + pointer inlined_space() { + return reinterpret_cast( + std::addressof(rep_.inlined_storage.inlined[0])); + } + + const_pointer inlined_space() const { + return reinterpret_cast( + std::addressof(rep_.inlined_storage.inlined[0])); + } + + pointer allocated_space() { return allocation().buffer(); } + + const_pointer allocated_space() const { return allocation().buffer(); } + + const allocator_type& allocator() const { + return allocator_and_tag_.allocator(); + } + + allocator_type& allocator() { return allocator_and_tag_.allocator(); } + + bool allocated() const { return tag().allocated(); } + + // Enlarge the underlying representation so we can store `size_ + delta` elems + // in allocated space. The size is not changed, and any newly added memory is + // not initialized. + void EnlargeBy(size_type delta); + + // Shift all elements from `position` to `end()` by `n` places to the right. + // If the vector needs to be enlarged, memory will be allocated. + // Returns `iterator`s pointing to the start of the previously-initialized + // portion and the start of the uninitialized portion of the created gap. + // The number of initialized spots is `pair.second - pair.first`. The number + // of raw spots is `n - (pair.second - pair.first)`. + // + // Updates the size of the InlinedVector internally. + std::pair ShiftRight(const_iterator position, + size_type n); + + void ResetAllocation(Allocation new_allocation, size_type new_size) { + if (allocated()) { + Destroy(allocated_space(), allocated_space() + size()); + assert(begin() == allocated_space()); + allocation().Dealloc(allocator()); + allocation() = new_allocation; + } else { + Destroy(inlined_space(), inlined_space() + size()); + init_allocation(new_allocation); // bug: only init once + } + tag().set_allocated_size(new_size); + } + + template + reference GrowAndEmplaceBack(Args&&... args) { + assert(size() == capacity()); + const size_type s = size(); + + Allocation new_allocation(allocator(), 2 * capacity()); + + reference new_element = + Construct(new_allocation.buffer() + s, std::forward(args)...); + UninitializedCopy(std::make_move_iterator(data()), + std::make_move_iterator(data() + s), + new_allocation.buffer()); + + ResetAllocation(new_allocation, s + 1); + + return new_element; + } + + void InitAssign(size_type n); + + void InitAssign(size_type n, const_reference v); + + template + reference Construct(pointer p, Args&&... args) { + std::allocator_traits::construct( + allocator(), p, std::forward(args)...); + return *p; + } + + template + void UninitializedCopy(Iterator src, Iterator src_last, pointer dst) { + for (; src != src_last; ++dst, ++src) Construct(dst, *src); + } + + template + void UninitializedFill(pointer dst, pointer dst_last, const Args&... args) { + for (; dst != dst_last; ++dst) Construct(dst, args...); + } + + // Destroy [`from`, `to`) in place. + void Destroy(pointer from, pointer to); + + template + void AppendRange(Iterator first, Iterator last, std::input_iterator_tag) { + std::copy(first, last, std::back_inserter(*this)); + } + + template + void AppendRange(Iterator first, Iterator last, std::forward_iterator_tag); + + template + void AppendRange(Iterator first, Iterator last) { + AppendRange(first, last, IteratorCategory()); + } + + template + void AssignRange(Iterator first, Iterator last, std::input_iterator_tag); + + template + void AssignRange(Iterator first, Iterator last, std::forward_iterator_tag); + + template + void AssignRange(Iterator first, Iterator last) { + AssignRange(first, last, IteratorCategory()); + } + + iterator InsertWithCount(const_iterator position, size_type n, + const_reference v); + + template + iterator InsertWithRange(const_iterator position, InputIterator first, + InputIterator last, std::input_iterator_tag); + + template + iterator InsertWithRange(const_iterator position, ForwardIterator first, + ForwardIterator last, std::forward_iterator_tag); + + // Stores either the inlined or allocated representation + union Rep { + using ValueTypeBuffer = + absl::aligned_storage_t; + using AllocationBuffer = + absl::aligned_storage_t; + + // Structs wrap the buffers to perform indirection that solves a bizarre + // compilation error on Visual Studio (all known versions). + struct InlinedRep { + // `N` used in place of `inlined_capacity()` due to b/119696660 + ValueTypeBuffer inlined[N]; + }; + struct AllocatedRep { + AllocationBuffer allocation; + }; + + InlinedRep inlined_storage; + AllocatedRep allocation_storage; + }; + + AllocatorAndTag allocator_and_tag_; + Rep rep_; +}; + +// ----------------------------------------------------------------------------- +// InlinedVector Non-Member Functions +// ----------------------------------------------------------------------------- + +// `swap()` +// +// Swaps the contents of two inlined vectors. This convenience function +// simply calls `InlinedVector::swap()`. +template +void swap(InlinedVector& a, + InlinedVector& b) noexcept(noexcept(a.swap(b))) { + a.swap(b); +} + +// `operator==()` +// +// Tests the equivalency of the contents of two inlined vectors. +template +bool operator==(const InlinedVector& a, + const InlinedVector& b) { + return absl::equal(a.begin(), a.end(), b.begin(), b.end()); +} + +// `operator!=()` +// +// Tests the inequality of the contents of two inlined vectors. +template +bool operator!=(const InlinedVector& a, + const InlinedVector& b) { + return !(a == b); +} + +// `operator<()` +// +// Tests whether the contents of one inlined vector are less than the contents +// of another through a lexicographical comparison operation. +template +bool operator<(const InlinedVector& a, + const InlinedVector& b) { + return std::lexicographical_compare(a.begin(), a.end(), b.begin(), b.end()); +} + +// `operator>()` +// +// Tests whether the contents of one inlined vector are greater than the +// contents of another through a lexicographical comparison operation. +template +bool operator>(const InlinedVector& a, + const InlinedVector& b) { + return b < a; +} + +// `operator<=()` +// +// Tests whether the contents of one inlined vector are less than or equal to +// the contents of another through a lexicographical comparison operation. +template +bool operator<=(const InlinedVector& a, + const InlinedVector& b) { + return !(b < a); +} + +// `operator>=()` +// +// Tests whether the contents of one inlined vector are greater than or equal to +// the contents of another through a lexicographical comparison operation. +template +bool operator>=(const InlinedVector& a, + const InlinedVector& b) { + return !(a < b); +} + +// ----------------------------------------------------------------------------- +// Implementation of InlinedVector +// +// Do not depend on any below implementation details! +// ----------------------------------------------------------------------------- + +template +InlinedVector::InlinedVector(const InlinedVector& other) + : allocator_and_tag_(other.allocator()) { + reserve(other.size()); + if (allocated()) { + UninitializedCopy(other.begin(), other.end(), allocated_space()); + tag().set_allocated_size(other.size()); + } else { + UninitializedCopy(other.begin(), other.end(), inlined_space()); + tag().set_inline_size(other.size()); + } +} + +template +InlinedVector::InlinedVector(const InlinedVector& other, + const allocator_type& alloc) + : allocator_and_tag_(alloc) { + reserve(other.size()); + if (allocated()) { + UninitializedCopy(other.begin(), other.end(), allocated_space()); + tag().set_allocated_size(other.size()); + } else { + UninitializedCopy(other.begin(), other.end(), inlined_space()); + tag().set_inline_size(other.size()); + } +} + +template +InlinedVector::InlinedVector(InlinedVector&& other) noexcept( + absl::allocator_is_nothrow::value || + std::is_nothrow_move_constructible::value) + : allocator_and_tag_(other.allocator_and_tag_) { + if (other.allocated()) { + // We can just steal the underlying buffer from the source. + // That leaves the source empty, so we clear its size. + init_allocation(other.allocation()); + other.tag() = Tag(); + } else { + UninitializedCopy( + std::make_move_iterator(other.inlined_space()), + std::make_move_iterator(other.inlined_space() + other.size()), + inlined_space()); + } +} + +template +InlinedVector::InlinedVector(InlinedVector&& other, + const allocator_type& alloc) noexcept( // + absl::allocator_is_nothrow::value) + : allocator_and_tag_(alloc) { + if (other.allocated()) { + if (alloc == other.allocator()) { + // We can just steal the allocation from the source. + tag() = other.tag(); + init_allocation(other.allocation()); + other.tag() = Tag(); + } else { + // We need to use our own allocator + reserve(other.size()); + UninitializedCopy(std::make_move_iterator(other.begin()), + std::make_move_iterator(other.end()), + allocated_space()); + tag().set_allocated_size(other.size()); + } + } else { + UninitializedCopy( + std::make_move_iterator(other.inlined_space()), + std::make_move_iterator(other.inlined_space() + other.size()), + inlined_space()); + tag().set_inline_size(other.size()); + } +} + +template +void InlinedVector::InitAssign(size_type n, const_reference v) { + if (n > inlined_capacity()) { + Allocation new_allocation(allocator(), n); + init_allocation(new_allocation); + UninitializedFill(allocated_space(), allocated_space() + n, v); + tag().set_allocated_size(n); + } else { + UninitializedFill(inlined_space(), inlined_space() + n, v); + tag().set_inline_size(n); + } +} + +template +void InlinedVector::InitAssign(size_type n) { + if (n > inlined_capacity()) { + Allocation new_allocation(allocator(), n); + init_allocation(new_allocation); + UninitializedFill(allocated_space(), allocated_space() + n); + tag().set_allocated_size(n); + } else { + UninitializedFill(inlined_space(), inlined_space() + n); + tag().set_inline_size(n); + } +} + +template +void InlinedVector::resize(size_type n) { + size_type s = size(); + if (n < s) { + erase(begin() + n, end()); + return; + } + reserve(n); + assert(capacity() >= n); + + // Fill new space with elements constructed in-place. + if (allocated()) { + UninitializedFill(allocated_space() + s, allocated_space() + n); + tag().set_allocated_size(n); + } else { + UninitializedFill(inlined_space() + s, inlined_space() + n); + tag().set_inline_size(n); + } +} + +template +void InlinedVector::resize(size_type n, const_reference v) { + size_type s = size(); + if (n < s) { + erase(begin() + n, end()); + return; + } + reserve(n); + assert(capacity() >= n); + + // Fill new space with copies of 'v'. + if (allocated()) { + UninitializedFill(allocated_space() + s, allocated_space() + n, v); + tag().set_allocated_size(n); + } else { + UninitializedFill(inlined_space() + s, inlined_space() + n, v); + tag().set_inline_size(n); + } +} + +template +template +auto InlinedVector::emplace(const_iterator position, Args&&... args) + -> iterator { + assert(position >= begin()); + assert(position <= end()); + if (ABSL_PREDICT_FALSE(position == end())) { + emplace_back(std::forward(args)...); + return end() - 1; + } + + T new_t = T(std::forward(args)...); + + auto range = ShiftRight(position, 1); + if (range.first == range.second) { + // constructing into uninitialized memory + Construct(range.first, std::move(new_t)); + } else { + // assigning into moved-from object + *range.first = T(std::move(new_t)); + } + + return range.first; +} + +template +auto InlinedVector::erase(const_iterator from, const_iterator to) + -> iterator { + assert(begin() <= from); + assert(from <= to); + assert(to <= end()); + + iterator range_start = const_cast(from); + iterator range_end = const_cast(to); + + size_type s = size(); + ptrdiff_t erase_gap = std::distance(range_start, range_end); + if (erase_gap > 0) { + pointer space; + if (allocated()) { + space = allocated_space(); + tag().set_allocated_size(s - erase_gap); + } else { + space = inlined_space(); + tag().set_inline_size(s - erase_gap); + } + std::move(range_end, space + s, range_start); + Destroy(space + s - erase_gap, space + s); + } + return range_start; +} + +template +void InlinedVector::swap(InlinedVector& other) { + using std::swap; // Augment ADL with `std::swap`. + if (ABSL_PREDICT_FALSE(this == &other)) return; + + if (allocated() && other.allocated()) { + // Both out of line, so just swap the tag, allocation, and allocator. + swap(tag(), other.tag()); + swap(allocation(), other.allocation()); + swap(allocator(), other.allocator()); + return; + } + if (!allocated() && !other.allocated()) { + // Both inlined: swap up to smaller size, then move remaining elements. + InlinedVector* a = this; + InlinedVector* b = &other; + if (size() < other.size()) { + swap(a, b); + } + + const size_type a_size = a->size(); + const size_type b_size = b->size(); + assert(a_size >= b_size); + // `a` is larger. Swap the elements up to the smaller array size. + std::swap_ranges(a->inlined_space(), a->inlined_space() + b_size, + b->inlined_space()); + + // Move the remaining elements: + // [`b_size`, `a_size`) from `a` -> [`b_size`, `a_size`) from `b` + b->UninitializedCopy(a->inlined_space() + b_size, + a->inlined_space() + a_size, + b->inlined_space() + b_size); + a->Destroy(a->inlined_space() + b_size, a->inlined_space() + a_size); + + swap(a->tag(), b->tag()); + swap(a->allocator(), b->allocator()); + assert(b->size() == a_size); + assert(a->size() == b_size); + return; + } + + // One is out of line, one is inline. + // We first move the elements from the inlined vector into the + // inlined space in the other vector. We then put the other vector's + // pointer/capacity into the originally inlined vector and swap + // the tags. + InlinedVector* a = this; + InlinedVector* b = &other; + if (a->allocated()) { + swap(a, b); + } + assert(!a->allocated()); + assert(b->allocated()); + const size_type a_size = a->size(); + const size_type b_size = b->size(); + // In an optimized build, `b_size` would be unused. + static_cast(b_size); + + // Made Local copies of `size()`, don't need `tag()` accurate anymore + swap(a->tag(), b->tag()); + + // Copy `b_allocation` out before `b`'s union gets clobbered by `inline_space` + Allocation b_allocation = b->allocation(); + + b->UninitializedCopy(a->inlined_space(), a->inlined_space() + a_size, + b->inlined_space()); + a->Destroy(a->inlined_space(), a->inlined_space() + a_size); + + a->allocation() = b_allocation; + + if (a->allocator() != b->allocator()) { + swap(a->allocator(), b->allocator()); + } + + assert(b->size() == a_size); + assert(a->size() == b_size); +} + +template +void InlinedVector::EnlargeBy(size_type delta) { + const size_type s = size(); + assert(s <= capacity()); + + size_type target = std::max(inlined_capacity(), s + delta); + + // Compute new capacity by repeatedly doubling current capacity + // TODO(user): Check and avoid overflow? + size_type new_capacity = capacity(); + while (new_capacity < target) { + new_capacity <<= 1; + } + + Allocation new_allocation(allocator(), new_capacity); + + UninitializedCopy(std::make_move_iterator(data()), + std::make_move_iterator(data() + s), + new_allocation.buffer()); + + ResetAllocation(new_allocation, s); +} + +template +auto InlinedVector::ShiftRight(const_iterator position, size_type n) + -> std::pair { + iterator start_used = const_cast(position); + iterator start_raw = const_cast(position); + size_type s = size(); + size_type required_size = s + n; + + if (required_size > capacity()) { + // Compute new capacity by repeatedly doubling current capacity + size_type new_capacity = capacity(); + while (new_capacity < required_size) { + new_capacity <<= 1; + } + // Move everyone into the new allocation, leaving a gap of `n` for the + // requested shift. + Allocation new_allocation(allocator(), new_capacity); + size_type index = position - begin(); + UninitializedCopy(std::make_move_iterator(data()), + std::make_move_iterator(data() + index), + new_allocation.buffer()); + UninitializedCopy(std::make_move_iterator(data() + index), + std::make_move_iterator(data() + s), + new_allocation.buffer() + index + n); + ResetAllocation(new_allocation, s); + + // New allocation means our iterator is invalid, so we'll recalculate. + // Since the entire gap is in new space, there's no used space to reuse. + start_raw = begin() + index; + start_used = start_raw; + } else { + // If we had enough space, it's a two-part move. Elements going into + // previously-unoccupied space need an `UninitializedCopy()`. Elements + // going into a previously-occupied space are just a `std::move()`. + iterator pos = const_cast(position); + iterator raw_space = end(); + size_type slots_in_used_space = raw_space - pos; + size_type new_elements_in_used_space = std::min(n, slots_in_used_space); + size_type new_elements_in_raw_space = n - new_elements_in_used_space; + size_type old_elements_in_used_space = + slots_in_used_space - new_elements_in_used_space; + + UninitializedCopy(std::make_move_iterator(pos + old_elements_in_used_space), + std::make_move_iterator(raw_space), + raw_space + new_elements_in_raw_space); + std::move_backward(pos, pos + old_elements_in_used_space, raw_space); + + // If the gap is entirely in raw space, the used space starts where the raw + // space starts, leaving no elements in used space. If the gap is entirely + // in used space, the raw space starts at the end of the gap, leaving all + // elements accounted for within the used space. + start_used = pos; + start_raw = pos + new_elements_in_used_space; + } + tag().add_size(n); + return std::make_pair(start_used, start_raw); +} + +template +void InlinedVector::Destroy(pointer from, pointer to) { + for (pointer cur = from; cur != to; ++cur) { + std::allocator_traits::destroy(allocator(), cur); + } +#ifndef NDEBUG + // Overwrite unused memory with `0xab` so we can catch uninitialized usage. + // Cast to `void*` to tell the compiler that we don't care that we might be + // scribbling on a vtable pointer. + if (from != to) { + auto len = sizeof(value_type) * std::distance(from, to); + std::memset(reinterpret_cast(from), 0xab, len); + } +#endif +} + +template +template +void InlinedVector::AppendRange(Iterator first, Iterator last, + std::forward_iterator_tag) { + auto length = std::distance(first, last); + reserve(size() + length); + if (allocated()) { + UninitializedCopy(first, last, allocated_space() + size()); + tag().set_allocated_size(size() + length); + } else { + UninitializedCopy(first, last, inlined_space() + size()); + tag().set_inline_size(size() + length); + } +} + +template +template +void InlinedVector::AssignRange(Iterator first, Iterator last, + std::input_iterator_tag) { + // Optimized to avoid reallocation. + // Prefer reassignment to copy construction for elements. + iterator out = begin(); + for (; first != last && out != end(); ++first, ++out) { + *out = *first; + } + erase(out, end()); + std::copy(first, last, std::back_inserter(*this)); +} + +template +template +void InlinedVector::AssignRange(Iterator first, Iterator last, + std::forward_iterator_tag) { + auto length = std::distance(first, last); + // Prefer reassignment to copy construction for elements. + if (static_cast(length) <= size()) { + erase(std::copy(first, last, begin()), end()); + return; + } + reserve(length); + iterator out = begin(); + for (; out != end(); ++first, ++out) *out = *first; + if (allocated()) { + UninitializedCopy(first, last, out); + tag().set_allocated_size(length); + } else { + UninitializedCopy(first, last, out); + tag().set_inline_size(length); + } +} + +template +auto InlinedVector::InsertWithCount(const_iterator position, + size_type n, const_reference v) + -> iterator { + assert(position >= begin() && position <= end()); + if (ABSL_PREDICT_FALSE(n == 0)) return const_cast(position); + + value_type copy = v; + std::pair it_pair = ShiftRight(position, n); + std::fill(it_pair.first, it_pair.second, copy); + UninitializedFill(it_pair.second, it_pair.first + n, copy); + + return it_pair.first; +} + +template +template +auto InlinedVector::InsertWithRange(const_iterator position, + InputIterator first, + InputIterator last, + std::input_iterator_tag) + -> iterator { + assert(position >= begin() && position <= end()); + size_type index = position - cbegin(); + size_type i = index; + while (first != last) insert(begin() + i++, *first++); + return begin() + index; +} + +template +template +auto InlinedVector::InsertWithRange(const_iterator position, + ForwardIterator first, + ForwardIterator last, + std::forward_iterator_tag) + -> iterator { + assert(position >= begin() && position <= end()); + if (ABSL_PREDICT_FALSE(first == last)) return const_cast(position); + + auto n = std::distance(first, last); + std::pair it_pair = ShiftRight(position, n); + size_type used_spots = it_pair.second - it_pair.first; + ForwardIterator open_spot = std::next(first, used_spots); + std::copy(first, open_spot, it_pair.first); + UninitializedCopy(open_spot, last, it_pair.second); + return it_pair.first; +} + +} // namespace absl + + +#endif // S2_THIRD_PARTY_ABSL_CONTAINER_INLINED_VECTOR_H_ diff --git a/inst/include/s2/third_party/absl/container/internal/compressed_tuple.h b/inst/include/s2/third_party/absl/container/internal/compressed_tuple.h new file mode 100644 index 0000000..b9b1a1d --- /dev/null +++ b/inst/include/s2/third_party/absl/container/internal/compressed_tuple.h @@ -0,0 +1,191 @@ +// Copyright 2018 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Helper class to perform the Empty Base Optimization. +// Ts can contain classes and non-classes, empty or not. For the ones that +// are empty classes, we perform the optimization. If all types in Ts are empty +// classes, then CompressedTuple is itself an empty class. +// +// To access the members, use member get() function. +// +// Eg: +// absl::container_internal::CompressedTuple value(7, t1, t2, +// t3); +// assert(value.get<0>() == 7); +// T1& t1 = value.get<1>(); +// const T2& t2 = value.get<2>(); +// ... +// +// http://en.cppreference.com/w/cpp/language/ebo + +#ifndef S2_THIRD_PARTY_ABSL_CONTAINER_INTERNAL_COMPRESSED_TUPLE_H_ +#define S2_THIRD_PARTY_ABSL_CONTAINER_INTERNAL_COMPRESSED_TUPLE_H_ + +#include +#include +#include + +#include "s2/third_party/absl/utility/utility.h" + +#ifdef _MSC_VER +// We need to mark these classes with this declspec to ensure that +// CompressedTuple happens. +#define ABSL_INTERNAL_COMPRESSED_TUPLE_DECLSPEC __declspec(empty_bases) +#else // _MSC_VER +#define ABSL_INTERNAL_COMPRESSED_TUPLE_DECLSPEC +#endif // _MSC_VER + +namespace absl { +namespace container_internal { + +template +class CompressedTuple; + +namespace internal_compressed_tuple { + +template +struct Elem; +template +struct Elem, I> + : std::tuple_element> {}; +template +using ElemT = typename Elem::type; + +// Use the __is_final intrinsic if available. Where it's not available, classes +// declared with the 'final' specifier cannot be used as CompressedTuple +// elements. +// TODO(user): Replace this with std::is_final in C++14. +template +constexpr bool IsFinal() { +#if defined(__clang__) || defined(__GNUC__) + return __is_final(T); +#else + return false; +#endif +} + +template +constexpr bool ShouldUseBase() { + return std::is_class::value && std::is_empty::value && !IsFinal(); +} + +// The storage class provides two specializations: +// - For empty classes, it stores T as a base class. +// - For everything else, it stores T as a member. +template >()> +struct Storage { + using T = ElemT; + T value; + constexpr Storage() = default; + explicit constexpr Storage(T&& v) : value(absl::forward(v)) {} + constexpr const T& get() const& { return value; } + T& get() & { return value; } + constexpr const T&& get() const&& { return absl::move(*this).value; } + T&& get() && { return std::move(*this).value; } +}; + +template +struct ABSL_INTERNAL_COMPRESSED_TUPLE_DECLSPEC Storage + : ElemT { + using T = internal_compressed_tuple::ElemT; + constexpr Storage() = default; + explicit constexpr Storage(T&& v) : T(absl::forward(v)) {} + constexpr const T& get() const& { return *this; } + T& get() & { return *this; } + constexpr const T&& get() const&& { return absl::move(*this); } + T&& get() && { return std::move(*this); } +}; + +template +struct ABSL_INTERNAL_COMPRESSED_TUPLE_DECLSPEC CompressedTupleImpl; + +template +struct ABSL_INTERNAL_COMPRESSED_TUPLE_DECLSPEC + CompressedTupleImpl, absl::index_sequence> + // We use the dummy identity function through std::integral_constant to + // convince MSVC of accepting and expanding I in that context. Without it + // you would get: + // error C3548: 'I': parameter pack cannot be used in this context + : Storage, + std::integral_constant::value>... { + constexpr CompressedTupleImpl() = default; + explicit constexpr CompressedTupleImpl(Ts&&... args) + : Storage, I>(absl::forward(args))... {} +}; + +} // namespace internal_compressed_tuple + +// Helper class to perform the Empty Base Class Optimization. +// Ts can contain classes and non-classes, empty or not. For the ones that +// are empty classes, we perform the CompressedTuple. If all types in Ts are +// empty classes, then CompressedTuple is itself an empty class. +// +// To access the members, use member .get() function. +// +// Eg: +// absl::container_internal::CompressedTuple value(7, t1, t2, +// t3); +// assert(value.get<0>() == 7); +// T1& t1 = value.get<1>(); +// const T2& t2 = value.get<2>(); +// ... +// +// http://en.cppreference.com/w/cpp/language/ebo +template +class ABSL_INTERNAL_COMPRESSED_TUPLE_DECLSPEC CompressedTuple + : private internal_compressed_tuple::CompressedTupleImpl< + CompressedTuple, absl::index_sequence_for> { + private: + template + using ElemT = internal_compressed_tuple::ElemT; + + public: + constexpr CompressedTuple() = default; + explicit constexpr CompressedTuple(Ts... base) + : CompressedTuple::CompressedTupleImpl(absl::forward(base)...) {} + + template + ElemT& get() & { + return internal_compressed_tuple::Storage::get(); + } + + template + constexpr const ElemT& get() const& { + return internal_compressed_tuple::Storage::get(); + } + + template + ElemT&& get() && { + return std::move(*this) + .internal_compressed_tuple::template Storage::get(); + } + + template + constexpr const ElemT&& get() const&& { + return absl::move(*this) + .internal_compressed_tuple::template Storage::get(); + } +}; + +// Explicit specialization for a zero-element tuple +// (needed to avoid ambiguous overloads for the default constructor). +template <> +class ABSL_INTERNAL_COMPRESSED_TUPLE_DECLSPEC CompressedTuple<> {}; + +} // namespace container_internal +} // namespace absl + +#undef ABSL_INTERNAL_COMPRESSED_TUPLE_DECLSPEC + +#endif // S2_THIRD_PARTY_ABSL_CONTAINER_INTERNAL_COMPRESSED_TUPLE_H_ diff --git a/inst/include/s2/third_party/absl/container/internal/container_memory.h b/inst/include/s2/third_party/absl/container/internal/container_memory.h new file mode 100644 index 0000000..ab533fd --- /dev/null +++ b/inst/include/s2/third_party/absl/container/internal/container_memory.h @@ -0,0 +1,424 @@ +// Copyright 2018 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef S2_THIRD_PARTY_ABSL_CONTAINER_INTERNAL_CONTAINER_MEMORY_H_ +#define S2_THIRD_PARTY_ABSL_CONTAINER_INTERNAL_CONTAINER_MEMORY_H_ + +#ifdef ADDRESS_SANITIZER +#include +#endif + +#ifdef MEMORY_SANITIZER +#include +#endif + +#include +#include +#include +#include +#include +#include + +#include "s2/third_party/absl/memory/memory.h" +#include "s2/third_party/absl/utility/utility.h" + +namespace absl { +namespace container_internal { + +// Allocates at least n bytes aligned to the specified alignment. +// Alignment must be a power of 2. It must be positive. +// +// Note that many allocators don't honor alignment requirements above certain +// threshold (usually either alignof(std::max_align_t) or alignof(void*)). +// Allocate() doesn't apply alignment corrections. If the underlying allocator +// returns insufficiently alignment pointer, that's what you are going to get. +template +void* Allocate(Alloc* alloc, size_t n) { + static_assert(Alignment > 0, ""); + assert(n && "n must be positive"); + struct alignas(Alignment) M {}; + using A = typename absl::allocator_traits::template rebind_alloc; + using AT = typename absl::allocator_traits::template rebind_traits; + A mem_alloc(*alloc); + void* p = AT::allocate(mem_alloc, (n + sizeof(M) - 1) / sizeof(M)); + assert(reinterpret_cast(p) % Alignment == 0 && + "allocator does not respect alignment"); + return p; +} + +// The pointer must have been previously obtained by calling +// Allocate(alloc, n). +template +void Deallocate(Alloc* alloc, void* p, size_t n) { + static_assert(Alignment > 0, ""); + assert(n && "n must be positive"); + struct alignas(Alignment) M {}; + using A = typename absl::allocator_traits::template rebind_alloc; + using AT = typename absl::allocator_traits::template rebind_traits; + A mem_alloc(*alloc); + AT::deallocate(mem_alloc, static_cast(p), + (n + sizeof(M) - 1) / sizeof(M)); +} + +namespace memory_internal { + +// Constructs T into uninitialized storage pointed by `ptr` using the args +// specified in the tuple. +template +void ConstructFromTupleImpl(Alloc* alloc, T* ptr, Tuple&& t, + absl::index_sequence) { + absl::allocator_traits::construct( + *alloc, ptr, std::get(std::forward(t))...); +} + +template +struct WithConstructedImplF { + template + decltype(std::declval()(std::declval())) operator()( + Args&&... args) const { + return std::forward(f)(T(std::forward(args)...)); + } + F&& f; +}; + +template +decltype(std::declval()(std::declval())) WithConstructedImpl( + Tuple&& t, absl::index_sequence, F&& f) { + return WithConstructedImplF{std::forward(f)}( + std::get(std::forward(t))...); +} + +template +auto TupleRefImpl(T&& t, absl::index_sequence) + -> decltype(std::forward_as_tuple(std::get(std::forward(t))...)) { + return std::forward_as_tuple(std::get(std::forward(t))...); +} + +// Returns a tuple of references to the elements of the input tuple. T must be a +// tuple. +template +auto TupleRef(T&& t) -> decltype( + TupleRefImpl(std::forward(t), + absl::make_index_sequence< + std::tuple_size::type>::value>())) { + return TupleRefImpl( + std::forward(t), + absl::make_index_sequence< + std::tuple_size::type>::value>()); +} + +template +decltype(std::declval()(std::declval(), std::piecewise_construct, + std::declval>(), std::declval())) +DecomposePairImpl(F&& f, std::pair, V> p) { + const auto& key = std::get<0>(p.first); + return std::forward(f)(key, std::piecewise_construct, std::move(p.first), + std::move(p.second)); +} + +} // namespace memory_internal + +// Constructs T into uninitialized storage pointed by `ptr` using the args +// specified in the tuple. +template +void ConstructFromTuple(Alloc* alloc, T* ptr, Tuple&& t) { + memory_internal::ConstructFromTupleImpl( + alloc, ptr, std::forward(t), + absl::make_index_sequence< + std::tuple_size::type>::value>()); +} + +// Constructs T using the args specified in the tuple and calls F with the +// constructed value. +template +decltype(std::declval()(std::declval())) WithConstructed( + Tuple&& t, F&& f) { + return memory_internal::WithConstructedImpl( + std::forward(t), + absl::make_index_sequence< + std::tuple_size::type>::value>(), + std::forward(f)); +} + +// Given arguments of an std::pair's consructor, PairArgs() returns a pair of +// tuples with references to the passed arguments. The tuples contain +// constructor arguments for the first and the second elements of the pair. +// +// The following two snippets are equivalent. +// +// 1. std::pair p(args...); +// +// 2. auto a = PairArgs(args...); +// std::pair p(std::piecewise_construct, +// std::move(p.first), std::move(p.second)); +inline std::pair, std::tuple<>> PairArgs() { return {}; } +template +std::pair, std::tuple> PairArgs(F&& f, S&& s) { + return {std::piecewise_construct, std::forward_as_tuple(std::forward(f)), + std::forward_as_tuple(std::forward(s))}; +} +template +std::pair, std::tuple> PairArgs( + const std::pair& p) { + return PairArgs(p.first, p.second); +} +template +std::pair, std::tuple> PairArgs(std::pair&& p) { + return PairArgs(std::forward(p.first), std::forward(p.second)); +} +template +auto PairArgs(std::piecewise_construct_t, F&& f, S&& s) + -> decltype(std::make_pair(memory_internal::TupleRef(std::forward(f)), + memory_internal::TupleRef(std::forward(s)))) { + return std::make_pair(memory_internal::TupleRef(std::forward(f)), + memory_internal::TupleRef(std::forward(s))); +} + +// A helper function for implementing apply() in map policies. +template +auto DecomposePair(F&& f, Args&&... args) + -> decltype(memory_internal::DecomposePairImpl( + std::forward(f), PairArgs(std::forward(args)...))) { + return memory_internal::DecomposePairImpl( + std::forward(f), PairArgs(std::forward(args)...)); +} + +// A helper function for implementing apply() in set policies. +template +decltype(std::declval()(std::declval(), std::declval())) +DecomposeValue(F&& f, Arg&& arg) { + const auto& key = arg; + return std::forward(f)(key, std::forward(arg)); +} + +// Helper functions for asan and msan. +inline void SanitizerPoisonMemoryRegion(const void* m, size_t s) { +#ifdef ADDRESS_SANITIZER + ASAN_POISON_MEMORY_REGION(m, s); +#endif +#ifdef MEMORY_SANITIZER + __msan_poison(m, s); +#endif + (void)m; + (void)s; +} + +inline void SanitizerUnpoisonMemoryRegion(const void* m, size_t s) { +#ifdef ADDRESS_SANITIZER + ASAN_UNPOISON_MEMORY_REGION(m, s); +#endif +#ifdef MEMORY_SANITIZER + __msan_unpoison(m, s); +#endif + (void)m; + (void)s; +} + +template +inline void SanitizerPoisonObject(const T* object) { + SanitizerPoisonMemoryRegion(object, sizeof(T)); +} + +template +inline void SanitizerUnpoisonObject(const T* object) { + SanitizerUnpoisonMemoryRegion(object, sizeof(T)); +} + +namespace memory_internal { + +// If Pair is a standard-layout type, OffsetOf::kFirst and +// OffsetOf::kSecond are equivalent to offsetof(Pair, first) and +// offsetof(Pair, second) respectively. Otherwise they are -1. +// +// The purpose of OffsetOf is to avoid calling offsetof() on non-standard-layout +// type, which is non-portable. +template +struct OffsetOf { + static constexpr size_t kFirst = -1; + static constexpr size_t kSecond = -1; +}; + +template +struct OffsetOf::type> { + static constexpr size_t kFirst = offsetof(Pair, first); + static constexpr size_t kSecond = offsetof(Pair, second); +}; + +template +struct IsLayoutCompatible { + private: + struct Pair { + K first; + V second; + }; + + // Is P layout-compatible with Pair? + template + static constexpr bool LayoutCompatible() { + return std::is_standard_layout

() && sizeof(P) == sizeof(Pair) && + alignof(P) == alignof(Pair) && + memory_internal::OffsetOf

::kFirst == + memory_internal::OffsetOf::kFirst && + memory_internal::OffsetOf

::kSecond == + memory_internal::OffsetOf::kSecond; + } + + public: + // Whether pair and pair are layout-compatible. If they are, + // then it is safe to store them in a union and read from either. + static constexpr bool value = std::is_standard_layout() && + std::is_standard_layout() && + memory_internal::OffsetOf::kFirst == 0 && + LayoutCompatible>() && + LayoutCompatible>(); +}; + +} // namespace memory_internal + +// The internal storage type for key-value containers like flat_hash_map. +// +// It is convenient for the value_type of a flat_hash_map to be +// pair; the "const K" prevents accidental modification of the key +// when dealing with the reference returned from find() and similar methods. +// However, this creates other problems; we want to be able to emplace(K, V) +// efficiently with move operations, and similarly be able to move a +// pair in insert(). +// +// The solution is this union, which aliases the const and non-const versions +// of the pair. This also allows flat_hash_map to work, even though +// that has the same efficiency issues with move in emplace() and insert() - +// but people do it anyway. +// +// If kMutableKeys is false, only the value member can be accessed. +// +// If kMutableKeys is true, key can be accessed through all slots while value +// and mutable_value must be accessed only via INITIALIZED slots. Slots are +// created and destroyed via mutable_value so that the key can be moved later. +// +// Accessing one of the union fields while the other is active is safe as +// long as they are layout-compatible, which is guaranteed by the definition of +// kMutableKeys. For C++11, the relevant section of the standard is +// https://timsong-cpp.github.io/cppwp/n3337/class.mem#19 (9.2.19) +template +union slot_type { + private: + static void emplace(slot_type* slot) { + // The construction of union doesn't do anything at runtime but it allows us + // to access its members without violating aliasing rules. + new (slot) slot_type; + } + // If pair and pair are layout-compatible, we can accept one + // or the other via slot_type. We are also free to access the key via + // slot_type::key in this case. + using kMutableKeys = + std::integral_constant::value>; + + public: + slot_type() {} + ~slot_type() = delete; + using value_type = std::pair; + using mutable_value_type = std::pair; + + value_type value; + mutable_value_type mutable_value; + K key; + + template + static void construct(Allocator* alloc, slot_type* slot, Args&&... args) { + emplace(slot); + if (kMutableKeys::value) { + absl::allocator_traits::construct(*alloc, &slot->mutable_value, + std::forward(args)...); + } else { + absl::allocator_traits::construct(*alloc, &slot->value, + std::forward(args)...); + } + } + + // Construct this slot by moving from another slot. + template + static void construct(Allocator* alloc, slot_type* slot, slot_type* other) { + emplace(slot); + if (kMutableKeys::value) { + absl::allocator_traits::construct( + *alloc, &slot->mutable_value, std::move(other->mutable_value)); + } else { + absl::allocator_traits::construct(*alloc, &slot->value, + std::move(other->value)); + } + } + + template + static void destroy(Allocator* alloc, slot_type* slot) { + if (kMutableKeys::value) { + absl::allocator_traits::destroy(*alloc, &slot->mutable_value); + } else { + absl::allocator_traits::destroy(*alloc, &slot->value); + } + } + + template + static void transfer(Allocator* alloc, slot_type* new_slot, + slot_type* old_slot) { + emplace(new_slot); + if (kMutableKeys::value) { + absl::allocator_traits::construct( + *alloc, &new_slot->mutable_value, std::move(old_slot->mutable_value)); + } else { + absl::allocator_traits::construct(*alloc, &new_slot->value, + std::move(old_slot->value)); + } + destroy(alloc, old_slot); + } + + template + static void swap(Allocator* alloc, slot_type* a, slot_type* b) { + if (kMutableKeys::value) { + using std::swap; + swap(a->mutable_value, b->mutable_value); + } else { + value_type tmp = std::move(a->value); + absl::allocator_traits::destroy(*alloc, &a->value); + absl::allocator_traits::construct(*alloc, &a->value, + std::move(b->value)); + absl::allocator_traits::destroy(*alloc, &b->value); + absl::allocator_traits::construct(*alloc, &b->value, + std::move(tmp)); + } + } + + template + static void move(Allocator* alloc, slot_type* src, slot_type* dest) { + if (kMutableKeys::value) { + dest->mutable_value = std::move(src->mutable_value); + } else { + absl::allocator_traits::destroy(*alloc, &dest->value); + absl::allocator_traits::construct(*alloc, &dest->value, + std::move(src->value)); + } + } + + template + static void move(Allocator* alloc, slot_type* first, slot_type* last, + slot_type* result) { + for (slot_type *src = first, *dest = result; src != last; ++src, ++dest) + move(alloc, src, dest); + } +}; + +} // namespace container_internal +} // namespace absl + +#endif // S2_THIRD_PARTY_ABSL_CONTAINER_INTERNAL_CONTAINER_MEMORY_H_ diff --git a/inst/include/s2/third_party/absl/container/internal/layout.h b/inst/include/s2/third_party/absl/container/internal/layout.h new file mode 100644 index 0000000..52d091c --- /dev/null +++ b/inst/include/s2/third_party/absl/container/internal/layout.h @@ -0,0 +1,739 @@ +// Copyright 2018 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// MOTIVATION AND TUTORIAL +// +// If you want to put in a single heap allocation N doubles followed by M ints, +// it's easy if N and M are known at compile time. +// +// struct S { +// double a[N]; +// int b[M]; +// }; +// +// S* p = new S; +// +// But what if N and M are known only in run time? Class template Layout to the +// rescue! It's a portable generalization of the technique known as struct hack. +// +// // This object will tell us everything we need to know about the memory +// // layout of double[N] followed by int[M]. It's structurally identical to +// // size_t[2] that stores N and M. It's very cheap to create. +// const Layout layout(N, M); +// +// // Allocate enough memory for both arrays. `AllocSize()` tells us how much +// // memory is needed. We are free to use any allocation function we want as +// // long as it returns aligned memory. +// std::unique_ptr p(new unsigned char[layout.AllocSize()]); +// +// // Obtain the pointer to the array of doubles. +// // Equivalent to `reinterpret_cast(p.get())`. +// // +// // We could have written layout.Pointer<0>(p) instead. If all the types are +// // unique you can use either form, but if some types are repeated you must +// // use the index form. +// double* a = layout.Pointer(p.get()); +// +// // Obtain the pointer to the array of ints. +// // Equivalent to `reinterpret_cast(p.get() + N * 8)`. +// int* b = layout.Pointer(p); +// +// If we are unable to specify sizes of all fields, we can pass as many sizes as +// we can to `Partial()`. In return, it'll allow us to access the fields whose +// locations and sizes can be computed from the provided information. +// `Partial()` comes in handy when the array sizes are embedded into the +// allocation. +// +// // size_t[1] containing N, size_t[1] containing M, double[N], int[M]. +// using L = Layout; +// +// unsigned char* Allocate(size_t n, size_t m) { +// const L layout(1, 1, n, m); +// unsigned char* p = new unsigned char[layout.AllocSize()]; +// *layout.Pointer<0>(p) = n; +// *layout.Pointer<1>(p) = m; +// return p; +// } +// +// void Use(unsigned char* p) { +// // First, extract N and M. +// // Specify that the first array has only one element. Using `prefix` we +// // can access the first two arrays but not more. +// constexpr auto prefix = L::Partial(1); +// size_t n = *prefix.Pointer<0>(p); +// size_t m = *prefix.Pointer<1>(p); +// +// // Now we can get pointers to the payload. +// const L layout(1, 1, n, m); +// double* a = layout.Pointer(p); +// int* b = layout.Pointer(p); +// } +// +// The layout we used above combines fixed-size with dynamically-sized fields. +// This is quite common. Layout is optimized for this use case and generates +// optimal code. All computations that can be performed at compile time are +// indeed performed at compile time. +// +// Efficiency tip: The order of fields matters. In `Layout` try to +// ensure that `alignof(T1) >= ... >= alignof(TN)`. This way you'll have no +// padding in between arrays. +// +// You can manually override the alignment of an array by wrapping the type in +// `Aligned`. `Layout<..., Aligned, ...>` has exactly the same API +// and behavior as `Layout<..., T, ...>` except that the first element of the +// array of `T` is aligned to `N` (the rest of the elements follow without +// padding). `N` cannot be less than `alignof(T)`. +// +// `AllocSize()` and `Pointer()` are the most basic methods for dealing with +// memory layouts. Check out the reference or code below to discover more. +// +// EXAMPLE +// +// // Immutable move-only string with sizeof equal to sizeof(void*). The +// // string size and the characters are kept in the same heap allocation. +// class CompactString { +// public: +// CompactString(const char* s = "") { +// const size_t size = strlen(s); +// // size_t[1] followed by char[size + 1]. +// const L layout(1, size + 1); +// p_.reset(new unsigned char[layout.AllocSize()]); +// // If running under ASAN, mark the padding bytes, if any, to catch +// // memory errors. +// layout.PoisonPadding(p_.get()); +// // Store the size in the allocation. +// *layout.Pointer(p_.get()) = size; +// // Store the characters in the allocation. +// memcpy(layout.Pointer(p_.get()), s, size + 1); +// } +// +// size_t size() const { +// // Equivalent to reinterpret_cast(*p). +// return *L::Partial().Pointer(p_.get()); +// } +// +// const char* c_str() const { +// // Equivalent to reinterpret_cast(p.get() + sizeof(size_t)). +// // The argument in Partial(1) specifies that we have size_t[1] in front +// // of the characters. +// return L::Partial(1).Pointer(p_.get()); +// } +// +// private: +// // Our heap allocation contains a size_t followed by an array of chars. +// using L = Layout; +// std::unique_ptr p_; +// }; +// +// int main() { +// CompactString s = "hello"; +// assert(s.size() == 5); +// assert(strcmp(s.c_str(), "hello") == 0); +// } +// +// DOCUMENTATION +// +// The interface exported by this file consists of: +// - class `Layout<>` and its public members. +// - The public members of class `internal_layout::LayoutImpl<>`. That class +// isn't intended to be used directly, and its name and template parameter +// list are internal implementation details, but the class itself provides +// most of the functionality in this file. See comments on its members for +// detailed documentation. +// +// `Layout::Partial(count1,..., countm)` (where `m` <= `n`) returns a +// `LayoutImpl<>` object. `Layout layout(count1,..., countn)` +// creates a `Layout` object, which exposes the same functionality by inheriting +// from `LayoutImpl<>`. + +#ifndef S2_THIRD_PARTY_ABSL_CONTAINER_INTERNAL_LAYOUT_H_ +#define S2_THIRD_PARTY_ABSL_CONTAINER_INTERNAL_LAYOUT_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef ADDRESS_SANITIZER +#include +#endif + +#include "s2/third_party/absl/meta/type_traits.h" +#include "s2/third_party/absl/strings/str_cat.h" +#include "s2/third_party/absl/types/span.h" +#include "s2/third_party/absl/utility/utility.h" + +#if defined(__GXX_RTTI) +#define ABSL_INTERNAL_HAS_CXA_DEMANGLE +#endif + +#ifdef ABSL_INTERNAL_HAS_CXA_DEMANGLE +#include +#endif + +namespace absl { +namespace container_internal { + +// A type wrapper that instructs `Layout` to use the specific alignment for the +// array. `Layout<..., Aligned, ...>` has exactly the same API +// and behavior as `Layout<..., T, ...>` except that the first element of the +// array of `T` is aligned to `N` (the rest of the elements follow without +// padding). +// +// Requires: `N >= alignof(T)` and `N` is a power of 2. +template +struct Aligned; + +namespace internal_layout { + +template +struct NotAligned {}; + +template +struct NotAligned> { + static_assert(sizeof(T) == 0, "Aligned cannot be const-qualified"); +}; + +template +using IntToSize = size_t; + +template +using TypeToSize = size_t; + +template +struct Type : NotAligned { + using type = T; +}; + +template +struct Type> { + using type = T; +}; + +template +struct SizeOf : NotAligned, std::integral_constant {}; + +template +struct SizeOf> : std::integral_constant {}; + +// Note: workaround for https://gcc.gnu.org/PR88115 +template +struct AlignOf : NotAligned { + static constexpr size_t value = alignof(T); +}; + +template +struct AlignOf> { + static_assert(N % alignof(T) == 0, + "Custom alignment can't be lower than the type's alignment"); + static constexpr size_t value = N; +}; + +// Does `Ts...` contain `T`? +template +using Contains = absl::disjunction...>; + +template +using CopyConst = + typename std::conditional::value, const To, To>::type; + +// Note: We're not qualifying this with absl:: because it doesn't compile under +// MSVC. +template +using SliceType = Span; + +// This namespace contains no types. It prevents functions defined in it from +// being found by ADL. +namespace adl_barrier { + +template +constexpr size_t Find(Needle, Needle, Ts...) { + static_assert(!Contains(), "Duplicate element type"); + return 0; +} + +template +constexpr size_t Find(Needle, T, Ts...) { + return adl_barrier::Find(Needle(), Ts()...) + 1; +} + +constexpr bool IsPow2(size_t n) { return !(n & (n - 1)); } + +// Returns `q * m` for the smallest `q` such that `q * m >= n`. +// Requires: `m` is a power of two. It's enforced by IsLegalElementType below. +constexpr size_t Align(size_t n, size_t m) { return (n + m - 1) & ~(m - 1); } + +constexpr size_t Min(size_t a, size_t b) { return b < a ? b : a; } + +constexpr size_t Max(size_t a) { return a; } + +template +constexpr size_t Max(size_t a, size_t b, Ts... rest) { + return adl_barrier::Max(b < a ? a : b, rest...); +} + +template +string TypeName() { + string out; + int status = 0; + char* demangled = nullptr; +#ifdef ABSL_INTERNAL_HAS_CXA_DEMANGLE + demangled = abi::__cxa_demangle(typeid(T).name(), nullptr, nullptr, &status); +#endif + if (status == 0 && demangled != nullptr) { // Demangling succeeded. + absl::StrAppend(&out, "<", demangled, ">"); + free(demangled); + } else { +#if defined(__GXX_RTTI) || defined(_CPPRTTI) + absl::StrAppend(&out, "<", typeid(T).name(), ">"); +#endif + } + return out; +} + +} // namespace adl_barrier + +template +using EnableIf = typename std::enable_if::type; + +// Can `T` be a template argument of `Layout`? +template +using IsLegalElementType = std::integral_constant< + bool, !std::is_reference::value && !std::is_volatile::value && + !std::is_reference::type>::value && + !std::is_volatile::type>::value && + adl_barrier::IsPow2(AlignOf::value)>; + +template +class LayoutImpl; + +// Public base class of `Layout` and the result type of `Layout::Partial()`. +// +// `Elements...` contains all template arguments of `Layout` that created this +// instance. +// +// `SizeSeq...` is `[0, NumSizes)` where `NumSizes` is the number of arguments +// passed to `Layout::Partial()` or `Layout::Layout()`. +// +// `OffsetSeq...` is `[0, NumOffsets)` where `NumOffsets` is +// `Min(sizeof...(Elements), NumSizes + 1)` (the number of arrays for which we +// can compute offsets). +template +class LayoutImpl, absl::index_sequence, + absl::index_sequence> { + private: + static_assert(sizeof...(Elements) > 0, "At least one field is required"); + static_assert(absl::conjunction...>::value, + "Invalid element type (see IsLegalElementType)"); + + enum { + NumTypes = sizeof...(Elements), + NumSizes = sizeof...(SizeSeq), + NumOffsets = sizeof...(OffsetSeq), + }; + + // These are guaranteed by `Layout`. + static_assert(NumOffsets == adl_barrier::Min(NumTypes, NumSizes + 1), + "Internal error"); + static_assert(NumTypes > 0, "Internal error"); + + // Returns the index of `T` in `Elements...`. Results in a compilation error + // if `Elements...` doesn't contain exactly one instance of `T`. + template + static constexpr size_t ElementIndex() { + static_assert(Contains, Type::type>...>(), + "Type not found"); + return adl_barrier::Find(Type(), + Type::type>()...); + } + + template + using ElementAlignment = + AlignOf>::type>; + + public: + // Element types of all arrays packed in a tuple. + using ElementTypes = std::tuple::type...>; + + // Element type of the Nth array. + template + using ElementType = typename std::tuple_element::type; + + constexpr explicit LayoutImpl(IntToSize... sizes) + : size_{sizes...} {} + + // Alignment of the layout, equal to the strictest alignment of all elements. + // All pointers passed to the methods of layout must be aligned to this value. + static constexpr size_t Alignment() { + return adl_barrier::Max(AlignOf::value...); + } + + // Offset in bytes of the Nth array. + // + // // int[3], 4 bytes of padding, double[4]. + // Layout x(3, 4); + // assert(x.Offset<0>() == 0); // The ints starts from 0. + // assert(x.Offset<1>() == 16); // The doubles starts from 16. + // + // Requires: `N <= NumSizes && N < sizeof...(Ts)`. + template = 0> + constexpr size_t Offset() const { + return 0; + } + + template = 0> + constexpr size_t Offset() const { + static_assert(N < NumOffsets, "Index out of bounds"); + return adl_barrier::Align( + Offset() + SizeOf>() * size_[N - 1], + ElementAlignment::value); + } + + // Offset in bytes of the array with the specified element type. There must + // be exactly one such array and its zero-based index must be at most + // `NumSizes`. + // + // // int[3], 4 bytes of padding, double[4]. + // Layout x(3, 4); + // assert(x.Offset() == 0); // The ints starts from 0. + // assert(x.Offset() == 16); // The doubles starts from 16. + template + constexpr size_t Offset() const { + return Offset()>(); + } + + // Offsets in bytes of all arrays for which the offsets are known. + constexpr std::array Offsets() const { + return {{Offset()...}}; + } + + // The number of elements in the Nth array. This is the Nth argument of + // `Layout::Partial()` or `Layout::Layout()` (zero-based). + // + // // int[3], 4 bytes of padding, double[4]. + // Layout x(3, 4); + // assert(x.Size<0>() == 3); + // assert(x.Size<1>() == 4); + // + // Requires: `N < NumSizes`. + template + constexpr size_t Size() const { + static_assert(N < NumSizes, "Index out of bounds"); + return size_[N]; + } + + // The number of elements in the array with the specified element type. + // There must be exactly one such array and its zero-based index must be + // at most `NumSizes`. + // + // // int[3], 4 bytes of padding, double[4]. + // Layout x(3, 4); + // assert(x.Size() == 3); + // assert(x.Size() == 4); + template + constexpr size_t Size() const { + return Size()>(); + } + + // The number of elements of all arrays for which they are known. + constexpr std::array Sizes() const { + return {{Size()...}}; + } + + // Pointer to the beginning of the Nth array. + // + // `Char` must be `[const] [signed|unsigned] char`. + // + // // int[3], 4 bytes of padding, double[4]. + // Layout x(3, 4); + // unsigned char* p = new unsigned char[x.AllocSize()]; + // int* ints = x.Pointer<0>(p); + // double* doubles = x.Pointer<1>(p); + // + // Requires: `N <= NumSizes && N < sizeof...(Ts)`. + // Requires: `p` is aligned to `Alignment()`. + template + CopyConst>* Pointer(Char* p) const { + using C = typename std::remove_const::type; + static_assert( + std::is_same() || std::is_same() || + std::is_same(), + "The argument must be a pointer to [const] [signed|unsigned] char"); + // Use a named variable to work around b/33479323. + constexpr size_t alignment = Alignment(); + (void)alignment; + assert(reinterpret_cast(p) % alignment == 0); + return reinterpret_cast>*>(p + Offset()); + } + + // Pointer to the beginning of the array with the specified element type. + // There must be exactly one such array and its zero-based index must be at + // most `NumSizes`. + // + // `Char` must be `[const] [signed|unsigned] char`. + // + // // int[3], 4 bytes of padding, double[4]. + // Layout x(3, 4); + // unsigned char* p = new unsigned char[x.AllocSize()]; + // int* ints = x.Pointer(p); + // double* doubles = x.Pointer(p); + // + // Requires: `p` is aligned to `Alignment()`. + template + CopyConst* Pointer(Char* p) const { + return Pointer()>(p); + } + + // Pointers to all arrays for which pointers are known. + // + // `Char` must be `[const] [signed|unsigned] char`. + // + // // int[3], 4 bytes of padding, double[4]. + // Layout x(3, 4); + // unsigned char* p = new unsigned char[x.AllocSize()]; + // + // int* ints; + // double* doubles; + // std::tie(ints, doubles) = x.Pointers(p); + // + // Requires: `p` is aligned to `Alignment()`. + // + // Note: We're not using ElementType alias here because it does not compile + // under MSVC. + template + std::tuple::type>*...> + Pointers(Char* p) const { + return std::tuple>*...>( + Pointer(p)...); + } + + // The Nth array. + // + // `Char` must be `[const] [signed|unsigned] char`. + // + // // int[3], 4 bytes of padding, double[4]. + // Layout x(3, 4); + // unsigned char* p = new unsigned char[x.AllocSize()]; + // Span ints = x.Slice<0>(p); + // Span doubles = x.Slice<1>(p); + // + // Requires: `N < NumSizes`. + // Requires: `p` is aligned to `Alignment()`. + template + SliceType>> Slice(Char* p) const { + return SliceType>>(Pointer(p), Size()); + } + + // The array with the specified element type. There must be exactly one + // such array and its zero-based index must be less than `NumSizes`. + // + // `Char` must be `[const] [signed|unsigned] char`. + // + // // int[3], 4 bytes of padding, double[4]. + // Layout x(3, 4); + // unsigned char* p = new unsigned char[x.AllocSize()]; + // Span ints = x.Slice(p); + // Span doubles = x.Slice(p); + // + // Requires: `p` is aligned to `Alignment()`. + template + SliceType> Slice(Char* p) const { + return Slice()>(p); + } + + // All arrays with known sizes. + // + // `Char` must be `[const] [signed|unsigned] char`. + // + // // int[3], 4 bytes of padding, double[4]. + // Layout x(3, 4); + // unsigned char* p = new unsigned char[x.AllocSize()]; + // + // Span ints; + // Span doubles; + // std::tie(ints, doubles) = x.Slices(p); + // + // Requires: `p` is aligned to `Alignment()`. + // + // Note: We're not using ElementType alias here because it does not compile + // under MSVC. + template + std::tuple::type>>...> + Slices(Char* p) const { + // Workaround for https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63875 (fixed + // in 6.1). + (void)p; + return std::tuple>>...>( + Slice(p)...); + } + + // The size of the allocation that fits all arrays. + // + // // int[3], 4 bytes of padding, double[4]. + // Layout x(3, 4); + // unsigned char* p = new unsigned char[x.AllocSize()]; // 48 bytes + // + // Requires: `NumSizes == sizeof...(Ts)`. + constexpr size_t AllocSize() const { + static_assert(NumTypes == NumSizes, "You must specify sizes of all fields"); + return Offset() + + SizeOf>() * size_[NumTypes - 1]; + } + + // If built with --config=asan, poisons padding bytes (if any) in the + // allocation. The pointer must point to a memory block at least + // `AllocSize()` bytes in length. + // + // `Char` must be `[const] [signed|unsigned] char`. + // + // Requires: `p` is aligned to `Alignment()`. + template = 0> + void PoisonPadding(const Char* p) const { + Pointer<0>(p); // verify the requirements on `Char` and `p` + } + + template = 0> + void PoisonPadding(const Char* p) const { + static_assert(N < NumOffsets, "Index out of bounds"); + (void)p; +#ifdef ADDRESS_SANITIZER + PoisonPadding(p); + // The `if` is an optimization. It doesn't affect the observable behaviour. + if (ElementAlignment::value % ElementAlignment::value) { + size_t start = + Offset() + SizeOf>() * size_[N - 1]; + ASAN_POISON_MEMORY_REGION(p + start, Offset() - start); + } +#endif + } + + // Human-readable description of the memory layout. Useful for debugging. + // Slow. + // + // // char[5], 3 bytes of padding, int[3], 4 bytes of padding, followed + // // by an unknown number of doubles. + // auto x = Layout::Partial(5, 3); + // assert(x.DebugString() == + // "@0(1)[5]; @8(4)[3]; @24(8)"); + // + // Each field is in the following format: @offset(sizeof)[size] ( + // may be missing depending on the target platform). For example, + // @8(4)[3] means that at offset 8 we have an array of ints, where each + // int is 4 bytes, and we have 3 of those ints. The size of the last field may + // be missing (as in the example above). Only fields with known offsets are + // described. Type names may differ across platforms: one compiler might + // produce "unsigned*" where another produces "unsigned int *". + string DebugString() const { + const auto offsets = Offsets(); + const size_t sizes[] = {SizeOf>()...}; + const string types[] = {adl_barrier::TypeName>()...}; + string res = absl::StrCat("@0", types[0], "(", sizes[0], ")"); + for (size_t i = 0; i != NumOffsets - 1; ++i) { + absl::StrAppend(&res, "[", size_[i], "]; @", offsets[i + 1], types[i + 1], + "(", sizes[i + 1], ")"); + } + // NumSizes is a constant that may be zero. Some compilers cannot see that + // inside the if statement "size_[NumSizes - 1]" must be valid. + int last = static_cast(NumSizes) - 1; + if (NumTypes == NumSizes && last >= 0) { + absl::StrAppend(&res, "[", size_[last], "]"); + } + return res; + } + + private: + // Arguments of `Layout::Partial()` or `Layout::Layout()`. + size_t size_[NumSizes > 0 ? NumSizes : 1]; +}; + +template +using LayoutType = LayoutImpl< + std::tuple, absl::make_index_sequence, + absl::make_index_sequence>; + +} // namespace internal_layout + +// Descriptor of arrays of various types and sizes laid out in memory one after +// another. See the top of the file for documentation. +// +// Check out the public API of internal_layout::LayoutImpl above. The type is +// internal to the library but its methods are public, and they are inherited +// by `Layout`. +template +class Layout : public internal_layout::LayoutType { + public: + static_assert(sizeof...(Ts) > 0, "At least one field is required"); + static_assert( + absl::conjunction...>::value, + "Invalid element type (see IsLegalElementType)"); + + // The result type of `Partial()` with `NumSizes` arguments. + template + using PartialType = internal_layout::LayoutType; + + // `Layout` knows the element types of the arrays we want to lay out in + // memory but not the number of elements in each array. + // `Partial(size1, ..., sizeN)` allows us to specify the latter. The + // resulting immutable object can be used to obtain pointers to the + // individual arrays. + // + // It's allowed to pass fewer array sizes than the number of arrays. E.g., + // if all you need is to the offset of the second array, you only need to + // pass one argument -- the number of elements in the first array. + // + // // int[3] followed by 4 bytes of padding and an unknown number of + // // doubles. + // auto x = Layout::Partial(3); + // // doubles start at byte 16. + // assert(x.Offset<1>() == 16); + // + // If you know the number of elements in all arrays, you can still call + // `Partial()` but it's more convenient to use the constructor of `Layout`. + // + // Layout x(3, 5); + // + // Note: The sizes of the arrays must be specified in number of elements, + // not in bytes. + // + // Requires: `sizeof...(Sizes) <= sizeof...(Ts)`. + // Requires: all arguments are convertible to `size_t`. + template + static constexpr PartialType Partial(Sizes&&... sizes) { + static_assert(sizeof...(Sizes) <= sizeof...(Ts), ""); + return PartialType(absl::forward(sizes)...); + } + + // Creates a layout with the sizes of all arrays specified. If you know + // only the sizes of the first N arrays (where N can be zero), you can use + // `Partial()` defined above. The constructor is essentially equivalent to + // calling `Partial()` and passing in all array sizes; the constructor is + // provided as a convenient abbreviation. + // + // Note: The sizes of the arrays must be specified in number of elements, + // not in bytes. + constexpr explicit Layout(internal_layout::TypeToSize... sizes) + : internal_layout::LayoutType(sizes...) {} +}; + +} // namespace container_internal +} // namespace absl + +#endif // S2_THIRD_PARTY_ABSL_CONTAINER_INTERNAL_LAYOUT_H_ diff --git a/inst/include/s2/third_party/absl/memory/memory.h b/inst/include/s2/third_party/absl/memory/memory.h new file mode 100644 index 0000000..7a853e8 --- /dev/null +++ b/inst/include/s2/third_party/absl/memory/memory.h @@ -0,0 +1,755 @@ +// Copyright 2017 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// ----------------------------------------------------------------------------- +// File: memory.h +// ----------------------------------------------------------------------------- +// +// This header file contains utility functions for managing the creation and +// conversion of smart pointers. This file is an extension to the C++ +// standard library header file. + +#ifndef S2_THIRD_PARTY_ABSL_MEMORY_MEMORY_H_ +#define S2_THIRD_PARTY_ABSL_MEMORY_MEMORY_H_ + +#include +#include +#include +#include +#include +#include + +#include "s2/third_party/absl/base/macros.h" +#include "s2/third_party/absl/meta/type_traits.h" + +namespace absl { + +// ----------------------------------------------------------------------------- +// Function Template: WrapUnique() +// ----------------------------------------------------------------------------- +// +// Adopts ownership from a raw pointer and transfers it to the returned +// `std::unique_ptr`, whose type is deduced. Because of this deduction, *do not* +// specify the template type `T` when calling `WrapUnique`. +// +// Example: +// X* NewX(int, int); +// auto x = WrapUnique(NewX(1, 2)); // 'x' is std::unique_ptr. +// +// The purpose of WrapUnique is to automatically deduce the pointer type. If you +// wish to make the type explicit, for readability reasons or because you prefer +// to use a base-class pointer rather than a derived one, just use +// `std::unique_ptr` directly. +// +// Example: +// X* Factory(int, int); +// auto x = std::unique_ptr(Factory(1, 2)); +// - or - +// std::unique_ptr x(Factory(1, 2)); +// +// This has the added advantage of working whether Factory returns a raw +// pointer or a `std::unique_ptr`. +// +// While `absl::WrapUnique` is useful for capturing the output of a raw +// pointer factory, prefer 'absl::make_unique(args...)' over +// 'absl::WrapUnique(new T(args...))'. +// +// auto x = WrapUnique(new X(1, 2)); // works, but nonideal. +// auto x = make_unique(1, 2); // safer, standard, avoids raw 'new'. +// +// Note that `absl::WrapUnique(p)` is valid only if `delete p` is a valid +// expression. In particular, `absl::WrapUnique()` cannot wrap pointers to +// arrays, functions or void, and it must not be used to capture pointers +// obtained from array-new expressions (even though that would compile!). +template +std::unique_ptr WrapUnique(T* ptr) { + static_assert(!std::is_array::value, "array types are unsupported"); + static_assert(std::is_object::value, "non-object types are unsupported"); + return std::unique_ptr(ptr); +} + +namespace memory_internal { + +// Traits to select proper overload and return type for `absl::make_unique<>`. +template +struct MakeUniqueResult { + using scalar = std::unique_ptr; +}; +template +struct MakeUniqueResult { + using array = std::unique_ptr; +}; +template +struct MakeUniqueResult { + using invalid = void; +}; + +} // namespace memory_internal + +// gcc 4.8 has __cplusplus at 201301 but doesn't define make_unique. Other +// supported compilers either just define __cplusplus as 201103 but have +// make_unique (msvc), or have make_unique whenever __cplusplus > 201103 (clang) +#if (__cplusplus > 201103L || defined(_MSC_VER)) && \ + !(defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ == 8) +using std::make_unique; +#else +// ----------------------------------------------------------------------------- +// Function Template: make_unique() +// ----------------------------------------------------------------------------- +// +// Creates a `std::unique_ptr<>`, while avoiding issues creating temporaries +// during the construction process. `absl::make_unique<>` also avoids redundant +// type declarations, by avoiding the need to explicitly use the `new` operator. +// +// This implementation of `absl::make_unique<>` is designed for C++11 code and +// will be replaced in C++14 by the equivalent `std::make_unique<>` abstraction. +// `absl::make_unique<>` is designed to be 100% compatible with +// `std::make_unique<>` so that the eventual migration will involve a simple +// rename operation. +// +// For more background on why `std::unique_ptr(new T(a,b))` is problematic, +// see Herb Sutter's explanation on +// (Exception-Safe Function Calls)[http://herbsutter.com/gotw/_102/]. +// (In general, reviewers should treat `new T(a,b)` with scrutiny.) +// +// Example usage: +// +// auto p = make_unique(args...); // 'p' is a std::unique_ptr +// auto pa = make_unique(5); // 'pa' is a std::unique_ptr +// +// Three overloads of `absl::make_unique` are required: +// +// - For non-array T: +// +// Allocates a T with `new T(std::forward args...)`, +// forwarding all `args` to T's constructor. +// Returns a `std::unique_ptr` owning that object. +// +// - For an array of unknown bounds T[]: +// +// `absl::make_unique<>` will allocate an array T of type U[] with +// `new U[n]()` and return a `std::unique_ptr` owning that array. +// +// Note that 'U[n]()' is different from 'U[n]', and elements will be +// value-initialized. Note as well that `std::unique_ptr` will perform its +// own destruction of the array elements upon leaving scope, even though +// the array [] does not have a default destructor. +// +// NOTE: an array of unknown bounds T[] may still be (and often will be) +// initialized to have a size, and will still use this overload. E.g: +// +// auto my_array = absl::make_unique(10); +// +// - For an array of known bounds T[N]: +// +// `absl::make_unique<>` is deleted (like with `std::make_unique<>`) as +// this overload is not useful. +// +// NOTE: an array of known bounds T[N] is not considered a useful +// construction, and may cause undefined behavior in templates. E.g: +// +// auto my_array = absl::make_unique(); +// +// In those cases, of course, you can still use the overload above and +// simply initialize it to its desired size: +// +// auto my_array = absl::make_unique(10); + +// `absl::make_unique` overload for non-array types. +template +typename memory_internal::MakeUniqueResult::scalar make_unique( + Args&&... args) { + return std::unique_ptr(new T(std::forward(args)...)); +} + +// `absl::make_unique` overload for an array T[] of unknown bounds. +// The array allocation needs to use the `new T[size]` form and cannot take +// element constructor arguments. The `std::unique_ptr` will manage destructing +// these array elements. +template +typename memory_internal::MakeUniqueResult::array make_unique(size_t n) { + return std::unique_ptr(new typename absl::remove_extent_t[n]()); +} + +// `absl::make_unique` overload for an array T[N] of known bounds. +// This construction will be rejected. +template +typename memory_internal::MakeUniqueResult::invalid make_unique( + Args&&... /* args */) = delete; +#endif + + +// These are make_unique_default_init variants modeled after +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1020r0.html +// Unlike absl::make_unique, values are default initialized rather than value +// initialized. +// +// `absl::make_unique_default_init` overload for non-array types. +template +typename memory_internal::MakeUniqueResult::scalar + make_unique_default_init() { + return std::unique_ptr(new T); +} + +// `absl::make_unique_default_init` overload for an array T[] of unknown bounds. +// The array allocation needs to use the `new T[size]` form and cannot take +// element constructor arguments. The `std::unique_ptr` will manage destructing +// these array elements. +template +typename memory_internal::MakeUniqueResult::array + make_unique_default_init(size_t n) { + return std::unique_ptr(new typename absl::remove_extent_t[n]); +} + +// `absl::make_unique_default_init` overload for an array T[N] of known bounds. +// This construction will be rejected. +template +typename memory_internal::MakeUniqueResult::invalid + make_unique_default_init(Args&&... /* args */) = delete; + + + +// NOTE TO GOOGLERS: +// absl::MakeUnique / gtl::MakeUnique is a legacy spelling. New code should +// prefer absl::make_unique. + +// `absl::MakeUnique` overload for non-array types. +template +typename memory_internal::MakeUniqueResult::scalar + MakeUnique(Args&&... args) { + return std::unique_ptr(new T(std::forward(args)...)); +} + +// `absl::MakeUnique` overload for an array T[] of unknown bounds. +// The array allocation needs to use the `new T[size]` form and cannot take +// element constructor arguments. The `std::unique_ptr` will manage destructing +// these array elements. +template +typename memory_internal::MakeUniqueResult::array MakeUnique(size_t n) { + return std::unique_ptr(new typename absl::remove_extent_t[n]()); +} + +// `absl::MakeUnique` overload for an array T[N] of known bounds. +// This construction will be rejected. +template +typename memory_internal::MakeUniqueResult::invalid + MakeUnique(Args&&... /* args */) = delete; + +// ----------------------------------------------------------------------------- +// Function Template: RawPtr() +// ----------------------------------------------------------------------------- +// +// Extracts the raw pointer from a pointer-like value `ptr`. `absl::RawPtr` is +// useful within templates that need to handle a complement of raw pointers, +// `std::nullptr_t`, and smart pointers. +template +auto RawPtr(T&& ptr) -> decltype(std::addressof(*ptr)) { + // ptr is a forwarding reference to support Ts with non-const operators. + return (ptr != nullptr) ? std::addressof(*ptr) : nullptr; +} +inline std::nullptr_t RawPtr(std::nullptr_t) { return nullptr; } + +// ----------------------------------------------------------------------------- +// Function Template: ShareUniquePtr() +// ----------------------------------------------------------------------------- +// +// Adopts a `std::unique_ptr` rvalue and returns a `std::shared_ptr` of deduced +// type. Ownership (if any) of the held value is transferred to the returned +// shared pointer. +// +// Example: +// +// auto up = absl::make_unique(10); +// auto sp = absl::ShareUniquePtr(std::move(up)); // shared_ptr +// CHECK_EQ(*sp, 10); +// CHECK(up == nullptr); +// +// Note that this conversion is correct even when T is an array type, and more +// generally it works for *any* deleter of the `unique_ptr` (single-object +// deleter, array deleter, or any custom deleter), since the deleter is adopted +// by the shared pointer as well. The deleter is copied (unless it is a +// reference). +// +// Implements the resolution of [LWG 2415](http://wg21.link/lwg2415), by which a +// null shared pointer does not attempt to call the deleter. +template +std::shared_ptr ShareUniquePtr(std::unique_ptr&& ptr) { + return ptr ? std::shared_ptr(std::move(ptr)) : std::shared_ptr(); +} + +// ----------------------------------------------------------------------------- +// Function Template: WeakenPtr() +// ----------------------------------------------------------------------------- +// +// Creates a weak pointer associated with a given shared pointer. The returned +// value is a `std::weak_ptr` of deduced type. +// +// Example: +// +// auto sp = std::make_shared(10); +// auto wp = absl::WeakenPtr(sp); +// CHECK_EQ(sp.get(), wp.lock().get()); +// sp.reset(); +// CHECK(wp.lock() == nullptr); +// +template +std::weak_ptr WeakenPtr(const std::shared_ptr& ptr) { + return std::weak_ptr(ptr); +} + +namespace memory_internal { + +// ExtractOr::type evaluates to E if possible. Otherwise, D. +template