initial range interface for hashtables
parent
c9e3ebd773
commit
fa7bf1d3db
|
@ -11,9 +11,12 @@
|
|||
#include "octa/types.h"
|
||||
#include "octa/utility.h"
|
||||
#include "octa/memory.h"
|
||||
#include "octa/range.h"
|
||||
|
||||
namespace octa {
|
||||
|
||||
template<typename T> struct HashRange;
|
||||
|
||||
namespace detail {
|
||||
template<
|
||||
typename B, /* contains methods specific to each ht type */
|
||||
|
@ -49,6 +52,9 @@ namespace detail {
|
|||
using FAPair = octa::detail::CompressedPair<AllocPair, FuncPair>;
|
||||
using DataPair = octa::detail::CompressedPair<Chain **, FAPair>;
|
||||
|
||||
using Range = octa::HashRange<E>;
|
||||
using ConstRange = octa::HashRange<const E>;
|
||||
|
||||
DataPair p_data;
|
||||
|
||||
float p_maxlf;
|
||||
|
@ -170,6 +176,16 @@ namespace detail {
|
|||
octa::Size bucket_count() const { return p_size; }
|
||||
octa::Size max_bucket_count() const { return Size(~0) / sizeof(Chain); }
|
||||
|
||||
Range each() {
|
||||
return Range(p_data.first(), bucket_count());
|
||||
}
|
||||
ConstRange each() const {
|
||||
return ConstRange(p_data.first(), bucket_count());
|
||||
}
|
||||
ConstRange ceach() const {
|
||||
return ConstRange(p_data.first(), bucket_count());
|
||||
}
|
||||
|
||||
void swap(Hashtable &h) {
|
||||
octa::swap(p_size, h.p_size);
|
||||
octa::swap(p_len, h.p_len);
|
||||
|
@ -180,6 +196,66 @@ namespace detail {
|
|||
};
|
||||
} /* namespace detail */
|
||||
|
||||
template<typename T>
|
||||
struct HashRange: octa::InputRange<HashRange<T>, octa::ForwardRangeTag, T> {
|
||||
private:
|
||||
struct Chain {
|
||||
T value;
|
||||
Chain *next;
|
||||
};
|
||||
|
||||
Chain **p_chains;
|
||||
Chain *p_node;
|
||||
octa::Size p_num;
|
||||
|
||||
void advance() {
|
||||
while (p_num > 0 && !p_chains[0]) {
|
||||
--p_num;
|
||||
++p_chains;
|
||||
}
|
||||
if (p_num > 0) {
|
||||
p_node = p_chains[0];
|
||||
--p_num;
|
||||
++p_chains;
|
||||
} else {
|
||||
p_node = nullptr;
|
||||
}
|
||||
}
|
||||
public:
|
||||
HashRange(): p_chains(), p_num(0) {}
|
||||
HashRange(void *ch, octa::Size n): p_chains((Chain **)ch), p_num(n) {
|
||||
advance();
|
||||
}
|
||||
HashRange(const HashRange &v): p_chains(v.p_chains), p_node(v.p_node),
|
||||
p_num(v.p_num) {}
|
||||
|
||||
HashRange &operator=(const HashRange &v) {
|
||||
p_chains = v.p_chains;
|
||||
p_node = v.p_node;
|
||||
p_num = v.p_num;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool empty() const { return !p_node && p_num <= 0; }
|
||||
|
||||
bool pop_front() {
|
||||
if (empty()) return false;
|
||||
if (p_node->next) {
|
||||
p_node = p_node->next;
|
||||
return true;
|
||||
}
|
||||
p_node = nullptr;
|
||||
advance();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool equals_front(const HashRange &v) const {
|
||||
return p_node == v.p_node;
|
||||
}
|
||||
|
||||
T &front() const { return p_node->value; }
|
||||
};
|
||||
|
||||
} /* namespace octa */
|
||||
|
||||
#endif
|
|
@ -17,7 +17,7 @@ namespace octa {
|
|||
|
||||
namespace detail {
|
||||
template<typename K, typename T> struct MapBase {
|
||||
typedef octa::Pair<const K, T> Element;
|
||||
using Element = octa::Pair<const K, T>;
|
||||
|
||||
static inline const K &get_key(Element &e) {
|
||||
return e.first;
|
||||
|
@ -56,6 +56,8 @@ public:
|
|||
using Reference = Value &;
|
||||
using Pointer = octa::AllocatorPointer<A>;
|
||||
using ConstPointer = octa::AllocatorConstPointer<A>;
|
||||
using Range = octa::HashRange<octa::Pair<const K, T>>;
|
||||
using ConstRange = octa::HashRange<const octa::Pair<const K, T>>;
|
||||
using Allocator = A;
|
||||
|
||||
Map(octa::Size size = 1 << 10, const H &hf = H(), const C &eqf = C(),
|
||||
|
@ -103,6 +105,10 @@ public:
|
|||
float max_load_factor() const { return p_table.max_load_factor(); }
|
||||
void max_load_factor(float lf) { p_table.max_load_factor(lf); }
|
||||
|
||||
Range each() { return p_table.each(); }
|
||||
ConstRange each() const { return p_table.each(); }
|
||||
ConstRange ceach() const { return p_table.ceach(); }
|
||||
|
||||
void swap(Map &v) {
|
||||
octa::swap(p_table, v.p_table);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue