mirror of
https://github.com/boostorg/unordered.git
synced 2026-08-03 20:24:07 +02:00
Fix issue with constructing an FOA container from a class with a template conversion operator (#334)
* Add missing compile-only tests in CMake * Rewrite the FOA containers' CFOA constructors so that a class with a template conversion operator does not instantiate the CFOA container * Rewrite the CFOA containers' FOA constructors so that a class with a template conversion operator does not instantiate the FOA container
This commit is contained in:
@@ -2,6 +2,7 @@
|
|||||||
*
|
*
|
||||||
* Copyright 2023 Christian Mazakas.
|
* Copyright 2023 Christian Mazakas.
|
||||||
* Copyright 2023-2026 Joaquin M Lopez Munoz.
|
* Copyright 2023-2026 Joaquin M Lopez Munoz.
|
||||||
|
* Copyright 2026 Braden Ganetsky
|
||||||
* Distributed under the Boost Software License, Version 1.0.
|
* Distributed under the Boost Software License, Version 1.0.
|
||||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||||
* http://www.boost.org/LICENSE_1_0.txt)
|
* http://www.boost.org/LICENSE_1_0.txt)
|
||||||
@@ -189,10 +190,10 @@ namespace boost {
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename Key2,
|
||||||
template <bool avoid_explicit_instantiation = true>
|
typename std::enable_if<std::is_same<Key, Key2>::value, int>::type = 0>
|
||||||
concurrent_flat_map(
|
concurrent_flat_map(
|
||||||
unordered_flat_map<Key, T, Hash, Pred, Allocator>&& other)
|
unordered_flat_map<Key2, T, Hash, Pred, Allocator>&& other)
|
||||||
: table_(std::move(other.table_))
|
: table_(std::move(other.table_))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
*
|
*
|
||||||
* Copyright 2023 Christian Mazakas.
|
* Copyright 2023 Christian Mazakas.
|
||||||
* Copyright 2023-2026 Joaquin M Lopez Munoz.
|
* Copyright 2023-2026 Joaquin M Lopez Munoz.
|
||||||
|
* Copyright 2026 Braden Ganetsky
|
||||||
* Distributed under the Boost Software License, Version 1.0.
|
* Distributed under the Boost Software License, Version 1.0.
|
||||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||||
* http://www.boost.org/LICENSE_1_0.txt)
|
* http://www.boost.org/LICENSE_1_0.txt)
|
||||||
@@ -186,10 +187,10 @@ namespace boost {
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename Key2,
|
||||||
template <bool avoid_explicit_instantiation = true>
|
typename std::enable_if<std::is_same<Key, Key2>::value, int>::type = 0>
|
||||||
concurrent_flat_set(
|
concurrent_flat_set(
|
||||||
unordered_flat_set<Key, Hash, Pred, Allocator>&& other)
|
unordered_flat_set<Key2, Hash, Pred, Allocator>&& other)
|
||||||
: table_(std::move(other.table_))
|
: table_(std::move(other.table_))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
*
|
*
|
||||||
* Copyright 2023 Christian Mazakas.
|
* Copyright 2023 Christian Mazakas.
|
||||||
* Copyright 2023-2026 Joaquin M Lopez Munoz.
|
* Copyright 2023-2026 Joaquin M Lopez Munoz.
|
||||||
|
* Copyright 2026 Braden Ganetsky
|
||||||
* Distributed under the Boost Software License, Version 1.0.
|
* Distributed under the Boost Software License, Version 1.0.
|
||||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||||
* http://www.boost.org/LICENSE_1_0.txt)
|
* http://www.boost.org/LICENSE_1_0.txt)
|
||||||
@@ -197,9 +198,10 @@ namespace boost {
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
template <bool avoid_explicit_instantiation = true>
|
template <typename Key2,
|
||||||
|
typename std::enable_if<std::is_same<Key, Key2>::value, int>::type = 0>
|
||||||
concurrent_node_map(
|
concurrent_node_map(
|
||||||
unordered_node_map<Key, T, Hash, Pred, Allocator>&& other)
|
unordered_node_map<Key2, T, Hash, Pred, Allocator>&& other)
|
||||||
: table_(std::move(other.table_))
|
: table_(std::move(other.table_))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
*
|
*
|
||||||
* Copyright 2023 Christian Mazakas.
|
* Copyright 2023 Christian Mazakas.
|
||||||
* Copyright 2023-2026 Joaquin M Lopez Munoz.
|
* Copyright 2023-2026 Joaquin M Lopez Munoz.
|
||||||
|
* Copyright 2026 Braden Ganetsky
|
||||||
* Distributed under the Boost Software License, Version 1.0.
|
* Distributed under the Boost Software License, Version 1.0.
|
||||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||||
* http://www.boost.org/LICENSE_1_0.txt)
|
* http://www.boost.org/LICENSE_1_0.txt)
|
||||||
@@ -194,9 +195,10 @@ namespace boost {
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
template <bool avoid_explicit_instantiation = true>
|
template <typename Key2,
|
||||||
|
typename std::enable_if<std::is_same<Key, Key2>::value, int>::type = 0>
|
||||||
concurrent_node_set(
|
concurrent_node_set(
|
||||||
unordered_node_set<Key, Hash, Pred, Allocator>&& other)
|
unordered_node_set<Key2, Hash, Pred, Allocator>&& other)
|
||||||
: table_(std::move(other.table_))
|
: table_(std::move(other.table_))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
// Copyright (C) 2022-2023 Christian Mazakas
|
// Copyright (C) 2022-2023 Christian Mazakas
|
||||||
// Copyright (C) 2024-2025 Joaquin M Lopez Munoz
|
// Copyright (C) 2024-2025 Joaquin M Lopez Munoz
|
||||||
|
// Copyright (C) 2026 Braden Ganetsky
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
@@ -182,9 +183,10 @@ namespace boost {
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
template <bool avoid_explicit_instantiation = true>
|
template <typename Key2,
|
||||||
|
typename std::enable_if<std::is_same<Key, Key2>::value, int>::type = 0>
|
||||||
unordered_flat_map(
|
unordered_flat_map(
|
||||||
concurrent_flat_map<Key, T, Hash, KeyEqual, Allocator>&& other)
|
concurrent_flat_map<Key2, T, Hash, KeyEqual, Allocator>&& other)
|
||||||
: table_(std::move(other.table_))
|
: table_(std::move(other.table_))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
// Copyright (C) 2022-2023 Christian Mazakas
|
// Copyright (C) 2022-2023 Christian Mazakas
|
||||||
// Copyright (C) 2024-2025 Joaquin M Lopez Munoz
|
// Copyright (C) 2024-2025 Joaquin M Lopez Munoz
|
||||||
|
// Copyright (C) 2026 Braden Ganetsky
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
@@ -178,9 +179,10 @@ namespace boost {
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
template <bool avoid_explicit_instantiation = true>
|
template <typename Key2,
|
||||||
|
typename std::enable_if<std::is_same<Key, Key2>::value, int>::type = 0>
|
||||||
unordered_flat_set(
|
unordered_flat_set(
|
||||||
concurrent_flat_set<Key, Hash, KeyEqual, Allocator>&& other)
|
concurrent_flat_set<Key2, Hash, KeyEqual, Allocator>&& other)
|
||||||
: table_(std::move(other.table_))
|
: table_(std::move(other.table_))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
// Copyright (C) 2022-2023 Christian Mazakas
|
// Copyright (C) 2022-2023 Christian Mazakas
|
||||||
// Copyright (C) 2024-2025 Joaquin M Lopez Munoz
|
// Copyright (C) 2024-2025 Joaquin M Lopez Munoz
|
||||||
|
// Copyright (C) 2026 Braden Ganetsky
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
@@ -189,9 +190,10 @@ namespace boost {
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
template <bool avoid_explicit_instantiation = true>
|
template <typename Key2,
|
||||||
|
typename std::enable_if<std::is_same<Key, Key2>::value, int>::type = 0>
|
||||||
unordered_node_map(
|
unordered_node_map(
|
||||||
concurrent_node_map<Key, T, Hash, KeyEqual, Allocator>&& other)
|
concurrent_node_map<Key2, T, Hash, KeyEqual, Allocator>&& other)
|
||||||
: table_(std::move(other.table_))
|
: table_(std::move(other.table_))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
// Copyright (C) 2022-2023 Christian Mazakas
|
// Copyright (C) 2022-2023 Christian Mazakas
|
||||||
// Copyright (C) 2024-2025 Joaquin M Lopez Munoz
|
// Copyright (C) 2024-2025 Joaquin M Lopez Munoz
|
||||||
|
// Copyright (C) 2026 Braden Ganetsky
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
@@ -187,9 +188,10 @@ namespace boost {
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
template <bool avoid_explicit_instantiation = true>
|
template <typename Key2,
|
||||||
|
typename std::enable_if<std::is_same<Key, Key2>::value, int>::type = 0>
|
||||||
unordered_node_set(
|
unordered_node_set(
|
||||||
concurrent_node_set<Key, Hash, KeyEqual, Allocator>&& other)
|
concurrent_node_set<Key2, Hash, KeyEqual, Allocator>&& other)
|
||||||
: table_(std::move(other.table_))
|
: table_(std::move(other.table_))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -163,4 +163,13 @@ cfoa_tests(SOURCES cfoa/rw_spinlock_test6.cpp)
|
|||||||
cfoa_tests(SOURCES cfoa/rw_spinlock_test7.cpp)
|
cfoa_tests(SOURCES cfoa/rw_spinlock_test7.cpp)
|
||||||
cfoa_tests(SOURCES cfoa/rw_spinlock_test8.cpp)
|
cfoa_tests(SOURCES cfoa/rw_spinlock_test8.cpp)
|
||||||
|
|
||||||
|
# Compile tests
|
||||||
|
|
||||||
|
fca_tests(TYPE compile NAME explicit_instantiation_tests SOURCES unordered/explicit_instantiation_tests.cpp)
|
||||||
|
foa_tests(TYPE compile NAME explicit_instantiation_tests SOURCES unordered/explicit_instantiation_tests.cpp)
|
||||||
|
cfoa_tests(TYPE compile NAME explicit_instantiation_tests SOURCES cfoa/explicit_instantiation_tests.cpp)
|
||||||
|
|
||||||
|
foa_tests(TYPE compile NAME conversion_operator_tests SOURCES unordered/conversion_operator_tests.cpp)
|
||||||
|
cfoa_tests(TYPE compile NAME conversion_operator_tests SOURCES cfoa/conversion_operator_tests.cpp)
|
||||||
|
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
@@ -166,6 +166,9 @@ compile unordered/explicit_instantiation_tests.cpp :
|
|||||||
compile unordered/explicit_instantiation_tests.cpp : <define>BOOST_UNORDERED_FOA_TESTS : foa_explicit_instantiation_tests ;
|
compile unordered/explicit_instantiation_tests.cpp : <define>BOOST_UNORDERED_FOA_TESTS : foa_explicit_instantiation_tests ;
|
||||||
compile cfoa/explicit_instantiation_tests.cpp : : cfoa_explicit_instantiation_tests ;
|
compile cfoa/explicit_instantiation_tests.cpp : : cfoa_explicit_instantiation_tests ;
|
||||||
|
|
||||||
|
compile unordered/conversion_operator_tests.cpp : <define>BOOST_UNORDERED_FOA_TESTS : foa_conversion_operator_tests ;
|
||||||
|
compile cfoa/conversion_operator_tests.cpp : : cfoa_conversion_operator_tests ;
|
||||||
|
|
||||||
local FCA_EXCEPTION_TESTS =
|
local FCA_EXCEPTION_TESTS =
|
||||||
constructor_exception_tests
|
constructor_exception_tests
|
||||||
copy_exception_tests
|
copy_exception_tests
|
||||||
|
|||||||
@@ -0,0 +1,42 @@
|
|||||||
|
// Copyright 2026 Braden Ganetsky
|
||||||
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
|
// https://www.boost.org/LICENSE_1_0.txt
|
||||||
|
|
||||||
|
#include <boost/static_assert.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>
|
||||||
|
// Don't include the FOA headers here!
|
||||||
|
|
||||||
|
using c_flat_map = boost::unordered::concurrent_flat_map<int, int>;
|
||||||
|
using c_flat_set = boost::unordered::concurrent_flat_set<int>;
|
||||||
|
using c_node_map = boost::unordered::concurrent_node_map<int, int>;
|
||||||
|
using c_node_set = boost::unordered::concurrent_node_set<int>;
|
||||||
|
|
||||||
|
struct constrained_template_converter
|
||||||
|
{
|
||||||
|
struct dummy
|
||||||
|
{
|
||||||
|
};
|
||||||
|
template <class T, typename std::enable_if<
|
||||||
|
std::is_constructible<T, dummy>::value, int>::type = 0>
|
||||||
|
operator T() const
|
||||||
|
{
|
||||||
|
return T{};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Check whether the corresponding FOA container gets instantiated.
|
||||||
|
// The FOA headers aren't included, so this would fail to compile if the FOA
|
||||||
|
// container was instantiated.
|
||||||
|
BOOST_STATIC_ASSERT(
|
||||||
|
(!std::is_constructible<c_flat_map, constrained_template_converter>::value));
|
||||||
|
BOOST_STATIC_ASSERT(
|
||||||
|
(!std::is_constructible<c_flat_set, constrained_template_converter>::value));
|
||||||
|
BOOST_STATIC_ASSERT(
|
||||||
|
(!std::is_constructible<c_node_map, constrained_template_converter>::value));
|
||||||
|
BOOST_STATIC_ASSERT(
|
||||||
|
(!std::is_constructible<c_node_set, constrained_template_converter>::value));
|
||||||
|
|
||||||
|
int main() { return 0; }
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
// Copyright 2026 Braden Ganetsky
|
||||||
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
|
// https://www.boost.org/LICENSE_1_0.txt
|
||||||
|
|
||||||
|
#if !defined(BOOST_UNORDERED_FOA_TESTS)
|
||||||
|
#error "This test is only for the FOA-style conatiners"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <boost/static_assert.hpp>
|
||||||
|
#include <boost/unordered/unordered_flat_map.hpp>
|
||||||
|
#include <boost/unordered/unordered_flat_set.hpp>
|
||||||
|
#include <boost/unordered/unordered_node_map.hpp>
|
||||||
|
#include <boost/unordered/unordered_node_set.hpp>
|
||||||
|
// Don't include the CFOA headers here!
|
||||||
|
|
||||||
|
using flat_map = boost::unordered::unordered_flat_map<int, int>;
|
||||||
|
using flat_set = boost::unordered::unordered_flat_set<int>;
|
||||||
|
using node_map = boost::unordered::unordered_node_map<int, int>;
|
||||||
|
using node_set = boost::unordered::unordered_node_set<int>;
|
||||||
|
|
||||||
|
struct constrained_template_converter
|
||||||
|
{
|
||||||
|
struct dummy
|
||||||
|
{
|
||||||
|
};
|
||||||
|
template <class T, typename std::enable_if<
|
||||||
|
std::is_constructible<T, dummy>::value, int>::type = 0>
|
||||||
|
operator T() const
|
||||||
|
{
|
||||||
|
return T{};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Check whether the corresponding CFOA container gets instantiated.
|
||||||
|
// The CFOA headers aren't included, so this would fail to compile if the CFOA
|
||||||
|
// container was instantiated.
|
||||||
|
BOOST_STATIC_ASSERT(
|
||||||
|
(!std::is_constructible<flat_map, constrained_template_converter>::value));
|
||||||
|
BOOST_STATIC_ASSERT(
|
||||||
|
(!std::is_constructible<flat_set, constrained_template_converter>::value));
|
||||||
|
BOOST_STATIC_ASSERT(
|
||||||
|
(!std::is_constructible<node_map, constrained_template_converter>::value));
|
||||||
|
BOOST_STATIC_ASSERT(
|
||||||
|
(!std::is_constructible<node_set, constrained_template_converter>::value));
|
||||||
|
|
||||||
|
int main() { return 0; }
|
||||||
Reference in New Issue
Block a user