-
Notifications
You must be signed in to change notification settings - Fork 17
/
mappable_vector.hpp
124 lines (99 loc) · 2.92 KB
/
mappable_vector.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#pragma once
#include <vector>
#include <algorithm>
#include <boost/utility.hpp>
#include <boost/range.hpp>
#include <boost/function.hpp>
#include <boost/lambda/bind.hpp>
#include <boost/lambda/construct.hpp>
#include <stdint.h>
#include "intrinsics.hpp"
namespace succinct { namespace mapper {
namespace detail {
class freeze_visitor;
class map_visitor;
class sizeof_visitor;
}
typedef boost::function<void()> deleter_t;
template <typename T> // 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 <typename Range>
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<T>& vec) {
clear();
m_size = vec.size();
if (m_size) {
std::vector<T>* new_vec = new std::vector<T>;
new_vec->swap(vec);
m_deleter = boost::lambda::bind(boost::lambda::delete_ptr(), new_vec);
m_data = &(*new_vec)[0];
}
}
template <typename Range>
void assign(Range const& from) {
clear();
mappable_vector(from).swap(*this);
}
uint64_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[](uint64_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;
uint64_t m_size;
deleter_t m_deleter;
};
}}