forked from OctaForge/libostd
support for hashtable assignment ops
parent
cfe7450d4b
commit
eca4310caf
|
@ -152,8 +152,16 @@ namespace detail {
|
||||||
|
|
||||||
A &get_alloc() { return p_data.second().first().first(); }
|
A &get_alloc() { return p_data.second().first().first(); }
|
||||||
const A &get_alloc() const { return p_data.second().first().first(); }
|
const A &get_alloc() const { return p_data.second().first().first(); }
|
||||||
|
|
||||||
CPA &get_cpalloc() { return p_data.second().first().second().first(); }
|
CPA &get_cpalloc() { return p_data.second().first().second().first(); }
|
||||||
|
const CPA &get_cpalloc() const {
|
||||||
|
return p_data.second().first().second().first();
|
||||||
|
}
|
||||||
|
|
||||||
CHA &get_challoc() { return p_data.second().first().second().second(); }
|
CHA &get_challoc() { return p_data.second().first().second().second(); }
|
||||||
|
const CHA &get_challoc() const {
|
||||||
|
return p_data.second().first().second().second();
|
||||||
|
}
|
||||||
|
|
||||||
Hashtable(octa::Size size, const H &hf, const C &eqf, const A &alloc):
|
Hashtable(octa::Size size, const H &hf, const C &eqf, const A &alloc):
|
||||||
p_size(size), p_len(0), p_chunks(nullptr), p_unused(nullptr),
|
p_size(size), p_len(0), p_chunks(nullptr), p_unused(nullptr),
|
||||||
|
@ -230,6 +238,38 @@ namespace detail {
|
||||||
delete_chunks(p_chunks);
|
delete_chunks(p_chunks);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Hashtable &operator=(const Hashtable &ht) {
|
||||||
|
clear();
|
||||||
|
if (octa::AllocatorPropagateOnContainerCopyAssignment<A>::value) {
|
||||||
|
if ((get_cpalloc() != ht.get_cpalloc()) && p_size) {
|
||||||
|
octa::allocator_deallocate(get_cpalloc(),
|
||||||
|
p_data.first(), p_size);
|
||||||
|
p_data.first() = octa::allocator_allocate(get_cpalloc(),
|
||||||
|
p_size);
|
||||||
|
memset(p_data.first(), 0, p_size * sizeof(Chain *));
|
||||||
|
}
|
||||||
|
get_alloc() = ht.get_alloc();
|
||||||
|
get_cpalloc() = ht.get_cpalloc();
|
||||||
|
get_challoc() = ht.get_challoc();
|
||||||
|
}
|
||||||
|
for (ConstRange range = ht.each(); !range.empty(); range.pop_front())
|
||||||
|
emplace(range.front());
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Hashtable &operator=(Hashtable &&ht) {
|
||||||
|
clear();
|
||||||
|
octa::swap(p_size, ht.p_size);
|
||||||
|
octa::swap(p_len, ht.p_len);
|
||||||
|
octa::swap(p_chunks, ht.p_chunks);
|
||||||
|
octa::swap(p_unused, ht.p_unused);
|
||||||
|
octa::swap(p_data.first(), ht.p_data.first());
|
||||||
|
octa::swap(p_data.second().second(), ht.p_data.second().second());
|
||||||
|
if (octa::AllocatorPropagateOnContainerMoveAssignment<A>::value)
|
||||||
|
octa::swap(p_data.second().first(), ht.p_data.second().first());
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
bool empty() const { return p_len == 0; }
|
bool empty() const { return p_len == 0; }
|
||||||
octa::Size size() const { return p_len; }
|
octa::Size size() const { return p_len; }
|
||||||
Size max_size() const { return Size(~0) / sizeof(E); }
|
Size max_size() const { return Size(~0) / sizeof(E); }
|
||||||
|
@ -403,10 +443,14 @@ namespace detail {
|
||||||
return Range(p_data.first(), p_data.first() + bucket_count());
|
return Range(p_data.first(), p_data.first() + bucket_count());
|
||||||
}
|
}
|
||||||
ConstRange each() const {
|
ConstRange each() const {
|
||||||
return ConstRange(p_data.first(), p_data.first() + bucket_count());
|
using Chain = octa::detail::HashChain<const E>;
|
||||||
|
return ConstRange((Chain **)p_data.first(),
|
||||||
|
(Chain **)(p_data.first() + bucket_count()));
|
||||||
}
|
}
|
||||||
ConstRange ceach() const {
|
ConstRange ceach() const {
|
||||||
return ConstRange(p_data.first(), p_data.first() + bucket_count());
|
using Chain = octa::detail::HashChain<const E>;
|
||||||
|
return ConstRange((Chain **)p_data.first(),
|
||||||
|
(Chain **)(p_data.first() + bucket_count()));
|
||||||
}
|
}
|
||||||
|
|
||||||
LocalRange each(octa::Size n) {
|
LocalRange each(octa::Size n) {
|
||||||
|
@ -414,23 +458,25 @@ namespace detail {
|
||||||
return LocalRange(p_data.first()[n]);
|
return LocalRange(p_data.first()[n]);
|
||||||
}
|
}
|
||||||
ConstLocalRange each(octa::Size n) const {
|
ConstLocalRange each(octa::Size n) const {
|
||||||
|
using Chain = octa::detail::HashChain<const E>;
|
||||||
if (n >= p_size) return ConstLocalRange();
|
if (n >= p_size) return ConstLocalRange();
|
||||||
return ConstLocalRange(p_data.first()[n]);
|
return ConstLocalRange((Chain *)p_data.first()[n]);
|
||||||
}
|
}
|
||||||
ConstLocalRange ceach(octa::Size n) const {
|
ConstLocalRange ceach(octa::Size n) const {
|
||||||
|
using Chain = octa::detail::HashChain<const E>;
|
||||||
if (n >= p_size) return ConstLocalRange();
|
if (n >= p_size) return ConstLocalRange();
|
||||||
return ConstLocalRange(p_data.first()[n]);
|
return ConstLocalRange((Chain *)p_data.first()[n]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void swap(Hashtable &h) {
|
void swap(Hashtable &ht) {
|
||||||
octa::swap(p_size, h.p_size);
|
octa::swap(p_size, ht.p_size);
|
||||||
octa::swap(p_len, h.p_len);
|
octa::swap(p_len, ht.p_len);
|
||||||
octa::swap(p_chunks, h.p_chunks);
|
octa::swap(p_chunks, ht.p_chunks);
|
||||||
octa::swap(p_unused, h.p_unused);
|
octa::swap(p_unused, ht.p_unused);
|
||||||
octa::swap(p_data.first(), h.p_data.first());
|
octa::swap(p_data.first(), ht.p_data.first());
|
||||||
octa::swap(p_data.second().second(), h.p_data.second().second());
|
octa::swap(p_data.second().second(), ht.p_data.second().second());
|
||||||
if (octa::AllocatorPropagateOnContainerSwap<A>::value)
|
if (octa::AllocatorPropagateOnContainerSwap<A>::value)
|
||||||
octa::swap(p_data.second().first(), h.p_data.second().first());
|
octa::swap(p_data.second().first(), ht.p_data.second().first());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} /* namespace detail */
|
} /* namespace detail */
|
||||||
|
|
30
octa/map.h
30
octa/map.h
|
@ -118,6 +118,36 @@ public:
|
||||||
const A &alloc
|
const A &alloc
|
||||||
): Map(octa::each(init), size, hf, C(), alloc) {}
|
): Map(octa::each(init), size, hf, C(), alloc) {}
|
||||||
|
|
||||||
|
Map &operator=(const Map &m) {
|
||||||
|
p_table = m.p_table;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map &operator=(Map &&m) {
|
||||||
|
p_table = octa::move(m.p_table);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename R>
|
||||||
|
octa::EnableIf<
|
||||||
|
octa::IsInputRange<R>::value &&
|
||||||
|
octa::IsConvertible<RangeReference<R>, Value>::value,
|
||||||
|
Map &
|
||||||
|
> operator=(R range) {
|
||||||
|
clear();
|
||||||
|
for (; !range.empty(); range.pop_front())
|
||||||
|
emplace(range.front());
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map &operator=(InitializerList<Value> il) {
|
||||||
|
Value *beg = il.begin(), *end = il.end();
|
||||||
|
clear();
|
||||||
|
while (beg != end)
|
||||||
|
emplace(*beg++);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
bool empty() const { return p_table.empty(); }
|
bool empty() const { return p_table.empty(); }
|
||||||
octa::Size size() const { return p_table.size(); }
|
octa::Size size() const { return p_table.size(); }
|
||||||
octa::Size max_size() const { return p_table.max_size(); }
|
octa::Size max_size() const { return p_table.max_size(); }
|
||||||
|
|
Loading…
Reference in New Issue