Skip to content

Commit 17cf5a2

Browse files
committed
Rewrite the CFOA containers' FOA constructors so that a class with a template conversion operator does not instantiate the FOA container
1 parent 3359163 commit 17cf5a2

7 files changed

Lines changed: 60 additions & 10 deletions

File tree

include/boost/unordered/concurrent_flat_map.hpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
*
33
* Copyright 2023 Christian Mazakas.
44
* Copyright 2023-2026 Joaquin M Lopez Munoz.
5+
* Copyright 2026 Braden Ganetsky
56
* Distributed under the Boost Software License, Version 1.0.
67
* (See accompanying file LICENSE_1_0.txt or copy at
78
* http://www.boost.org/LICENSE_1_0.txt)
@@ -189,10 +190,10 @@ namespace boost {
189190
{
190191
}
191192

192-
193-
template <bool avoid_explicit_instantiation = true>
193+
template <typename Key2,
194+
typename std::enable_if<std::is_same<Key, Key2>::value, int>::type = 0>
194195
concurrent_flat_map(
195-
unordered_flat_map<Key, T, Hash, Pred, Allocator>&& other)
196+
unordered_flat_map<Key2, T, Hash, Pred, Allocator>&& other)
196197
: table_(std::move(other.table_))
197198
{
198199
}

include/boost/unordered/concurrent_flat_set.hpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
*
33
* Copyright 2023 Christian Mazakas.
44
* Copyright 2023-2026 Joaquin M Lopez Munoz.
5+
* Copyright 2026 Braden Ganetsky
56
* Distributed under the Boost Software License, Version 1.0.
67
* (See accompanying file LICENSE_1_0.txt or copy at
78
* http://www.boost.org/LICENSE_1_0.txt)
@@ -186,10 +187,10 @@ namespace boost {
186187
{
187188
}
188189

189-
190-
template <bool avoid_explicit_instantiation = true>
190+
template <typename Key2,
191+
typename std::enable_if<std::is_same<Key, Key2>::value, int>::type = 0>
191192
concurrent_flat_set(
192-
unordered_flat_set<Key, Hash, Pred, Allocator>&& other)
193+
unordered_flat_set<Key2, Hash, Pred, Allocator>&& other)
193194
: table_(std::move(other.table_))
194195
{
195196
}

include/boost/unordered/concurrent_node_map.hpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
*
33
* Copyright 2023 Christian Mazakas.
44
* Copyright 2023-2026 Joaquin M Lopez Munoz.
5+
* Copyright 2026 Braden Ganetsky
56
* Distributed under the Boost Software License, Version 1.0.
67
* (See accompanying file LICENSE_1_0.txt or copy at
78
* http://www.boost.org/LICENSE_1_0.txt)
@@ -197,9 +198,10 @@ namespace boost {
197198
{
198199
}
199200

200-
template <bool avoid_explicit_instantiation = true>
201+
template <typename Key2,
202+
typename std::enable_if<std::is_same<Key, Key2>::value, int>::type = 0>
201203
concurrent_node_map(
202-
unordered_node_map<Key, T, Hash, Pred, Allocator>&& other)
204+
unordered_node_map<Key2, T, Hash, Pred, Allocator>&& other)
203205
: table_(std::move(other.table_))
204206
{
205207
}

include/boost/unordered/concurrent_node_set.hpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
*
33
* Copyright 2023 Christian Mazakas.
44
* Copyright 2023-2026 Joaquin M Lopez Munoz.
5+
* Copyright 2026 Braden Ganetsky
56
* Distributed under the Boost Software License, Version 1.0.
67
* (See accompanying file LICENSE_1_0.txt or copy at
78
* http://www.boost.org/LICENSE_1_0.txt)
@@ -194,9 +195,10 @@ namespace boost {
194195
{
195196
}
196197

197-
template <bool avoid_explicit_instantiation = true>
198+
template <typename Key2,
199+
typename std::enable_if<std::is_same<Key, Key2>::value, int>::type = 0>
198200
concurrent_node_set(
199-
unordered_node_set<Key, Hash, Pred, Allocator>&& other)
201+
unordered_node_set<Key2, Hash, Pred, Allocator>&& other)
200202
: table_(std::move(other.table_))
201203
{
202204
}

test/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,5 +170,6 @@ foa_tests(TYPE compile NAME explicit_instantiation_tests SOURCES unordered/expli
170170
cfoa_tests(TYPE compile NAME explicit_instantiation_tests SOURCES cfoa/explicit_instantiation_tests.cpp)
171171

172172
foa_tests(TYPE compile NAME conversion_operator_tests SOURCES unordered/conversion_operator_tests.cpp)
173+
cfoa_tests(TYPE compile NAME conversion_operator_tests SOURCES cfoa/conversion_operator_tests.cpp)
173174

174175
endif()

test/Jamfile.v2

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,7 @@ compile unordered/explicit_instantiation_tests.cpp : <define>BOOST_UNORDERED_FOA
167167
compile cfoa/explicit_instantiation_tests.cpp : : cfoa_explicit_instantiation_tests ;
168168

169169
compile unordered/conversion_operator_tests.cpp : <define>BOOST_UNORDERED_FOA_TESTS : foa_conversion_operator_tests ;
170+
compile cfoa/conversion_operator_tests.cpp : : cfoa_conversion_operator_tests ;
170171

171172
local FCA_EXCEPTION_TESTS =
172173
constructor_exception_tests
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// Copyright 2026 Braden Ganetsky
2+
// Distributed under the Boost Software License, Version 1.0.
3+
// https://www.boost.org/LICENSE_1_0.txt
4+
5+
#include <boost/static_assert.hpp>
6+
#include <boost/unordered/concurrent_flat_map.hpp>
7+
#include <boost/unordered/concurrent_flat_set.hpp>
8+
#include <boost/unordered/concurrent_node_map.hpp>
9+
#include <boost/unordered/concurrent_node_set.hpp>
10+
// Don't include the FOA headers here!
11+
12+
using c_flat_map = boost::unordered::concurrent_flat_map<int, int>;
13+
using c_flat_set = boost::unordered::concurrent_flat_set<int>;
14+
using c_node_map = boost::unordered::concurrent_node_map<int, int>;
15+
using c_node_set = boost::unordered::concurrent_node_set<int>;
16+
17+
struct constrained_template_converter
18+
{
19+
struct dummy
20+
{
21+
};
22+
template <class T, typename std::enable_if<
23+
std::is_constructible<T, dummy>::value, int>::type = 0>
24+
operator T() const
25+
{
26+
return T{};
27+
}
28+
};
29+
30+
// Check whether the corresponding FOA container gets instantiated.
31+
// The FOA headers aren't included, so this would fail to compile if the FOA
32+
// container was instantiated.
33+
BOOST_STATIC_ASSERT(
34+
(!std::is_constructible<c_flat_map, constrained_template_converter>::value));
35+
BOOST_STATIC_ASSERT(
36+
(!std::is_constructible<c_flat_set, constrained_template_converter>::value));
37+
BOOST_STATIC_ASSERT(
38+
(!std::is_constructible<c_node_map, constrained_template_converter>::value));
39+
BOOST_STATIC_ASSERT(
40+
(!std::is_constructible<c_node_set, constrained_template_converter>::value));
41+
42+
int main() { return 0; }

0 commit comments

Comments
 (0)