实施连续(扁平)无序容器

时间:2017-04-04 22:25:40

标签: c++ boost stl containers

我正在尝试实现或从概念上设计一个容器,该容器具有连续的内存但元素顺序不重要(并且被用于插入/删除对象)。

这与std::vector类似,但解除了一个约束,即当一个元素被移除时,其他元素的相对顺序将被保留,因为在这种情况下,最后一个元素可以代替删除了一个。

我或多或少知道如何实现它(基于std::vector和一些特殊的反向引用iterator)但是我正在寻找一个参考实现来避免重新发明轮

我熟悉Boost.Container,但我找不到这样的容器。 boost::container::flat_set很接近,但它保持顺序,这是不必要的。从某种意义上说,我正在寻找某种“boost::container::unordered_flat_set”或“unordered_vector”。

这是我期望的行为:

unordered_flat_set<T> ufs(100); // allocates 100 elements
ufs.reserve(120);

unordered_flat_set<T>::iterator it = ...; // find something
ufs.erase(it); // overwrite last element to that position, destroy last element
ufs.insert(T{}); //add element at "end", only if necessary reallocate, keep buffer memory in multiples of 2 (or 1.6). Element order is not fundamental, can be altered completely by a call to "erase".
ufs.size(); // report size

eraseinsert都是O(1),(除非需要重新分配)。

这是一个尚未在标准或非标准容器中的概念。 (也许是无序的概念与当前的容器不能很好地配合。 毕竟唯一的“无序”目前是std::unordered_set并且它是相当新的。)

这是一个参考(非常小)的实现,它主要是给出我正在寻找的概念的具体实现。事实上,我正在寻找是否已经存在将其应用于现有基本代码的概念。 我不是想重新发明轮子。

#include<iostream>
#include<vector>

template<class T>
class unordered_vector{
    std::vector<T> impl_;
    public:
    unordered_vector(){}
    void reserve(int i){impl_.reserve(i);}
    struct iterator{
        std::vector<T>* back_ptr;
        int i;
        T& operator*(){return back_ptr->operator[](i);}
        iterator operator++(){++i; return *this;}
        iterator operator--(){--i; return *this;}
        bool operator==(iterator const& other) const{return back_ptr == other.back_ptr and i == other.i;}
        bool operator!=(iterator const& other) const{return not(*this == other);}
    };
    int size(){return impl_.size();}
    iterator erase(iterator it){
        *it = it.back_ptr->last(); // should I use placement new here to not rely in customized (or not assignable object type)?
        return it.back_ptr->erase(it.rbegin()); // I return this for compatibility, although there is no use for this
    }
    iterator insert(T t){
        impl_.push_back(t); return {&impl_, size()-1};
    }
    iterator begin(){return {&impl_, 0};} // does an unordered container have a begin ?? ok, for compatibility, like std::unordered_set
    iterator end(){return {&impl_, (int)impl_.size()};} // same question,
    T& operator[](int i){return impl_[i];} // same question, if it is unordered v[i] has not a "salient" meaning.
};

int main(){

    unordered_vector<double> uv;
    uv.reserve(10);
    uv.insert(1.1);
    uv.insert(2.3);
    uv.insert(5.4);
    uv.insert(3.1);
    std::cout << uv.size() << std::endl;
    auto it = uv.begin();
    assert( uv.begin() != uv.end());
    assert( it != uv.end() );
    for(auto it = uv.begin(); it != uv.end(); ++it){
        std::cout << *it << std::endl;
    }
}

0 个答案:

没有答案