Remove libosmium
This commit is contained in:
-103
@@ -1,103 +0,0 @@
|
||||
#ifndef OSMIUM_UTIL_CAST_HPP
|
||||
#define OSMIUM_UTIL_CAST_HPP
|
||||
|
||||
/*
|
||||
|
||||
This file is part of Osmium (http://osmcode.org/libosmium).
|
||||
|
||||
Copyright 2013-2016 Jochen Topf <jochen@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.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef assert
|
||||
# include <cassert>
|
||||
#endif
|
||||
|
||||
#include <cstdint>
|
||||
#include <limits>
|
||||
#include <type_traits>
|
||||
|
||||
namespace osmium {
|
||||
|
||||
// These functions are wrappers around static_cast<>() that call assert()
|
||||
// to check that there is no integer overflow happening before doing the
|
||||
// cast. There are several versions of this templated function here
|
||||
// depending on the types of the input and output. In any case, both input
|
||||
// and output have to be integral types. If the cast can't overflow, no
|
||||
// check is done.
|
||||
|
||||
template <typename A, typename B>
|
||||
struct are_real_integers :
|
||||
std::integral_constant<bool,
|
||||
std::is_integral<A>::value &&
|
||||
std::is_integral<B>::value &&
|
||||
!std::is_same<A, bool>::value &&
|
||||
!std::is_same<B, bool>::value> {
|
||||
};
|
||||
|
||||
template <typename T, typename F, typename std::enable_if<are_real_integers<T, F>::value && std::is_same<T, F>::value, int>::type = 0>
|
||||
inline T static_cast_with_assert(const F value) {
|
||||
return value;
|
||||
}
|
||||
|
||||
template <typename T, typename F, typename std::enable_if<are_real_integers<T, F>::value && !std::is_same<T, F>::value && (sizeof(T) > sizeof(F)), int>::type = 0>
|
||||
inline T static_cast_with_assert(const F value) {
|
||||
return static_cast<T>(value);
|
||||
}
|
||||
|
||||
template <typename T, typename F, typename std::enable_if<are_real_integers<T, F>::value && !std::is_same<T, F>::value && std::is_signed<T>::value == std::is_signed<F>::value && (sizeof(T) == sizeof(F)), int>::type = 0>
|
||||
inline T static_cast_with_assert(const F value) {
|
||||
return static_cast<T>(value);
|
||||
}
|
||||
|
||||
template <typename T, typename F, typename std::enable_if<are_real_integers<T, F>::value && !std::is_same<T, F>::value && (sizeof(T) < sizeof(F)) && std::is_signed<T>::value && std::is_signed<F>::value, int>::type = 0>
|
||||
inline T static_cast_with_assert(const F value) {
|
||||
assert(value >= std::numeric_limits<T>::min() && value <= std::numeric_limits<T>::max());
|
||||
return static_cast<T>(value);
|
||||
}
|
||||
|
||||
template <typename T, typename F, typename std::enable_if<are_real_integers<T, F>::value && !std::is_same<T, F>::value && (sizeof(T) <= sizeof(F)) && std::is_unsigned<T>::value && std::is_signed<F>::value, int>::type = 0>
|
||||
inline T static_cast_with_assert(const F value) {
|
||||
assert(value >= 0 && static_cast<typename std::make_unsigned<F>::type>(value) <= std::numeric_limits<T>::max());
|
||||
return static_cast<T>(value);
|
||||
}
|
||||
|
||||
template <typename T, typename F, typename std::enable_if<are_real_integers<T, F>::value && !std::is_same<T, F>::value && (sizeof(T) < sizeof(F)) && std::is_unsigned<T>::value && std::is_unsigned<F>::value, int>::type = 0>
|
||||
inline T static_cast_with_assert(const F value) {
|
||||
assert(value <= std::numeric_limits<T>::max());
|
||||
return static_cast<T>(value);
|
||||
}
|
||||
|
||||
template <typename T, typename F, typename std::enable_if<are_real_integers<T, F>::value && !std::is_same<T, F>::value && (sizeof(T) <= sizeof(F)) && std::is_signed<T>::value && std::is_unsigned<F>::value, int>::type = 0>
|
||||
inline T static_cast_with_assert(const F value) {
|
||||
assert(static_cast<int64_t>(value) <= static_cast<int64_t>(std::numeric_limits<T>::max()));
|
||||
return static_cast<T>(value);
|
||||
}
|
||||
|
||||
} // namespace osmium
|
||||
|
||||
#endif // OSMIUM_UTIL_CAST_HPP
|
||||
@@ -1,53 +0,0 @@
|
||||
#ifndef OSMIUM_UTIL_COMPATIBILITY_HPP
|
||||
#define OSMIUM_UTIL_COMPATIBILITY_HPP
|
||||
|
||||
/*
|
||||
|
||||
This file is part of Osmium (http://osmcode.org/libosmium).
|
||||
|
||||
Copyright 2013-2016 Jochen Topf <jochen@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.
|
||||
|
||||
*/
|
||||
|
||||
// Workarounds for MSVC which doesn't support
|
||||
// * [[noreturn]]
|
||||
#ifdef _MSC_VER
|
||||
# define OSMIUM_NORETURN __declspec(noreturn)
|
||||
#else
|
||||
# define OSMIUM_NORETURN [[noreturn]]
|
||||
#endif
|
||||
|
||||
// [[deprecated]] is only available in C++14, use this for the time being
|
||||
#ifdef __GNUC__
|
||||
# define OSMIUM_DEPRECATED __attribute__((deprecated))
|
||||
#elif defined(_MSC_VER)
|
||||
# define OSMIUM_DEPRECATED __declspec(deprecated)
|
||||
#else
|
||||
# define OSMIUM_DEPRECATED
|
||||
#endif
|
||||
|
||||
#endif // OSMIUM_UTIL_COMPATIBILITY_HPP
|
||||
@@ -1,72 +0,0 @@
|
||||
#ifndef OSMIUM_UTIL_CONFIG_HPP
|
||||
#define OSMIUM_UTIL_CONFIG_HPP
|
||||
|
||||
/*
|
||||
|
||||
This file is part of Osmium (http://osmcode.org/libosmium).
|
||||
|
||||
Copyright 2013-2016 Jochen Topf <jochen@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 <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# define strcasecmp _stricmp
|
||||
#endif
|
||||
|
||||
namespace osmium {
|
||||
|
||||
namespace config {
|
||||
|
||||
inline int get_pool_threads() {
|
||||
const char* env = getenv("OSMIUM_POOL_THREADS");
|
||||
if (env) {
|
||||
return std::atoi(env);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline bool use_pool_threads_for_pbf_parsing() {
|
||||
const char* env = getenv("OSMIUM_USE_POOL_THREADS_FOR_PBF_PARSING");
|
||||
if (env) {
|
||||
if (!strcasecmp(env, "off") ||
|
||||
!strcasecmp(env, "false") ||
|
||||
!strcasecmp(env, "no") ||
|
||||
!strcasecmp(env, "0")) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace config
|
||||
|
||||
} // namespace osmium
|
||||
|
||||
#endif // OSMIUM_UTIL_CONFIG_HPP
|
||||
-174
@@ -1,174 +0,0 @@
|
||||
#ifndef OSMIUM_UTIL_DELTA_HPP
|
||||
#define OSMIUM_UTIL_DELTA_HPP
|
||||
|
||||
/*
|
||||
|
||||
This file is part of Osmium (http://osmcode.org/libosmium).
|
||||
|
||||
Copyright 2013-2016 Jochen Topf <jochen@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 <iterator>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#include <osmium/util/cast.hpp>
|
||||
|
||||
namespace osmium {
|
||||
|
||||
namespace util {
|
||||
|
||||
/**
|
||||
* Helper class for delta encoding.
|
||||
*/
|
||||
template <typename TValue, typename TDelta = int64_t>
|
||||
class DeltaEncode {
|
||||
|
||||
static_assert(std::is_integral<TValue>::value,
|
||||
"DeltaEncode value type must be some integer");
|
||||
|
||||
static_assert(std::is_integral<TDelta>::value && std::is_signed<TDelta>::value,
|
||||
"DeltaEncode delta type must be some signed integer");
|
||||
|
||||
TValue m_value;
|
||||
|
||||
public:
|
||||
|
||||
using value_type = TValue;
|
||||
using delta_type = TDelta;
|
||||
|
||||
explicit DeltaEncode(TValue value = 0) :
|
||||
m_value(value) {
|
||||
}
|
||||
|
||||
void clear() noexcept {
|
||||
m_value = 0;
|
||||
}
|
||||
|
||||
TValue value() const noexcept {
|
||||
return m_value;
|
||||
}
|
||||
|
||||
TDelta update(TValue new_value) noexcept {
|
||||
using std::swap;
|
||||
swap(m_value, new_value);
|
||||
return static_cast_with_assert<TDelta>(m_value) -
|
||||
static_cast_with_assert<TDelta>(new_value);
|
||||
}
|
||||
|
||||
}; // class DeltaEncode
|
||||
|
||||
/**
|
||||
* Helper class for delta decoding.
|
||||
*/
|
||||
template <typename TValue, typename TDelta = int64_t>
|
||||
class DeltaDecode {
|
||||
|
||||
static_assert(std::is_integral<TValue>::value,
|
||||
"DeltaDecode value type must be some integer");
|
||||
|
||||
static_assert(std::is_integral<TDelta>::value && std::is_signed<TDelta>::value,
|
||||
"DeltaDecode delta type must be some signed integer");
|
||||
|
||||
TValue m_value;
|
||||
|
||||
public:
|
||||
|
||||
using value_type = TValue;
|
||||
using delta_type = TDelta;
|
||||
|
||||
DeltaDecode() :
|
||||
m_value(0) {
|
||||
}
|
||||
|
||||
void clear() noexcept {
|
||||
m_value = 0;
|
||||
}
|
||||
|
||||
TValue update(TDelta delta) noexcept {
|
||||
m_value = static_cast_with_assert<TValue>(
|
||||
static_cast_with_assert<TDelta>(m_value) + delta);
|
||||
return m_value;
|
||||
}
|
||||
|
||||
}; // class DeltaDecode
|
||||
|
||||
template <typename TBaseIterator, typename TTransform, typename TValue, typename TDelta = int64_t>
|
||||
class DeltaEncodeIterator : public std::iterator<std::input_iterator_tag, TValue> {
|
||||
|
||||
TBaseIterator m_it;
|
||||
TBaseIterator m_end;
|
||||
TTransform m_trans;
|
||||
DeltaEncode<TValue, TDelta> m_value;
|
||||
TDelta m_delta;
|
||||
|
||||
public:
|
||||
|
||||
using value_type = TValue;
|
||||
using delta_type = TDelta;
|
||||
|
||||
DeltaEncodeIterator(TBaseIterator first, TBaseIterator last, TTransform& trans) :
|
||||
m_it(first),
|
||||
m_end(last),
|
||||
m_trans(trans),
|
||||
m_value(m_it != m_end ? m_trans(m_it) : 0),
|
||||
m_delta(static_cast_with_assert<TDelta>(m_value.value())) {
|
||||
}
|
||||
|
||||
DeltaEncodeIterator& operator++() {
|
||||
if (++m_it != m_end) {
|
||||
m_delta = m_value.update(m_trans(m_it));
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
DeltaEncodeIterator operator++(int) {
|
||||
DeltaEncodeIterator tmp(*this);
|
||||
operator++();
|
||||
return tmp;
|
||||
}
|
||||
|
||||
TDelta operator*() {
|
||||
return m_delta;
|
||||
}
|
||||
|
||||
bool operator==(const DeltaEncodeIterator& rhs) const {
|
||||
return m_it == rhs.m_it && m_end == rhs.m_end;
|
||||
}
|
||||
|
||||
bool operator!=(const DeltaEncodeIterator& rhs) const {
|
||||
return !(*this == rhs);
|
||||
}
|
||||
|
||||
}; // class DeltaEncodeIterator
|
||||
|
||||
} // namespace util
|
||||
|
||||
} // namespace osmium
|
||||
|
||||
#endif // OSMIUM_UTIL_DELTA_HPP
|
||||
@@ -1,97 +0,0 @@
|
||||
#ifndef OSMIUM_UTIL_DOUBLE_HPP
|
||||
#define OSMIUM_UTIL_DOUBLE_HPP
|
||||
|
||||
/*
|
||||
|
||||
This file is part of Osmium (http://osmcode.org/libosmium).
|
||||
|
||||
Copyright 2013-2016 Jochen Topf <jochen@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 <algorithm>
|
||||
#include <cassert>
|
||||
#include <cmath>
|
||||
#include <cstdio>
|
||||
#include <iterator>
|
||||
#include <string>
|
||||
|
||||
namespace osmium {
|
||||
|
||||
namespace util {
|
||||
|
||||
constexpr int max_double_length = 20; // should fit any double
|
||||
|
||||
/**
|
||||
* Write double to iterator, removing superfluous '0' characters at
|
||||
* the end. The decimal dot will also be removed if necessary.
|
||||
*
|
||||
* @tparam T iterator type
|
||||
* @param iterator output iterator
|
||||
* @param value the value that should be written
|
||||
* @param precision max number of digits after the decimal point (must be <= 17)
|
||||
*/
|
||||
template <typename T>
|
||||
inline T double2string(T iterator, double value, int precision) {
|
||||
assert(precision <= 17);
|
||||
|
||||
char buffer[max_double_length];
|
||||
|
||||
#ifndef _MSC_VER
|
||||
int len = snprintf(buffer, max_double_length, "%.*f", precision, value);
|
||||
#else
|
||||
int len = _snprintf(buffer, max_double_length, "%.*f", precision, value);
|
||||
#endif
|
||||
assert(len > 0 && len < max_double_length);
|
||||
|
||||
while (buffer[len-1] == '0') {
|
||||
--len;
|
||||
}
|
||||
if (buffer[len-1] == '.') {
|
||||
--len;
|
||||
}
|
||||
|
||||
return std::copy_n(buffer, len, iterator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write double to string, removing superfluous '0' characters at
|
||||
* the end. The decimal dot will also be removed if necessary.
|
||||
*
|
||||
* @param out string
|
||||
* @param value the value that should be written
|
||||
* @param precision max number of digits after the decimal point
|
||||
*/
|
||||
inline void double2string(std::string& out, double value, int precision) {
|
||||
double2string(std::back_inserter(out), value, precision);
|
||||
}
|
||||
|
||||
} // namespace util
|
||||
|
||||
} // namespace osmium
|
||||
|
||||
#endif // OSMIUM_UTIL_DOUBLE_HPP
|
||||
@@ -1,45 +0,0 @@
|
||||
#ifndef OSMIUM_UTIL_ENDIAN_HPP
|
||||
#define OSMIUM_UTIL_ENDIAN_HPP
|
||||
|
||||
/*
|
||||
|
||||
This file is part of Osmium (http://osmcode.org/libosmium).
|
||||
|
||||
Copyright 2013-2016 Jochen Topf <jochen@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.
|
||||
|
||||
*/
|
||||
|
||||
// Windows is only available for little endian architectures
|
||||
// http://stackoverflow.com/questions/6449468/can-i-safely-assume-that-windows-installations-will-always-be-little-endian
|
||||
#if !defined(_WIN32) && !defined(__APPLE__)
|
||||
# include <endian.h>
|
||||
#else
|
||||
# define __LITTLE_ENDIAN 1234
|
||||
# define __BYTE_ORDER __LITTLE_ENDIAN
|
||||
#endif
|
||||
|
||||
#endif // OSMIUM_UTIL_ENDIAN_HPP
|
||||
-121
@@ -1,121 +0,0 @@
|
||||
#ifndef OSMIUM_UTIL_FILE_HPP
|
||||
#define OSMIUM_UTIL_FILE_HPP
|
||||
|
||||
/*
|
||||
|
||||
This file is part of Osmium (http://osmcode.org/libosmium).
|
||||
|
||||
Copyright 2013-2016 Jochen Topf <jochen@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 <system_error>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
# include <io.h>
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
#ifndef _MSC_VER
|
||||
# include <unistd.h>
|
||||
#else
|
||||
// https://msdn.microsoft.com/en-us/library/whx354w1.aspx
|
||||
# define ftruncate _chsize_s
|
||||
#endif
|
||||
|
||||
#include <osmium/util/cast.hpp>
|
||||
|
||||
namespace osmium {
|
||||
|
||||
namespace util {
|
||||
|
||||
/**
|
||||
* Get file size.
|
||||
* This is a small wrapper around a system call.
|
||||
*
|
||||
* @param fd File descriptor
|
||||
* @returns file size
|
||||
* @throws std::system_error If system call failed
|
||||
*/
|
||||
inline size_t file_size(int fd) {
|
||||
#ifdef _MSC_VER
|
||||
// Windows implementation
|
||||
// https://msdn.microsoft.com/en-us/library/dfbc2kec.aspx
|
||||
auto size = ::_filelengthi64(fd);
|
||||
if (size == -1L) {
|
||||
throw std::system_error(errno, std::system_category(), "_filelengthi64 failed");
|
||||
}
|
||||
return size_t(size);
|
||||
#else
|
||||
// Unix implementation
|
||||
struct stat s;
|
||||
if (::fstat(fd, &s) != 0) {
|
||||
throw std::system_error(errno, std::system_category(), "fstat failed");
|
||||
}
|
||||
return size_t(s.st_size);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Resize file.
|
||||
* Small wrapper around ftruncate(2) system call.
|
||||
*
|
||||
* @param fd File descriptor
|
||||
* @param new_size New size
|
||||
* @throws std::system_error If ftruncate(2) call failed
|
||||
*/
|
||||
inline void resize_file(int fd, size_t new_size) {
|
||||
if (::ftruncate(fd, static_cast_with_assert<off_t>(new_size)) != 0) {
|
||||
throw std::system_error(errno, std::system_category(), "ftruncate failed");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the page size for this system.
|
||||
*/
|
||||
inline size_t get_pagesize() {
|
||||
#ifdef _WIN32
|
||||
// Windows implementation
|
||||
SYSTEM_INFO si;
|
||||
GetSystemInfo(&si);
|
||||
return si.dwPageSize;
|
||||
#else
|
||||
// Unix implementation
|
||||
return size_t(::sysconf(_SC_PAGESIZE));
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace util
|
||||
|
||||
} // namespace osmium
|
||||
|
||||
#endif // OSMIUM_UTIL_FILE_HPP
|
||||
@@ -1,99 +0,0 @@
|
||||
#ifndef OSMIUM_UTIL_MEMORY_HPP
|
||||
#define OSMIUM_UTIL_MEMORY_HPP
|
||||
|
||||
/*
|
||||
|
||||
This file is part of Osmium (http://osmcode.org/libosmium).
|
||||
|
||||
Copyright 2013-2016 Jochen Topf <jochen@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 <cstdlib>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
|
||||
namespace osmium {
|
||||
|
||||
class MemoryUsage {
|
||||
|
||||
int m_current = 0;
|
||||
int m_peak = 0;
|
||||
|
||||
#ifdef __linux__
|
||||
int parse_number(const std::string& line) {
|
||||
int f = line.find_first_of("0123456789");
|
||||
int l = line.find_last_of("0123456789");
|
||||
return std::atoi(line.substr(f, l-f+1).c_str());
|
||||
}
|
||||
#endif
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Get the memory usage for the current process. The constructor will
|
||||
* get the memory usage. Use the current() and peak() calls to access
|
||||
* the result.
|
||||
*
|
||||
* This will only work on Linux, on other architectures this will
|
||||
* always return 0.
|
||||
*/
|
||||
MemoryUsage() {
|
||||
#ifdef __linux__
|
||||
static const char* filename = "/proc/self/status";
|
||||
std::ifstream status_file(filename);
|
||||
|
||||
if (status_file.is_open()) {
|
||||
std::string line;
|
||||
while (! status_file.eof() ) {
|
||||
std::getline(status_file, line);
|
||||
if (line.substr(0, 6) == "VmPeak") {
|
||||
m_peak = parse_number(line);
|
||||
}
|
||||
if (line.substr(0, 6) == "VmSize") {
|
||||
m_current = parse_number(line);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/// Return current memory usage in MBytes
|
||||
int current() const {
|
||||
return m_current / 1024;
|
||||
}
|
||||
|
||||
/// Return peak memory usage in MBytes
|
||||
int peak() const {
|
||||
return m_peak / 1024;
|
||||
}
|
||||
|
||||
}; // class MemoryUsage
|
||||
|
||||
} // namespace osmium
|
||||
|
||||
#endif // OSMIUM_UTIL_MEMORY_HPP
|
||||
@@ -1,768 +0,0 @@
|
||||
#ifndef OSMIUM_UTIL_MEMORY_MAPPING_HPP
|
||||
#define OSMIUM_UTIL_MEMORY_MAPPING_HPP
|
||||
|
||||
/*
|
||||
|
||||
This file is part of Osmium (http://osmcode.org/libosmium).
|
||||
|
||||
Copyright 2013-2016 Jochen Topf <jochen@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 <cassert>
|
||||
#include <cerrno>
|
||||
#include <stdexcept>
|
||||
#include <system_error>
|
||||
|
||||
#include <osmium/util/compatibility.hpp>
|
||||
#include <osmium/util/file.hpp>
|
||||
|
||||
#ifndef _WIN32
|
||||
# include <sys/mman.h>
|
||||
#else
|
||||
# include <fcntl.h>
|
||||
# include <io.h>
|
||||
# include <windows.h>
|
||||
# include <sys/types.h>
|
||||
#endif
|
||||
|
||||
namespace osmium {
|
||||
|
||||
namespace util {
|
||||
|
||||
/**
|
||||
* Class for wrapping memory mapping system calls.
|
||||
*
|
||||
* Usage for anonymous mapping:
|
||||
* @code
|
||||
* MemoryMapping mapping(1024); // create anonymous mapping with size
|
||||
* auto ptr = mapping.get_addr<char*>(); // get pointer to memory
|
||||
* mapping.unmap(); // release mapping by calling unmap() (or at end of scope)
|
||||
* @endcode
|
||||
*
|
||||
* Or for file-backed mapping:
|
||||
* @code
|
||||
* int fd = ::open(...);
|
||||
* {
|
||||
* MemoryMapping mapping(1024, MemoryMapping::mapping_mode::write_shared, fd, offset);
|
||||
* // use mapping
|
||||
* }
|
||||
* ::close(fd);
|
||||
* @endcode
|
||||
*
|
||||
* If the file backing a file-backed mapping is not large enough, it
|
||||
* will be resized. This works, of course, only for writable files,
|
||||
* so for read-only files you have to make sure they are large enough
|
||||
* for any mapping you want.
|
||||
*
|
||||
* If you ask for a zero-sized mapping, a mapping of the systems page
|
||||
* size will be created instead. For file-backed mapping this will only
|
||||
* work if the file is writable.
|
||||
*
|
||||
* There are different implementations for Unix and Windows systems.
|
||||
* On Unix systems this wraps the mmap(), munmap(), and the mremap()
|
||||
* system calls. On Windows it wraps the CreateFileMapping(),
|
||||
* CloseHandle(), MapViewOfFile(), and UnmapViewOfFile() functions.
|
||||
*
|
||||
* On Windows the file will be set to binary mode before the memory
|
||||
* mapping.
|
||||
*/
|
||||
class MemoryMapping {
|
||||
|
||||
public:
|
||||
enum class mapping_mode {
|
||||
readonly = 0,
|
||||
write_private = 1,
|
||||
write_shared = 2
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
/// The size of the mapping
|
||||
size_t m_size;
|
||||
|
||||
/// Offset into the file
|
||||
off_t m_offset;
|
||||
|
||||
/// File handle we got the mapping from
|
||||
int m_fd;
|
||||
|
||||
/// Mapping mode
|
||||
mapping_mode m_mapping_mode;
|
||||
|
||||
#ifdef _WIN32
|
||||
HANDLE m_handle;
|
||||
#endif
|
||||
|
||||
/// The address where the memory is mapped
|
||||
void* m_addr;
|
||||
|
||||
bool is_valid() const noexcept;
|
||||
|
||||
void make_invalid() noexcept;
|
||||
|
||||
#ifdef _WIN32
|
||||
typedef DWORD flag_type;
|
||||
#else
|
||||
typedef int flag_type;
|
||||
#endif
|
||||
|
||||
flag_type get_protection() const noexcept;
|
||||
|
||||
flag_type get_flags() const noexcept;
|
||||
|
||||
// A zero-sized mapping is not allowed by the operating system.
|
||||
// So if the user asks for a mapping of size 0, we map a full
|
||||
// page instead. This way we don't have a special case in the rest
|
||||
// of the code.
|
||||
static size_t initial_size(size_t size) {
|
||||
if (size == 0) {
|
||||
return osmium::util::get_pagesize();
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
HANDLE get_handle() const noexcept;
|
||||
HANDLE osmium::util::MemoryMapping::create_file_mapping() const noexcept;
|
||||
void* osmium::util::MemoryMapping::map_view_of_file() const noexcept;
|
||||
#endif
|
||||
|
||||
int resize_fd(int fd) {
|
||||
// Anonymous mapping doesn't need resizing.
|
||||
if (fd == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Make sure the file backing this mapping is large enough.
|
||||
if (osmium::util::file_size(fd) < m_size + m_offset) {
|
||||
osmium::util::resize_file(fd, m_size + m_offset);
|
||||
}
|
||||
return fd;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Create memory mapping of given size.
|
||||
*
|
||||
* If fd is not set (or fd == -1), an anonymous mapping will be
|
||||
* created, otherwise a mapping based on the file descriptor will
|
||||
* be created.
|
||||
*
|
||||
* @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)
|
||||
* @param fd Open file descriptor of a file we want to map
|
||||
* @param offset Offset into the file where the mapping should start
|
||||
* @throws std::system_error if the mapping fails
|
||||
*/
|
||||
MemoryMapping(size_t size, mapping_mode mode, 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) {
|
||||
}
|
||||
|
||||
/// You can not copy construct a MemoryMapping.
|
||||
MemoryMapping(const MemoryMapping&) = delete;
|
||||
|
||||
/// You can not copy a MemoryMapping.
|
||||
MemoryMapping& operator=(const MemoryMapping&) = delete;
|
||||
|
||||
/**
|
||||
* Move construct a mapping from another one. The other mapping
|
||||
* will be marked as invalid.
|
||||
*/
|
||||
MemoryMapping(MemoryMapping&& other);
|
||||
|
||||
/**
|
||||
* Move a mapping. The other mapping will be marked as invalid.
|
||||
*/
|
||||
MemoryMapping& operator=(MemoryMapping&& other);
|
||||
|
||||
/**
|
||||
* Releases the mapping by calling unmap(). Will never throw.
|
||||
* Call unmap() instead if you want to be notified of any error.
|
||||
*/
|
||||
~MemoryMapping() noexcept {
|
||||
try {
|
||||
unmap();
|
||||
} catch (std::system_error&) {
|
||||
// Ignore any exceptions because destructor must not throw.
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unmap a mapping. If the mapping is not valid, it will do
|
||||
* nothing.
|
||||
*
|
||||
* @throws std::system_error if the unmapping fails
|
||||
*/
|
||||
void unmap();
|
||||
|
||||
/**
|
||||
* Resize a mapping to the given new size.
|
||||
*
|
||||
* On Linux systems this will use the mremap() function. On other
|
||||
* 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 (must be > 0).
|
||||
*
|
||||
* @throws std::system_error if the remapping fails.
|
||||
*/
|
||||
void resize(size_t new_size);
|
||||
|
||||
/**
|
||||
* In a boolean context a MemoryMapping is true when it is a valid
|
||||
* existing mapping.
|
||||
*/
|
||||
explicit operator bool() const noexcept {
|
||||
return is_valid();
|
||||
}
|
||||
|
||||
/**
|
||||
* The number of bytes mapped. This is the same size you created
|
||||
* the mapping with. The actual mapping will probably be larger
|
||||
* because the system will round it to the page size.
|
||||
*/
|
||||
size_t size() const noexcept {
|
||||
return m_size;
|
||||
}
|
||||
|
||||
/**
|
||||
* The file descriptor this mapping was created from.
|
||||
*
|
||||
* @returns file descriptor, -1 for anonymous mappings
|
||||
*/
|
||||
int fd() const noexcept {
|
||||
return m_fd;
|
||||
}
|
||||
|
||||
/**
|
||||
* Was this mapping created as a writable mapping?
|
||||
*/
|
||||
bool writable() const noexcept {
|
||||
return m_mapping_mode != mapping_mode::readonly;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the address of the mapping as any pointer type you like.
|
||||
*
|
||||
* @throws std::runtime_error if the mapping is invalid
|
||||
*/
|
||||
template <typename T = void>
|
||||
T* get_addr() const {
|
||||
if (is_valid()) {
|
||||
return reinterpret_cast<T*>(m_addr);
|
||||
}
|
||||
throw std::runtime_error("invalid memory mapping");
|
||||
}
|
||||
|
||||
}; // class MemoryMapping
|
||||
|
||||
/**
|
||||
* Anonymous memory mapping.
|
||||
*
|
||||
* Usage for anonymous mapping:
|
||||
* @code
|
||||
* AnonymousMemoryMapping mapping(1024); // create anonymous mapping with size
|
||||
* auto ptr = mapping.get_addr<char*>(); // get pointer to memory
|
||||
* mapping.unmap(); // release mapping by calling unmap() (or at end of scope)
|
||||
* @endcode
|
||||
*/
|
||||
class AnonymousMemoryMapping : public MemoryMapping {
|
||||
|
||||
public:
|
||||
|
||||
AnonymousMemoryMapping(size_t size) :
|
||||
MemoryMapping(size, mapping_mode::write_private) {
|
||||
}
|
||||
|
||||
#ifndef __linux__
|
||||
/**
|
||||
* On systems other than Linux anonymous mappings can not be
|
||||
* resized!
|
||||
*/
|
||||
void resize(size_t) = delete;
|
||||
#endif
|
||||
|
||||
}; // class AnonymousMemoryMapping
|
||||
|
||||
/**
|
||||
* A thin wrapper around the MemoryMapping class used when all the
|
||||
* data in the mapped memory is of the same type. Instead of thinking
|
||||
* about the number of bytes mapped, this counts sizes in the number
|
||||
* of objects of that type.
|
||||
*
|
||||
* Note that no effort is made to actually initialize the objects in
|
||||
* this memory. This has to be done by the caller!
|
||||
*/
|
||||
template <typename T>
|
||||
class TypedMemoryMapping {
|
||||
|
||||
MemoryMapping m_mapping;
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Create anonymous typed memory mapping of given size.
|
||||
*
|
||||
* @param size Number of objects of type T to be mapped
|
||||
* @throws std::system_error if the mapping fails
|
||||
*/
|
||||
TypedMemoryMapping(size_t size) :
|
||||
m_mapping(sizeof(T) * size, MemoryMapping::mapping_mode::write_private) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create file-backed memory mapping of given size. The file must
|
||||
* contain at least `sizeof(T) * size` bytes!
|
||||
*
|
||||
* @param size Number of objects of type T to be mapped
|
||||
* @param mode Mapping mode: readonly, or writable (shared or private)
|
||||
* @param fd Open file descriptor of a file we want to map
|
||||
* @param offset Offset into the file where the mapping should start
|
||||
* @throws std::system_error if the mapping fails
|
||||
*/
|
||||
TypedMemoryMapping(size_t size, MemoryMapping::mapping_mode mode, int fd, off_t offset = 0) :
|
||||
m_mapping(sizeof(T) * size, mode, fd, sizeof(T) * offset) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @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) {
|
||||
}
|
||||
|
||||
/// You can not copy construct a TypedMemoryMapping.
|
||||
TypedMemoryMapping(const TypedMemoryMapping&) = delete;
|
||||
|
||||
/// You can not copy a MemoryMapping.
|
||||
TypedMemoryMapping& operator=(const TypedMemoryMapping&) = delete;
|
||||
|
||||
/**
|
||||
* Move construct a mapping from another one. The other mapping
|
||||
* will be marked as invalid.
|
||||
*/
|
||||
TypedMemoryMapping(TypedMemoryMapping&& other) = default;
|
||||
|
||||
/**
|
||||
* Move a mapping. The other mapping will be marked as invalid.
|
||||
*/
|
||||
TypedMemoryMapping& operator=(TypedMemoryMapping&& other) = default;
|
||||
|
||||
/**
|
||||
* Releases the mapping by calling unmap(). Will never throw.
|
||||
* Call unmap() instead if you want to be notified of any error.
|
||||
*/
|
||||
~TypedMemoryMapping() noexcept = default;
|
||||
|
||||
/**
|
||||
* Unmap a mapping. If the mapping is not valid, it will do
|
||||
* nothing.
|
||||
*
|
||||
* @throws std::system_error if the unmapping fails
|
||||
*/
|
||||
void unmap() {
|
||||
m_mapping.unmap();
|
||||
}
|
||||
|
||||
/**
|
||||
* Resize a mapping to the given new size.
|
||||
*
|
||||
* On Linux systems this will use the mremap() function. On other
|
||||
* 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 objects of type T to resize to
|
||||
* @throws std::system_error if the remapping fails
|
||||
*/
|
||||
void resize(size_t new_size) {
|
||||
m_mapping.resize(sizeof(T) * new_size);
|
||||
}
|
||||
|
||||
/**
|
||||
* In a boolean context a TypedMemoryMapping is true when it is
|
||||
* a valid existing mapping.
|
||||
*/
|
||||
explicit operator bool() const noexcept {
|
||||
return !!m_mapping;
|
||||
}
|
||||
|
||||
/**
|
||||
* The number of objects of class T mapped. This is the same size
|
||||
* you created the mapping with. The actual mapping will probably
|
||||
* be larger because the system will round it to the page size.
|
||||
*/
|
||||
size_t size() const noexcept {
|
||||
assert(m_mapping.size() % sizeof(T) == 0);
|
||||
return m_mapping.size() / sizeof(T);
|
||||
}
|
||||
|
||||
/**
|
||||
* The file descriptor this mapping was created from.
|
||||
*
|
||||
* @returns file descriptor, -1 for anonymous mappings
|
||||
*/
|
||||
int fd() const noexcept {
|
||||
return m_mapping.fd();
|
||||
}
|
||||
|
||||
/**
|
||||
* Was this mapping created as a writable mapping?
|
||||
*/
|
||||
bool writable() const noexcept {
|
||||
return m_mapping.writable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the address of the beginning of the mapping.
|
||||
*
|
||||
* @throws std::runtime_error if the mapping is invalid
|
||||
*/
|
||||
T* begin() {
|
||||
return m_mapping.get_addr<T>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the address one past the end of the mapping.
|
||||
*
|
||||
* @throws std::runtime_error if the mapping is invalid
|
||||
*/
|
||||
T* end() {
|
||||
return m_mapping.get_addr<T>() + size();
|
||||
}
|
||||
|
||||
const T* cbegin() const {
|
||||
return m_mapping.get_addr<T>();
|
||||
}
|
||||
|
||||
const T* cend() const {
|
||||
return m_mapping.get_addr<T>() + size();
|
||||
}
|
||||
|
||||
const T* begin() const {
|
||||
return m_mapping.get_addr<T>();
|
||||
}
|
||||
|
||||
const T* end() const {
|
||||
return m_mapping.get_addr<T>() + size();
|
||||
}
|
||||
|
||||
}; // class TypedMemoryMapping
|
||||
|
||||
template <typename T>
|
||||
class AnonymousTypedMemoryMapping : public TypedMemoryMapping<T> {
|
||||
|
||||
public:
|
||||
|
||||
AnonymousTypedMemoryMapping(size_t size) :
|
||||
TypedMemoryMapping<T>(size) {
|
||||
}
|
||||
|
||||
#ifndef __linux__
|
||||
/**
|
||||
* On systems other than Linux anonymous mappings can not be
|
||||
* resized!
|
||||
*/
|
||||
void resize(size_t) = delete;
|
||||
#endif
|
||||
|
||||
}; // class AnonymousTypedMemoryMapping
|
||||
|
||||
} // namespace util
|
||||
|
||||
} // namespace osmium
|
||||
|
||||
#ifndef _WIN32
|
||||
|
||||
// =========== Unix implementation =============
|
||||
|
||||
// MAP_FAILED is often a macro containing an old style cast
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wold-style-cast"
|
||||
|
||||
inline bool osmium::util::MemoryMapping::is_valid() const noexcept {
|
||||
return m_addr != MAP_FAILED;
|
||||
}
|
||||
|
||||
inline void osmium::util::MemoryMapping::make_invalid() noexcept {
|
||||
m_addr = MAP_FAILED;
|
||||
}
|
||||
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
// for BSD systems
|
||||
#ifndef MAP_ANONYMOUS
|
||||
# define MAP_ANONYMOUS MAP_ANON
|
||||
#endif
|
||||
|
||||
inline int osmium::util::MemoryMapping::get_protection() const noexcept {
|
||||
if (m_mapping_mode == mapping_mode::readonly) {
|
||||
return PROT_READ;
|
||||
}
|
||||
return PROT_READ | PROT_WRITE;
|
||||
}
|
||||
|
||||
inline int osmium::util::MemoryMapping::get_flags() const noexcept {
|
||||
if (m_fd == -1) {
|
||||
return MAP_PRIVATE | MAP_ANONYMOUS;
|
||||
}
|
||||
if (m_mapping_mode == mapping_mode::write_shared) {
|
||||
return MAP_SHARED;
|
||||
}
|
||||
return MAP_PRIVATE;
|
||||
}
|
||||
|
||||
inline osmium::util::MemoryMapping::MemoryMapping(size_t size, mapping_mode mode, int fd, off_t offset) :
|
||||
m_size(initial_size(size)),
|
||||
m_offset(offset),
|
||||
m_fd(resize_fd(fd)),
|
||||
m_mapping_mode(mode),
|
||||
m_addr(::mmap(nullptr, m_size, get_protection(), get_flags(), m_fd, m_offset)) {
|
||||
assert(!(fd == -1 && mode == mapping_mode::readonly));
|
||||
if (!is_valid()) {
|
||||
throw std::system_error(errno, std::system_category(), "mmap failed");
|
||||
}
|
||||
}
|
||||
|
||||
inline osmium::util::MemoryMapping::MemoryMapping(MemoryMapping&& other) :
|
||||
m_size(other.m_size),
|
||||
m_offset(other.m_offset),
|
||||
m_fd(other.m_fd),
|
||||
m_mapping_mode(other.m_mapping_mode),
|
||||
m_addr(other.m_addr) {
|
||||
other.make_invalid();
|
||||
}
|
||||
|
||||
inline osmium::util::MemoryMapping& osmium::util::MemoryMapping::operator=(osmium::util::MemoryMapping&& other) {
|
||||
unmap();
|
||||
m_size = other.m_size;
|
||||
m_offset = other.m_offset;
|
||||
m_fd = other.m_fd;
|
||||
m_mapping_mode = other.m_mapping_mode;
|
||||
m_addr = other.m_addr;
|
||||
other.make_invalid();
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline void osmium::util::MemoryMapping::unmap() {
|
||||
if (is_valid()) {
|
||||
if (::munmap(m_addr, m_size) != 0) {
|
||||
throw std::system_error(errno, std::system_category(), "munmap failed");
|
||||
}
|
||||
make_invalid();
|
||||
}
|
||||
}
|
||||
|
||||
inline void osmium::util::MemoryMapping::resize(size_t new_size) {
|
||||
assert(new_size > 0 && "can not resize to zero size");
|
||||
if (m_fd == -1) { // anonymous mapping
|
||||
#ifdef __linux__
|
||||
m_addr = ::mremap(m_addr, m_size, new_size, MREMAP_MAYMOVE);
|
||||
if (!is_valid()) {
|
||||
throw std::system_error(errno, std::system_category(), "mremap failed");
|
||||
}
|
||||
m_size = new_size;
|
||||
#else
|
||||
assert(false && "can't resize anonymous mappings on non-linux systems");
|
||||
#endif
|
||||
} else { // file-based mapping
|
||||
unmap();
|
||||
m_size = new_size;
|
||||
resize_fd(m_fd);
|
||||
m_addr = ::mmap(nullptr, new_size, get_protection(), get_flags(), m_fd, m_offset);
|
||||
if (!is_valid()) {
|
||||
throw std::system_error(errno, std::system_category(), "mmap (remap) failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
// =========== Windows implementation =============
|
||||
|
||||
/* References:
|
||||
* CreateFileMapping: http://msdn.microsoft.com/en-us/library/aa366537(VS.85).aspx
|
||||
* CloseHandle: http://msdn.microsoft.com/en-us/library/ms724211(VS.85).aspx
|
||||
* MapViewOfFile: http://msdn.microsoft.com/en-us/library/aa366761(VS.85).aspx
|
||||
* UnmapViewOfFile: http://msdn.microsoft.com/en-us/library/aa366882(VS.85).aspx
|
||||
*/
|
||||
|
||||
namespace osmium {
|
||||
|
||||
namespace util {
|
||||
|
||||
inline DWORD dword_hi(uint64_t x) {
|
||||
return static_cast<DWORD>(x >> 32);
|
||||
}
|
||||
|
||||
inline DWORD dword_lo(uint64_t x) {
|
||||
return static_cast<DWORD>(x & 0xffffffff);
|
||||
}
|
||||
|
||||
} // namespace util
|
||||
|
||||
} // namespace osmium
|
||||
|
||||
inline DWORD osmium::util::MemoryMapping::get_protection() const noexcept {
|
||||
switch (m_mapping_mode) {
|
||||
case mapping_mode::readonly:
|
||||
return PAGE_READONLY;
|
||||
case mapping_mode::write_private:
|
||||
return PAGE_WRITECOPY;
|
||||
case mapping_mode::write_shared:
|
||||
return PAGE_READWRITE;
|
||||
}
|
||||
}
|
||||
|
||||
inline DWORD osmium::util::MemoryMapping::get_flags() const noexcept {
|
||||
switch (m_mapping_mode) {
|
||||
case mapping_mode::readonly:
|
||||
return FILE_MAP_READ;
|
||||
case mapping_mode::write_private:
|
||||
return FILE_MAP_COPY;
|
||||
case mapping_mode::write_shared:
|
||||
return FILE_MAP_WRITE;
|
||||
}
|
||||
}
|
||||
|
||||
inline HANDLE osmium::util::MemoryMapping::get_handle() const noexcept {
|
||||
if (m_fd == -1) {
|
||||
return INVALID_HANDLE_VALUE;
|
||||
}
|
||||
return reinterpret_cast<HANDLE>(_get_osfhandle(m_fd));
|
||||
}
|
||||
|
||||
inline HANDLE osmium::util::MemoryMapping::create_file_mapping() const noexcept {
|
||||
if (m_fd != -1) {
|
||||
_setmode(m_fd, _O_BINARY);
|
||||
}
|
||||
return CreateFileMapping(get_handle(), nullptr, get_protection(), osmium::util::dword_hi(static_cast<uint64_t>(m_size) + m_offset), osmium::util::dword_lo(static_cast<uint64_t>(m_size) + m_offset), nullptr);
|
||||
}
|
||||
|
||||
inline void* osmium::util::MemoryMapping::map_view_of_file() const noexcept {
|
||||
return MapViewOfFile(m_handle, get_flags(), osmium::util::dword_hi(m_offset), osmium::util::dword_lo(m_offset), m_size);
|
||||
}
|
||||
|
||||
inline bool osmium::util::MemoryMapping::is_valid() const noexcept {
|
||||
return m_addr != nullptr;
|
||||
}
|
||||
|
||||
inline void osmium::util::MemoryMapping::make_invalid() noexcept {
|
||||
m_addr = nullptr;
|
||||
}
|
||||
|
||||
inline osmium::util::MemoryMapping::MemoryMapping(size_t size, MemoryMapping::mapping_mode mode, int fd, off_t offset) :
|
||||
m_size(initial_size(size)),
|
||||
m_offset(offset),
|
||||
m_fd(resize_fd(fd)),
|
||||
m_mapping_mode(mode),
|
||||
m_handle(create_file_mapping()),
|
||||
m_addr(nullptr) {
|
||||
|
||||
if (!m_handle) {
|
||||
throw std::system_error(GetLastError(), std::system_category(), "CreateFileMapping failed");
|
||||
}
|
||||
|
||||
m_addr = map_view_of_file();
|
||||
if (!is_valid()) {
|
||||
throw std::system_error(GetLastError(), std::system_category(), "MapViewOfFile failed");
|
||||
}
|
||||
}
|
||||
|
||||
inline osmium::util::MemoryMapping::MemoryMapping(MemoryMapping&& other) :
|
||||
m_size(other.m_size),
|
||||
m_offset(other.m_offset),
|
||||
m_fd(other.m_fd),
|
||||
m_mapping_mode(other.m_mapping_mode),
|
||||
m_handle(std::move(other.m_handle)),
|
||||
m_addr(other.m_addr) {
|
||||
other.make_invalid();
|
||||
other.m_handle = nullptr;
|
||||
}
|
||||
|
||||
inline osmium::util::MemoryMapping& osmium::util::MemoryMapping::operator=(osmium::util::MemoryMapping&& other) {
|
||||
unmap();
|
||||
m_size = other.m_size;
|
||||
m_offset = other.m_offset;
|
||||
m_fd = other.m_fd;
|
||||
m_mapping_mode = other.m_mapping_mode;
|
||||
m_handle = std::move(other.m_handle);
|
||||
m_addr = other.m_addr;
|
||||
other.make_invalid();
|
||||
other.m_handle = nullptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline void osmium::util::MemoryMapping::unmap() {
|
||||
if (is_valid()) {
|
||||
if (! UnmapViewOfFile(m_addr)) {
|
||||
throw std::system_error(GetLastError(), std::system_category(), "UnmapViewOfFile failed");
|
||||
}
|
||||
make_invalid();
|
||||
}
|
||||
|
||||
if (m_handle) {
|
||||
if (! CloseHandle(m_handle)) {
|
||||
throw std::system_error(GetLastError(), std::system_category(), "CloseHandle failed");
|
||||
}
|
||||
m_handle = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
inline void osmium::util::MemoryMapping::resize(size_t new_size) {
|
||||
unmap();
|
||||
|
||||
m_size = new_size;
|
||||
resize_fd(m_fd);
|
||||
|
||||
m_handle = create_file_mapping();
|
||||
if (!m_handle) {
|
||||
throw std::system_error(GetLastError(), std::system_category(), "CreateFileMapping failed");
|
||||
}
|
||||
|
||||
m_addr = map_view_of_file();
|
||||
if (!is_valid()) {
|
||||
throw std::system_error(GetLastError(), std::system_category(), "MapViewOfFile failed");
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif // OSMIUM_UTIL_MEMORY_MAPPING_HPP
|
||||
@@ -1,120 +0,0 @@
|
||||
#ifndef OSMIUM_UTIL_MINMAX_HPP
|
||||
#define OSMIUM_UTIL_MINMAX_HPP
|
||||
|
||||
/*
|
||||
|
||||
This file is part of Osmium (http://osmcode.org/libosmium).
|
||||
|
||||
Copyright 2013-2016 Jochen Topf <jochen@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 <limits>
|
||||
|
||||
namespace osmium {
|
||||
|
||||
template <typename T>
|
||||
inline T min_op_start_value() {
|
||||
return std::numeric_limits<T>::max();
|
||||
}
|
||||
|
||||
/**
|
||||
* Class for calculating the minimum of a bunch of values.
|
||||
* Works with any numeric type.
|
||||
*
|
||||
* Usage:
|
||||
*
|
||||
* min_op<int> x;
|
||||
* x.update(27);
|
||||
* x.update(12);
|
||||
* auto min = x.get(); // 12
|
||||
*/
|
||||
template <typename T>
|
||||
class min_op {
|
||||
|
||||
T m_value;
|
||||
|
||||
public:
|
||||
|
||||
explicit min_op(T start_value = min_op_start_value<T>()) :
|
||||
m_value(start_value) {
|
||||
}
|
||||
|
||||
void update(T value) noexcept {
|
||||
if (value < m_value) {
|
||||
m_value = value;
|
||||
}
|
||||
}
|
||||
|
||||
T operator()() const noexcept {
|
||||
return m_value;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
inline T max_op_start_value() {
|
||||
return std::numeric_limits<T>::min();
|
||||
}
|
||||
|
||||
/**
|
||||
* Class for calculating the maximum of a bunch of values.
|
||||
* Works with any numeric type.
|
||||
*
|
||||
* Usage:
|
||||
*
|
||||
* max_op<int> x;
|
||||
* x.update(27);
|
||||
* x.update(12);
|
||||
* auto max = x.get(); // 27
|
||||
*/
|
||||
template <typename T>
|
||||
class max_op {
|
||||
|
||||
T m_value;
|
||||
|
||||
public:
|
||||
|
||||
explicit max_op(T start_value = max_op_start_value<T>()) :
|
||||
m_value(start_value) {
|
||||
}
|
||||
|
||||
void update(T value) noexcept {
|
||||
if (value > m_value) {
|
||||
m_value = value;
|
||||
}
|
||||
}
|
||||
|
||||
T operator()() const noexcept {
|
||||
return m_value;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
} // namespace osmium
|
||||
|
||||
#endif // OSMIUM_UTIL_MINMAX_HPP
|
||||
@@ -1,205 +0,0 @@
|
||||
#ifndef OSMIUM_UTIL_OPTIONS_HPP
|
||||
#define OSMIUM_UTIL_OPTIONS_HPP
|
||||
|
||||
/*
|
||||
|
||||
This file is part of Osmium (http://osmcode.org/libosmium).
|
||||
|
||||
Copyright 2013-2016 Jochen Topf <jochen@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 <initializer_list>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
namespace osmium {
|
||||
|
||||
namespace util {
|
||||
|
||||
/**
|
||||
* Stores key=value type options. This class can be used stand-alone or
|
||||
* 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 {
|
||||
|
||||
using option_map = std::map<std::string, std::string>;
|
||||
option_map m_options;
|
||||
|
||||
public:
|
||||
|
||||
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) {
|
||||
}
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
m_options[data] = "true";
|
||||
} else {
|
||||
std::string value = data.substr(pos+1);
|
||||
data.erase(pos);
|
||||
set(data, value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 {
|
||||
auto it = m_options.find(key);
|
||||
if (it == m_options.end()) {
|
||||
return default_value;
|
||||
}
|
||||
return it->second;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this option set to a true value ("true" or "yes")?
|
||||
* Will return false if the value is unset.
|
||||
*/
|
||||
bool is_true(const std::string& key) const noexcept {
|
||||
std::string value = get(key);
|
||||
return (value == "true" || value == "yes");
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this option not set to a false value ("false" or "no")?
|
||||
* Will return true if the value is unset.
|
||||
*/
|
||||
bool is_not_false(const std::string& key) const noexcept {
|
||||
std::string value = get(key);
|
||||
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();
|
||||
}
|
||||
|
||||
}; // class Options
|
||||
|
||||
} // namespace util
|
||||
|
||||
} // namespace osmium
|
||||
|
||||
#endif // OSMIUM_UTIL_OPTIONS_HPP
|
||||
@@ -1,102 +0,0 @@
|
||||
#ifndef OSMIUM_UTIL_STRING_HPP
|
||||
#define OSMIUM_UTIL_STRING_HPP
|
||||
|
||||
/*
|
||||
|
||||
This file is part of Osmium (http://osmcode.org/libosmium).
|
||||
|
||||
Copyright 2013-2016 Jochen Topf <jochen@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 <string>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
|
||||
namespace osmium {
|
||||
|
||||
/**
|
||||
* Split string on the separator character.
|
||||
*
|
||||
* @param str The string to be split.
|
||||
* @param sep The separator character.
|
||||
* @param compact Set this to true to remove empty strings from result
|
||||
* @returns Vector with the parts of the string split up.
|
||||
*/
|
||||
inline std::vector<std::string> split_string(const std::string& str, const char sep, bool compact = false) {
|
||||
std::vector<std::string> tokens;
|
||||
|
||||
if (!str.empty()) {
|
||||
size_t pos = 0;
|
||||
size_t nextpos = str.find_first_of(sep);
|
||||
while (nextpos != std::string::npos) {
|
||||
if (!compact || (nextpos - pos != 0)) {
|
||||
tokens.push_back(str.substr(pos, nextpos-pos));
|
||||
}
|
||||
pos = nextpos + 1;
|
||||
nextpos = str.find_first_of(sep, pos);
|
||||
}
|
||||
if (!compact || pos != str.size()) {
|
||||
tokens.push_back(str.substr(pos));
|
||||
}
|
||||
}
|
||||
|
||||
return tokens;
|
||||
}
|
||||
|
||||
/**
|
||||
* Split string on the separator character(s).
|
||||
*
|
||||
* @param str The string to be split.
|
||||
* @param sep The separator character(s).
|
||||
* @param compact Set this to true to remove empty strings from result
|
||||
* @returns Vector with the parts of the string split up.
|
||||
*/
|
||||
inline std::vector<std::string> split_string(const std::string& str, const char* sep, bool compact = false) {
|
||||
std::vector<std::string> tokens;
|
||||
|
||||
if (!str.empty()) {
|
||||
size_t pos = 0;
|
||||
size_t nextpos = str.find_first_of(sep);
|
||||
while (nextpos != std::string::npos) {
|
||||
if (!compact || (nextpos - pos != 0)) {
|
||||
tokens.push_back(str.substr(pos, nextpos-pos));
|
||||
}
|
||||
pos = nextpos + 1;
|
||||
nextpos = str.find_first_of(sep, pos);
|
||||
}
|
||||
if (!compact || pos != str.size()) {
|
||||
tokens.push_back(str.substr(pos));
|
||||
}
|
||||
}
|
||||
|
||||
return tokens;
|
||||
}
|
||||
|
||||
} // namespace osmium
|
||||
|
||||
#endif // OSMIUM_UTIL_STRING_HPP
|
||||
@@ -1,144 +0,0 @@
|
||||
#ifndef OSMIUM_UTIL_VERBOSE_OUTPUT_HPP
|
||||
#define OSMIUM_UTIL_VERBOSE_OUTPUT_HPP
|
||||
|
||||
/*
|
||||
|
||||
This file is part of Osmium (http://osmcode.org/libosmium).
|
||||
|
||||
Copyright 2013-2016 Jochen Topf <jochen@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 <time.h>
|
||||
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
namespace osmium {
|
||||
|
||||
/**
|
||||
* @brief Helpful utility classes and functions not strictly OSM related
|
||||
*/
|
||||
namespace util {
|
||||
|
||||
/**
|
||||
* Osmium programs often run for a long time because of the amount of
|
||||
* OSM data processed. This class helps with keeping the user up to
|
||||
* date by offering an easy way for programs to optionally output
|
||||
* verbose information about what's going on.
|
||||
*
|
||||
* Use an object of this class instead of std::cerr as an output
|
||||
* stream. Nothing is actually written if the object is not set to
|
||||
* verbose mode. If it is set to verbose mode, each line is prepended
|
||||
* with the running time, ie the time since the VerboseOutput object
|
||||
* was created.
|
||||
*/
|
||||
class VerboseOutput {
|
||||
|
||||
/// all time output will be relative to this start time
|
||||
time_t m_start;
|
||||
|
||||
/// is verbose mode enabled?
|
||||
bool m_verbose;
|
||||
|
||||
/// a newline was written, start next output with runtime
|
||||
bool m_newline;
|
||||
|
||||
/**
|
||||
* If we remember that a newline was written as the last thing
|
||||
* write out the time elapsed and reset the newline flag.
|
||||
*/
|
||||
void start_line() {
|
||||
if (m_newline) {
|
||||
time_t elapsed = runtime();
|
||||
|
||||
char old_fill = std::cerr.fill();
|
||||
std::cerr << '[' << std::setw(2) << (elapsed / 60) << ':' << std::setw(2) << std::setfill('0') << (elapsed % 60) << "] ";
|
||||
std::cerr.fill(old_fill);
|
||||
|
||||
m_newline = false;
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
explicit VerboseOutput(bool verbose = false) noexcept :
|
||||
m_start(time(NULL)),
|
||||
m_verbose(verbose),
|
||||
m_newline(true) {
|
||||
}
|
||||
|
||||
~VerboseOutput() = default;
|
||||
|
||||
VerboseOutput(const VerboseOutput&) = default;
|
||||
VerboseOutput& operator=(const VerboseOutput&) = default;
|
||||
VerboseOutput(VerboseOutput&&) = default;
|
||||
VerboseOutput& operator=(VerboseOutput&&) = default;
|
||||
|
||||
time_t runtime() const noexcept {
|
||||
return time(NULL) - m_start;
|
||||
}
|
||||
|
||||
/// Get "verbose" setting.
|
||||
bool verbose() const noexcept {
|
||||
return m_verbose;
|
||||
}
|
||||
|
||||
/// Set "verbose" setting.
|
||||
void verbose(bool verbose) noexcept {
|
||||
m_verbose = verbose;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void print(const T& value) {
|
||||
if (m_verbose) {
|
||||
start_line();
|
||||
std::cerr << value;
|
||||
|
||||
// check if there was a newline a the end and remember that
|
||||
std::ostringstream output_buffer;
|
||||
output_buffer << value;
|
||||
if (!output_buffer.str().empty() && output_buffer.str().back() == '\n') {
|
||||
m_newline = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}; // class VerboseOutput
|
||||
|
||||
template<typename T>
|
||||
inline VerboseOutput& operator<<(VerboseOutput& verbose_output, const T& value) {
|
||||
verbose_output.print(value);
|
||||
return verbose_output;
|
||||
}
|
||||
|
||||
} // namespace util
|
||||
|
||||
} // namespace osmium
|
||||
|
||||
#endif // OSMIUM_UTIL_VERBOSE_OUTPUT_HPP
|
||||
Reference in New Issue
Block a user