Merge commit '879f7eb04200d7d2c28af565229bf6e3d54274fd' into retry/libosmium
This commit is contained in:
@@ -517,6 +517,16 @@ namespace osmium {
|
||||
*/
|
||||
using const_iterator = t_const_iterator<osmium::OSMEntity>;
|
||||
|
||||
template <typename T>
|
||||
ItemIteratorRange<T> select() {
|
||||
return ItemIteratorRange<T>{m_data, m_data + m_committed};
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
ItemIteratorRange<const T> select() const {
|
||||
return ItemIteratorRange<const T>{m_data, m_data + m_committed};
|
||||
}
|
||||
|
||||
/**
|
||||
* Get iterator for iterating over all items of type T in the
|
||||
* buffer.
|
||||
|
||||
+11
-5
@@ -44,17 +44,23 @@ namespace osmium {
|
||||
namespace memory {
|
||||
|
||||
template <typename TMember>
|
||||
class CollectionIterator : public std::iterator<std::forward_iterator_tag, TMember> {
|
||||
class CollectionIterator {
|
||||
|
||||
// This data_type is either 'unsigned char*' or 'const unsigned char*' depending
|
||||
// on whether TMember is const. This allows this class to be used as an iterator and
|
||||
// as a const_iterator.
|
||||
typedef typename std::conditional<std::is_const<TMember>::value, const unsigned char*, unsigned char*>::type data_type;
|
||||
using data_type = typename std::conditional<std::is_const<TMember>::value, const unsigned char*, unsigned char*>::type;
|
||||
|
||||
data_type m_data;
|
||||
|
||||
public:
|
||||
|
||||
using iterator_category = std::forward_iterator_tag;
|
||||
using value_type = TMember;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
using pointer = value_type*;
|
||||
using reference = value_type&;
|
||||
|
||||
CollectionIterator() noexcept :
|
||||
m_data(nullptr) {
|
||||
}
|
||||
@@ -112,9 +118,9 @@ namespace osmium {
|
||||
|
||||
public:
|
||||
|
||||
typedef CollectionIterator<TMember> iterator;
|
||||
typedef CollectionIterator<const TMember> const_iterator;
|
||||
typedef TMember value_type;
|
||||
using iterator = CollectionIterator<TMember>;
|
||||
using const_iterator = CollectionIterator<const TMember>;
|
||||
using value_type = TMember;
|
||||
|
||||
static constexpr osmium::item_type itemtype = TCollectionItemType;
|
||||
|
||||
|
||||
+29
-7
@@ -33,8 +33,10 @@ DEALINGS IN THE SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <type_traits>
|
||||
|
||||
#include <osmium/util/cast.hpp>
|
||||
|
||||
namespace osmium {
|
||||
|
||||
@@ -45,16 +47,21 @@ namespace osmium {
|
||||
class Builder;
|
||||
} // namespace builder
|
||||
|
||||
enum class diff_indicator_type {
|
||||
none = 0,
|
||||
left = 1,
|
||||
right = 2,
|
||||
both = 3
|
||||
}; // diff_indicator_type
|
||||
|
||||
namespace memory {
|
||||
|
||||
typedef uint32_t item_size_type;
|
||||
using item_size_type = uint32_t;
|
||||
|
||||
// align datastructures to this many bytes
|
||||
constexpr item_size_type align_bytes = 8;
|
||||
|
||||
template <typename T>
|
||||
inline T padded_length(T length) noexcept {
|
||||
static_assert(std::is_integral<T>::value && std::is_unsigned<T>::value, "Template parameter must be unsigned integral type");
|
||||
inline std::size_t padded_length(std::size_t length) noexcept {
|
||||
return (length + align_bytes - 1) & ~(align_bytes - 1);
|
||||
}
|
||||
|
||||
@@ -100,7 +107,8 @@ namespace osmium {
|
||||
item_size_type m_size;
|
||||
item_type m_type;
|
||||
uint16_t m_removed : 1;
|
||||
uint16_t m_padding : 15;
|
||||
uint16_t m_diff : 2;
|
||||
uint16_t m_padding : 13;
|
||||
|
||||
template <typename TMember>
|
||||
friend class CollectionIterator;
|
||||
@@ -121,6 +129,7 @@ namespace osmium {
|
||||
m_size(size),
|
||||
m_type(type),
|
||||
m_removed(false),
|
||||
m_diff(0),
|
||||
m_padding(0) {
|
||||
}
|
||||
|
||||
@@ -150,7 +159,7 @@ namespace osmium {
|
||||
}
|
||||
|
||||
item_size_type padded_size() const {
|
||||
return padded_length(m_size);
|
||||
return static_cast_with_assert<item_size_type>(padded_length(m_size));
|
||||
}
|
||||
|
||||
item_type type() const noexcept {
|
||||
@@ -165,6 +174,19 @@ namespace osmium {
|
||||
m_removed = removed;
|
||||
}
|
||||
|
||||
diff_indicator_type diff() const noexcept {
|
||||
return diff_indicator_type(m_diff);
|
||||
}
|
||||
|
||||
char diff_as_char() const noexcept {
|
||||
static constexpr const char* diff_chars = "*-+ ";
|
||||
return diff_chars[m_diff];
|
||||
}
|
||||
|
||||
void set_diff(diff_indicator_type diff) noexcept {
|
||||
m_diff = uint16_t(diff);
|
||||
}
|
||||
|
||||
}; // class Item
|
||||
|
||||
static_assert(sizeof(Item) == 8, "Class osmium::Item has wrong size!");
|
||||
|
||||
+110
-15
@@ -34,16 +34,29 @@ DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
#include <iterator>
|
||||
#include <iosfwd>
|
||||
#include <type_traits>
|
||||
|
||||
#include <osmium/fwd.hpp>
|
||||
#include <osmium/memory/item.hpp>
|
||||
#include <osmium/osm/item_type.hpp>
|
||||
|
||||
namespace osmium {
|
||||
|
||||
class Area;
|
||||
class Changeset;
|
||||
class InnerRing;
|
||||
class Node;
|
||||
class OSMEntity;
|
||||
class OSMObject;
|
||||
class OuterRing;
|
||||
class Relation;
|
||||
class RelationMemberList;
|
||||
class TagList;
|
||||
class Way;
|
||||
class WayNodeList;
|
||||
|
||||
namespace memory {
|
||||
|
||||
namespace detail {
|
||||
@@ -116,19 +129,19 @@ namespace osmium {
|
||||
} // namespace detail
|
||||
|
||||
template <typename TMember>
|
||||
class ItemIterator : public std::iterator<std::forward_iterator_tag, TMember> {
|
||||
class ItemIterator {
|
||||
|
||||
static_assert(std::is_base_of<osmium::memory::Item, TMember>::value, "TMember must derive from osmium::memory::Item");
|
||||
|
||||
// This data_type is either 'unsigned char*' or 'const unsigned char*' depending
|
||||
// on whether TMember is const. This allows this class to be used as an iterator and
|
||||
// as a const_iterator.
|
||||
typedef typename std::conditional<std::is_const<TMember>::value, const unsigned char*, unsigned char*>::type data_type;
|
||||
using data_type = typename std::conditional<std::is_const<TMember>::value, const unsigned char*, unsigned char*>::type;
|
||||
|
||||
data_type m_data;
|
||||
data_type m_end;
|
||||
|
||||
void advance_to_next_item_of_right_type() {
|
||||
void advance_to_next_item_of_right_type() noexcept {
|
||||
while (m_data != m_end &&
|
||||
!detail::type_is_compatible<typename std::remove_const<TMember>::type>(reinterpret_cast<const osmium::memory::Item*>(m_data)->type())) {
|
||||
m_data = reinterpret_cast<TMember*>(m_data)->next();
|
||||
@@ -137,23 +150,29 @@ namespace osmium {
|
||||
|
||||
public:
|
||||
|
||||
using iterator_category = std::forward_iterator_tag;
|
||||
using value_type = TMember;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
using pointer = value_type*;
|
||||
using reference = value_type&;
|
||||
|
||||
ItemIterator() noexcept :
|
||||
m_data(nullptr),
|
||||
m_end(nullptr) {
|
||||
}
|
||||
|
||||
ItemIterator(data_type data, data_type end) :
|
||||
ItemIterator(data_type data, data_type end) noexcept :
|
||||
m_data(data),
|
||||
m_end(end) {
|
||||
advance_to_next_item_of_right_type();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
ItemIterator<T> cast() const {
|
||||
ItemIterator<T> cast() const noexcept {
|
||||
return ItemIterator<T>(m_data, m_end);
|
||||
}
|
||||
|
||||
ItemIterator<TMember>& operator++() {
|
||||
ItemIterator<TMember>& operator++() noexcept {
|
||||
assert(m_data);
|
||||
assert(m_data != m_end);
|
||||
m_data = reinterpret_cast<TMember*>(m_data)->next();
|
||||
@@ -166,45 +185,50 @@ namespace osmium {
|
||||
* types. Do not use this unless you know what you are
|
||||
* doing.
|
||||
*/
|
||||
ItemIterator<TMember>& advance_once() {
|
||||
ItemIterator<TMember>& advance_once() noexcept {
|
||||
assert(m_data);
|
||||
assert(m_data != m_end);
|
||||
m_data = reinterpret_cast<TMember*>(m_data)->next();
|
||||
return *static_cast<ItemIterator<TMember>*>(this);
|
||||
}
|
||||
|
||||
ItemIterator<TMember> operator++(int) {
|
||||
ItemIterator<TMember> operator++(int) noexcept {
|
||||
ItemIterator<TMember> tmp(*this);
|
||||
operator++();
|
||||
return tmp;
|
||||
}
|
||||
|
||||
bool operator==(const ItemIterator<TMember>& rhs) const {
|
||||
bool operator==(const ItemIterator<TMember>& rhs) const noexcept {
|
||||
return m_data == rhs.m_data && m_end == rhs.m_end;
|
||||
}
|
||||
|
||||
bool operator!=(const ItemIterator<TMember>& rhs) const {
|
||||
bool operator!=(const ItemIterator<TMember>& rhs) const noexcept {
|
||||
return !(*this == rhs);
|
||||
}
|
||||
|
||||
unsigned char* data() const {
|
||||
data_type data() noexcept {
|
||||
assert(m_data);
|
||||
return m_data;
|
||||
}
|
||||
|
||||
TMember& operator*() const {
|
||||
const unsigned char* data() const noexcept {
|
||||
assert(m_data);
|
||||
return m_data;
|
||||
}
|
||||
|
||||
TMember& operator*() const noexcept {
|
||||
assert(m_data);
|
||||
assert(m_data != m_end);
|
||||
return *reinterpret_cast<TMember*>(m_data);
|
||||
}
|
||||
|
||||
TMember* operator->() const {
|
||||
TMember* operator->() const noexcept {
|
||||
assert(m_data);
|
||||
assert(m_data != m_end);
|
||||
return reinterpret_cast<TMember*>(m_data);
|
||||
}
|
||||
|
||||
explicit operator bool() const {
|
||||
explicit operator bool() const noexcept {
|
||||
return (m_data != nullptr) && (m_data != m_end);
|
||||
}
|
||||
|
||||
@@ -221,6 +245,77 @@ namespace osmium {
|
||||
return out;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
class ItemIteratorRange {
|
||||
|
||||
static_assert(std::is_base_of<osmium::memory::Item, T>::value, "Template parameter must derive from osmium::memory::Item");
|
||||
|
||||
// This data_type is either 'unsigned char*' or
|
||||
// 'const unsigned char*' depending on whether T is const.
|
||||
using data_type = typename std::conditional<std::is_const<T>::value, const unsigned char*, unsigned char*>::type;
|
||||
|
||||
data_type m_begin;
|
||||
data_type m_end;
|
||||
|
||||
public:
|
||||
|
||||
using iterator = ItemIterator<T>;
|
||||
using const_iterator = ItemIterator<const T>;
|
||||
|
||||
ItemIteratorRange(data_type first, data_type last) noexcept :
|
||||
m_begin(first),
|
||||
m_end(last) {
|
||||
}
|
||||
|
||||
iterator begin() noexcept {
|
||||
return iterator{m_begin, m_end};
|
||||
}
|
||||
|
||||
iterator end() noexcept {
|
||||
return iterator{m_end, m_end};
|
||||
}
|
||||
|
||||
const_iterator cbegin() const noexcept {
|
||||
return const_iterator{m_begin, m_end};
|
||||
}
|
||||
|
||||
const_iterator cend() const noexcept {
|
||||
return const_iterator{m_end, m_end};
|
||||
}
|
||||
|
||||
const_iterator begin() const noexcept {
|
||||
return cbegin();
|
||||
}
|
||||
|
||||
const_iterator end() const noexcept {
|
||||
return cend();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the number of items in this range.
|
||||
*
|
||||
* Note that this methods has worst-case complexity O(n) with n
|
||||
* being the number of items in the underlying range.
|
||||
*/
|
||||
size_t size() const {
|
||||
if (m_begin == m_end) {
|
||||
return 0;
|
||||
}
|
||||
return std::distance(cbegin(), cend());
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this range empty?
|
||||
*
|
||||
* Note that this methods has worst-case complexity O(n) with n
|
||||
* being the number of items in the underlying range.
|
||||
*/
|
||||
bool empty() const {
|
||||
return size() == 0;
|
||||
}
|
||||
|
||||
}; // class ItemIteratorRange
|
||||
|
||||
} // namespace memory
|
||||
|
||||
} // namespace osmium
|
||||
|
||||
Reference in New Issue
Block a user