Sync from upstream.

This commit is contained in:
Rene Rivera 2024-09-03 20:09:40 -05:00
commit 9a2483dd2c
10 changed files with 185 additions and 33 deletions

View File

@ -14,6 +14,9 @@
({github-pr-url}/265[PR#265^]).
* In Visual Studio Natvis, supported any container with an allocator that uses fancy pointers. This applies to any fancy pointer type, as long as the proper Natvis customization point "Intrinsic" functions are written for the fancy pointer type.
* Added GDB pretty-printers for all containers and iterators. For a container with an allocator that uses fancy pointers, these only work if the proper pretty-printer is written for the fancy pointer type itself.
* Fixed `std::initializer_list` assignment issues for open-addressing containers
({github-pr-url}/277[PR#277^]).
== Release 1.86.0

View File

@ -1,4 +1,5 @@
// Copyright (C) 2022-2023 Christian Mazakas
// Copyright (C) 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)
@ -202,6 +203,13 @@ namespace boost {
return *this;
}
unordered_flat_map& operator=(std::initializer_list<value_type> il)
{
this->clear();
this->insert(il.begin(), il.end());
return *this;
}
allocator_type get_allocator() const noexcept
{
return table_.get_allocator();

View File

@ -1,4 +1,5 @@
// Copyright (C) 2022-2023 Christian Mazakas
// Copyright (C) 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)
@ -198,6 +199,13 @@ namespace boost {
return *this;
}
unordered_flat_set& operator=(std::initializer_list<value_type> il)
{
this->clear();
this->insert(il.begin(), il.end());
return *this;
}
allocator_type get_allocator() const noexcept
{
return table_.get_allocator();

View File

@ -210,6 +210,13 @@ namespace boost {
return *this;
}
unordered_node_map& operator=(std::initializer_list<value_type> il)
{
this->clear();
this->insert(il.begin(), il.end());
return *this;
}
allocator_type get_allocator() const noexcept
{
return table_.get_allocator();

View File

@ -208,6 +208,13 @@ namespace boost {
return *this;
}
unordered_node_set& operator=(std::initializer_list<value_type> il)
{
this->clear();
this->insert(il.begin(), il.end());
return *this;
}
allocator_type get_allocator() const noexcept
{
return table_.get_allocator();

View File

@ -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))

View 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)

View 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

View File

@ -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;

View File

@ -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);