[libosmium] 01/04: Imported Upstream version 2.5.3
Sebastiaan Couwenberg
sebastic at moszumanska.debian.org
Wed Nov 18 21:54:19 UTC 2015
This is an automated email from the git hooks/post-receive script.
sebastic pushed a commit to branch master
in repository libosmium.
commit eec33478f11b5535dcf3587595aa1e3ea2b8bb02
Author: Bas Couwenberg <sebastic at xs4all.nl>
Date: Wed Nov 18 22:36:47 2015 +0100
Imported Upstream version 2.5.3
---
CHANGELOG.md | 21 ++-
CMakeLists.txt | 2 +-
include/osmium/area/multipolygon_collector.hpp | 22 ---
include/osmium/diff_handler.hpp | 3 +-
include/osmium/diff_iterator.hpp | 35 ++--
include/osmium/diff_visitor.hpp | 2 +-
include/osmium/io/output_iterator.hpp | 13 +-
include/osmium/memory/buffer.hpp | 231 +++++++++++++++++++------
include/osmium/memory/item_iterator.hpp | 16 +-
include/osmium/osm/diff_object.hpp | 140 ++++++++++++---
include/osmium/osm/item_type.hpp | 8 +
include/osmium/osm/node_ref.hpp | 74 +++++++-
include/osmium/osm/node_ref_list.hpp | 29 ++--
include/osmium/osm/timestamp.hpp | 66 +++++--
include/osmium/osm/types_from_string.hpp | 67 +++++++
include/osmium/relations/collector.hpp | 159 +++++++++--------
include/osmium/util/data_file.hpp | 194 ---------------------
include/osmium/util/memory_mapping.hpp | 25 ++-
include/osmium/util/options.hpp | 66 +++++--
include/osmium/visitor.hpp | 7 +-
test/CMakeLists.txt | 1 -
test/t/basic/test_object_comparisons.cpp | 44 ++---
test/t/basic/test_timestamp.cpp | 17 +-
test/t/buffer/test_buffer_node.cpp | 44 ++++-
test/t/util/test_data_file.cpp | 81 ---------
test/t/util/test_options.cpp | 30 +++-
26 files changed, 813 insertions(+), 584 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 781a04a..70d77bc 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -13,6 +13,24 @@ This project adheres to [Semantic Versioning](http://semver.org/).
### Fixed
+## [2.5.3] - 2015-11-17
+
+### Added
+
+- osmium::make_diff_iterator() helper function.
+
+### Changed
+
+- Deprecated osmium::Buffer::set_full_callback().
+- Removed DataFile class which was never used anywhere.
+- Removed unused and obscure Buffer::value_type typedef.
+
+### Fixed
+
+- Possible overrun in Buffer when using the full-callback.
+- Incorrect swapping of Buffer.
+
+
## [2.5.2] - 2015-11-06
# Fixed
@@ -196,7 +214,8 @@ This project adheres to [Semantic Versioning](http://semver.org/).
Doxygen (up to version 1.8.8). This version contains a workaround to fix
this.
-[unreleased]: https://github.com/osmcode/libosmium/compare/v2.5.2...HEAD
+[unreleased]: https://github.com/osmcode/libosmium/compare/v2.5.3...HEAD
+[2.5.3]: https://github.com/osmcode/libosmium/compare/v2.5.1...v2.5.3
[2.5.2]: https://github.com/osmcode/libosmium/compare/v2.5.1...v2.5.2
[2.5.1]: https://github.com/osmcode/libosmium/compare/v2.5.0...v2.5.1
[2.5.0]: https://github.com/osmcode/libosmium/compare/v2.4.1...v2.5.0
diff --git a/CMakeLists.txt b/CMakeLists.txt
index f28e2aa..fc3e97e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -27,7 +27,7 @@ project(libosmium)
set(LIBOSMIUM_VERSION_MAJOR 2)
set(LIBOSMIUM_VERSION_MINOR 5)
-set(LIBOSMIUM_VERSION_PATCH 2)
+set(LIBOSMIUM_VERSION_PATCH 3)
set(LIBOSMIUM_VERSION
"${LIBOSMIUM_VERSION_MAJOR}.${LIBOSMIUM_VERSION_MINOR}.${LIBOSMIUM_VERSION_PATCH}")
diff --git a/include/osmium/area/multipolygon_collector.hpp b/include/osmium/area/multipolygon_collector.hpp
index c4155db..d3ca10f 100644
--- a/include/osmium/area/multipolygon_collector.hpp
+++ b/include/osmium/area/multipolygon_collector.hpp
@@ -177,28 +177,6 @@ namespace osmium {
} catch (osmium::invalid_location&) {
// XXX ignore
}
-
- // clear member metas
- for (const auto& member : relation.members()) {
- if (member.ref() != 0) {
- auto& mmv = this->member_meta(member.type());
- auto range = std::equal_range(mmv.begin(), mmv.end(), osmium::relations::MemberMeta(member.ref()));
- assert(range.first != range.second);
-
- // if this is the last time this object was needed
- // then mark it as removed
- if (osmium::relations::count_not_removed(range.first, range.second) == 1) {
- this->get_member(range.first->buffer_offset()).set_removed(true);
- }
-
- for (auto it = range.first; it != range.second; ++it) {
- if (!it->removed() && relation.id() == this->get_relation(it->relation_pos()).id()) {
- it->remove();
- break;
- }
- }
- }
- }
}
void flush() {
diff --git a/include/osmium/diff_handler.hpp b/include/osmium/diff_handler.hpp
index 4f9b3a1..06d8a93 100644
--- a/include/osmium/diff_handler.hpp
+++ b/include/osmium/diff_handler.hpp
@@ -46,8 +46,7 @@ namespace osmium {
public:
- DiffHandler() {
- }
+ DiffHandler() = default;
void node(const osmium::DiffNode&) const {
}
diff --git a/include/osmium/diff_iterator.hpp b/include/osmium/diff_iterator.hpp
index ae80afb..6725fec 100644
--- a/include/osmium/diff_iterator.hpp
+++ b/include/osmium/diff_iterator.hpp
@@ -43,6 +43,11 @@ namespace osmium {
class OSMObject;
+ /**
+ * An input iterator wrapping any iterator over OSMObjects. When
+ * dereferenced it will yield DiffObject objects pointing to the
+ * underlying OSMObjects.
+ */
template <typename TBasicIterator>
class DiffIterator : public std::iterator<std::input_iterator_tag, const osmium::DiffObject> {
@@ -56,7 +61,7 @@ namespace osmium {
mutable osmium::DiffObject m_diff;
- void set_diff() const {
+ void set_diff() const noexcept {
assert(m_curr != m_end);
bool use_curr_for_prev = m_prev->type() != m_curr->type() || m_prev->id() != m_curr->id();
@@ -71,19 +76,14 @@ namespace osmium {
public:
- explicit DiffIterator(TBasicIterator begin, TBasicIterator end) :
+ DiffIterator(TBasicIterator begin, TBasicIterator end) :
m_prev(begin),
m_curr(begin),
m_next(begin == end ? begin : ++begin),
- m_end(std::move(end)) {
+ m_end(std::move(end)),
+ m_diff() {
}
- DiffIterator(const DiffIterator&) = default;
- DiffIterator& operator=(const DiffIterator&) = default;
-
- DiffIterator(DiffIterator&&) = default;
- DiffIterator& operator=(DiffIterator&&) = default;
-
DiffIterator& operator++() {
m_prev = std::move(m_curr);
m_curr = m_next;
@@ -101,26 +101,35 @@ namespace osmium {
return tmp;
}
- bool operator==(const DiffIterator& rhs) const {
+ bool operator==(const DiffIterator& rhs) const noexcept {
return m_curr == rhs.m_curr && m_end == rhs.m_end;
}
- bool operator!=(const DiffIterator& rhs) const {
+ bool operator!=(const DiffIterator& rhs) const noexcept {
return !(*this == rhs);
}
- reference operator*() const {
+ reference operator*() const noexcept {
set_diff();
return m_diff;
}
- pointer operator->() const {
+ pointer operator->() const noexcept {
set_diff();
return &m_diff;
}
}; // class DiffIterator
+ /**
+ * Create a DiffIterator based on the given iterators.
+ */
+ template <typename TBasicIterator>
+ inline DiffIterator<TBasicIterator> make_diff_iterator(TBasicIterator begin,
+ TBasicIterator end) {
+ return DiffIterator<TBasicIterator>{begin, end};
+ }
+
} // namespace osmium
#endif // OSMIUM_DIFF_ITERATOR_HPP
diff --git a/include/osmium/diff_visitor.hpp b/include/osmium/diff_visitor.hpp
index e7dc576..ac16a8e 100644
--- a/include/osmium/diff_visitor.hpp
+++ b/include/osmium/diff_visitor.hpp
@@ -70,7 +70,7 @@ namespace osmium {
template <typename TIterator, typename... THandlers>
inline void apply_diff(TIterator it, TIterator end, THandlers&... handlers) {
- typedef osmium::DiffIterator<TIterator> diff_iterator;
+ using diff_iterator = osmium::DiffIterator<TIterator>;
diff_iterator dit(it, end);
diff_iterator dend(end, end);
diff --git a/include/osmium/io/output_iterator.hpp b/include/osmium/io/output_iterator.hpp
index 3d60fe6..1cf1d1d 100644
--- a/include/osmium/io/output_iterator.hpp
+++ b/include/osmium/io/output_iterator.hpp
@@ -62,7 +62,8 @@ namespace osmium {
}
/**
- * Warning! Use of buffer size argument on OutputIterator
+ * @deprecated
+ * Use of buffer size argument on OutputIterator
* constructor is deprecated. Call Writer::set_buffer_size()
* instead if you want to change the default.
*/
@@ -80,7 +81,8 @@ namespace osmium {
~OutputIterator() = default;
/**
- * Warning! Calling OutputIterator<Writer>::flush() is usually not
+ * @deprecated
+ * Calling OutputIterator<Writer>::flush() is usually not
* needed any more. Call flush() on the Writer instead if needed.
*/
OSMIUM_DEPRECATED void flush() {
@@ -116,9 +118,10 @@ namespace osmium {
}
/**
- * Warning! Use of buffer size argument on make_output_iterator is
- * deprecated. Call Writer::set_buffer_size() instead if you want to
- * change the default.
+ * @deprecated
+ * Use of buffer size argument on make_output_iterator is deprecated.
+ * Call Writer::set_buffer_size() instead if you want to change the
+ * default.
*/
template <typename TDest>
OSMIUM_DEPRECATED OutputIterator<TDest> make_output_iterator(TDest& destination, const size_t buffer_size) {
diff --git a/include/osmium/memory/buffer.hpp b/include/osmium/memory/buffer.hpp
index 11a4c97..ce8c587 100644
--- a/include/osmium/memory/buffer.hpp
+++ b/include/osmium/memory/buffer.hpp
@@ -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,7 +90,9 @@ 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 {
@@ -112,12 +115,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-data.
+ *
+ * Most methods of the Buffer class will not work with an invalid
+ * buffer.
*/
Buffer() noexcept :
m_memory(),
@@ -128,12 +132,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 +153,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 +178,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,6 +215,8 @@ namespace osmium {
/**
* Return a pointer to data inside the buffer.
+ *
+ * @pre The buffer must be valid.
*/
unsigned char* data() const noexcept {
assert(m_data);
@@ -206,8 +224,8 @@ namespace osmium {
}
/**
- * Returns the capacity of the buffer, ie how many bytes it can contain.
- * Always returns 0 on invalid buffers.
+ * 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;
@@ -234,8 +252,7 @@ namespace osmium {
* This tests if the current state of the buffer is aligned
* properly. Can be used for asserts.
*
- * The behaviour is undefined if you call this on an invalid
- * buffer.
+ * @pre The buffer must be valid.
*/
bool is_aligned() const noexcept {
assert(m_data);
@@ -248,8 +265,21 @@ namespace osmium {
*
* 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;
}
@@ -257,13 +287,18 @@ namespace osmium {
/**
* 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.
*
- * The behaviour is undefined if you call this on an invalid
- * buffer.
+ * @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);
@@ -283,10 +318,12 @@ namespace osmium {
/**
* Mark currently written bytes in the buffer as committed.
*
- * The behaviour is undefined if you call this on an invalid
- * buffer.
+ * @pre The buffer must be valid and aligned properly (as indicated
+ * by is_aligned().
*
- * @returns Last number of committed bytes before this commit.
+ * @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);
@@ -300,8 +337,7 @@ namespace osmium {
/**
* Roll back changes in buffer to last committed state.
*
- * The behaviour is undefined if you call this on an invalid
- * buffer.
+ * @pre The buffer must be valid.
*/
void rollback() {
assert(m_data);
@@ -325,11 +361,12 @@ namespace osmium {
/**
* Get the data in the buffer at the given offset.
*
- * The behaviour is undefined if you call this on an invalid
- * buffer.
+ * @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 <typename T>
T& get(const size_t offset) const {
@@ -350,27 +387,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.
*
- * The behaviour is undefined if you call this on an invalid
- * buffer.
+ * @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) {
@@ -393,11 +438,12 @@ namespace osmium {
* Note that you have to eventually call commit() to actually
* commit this data.
*
- * The behaviour is undefined if you call this on an invalid
- * buffer.
+ * @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 <typename T>
@@ -411,24 +457,26 @@ namespace osmium {
/**
* Add committed contents of the given buffer to this buffer.
*
- * The behaviour is undefined if you call this on an invalid
- * 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);
+ 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.
*
- * The behaviour is undefined if you call this on an invalid
- * buffer.
+ * @pre The buffer must be valid.
+ *
+ * @param item The item to be added.
*/
void push_back(const osmium::memory::Item& item) {
assert(m_data);
@@ -437,46 +485,109 @@ namespace osmium {
}
/**
- * 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 <typename T>
using t_iterator = osmium::memory::ItemIterator<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>;
+
+ /**
+ * 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);
}
+ /**
+ * 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);
}
+ /**
+ * 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);
@@ -534,7 +645,7 @@ namespace osmium {
}
/**
- * In a bool context any initialized buffer is true.
+ * In a bool context any valid buffer is true.
*/
explicit operator bool() const {
return m_data != nullptr;
@@ -548,6 +659,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);
}
/**
@@ -555,8 +668,8 @@ 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
@@ -564,8 +677,7 @@ namespace osmium {
* be and is now, respectively. This call can be used to update any
* indexes.
*
- * The behaviour is undefined if you call this on an invalid
- * buffer.
+ * @pre The buffer must be valid.
*/
template <typename TCallbackClass>
void purge_removed(TCallbackClass* callback) {
@@ -599,6 +711,13 @@ 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;
diff --git a/include/osmium/memory/item_iterator.hpp b/include/osmium/memory/item_iterator.hpp
index c6b4205..5751698 100644
--- a/include/osmium/memory/item_iterator.hpp
+++ b/include/osmium/memory/item_iterator.hpp
@@ -38,24 +38,12 @@ 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 {
@@ -217,7 +205,7 @@ namespace osmium {
}
explicit operator bool() const {
- return m_data != nullptr;
+ return bool(m_data) && (m_data != m_end);
}
template <typename TChar, typename TTraits>
diff --git a/include/osmium/osm/diff_object.hpp b/include/osmium/osm/diff_object.hpp
index 96e07bc..d9872ea 100644
--- a/include/osmium/osm/diff_object.hpp
+++ b/include/osmium/osm/diff_object.hpp
@@ -33,6 +33,8 @@ DEALINGS IN THE SOFTWARE.
*/
+#include <cassert>
+
#include <osmium/fwd.hpp>
#include <osmium/osm/item_type.hpp>
#include <osmium/osm/object.hpp>
@@ -41,71 +43,158 @@ DEALINGS IN THE SOFTWARE.
namespace osmium {
+ /**
+ * A DiffObject holds pointers to three OSMObjects, the current object,
+ * the previous, and the next. They always have the same type (Node, Way,
+ * or Relation) and the same ID, but may have different versions.
+ *
+ * It is used when iterating over OSM files with history data to make
+ * working with versioned OSM objects easier. Because you have access to
+ * the previous and next objects as well as the current one, comparisons
+ * between object versions is easy.
+ *
+ * If the current object is the first version available, the previous
+ * pointer must be the same as the current one. If the current object is
+ * the last version available, the next pointer must be the same as the
+ * current one.
+ *
+ * DiffObjects are immutable.
+ */
class DiffObject {
- protected:
-
- osmium::OSMObject* m_prev;
- osmium::OSMObject* m_curr;
- osmium::OSMObject* m_next;
+ const osmium::OSMObject* m_prev;
+ const osmium::OSMObject* m_curr;
+ const osmium::OSMObject* m_next;
public:
+ /**
+ * Default construct an empty DiffObject. Most methods of this class
+ * can not be called on empty DiffObjects.
+ */
DiffObject() noexcept :
m_prev(nullptr),
m_curr(nullptr),
m_next(nullptr) {
}
- explicit DiffObject(osmium::OSMObject& prev, osmium::OSMObject& curr, osmium::OSMObject& next) noexcept :
+ /**
+ * Construct a non-empty DiffObject from the given OSMObjects. All
+ * OSMObjects must be of the same type (Node, Way, or Relation) and
+ * have the same ID.
+ */
+ DiffObject(const osmium::OSMObject& prev, const osmium::OSMObject& curr, const osmium::OSMObject& next) noexcept :
m_prev(&prev),
m_curr(&curr),
m_next(&next) {
+ assert(prev.type() == curr.type() && curr.type() == next.type());
+ assert(prev.id() == curr.id() && curr.id() == next.id());
}
- DiffObject(const DiffObject&) = default;
- DiffObject& operator=(const DiffObject&) = default;
-
- DiffObject(DiffObject&&) = default;
- DiffObject& operator=(DiffObject&&) = default;
+ /**
+ * Check whether the DiffObject was created empty.
+ */
+ bool empty() const noexcept {
+ return m_prev == nullptr;
+ }
+ /**
+ * Get the previous object stored.
+ *
+ * @pre DiffObject must not be empty.
+ */
const osmium::OSMObject& prev() const noexcept {
+ assert(m_prev && m_curr && m_next);
return *m_prev;
}
+ /**
+ * Get the current object stored.
+ *
+ * @pre DiffObject must not be empty.
+ */
const osmium::OSMObject& curr() const noexcept {
+ assert(m_prev && m_curr && m_next);
return *m_curr;
}
+ /**
+ * Get the next object stored.
+ *
+ * @pre DiffObject must not be empty.
+ */
const osmium::OSMObject& next() const noexcept {
+ assert(m_prev && m_curr && m_next);
return *m_next;
}
+ /**
+ * Is the current object version the first (with this type and ID)?
+ *
+ * @pre DiffObject must not be empty.
+ */
bool first() const noexcept {
+ assert(m_prev && m_curr && m_next);
return m_prev == m_curr;
}
+ /**
+ * Is the current object version the last (with this type and ID)?
+ *
+ * @pre DiffObject must not be empty.
+ */
bool last() const noexcept {
+ assert(m_prev && m_curr && m_next);
return m_curr == m_next;
}
+ /**
+ * Return the type of the current object.
+ *
+ * @pre DiffObject must not be empty.
+ */
osmium::item_type type() const noexcept {
+ assert(m_prev && m_curr && m_next);
return m_curr->type();
}
+ /**
+ * Return the ID of the current object.
+ *
+ * @pre DiffObject must not be empty.
+ */
osmium::object_id_type id() const noexcept {
+ assert(m_prev && m_curr && m_next);
return m_curr->id();
}
+ /**
+ * Return the version of the current object.
+ *
+ * @pre DiffObject must not be empty.
+ */
osmium::object_version_type version() const noexcept {
+ assert(m_prev && m_curr && m_next);
return m_curr->version();
}
+ /**
+ * Return the changeset ID of the current object.
+ *
+ * @pre DiffObject must not be empty.
+ */
osmium::changeset_id_type changeset() const noexcept {
+ assert(m_prev && m_curr && m_next);
return m_curr->changeset();
}
+ /**
+ * Return the timestamp when the current object version was created.
+ *
+ * @pre DiffObject must not be empty.
+ */
const osmium::Timestamp start_time() const noexcept {
+ assert(m_prev && m_curr && m_next);
return m_curr->timestamp();
}
@@ -115,8 +204,11 @@ namespace osmium {
* is valid. If this is the last version of the object, this will
* return a special "end of time" timestamp that is guaranteed to
* be larger than any normal timestamp.
+ *
+ * @pre DiffObject must not be empty.
*/
const osmium::Timestamp end_time() const noexcept {
+ assert(m_prev && m_curr && m_next);
return last() ? osmium::end_of_time() : m_next->timestamp();
}
@@ -126,8 +218,11 @@ namespace osmium {
*
* This is a bit more complex than you'd think, because we have to
* handle the case properly where the start_time() == end_time().
+ *
+ * @pre DiffObject must not be empty.
*/
bool is_between(const osmium::Timestamp& from, const osmium::Timestamp& to) const noexcept {
+ assert(m_prev && m_curr && m_next);
return start_time() < to &&
((start_time() != end_time() && end_time() > from) ||
(start_time() == end_time() && end_time() >= from));
@@ -135,8 +230,11 @@ namespace osmium {
/**
* Current object version is visible at the given timestamp.
+ *
+ * @pre DiffObject must not be empty.
*/
bool is_visible_at(const osmium::Timestamp& timestamp) const noexcept {
+ assert(m_prev && m_curr && m_next);
return start_time() <= timestamp && end_time() > timestamp && m_curr->visible();
}
@@ -147,33 +245,27 @@ namespace osmium {
public:
- DiffObjectDerived(T& prev, T& curr, T& next) noexcept :
+ DiffObjectDerived(const T& prev, const T& curr, const T& next) noexcept :
DiffObject(prev, curr, next) {
}
- DiffObjectDerived(const DiffObjectDerived&) = default;
- DiffObjectDerived& operator=(const DiffObjectDerived&) = default;
-
- DiffObjectDerived(DiffObjectDerived&&) = default;
- DiffObjectDerived& operator=(DiffObjectDerived&&) = default;
-
const T& prev() const noexcept {
- return *static_cast<const T*>(m_prev);
+ return static_cast<const T&>(DiffObject::prev());
}
const T& curr() const noexcept {
- return *static_cast<const T*>(m_curr);
+ return static_cast<const T&>(DiffObject::curr());
}
const T& next() const noexcept {
- return *static_cast<const T*>(m_next);
+ return static_cast<const T&>(DiffObject::next());
}
}; // class DiffObjectDerived
- typedef DiffObjectDerived<osmium::Node> DiffNode;
- typedef DiffObjectDerived<osmium::Way> DiffWay;
- typedef DiffObjectDerived<osmium::Relation> DiffRelation;
+ using DiffNode = DiffObjectDerived<osmium::Node>;
+ using DiffWay = DiffObjectDerived<osmium::Way>;
+ using DiffRelation = DiffObjectDerived<osmium::Relation>;
} // namespace osmium
diff --git a/include/osmium/osm/item_type.hpp b/include/osmium/osm/item_type.hpp
index d8f5296..95826bc 100644
--- a/include/osmium/osm/item_type.hpp
+++ b/include/osmium/osm/item_type.hpp
@@ -61,6 +61,10 @@ namespace osmium {
/**
* Return item_type for index:
* 0 -> node, 1 -> way, 2 -> relation
+ *
+ * @param i Index. Must be between 0 and 2.
+ *
+ * @returns Item type.
*/
inline item_type nwr_index_to_item_type(unsigned int i) noexcept {
assert(i <= 2);
@@ -70,6 +74,10 @@ namespace osmium {
/**
* Return index for item_type:
* node -> 0, way -> 1, relation -> 2
+ *
+ * @param type Item type. Must be node, way, or relation.
+ *
+ * @returns Index.
*/
inline unsigned int item_type_to_nwr_index(item_type type) noexcept {
unsigned int i = static_cast<unsigned int>(type);
diff --git a/include/osmium/osm/node_ref.hpp b/include/osmium/osm/node_ref.hpp
index 72359cd..def63b2 100644
--- a/include/osmium/osm/node_ref.hpp
+++ b/include/osmium/osm/node_ref.hpp
@@ -59,10 +59,16 @@ namespace osmium {
m_location(location) {
}
+ /**
+ * Get reference ID of this NodeRef.
+ */
osmium::object_id_type ref() const noexcept {
return m_ref;
}
+ /**
+ * Get absolute value of the reference ID of this NodeRef.
+ */
osmium::unsigned_object_id_type positive_ref() const noexcept {
return static_cast<osmium::unsigned_object_id_type>(std::abs(m_ref));
}
@@ -74,31 +80,60 @@ namespace osmium {
return m_location;
}
+ /**
+ * Get location of this NodeRef.
+ */
osmium::Location location() const noexcept {
return m_location;
}
+ /**
+ * Get longitude of the location in this NodeRef.
+ *
+ * @throws osmium::invalid_location if the location is not set.
+ */
double lon() const {
return m_location.lon();
}
+ /**
+ * Get latitude of the location in this NodeRef.
+ *
+ * @throws osmium::invalid_location if the location is not set.
+ */
double lat() const {
return m_location.lat();
}
+ /**
+ * Get internal x value of the location in this NodeRef.
+ */
int32_t x() const noexcept {
return m_location.x();
}
+ /**
+ * Get internal y value of the location in this NodeRef.
+ */
int32_t y() const noexcept {
return m_location.y();
}
+ /**
+ * Set the referenced ID.
+ *
+ * @returns Reference to this NodeRef for chaining calls.
+ */
NodeRef& set_ref(const osmium::object_id_type ref) noexcept {
m_ref = ref;
return *this;
}
+ /**
+ * Set the location.
+ *
+ * @returns Reference to this NodeRef for chaining calls.
+ */
NodeRef& set_location(const osmium::Location& location) noexcept {
m_location = location;
return *this;
@@ -106,26 +141,49 @@ namespace osmium {
}; // class NodeRef
+ /**
+ * Compare two NodeRefs. They are equal if they reference the same Node ID.
+ */
inline bool operator==(const NodeRef& lhs, const NodeRef& rhs) noexcept {
return lhs.ref() == rhs.ref();
}
+ /**
+ * Compare two NodeRefs. They are not equal if they reference different
+ * Node IDs.
+ */
inline bool operator!=(const NodeRef& lhs, const NodeRef& rhs) noexcept {
return ! (lhs == rhs);
}
+ /**
+ * Compare two NodeRefs. NodeRefs are ordered according to the Node ID
+ * they reference.
+ */
inline bool operator<(const NodeRef& lhs, const NodeRef& rhs) noexcept {
return lhs.ref() < rhs.ref();
}
+ /**
+ * Compare two NodeRefs. NodeRefs are ordered according to the Node ID
+ * they reference.
+ */
inline bool operator>(const NodeRef& lhs, const NodeRef& rhs) noexcept {
return rhs < lhs;
}
+ /**
+ * Compare two NodeRefs. NodeRefs are ordered according to the Node ID
+ * they reference.
+ */
inline bool operator<=(const NodeRef& lhs, const NodeRef& rhs) noexcept {
return ! (rhs < lhs);
}
+ /**
+ * Compare two NodeRefs. NodeRefs are ordered according to the Node ID
+ * they reference.
+ */
inline bool operator>=(const NodeRef& lhs, const NodeRef& rhs) noexcept {
return ! (lhs < rhs);
}
@@ -139,7 +197,7 @@ namespace osmium {
}
/**
- * Functor to compare NodeRefs by Location instead of id.
+ * Functor to compare NodeRefs by Location instead of ID.
*/
struct location_equal {
@@ -147,14 +205,14 @@ namespace osmium {
return lhs.location() == rhs.location();
}
- typedef NodeRef first_argument_type;
- typedef NodeRef second_argument_type;
- typedef bool result_type;
+ using first_argument_type = NodeRef;
+ using second_argument_type = NodeRef;
+ using result_type = bool;
}; // struct location_equal
/**
- * Functor to compare NodeRefs by Location instead of id.
+ * Functor to compare NodeRefs by Location instead of ID.
*/
struct location_less {
@@ -162,9 +220,9 @@ namespace osmium {
return lhs.location() < rhs.location();
}
- typedef NodeRef first_argument_type;
- typedef NodeRef second_argument_type;
- typedef bool result_type;
+ using first_argument_type = NodeRef;
+ using second_argument_type = NodeRef;
+ using result_type = bool;
}; // struct location_less
diff --git a/include/osmium/osm/node_ref_list.hpp b/include/osmium/osm/node_ref_list.hpp
index c6c4213..e46a66d 100644
--- a/include/osmium/osm/node_ref_list.hpp
+++ b/include/osmium/osm/node_ref_list.hpp
@@ -44,8 +44,8 @@ DEALINGS IN THE SOFTWARE.
namespace osmium {
/**
- * A vector of NodeRef objects. Usually this is not instantiated directly,
- * but one of its subclasses are used.
+ * An ordered collection of NodeRef objects. Usually this is not
+ * instantiated directly, but one of its subclasses are used.
*/
class NodeRefList : public osmium::memory::Item {
@@ -56,14 +56,14 @@ namespace osmium {
}
/**
- * Checks whether the node list is empty.
+ * Checks whether the collection is empty.
*/
bool empty() const noexcept {
return sizeof(NodeRefList) == byte_size();
}
/**
- * Returns the number of nodes in the list.
+ * Returns the number of NodeRefs in the collection.
*/
size_t size() const noexcept {
auto size_node_refs = byte_size() - sizeof(NodeRefList);
@@ -74,8 +74,9 @@ namespace osmium {
/**
* Access specified element.
*
- * @param n Get this element of the list.
* @pre @code n < size() @endcode
+ *
+ * @param n Get the n-th element of the collection.
*/
const NodeRef& operator[](size_t n) const noexcept {
assert(n < size());
@@ -104,16 +105,18 @@ namespace osmium {
}
/**
- * Checks whether the first and last node in the list have the same ID.
+ * Checks whether the first and last node in the collection have the
+ * same ID. The locations are not checked.
*
* @pre @code !empty() @endcode
*/
bool is_closed() const noexcept {
- return front().ref() == back().ref();
+ return ends_have_same_id();
}
/**
- * Checks whether the first and last node in the list have the same ID.
+ * Checks whether the first and last node in the collection have the
+ * same ID. The locations are not checked.
*
* @pre @code !empty() @endcode
*/
@@ -122,8 +125,8 @@ namespace osmium {
}
/**
- * Checks whether the first and last node in the list have the same
- * location. The ID is not checked.
+ * Checks whether the first and last node in the collection have the
+ * same location. The IDs are not checked.
*
* @pre @code !empty() @endcode
* @pre @code front().location() && back().location() @endcode
@@ -133,9 +136,9 @@ namespace osmium {
return front().location() == back().location();
}
- typedef NodeRef* iterator;
- typedef const NodeRef* const_iterator;
- typedef std::reverse_iterator<const NodeRef*> const_reverse_iterator;
+ using iterator = NodeRef*;
+ using const_iterator = const NodeRef*;
+ using const_reverse_iterator = std::reverse_iterator<const NodeRef*>;
/// Returns an iterator to the beginning.
iterator begin() noexcept {
diff --git a/include/osmium/osm/timestamp.hpp b/include/osmium/osm/timestamp.hpp
index 2145fcb..9de727f 100644
--- a/include/osmium/osm/timestamp.hpp
+++ b/include/osmium/osm/timestamp.hpp
@@ -54,10 +54,8 @@ namespace osmium {
// length of ISO timestamp string yyyy-mm-ddThh:mm:ssZ\0
static constexpr int timestamp_length = 20 + 1;
- /**
- * The timestamp format for OSM timestamps in strftime(3) format.
- * This is the ISO-Format yyyy-mm-ddThh:mm:ssZ
- */
+ // The timestamp format for OSM timestamps in strftime(3) format.
+ // This is the ISO-Format "yyyy-mm-ddThh:mm:ssZ".
static const char* timestamp_format() {
static const char f[timestamp_length] = "%Y-%m-%dT%H:%M:%SZ";
return f;
@@ -67,27 +65,29 @@ namespace osmium {
public:
+ /**
+ * Default construct an invalid Timestamp.
+ */
constexpr Timestamp() noexcept :
m_timestamp(0) {
}
- // Not "explicit" so that conversions from time_t work
- // like in node.timestamp(123);
- constexpr Timestamp(time_t timestamp) noexcept :
- m_timestamp(static_cast<uint32_t>(timestamp)) {
- }
-
/**
- * Returns true if this timestamp is valid (ie set to something other
- * than 0).
+ * Construct a Timestamp from a time_t containing the seconds since
+ * the epoch.
+ *
+ * The constructor is not declared "explicit" so that conversions
+ * like @code node.set_timestamp(123); @endcode work.
*/
- bool valid() const noexcept {
- return m_timestamp != 0;
+ constexpr Timestamp(time_t timestamp) noexcept :
+ m_timestamp(static_cast<uint32_t>(timestamp)) {
}
/**
- * Construct timestamp from ISO date/time string.
- * Throws std::invalid_argument, if the timestamp can not be parsed.
+ * Construct timestamp from ISO date/time string in the format
+ * "yyyy-mm-ddThh:mm:ssZ".
+ *
+ * @throws std::invalid_argument if the timestamp can not be parsed.
*/
explicit Timestamp(const char* timestamp) {
#ifndef _WIN32
@@ -113,14 +113,35 @@ namespace osmium {
#endif
}
+ /**
+ * Construct timestamp from ISO date/time string in the format
+ * "yyyy-mm-ddThh:mm:ssZ".
+ *
+ * @throws std::invalid_argument if the timestamp can not be parsed.
+ */
+ explicit Timestamp(const std::string& timestamp) :
+ Timestamp(timestamp.c_str()) {
+ }
+
+ /**
+ * Returns true if this timestamp is valid (ie set to something other
+ * than 0).
+ */
+ bool valid() const noexcept {
+ return m_timestamp != 0;
+ }
+
+ /// Explicit conversion into time_t.
constexpr time_t seconds_since_epoch() const noexcept {
return static_cast<time_t>(m_timestamp);
}
+ /// Implicit conversion into time_t.
constexpr operator time_t() const noexcept {
return static_cast<time_t>(m_timestamp);
}
+ /// Explicit conversion into uint32_t.
explicit constexpr operator uint32_t() const noexcept {
return m_timestamp;
}
@@ -136,7 +157,8 @@ namespace osmium {
}
/**
- * Return UTC Unix time as string in ISO date/time format.
+ * Return UTC Unix time as string in ISO date/time
+ * ("yyyy-mm-ddThh:mm:ssZ") format.
*/
std::string to_iso() const {
std::string s;
@@ -164,12 +186,20 @@ namespace osmium {
}; // class Timestamp
+ /**
+ * A special Timestamp guaranteed to be ordered before any other valid
+ * Timestamp.
+ */
inline OSMIUM_CONSTEXPR Timestamp start_of_time() noexcept {
return Timestamp(1);
}
+ /**
+ * A special Timestamp guaranteed to be ordered after any other valid
+ * Timestamp.
+ */
inline OSMIUM_CONSTEXPR Timestamp end_of_time() noexcept {
- return Timestamp(std::numeric_limits<time_t>::max());
+ return Timestamp(std::numeric_limits<uint32_t>::max());
}
template <typename TChar, typename TTraits>
diff --git a/include/osmium/osm/types_from_string.hpp b/include/osmium/osm/types_from_string.hpp
index b0e22a7..67ab2c1 100644
--- a/include/osmium/osm/types_from_string.hpp
+++ b/include/osmium/osm/types_from_string.hpp
@@ -47,6 +47,15 @@ DEALINGS IN THE SOFTWARE.
namespace osmium {
+ /**
+ * Convert string with object id to object_id_type.
+ *
+ * @pre input must not be nullptr.
+ *
+ * @param input Input string.
+ *
+ * @throws std::range_error if the value is out of range.
+ */
inline object_id_type string_to_object_id(const char* input) {
assert(input);
if (*input != '\0' && !std::isspace(*input)) {
@@ -59,6 +68,19 @@ namespace osmium {
throw std::range_error(std::string("illegal id: '") + input + "'");
}
+ /**
+ * Parse string with object type identifier followed by object id. This
+ * reads strings like "n1234" and "w10".
+ *
+ * @pre input must not be nullptr.
+ *
+ * @param input Input string.
+ * @param types Allowed types. Must not be osmium::osm_entity_bits::nothing.
+ *
+ * @returns std::pair of type and id.
+ *
+ * @throws std::range_error if the value is out of range.
+ */
inline std::pair<osmium::item_type, osmium::object_id_type> string_to_object_id(const char* input, osmium::osm_entity_bits::type types) {
assert(input);
assert(types != osmium::osm_entity_bits::nothing);
@@ -89,16 +111,43 @@ namespace osmium {
} // namespace detail
+ /**
+ * Convert string with object version to object_version_type.
+ *
+ * @pre input must not be nullptr.
+ *
+ * @param input Input string.
+ *
+ * @throws std::range_error if the value is out of range.
+ */
inline object_version_type string_to_object_version(const char* input) {
assert(input);
return static_cast_with_assert<object_version_type>(detail::string_to_ulong(input, "version"));
}
+ /**
+ * Convert string with object version to object_version_type.
+ *
+ * @pre input must not be nullptr.
+ *
+ * @param input Input string.
+ *
+ * @throws std::range_error if the value is out of range.
+ */
inline changeset_id_type string_to_changeset_id(const char* input) {
assert(input);
return static_cast_with_assert<changeset_id_type>(detail::string_to_ulong(input, "changeset"));
}
+ /**
+ * Convert string with user id to signed_user_id_type.
+ *
+ * @pre input must not be nullptr.
+ *
+ * @param input Input string.
+ *
+ * @throws std::range_error if the value is out of range.
+ */
inline signed_user_id_type string_to_user_id(const char* input) {
assert(input);
if (input[0] == '-' && input[1] == '1' && input[2] == '\0') {
@@ -107,11 +156,29 @@ namespace osmium {
return static_cast_with_assert<signed_user_id_type>(detail::string_to_ulong(input, "user id"));
}
+ /**
+ * Convert string with number of changes to num_changes_type.
+ *
+ * @pre input must not be nullptr.
+ *
+ * @param input Input string.
+ *
+ * @throws std::range_error if the value is out of range.
+ */
inline num_changes_type string_to_num_changes(const char* input) {
assert(input);
return static_cast_with_assert<num_changes_type>(detail::string_to_ulong(input, "value for num changes"));
}
+ /**
+ * Convert string with number of comments to num_comments_type.
+ *
+ * @pre input must not be nullptr.
+ *
+ * @param input Input string.
+ *
+ * @throws std::range_error if the value is out of range.
+ */
inline num_comments_type string_to_num_comments(const char* input) {
assert(input);
return static_cast_with_assert<num_comments_type>(detail::string_to_ulong(input, "value for num comments"));
diff --git a/include/osmium/relations/collector.hpp b/include/osmium/relations/collector.hpp
index e7f76a2..7d27b33 100644
--- a/include/osmium/relations/collector.hpp
+++ b/include/osmium/relations/collector.hpp
@@ -122,82 +122,15 @@ namespace osmium {
TCollector& m_collector;
- /**
- * This variable is initialized with the number of different
- * kinds of OSM objects we are interested in. If we only need
- * way members (for instance for the multipolygon collector)
- * it is intialized with 1 for instance. If node and way
- * members are needed, it is initialized with 2.
- *
- * In the after_* methods of this handler, it is decremented
- * and once it reaches 0, we know we have all members available
- * that we are ever going to get.
- */
- int m_want_types;
-
- /**
- * Find this object in the member vectors and add it to all
- * relations that need it.
- *
- * @returns true if the member was added to at least one
- * relation and false otherwise
- */
- bool find_and_add_object(const osmium::OSMObject& object) {
- auto& mmv = m_collector.member_meta(object.type());
- auto range = std::equal_range(mmv.begin(), mmv.end(), MemberMeta(object.id()));
-
- if (osmium::relations::count_not_removed(range.first, range.second) == 0) {
- // nothing found
- return false;
- }
-
- {
- m_collector.members_buffer().add_item(object);
- const size_t member_offset = m_collector.members_buffer().commit();
-
- for (auto it = range.first; it != range.second; ++it) {
- it->set_buffer_offset(member_offset);
- }
- }
-
- for (auto it = range.first; it != range.second; ++it) {
- MemberMeta& member_meta = *it;
- if (member_meta.removed()) {
- break;
- }
- assert(member_meta.member_id() == object.id());
- assert(member_meta.relation_pos() < m_collector.m_relations.size());
- RelationMeta& relation_meta = m_collector.m_relations[member_meta.relation_pos()];
-// std::cerr << " => " << member_meta.member_pos() << " < " << m_collector.get_relation(relation_meta).members().size() << " (id=" << m_collector.get_relation(relation_meta).id() << ")\n";
- assert(member_meta.member_pos() < m_collector.get_relation(relation_meta).members().size());
-// std::cerr << " add way " << member_meta.member_id() << " to rel " << m_collector.get_relation(relation_meta).id() << " at pos " << member_meta.member_pos() << "\n";
- relation_meta.got_one_member();
- if (relation_meta.has_all_members()) {
- const size_t relation_offset = member_meta.relation_pos();
- m_collector.complete_relation(relation_meta);
- m_collector.m_relations[relation_offset] = RelationMeta();
- m_collector.possibly_purge_removed_members();
- }
- }
-
- // Remove MemberMetas that were marked as removed.
- mmv.erase(std::remove_if(mmv.begin(), mmv.end(), [](MemberMeta& mm) {
- return mm.removed();
- }), mmv.end());
-
- return true;
- }
-
public:
HandlerPass2(TCollector& collector) noexcept :
- m_collector(collector),
- m_want_types((TNodes?1:0) + (TWays?1:0) + (TRelations?1:0)) {
+ m_collector(collector) {
}
void node(const osmium::Node& node) {
if (TNodes) {
- if (! find_and_add_object(node)) {
+ if (! m_collector.find_and_add_object(node)) {
m_collector.node_not_in_any_relation(node);
}
}
@@ -205,7 +138,7 @@ namespace osmium {
void way(const osmium::Way& way) {
if (TWays) {
- if (! find_and_add_object(way)) {
+ if (! m_collector.find_and_add_object(way)) {
m_collector.way_not_in_any_relation(way);
}
}
@@ -213,7 +146,7 @@ namespace osmium {
void relation(const osmium::Relation& relation) {
if (TRelations) {
- if (! find_and_add_object(relation)) {
+ if (! m_collector.find_and_add_object(relation)) {
m_collector.relation_not_in_any_relation(relation);
}
}
@@ -225,6 +158,8 @@ namespace osmium {
}; // class HandlerPass2
+ private:
+
HandlerPass2 m_handler_pass2;
// All relations we are interested in will be kept in this buffer
@@ -373,6 +308,8 @@ namespace osmium {
return m_members_buffer.get<osmium::OSMObject>(offset);
}
+ private:
+
/**
* Tell the Collector that you are interested in this relation
* and want it kept until all members have been assembled and
@@ -422,6 +359,84 @@ namespace osmium {
std::sort(m_member_meta[2].begin(), m_member_meta[2].end());
}
+ /**
+ * Find this object in the member vectors and add it to all
+ * relations that need it.
+ *
+ * @returns true if the member was added to at least one
+ * relation and false otherwise
+ */
+ bool find_and_add_object(const osmium::OSMObject& object) {
+ auto& mmv = member_meta(object.type());
+ auto range = std::equal_range(mmv.begin(), mmv.end(), MemberMeta(object.id()));
+
+ if (osmium::relations::count_not_removed(range.first, range.second) == 0) {
+ // nothing found
+ return false;
+ }
+
+ {
+ members_buffer().add_item(object);
+ const size_t member_offset = members_buffer().commit();
+
+ for (auto it = range.first; it != range.second; ++it) {
+ it->set_buffer_offset(member_offset);
+ }
+ }
+
+ for (auto it = range.first; it != range.second; ++it) {
+ MemberMeta& member_meta = *it;
+ if (member_meta.removed()) {
+ break;
+ }
+ assert(member_meta.member_id() == object.id());
+ assert(member_meta.relation_pos() < m_relations.size());
+ RelationMeta& relation_meta = m_relations[member_meta.relation_pos()];
+// std::cerr << " => " << member_meta.member_pos() << " < " << get_relation(relation_meta).members().size() << " (id=" << get_relation(relation_meta).id() << ")\n";
+ assert(member_meta.member_pos() < get_relation(relation_meta).members().size());
+// std::cerr << " add way " << member_meta.member_id() << " to rel " << get_relation(relation_meta).id() << " at pos " << member_meta.member_pos() << "\n";
+ relation_meta.got_one_member();
+ if (relation_meta.has_all_members()) {
+ const size_t relation_offset = member_meta.relation_pos();
+ static_cast<TCollector*>(this)->complete_relation(relation_meta);
+ clear_member_metas(relation_meta);
+ m_relations[relation_offset] = RelationMeta();
+ possibly_purge_removed_members();
+ }
+ }
+
+ // Remove MemberMetas that were marked as removed.
+ mmv.erase(std::remove_if(mmv.begin(), mmv.end(), [](MemberMeta& mm) {
+ return mm.removed();
+ }), mmv.end());
+
+ return true;
+ }
+
+ void clear_member_metas(const osmium::relations::RelationMeta& relation_meta) {
+ const osmium::Relation& relation = get_relation(relation_meta);
+ for (const auto& member : relation.members()) {
+ if (member.ref() != 0) {
+ auto& mmv = member_meta(member.type());
+ auto range = std::equal_range(mmv.begin(), mmv.end(), MemberMeta(member.ref()));
+ assert(range.first != range.second);
+
+ // if this is the last time this object was needed
+ // then mark it as removed
+ if (osmium::relations::count_not_removed(range.first, range.second) == 1) {
+ get_member(range.first->buffer_offset()).set_removed(true);
+ }
+
+ for (auto it = range.first; it != range.second; ++it) {
+ if (!it->removed() && relation.id() == get_relation(it->relation_pos()).id()) {
+ it->remove();
+ break;
+ }
+ }
+ }
+ }
+ }
+
public:
uint64_t used_memory() const {
@@ -488,7 +503,7 @@ namespace osmium {
void moving_in_buffer(size_t old_offset, size_t new_offset) {
const osmium::OSMObject& object = m_members_buffer.get<osmium::OSMObject>(old_offset);
auto& mmv = member_meta(object.type());
- auto range = std::equal_range(mmv.begin(), mmv.end(), osmium::relations::MemberMeta(object.id()));
+ auto range = std::equal_range(mmv.begin(), mmv.end(), MemberMeta(object.id()));
for (auto it = range.first; it != range.second; ++it) {
assert(it->buffer_offset() == old_offset);
it->set_buffer_offset(new_offset);
diff --git a/include/osmium/util/data_file.hpp b/include/osmium/util/data_file.hpp
deleted file mode 100644
index 53bb81c..0000000
--- a/include/osmium/util/data_file.hpp
+++ /dev/null
@@ -1,194 +0,0 @@
-#ifndef OSMIUM_UTIL_DATA_FILE_HPP
-#define OSMIUM_UTIL_DATA_FILE_HPP
-
-/*
-
-This file is part of Osmium (http://osmcode.org/libosmium).
-
-Copyright 2013-2015 Jochen Topf <jochen at topf.org> and others (see README).
-
-Boost Software License - Version 1.0 - August 17th, 2003
-
-Permission is hereby granted, free of charge, to any person or organization
-obtaining a copy of the software and accompanying documentation covered by
-this license (the "Software") to use, reproduce, display, distribute,
-execute, and transmit the Software, and to prepare derivative works of the
-Software, and to permit third-parties to whom the Software is furnished to
-do so, all subject to the following:
-
-The copyright notices in the Software and this entire statement, including
-the above license grant, this restriction and the following disclaimer,
-must be included in all copies of the Software, in whole or in part, and
-all derivative works of the Software, unless such copies or derivative
-works are solely in the form of machine-executable object code generated by
-a source language processor.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
-SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
-FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
-ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-DEALINGS IN THE SOFTWARE.
-
-*/
-
-#include <cerrno>
-#include <cstddef>
-#include <cstdio>
-#include <stdexcept>
-#include <string>
-#include <system_error>
-
-#ifdef _WIN32
-# include <io.h>
-# include <windows.h>
-#endif
-
-#include <osmium/util/file.hpp>
-
-namespace osmium {
-
- namespace util {
-
- /**
- * Class wrapper for convenient access to some low-level file
- * functions.
- */
- class DataFile {
-
- FILE* m_file;
-
- public:
-
- /**
- * Create and open a temporary file. It is removed after opening.
- *
- * @throws std::system_error if something went wrong.
- */
- DataFile() :
- m_file(::tmpfile()) {
- if (!m_file) {
- throw std::system_error(errno, std::system_category(), "tmpfile failed");
- }
- }
-
- /**
- * Create and open a temporary file with the specified size. It
- * is removed after opening.
- *
- * @throws std::system_error if something went wrong.
- */
- explicit DataFile(size_t size) :
- DataFile() {
- grow(size);
- }
-
- /**
- * Create and open a named file.
- *
- * @param filename the name of the file
- * @param writable should the file be writable?
- * @throws std::system_error if something went wrong.
- */
- DataFile(const char* filename, bool writable) :
- m_file(::fopen(filename, writable ? "wb+" : "rb" )) {
- if (!m_file) {
- throw std::system_error(errno, std::system_category(), "fopen failed");
- }
- }
-
- /**
- * Create and open a named file.
- *
- * @param filename the name of the file
- * @param writable should the file be writable?
- * @throws std::system_error if something went wrong.
- */
- DataFile(const std::string& filename, bool writable) :
- DataFile(filename.c_str(), writable) {
- }
-
- /**
- * In boolean context the DataFile class returns true if the file
- * is open.
- */
- operator bool() const noexcept {
- return m_file != nullptr;
- }
-
- /**
- * Close the file.
- *
- * Does nothing if the file is already closed.
- *
- * @throws std::system_error if file could not be closed
- */
- void close() {
- if (m_file) {
- if (::fclose(m_file) != 0) {
- throw std::system_error(errno, std::system_category(), "fclose failed");
- }
- m_file = nullptr;
- }
- }
-
- ~DataFile() noexcept {
- try {
- close();
- } catch (std::system_error&) {
- // Ignore any exceptions because destructor must not throw.
- }
- }
-
- /**
- * Get file descriptor of underlying file.
- *
- * @throws std::runtime_errro if file is not open
- * @throws std::system_error if fileno(3) call failed
- */
- int fd() const {
- if (!m_file) {
- throw std::runtime_error("no open file");
- }
-
- int fd = ::fileno(m_file);
-
- if (fd == -1) {
- throw std::system_error(errno, std::system_category(), "fileno failed");
- }
-
- return fd;
- }
-
- /**
- * Ask the operating system for the size of this file.
- *
- * @throws std::system_error if fstat(2) call failed
- */
- size_t size() const {
- return osmium::util::file_size(fd());
- }
-
- /**
- * Grow file to given size.
- *
- * If the file is large enough already, nothing is done.
- * The file is never shrunk.
- *
- * @throws std::system_error if ftruncate(2) call failed
- */
- void grow(size_t new_size) const {
- if (size() < new_size) {
- osmium::util::resize_file(fd(), new_size);
- }
- }
-
- }; // class DataFile
-
- } // namespace util
-
-} // namespace osmium
-
-
-#endif // OSMIUM_UTIL_DATA_FILE_HPP
diff --git a/include/osmium/util/memory_mapping.hpp b/include/osmium/util/memory_mapping.hpp
index d5a057d..48da13a 100644
--- a/include/osmium/util/memory_mapping.hpp
+++ b/include/osmium/util/memory_mapping.hpp
@@ -38,6 +38,7 @@ DEALINGS IN THE SOFTWARE.
#include <stdexcept>
#include <system_error>
+#include <osmium/util/compatibility.hpp>
#include <osmium/util/file.hpp>
#ifndef _WIN32
@@ -173,7 +174,8 @@ private:
* created, otherwise a mapping based on the file descriptor will
* be created.
*
- * @pre size > 0 or mode == write_shared oder write_private
+ * @pre @code size > 0 @endcode or
+ * @code mode == write_shared || mode == write_private @endcode
*
* @param size Size of the mapping in bytes
* @param mode Mapping mode: readonly, or writable (shared or private)
@@ -183,8 +185,12 @@ private:
*/
MemoryMapping(size_t size, mapping_mode mode, int fd=-1, off_t offset=0);
- /// DEPRECATED: For backwards compatibility
- MemoryMapping(size_t size, bool writable=true, int fd=-1, off_t offset=0) :
+ /**
+ * @deprecated
+ * For backwards compatibility only. Use the constructor taking
+ * a mapping_mode as second argument instead.
+ */
+ OSMIUM_DEPRECATED MemoryMapping(size_t size, bool writable=true, int fd=-1, off_t offset=0) :
MemoryMapping(size, writable ? mapping_mode::write_shared : mapping_mode::readonly, fd, offset) {
}
@@ -232,8 +238,9 @@ private:
* systems it will unmap and remap the memory. This can only be
* done for file-based mappings, not anonymous mappings!
*
- * @param new_size Number of bytes to resize to
- * @throws std::system_error if the remapping fails
+ * @param new_size Number of bytes to resize to (must be > 0).
+ *
+ * @throws std::system_error if the remapping fails.
*/
void resize(size_t new_size);
@@ -353,8 +360,12 @@ private:
m_mapping(sizeof(T) * size, mode, fd, sizeof(T) * offset) {
}
- /// DEPRECATED: For backwards compatibility
- TypedMemoryMapping(size_t size, bool writable, int fd, off_t offset = 0) :
+ /**
+ * @deprecated
+ * For backwards compatibility only. Use the constructor taking
+ * a mapping_mode as second argument instead.
+ */
+ OSMIUM_DEPRECATED TypedMemoryMapping(size_t size, bool writable, int fd, off_t offset = 0) :
m_mapping(sizeof(T) * size, writable ? MemoryMapping::mapping_mode::write_shared : MemoryMapping::mapping_mode::readonly, fd, sizeof(T) * offset) {
}
diff --git a/include/osmium/util/options.hpp b/include/osmium/util/options.hpp
index 24c0918..1019c8b 100644
--- a/include/osmium/util/options.hpp
+++ b/include/osmium/util/options.hpp
@@ -47,46 +47,65 @@ namespace osmium {
* as a base class. Options are stored and retrieved by key using the
* different set() and get() methods.
*
+ * Both keys and values are stored as strings. The values "true",
+ * "yes", "false", and "no" are interpreted as boolean values in some
+ * functions.
+ *
* You can iterate over all set options. Dereferencing an iterator
* yields a std::pair of the key and value strings.
*/
class Options {
- typedef std::map<std::string, std::string> option_map;
+ using option_map = std::map<std::string, std::string>;
option_map m_options;
public:
- typedef option_map::iterator iterator;
- typedef option_map::const_iterator const_iterator;
- typedef option_map::value_type value_type;
+ using iterator = option_map::iterator;
+ using const_iterator = option_map::const_iterator;
+ using value_type = option_map::value_type;
+ /**
+ * Construct empty option set.
+ */
Options() = default;
+ /**
+ * Construct option set from initializer list:
+ * @code
+ * Options options{ { "foo", "true" }, { "bar", "17" } };
+ * @endcode
+ */
explicit Options(const std::initializer_list<value_type>& values) :
m_options(values) {
}
- Options(const Options&) = default;
- Options& operator=(const Options&) = default;
-
- Options(Options&&) = default;
- Options& operator=(Options&&) = default;
-
- ~Options() = default;
-
+ /**
+ * Set option 'key' to 'value'.
+ */
void set(const std::string& key, const std::string& value) {
m_options[key] = value;
}
+ /**
+ * Set option 'key' to 'value'.
+ */
void set(const std::string& key, const char* value) {
m_options[key] = value;
}
+ /**
+ * Set option 'key' to 'value'.
+ */
void set(const std::string& key, bool value) {
m_options[key] = value ? "true" : "false";
}
+ /**
+ * Set option from string in the form 'key=value'. If the string
+ * contains no equal sign, the whole string is the key and it will
+ * be set to "true".
+ */
void set(std::string data) {
size_t pos = data.find_first_of('=');
if (pos == std::string::npos) {
@@ -99,7 +118,7 @@ namespace osmium {
}
/**
- * Get value of "key" option. If not set the default_value (or
+ * Get value of "key" option. If not set, the default_value (or
* empty string) is returned.
*/
std::string get(const std::string& key, const std::string& default_value="") const noexcept {
@@ -128,30 +147,51 @@ namespace osmium {
return !(value == "false" || value == "no");
}
+ /**
+ * The number of options set.
+ */
size_t size() const noexcept {
return m_options.size();
}
+ /**
+ * Returns an iterator to the beginning.
+ */
iterator begin() noexcept {
return m_options.begin();
}
+ /**
+ * Returns an iterator to the end.
+ */
iterator end() noexcept {
return m_options.end();
}
+ /**
+ * Returns an iterator to the beginning.
+ */
const_iterator begin() const noexcept {
return m_options.cbegin();
}
+ /**
+ * Returns an iterator to the end.
+ */
const_iterator end() const noexcept {
return m_options.cend();
}
+ /**
+ * Returns an iterator to the beginning.
+ */
const_iterator cbegin() const noexcept {
return m_options.cbegin();
}
+ /**
+ * Returns a iterator to the end.
+ */
const_iterator cend() const noexcept {
return m_options.cend();
}
diff --git a/include/osmium/visitor.hpp b/include/osmium/visitor.hpp
index 35fcb4e..48ce45d 100644
--- a/include/osmium/visitor.hpp
+++ b/include/osmium/visitor.hpp
@@ -35,6 +35,7 @@ DEALINGS IN THE SOFTWARE.
#include <type_traits>
+#include <osmium/fwd.hpp>
#include <osmium/io/reader_iterator.hpp> // IWYU pragma: keep
#include <osmium/memory/buffer.hpp>
#include <osmium/osm.hpp>
@@ -43,12 +44,6 @@ DEALINGS IN THE SOFTWARE.
namespace osmium {
- class TagList;
- class WayNodeList;
- class RelationMemberList;
- class OuterRing;
- class InnerRing;
-
namespace memory {
class Item;
}
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index b9f02ee..f574161 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -151,7 +151,6 @@ add_unit_test(tags test_tag_list)
add_unit_test(thread test_pool ENABLE_IF ${Threads_FOUND} LIBS ${CMAKE_THREAD_LIBS_INIT})
add_unit_test(util test_cast_with_assert)
-add_unit_test(util test_data_file)
add_unit_test(util test_delta)
add_unit_test(util test_double)
add_unit_test(util test_file)
diff --git a/test/t/basic/test_object_comparisons.cpp b/test/t/basic/test_object_comparisons.cpp
index 2bfdcad..ec9e6fa 100644
--- a/test/t/basic/test_object_comparisons.cpp
+++ b/test/t/basic/test_object_comparisons.cpp
@@ -31,20 +31,20 @@ TEST_CASE("Object_Comparisons") {
node1.set_version(1);
node2.set_id(15);
node2.set_version(2);
- REQUIRE(true == (node1 < node2));
- REQUIRE(false == (node1 > node2));
+ REQUIRE(node1 < node2);
+ REQUIRE_FALSE(node1 > node2);
node1.set_id(20);
node1.set_version(1);
node2.set_id(20);
node2.set_version(2);
- REQUIRE(true == (node1 < node2));
- REQUIRE(false == (node1 > node2));
+ REQUIRE(node1 < node2);
+ REQUIRE_FALSE(node1 > node2);
node1.set_id(-10);
node1.set_version(2);
node2.set_id(-15);
node2.set_version(1);
- REQUIRE(true == (node1 < node2));
- REQUIRE(false == (node1 > node2));
+ REQUIRE(node1 < node2);
+ REQUIRE_FALSE(node1 > node2);
}
SECTION("order_types") {
@@ -122,26 +122,26 @@ TEST_CASE("Object_Comparisons") {
const osmium::Way& way = static_cast<const osmium::Way&>(*(++it));
const osmium::Relation& relation = static_cast<const osmium::Relation&>(*(++it));
- REQUIRE(true == (node1 < node2));
- REQUIRE(true == (node2 < way));
- REQUIRE(false == (node2 > way));
- REQUIRE(true == (way < relation));
- REQUIRE(true == (node1 < relation));
+ REQUIRE(node1 < node2);
+ REQUIRE(node2 < way);
+ REQUIRE_FALSE(node2 > way);
+ REQUIRE(way < relation);
+ REQUIRE(node1 < relation);
- REQUIRE(true == osmium::object_order_type_id_version()(node1, node2));
- REQUIRE(true == osmium::object_order_type_id_reverse_version()(node2, node1));
- REQUIRE(true == osmium::object_order_type_id_version()(node1, way));
- REQUIRE(true == osmium::object_order_type_id_reverse_version()(node1, way));
+ REQUIRE(osmium::object_order_type_id_version()(node1, node2));
+ REQUIRE(osmium::object_order_type_id_reverse_version()(node2, node1));
+ REQUIRE(osmium::object_order_type_id_version()(node1, way));
+ REQUIRE(osmium::object_order_type_id_reverse_version()(node1, way));
- REQUIRE(false == osmium::object_equal_type_id_version()(node1, node2));
- REQUIRE(true == osmium::object_equal_type_id_version()(node2, node3));
+ REQUIRE_FALSE(osmium::object_equal_type_id_version()(node1, node2));
+ REQUIRE(osmium::object_equal_type_id_version()(node2, node3));
- REQUIRE(true == osmium::object_equal_type_id()(node1, node2));
- REQUIRE(true == osmium::object_equal_type_id()(node2, node3));
+ REQUIRE(osmium::object_equal_type_id()(node1, node2));
+ REQUIRE(osmium::object_equal_type_id()(node2, node3));
- REQUIRE(false == osmium::object_equal_type_id_version()(node1, way));
- REQUIRE(false == osmium::object_equal_type_id_version()(node1, relation));
- REQUIRE(false == osmium::object_equal_type_id()(node1, relation));
+ REQUIRE_FALSE(osmium::object_equal_type_id_version()(node1, way));
+ REQUIRE_FALSE(osmium::object_equal_type_id_version()(node1, relation));
+ REQUIRE_FALSE(osmium::object_equal_type_id()(node1, relation));
}
}
diff --git a/test/t/basic/test_timestamp.cpp b/test/t/basic/test_timestamp.cpp
index f015730..f5c4eba 100644
--- a/test/t/basic/test_timestamp.cpp
+++ b/test/t/basic/test_timestamp.cpp
@@ -10,23 +10,34 @@ TEST_CASE("Timestamp") {
osmium::Timestamp t;
REQUIRE(0 == t);
REQUIRE("" == t.to_iso());
+ REQUIRE_FALSE(t.valid());
}
SECTION("invalid value is zero") {
osmium::Timestamp t(static_cast<time_t>(0));
REQUIRE(0 == t);
REQUIRE("" == t.to_iso());
+ REQUIRE_FALSE(t.valid());
}
SECTION("can be initialized from time_t") {
osmium::Timestamp t(static_cast<time_t>(1));
REQUIRE(1 == t);
REQUIRE("1970-01-01T00:00:01Z" == t.to_iso());
+ REQUIRE(t.valid());
}
- SECTION("can be initialized from string") {
+ SECTION("can be initialized from const char*") {
osmium::Timestamp t("2000-01-01T00:00:00Z");
REQUIRE("2000-01-01T00:00:00Z" == t.to_iso());
+ REQUIRE(t.valid());
+ }
+
+ SECTION("can be initialized from string") {
+ std::string s = "2000-01-01T00:00:00Z";
+ osmium::Timestamp t(s);
+ REQUIRE("2000-01-01T00:00:00Z" == t.to_iso());
+ REQUIRE(t.valid());
}
SECTION("throws if initialized from bad string") {
@@ -50,6 +61,10 @@ TEST_CASE("Timestamp") {
osmium::Timestamp t1(10);
osmium::Timestamp t2(50);
REQUIRE(t1 < t2);
+ REQUIRE(t1 > osmium::start_of_time());
+ REQUIRE(t2 > osmium::start_of_time());
+ REQUIRE(t1 < osmium::end_of_time());
+ REQUIRE(t2 < osmium::end_of_time());
}
SECTION("can be written to stream") {
diff --git a/test/t/buffer/test_buffer_node.cpp b/test/t/buffer/test_buffer_node.cpp
index 9bc8f70..e985009 100644
--- a/test/t/buffer/test_buffer_node.cpp
+++ b/test/t/buffer/test_buffer_node.cpp
@@ -56,13 +56,14 @@ void check_node_2(osmium::Node& node) {
REQUIRE(2 == n);
}
-TEST_CASE("Buffer_Node") {
+TEST_CASE("Node in Buffer") {
- SECTION("buffer_node") {
- constexpr size_t buffer_size = 10000;
- unsigned char data[buffer_size];
+ constexpr size_t buffer_size = 10000;
+ unsigned char data[buffer_size];
- osmium::memory::Buffer buffer(data, buffer_size, 0);
+ osmium::memory::Buffer buffer(data, buffer_size, 0);
+
+ SECTION("Add node to buffer") {
{
// add node 1
@@ -132,4 +133,37 @@ TEST_CASE("Buffer_Node") {
}
+ SECTION("Add buffer to another one") {
+
+ {
+ // add node 1
+ osmium::builder::NodeBuilder node_builder(buffer);
+ osmium::Node& node = node_builder.object();
+ REQUIRE(osmium::item_type::node == node.type());
+
+ node.set_id(1);
+ node.set_version(3);
+ node.set_visible(true);
+ node.set_changeset(333);
+ node.set_uid(21);
+ node.set_timestamp(123);
+ node.set_location(osmium::Location(3.5, 4.7));
+
+ node_builder.add_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(node.timestamp() == 123);
+ }
+
}
+
diff --git a/test/t/util/test_data_file.cpp b/test/t/util/test_data_file.cpp
deleted file mode 100644
index 792cedf..0000000
--- a/test/t/util/test_data_file.cpp
+++ /dev/null
@@ -1,81 +0,0 @@
-#include "catch.hpp"
-
-#include <cstring>
-
-#include <osmium/util/data_file.hpp>
-
-TEST_CASE("temporary file") {
-
- SECTION("create/open") {
- osmium::util::DataFile file;
-
- REQUIRE(!!file);
- int fd = file.fd();
-
- REQUIRE(fd > 0);
-
- const char buf[] = "foobar";
- REQUIRE(::write(fd, buf, sizeof(buf)) == sizeof(buf));
-
- file.close();
-
- REQUIRE(!file);
- }
-
-}
-
-TEST_CASE("named file") {
-
- SECTION("create/open") {
- {
- osmium::util::DataFile file("test.data", true);
-
- REQUIRE(!!file);
- int fd = file.fd();
-
- REQUIRE(fd > 0);
-
- REQUIRE(file.size() == 0);
-
- const char buf[] = "foobar";
- REQUIRE(::write(fd, buf, sizeof(buf) - 1) == sizeof(buf) - 1);
-
- file.close();
-
- REQUIRE(!file);
- }
- {
- osmium::util::DataFile file("test.data", false);
-
- REQUIRE(!!file);
- int fd = file.fd();
-
- REQUIRE(fd > 0);
-
- REQUIRE(file.size() == 6);
-
- char buf[10];
- auto len = ::read(fd, buf, sizeof(buf));
-
- REQUIRE(len == 6);
- REQUIRE(!strncmp(buf, "foobar", 6));
-
- file.close();
-
- REQUIRE(!file);
- REQUIRE(unlink("test.data") == 0);
- }
- }
-
- SECTION("grow file") {
- osmium::util::DataFile file("test.data", true);
-
- REQUIRE(!!file);
-
- REQUIRE(file.size() == 0);
- file.grow(10);
- REQUIRE(file.size() == 10);
- }
-
-}
-
diff --git a/test/t/util/test_options.cpp b/test/t/util/test_options.cpp
index c1e13bd..8cba095 100644
--- a/test/t/util/test_options.cpp
+++ b/test/t/util/test_options.cpp
@@ -8,7 +8,7 @@ TEST_CASE("Options") {
osmium::util::Options o;
- SECTION("set_simple") {
+ SECTION("set a single value from string") {
o.set("foo", "bar");
REQUIRE("bar" == o.get("foo"));
REQUIRE("" == o.get("empty"));
@@ -23,7 +23,7 @@ TEST_CASE("Options") {
REQUIRE(1 == o.size());
}
- SECTION("set_from_bool") {
+ SECTION("set values from booleans") {
o.set("t", true);
o.set("f", false);
REQUIRE("true" == o.get("t"));
@@ -39,13 +39,13 @@ TEST_CASE("Options") {
REQUIRE(2 == o.size());
}
- SECTION("set_from_single_string_with_equals") {
+ SECTION("set value from string with equal sign") {
o.set("foo=bar");
REQUIRE("bar" == o.get("foo"));
REQUIRE(1 == o.size());
}
- SECTION("set_from_single_string_without_equals") {
+ SECTION("set value from string without equal sign") {
o.set("foo");
REQUIRE("true" == o.get("foo"));
@@ -57,3 +57,25 @@ TEST_CASE("Options") {
}
+TEST_CASE("Options with initializer list") {
+
+ osmium::util::Options o{ { "foo", "true" }, { "bar", "17" } };
+
+ REQUIRE(o.get("foo") == "true");
+ REQUIRE(o.get("bar") == "17");
+ REQUIRE(o.is_true("foo"));
+ REQUIRE_FALSE(o.is_true("bar"));
+ REQUIRE(o.size() == 2);
+
+ SECTION("Change existing value") {
+ o.set("foo", "false");
+ REQUIRE_FALSE(o.is_true("foo"));
+ }
+
+ SECTION("Add new value") {
+ o.set("new", "something");
+ REQUIRE_FALSE(o.is_true("new"));
+ REQUIRE(o.get("new") == "something");
+ }
+}
+
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-grass/libosmium.git
More information about the Pkg-grass-devel
mailing list