concurrent_vector テンプレート・クラス

概要

同時に拡張してアクセスできるベクトル用のテンプレート・クラス。

構文

template<typename T, class Alloc=cache_aligned_allocator<T> >
class concurrent_vector;

ヘッダー

#include "tbb/concurrent_vector.h"

説明

concurrent_vector は、次の機能を備えたコンテナーです。

concurrent_vector は、ISO C++ 標準のコンテナーおよび可逆コンテナーのすべての要件を満たしています。insert() メソッドと erase() メソッドがないため、シーケンス要件は満たしていません。

メンバー

namespace tbb {
    template<typename T, typename Alloc=cache_aligned_allocator<T> >
    class concurrent_vector {
    public:
        typedef size_t size_type;
        typedef allocator-A-rebound-for-T allocator_type;
        typedef T value_type;
        typedef ptrdiff_t difference_type;
        typedef T& reference;
        typedef const T& const_reference;
        typedef T* pointer;
        typedef const T* const_pointer;
        typedef implementation-defined iterator;
        typedef implementation-defined const_iterator;
        typedef implementation-defined reverse_iterator;
        typedef implementation-defined const_reverse_iterator;

        // 並列範囲
        typedef implementation-defined range_type;
        typedef implementation-defined const_range_type;
        range_type range( size_t grainsize );
        const_range_type range( size_t grainsize ) const;

        // コンストラクター
        explicit concurrent_vector( const allocator_type& a = allocator_type() );
        concurrent_vector( const concurrent_vector& x );
        template<typename M>
        concurrent_vector( const concurrent_vector<T, M>& x );
        explicit concurrent_vector( size_type n, const T& t = T(),
                                    const allocator_type& a = allocator_type() );
        template<typename InputIterator>
        concurrent_vector( InputIterator first, InputIterator last,
                           const allocator_type& a = allocator_type());
        // C++11 仕様
        concurrent_vector( concurrent_vector&& x);
        concurrent_vector( concurrent_vector&& x, const allocator_type& a);
        concurrent_vector( std::initializer_list<T> il,
                           const allocator_type& a = allocator_type() );

        // 代入
        concurrent_vector& operator=( const concurrent_vector& x );
        template<class M>
        concurrent_vector& operator=( const concurrent_vector<T, M>& x );
        void assign( size_type n, const T& t );
        template<class InputIterator >
        void assign( InputIterator first, InputIterator last );
        // C++11 仕様
        concurrent_vector& operator=( concurrent_vector&& x );
        concurrent_vector& operator=( std::initializer_list<T> il );
        void assign( std::initializer_list<T> il );

        // 同時拡張操作
        iterator grow_by( size_type delta );
        iterator grow_by( size_type delta, const T& t );
        template<typename ForwardIterator>
        iterator grow_by( ForwardIterator first, ForwardIterator last );
        // C++11 仕様
        iterator grow_by( std::initializer_list<T>& il )
        iterator grow_to_at_least( size_type n );
        iterator grow_to_at_least( size_type n, const T& t );
        iterator push_back( const T& item );
        // C++11 仕様
        iterator push_back( T&& item );
        template<typename... Args>
        iterator emplace_back( Args&&... args);

        // アクセスするアイテム
        reference operator[]( size_type index );
        const_reference operator[]( size_type index ) const;
        reference at( size_type index );
        const_reference at( size_type index ) const;
        reference front();
        const_reference front() const;
        reference back();
        const_reference back() const;

        // 記憶域
        bool empty() const;
        size_type capacity() const;
        size_type max_size() const;
        size_type size() const;
        allocator_type get_allocator() const;

        // コンテナー全体で並列でない操作
        void reserve( size_type n );
        void compact();
        void swap( concurrent_vector& vector );
        void clear();
        ~concurrent_vector();

        // イテレーター
        iterator begin();
        iterator end();
        const_iterator begin() const;
        const_iterator end() const;
        reverse_iterator rbegin();
        reverse_iterator rend();
        const_reverse_iterator rbegin() const;
        const_reverse_iterator rend() const;
        // C++11 拡張
        const_iterator cbegin() const;
        const_iterator cend() const;
        const_reverse_iterator crbegin() const;
        const_reverse_iterator crend() const;
    };

    // グローバル関数
    template<typename T, class A1, class A2>
    bool operator==( const concurrent_vector<T, A1>& a,
                     const concurrent_vector<T, A2>& b );

    template<typename T, class A1, class A2>
    bool operator!=( const concurrent_vector<T, A1>& a,
                     const concurrent_vector<T, A2>& b );

    template<typename T, class A1, class A2>
    bool operator<( const concurrent_vector<T, A1>& a,
                       const concurrent_vector<T, A2>& b );

    template<typename T, class A1, class A2>
    bool operator>( const concurrent_vector<T, A1>& a,
                       const concurrent_vector<T, A2>& b );

    template<typename T, class A1, class A2>
    bool operator<=( const concurrent_vector<T, A1>& a,
                        const concurrent_vector<T, A2>& b );

    template<typename T, class A1, class A2>
    bool operator>=( const concurrent_vector<T, A1>& a,
                        const concurrent_vector<T, A2>& b );

    template<typename T, class A>
    void swap( concurrent_vector<T, A>& a, concurrent_vector<T, A>& b);
}

allocator_type の再結合は、std::vector の Microsoft® 実装および GNU* 実装に似ています。

例外の安全性

同時拡張と理想的な例外の安全性は、根本的に両立しません。しかし、concurrent_vector は、実用レベルでの例外の安全性を提供します。

要素型 T は、次の要件を満たしていなければなりません。

その他の場合のプログラムの動作は不定です。

拡張およびベクトル代入操作は、ベクトルに要素のシーケンスを追加します。例外が発生した場合、ベクトルへの影響はその原因に依存します。

ベクトルが壊れた場合、要素のアクセスには注意が必要です。

ただし、次のことは、ベクトルが壊れていてもいなくても保証されます。

同時拡張操作が完了すると、後続の拡張操作が失敗した場合であっても、追加されたシーケンスは有効なままとなり、アクセスできます。

フラグメンテーション

std::vector とは異なり、concurrent_vector は拡張する際に既存の要素を移動しません。コンテナーは、一連の連続した配列を割り当てます。最初の予約、拡張、または代入操作により、最初の配列のサイズが決定します。小さな要素数を初期サイズとして使用すると、キャッシュラインをまたぐフラグメンテーションが生じ、要素へのアクセス時間が増えることがあります。shrink_to_fit() メソッドは、複数の小さな配列を 1 つの連続する配列にマージします。これにより、アクセス時間が向上することがあります。