#pragma once #include #include #include #include #include #include #include #include "intrinsics.hpp" namespace succinct { namespace mapper { namespace detail { class freeze_visitor; class map_visitor; class sizeof_visitor; } typedef boost::function deleter_t; template // T must be a POD class mappable_vector : boost::noncopyable { public: typedef T value_type; typedef const T* iterator; typedef const T* const_iterator; mappable_vector() : m_data(0) , m_size(0) , m_deleter() {} template mappable_vector(Range const& from) : m_data(0) , m_size(0) { size_t size = boost::size(from); T* data = new T[size]; m_deleter = boost::lambda::bind(boost::lambda::delete_array(), data); std::copy(boost::begin(from), boost::end(from), data); m_data = data; m_size = size; } ~mappable_vector() { if (m_deleter) { m_deleter(); } } void swap(mappable_vector& other) { using std::swap; swap(m_data, other.m_data); swap(m_size, other.m_size); swap(m_deleter, other.m_deleter); } void clear() { mappable_vector().swap(*this); } void steal(std::vector& vec) { clear(); m_size = vec.size(); if (m_size) { std::vector* new_vec = new std::vector; new_vec->swap(vec); m_deleter = boost::lambda::bind(boost::lambda::delete_ptr(), new_vec); m_data = &(*new_vec)[0]; } } template void assign(Range const& from) { clear(); mappable_vector(from).swap(*this); } size_t size() const { return m_size; } inline const_iterator begin() const { return m_data; } inline const_iterator end() const { return m_data + m_size; } inline T const& operator[](size_t i) const { assert(i < m_size); return m_data[i]; } inline T const* data() const { return m_data; } inline void prefetch(size_t i) const { succinct::intrinsics::prefetch(m_data + i); } friend class detail::freeze_visitor; friend class detail::map_visitor; friend class detail::sizeof_visitor; protected: const T* m_data; size_t m_size; deleter_t m_deleter; }; }}