osrm-backend/include/util/shared_memory_vector_wrapper.hpp

150 lines
3.7 KiB
C++
Raw Normal View History

#ifndef SHARED_MEMORY_VECTOR_WRAPPER_HPP
#define SHARED_MEMORY_VECTOR_WRAPPER_HPP
2013-09-17 08:23:06 -04:00
#include <boost/assert.hpp>
2016-02-05 10:45:36 -05:00
#include <cstddef>
2013-09-23 12:01:30 -04:00
#include <algorithm>
2013-09-17 08:23:06 -04:00
#include <iterator>
2014-05-07 12:39:16 -04:00
#include <type_traits>
2013-09-17 08:23:06 -04:00
#include <vector>
2016-02-05 10:45:36 -05:00
#include <utility>
2013-09-17 08:23:06 -04:00
2016-01-05 10:51:13 -05:00
namespace osrm
{
namespace util
{
2014-05-07 12:39:16 -04:00
template <typename DataT> class ShMemIterator : public std::iterator<std::input_iterator_tag, DataT>
{
DataT *p;
public:
explicit ShMemIterator(DataT *x) : p(x) {}
ShMemIterator(const ShMemIterator &mit) : p(mit.p) {}
ShMemIterator &operator++()
{
2013-09-17 08:23:06 -04:00
++p;
return *this;
}
2014-05-07 12:39:16 -04:00
ShMemIterator operator++(int)
{
2013-09-17 08:23:06 -04:00
ShMemIterator tmp(*this);
operator++();
return tmp;
}
2014-05-07 12:39:16 -04:00
ShMemIterator operator+(std::ptrdiff_t diff)
{
ShMemIterator tmp(p + diff);
return tmp;
}
2014-05-07 12:39:16 -04:00
bool operator==(const ShMemIterator &rhs) { return p == rhs.p; }
bool operator!=(const ShMemIterator &rhs) { return p != rhs.p; }
DataT &operator*() { return *p; }
2013-09-17 08:23:06 -04:00
};
2014-05-07 12:39:16 -04:00
template <typename DataT> class SharedMemoryWrapper
{
private:
DataT *m_ptr;
2013-09-17 08:23:06 -04:00
std::size_t m_size;
2014-05-07 12:39:16 -04:00
public:
SharedMemoryWrapper() : m_ptr(nullptr), m_size(0) {}
2013-09-23 12:01:30 -04:00
2014-05-07 12:39:16 -04:00
SharedMemoryWrapper(DataT *ptr, std::size_t size) : m_ptr(ptr), m_size(size) {}
2013-09-17 08:23:06 -04:00
2016-05-01 07:48:56 -04:00
void reset(DataT *ptr, std::size_t size)
{
m_ptr = ptr;
m_size = size;
}
2014-05-07 12:39:16 -04:00
DataT &at(const std::size_t index) { return m_ptr[index]; }
2013-09-23 12:01:30 -04:00
2014-05-07 12:39:16 -04:00
const DataT &at(const std::size_t index) const { return m_ptr[index]; }
2014-05-07 12:39:16 -04:00
ShMemIterator<DataT> begin() const { return ShMemIterator<DataT>(m_ptr); }
2013-09-23 12:01:30 -04:00
2014-05-07 12:39:16 -04:00
ShMemIterator<DataT> end() const { return ShMemIterator<DataT>(m_ptr + m_size); }
2013-09-17 08:23:06 -04:00
std::size_t size() const { return m_size; }
bool empty() const { return 0 == size(); }
2014-05-07 12:39:16 -04:00
DataT &operator[](const unsigned index)
{
2013-09-17 08:23:06 -04:00
BOOST_ASSERT_MSG(index < m_size, "invalid size");
return m_ptr[index];
}
2013-09-23 12:01:30 -04:00
2014-05-07 12:39:16 -04:00
const DataT &operator[](const unsigned index) const
{
2013-09-23 12:01:30 -04:00
BOOST_ASSERT_MSG(index < m_size, "invalid size");
return m_ptr[index];
}
template <typename T>
friend void swap(SharedMemoryWrapper<T> &, SharedMemoryWrapper<T> &) noexcept;
2013-09-17 08:23:06 -04:00
};
2014-05-07 12:39:16 -04:00
template <> class SharedMemoryWrapper<bool>
{
private:
unsigned *m_ptr;
std::size_t m_size;
2014-05-07 12:39:16 -04:00
public:
SharedMemoryWrapper() : m_ptr(nullptr), m_size(0) {}
2014-05-07 12:39:16 -04:00
SharedMemoryWrapper(unsigned *ptr, std::size_t size) : m_ptr(ptr), m_size(size) {}
2014-05-07 12:39:16 -04:00
bool at(const std::size_t index) const
{
const std::size_t bucket = index / 32;
const unsigned offset = static_cast<unsigned>(index % 32);
return m_ptr[bucket] & (1u << offset);
}
2016-05-01 07:48:56 -04:00
void reset(unsigned *ptr, std::size_t size)
{
m_ptr = ptr;
m_size = size;
}
std::size_t size() const { return m_size; }
bool empty() const { return 0 == size(); }
2014-05-07 12:39:16 -04:00
bool operator[](const unsigned index)
{
BOOST_ASSERT_MSG(index < m_size, "invalid size");
const unsigned bucket = index / 32;
const unsigned offset = index % 32;
return m_ptr[bucket] & (1u << offset);
}
template <typename T>
friend void swap(SharedMemoryWrapper<T> &, SharedMemoryWrapper<T> &) noexcept;
};
// Both SharedMemoryWrapper<T> and the SharedMemoryWrapper<bool> specializations share this impl.
template <typename DataT>
void swap(SharedMemoryWrapper<DataT> &lhs, SharedMemoryWrapper<DataT> &rhs) noexcept
{
std::swap(lhs.m_ptr, rhs.m_ptr);
std::swap(lhs.m_size, rhs.m_size);
}
2014-05-07 12:39:16 -04:00
template <typename DataT, bool UseSharedMemory> struct ShM
{
using vector = typename std::conditional<UseSharedMemory,
SharedMemoryWrapper<DataT>,
std::vector<DataT>>::type;
2014-05-07 12:39:16 -04:00
};
2016-01-05 10:51:13 -05:00
}
}
#endif // SHARED_MEMORY_VECTOR_WRAPPER_HPP