1

mmap を使用して固定サイズのセグメント プールを割り当てる、カスタマイズされたスラブ アロケータを作成しました。これらのセグメントは、論理的には連続していますが、物理的には個別です。また、プールの論理開始点からのオフセットを含むポインタ ラッパー クラスも定義しました。ポインタ クラスは次のようになります。

template<typename T>
struct offptr_t {
    typedef offptr_t<T> this_t;
    typedef T element_type;
    typedef OFFSET difference_type;
    template<typename U> struct rebind { typedef offptr_t<U> other; };
    offptr_t(const mem_pool *p, OFFSET o)
    : pool(p), offset(o)
    {}
    // ...
};

アロケーターは次のとおりです。

template<typename T>
struct mem_pool_allocator {
public:
    typedef mem_pool_allocator<T> this_t;
    typedef T value_type;
    typedef offptr_t<T> pointer;
    typedef const offptr_t<T> const_pointer;
    typedef T& reference;
    typedef const T& const_reference;
    typedef size_t size_type;
    typedef int64_t difference_type;
    template< class U > struct rebind { typedef mem_pool_allocator<U> other; };
    // ...
};

次に、必要な STL として pointer_traits および iterator_traits クラスを定義しました。

namespace std {
    template<typename T>
    struct pointer_traits<offptr_t<T>> {
        typedef typename offptr_t<T> pointer;
        template<typename U> struct rebind { typedef offptr_t<U> other; };
    };

    template<typename T>
    struct iterator_traits<offptr_t<T>> {
        typedef typename offptr_t<T> pointer;
        typedef typename pointer::difference_type difference_type;
        typedef typename pointer::element_type value_type;
        typedef typename pointer::element_type &reference;
        typedef std::random_access_iterator_tag iterator_category;
    };
}   // End of namespace std

これらのクラスを libc++ の STL コンテナーで使用すると、c++/v1/vector でいくつかのコンパイル エラーが発生しました。

template <class _Tp, class _Allocator>
_LIBCPP_INLINE_VISIBILITY inline
void
__vector_base<_Tp, _Allocator>::__destruct_at_end(const_pointer __new_last, false_type) _NOEXCEPT
{
    while (__new_last != __end_)
        __alloc_traits::destroy(__alloc(), const_cast<pointer>(--__end_));
}


template <class _Tp, class _Allocator>
_LIBCPP_INLINE_VISIBILITY inline
void
__vector_base<_Tp, _Allocator>::__destruct_at_end(const_pointer __new_last, true_type) _NOEXCEPT
{
    __end_ = const_cast<pointer>(__new_last);
}

ベクトルはポインター型で const_cast<> を使用しています。const_cast<> は生のポインター/参照でのみ使用でき、オーバーロードできません。つまり、カスタマイズされたポインターのようなオブジェクトを操作することは不可能です。

私は何か間違ったことをしていますか、それとも libc++ の STL 実装の欠陥ですか?

4

1 に答える 1

0

これは libc++ のバグのように見えます。修正作業中です…

于 2013-02-02T00:36:54.937 に答える