Update in-tree libosmium dependency to 2.5.4

The latest releases have some critical fixes, see the changelog:
https://github.com/osmcode/libosmium/blob/v2.5.4/CHANGELOG.md

Merge commit 'afdf8e7b21fbaf597e91d9d8a7542635e60ee9a1' into use_libosmium_2_5_4
This commit is contained in:
Daniel J. Hofmann
2016-01-05 12:00:40 +01:00
171 changed files with 7150 additions and 3988 deletions
+236 -49
View File
@@ -46,6 +46,7 @@ DEALINGS IN THE SOFTWARE.
#include <osmium/memory/item.hpp>
#include <osmium/memory/item_iterator.hpp>
#include <osmium/osm/entity.hpp>
#include <osmium/util/compatibility.hpp>
namespace osmium {
@@ -89,12 +90,17 @@ namespace osmium {
*
* By default, if a buffer gets full it will throw a buffer_is_full exception.
* You can use the set_full_callback() method to set a callback functor
* which will be called instead of throwing an exception.
* which will be called instead of throwing an exception. The full
* callback functionality is deprecated and will be removed in the
* future. See the documentation for set_full_callback() for alternatives.
*/
class Buffer {
public:
// This is needed so we can call std::back_inserter() on a Buffer.
using value_type = Item;
enum class auto_grow : bool {
yes = true,
no = false
@@ -112,12 +118,13 @@ namespace osmium {
public:
typedef Item value_type;
/**
* The constructor without any parameters creates a non-initialized
* The constructor without any parameters creates an invalid,
* buffer, ie an empty hull of a buffer that has no actual memory
* associated with it. It can be used to signify end-of-input.
* associated with it. It can be used to signify end-of-data.
*
* Most methods of the Buffer class will not work with an invalid
* buffer.
*/
Buffer() noexcept :
m_memory(),
@@ -128,12 +135,14 @@ namespace osmium {
}
/**
* Constructs an externally memory-managed buffer using the given
* memory and size.
* Constructs a valid externally memory-managed buffer using the
* given memory and size.
*
* @param data A pointer to some already initialized data.
* @param size The size of the initialized data.
* @throws std::invalid_argument When the size isn't a multiple of the alignment.
*
* @throws std::invalid_argument if the size isn't a multiple of
* the alignment.
*/
explicit Buffer(unsigned char* data, size_t size) :
m_memory(),
@@ -147,13 +156,15 @@ namespace osmium {
}
/**
* Constructs an externally memory-managed buffer with the given
* capacity that already contains 'committed' bytes of data.
* Constructs a valid externally memory-managed buffer with the
* given capacity that already contains 'committed' bytes of data.
*
* @param data A pointer to some (possibly initialized) data.
* @param capacity The size of the memory for this buffer.
* @param committed The size of the initialized data. If this is 0, the buffer startes out empty.
* @throws std::invalid_argument When the capacity or committed isn't a multiple of the alignment.
*
* @throws std::invalid_argument if the capacity or committed isn't
* a multiple of the alignment.
*/
explicit Buffer(unsigned char* data, size_t capacity, size_t committed) :
m_memory(),
@@ -170,10 +181,18 @@ namespace osmium {
}
/**
* Create an internally memory-managed buffer with the given capacity.
* different in that it internally gets dynamic memory of the
* required size. The dynamic memory will be automatically
* freed when the Buffer is destroyed.
* Constructs a valid internally memory-managed buffer with the
* given capacity.
* Will internally get dynamic memory of the required size.
* The dynamic memory will be automatically freed when the Buffer
* is destroyed.
*
* @param capacity The (initial) size of the memory for this buffer.
* @param auto_grow Should this buffer automatically grow when it
* becomes to small?
*
* @throws std::invalid_argument if the capacity isn't a multiple
* of the alignment.
*/
explicit Buffer(size_t capacity, auto_grow auto_grow = auto_grow::yes) :
m_memory(capacity),
@@ -199,13 +218,17 @@ namespace osmium {
/**
* Return a pointer to data inside the buffer.
*
* @pre The buffer must be valid.
*/
unsigned char* data() const noexcept {
assert(m_data);
return m_data;
}
/**
* Returns the capacity of the buffer, ie how many bytes it can contain.
* Returns the capacity of the buffer, ie how many bytes it can
* contain. Always returns 0 on invalid buffers.
*/
size_t capacity() const noexcept {
return m_capacity;
@@ -213,6 +236,7 @@ namespace osmium {
/**
* Returns the number of bytes already filled in this buffer.
* Always returns 0 on invalid buffers.
*/
size_t committed() const noexcept {
return m_committed;
@@ -221,6 +245,7 @@ namespace osmium {
/**
* Returns the number of bytes currently filled in this buffer that
* are not yet committed.
* Always returns 0 on invalid buffers.
*/
size_t written() const noexcept {
return m_written;
@@ -229,28 +254,57 @@ namespace osmium {
/**
* This tests if the current state of the buffer is aligned
* properly. Can be used for asserts.
*
* @pre The buffer must be valid.
*/
bool is_aligned() const noexcept {
assert(m_data);
return (m_written % align_bytes == 0) && (m_committed % align_bytes == 0);
}
/**
* Set functor to be called whenever the buffer is full
* instead of throwing buffer_is_full.
*
* The behaviour is undefined if you call this on an invalid
* buffer.
*
* @pre The buffer must be valid.
*
* @deprecated
* Callback functionality will be removed in the future. Either
* detect the buffer_is_full exception or use a buffer with
* auto_grow::yes. If you want to avoid growing buffers, check
* that the used size of the buffer (committed()) is small enough
* compared to the capacity (for instance small than 90% of the
* capacity) before adding anything to the Buffer. If the buffer
* is initialized with auto_grow::yes, it will still grow in the
* rare case that a very large object will be added taking more
* than the difference between committed() and capacity().
*/
void set_full_callback(std::function<void(Buffer&)> full) {
OSMIUM_DEPRECATED void set_full_callback(std::function<void(Buffer&)> full) {
assert(m_data);
m_full = full;
}
/**
* Grow capacity of this buffer to the given size.
* This works only with internally memory-managed buffers.
* If the given size is not larger than the current capacity, nothing is done.
* If the given size is not larger than the current capacity,
* nothing is done.
* Already written but not committed data is discarded.
*
* @pre The buffer must be valid.
*
* @param size New capacity.
*
* @throws std::logic_error if the buffer doesn't use internal
* memory management.
* @throws std::invalid_argument if the size isn't a multiple
* of the alignment.
*/
void grow(size_t size) {
assert(m_data);
if (m_memory.empty()) {
throw std::logic_error("Can't grow Buffer if it doesn't use internal memory management.");
}
@@ -267,9 +321,15 @@ namespace osmium {
/**
* Mark currently written bytes in the buffer as committed.
*
* @returns Last number of committed bytes before this commit.
* @pre The buffer must be valid and aligned properly (as indicated
* by is_aligned().
*
* @returns Number of committed bytes before this commit. Can be
* used as an offset into the buffer to get to the
* object being committed by this call.
*/
size_t commit() {
assert(m_data);
assert(is_aligned());
const size_t offset = m_committed;
@@ -279,14 +339,19 @@ namespace osmium {
/**
* Roll back changes in buffer to last committed state.
*
* @pre The buffer must be valid.
*/
void rollback() {
assert(m_data);
m_written = m_committed;
}
/**
* Clear the buffer.
*
* No-op on an invalid buffer.
*
* @returns Number of bytes in the buffer before it was cleared.
*/
size_t clear() {
@@ -299,11 +364,16 @@ namespace osmium {
/**
* Get the data in the buffer at the given offset.
*
* @pre The buffer must be valid.
*
* @tparam T Type we want to the data to be interpreted as.
* @returns Reference of given type pointing to the data in the buffer.
*
* @returns Reference of given type pointing to the data in the
* buffer.
*/
template <class T>
template <typename T>
T& get(const size_t offset) const {
assert(m_data);
return *reinterpret_cast<T*>(&m_data[offset]);
}
@@ -320,23 +390,35 @@ namespace osmium {
*
* * If you have set a callback with set_full_callback(), it is
* called. After the call returns, you must have either grown
* the buffer or cleared it by calling buffer.clear().
* the buffer or cleared it by calling buffer.clear(). (Usage
* of the full callback is deprecated and this functionality
* will be removed in the future. See the documentation for
* set_full_callback() for alternatives.
* * If no callback is defined and this buffer uses internal
* memory management, the buffers capacity is grown, so that
* the new data will fit.
* * Else the buffer_is_full exception is thrown.
*
* @pre The buffer must be valid.
*
* @param size Number of bytes to reserve.
*
* @returns Pointer to reserved space. Note that this pointer is
* only guaranteed to be valid until the next call to
* reserve_space().
* @throws osmium::buffer_is_full Might be thrown if the buffer is full.
* only guaranteed to be valid until the next call to
* reserve_space().
*
* @throws osmium::buffer_is_full if the buffer is full there is
* no callback defined and the buffer isn't auto-growing.
*/
unsigned char* reserve_space(const size_t size) {
assert(m_data);
// try to flush the buffer empty first.
if (m_written + size > m_capacity && m_full) {
m_full(*this);
}
// if there's still not enough space, then try growing the buffer.
if (m_written + size > m_capacity) {
if (m_full) {
m_full(*this);
} else if (!m_memory.empty() && (m_auto_grow == auto_grow::yes)) {
if (!m_memory.empty() && (m_auto_grow == auto_grow::yes)) {
// double buffer size until there is enough space
size_t new_capacity = m_capacity * 2;
while (m_written + size > new_capacity) {
@@ -359,12 +441,17 @@ namespace osmium {
* Note that you have to eventually call commit() to actually
* commit this data.
*
* @pre The buffer must be valid.
*
* @tparam T Class of the item to be copied.
*
* @param item Reference to the item to be copied.
*
* @returns Reference to newly copied data in the buffer.
*/
template <class T>
template <typename T>
T& add_item(const T& item) {
assert(m_data);
unsigned char* target = reserve_space(item.padded_size());
std::copy_n(reinterpret_cast<const unsigned char*>(&item), item.padded_size(), target);
return *reinterpret_cast<T*>(target);
@@ -373,91 +460,176 @@ namespace osmium {
/**
* Add committed contents of the given buffer to this buffer.
*
* @pre The buffer must be valid.
*
* Note that you have to eventually call commit() to actually
* commit this data.
*
* @param buffer The source of the copy. Must be valid.
*/
void add_buffer(const Buffer& buffer) {
assert(m_data && buffer);
unsigned char* target = reserve_space(buffer.committed());
std::copy_n(reinterpret_cast<const unsigned char*>(buffer.data()), buffer.committed(), target);
std::copy_n(buffer.data(), buffer.committed(), target);
}
/**
* Add an item to the buffer. This function is provided so that
* you can use std::back_inserter.
*
* @pre The buffer must be valid.
*
* @param item The item to be added.
*/
void push_back(const osmium::memory::Item& item) {
assert(m_data);
add_item(item);
commit();
}
/**
* These iterators can be used to iterate over all items in
* a buffer.
* An iterator that can be used to iterate over all items of
* type T in a buffer.
*/
template <class T>
template <typename T>
using t_iterator = osmium::memory::ItemIterator<T>;
template <class T>
/**
* A const iterator that can be used to iterate over all items of
* type T in a buffer.
*/
template <typename T>
using t_const_iterator = osmium::memory::ItemIterator<const T>;
typedef t_iterator<osmium::OSMEntity> iterator;
typedef t_const_iterator<osmium::OSMEntity> const_iterator;
/**
* An iterator that can be used to iterate over all OSMEntity
* objects in a buffer.
*/
using iterator = t_iterator<osmium::OSMEntity>;
template <class T>
/**
* A const iterator that can be used to iterate over all OSMEntity
* objects in a buffer.
*/
using const_iterator = t_const_iterator<osmium::OSMEntity>;
/**
* Get iterator for iterating over all items of type T in the
* buffer.
*
* @pre The buffer must be valid.
*
* @returns Iterator to first item of type T in the buffer.
*/
template <typename T>
t_iterator<T> begin() {
assert(m_data);
return t_iterator<T>(m_data, m_data + m_committed);
}
/**
* Get iterator for iterating over all objects of class OSMEntity
* in the buffer.
*
* @pre The buffer must be valid.
*
* @returns Iterator to first OSMEntity in the buffer.
*/
iterator begin() {
assert(m_data);
return iterator(m_data, m_data + m_committed);
}
template <class T>
/**
* Get iterator for iterating over all items of type T in the
* buffer.
*
* @pre The buffer must be valid.
*
* @returns Iterator to first item of type T after given offset
* in the buffer.
*/
template <typename T>
t_iterator<T> get_iterator(size_t offset) {
assert(m_data);
return t_iterator<T>(m_data + offset, m_data + m_committed);
}
/**
* Get iterator for iterating over all objects of class OSMEntity
* in the buffer.
*
* @pre The buffer must be valid.
*
* @returns Iterator to first OSMEntity after given offset in the
* buffer.
*/
iterator get_iterator(size_t offset) {
assert(m_data);
return iterator(m_data + offset, m_data + m_committed);
}
template <class T>
/**
* Get iterator for iterating over all items of type T in the
* buffer.
*
* @pre The buffer must be valid.
*
* @returns End iterator.
*/
template <typename T>
t_iterator<T> end() {
assert(m_data);
return t_iterator<T>(m_data + m_committed, m_data + m_committed);
}
/**
* Get iterator for iterating over all objects of class OSMEntity
* in the buffer.
*
* @pre The buffer must be valid.
*
* @returns End iterator.
*/
iterator end() {
assert(m_data);
return iterator(m_data + m_committed, m_data + m_committed);
}
template <class T>
template <typename T>
t_const_iterator<T> cbegin() const {
assert(m_data);
return t_const_iterator<T>(m_data, m_data + m_committed);
}
const_iterator cbegin() const {
assert(m_data);
return const_iterator(m_data, m_data + m_committed);
}
template <class T>
template <typename T>
t_const_iterator<T> get_iterator(size_t offset) const {
assert(m_data);
return t_const_iterator<T>(m_data + offset, m_data + m_committed);
}
const_iterator get_iterator(size_t offset) const {
assert(m_data);
return const_iterator(m_data + offset, m_data + m_committed);
}
template <class T>
template <typename T>
t_const_iterator<T> cend() const {
assert(m_data);
return t_const_iterator<T>(m_data + m_committed, m_data + m_committed);
}
const_iterator cend() const {
assert(m_data);
return const_iterator(m_data + m_committed, m_data + m_committed);
}
template <class T>
template <typename T>
t_const_iterator<T> begin() const {
return cbegin<T>();
}
@@ -466,7 +638,7 @@ namespace osmium {
return cbegin();
}
template <class T>
template <typename T>
t_const_iterator<T> end() const {
return cend<T>();
}
@@ -476,9 +648,9 @@ namespace osmium {
}
/**
* In a bool context any initialized buffer is true.
* In a bool context any valid buffer is true.
*/
explicit operator bool() const {
explicit operator bool() const noexcept {
return m_data != nullptr;
}
@@ -490,6 +662,8 @@ namespace osmium {
swap(lhs.m_capacity, rhs.m_capacity);
swap(lhs.m_written, rhs.m_written);
swap(lhs.m_committed, rhs.m_committed);
swap(lhs.m_auto_grow, rhs.m_auto_grow);
swap(lhs.m_full, rhs.m_full);
}
/**
@@ -497,17 +671,20 @@ namespace osmium {
* non-removed items forward in the buffer overwriting removed
* items and then correcting the m_written and m_committed numbers.
*
* Note that calling this function invalidates all iterators on this
* buffer and all offsets in this buffer.
* Note that calling this function invalidates all iterators on
* this buffer and all offsets in this buffer.
*
* For every non-removed item that moves its position, the function
* 'moving_in_buffer' is called on the given callback object with
* the old and new offsets in the buffer where the object used to
* be and is now, respectively. This call can be used to update any
* indexes.
*
* @pre The buffer must be valid.
*/
template <class TCallbackClass>
template <typename TCallbackClass>
void purge_removed(TCallbackClass* callback) {
assert(m_data);
if (begin() == end()) {
return;
}
@@ -537,7 +714,17 @@ namespace osmium {
}; // class Buffer
/**
* Compare two buffers for equality.
*
* Buffers are equal if they are both invalid or if they are both
* valid and have the same data pointer, capacity and committed
* data.
*/
inline bool operator==(const Buffer& lhs, const Buffer& rhs) noexcept {
if (!lhs || !rhs) {
return !lhs && !rhs;
}
return lhs.data() == rhs.data() && lhs.capacity() == rhs.capacity() && lhs.committed() == rhs.committed();
}
+3 -3
View File
@@ -43,7 +43,7 @@ namespace osmium {
namespace memory {
template <class TMember>
template <typename TMember>
class CollectionIterator : public std::iterator<std::forward_iterator_tag, TMember> {
// This data_type is either 'unsigned char*' or 'const unsigned char*' depending
@@ -59,7 +59,7 @@ namespace osmium {
m_data(nullptr) {
}
CollectionIterator(data_type data) noexcept :
explicit CollectionIterator(data_type data) noexcept :
m_data(data) {
}
@@ -101,7 +101,7 @@ namespace osmium {
}; // class CollectionIterator
template <class TMember, osmium::item_type TCollectionItemType>
template <typename TMember, osmium::item_type TCollectionItemType>
class Collection : public Item {
public:
+3 -3
View File
@@ -43,7 +43,7 @@ namespace osmium {
namespace builder {
class Builder;
}
} // namespace builder
namespace memory {
@@ -102,10 +102,10 @@ namespace osmium {
uint16_t m_removed : 1;
uint16_t m_padding : 15;
template <class TMember>
template <typename TMember>
friend class CollectionIterator;
template <class TMember>
template <typename TMember>
friend class ItemIterator;
friend class osmium::builder::Builder;
@@ -38,29 +38,17 @@ DEALINGS IN THE SOFTWARE.
#include <iosfwd>
#include <type_traits>
#include <osmium/fwd.hpp>
#include <osmium/memory/item.hpp>
#include <osmium/osm/item_type.hpp>
namespace osmium {
class Node;
class Way;
class Relation;
class Area;
class Changeset;
class OSMObject;
class OSMEntity;
class TagList;
class WayNodeList;
class RelationMemberList;
class InnerRing;
class OuterRing;
namespace memory {
namespace detail {
template <class T>
template <typename T>
inline bool type_is_compatible(osmium::item_type) noexcept {
return true;
}
@@ -127,7 +115,7 @@ namespace osmium {
} // namespace detail
template <class TMember>
template <typename TMember>
class ItemIterator : public std::iterator<std::forward_iterator_tag, TMember> {
static_assert(std::is_base_of<osmium::memory::Item, TMember>::value, "TMember must derive from osmium::memory::Item");
@@ -160,7 +148,7 @@ namespace osmium {
advance_to_next_item_of_right_type();
}
template <class T>
template <typename T>
ItemIterator<T> cast() const {
return ItemIterator<T>(m_data, m_end);
}
@@ -217,7 +205,7 @@ namespace osmium {
}
explicit operator bool() const {
return m_data != nullptr;
return (m_data != nullptr) && (m_data != m_end);
}
template <typename TChar, typename TTraits>