@@ -86,7 +86,7 @@ struct compact_vector //
8686 struct builder {
8787 builder () : m_size(0 ), m_width(0 ), m_mask(0 ), m_back(0 ), m_cur_block(0 ), m_cur_shift(0 ) {}
8888
89- builder (uint64_t n, uint64_t w) { resize (n, w); }
89+ builder (uint64_t n, uint64_t w) : builder() { resize (n, w); }
9090
9191 /*
9292 Resize the container to hold n values, each of width w.
@@ -96,6 +96,8 @@ struct compact_vector //
9696 m_width = w;
9797 m_mask = -(w == 64 ) | ((uint64_t (1 ) << w) - 1 );
9898 m_back = 0 ;
99+ m_cur_block = 0 ;
100+ m_cur_shift = 0 ;
99101 m_data.resize (
100102 /* use 1 word more for safe access() */
101103 essentials::words_for (m_size * m_width) + 1 , 0 );
@@ -109,7 +111,9 @@ struct compact_vector //
109111 template <typename Iterator>
110112 void fill (Iterator begin, uint64_t n) {
111113 if (m_width == 0 ) throw std::runtime_error (" width must be > 0" );
112- for (uint64_t i = 0 ; i != n; ++i, ++begin) set (i, *begin);
114+ for (uint64_t i = 0 ; i != n; ++i, ++begin) {
115+ set (i, *begin); // can just do push_back(*begin);
116+ }
113117 }
114118
115119 /*
@@ -134,6 +138,28 @@ struct compact_vector //
134138 }
135139 }
136140
141+ void push_back (uint64_t v) {
142+ assert (m_width != 0 );
143+ m_back = v;
144+ m_data[m_cur_block] &= ~(m_mask << m_cur_shift);
145+ m_data[m_cur_block] |= v << m_cur_shift;
146+
147+ uint64_t res_shift = 64 - m_cur_shift;
148+ if (res_shift < m_width) {
149+ ++m_cur_block;
150+ m_data[m_cur_block] &= ~(m_mask >> res_shift);
151+ m_data[m_cur_block] |= v >> res_shift;
152+ m_cur_shift = -res_shift;
153+ }
154+
155+ m_cur_shift += m_width;
156+
157+ if (m_cur_shift == 64 ) {
158+ m_cur_shift = 0 ;
159+ ++m_cur_block;
160+ }
161+ }
162+
137163 void reduce_width_by (uint64_t n) {
138164 assert (m_width > n);
139165
0 commit comments