Merge commit '6eb4f090f98f6b17a23c57768c16b7716b6c9cbd' as 'third_party/libosmium'

This commit is contained in:
Patrick Niklaus
2017-08-30 09:30:27 +00:00
434 changed files with 81367 additions and 0 deletions
@@ -0,0 +1,131 @@
#include "catch.hpp"
#include <array>
#include <stdexcept>
#include <osmium/memory/buffer.hpp>
TEST_CASE("Buffer basics") {
osmium::memory::Buffer invalid_buffer1;
osmium::memory::Buffer invalid_buffer2;
osmium::memory::Buffer empty_buffer1{1024};
osmium::memory::Buffer empty_buffer2{2048};
REQUIRE_FALSE(invalid_buffer1);
REQUIRE_FALSE(invalid_buffer2);
REQUIRE(empty_buffer1);
REQUIRE(empty_buffer2);
REQUIRE(invalid_buffer1 == invalid_buffer2);
REQUIRE(invalid_buffer1 != empty_buffer1);
REQUIRE(empty_buffer1 != empty_buffer2);
REQUIRE(invalid_buffer1.capacity() == 0);
REQUIRE(invalid_buffer1.written() == 0);
REQUIRE(invalid_buffer1.committed() == 0);
REQUIRE(invalid_buffer1.clear() == 0);
REQUIRE(empty_buffer1.capacity() == 1024);
REQUIRE(empty_buffer1.written() == 0);
REQUIRE(empty_buffer1.committed() == 0);
REQUIRE(empty_buffer1.is_aligned());
REQUIRE(empty_buffer1.clear() == 0);
REQUIRE(empty_buffer2.capacity() == 2048);
REQUIRE(empty_buffer2.written() == 0);
REQUIRE(empty_buffer2.committed() == 0);
REQUIRE(empty_buffer2.is_aligned());
REQUIRE(empty_buffer2.clear() == 0);
}
TEST_CASE("Buffer with zero size") {
osmium::memory::Buffer buffer{0};
REQUIRE(buffer.capacity() == 64);
}
TEST_CASE("Buffer with less than minimum size") {
osmium::memory::Buffer buffer{63};
REQUIRE(buffer.capacity() == 64);
}
TEST_CASE("Buffer with minimum size") {
osmium::memory::Buffer buffer{64};
REQUIRE(buffer.capacity() == 64);
}
TEST_CASE("Buffer with non-aligned size") {
osmium::memory::Buffer buffer{65};
REQUIRE(buffer.capacity() > 65);
}
TEST_CASE("Grow a buffer") {
osmium::memory::Buffer buffer{128};
REQUIRE(buffer.capacity() == 128);
buffer.grow(256);
REQUIRE(buffer.capacity() == 256);
buffer.grow(257);
REQUIRE(buffer.capacity() > 256);
REQUIRE(buffer.committed() == 0);
REQUIRE(buffer.written() == 0);
REQUIRE(buffer.is_aligned());
}
TEST_CASE("Reserve space in a non-growing buffer") {
osmium::memory::Buffer buffer{128, osmium::memory::Buffer::auto_grow::no};
REQUIRE(buffer.reserve_space(20) != nullptr);
REQUIRE(buffer.written() == 20);
REQUIRE_THROWS_AS(buffer.reserve_space(1000), const osmium::buffer_is_full&);
}
TEST_CASE("Reserve space in a growing buffer") {
osmium::memory::Buffer buffer{128, osmium::memory::Buffer::auto_grow::yes};
REQUIRE(buffer.reserve_space(20) != nullptr);
REQUIRE(buffer.written() == 20);
REQUIRE(buffer.reserve_space(1000) != nullptr);
REQUIRE(buffer.written() == 1020);
}
TEST_CASE("Create buffer from existing data with good alignment works") {
std::array<unsigned char, 128> data;
osmium::memory::Buffer buffer{data.data(), data.size()};
REQUIRE(buffer.capacity() == 128);
REQUIRE(buffer.committed() == 128);
}
TEST_CASE("Create buffer from existing data with good alignment and committed value works") {
std::array<unsigned char, 128> data;
osmium::memory::Buffer buffer{data.data(), data.size(), 32};
REQUIRE(buffer.capacity() == 128);
REQUIRE(buffer.committed() == 32);
REQUIRE(buffer.written() == 32);
}
TEST_CASE("Create buffer from existing data with bad alignment fails") {
std::array<unsigned char, 128> data;
const auto l1 = [&](){
osmium::memory::Buffer buffer{data.data(), 127};
};
const auto l2 = [&](){
osmium::memory::Buffer buffer{data.data(), 127, 120};
};
const auto l3 = [&](){
osmium::memory::Buffer buffer{data.data(), 128, 127};
};
const auto l4 = [&](){
osmium::memory::Buffer buffer{data.data(), 32, 128};
};
REQUIRE_THROWS_AS(l1(), const std::invalid_argument&);
REQUIRE_THROWS_AS(l2(), const std::invalid_argument&);
REQUIRE_THROWS_AS(l3(), const std::invalid_argument&);
REQUIRE_THROWS_AS(l4(), const std::invalid_argument&);
}
+185
View File
@@ -0,0 +1,185 @@
#include "catch.hpp"
#include <osmium/builder/osm_object_builder.hpp>
#include <osmium/osm/node.hpp>
void check_node_1(const osmium::Node& node) {
REQUIRE(1 == node.id());
REQUIRE(3 == node.version());
REQUIRE(true == node.visible());
REQUIRE(333 == node.changeset());
REQUIRE(21 == node.uid());
REQUIRE(123 == uint32_t(node.timestamp()));
REQUIRE(osmium::Location(3.5, 4.7) == node.location());
REQUIRE(std::string{"testuser"} == node.user());
for (const osmium::memory::Item& item : node) {
REQUIRE(osmium::item_type::tag_list == item.type());
}
REQUIRE(node.tags().begin() == node.tags().end());
REQUIRE(node.tags().empty());
REQUIRE(0 == std::distance(node.tags().begin(), node.tags().end()));
}
void check_node_2(const osmium::Node& node) {
REQUIRE(2 == node.id());
REQUIRE(3 == node.version());
REQUIRE(true == node.visible());
REQUIRE(333 == node.changeset());
REQUIRE(21 == node.uid());
REQUIRE(123 == uint32_t(node.timestamp()));
REQUIRE(osmium::Location(3.5, 4.7) == node.location());
REQUIRE(std::string{"testuser"} == node.user());
for (const osmium::memory::Item& item : node) {
REQUIRE(osmium::item_type::tag_list == item.type());
}
REQUIRE_FALSE(node.tags().empty());
REQUIRE(2 == std::distance(node.tags().begin(), node.tags().end()));
int n = 0;
for (const osmium::Tag& tag : node.tags()) {
switch (n) {
case 0:
REQUIRE(std::string("amenity") == tag.key());
REQUIRE(std::string("bank") == tag.value());
break;
case 1:
REQUIRE(std::string("name") == tag.key());
REQUIRE(std::string("OSM Savings") == tag.value());
break;
}
++n;
}
REQUIRE(2 == n);
}
TEST_CASE("Node in Buffer") {
constexpr size_t buffer_size = 10000;
unsigned char data[buffer_size];
osmium::memory::Buffer buffer{data, buffer_size, 0};
SECTION("Add node to buffer") {
{
// add node 1
osmium::builder::NodeBuilder node_builder{buffer};
node_builder.set_id(1)
.set_version(3)
.set_visible(true)
.set_changeset(333)
.set_uid(21)
.set_timestamp(123)
.set_location(osmium::Location{3.5, 4.7})
.set_user("testuser");
}
buffer.commit();
{
// add node 2
osmium::builder::NodeBuilder node_builder{buffer};
node_builder.set_id(2)
.set_version(3)
.set_visible(true)
.set_changeset(333)
.set_uid(21)
.set_timestamp(123)
.set_location(osmium::Location{3.5, 4.7})
.set_user("testuser");
osmium::builder::TagListBuilder tag_builder{node_builder};
tag_builder.add_tag("amenity", "bank");
tag_builder.add_tag("name", "OSM Savings");
}
buffer.commit();
REQUIRE(2 == std::distance(buffer.begin(), buffer.end()));
int item_no = 0;
for (const osmium::memory::Item& item : buffer) {
REQUIRE(osmium::item_type::node == item.type());
const osmium::Node& node = static_cast<const osmium::Node&>(item);
switch (item_no) {
case 0:
check_node_1(node);
break;
case 1:
check_node_2(node);
break;
default:
break;
}
++item_no;
}
}
SECTION("Add buffer to another one") {
{
// add node 1
osmium::builder::NodeBuilder node_builder{buffer};
node_builder.set_id(1)
.set_version(3)
.set_visible(true)
.set_changeset(333)
.set_uid(21)
.set_timestamp(123)
.set_location(osmium::Location{3.5, 4.7})
.set_user("testuser");
}
buffer.commit();
osmium::memory::Buffer buffer2{buffer_size, osmium::memory::Buffer::auto_grow::yes};
buffer2.add_buffer(buffer);
buffer2.commit();
REQUIRE(buffer.committed() == buffer2.committed());
const osmium::Node& node = buffer2.get<osmium::Node>(0);
REQUIRE(node.id() == 1);
REQUIRE(123 == uint32_t(node.timestamp()));
}
SECTION("Use back_inserter on buffer") {
{
// add node 1
osmium::builder::NodeBuilder node_builder{buffer};
node_builder.set_id(1)
.set_version(3)
.set_visible(true)
.set_changeset(333)
.set_uid(21)
.set_timestamp(123)
.set_location(osmium::Location{3.5, 4.7})
.set_user("testuser");
}
buffer.commit();
osmium::memory::Buffer buffer2{buffer_size, osmium::memory::Buffer::auto_grow::yes};
std::copy(buffer.begin(), buffer.end(), std::back_inserter(buffer2));
REQUIRE(buffer.committed() == buffer2.committed());
const osmium::Node& node = buffer2.get<osmium::Node>(0);
REQUIRE(node.id() == 1);
REQUIRE(123 == uint32_t(node.timestamp()));
}
}
@@ -0,0 +1,174 @@
#include "catch.hpp"
#include <osmium/builder/osm_object_builder.hpp>
#include <osmium/osm/node.hpp>
struct CallbackClass {
int count = 0;
void moving_in_buffer(size_t old_offset, size_t new_offset) {
REQUIRE(old_offset > new_offset);
++count;
}
}; // struct CallbackClass
TEST_CASE("Purge data from buffer") {
constexpr size_t buffer_size = 10000;
osmium::memory::Buffer buffer{buffer_size};
SECTION("purge empty buffer") {
REQUIRE(std::distance(buffer.begin(), buffer.end()) == 0);
CallbackClass callback;
buffer.purge_removed(&callback);
REQUIRE(callback.count == 0);
REQUIRE(buffer.committed() == 0);
}
SECTION("purge buffer with one object but nothing to delete") {
{
osmium::builder::NodeBuilder node_builder{buffer};
node_builder.set_user("testuser");
}
buffer.commit();
REQUIRE(std::distance(buffer.begin(), buffer.end()) == 1);
const size_t committed = buffer.committed();
CallbackClass callback;
buffer.purge_removed(&callback);
REQUIRE(callback.count == 0);
REQUIRE(committed == buffer.committed());
REQUIRE(std::distance(buffer.begin(), buffer.end()) == 1);
}
SECTION("purge buffer with one object which gets deleted") {
{
osmium::builder::NodeBuilder node_builder{buffer};
node_builder.set_user("testuser");
node_builder.set_removed(true);
}
buffer.commit();
REQUIRE(std::distance(buffer.begin(), buffer.end()) == 1);
CallbackClass callback;
buffer.purge_removed(&callback);
REQUIRE(callback.count == 0);
REQUIRE(buffer.committed() == 0);
REQUIRE(std::distance(buffer.begin(), buffer.end()) == 0);
}
SECTION("purge buffer with two objects, first gets deleted") {
{
osmium::builder::NodeBuilder node_builder{buffer};
node_builder.set_user("testuser");
node_builder.set_removed(true);
}
buffer.commit();
const size_t size1 = buffer.committed();
{
osmium::builder::NodeBuilder node_builder{buffer};
node_builder.set_user("testuser");
}
buffer.commit();
const size_t size2 = buffer.committed() - size1;
REQUIRE(std::distance(buffer.begin(), buffer.end()) == 2);
CallbackClass callback;
buffer.purge_removed(&callback);
REQUIRE(callback.count == 1);
REQUIRE(std::distance(buffer.begin(), buffer.end()) == 1);
REQUIRE(buffer.committed() == size2);
}
SECTION("purge buffer with two objects, second gets deleted") {
{
osmium::builder::NodeBuilder node_builder{buffer};
node_builder.set_user("testuser_longer_name");
}
buffer.commit();
size_t size1 = buffer.committed();
{
osmium::builder::NodeBuilder node_builder{buffer};
node_builder.set_user("testuser");
node_builder.set_removed(true);
}
buffer.commit();
REQUIRE(std::distance(buffer.begin(), buffer.end()) == 2);
CallbackClass callback;
buffer.purge_removed(&callback);
REQUIRE(callback.count == 0);
REQUIRE(std::distance(buffer.begin(), buffer.end()) == 1);
REQUIRE(buffer.committed() == size1);
}
SECTION("purge buffer with three objects, middle one gets deleted") {
{
osmium::builder::NodeBuilder node_builder{buffer};
node_builder.set_user("testuser_longer_name");
}
buffer.commit();
{
osmium::builder::NodeBuilder node_builder{buffer};
node_builder.set_user("testuser");
node_builder.set_removed(true);
}
buffer.commit();
{
osmium::builder::NodeBuilder node_builder{buffer};
node_builder.set_user("sn");
}
buffer.commit();
REQUIRE(std::distance(buffer.begin(), buffer.end()) == 3);
CallbackClass callback;
buffer.purge_removed(&callback);
REQUIRE(callback.count == 1);
REQUIRE(std::distance(buffer.begin(), buffer.end()) == 2);
}
SECTION("purge buffer with three objects, all get deleted") {
{
osmium::builder::NodeBuilder node_builder{buffer};
node_builder.set_user("testuser_longer_name");
node_builder.set_removed(true);
}
buffer.commit();
{
osmium::builder::NodeBuilder node_builder{buffer};
node_builder.set_user("testuser");
node_builder.set_removed(true);
}
buffer.commit();
{
osmium::builder::NodeBuilder node_builder{buffer};
node_builder.set_user("sn");
node_builder.set_removed(true);
}
buffer.commit();
REQUIRE(std::distance(buffer.begin(), buffer.end()) == 3);
CallbackClass callback;
buffer.purge_removed(&callback);
REQUIRE(callback.count == 0);
REQUIRE(std::distance(buffer.begin(), buffer.end()) == 0);
}
}
@@ -0,0 +1,101 @@
#include "catch.hpp"
#include <iterator>
#include <osmium/builder/attr.hpp>
#include <osmium/memory/callback_buffer.hpp>
using namespace osmium::builder::attr;
TEST_CASE("Callback buffer") {
osmium::memory::CallbackBuffer cb;
REQUIRE(cb.buffer().committed() == 0);
osmium::builder::add_node(cb.buffer(), _id(1));
osmium::builder::add_node(cb.buffer(), _id(2));
osmium::builder::add_node(cb.buffer(), _id(3));
auto c = cb.buffer().committed();
REQUIRE(c > 0);
REQUIRE(std::distance(cb.buffer().begin(), cb.buffer().end()) == 3);
auto buffer = cb.read();
REQUIRE(cb.buffer().committed() == 0);
REQUIRE(buffer.committed() == c);
REQUIRE(std::distance(cb.buffer().begin(), cb.buffer().end()) == 0);
// no callback defined, so nothing will happen
cb.flush();
}
TEST_CASE("Callback buffer with callback triggering every time") {
int run = 0;
osmium::memory::CallbackBuffer cb{[&](osmium::memory::Buffer&& buffer){
REQUIRE(buffer.committed() > 0);
REQUIRE(std::distance(buffer.begin(), buffer.end()) == 1);
++run;
}, 1000, 10};
osmium::builder::add_node(cb.buffer(), _id(1));
REQUIRE(cb.buffer().committed() > 10);
cb.possibly_flush();
osmium::builder::add_node(cb.buffer(), _id(2));
REQUIRE(cb.buffer().committed() > 10);
cb.possibly_flush();
osmium::builder::add_node(cb.buffer(), _id(3));
REQUIRE(cb.buffer().committed() > 10);
cb.possibly_flush();
REQUIRE(run == 3);
REQUIRE(std::distance(cb.buffer().begin(), cb.buffer().end()) == 0);
}
TEST_CASE("Callback buffer with callback triggering sometimes") {
int run = 0;
osmium::memory::CallbackBuffer cb{[&](osmium::memory::Buffer&& buffer){
REQUIRE(buffer.committed() > 0);
++run;
}, 1000, 100};
osmium::builder::add_node(cb.buffer(), _id(1));
REQUIRE(cb.buffer().committed() < 100);
cb.possibly_flush();
osmium::builder::add_node(cb.buffer(), _id(2));
cb.possibly_flush();
osmium::builder::add_node(cb.buffer(), _id(3));
cb.possibly_flush();
REQUIRE(run < 3);
}
TEST_CASE("Callback buffer with callback set later") {
int run = 0;
osmium::memory::CallbackBuffer cb{1000, 10};
osmium::builder::add_node(cb.buffer(), _id(1));
cb.possibly_flush();
osmium::builder::add_node(cb.buffer(), _id(2));
cb.possibly_flush();
osmium::builder::add_node(cb.buffer(), _id(3));
cb.set_callback([&](osmium::memory::Buffer&& buffer){
REQUIRE(buffer.committed() > 0);
REQUIRE(std::distance(buffer.begin(), buffer.end()) == 3);
++run;
});
REQUIRE(std::distance(cb.buffer().begin(), cb.buffer().end()) == 3);
cb.possibly_flush();
REQUIRE(std::distance(cb.buffer().begin(), cb.buffer().end()) == 0);
REQUIRE(run == 1);
}
+29
View File
@@ -0,0 +1,29 @@
#include "catch.hpp"
#include <osmium/memory/item.hpp>
TEST_CASE("padded length") {
REQUIRE(osmium::memory::padded_length(0) == 0);
REQUIRE(osmium::memory::padded_length(1) == 8);
REQUIRE(osmium::memory::padded_length(2) == 8);
REQUIRE(osmium::memory::padded_length(7) == 8);
REQUIRE(osmium::memory::padded_length(8) == 8);
REQUIRE(osmium::memory::padded_length(9) == 16);
REQUIRE(osmium::memory::padded_length(2147483647) == 2147483648);
REQUIRE(osmium::memory::padded_length(2147483648) == 2147483648);
REQUIRE(osmium::memory::padded_length(2147483650) == 2147483656);
// The following checks only make sense on a 64 bit system (with
// sizeof(size_t) == 8), because the numbers are too large for 32 bit.
// The casts to size_t do nothing on a 64 bit system, on a 32 bit system
// they bring the numbers into the right range and everything still works.
REQUIRE(osmium::memory::padded_length(static_cast<std::size_t>(4294967295)) == static_cast<std::size_t>(4294967296));
REQUIRE(osmium::memory::padded_length(static_cast<std::size_t>(4294967296)) == static_cast<std::size_t>(4294967296));
REQUIRE(osmium::memory::padded_length(static_cast<std::size_t>(4294967297)) == static_cast<std::size_t>(4294967304));
REQUIRE(osmium::memory::padded_length(static_cast<std::size_t>(7999999999)) == static_cast<std::size_t>(8000000000));
REQUIRE(osmium::memory::padded_length(static_cast<std::size_t>(8000000000)) == static_cast<std::size_t>(8000000000));
REQUIRE(osmium::memory::padded_length(static_cast<std::size_t>(8000000001)) == static_cast<std::size_t>(8000000008));
}
@@ -0,0 +1,72 @@
#include "catch.hpp"
#include <osmium/memory/item_iterator.hpp>
#include <osmium/osm.hpp>
static_assert(osmium::memory::detail::type_is_compatible<osmium::Node>(osmium::item_type::node), "");
static_assert(!osmium::memory::detail::type_is_compatible<osmium::Way>(osmium::item_type::node), "");
static_assert(!osmium::memory::detail::type_is_compatible<osmium::Relation>(osmium::item_type::node), "");
static_assert(!osmium::memory::detail::type_is_compatible<osmium::Area>(osmium::item_type::node), "");
static_assert(osmium::memory::detail::type_is_compatible<osmium::OSMObject>(osmium::item_type::node), "");
static_assert(!osmium::memory::detail::type_is_compatible<osmium::Changeset>(osmium::item_type::node), "");
static_assert(osmium::memory::detail::type_is_compatible<osmium::OSMEntity>(osmium::item_type::node), "");
static_assert(osmium::memory::detail::type_is_compatible<osmium::memory::Item>(osmium::item_type::node), "");
static_assert(!osmium::memory::detail::type_is_compatible<osmium::Node>(osmium::item_type::way), "");
static_assert(osmium::memory::detail::type_is_compatible<osmium::Way>(osmium::item_type::way), "");
static_assert(!osmium::memory::detail::type_is_compatible<osmium::Relation>(osmium::item_type::way), "");
static_assert(!osmium::memory::detail::type_is_compatible<osmium::Area>(osmium::item_type::way), "");
static_assert(osmium::memory::detail::type_is_compatible<osmium::OSMObject>(osmium::item_type::way), "");
static_assert(!osmium::memory::detail::type_is_compatible<osmium::Changeset>(osmium::item_type::way), "");
static_assert(osmium::memory::detail::type_is_compatible<osmium::OSMEntity>(osmium::item_type::way), "");
static_assert(osmium::memory::detail::type_is_compatible<osmium::memory::Item>(osmium::item_type::way), "");
static_assert(!osmium::memory::detail::type_is_compatible<osmium::Node>(osmium::item_type::relation), "");
static_assert(!osmium::memory::detail::type_is_compatible<osmium::Way>(osmium::item_type::relation), "");
static_assert(osmium::memory::detail::type_is_compatible<osmium::Relation>(osmium::item_type::relation), "");
static_assert(!osmium::memory::detail::type_is_compatible<osmium::Area>(osmium::item_type::relation), "");
static_assert(osmium::memory::detail::type_is_compatible<osmium::OSMObject>(osmium::item_type::relation), "");
static_assert(!osmium::memory::detail::type_is_compatible<osmium::Changeset>(osmium::item_type::relation), "");
static_assert(osmium::memory::detail::type_is_compatible<osmium::OSMEntity>(osmium::item_type::relation), "");
static_assert(osmium::memory::detail::type_is_compatible<osmium::memory::Item>(osmium::item_type::relation), "");
static_assert(!osmium::memory::detail::type_is_compatible<osmium::Node>(osmium::item_type::area), "");
static_assert(!osmium::memory::detail::type_is_compatible<osmium::Way>(osmium::item_type::area), "");
static_assert(!osmium::memory::detail::type_is_compatible<osmium::Relation>(osmium::item_type::area), "");
static_assert(osmium::memory::detail::type_is_compatible<osmium::Area>(osmium::item_type::area), "");
static_assert(osmium::memory::detail::type_is_compatible<osmium::OSMObject>(osmium::item_type::area), "");
static_assert(!osmium::memory::detail::type_is_compatible<osmium::Changeset>(osmium::item_type::area), "");
static_assert(osmium::memory::detail::type_is_compatible<osmium::OSMEntity>(osmium::item_type::area), "");
static_assert(osmium::memory::detail::type_is_compatible<osmium::memory::Item>(osmium::item_type::area), "");
static_assert(!osmium::memory::detail::type_is_compatible<osmium::Node>(osmium::item_type::changeset), "");
static_assert(!osmium::memory::detail::type_is_compatible<osmium::Way>(osmium::item_type::changeset), "");
static_assert(!osmium::memory::detail::type_is_compatible<osmium::Relation>(osmium::item_type::changeset), "");
static_assert(!osmium::memory::detail::type_is_compatible<osmium::Area>(osmium::item_type::changeset), "");
static_assert(!osmium::memory::detail::type_is_compatible<osmium::OSMObject>(osmium::item_type::changeset), "");
static_assert(osmium::memory::detail::type_is_compatible<osmium::Changeset>(osmium::item_type::changeset), "");
static_assert(osmium::memory::detail::type_is_compatible<osmium::OSMEntity>(osmium::item_type::changeset), "");
static_assert(osmium::memory::detail::type_is_compatible<osmium::memory::Item>(osmium::item_type::changeset), "");
static_assert(osmium::memory::detail::type_is_compatible<osmium::OuterRing>(osmium::item_type::outer_ring), "");
static_assert(osmium::memory::detail::type_is_compatible<osmium::InnerRing>(osmium::item_type::inner_ring), "");
static_assert(osmium::memory::detail::type_is_compatible<osmium::WayNodeList>(osmium::item_type::way_node_list), "");
static_assert(!osmium::memory::detail::type_is_compatible<osmium::OuterRing>(osmium::item_type::inner_ring), "");
static_assert(!osmium::memory::detail::type_is_compatible<osmium::InnerRing>(osmium::item_type::outer_ring), "");
static_assert(!osmium::memory::detail::type_is_compatible<osmium::WayNodeList>(osmium::item_type::outer_ring), "");
static_assert(osmium::memory::detail::type_is_compatible<osmium::TagList>(osmium::item_type::tag_list), "");
static_assert(osmium::memory::detail::type_is_compatible<osmium::InnerRing>(osmium::item_type::inner_ring), "");
static_assert(!osmium::memory::detail::type_is_compatible<osmium::TagList>(osmium::item_type::inner_ring), "");
static_assert(!osmium::memory::detail::type_is_compatible<osmium::InnerRing>(osmium::item_type::tag_list), "");
static_assert(osmium::memory::detail::type_is_compatible<osmium::RelationMemberList>(osmium::item_type::relation_member_list), "");
static_assert(osmium::memory::detail::type_is_compatible<osmium::RelationMemberList>(osmium::item_type::relation_member_list_with_full_members), "");
static_assert(!osmium::memory::detail::type_is_compatible<osmium::RelationMemberList>(osmium::item_type::tag_list), "");
static_assert(osmium::memory::detail::type_is_compatible<osmium::ChangesetDiscussion>(osmium::item_type::changeset_discussion), "");
static_assert(!osmium::memory::detail::type_is_compatible<osmium::ChangesetDiscussion>(osmium::item_type::relation_member_list), "");