diff --git a/.clang-tidy b/.clang-tidy index 37f90618f..97f5bdcc0 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -23,6 +23,7 @@ hicpp-*,\ misc-*,\ -misc-const-correctness,\ -misc-include-cleaner,\ +-misc-use-internal-linkage,\ modernize-*,\ -modernize-avoid-c-arrays,\ -modernize-use-auto,\ diff --git a/examples/createAndDestroyDeviceObject.cpp b/examples/createAndDestroyDeviceObject.cpp index eebcb2604..26a57471b 100644 --- a/examples/createAndDestroyDeviceObject.cpp +++ b/examples/createAndDestroyDeviceObject.cpp @@ -69,7 +69,7 @@ class Image STDGPU_HOST_DEVICE std::uint8_t& operator()(const stdgpu::index_t x, const stdgpu::index_t y) { - return _values[y * _width + x]; + return _values[(y * _width) + x]; } STDGPU_HOST_DEVICE stdgpu::index_t diff --git a/src/stdgpu/impl/algorithm_detail.h b/src/stdgpu/impl/algorithm_detail.h index 9f275fd81..f589e49ea 100644 --- a/src/stdgpu/impl/algorithm_detail.h +++ b/src/stdgpu/impl/algorithm_detail.h @@ -29,14 +29,14 @@ template constexpr STDGPU_HOST_DEVICE const T& min(const T& a, const T& b) { - return (b < a) ? b : a; + return (b < a) ? b : a; // NOLINT(bugprone-return-const-ref-from-parameter) } template constexpr STDGPU_HOST_DEVICE const T& max(const T& a, const T& b) { - return (a < b) ? b : a; + return (a < b) ? b : a; // NOLINT(bugprone-return-const-ref-from-parameter) } template @@ -45,7 +45,8 @@ clamp(const T& v, const T& lower, const T& upper) { STDGPU_EXPECTS(!(upper < lower)); - return v < lower ? lower : upper < v ? upper : v; // NOLINT(readability-avoid-nested-conditional-operator) + // NOLINTNEXTLINE(bugprone-return-const-ref-from-parameter,readability-avoid-nested-conditional-operator) + return v < lower ? lower : upper < v ? upper : v; } template (policy), thrust::counting_iterator(0), thrust::counting_iterator(size), - f); + std::move(f)); } namespace detail diff --git a/src/stdgpu/impl/bitset_detail.cuh b/src/stdgpu/impl/bitset_detail.cuh index c5c8fb73a..46f6b79ce 100644 --- a/src/stdgpu/impl/bitset_detail.cuh +++ b/src/stdgpu/impl/bitset_detail.cuh @@ -17,6 +17,7 @@ #define STDGPU_BITSET_DETAIL_H #include +#include #include #include @@ -119,7 +120,7 @@ div_up(const index_t a, const index_t b) noexcept STDGPU_EXPECTS(a >= 0); STDGPU_EXPECTS(b > 0); - index_t result = (a % b != 0) ? (a / b + 1) : (a / b); + index_t result = (a % b != 0) ? ((a / b) + 1) : (a / b); STDGPU_ENSURES(result * b >= a); @@ -146,7 +147,7 @@ private: STDGPU_HOST_DEVICE Block block_mask(const index_t i) const { - index_t remaining_bits = _size - i * _bits_per_block; + index_t remaining_bits = _size - (i * _bits_per_block); return (remaining_bits >= _bits_per_block) ? ~static_cast(0) : (static_cast(1) << static_cast(remaining_bits)) - static_cast(1); @@ -256,7 +257,7 @@ template ::set(ExecutionPolicy&& policy) { - fill(std::forward(policy), device_begin(_bit_blocks), device_end(_bit_blocks), ~block_type(0)); + fill(std::decay_t{ policy }, device_begin(_bit_blocks), device_end(_bit_blocks), ~block_type(0)); STDGPU_ENSURES(count(std::forward(policy)) == size()); } @@ -284,7 +285,7 @@ template ::reset(ExecutionPolicy&& policy) { - fill(std::forward(policy), device_begin(_bit_blocks), device_end(_bit_blocks), block_type(0)); + fill(std::decay_t{ policy }, device_begin(_bit_blocks), device_end(_bit_blocks), block_type(0)); STDGPU_ENSURES(count(std::forward(policy)) == 0); } diff --git a/src/stdgpu/impl/deque_detail.cuh b/src/stdgpu/impl/deque_detail.cuh index fbda4d320..637953aa5 100644 --- a/src/stdgpu/impl/deque_detail.cuh +++ b/src/stdgpu/impl/deque_detail.cuh @@ -16,6 +16,8 @@ #ifndef STDGPU_DEQUE_DETAIL_H #define STDGPU_DEQUE_DETAIL_H +#include + #include #include #include @@ -42,19 +44,21 @@ deque::createDeviceObject(ExecutionPolicy&& policy, const index_t& deque result( mutex_array::createDeviceObject( - std::forward(policy), + std::decay_t{ policy }, capacity, mutex_array_allocator_type(allocator)), bitset::createDeviceObject( - std::forward(policy), + std::decay_t{ policy }, capacity, bitset_allocator_type(allocator)), - atomic::createDeviceObject(std::forward(policy), + atomic::createDeviceObject(std::decay_t{ policy }, atomic_int_allocator_type(allocator)), - atomic::createDeviceObject(std::forward(policy), - atomic_uint_allocator_type(allocator)), - atomic::createDeviceObject(std::forward(policy), - atomic_uint_allocator_type(allocator)), + atomic::createDeviceObject( + std::decay_t{ policy }, + atomic_uint_allocator_type(allocator)), + atomic::createDeviceObject( + std::decay_t{ policy }, + atomic_uint_allocator_type(allocator)), allocator); result._data = allocator_traits::allocate(result._allocator, capacity); result._range_indices = allocator_traits::allocate(result._index_allocator, capacity); @@ -77,7 +81,7 @@ deque::destroyDeviceObject(ExecutionPolicy&& policy, deque()) { - device_object.clear(std::forward(policy)); + device_object.clear(std::decay_t{ policy }); } allocator_traits::deallocate(device_object._allocator, @@ -89,13 +93,13 @@ deque::destroyDeviceObject(ExecutionPolicy&& policy, deque::destroyDeviceObject( - std::forward(policy), + std::decay_t{ policy }, device_object._locks); - bitset::destroyDeviceObject(std::forward(policy), + bitset::destroyDeviceObject(std::decay_t{ policy }, device_object._occupied); - atomic::destroyDeviceObject(std::forward(policy), + atomic::destroyDeviceObject(std::decay_t{ policy }, device_object._size); - atomic::destroyDeviceObject(std::forward(policy), + atomic::destroyDeviceObject(std::decay_t{ policy }, device_object._begin); atomic::destroyDeviceObject(std::forward(policy), device_object._end); @@ -550,48 +554,50 @@ template ::clear(ExecutionPolicy&& policy) { - if (empty(std::forward(policy))) + if (empty(std::decay_t{ policy })) { return; } if (!detail::is_destroy_optimizable()) { - const index_t begin = static_cast(_begin.load(std::forward(policy))); - const index_t end = static_cast(_end.load(std::forward(policy))); + const index_t begin = static_cast(_begin.load(std::decay_t{ policy })); + const index_t end = static_cast(_end.load(std::decay_t{ policy })); // Full, i.e. one large block and begin == end - if (full(std::forward(policy))) + if (full(std::decay_t{ policy })) { - detail::unoptimized_destroy(std::forward(policy), device_begin(_data), device_end(_data)); + detail::unoptimized_destroy(std::decay_t{ policy }, + device_begin(_data), + device_end(_data)); } // One large block else if (begin <= end) { - detail::unoptimized_destroy(std::forward(policy), + detail::unoptimized_destroy(std::decay_t{ policy }, make_device(_data + begin), make_device(_data + end)); } // Two disconnected blocks else { - detail::unoptimized_destroy(std::forward(policy), + detail::unoptimized_destroy(std::decay_t{ policy }, device_begin(_data), make_device(_data + end)); - detail::unoptimized_destroy(std::forward(policy), + detail::unoptimized_destroy(std::decay_t{ policy }, make_device(_data + begin), device_end(_data)); } } - _occupied.reset(std::forward(policy)); + _occupied.reset(std::decay_t{ policy }); - _size.store(std::forward(policy), 0); + _size.store(std::decay_t{ policy }, 0); - _begin.store(std::forward(policy), 0); - _end.store(std::forward(policy), 0); + _begin.store(std::decay_t{ policy }, 0); + _end.store(std::decay_t{ policy }, 0); - STDGPU_ENSURES(empty(std::forward(policy))); + STDGPU_ENSURES(empty(std::decay_t{ policy })); STDGPU_ENSURES(valid(std::forward(policy))); } @@ -614,9 +620,9 @@ deque::valid(ExecutionPolicy&& policy) const return true; } - return (size_valid(std::forward(policy)) && - occupied_count_valid(std::forward(policy)) && - _locks.valid(std::forward(policy))); + return (size_valid(std::decay_t{ policy }) && + occupied_count_valid(std::decay_t{ policy }) && + _locks.valid(std::decay_t{ policy })); } template @@ -632,18 +638,18 @@ template deque::device_range(ExecutionPolicy&& policy) { - const index_t begin = static_cast(_begin.load(std::forward(policy))); - const index_t end = static_cast(_end.load(std::forward(policy))); + const index_t begin = static_cast(_begin.load(std::decay_t{ policy })); + const index_t end = static_cast(_end.load(std::decay_t{ policy })); // Full, i.e. one large block and begin == end - if (full(std::forward(policy))) + if (full(std::decay_t{ policy })) { - iota(std::forward(policy), device_begin(_range_indices), device_end(_range_indices), 0); + iota(std::decay_t{ policy }, device_begin(_range_indices), device_end(_range_indices), 0); } // One large block, including empty block else if (begin <= end) { - iota(std::forward(policy), + iota(std::decay_t{ policy }, device_begin(_range_indices), device_begin(_range_indices) + (end - begin), begin); @@ -651,11 +657,11 @@ deque::device_range(ExecutionPolicy&& policy) // Two disconnected blocks else { - iota(std::forward(policy), + iota(std::decay_t{ policy }, device_begin(_range_indices), device_begin(_range_indices) + end, 0); - iota(std::forward(policy), + iota(std::decay_t{ policy }, device_begin(_range_indices) + end, device_begin(_range_indices) + (end + capacity() - begin), begin); @@ -679,18 +685,18 @@ template deque::device_range(ExecutionPolicy&& policy) const { - const index_t begin = static_cast(_begin.load(std::forward(policy))); - const index_t end = static_cast(_end.load(std::forward(policy))); + const index_t begin = static_cast(_begin.load(std::decay_t{ policy })); + const index_t end = static_cast(_end.load(std::decay_t{ policy })); // Full, i.e. one large block and begin == end - if (full(std::forward(policy))) + if (full(std::decay_t{ policy })) { - iota(std::forward(policy), device_begin(_range_indices), device_end(_range_indices), 0); + iota(std::decay_t{ policy }, device_begin(_range_indices), device_end(_range_indices), 0); } // One large block, including empty block else if (begin <= end) { - iota(std::forward(policy), + iota(std::decay_t{ policy }, device_begin(_range_indices), device_begin(_range_indices) + (end - begin), begin); @@ -698,11 +704,11 @@ deque::device_range(ExecutionPolicy&& policy) const // Two disconnected blocks else { - iota(std::forward(policy), + iota(std::decay_t{ policy }, device_begin(_range_indices), device_begin(_range_indices) + end, 0); - iota(std::forward(policy), + iota(std::decay_t{ policy }, device_begin(_range_indices) + end, device_begin(_range_indices) + (end + capacity() - begin), begin); @@ -726,7 +732,7 @@ template ::occupied_count_valid(ExecutionPolicy&& policy) const { - index_t size_count = size(std::forward(policy)); + index_t size_count = size(std::decay_t{ policy }); index_t size_sum = _occupied.count(std::forward(policy)); return (size_count == size_sum); diff --git a/src/stdgpu/impl/memory_detail.h b/src/stdgpu/impl/memory_detail.h index 91fc1e47b..33238eb89 100644 --- a/src/stdgpu/impl/memory_detail.h +++ b/src/stdgpu/impl/memory_detail.h @@ -174,7 +174,7 @@ unoptimized_destroy(ExecutionPolicy&& policy, Iterator first, Iterator last) template T* -createDeviceArray(const stdgpu::index64_t count, const T default_value) +createDeviceArray(const stdgpu::index64_t count, const T default_value) // NOLINT(performance-unnecessary-value-param) { T* device_array = nullptr; @@ -441,8 +441,8 @@ template >)> device_unique_object::device_unique_object(ExecutionPolicy&& policy, Args&&... args) - : _object(new T(T::createDeviceObject(std::forward(policy), std::forward(args)...)), - [_policy = std::forward(policy)](T* ptr) + : _object(new T(T::createDeviceObject(std::decay_t{ policy }, std::forward(args)...)), + [_policy = std::decay_t{ policy }](T* ptr) { T::destroyDeviceObject(_policy, *ptr); delete ptr; diff --git a/src/stdgpu/impl/unordered_base_detail.cuh b/src/stdgpu/impl/unordered_base_detail.cuh index e5e350053..ad72e0fbb 100644 --- a/src/stdgpu/impl/unordered_base_detail.cuh +++ b/src/stdgpu/impl/unordered_base_detail.cuh @@ -17,6 +17,7 @@ #define STDGPU_UNORDERED_BASE_DETAIL_H #include +#include #include #include @@ -168,9 +169,9 @@ template ::value_type> unordered_base::device_range(ExecutionPolicy&& policy) { - _range_indices_end.store(std::forward(policy), 0); + _range_indices_end.store(std::decay_t{ policy }, 0); - for_each_index(std::forward(policy), + for_each_index(std::decay_t{ policy }, total_count(), unordered_base_collect_positions(*this)); @@ -193,9 +194,9 @@ template ::value_type> unordered_base::device_range(ExecutionPolicy&& policy) const { - _range_indices_end.store(std::forward(policy), 0); + _range_indices_end.store(std::decay_t{ policy }, 0); - for_each_index(std::forward(policy), + for_each_index(std::decay_t{ policy }, total_count(), unordered_base_collect_positions(*this)); @@ -324,16 +325,16 @@ loop_free(ExecutionPolicy&& policy, const unordered_base::template rebind_alloc; flags_allocator_type flags_allocator = flags_allocator_type(base.get_allocator()); - int* flags = allocator_traits::allocate_filled(std::forward(policy), + int* flags = allocator_traits::allocate_filled(std::decay_t{ policy }, flags_allocator, base.total_count(), 0); - for_each_index(std::forward(policy), + for_each_index(std::decay_t{ policy }, base.bucket_count(), count_visits(base, flags)); - bool result = transform_reduce_index(std::forward(policy), + bool result = transform_reduce_index(std::decay_t{ policy }, base.total_count(), true, logical_and<>(), @@ -459,7 +460,7 @@ inline bool occupied_count_valid(ExecutionPolicy&& policy, const unordered_base& base) { - index_t size_count = base.size(std::forward(policy)); + index_t size_count = base.size(std::decay_t{ policy }); index_t size_sum = base._occupied.count(std::forward(policy)); return (size_count == size_sum); @@ -1197,13 +1198,13 @@ unordered_base::valid(Execu return true; } - return (offset_range_valid(std::forward(policy), *this) && - loop_free(std::forward(policy), *this) && - values_reachable(std::forward(policy), *this) && - unique(std::forward(policy), *this) && - occupied_count_valid(std::forward(policy), *this) && - _locks.valid(std::forward(policy)) && - _excess_list_positions.valid(std::forward(policy))); + return (offset_range_valid(std::decay_t{ policy }, *this) && + loop_free(std::decay_t{ policy }, *this) && + values_reachable(std::decay_t{ policy }, *this) && + unique(std::decay_t{ policy }, *this) && + occupied_count_valid(std::decay_t{ policy }, *this) && + _locks.valid(std::decay_t{ policy }) && + _excess_list_positions.valid(std::decay_t{ policy })); } template @@ -1219,23 +1220,23 @@ template ::clear(ExecutionPolicy&& policy) { - if (empty(std::forward(policy))) + if (empty(std::decay_t{ policy })) { return; } if (!detail::is_destroy_optimizable()) { - for_each_index(std::forward(policy), + for_each_index(std::decay_t{ policy }, total_count(), destroy_values(*this)); } - fill(std::forward(policy), device_begin(_offsets), device_end(_offsets), 0); + fill(std::decay_t{ policy }, device_begin(_offsets), device_end(_offsets), 0); - _occupied.reset(std::forward(policy)); + _occupied.reset(std::decay_t{ policy }); - _occupied_count.store(std::forward(policy), 0); + _occupied_count.store(std::decay_t{ policy }, 0); detail::vector_clear_iota(std::forward(policy), _excess_list_positions, bucket_count()); } @@ -1263,24 +1264,24 @@ unordered_base::createDevic unordered_base result( bitset::createDeviceObject( - std::forward(policy), + std::decay_t{ policy }, total_count, bitset_allocator_type(allocator)), - atomic::createDeviceObject(std::forward(policy), + atomic::createDeviceObject(std::decay_t{ policy }, atomic_allocator_type(allocator)), - vector::createDeviceObject(std::forward(policy), + vector::createDeviceObject(std::decay_t{ policy }, excess_count, index_allocator_type(allocator)), mutex_array::createDeviceObject( - std::forward(policy), + std::decay_t{ policy }, total_count, mutex_array_allocator_type(allocator)), - atomic::createDeviceObject(std::forward(policy), + atomic::createDeviceObject(std::decay_t{ policy }, atomic_allocator_type(allocator)), allocator); result._bucket_count = bucket_count; result._values = allocator_traits::allocate(result._allocator, total_count); - result._offsets = allocator_traits::allocate_filled(std::forward(policy), + result._offsets = allocator_traits::allocate_filled(std::decay_t{ policy }, result._index_allocator, total_count, 0); @@ -1289,7 +1290,7 @@ unordered_base::createDevic result._hash = hasher(); result._key_equal = key_equal(); - detail::vector_clear_iota(std::forward(policy), result._excess_list_positions, bucket_count); + detail::vector_clear_iota(std::decay_t{ policy }, result._excess_list_positions, bucket_count); STDGPU_ENSURES(result._excess_list_positions.full(std::forward(policy))); @@ -1306,28 +1307,28 @@ unordered_base::destroyDevi { if (!detail::is_destroy_optimizable()) { - device_object.clear(std::forward(policy)); + device_object.clear(std::decay_t{ policy }); } device_object._bucket_count = 0; allocator_traits::deallocate(device_object._allocator, device_object._values, device_object.total_count()); - allocator_traits::deallocate_filled(std::forward(policy), + allocator_traits::deallocate_filled(std::decay_t{ policy }, device_object._index_allocator, device_object._offsets, device_object.total_count()); allocator_traits::deallocate(device_object._index_allocator, device_object._range_indices, device_object.total_count()); - bitset::destroyDeviceObject(std::forward(policy), + bitset::destroyDeviceObject(std::decay_t{ policy }, device_object._occupied); - atomic::destroyDeviceObject(std::forward(policy), + atomic::destroyDeviceObject(std::decay_t{ policy }, device_object._occupied_count); mutex_array::destroyDeviceObject( - std::forward(policy), + std::decay_t{ policy }, device_object._locks); - vector::destroyDeviceObject(std::forward(policy), + vector::destroyDeviceObject(std::decay_t{ policy }, device_object._excess_list_positions); atomic::destroyDeviceObject(std::forward(policy), device_object._range_indices_end); diff --git a/src/stdgpu/impl/vector_detail.cuh b/src/stdgpu/impl/vector_detail.cuh index 159645f2d..fd84cd4d4 100644 --- a/src/stdgpu/impl/vector_detail.cuh +++ b/src/stdgpu/impl/vector_detail.cuh @@ -16,6 +16,8 @@ #ifndef STDGPU_VECTOR_DETAIL_H #define STDGPU_VECTOR_DETAIL_H +#include + #include #include #include @@ -43,14 +45,14 @@ vector::createDeviceObject(ExecutionPolicy&& policy, const index_t vector result( mutex_array::createDeviceObject( - std::forward(policy), + std::decay_t{ policy }, capacity, mutex_array_allocator_type(allocator)), bitset::createDeviceObject( - std::forward(policy), + std::decay_t{ policy }, capacity, bitset_allocator_type(allocator)), - atomic::createDeviceObject(std::forward(policy), + atomic::createDeviceObject(std::decay_t{ policy }, atomic_allocator_type(allocator)), allocator); result._data = allocator_traits::allocate(result._allocator, capacity); @@ -73,7 +75,7 @@ vector::destroyDeviceObject(ExecutionPolicy&& policy, vector()) { - device_object.clear(std::forward(policy)); + device_object.clear(std::decay_t{ policy }); } allocator_traits::deallocate(device_object._allocator, @@ -81,9 +83,9 @@ vector::destroyDeviceObject(ExecutionPolicy&& policy, vector::destroyDeviceObject( - std::forward(policy), + std::decay_t{ policy }, device_object._locks); - bitset::destroyDeviceObject(std::forward(policy), + bitset::destroyDeviceObject(std::decay_t{ policy }, device_object._occupied); atomic::destroyDeviceObject(std::forward(policy), device_object._size); } @@ -344,8 +346,8 @@ template void vector_clear_iota(ExecutionPolicy&& policy, vector& v, const T& value) { - iota(std::forward(policy), device_begin(v.data()), device_end(v.data()), value); - v._occupied.set(std::forward(policy)); + iota(std::decay_t{ policy }, device_begin(v.data()), device_end(v.data()), value); + v._occupied.set(std::decay_t{ policy }); v._size.store(std::forward(policy), static_cast(v.capacity())); } @@ -370,14 +372,14 @@ vector::insert(ExecutionPolicy&& policy, ValueIterator begin, ValueIterator end) { - if (position != device_end(std::forward(policy))) + if (position != device_end(std::decay_t{ policy })) { printf("stdgpu::vector::insert : Position not equal to device_end()\n"); return; } index_t N = static_cast(end - begin); - index_t new_size = size(std::forward(policy)) + N; + index_t new_size = size(std::decay_t{ policy }) + N; if (new_size > capacity()) { @@ -388,7 +390,7 @@ vector::insert(ExecutionPolicy&& policy, return; } - for_each_index(std::forward(policy), + for_each_index(std::decay_t{ policy }, N, detail::vector_insert(*this, size(), begin)); @@ -408,14 +410,14 @@ template ::erase(ExecutionPolicy&& policy, device_ptr begin, device_ptr end) { - if (end != device_end(std::forward(policy))) + if (end != device_end(std::decay_t{ policy })) { printf("stdgpu::vector::erase : End iterator not equal to device_end()\n"); return; } index_t N = static_cast(end - begin); - index_t new_size = size(std::forward(policy)) - N; + index_t new_size = size(std::decay_t{ policy }) - N; if (new_size < 0) { @@ -424,7 +426,9 @@ vector::erase(ExecutionPolicy&& policy, device_ptr begin, return; } - for_each_index(std::forward(policy), N, detail::vector_erase(*this, new_size)); + for_each_index(std::decay_t{ policy }, + N, + detail::vector_erase(*this, new_size)); _size.store(std::forward(policy), static_cast(new_size)); } @@ -569,25 +573,25 @@ template ::clear(ExecutionPolicy&& policy) { - if (empty(std::forward(policy))) + if (empty(std::decay_t{ policy })) { return; } if (!detail::is_destroy_optimizable()) { - const index_t current_size = size(std::forward(policy)); + const index_t current_size = size(std::decay_t{ policy }); - detail::unoptimized_destroy(std::forward(policy), + detail::unoptimized_destroy(std::decay_t{ policy }, stdgpu::device_begin(_data), stdgpu::device_begin(_data) + current_size); } - _occupied.reset(std::forward(policy)); + _occupied.reset(std::decay_t{ policy }); - _size.store(std::forward(policy), static_cast(0)); + _size.store(std::decay_t{ policy }, static_cast(0)); - STDGPU_ENSURES(empty(std::forward(policy))); + STDGPU_ENSURES(empty(std::decay_t{ policy })); STDGPU_ENSURES(valid(std::forward(policy))); } @@ -610,9 +614,9 @@ vector::valid(ExecutionPolicy&& policy) const return true; } - return (size_valid(std::forward(policy)) && - occupied_count_valid(std::forward(policy)) && - _locks.valid(std::forward(policy))); + return (size_valid(std::decay_t{ policy }) && + occupied_count_valid(std::decay_t{ policy }) && + _locks.valid(std::decay_t{ policy })); } template @@ -758,7 +762,7 @@ template bool vector::occupied_count_valid(ExecutionPolicy&& policy) const { - index_t size_count = size(std::forward(policy)); + index_t size_count = size(std::decay_t{ policy }); index_t size_sum = _occupied.count(std::forward(policy)); return (size_count == size_sum);