Skip to content

Commit

Permalink
Added missing definitions of assignment operators.
Browse files Browse the repository at this point in the history
This fixes incorrect return types of assignment operators imported from
base classes. Other than copy and move assignment operators, which are
generated by the compiler even if imported with a using-declaration,
the imported operators will be returning a reference to the base class
instead of the derived class.

In concurrent_queue, the assignment operator was missing while copy/move
constructors were present and contained non-trivial logic. The implicitly
generated assignment operator would have been incorrect. The added assignment
operator reuses copy/move constructors to implement assignment.

In concurrent_bounded_queue, the assignment operator was also missing and
would have been deleted because of std::atomic member, while the class also
had copy and move constructors. The added assignment operator also reuses
the existing constructors.

Fixes #312.
Fixes #372.
Fixes #373.

Signed-off-by: Andrey Semashev <andrey.semashev@gmail.com>
  • Loading branch information
Lastique committed Nov 25, 2021
1 parent fb8ae3b commit 9ea86a8
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 8 deletions.
12 changes: 10 additions & 2 deletions include/oneapi/tbb/concurrent_map.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,6 @@ class concurrent_map : public concurrent_skip_list<map_traits<Key, Value, Compar

// Include constructors of base type
using base_type::base_type;
using base_type::operator=;

// Required for implicit deduction guides
concurrent_map() = default;
Expand All @@ -104,6 +103,11 @@ class concurrent_map : public concurrent_skip_list<map_traits<Key, Value, Compar
concurrent_map& operator=( const concurrent_map& ) = default;
concurrent_map& operator=( concurrent_map&& ) = default;

concurrent_map& operator=( std::initializer_list<value_type> il ) {
base_type::operator= (il);
return *this;
}

// Observers
mapped_type& at(const key_type& key) {
iterator it = this->find(key);
Expand Down Expand Up @@ -239,7 +243,6 @@ class concurrent_multimap : public concurrent_skip_list<map_traits<Key, Value, C
// Include constructors of base_type
using base_type::base_type;
using base_type::insert;
using base_type::operator=;

// Required for implicit deduction guides
concurrent_multimap() = default;
Expand All @@ -251,6 +254,11 @@ class concurrent_multimap : public concurrent_skip_list<map_traits<Key, Value, C
concurrent_multimap& operator=( const concurrent_multimap& ) = default;
concurrent_multimap& operator=( concurrent_multimap&& ) = default;

concurrent_multimap& operator=( std::initializer_list<value_type> il ) {
base_type::operator= (il);
return *this;
}

template <typename P>
typename std::enable_if<std::is_constructible<value_type, P&&>::value,
std::pair<iterator, bool>>::type insert( P&& value )
Expand Down
10 changes: 10 additions & 0 deletions include/oneapi/tbb/concurrent_queue.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,11 @@ class concurrent_queue {
r1::cache_aligned_deallocate(my_queue_representation);
}

concurrent_queue& operator= (concurrent_queue src) {
internal_swap(src);
return *this;
}

// Enqueue an item at tail of queue.
void push(const T& value) {
internal_push(value);
Expand Down Expand Up @@ -344,6 +349,11 @@ class concurrent_bounded_queue {
sizeof(queue_representation_type));
}

concurrent_bounded_queue& operator= (concurrent_bounded_queue src) {
internal_swap(src);
return *this;
}

// Enqueue an item at tail of queue.
void push( const T& value ) {
internal_push(value);
Expand Down
12 changes: 10 additions & 2 deletions include/oneapi/tbb/concurrent_set.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,6 @@ class concurrent_set : public concurrent_skip_list<set_traits<Key, Compare, conc

// Include constructors of base_type
using base_type::base_type;
using base_type::operator=;

// Required for implicit deduction guides
concurrent_set() = default;
Expand All @@ -87,6 +86,11 @@ class concurrent_set : public concurrent_skip_list<set_traits<Key, Compare, conc
concurrent_set& operator=( const concurrent_set& ) = default;
concurrent_set& operator=( concurrent_set&& ) = default;

concurrent_set& operator=( std::initializer_list<value_type> il ) {
base_type::operator= (il);
return *this;
}

template<typename OtherCompare>
void merge(concurrent_set<key_type, OtherCompare, Allocator>& source) {
this->internal_merge(source);
Expand Down Expand Up @@ -172,7 +176,6 @@ class concurrent_multiset : public concurrent_skip_list<set_traits<Key, Compare,

// Include constructors of base_type;
using base_type::base_type;
using base_type::operator=;

// Required for implicit deduction guides
concurrent_multiset() = default;
Expand All @@ -184,6 +187,11 @@ class concurrent_multiset : public concurrent_skip_list<set_traits<Key, Compare,
concurrent_multiset& operator=( const concurrent_multiset& ) = default;
concurrent_multiset& operator=( concurrent_multiset&& ) = default;

concurrent_multiset& operator=( std::initializer_list<value_type> il ) {
base_type::operator= (il);
return *this;
}

template<typename OtherCompare>
void merge(concurrent_set<key_type, OtherCompare, Allocator>& source) {
this->internal_merge(source);
Expand Down
12 changes: 10 additions & 2 deletions include/oneapi/tbb/concurrent_unordered_map.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,6 @@ class concurrent_unordered_map

// Include constructors of base type
using base_type::base_type;
using base_type::operator=;

// Required for implicit deduction guides
concurrent_unordered_map() = default;
Expand All @@ -82,6 +81,11 @@ class concurrent_unordered_map
concurrent_unordered_map& operator=( const concurrent_unordered_map& ) = default;
concurrent_unordered_map& operator=( concurrent_unordered_map&& ) = default;

concurrent_unordered_map& operator=( std::initializer_list<value_type> il ) {
base_type::operator= (il);
return *this;
}

// Observers
mapped_type& operator[]( const key_type& key ) {
iterator where = this->find(key);
Expand Down Expand Up @@ -255,7 +259,6 @@ class concurrent_unordered_multimap

// Include constructors of base type
using base_type::base_type;
using base_type::operator=;
using base_type::insert;

// Required for implicit deduction guides
Expand All @@ -268,6 +271,11 @@ class concurrent_unordered_multimap
concurrent_unordered_multimap& operator=( const concurrent_unordered_multimap& ) = default;
concurrent_unordered_multimap& operator=( concurrent_unordered_multimap&& ) = default;

concurrent_unordered_multimap& operator=( std::initializer_list<value_type> il ) {
base_type::operator= (il);
return *this;
}

template <typename P>
typename std::enable_if<std::is_constructible<value_type, P&&>::value,
std::pair<iterator, bool>>::type insert( P&& value ) {
Expand Down
13 changes: 11 additions & 2 deletions include/oneapi/tbb/concurrent_unordered_set.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ class concurrent_unordered_set

// Include constructors of base_type;
using base_type::base_type;
using base_type::operator=;

// Required for implicit deduction guides
concurrent_unordered_set() = default;
concurrent_unordered_set( const concurrent_unordered_set& ) = default;
Expand All @@ -79,6 +79,11 @@ class concurrent_unordered_set
concurrent_unordered_set& operator=( const concurrent_unordered_set& ) = default;
concurrent_unordered_set& operator=( concurrent_unordered_set&& ) = default;

concurrent_unordered_set& operator=( std::initializer_list<value_type> il ) {
base_type::operator= (il);
return *this;
}

template <typename OtherHash, typename OtherKeyEqual>
void merge( concurrent_unordered_set<key_type, OtherHash, OtherKeyEqual, allocator_type>& source ) {
this->internal_merge(source);
Expand Down Expand Up @@ -193,7 +198,6 @@ class concurrent_unordered_multiset

// Include constructors of base_type;
using base_type::base_type;
using base_type::operator=;

// Required for implicit deduction guides
concurrent_unordered_multiset() = default;
Expand All @@ -205,6 +209,11 @@ class concurrent_unordered_multiset
concurrent_unordered_multiset& operator=( const concurrent_unordered_multiset& ) = default;
concurrent_unordered_multiset& operator=( concurrent_unordered_multiset&& ) = default;

concurrent_unordered_multiset& operator=( std::initializer_list<value_type> il ) {
base_type::operator= (il);
return *this;
}

template <typename OtherHash, typename OtherKeyEqual>
void merge( concurrent_unordered_set<key_type, OtherHash, OtherKeyEqual, allocator_type>& source ) {
this->internal_merge(source);
Expand Down

0 comments on commit 9ea86a8

Please sign in to comment.