Merge commit '879f7eb04200d7d2c28af565229bf6e3d54274fd' into retry/libosmium

This commit is contained in:
karenzshea
2016-10-03 13:08:59 -04:00
208 changed files with 11590 additions and 4051 deletions
+10
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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