mirror of
https://github.com/boostorg/unordered.git
synced 2025-11-03 17:21:48 +01:00
Fixed std::initializer_list assignment issues for open-addressing containers (#277)
* fixed #276 * used range insert, stylistic this-> * assigned non-empty std::initializer_lists
This commit is contained in:
@@ -5,11 +5,16 @@
|
||||
|
||||
#include "helpers.hpp"
|
||||
|
||||
#include "../helpers/replace_allocator.hpp"
|
||||
#include "../objects/non_default_ctble_allocator.hpp"
|
||||
|
||||
#include <boost/unordered/concurrent_flat_map.hpp>
|
||||
#include <boost/unordered/concurrent_flat_set.hpp>
|
||||
#include <boost/unordered/concurrent_node_map.hpp>
|
||||
#include <boost/unordered/concurrent_node_set.hpp>
|
||||
|
||||
#include <vector>
|
||||
|
||||
#if defined(__clang__) && defined(__has_warning)
|
||||
|
||||
#if __has_warning("-Wself-assign-overloaded")
|
||||
@@ -882,6 +887,28 @@ namespace {
|
||||
check_raii_counts();
|
||||
}
|
||||
|
||||
template <class X, class GF>
|
||||
void initializer_list_assign_gh276(
|
||||
X*, GF gen_factory, test::random_generator rg)
|
||||
{
|
||||
// https://github.com/boostorg/unordered/issues/276
|
||||
|
||||
using replaced_allocator_container = test::replace_allocator<
|
||||
X, test::non_default_ctble_allocator<int> >;
|
||||
using replaced_allocator_type =
|
||||
typename replaced_allocator_container::allocator_type;
|
||||
|
||||
auto gen = gen_factory.template get<X>();
|
||||
auto values = make_random_values(4, [&] { return gen(rg); });
|
||||
|
||||
replaced_allocator_container
|
||||
x(replaced_allocator_type(0)),
|
||||
y(values.begin(), values.end(), replaced_allocator_type(0));
|
||||
|
||||
x = {values[0], values[1], values[2], values[3]};
|
||||
BOOST_TEST(x == y);
|
||||
}
|
||||
|
||||
template <class X, class GF>
|
||||
void insert_and_assign(X*, GF gen_factory, test::random_generator rg)
|
||||
{
|
||||
@@ -1112,6 +1139,12 @@ UNORDERED_TEST(
|
||||
((test_map_and_init_list)(test_node_map_and_init_list)
|
||||
(test_set_and_init_list)(test_node_set_and_init_list)))
|
||||
|
||||
UNORDERED_TEST(
|
||||
initializer_list_assign_gh276,
|
||||
((test_map)(test_node_map)(test_set)(test_node_set))
|
||||
((value_type_generator_factory))
|
||||
((default_generator)))
|
||||
|
||||
UNORDERED_TEST(
|
||||
insert_and_assign,
|
||||
((test_map)(test_node_map)(test_set)(test_node_set))
|
||||
|
||||
44
test/helpers/replace_allocator.hpp
Normal file
44
test/helpers/replace_allocator.hpp
Normal file
@@ -0,0 +1,44 @@
|
||||
|
||||
// Copyright 2024 Joaquin M Lopez Munz.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or move at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_UNORDERED_TEST_REPLACE_ALLOCATOR
|
||||
#define BOOST_UNORDERED_TEST_REPLACE_ALLOCATOR
|
||||
|
||||
#include <boost/core/allocator_access.hpp>
|
||||
#include <utility>
|
||||
|
||||
namespace test {
|
||||
template <typename Container, typename Allocator>
|
||||
struct replace_allocator_impl;
|
||||
|
||||
template <typename Container, typename Allocator>
|
||||
using replace_allocator =
|
||||
typename replace_allocator_impl<Container, Allocator>::type;
|
||||
|
||||
template <
|
||||
typename K, typename H, typename P, typename A,
|
||||
template <typename, typename, typename, typename> class Set,
|
||||
typename Allocator
|
||||
>
|
||||
struct replace_allocator_impl<Set<K, H, P, A>, Allocator>
|
||||
{
|
||||
using type = Set<
|
||||
K, H, P, boost::allocator_rebind_t<Allocator, K> >;
|
||||
};
|
||||
|
||||
template <
|
||||
typename K, typename H, typename T, typename P, typename A,
|
||||
template <typename, typename, typename, typename, typename> class Map,
|
||||
typename Allocator
|
||||
>
|
||||
struct replace_allocator_impl<Map<K, T, H, P, A>, Allocator>
|
||||
{
|
||||
using type = Map<
|
||||
K, T, H, P,
|
||||
boost::allocator_rebind_t<Allocator, std::pair<K const, T> > >;
|
||||
};
|
||||
} // namespace test
|
||||
|
||||
#endif // !defined(BOOST_UNORDERED_TEST_REPLACE_ALLOCATOR)
|
||||
46
test/objects/non_default_ctble_allocator.hpp
Normal file
46
test/objects/non_default_ctble_allocator.hpp
Normal file
@@ -0,0 +1,46 @@
|
||||
|
||||
// Copyright 2024 Joaquin M Lopez Munoz
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#if !defined(BOOST_UNORDERED_TEST_NON_DEFAULT_CTBLE_ALLOCATOR_HEADER)
|
||||
#define BOOST_UNORDERED_TEST_NON_DEFAULT_CTBLE_ALLOCATOR_HEADER
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace test
|
||||
{
|
||||
template <class T> struct non_default_ctble_allocator
|
||||
{
|
||||
typedef T value_type;
|
||||
|
||||
non_default_ctble_allocator(int) {}
|
||||
|
||||
template <class U>
|
||||
non_default_ctble_allocator(const non_default_ctble_allocator<U>&) {}
|
||||
|
||||
template<class U>
|
||||
bool operator==(non_default_ctble_allocator<U> const &) const noexcept
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
template<class U>
|
||||
bool operator!=(non_default_ctble_allocator<U> const &) const noexcept
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
T* allocate(std::size_t n)
|
||||
{
|
||||
return std::allocator<T>().allocate(n);
|
||||
}
|
||||
|
||||
void deallocate(T* p, std::size_t n)
|
||||
{
|
||||
std::allocator<T>().deallocate(p, n);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -7,12 +7,16 @@
|
||||
#include "../helpers/unordered.hpp"
|
||||
|
||||
#include "../helpers/test.hpp"
|
||||
#include "../helpers/replace_allocator.hpp"
|
||||
#include "../objects/test.hpp"
|
||||
#include "../objects/cxx11_allocator.hpp"
|
||||
#include "../objects/non_default_ctble_allocator.hpp"
|
||||
#include "../helpers/random_values.hpp"
|
||||
#include "../helpers/tracker.hpp"
|
||||
#include "../helpers/equivalent.hpp"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
#pragma warning(disable : 4127) // conditional expression is constant
|
||||
#endif
|
||||
@@ -288,6 +292,27 @@ namespace assign_tests {
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "gh276\n";
|
||||
{
|
||||
// https://github.com/boostorg/unordered/issues/276
|
||||
|
||||
using value_type = typename T::value_type;
|
||||
using replaced_allocator_container = test::replace_allocator<
|
||||
T, test::non_default_ctble_allocator<int> >;
|
||||
using replaced_allocator_type =
|
||||
typename replaced_allocator_container::allocator_type;
|
||||
|
||||
test::random_values<T> v(4, generator);
|
||||
std::vector<value_type> vv(v.begin(), v.end());
|
||||
|
||||
replaced_allocator_container
|
||||
x(replaced_allocator_type(0)),
|
||||
y(vv.begin(), vv.begin() + 4, replaced_allocator_type(0));
|
||||
|
||||
x = {vv[0], vv[1], vv[2], vv[3]};
|
||||
BOOST_TEST(x == y);
|
||||
}
|
||||
}
|
||||
|
||||
using test::default_generator;
|
||||
|
||||
@@ -20,7 +20,8 @@
|
||||
#endif
|
||||
|
||||
#include "../helpers/test.hpp"
|
||||
|
||||
#include "../helpers/replace_allocator.hpp"
|
||||
|
||||
#include <boost/config/workaround.hpp>
|
||||
#include <boost/core/allocator_access.hpp>
|
||||
#include <memory>
|
||||
@@ -82,42 +83,12 @@ namespace {
|
||||
bool operator!=(pocx_allocator const& rhs) const { return x_ != rhs.x_; }
|
||||
};
|
||||
|
||||
template <typename Container, typename Allocator>
|
||||
struct replace_allocator_impl;
|
||||
|
||||
template <typename Container, typename Allocator>
|
||||
using replace_allocator =
|
||||
typename replace_allocator_impl<Container, Allocator>::type;
|
||||
|
||||
template <
|
||||
typename K, typename H, typename P, typename A,
|
||||
template <typename, typename, typename, typename> class Set,
|
||||
typename Allocator
|
||||
>
|
||||
struct replace_allocator_impl<Set<K, H, P, A>, Allocator>
|
||||
{
|
||||
using type = Set<
|
||||
K, H, P, boost::allocator_rebind_t<Allocator, K> >;
|
||||
};
|
||||
|
||||
template <
|
||||
typename K, typename H, typename T, typename P, typename A,
|
||||
template <typename, typename, typename, typename, typename> class Map,
|
||||
typename Allocator
|
||||
>
|
||||
struct replace_allocator_impl<Map<K, T, H, P, A>, Allocator>
|
||||
{
|
||||
using type = Map<
|
||||
K, T, H, P,
|
||||
boost::allocator_rebind_t<Allocator, std::pair<K const, T> > >;
|
||||
};
|
||||
|
||||
template<typename X, typename Allocator>
|
||||
void node_handle_allocator_tests(
|
||||
X*, std::pair<Allocator, Allocator> allocators)
|
||||
{
|
||||
using value_type = typename X::value_type;
|
||||
using replaced_allocator_container = replace_allocator<X, Allocator>;
|
||||
using replaced_allocator_container = test::replace_allocator<X, Allocator>;
|
||||
using node_type = typename replaced_allocator_container::node_type;
|
||||
|
||||
replaced_allocator_container x1(allocators.first);
|
||||
@@ -143,7 +114,7 @@ namespace {
|
||||
X*, std::pair<Allocator, Allocator> allocators)
|
||||
{
|
||||
using value_type = typename X::value_type;
|
||||
using replaced_allocator_container = replace_allocator<X, Allocator>;
|
||||
using replaced_allocator_container = test::replace_allocator<X, Allocator>;
|
||||
using node_type = typename replaced_allocator_container::node_type;
|
||||
|
||||
replaced_allocator_container x1(allocators.first), x2(allocators.second);
|
||||
|
||||
Reference in New Issue
Block a user