concurrent_vector

[containers.concurrent_vector]

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

クラス・テンプレートの概要


// <oneapi/tbb/concurrent_vector.h> ヘッダーで定義 namespace
 oneapi { 
        namespace tbb { 

            template <typename T, 
                       typename Allocator = cache_aligned_allocator<T>> 
            class concurrent_vector { 
                using value_type = T; 
                using allocator_type = Allocator; 

                using size_type = <implementation-defined unsigned integer type>; 
                using difference_type = <implementation-defined signed integer type>; 

                using reference = value_type&; 
                using const_reference = const value_type&; 

                using pointer = typename std::allocator_traits<allocator_type>::pointer; 
                using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer; 

                using iterator = <implementation-defined RandomAccessIterator>; 
                using const_iterator = <implementation-defined constant RandomAccessIterator>; 

                using reverse_iterator = std::reverse_iterator<iterator>; 
                using const_reverse_iterator = std::reverse_iterator<const_iterator>; 

                using range_type = <implementation-defined ContainerRange>; 
                using const_range_type = <implementation-defined constant ContainerRange>; 

                // 構築、破棄、複製 
                concurrent_vector(); 
                explicit concurrent_vector( const allocator_type& alloc ) noexcept; 

                explicit concurrent_vector( size_type count, const value_type& value, 
                                            const allocator_type& alloc = allocator_type() ); 

                explicit concurrent_vector( size_type count, 
                                            const allocator_type& alloc = allocator_type() ); 

                template <typename InputIterator> 
                concurrent_vector( InputIterator first, InputIterator last, 
                                           const allocator_type& alloc = allocator_type() ); 

                concurrent_vector( std::initializer_list<value_type> init, 
                                           const allocator_type& alloc = allocator_type() ); 

                concurrent_vector( const concurrent_vector& other ); 
                concurrent_vector( const concurrent_vector& other, const allocator_type& alloc ); 

                concurrent_vector( concurrent_vector&& other ) noexcept; 
                concurrent_vector( concurrent_vector&& other, const allocator_type& alloc ); 

                ~concurrent_vector(); 

                concurrent_vector& operator=( const concurrent_vector& other ); 

                concurrent_vector& operator=( concurrent_vector&& other ) noexcept(/*See details*/); 

                concurrent_vector& operator=( std::initializer_list<value_type> init ); 

                void assign( size_type count, const value_type& value ); 

                template <typename InputIterator> 
                void assign( InputIterator first, InputIterator last ); 

                void assign( std::initializer_list<value_type> init ); 

                // 同時伸長 
                iterator grow_by( size_type delta ); 
                iterator grow_by( size_type delta, const value_type& value ); 

                template <typename 
                InputIterator> iterator grow_by( InputIterator first, InputIterator last ); 

                iterator grow_by( std::initializer_list<value_type> init ); 

                iterator grow_to_at_least( size_type n ); 
                iterator grow_to_at_least( size_type n, const value_type& value ); 

                iterator push_back( const value_type& value ); 
                iterator push_back( value_type&& value ); 

                template <typename...Args
                > iterator emplace_back( Args&&... args ); 

                // 要素アクセス 
                value_type& operator[]( size_type index ); 
                const value_type& operator[]( size_type index ) const; 

                value_type& at( size_type index ); 
                const value_type& at( size_type index ) const; 

                value_type& front(); 
                const value_type& front() const; 

                value_type& back(); 
                const value_type& back() const; 

                // イテレーター 
                iterator begin(); 
                const_iterator begin() const; 
                const_iterator cbegin() const; 

                iterator end(); 
                const_iterator end() const; 
                const_iterator cend() const; 

                reverse_iterator rbegin(); 
                const_reverse_iterator rbegin() const; 
                const_reverse_iterator crbegin() const; 

                reverse_iterator rend(); 
                const_reverse_iterator rend() const; 
                const_reverse_iterator crend() const; 

                // サイズと容量 
                size_type size() const noexcept; 

                bool empty() const noexcept; 

                size_type max_size() const noexcept; 

                size_type capacity() const noexcept; 

                // 安全でない同時操作 
                void reserve( size_type n ); 

                void resize( size_type n ); 
                void resize( size_type n, const value_type& value ); 

                void shrink_to_fit(); 

                void swap( concurrent_vector& other ) noexcept(/*See details*/); 

                void clear(); 

                allocator_type get_allocator() const; 

                // 並列反復 
                range_type range( size_type grainsize = 1 ); 
                const_range_type range( size_type grainsize = 1 ) const; };
             // class concurrent_vector 
    } // namespace tbb }
 // namespace oneapi

要件:

  • T タイプは、次の要件を満たしていなければなりません。

    • [container.requirements] ISO C++ 標準の Erasable の要件。

    • デストラクターは例外をスローしてはなりません。

    • デフォルト・コンストラクターが例外をスローする可能性がある場合、デストラクターは非仮想であり、ゼロに設定されたメモリーで正しく動作できなければなりません。

    • メンバー関数は、操作タイプに応じてより厳密な要件を課す場合があります。

  • Allocator タイプは、[allocator.requirements] ISO C++ 標準の Allocator 要件を満たしている必要があります。

説明

oneapi::tbb::concurrent_vector は、次の機能を備えたシーケンスコンテナーを表すクラス・テンプレートです。

  • 複数のスレッドがコンテナーを同時に拡張し、新しい要素を追加できます。

  • インデックスによるランダムアクセス。最初の要素のインデックスはゼロです。

  • コンテナーを拡張しても既存のイテレーターまたはインデックスが無効になることはありません。

例外の安全性

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

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

  • 要素のコンストラクターによって例外がスローされた場合、追加されたシーケンスの残りはすべてゼロに設定されます。

  • そ例外は、ベクトルのアロケーターによって例外がスローされます。ベクトルが壊れます。追加されるシーケンスの各要素は、次の 3 つの状態のいずれかになります。

    • 構築済み

    • ゼロに設定

    • メモリーが未割り当て

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

  • at メソッドで未割り当ての要素にアクセスすると、std::range_error 例外が発生します。その他のメソッドを使用して未割り当ての要素にアクセスした場合の動作は未定義です。

  • capacity() および size() の値が予期される値よりも小さくなることがあります。

  • back() を使用して壊れたベクトルにアクセスした場合の動作は未定義です。

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

  • k を未割り当て要素のインデックスとします。次に、size() <= capacity() <= kとなります。

  • 拡張操作により size() または capacity() の値が減ることはありません。

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

メンバー関数

非メンバー関数

これらの関数は、oneapi::tbb::concurrent_vector オブジェクトに対してバイナリーおよび辞書式の順序の比較とスワップ操作を提供します。

これらの関数が定義される名前空間は、それぞれの比較操作で使用できるかぎり未指定です。例えば、実装では、同じ内部名前空間でクラスと関数を定義し oneapi::tbb::concurrent_vector をタイプエイリアスとして定義できます。この場合、非メンバー関数には引数依存のルックアップによってのみ到達できます。


template <typename T, typename Allocator> 
bool operator==( const concurrent_vector<T, Allocator>& lhs, 
                           const concurrent_vector<T, Allocator>& rhs ); 

template <typename T, typename Allocator> 
bool operator!=( const concurrent_vector<T, Allocator>& lhs, 
                           const concurrent_vector<T, Allocator>& rhs ); 

template <typename T, typename Allocator> 
bool operator<( const concurrent_vector<T, Allocator>& lhs, 
                           const concurrent_vector<T, Allocator>& rhs ); 

template <typename T, typename Allocator> 
bool operator<=( const concurrent_vector<T, Allocator>& lhs, 
                           const concurrent_vector<T, Allocator>& rhs ); 

template <typename T, typename Allocator> 
bool operator>( const concurrent_vector<T, Allocator>& lhs, 
                           const concurrent_vector<T, Allocator>& rhs ); 

template <typename T, typename Allocator> 
bool operator>=( const concurrent_vector<T, Allocator>& lhs, 
                           const concurrent_vector<T, Allocator>& rhs ); 

template <typename T, typename Allocator> 
void swap( concurrent_vector<T, Allocator>& lhs, 
                           concurrent_vector<T, Allocator>& rhs );

その他