9119 {
9120 if (_type == xpath_node_set::type_unsorted && _end - _begin > 2)
9121 {
9122 xpath_allocator_capture cr(alloc);
9123
9124 size_t size_ = static_cast<size_t>(_end - _begin);
9125
9126 size_t hash_size = 1;
9127 while (hash_size < size_ + size_ / 2) hash_size *= 2;
9128
9129 const void** hash_data =
static_cast<const void**
>(alloc->
allocate(hash_size *
sizeof(
void**)));
9130 if (!hash_data) return;
9131
9132 memset(hash_data, 0, hash_size * sizeof(const void**));
9133
9134 xpath_node* write = _begin;
9135
9136 for (xpath_node* it = _begin; it != _end; ++it)
9137 {
9138 const void* attr = it->attribute().internal_object();
9139 const void* node = it->node().internal_object();
9140 const void* key = attr ? attr : node;
9141
9142 if (key &&
hash_insert(hash_data, hash_size, key))
9143 {
9144 *write++ = *it;
9145 }
9146 }
9147
9148 _end = write;
9149 }
9150 else
9151 {
9152 _end =
unique(_begin, _end);
9153 }
9154 }
PUGI__FN I unique(I begin, I end)
PUGI__FN bool hash_insert(const void **table, size_t size, const void *key)
void * allocate(size_t size)