12 #ifndef CPROVER_UTIL_SMALL_MAP_H
13 #define CPROVER_UTIL_SMALL_MAP_H
21 #include <type_traits>
67 template <
typename T,
typename Ind = u
int32_t, std::
size_t Num = 8>
76 static_assert(std::is_unsigned<Ind>::value,
"Ind should be an unsigned type");
84 void copy(T *dest,
const T *src, std::size_t n)
const
86 for(std::size_t i = 0; i < n; i++)
88 new(dest + i) T(*(src + i));
97 T *mem = (T *)
malloc(
sizeof(T) * n);
100 throw std::bad_alloc();
113 T *mem = (T *)
realloc((
char *)ptr,
sizeof(T) * n);
116 throw std::bad_alloc();
118 #ifdef _SMALL_MAP_REALLOC_STATS
123 else if(ptr !=
nullptr)
140 const std::size_t n = m.
size();
141 INVARIANT(n > 0,
"size is > 0 if data pointer is non-null");
152 std::size_t n =
size();
154 for(std::size_t i = 0; i < n; i++)
166 static const std::size_t
N_BITS = std::numeric_limits<index_fieldt>::digits;
168 static const std::size_t
NUM = Num;
170 static_assert(
NUM >= 2,
"NUM should be at least 2");
172 static constexpr std::size_t
num_bits(
const std::size_t n)
174 return n < 2 ? 1 : 1 +
num_bits(n >> 1);
190 static_assert(
S_BITS <=
N_BITS,
"S_BITS should be no larger than N_BITS");
193 std::numeric_limits<std::size_t>::digits >=
BITS,
194 "BITS must fit into an unsigned");
202 std::size_t shift = field *
BITS;
203 return (
ind & (
MASK << shift)) >> shift;
211 std::size_t shift = field *
BITS;
219 for(std::size_t idx = 0; idx <
S_BITS /
BITS; idx++)
227 v = ((v - 1) << 1) | 1;
237 typedef std::pair<const std::size_t, const T &>
valuet;
252 const std::size_t
idx,
253 const std::size_t
ii)
265 return std::make_shared<valuet>(
idx, *(
m.
p +
ii));
287 std::size_t old_idx =
idx;
288 std::size_t old_ii =
ii;
377 return ii == other.
ii;
382 return ii != other.
ii;
409 std::size_t ii = v >> 1;
413 std::size_t ii =
size();
430 std::size_t ii = v >> 1;
445 std::size_t ii = v >> 1;
448 std::size_t n =
size();
455 memmove((
char *)(
p + ii),
p + ii + 1,
sizeof(T) * (n - ii - 1));
479 INVARIANT(v & 1,
"element must be in map");
481 std::size_t ii = v >> 1;
482 std::size_t n =
size();
499 copy(m->
p + ii,
p + ii + 1, n - ii - 1);
513 INVARIANT(!(v & 1),
"element must not be in map");
515 std::size_t n =
size();
526 new(m->
p + ii) T(value);
537 std::bitset<N_BITS> bs(
ind &
IND);
546 #ifdef _SMALL_MAP_REALLOC_STATS
547 mutable std::size_t realloc_failure = 0;
548 mutable std::size_t realloc_success = 0;
bool operator==(const const_iterator &other) const
const_iterator(const small_mapt &m, const std::size_t idx, const std::size_t ii)
const_iterator operator++()
bool operator!=(const const_iterator &other) const
const valuet operator*() const
const std::shared_ptr< valuet > operator->() const
const_iterator(const small_mapt &m)
const T & get_value() const
Non-standard direct access to the underlying value instead of creating a valuet object.
const_iterator operator++(int)
const_value_iterator operator++(int)
const_value_iterator(const small_mapt &m, const int ii)
const_value_iterator operator++()
bool operator!=(const const_value_iterator &other) const
bool operator==(const const_value_iterator &other) const
const T & operator*() const
const T * operator->() const
Map from small integers to values.
static const std::size_t BITS
small_mapt * copy_and_insert(std::size_t idx, const T &value) const
T * allocate(std::size_t n) const
T & operator[](std::size_t idx)
static constexpr std::size_t S_BITS
static const std::size_t N_BITS
small_mapt(const small_mapt &m)
const_iterator find(std::size_t idx) const
const_value_iterator value_begin() const
static const index_fieldt IND
const_iterator end() const
void shift_indices(std::size_t ii)
const_iterator begin() const
static constexpr index_fieldt indicator_mask(const index_fieldt digit=1)
small_mapt * copy_and_erase(std::size_t idx) const
std::size_t erase(std::size_t idx)
const_value_iterator value_end() const
static constexpr std::size_t num_bits(const std::size_t n)
void set_field(std::size_t field, std::size_t v)
static const index_fieldt MASK
static const std::size_t NUM
std::pair< const std::size_t, const T & > valuet
std::size_t get_field(std::size_t field) const
friend void small_map_test()
void copy(T *dest, const T *src, std::size_t n) const
T * allocate(T *ptr, std::size_t n) const
#define PRECONDITION(CONDITION)
void * realloc(void *ptr, __CPROVER_size_t malloc_size)
void * malloc(__CPROVER_size_t malloc_size)
void * memmove(void *dest, const void *src, size_t n)