Merge commit 'babbda98a6ea1d53a8bc5015ef5dfb313c47186a' into libosmium-2.10.0

This commit is contained in:
Daniel J. Hofmann
2016-11-11 15:50:02 +01:00
120 changed files with 4266 additions and 2031 deletions
+56 -26
View File
@@ -113,6 +113,9 @@ namespace osmium {
size_t m_capacity;
size_t m_written;
size_t m_committed;
#ifndef NDEBUG
uint8_t m_builder_count{0};
#endif
auto_grow m_auto_grow {auto_grow::no};
std::function<void(Buffer&)> m_full;
@@ -216,13 +219,28 @@ namespace osmium {
~Buffer() = default;
#ifndef NDEBUG
void increment_builder_count() noexcept {
++m_builder_count;
}
void decrement_builder_count() noexcept {
assert(m_builder_count > 0);
--m_builder_count;
}
uint8_t builder_count() const noexcept {
return m_builder_count;
}
#endif
/**
* Return a pointer to data inside the buffer.
*
* @pre The buffer must be valid.
*/
unsigned char* data() const noexcept {
assert(m_data);
assert(m_data && "This must be a valid buffer");
return m_data;
}
@@ -258,7 +276,7 @@ namespace osmium {
* @pre The buffer must be valid.
*/
bool is_aligned() const noexcept {
assert(m_data);
assert(m_data && "This must be a valid buffer");
return (m_written % align_bytes == 0) && (m_committed % align_bytes == 0);
}
@@ -283,7 +301,7 @@ namespace osmium {
* than the difference between committed() and capacity().
*/
OSMIUM_DEPRECATED void set_full_callback(std::function<void(Buffer&)> full) {
assert(m_data);
assert(m_data && "This must be a valid buffer");
m_full = full;
}
@@ -292,7 +310,6 @@ namespace osmium {
* This works only with internally memory-managed buffers.
* If the given size is not larger than the current capacity,
* nothing is done.
* Already written but not committed data is discarded.
*
* @pre The buffer must be valid.
*
@@ -305,7 +322,7 @@ namespace osmium {
* @throws std::bad_alloc if there isn't enough memory available.
*/
void grow(size_t size) {
assert(m_data);
assert(m_data && "This must be a valid buffer");
if (!m_memory) {
throw std::logic_error("Can't grow Buffer if it doesn't use internal memory management.");
}
@@ -325,15 +342,18 @@ namespace osmium {
/**
* Mark currently written bytes in the buffer as committed.
*
* @pre The buffer must be valid and aligned properly (as indicated
* @pre The buffer must be valid.
* @pre The buffer must be aligned properly (as indicated
* by is_aligned().
* @pre No builder can be open on this buffer.
*
* @returns Number of committed bytes before this commit. Can be
* used as an offset into the buffer to get to the
* object being committed by this call.
*/
size_t commit() {
assert(m_data);
assert(m_data && "This must be a valid buffer");
assert(m_builder_count == 0 && "Make sure there are no Builder objects still in scope");
assert(is_aligned());
const size_t offset = m_committed;
@@ -345,9 +365,11 @@ namespace osmium {
* Roll back changes in buffer to last committed state.
*
* @pre The buffer must be valid.
* @pre No builder can be open on this buffer.
*/
void rollback() {
assert(m_data);
assert(m_data && "This must be a valid buffer");
assert(m_builder_count == 0 && "Make sure there are no Builder objects still in scope");
m_written = m_committed;
}
@@ -356,9 +378,12 @@ namespace osmium {
*
* No-op on an invalid buffer.
*
* @pre No builder can be open on this buffer.
*
* @returns Number of bytes in the buffer before it was cleared.
*/
size_t clear() {
assert(m_builder_count == 0 && "Make sure there are no Builder objects still in scope");
const size_t committed = m_committed;
m_written = 0;
m_committed = 0;
@@ -377,7 +402,7 @@ namespace osmium {
*/
template <typename T>
T& get(const size_t offset) const {
assert(m_data);
assert(m_data && "This must be a valid buffer");
return *reinterpret_cast<T*>(&m_data[offset]);
}
@@ -415,7 +440,7 @@ namespace osmium {
* no callback defined and the buffer isn't auto-growing.
*/
unsigned char* reserve_space(const size_t size) {
assert(m_data);
assert(m_data && "This must be a valid buffer");
// try to flush the buffer empty first.
if (m_written + size > m_capacity && m_full) {
m_full(*this);
@@ -455,7 +480,7 @@ namespace osmium {
*/
template <typename T>
T& add_item(const T& item) {
assert(m_data);
assert(m_data && "This must be a valid buffer");
unsigned char* target = reserve_space(item.padded_size());
std::copy_n(reinterpret_cast<const unsigned char*>(&item), item.padded_size(), target);
return *reinterpret_cast<T*>(target);
@@ -465,6 +490,7 @@ namespace osmium {
* Add committed contents of the given buffer to this buffer.
*
* @pre The buffer must be valid.
* @pre No builder can be open on this buffer.
*
* Note that you have to eventually call commit() to actually
* commit this data.
@@ -472,7 +498,9 @@ namespace osmium {
* @param buffer The source of the copy. Must be valid.
*/
void add_buffer(const Buffer& buffer) {
assert(m_data && buffer);
assert(m_data && "This must be a valid buffer");
assert(buffer && "Buffer parameter must be a valid buffer");
assert(m_builder_count == 0 && "Make sure there are no Builder objects still in scope");
unsigned char* target = reserve_space(buffer.committed());
std::copy_n(buffer.data(), buffer.committed(), target);
}
@@ -482,11 +510,13 @@ namespace osmium {
* you can use std::back_inserter.
*
* @pre The buffer must be valid.
* @pre No builder can be open on this buffer.
*
* @param item The item to be added.
*/
void push_back(const osmium::memory::Item& item) {
assert(m_data);
assert(m_data && "This must be a valid buffer");
assert(m_builder_count == 0 && "Make sure there are no Builder objects still in scope");
add_item(item);
commit();
}
@@ -537,7 +567,7 @@ namespace osmium {
*/
template <typename T>
t_iterator<T> begin() {
assert(m_data);
assert(m_data && "This must be a valid buffer");
return t_iterator<T>(m_data, m_data + m_committed);
}
@@ -550,7 +580,7 @@ namespace osmium {
* @returns Iterator to first OSMEntity in the buffer.
*/
iterator begin() {
assert(m_data);
assert(m_data && "This must be a valid buffer");
return iterator(m_data, m_data + m_committed);
}
@@ -565,7 +595,7 @@ namespace osmium {
*/
template <typename T>
t_iterator<T> get_iterator(size_t offset) {
assert(m_data);
assert(m_data && "This must be a valid buffer");
return t_iterator<T>(m_data + offset, m_data + m_committed);
}
@@ -579,7 +609,7 @@ namespace osmium {
* buffer.
*/
iterator get_iterator(size_t offset) {
assert(m_data);
assert(m_data && "This must be a valid buffer");
return iterator(m_data + offset, m_data + m_committed);
}
@@ -593,7 +623,7 @@ namespace osmium {
*/
template <typename T>
t_iterator<T> end() {
assert(m_data);
assert(m_data && "This must be a valid buffer");
return t_iterator<T>(m_data + m_committed, m_data + m_committed);
}
@@ -606,40 +636,40 @@ namespace osmium {
* @returns End iterator.
*/
iterator end() {
assert(m_data);
assert(m_data && "This must be a valid buffer");
return iterator(m_data + m_committed, m_data + m_committed);
}
template <typename T>
t_const_iterator<T> cbegin() const {
assert(m_data);
assert(m_data && "This must be a valid buffer");
return t_const_iterator<T>(m_data, m_data + m_committed);
}
const_iterator cbegin() const {
assert(m_data);
assert(m_data && "This must be a valid buffer");
return const_iterator(m_data, m_data + m_committed);
}
template <typename T>
t_const_iterator<T> get_iterator(size_t offset) const {
assert(m_data);
assert(m_data && "This must be a valid buffer");
return t_const_iterator<T>(m_data + offset, m_data + m_committed);
}
const_iterator get_iterator(size_t offset) const {
assert(m_data);
assert(m_data && "This must be a valid buffer");
return const_iterator(m_data + offset, m_data + m_committed);
}
template <typename T>
t_const_iterator<T> cend() const {
assert(m_data);
assert(m_data && "This must be a valid buffer");
return t_const_iterator<T>(m_data + m_committed, m_data + m_committed);
}
const_iterator cend() const {
assert(m_data);
assert(m_data && "This must be a valid buffer");
return const_iterator(m_data + m_committed, m_data + m_committed);
}
@@ -698,7 +728,7 @@ namespace osmium {
*/
template <typename TCallbackClass>
void purge_removed(TCallbackClass* callback) {
assert(m_data);
assert(m_data && "This must be a valid buffer");
if (begin() == end()) {
return;
}
+32 -15
View File
@@ -46,9 +46,9 @@ namespace osmium {
template <typename 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.
// 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.
using data_type = typename std::conditional<std::is_const<TMember>::value, const unsigned char*, unsigned char*>::type;
data_type m_data;
@@ -92,11 +92,11 @@ namespace osmium {
return m_data;
}
TMember& operator*() const {
TMember& operator*() const noexcept {
return *reinterpret_cast<TMember*>(m_data);
}
TMember* operator->() const {
TMember* operator->() const noexcept {
return reinterpret_cast<TMember*>(m_data);
}
@@ -118,9 +118,12 @@ namespace osmium {
public:
using iterator = CollectionIterator<TMember>;
using const_iterator = CollectionIterator<const TMember>;
using value_type = TMember;
using value_type = TMember;
using reference = TMember&;
using const_reference = const TMember&;
using iterator = CollectionIterator<TMember>;
using const_iterator = CollectionIterator<const TMember>;
using size_type = size_t;
static constexpr osmium::item_type itemtype = TCollectionItemType;
@@ -128,31 +131,45 @@ namespace osmium {
Item(sizeof(Collection<TMember, TCollectionItemType>), TCollectionItemType) {
}
bool empty() const {
/**
* Does this collection contain any items?
*
* Complexity: Constant.
*/
bool empty() const noexcept {
return sizeof(Collection<TMember, TCollectionItemType>) == byte_size();
}
iterator begin() {
/**
* Returns the number of items in this collection.
*
* Complexity: Linear in the number of items.
*/
size_type size() const noexcept {
return static_cast<size_type>(std::distance(begin(), end()));
}
iterator begin() noexcept {
return iterator(data() + sizeof(Collection<TMember, TCollectionItemType>));
}
iterator end() {
iterator end() noexcept {
return iterator(data() + byte_size());
}
const_iterator cbegin() const {
const_iterator cbegin() const noexcept {
return const_iterator(data() + sizeof(Collection<TMember, TCollectionItemType>));
}
const_iterator cend() const {
const_iterator cend() const noexcept {
return const_iterator(data() + byte_size());
}
const_iterator begin() const {
const_iterator begin() const noexcept {
return cbegin();
}
const_iterator end() const {
const_iterator end() const noexcept {
return cend();
}
+2 -2
View File
@@ -59,9 +59,9 @@ namespace osmium {
using item_size_type = uint32_t;
// align datastructures to this many bytes
constexpr item_size_type align_bytes = 8;
constexpr const item_size_type align_bytes = 8;
inline std::size_t padded_length(std::size_t length) noexcept {
inline constexpr std::size_t padded_length(std::size_t length) noexcept {
return (length + align_bytes - 1) & ~(align_bytes - 1);
}