Skip to content

Commit 32401e3

Browse files
authored
Replace boost::container with cpp17::pmr (#4731)
This removes the boost dependency to avoid having to make that work in our builds that are still using external packages. This change uses std::pmr when it is detected as available and usable. On platforms that don't have a working std::pmr (notably, macOS < 14), it uses the implementation from Pablo Halpern that is implemented with purely C++11 features. The major downfall to this approach is that if/when we start changing allocator strategies it'll require us to backport/reimplement those allocator strategies for macOS < 14. However, if we end up writing our own allocation strategies they'll work on either implementation seamlessly. --- TYPE: NO_HISTORY DESC: Remove boost::container
1 parent fbf244a commit 32401e3

File tree

12 files changed

+651
-14
lines changed

12 files changed

+651
-14
lines changed

CMakeLists.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,15 @@ if(TILEDB_SANITIZER)
258258
validate_sanitizer_options()
259259
endif()
260260

261+
include(DetectStdPmr)
262+
263+
if(TILEDB_USE_CPP17_PMR)
264+
message(STATUS "Building with cpp17::pmr")
265+
add_definitions(-DUSE_CPP17_PMR)
266+
else()
267+
message(STATUS "Building with std::pmr")
268+
endif()
269+
261270
#######################################################
262271
# Header Files
263272
#######################################################

cmake/Modules/DetectStdPmr.cmake

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
#
2+
# DetectStdPmr.cmake
3+
#
4+
#
5+
# The MIT License
6+
#
7+
# Copyright (c) 2024 TileDB, Inc.
8+
#
9+
# Permission is hereby granted, free of charge, to any person obtaining a copy
10+
# of this software and associated documentation files (the "Software"), to deal
11+
# in the Software without restriction, including without limitation the rights
12+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13+
# copies of the Software, and to permit persons to whom the Software is
14+
# furnished to do so, subject to the following conditions:
15+
#
16+
# The above copyright notice and this permission notice shall be included in
17+
# all copies or substantial portions of the Software.
18+
#
19+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25+
# THE SOFTWARE.
26+
#
27+
# Detect whether polymorphic allocators are available on the system.
28+
29+
# Special case for macOS when the MACOSX_DEPLOYMENT_TARGET is set to anything
30+
# less than 14. For some reason, std::pmr is still detectable, but the resulting
31+
# binary dies with a dyld missing symbol error.
32+
33+
if (ENV{MACOSX_DEPLOYMENT_TARGET})
34+
string(COMPARE LESS "$ENV{MACOSX_DEPLOYMENT_TARGET}" "14" MACOS_BAD_PMR_SUPPORT)
35+
if (MACOS_BAD_PMR_SUPPORT)
36+
set(TILEDB_USE_CPP17_PMR ON)
37+
message(STATUS "Using vendored cpp17::pmr for polymorphic allocators")
38+
return()
39+
endif()
40+
endif()
41+
42+
# Otherwise, if we're not building a targeted macOS version, we just detect
43+
# whether std::pmr is available.
44+
#
45+
# However CMake makes this extra awesome because try_run appears to have
46+
# changed in a backwards compatible manner. We'll just version check for
47+
# selecting which to run.
48+
49+
if (CMAKE_VERSION VERSION_LESS "3.25")
50+
try_run(
51+
TILEDB_CAN_RUN_STD_PMR
52+
TILEDB_CAN_COMPILE_STD_PMR
53+
"${CMAKE_CURRENT_BINARY_DIR}"
54+
"${CMAKE_SOURCE_DIR}/cmake/inputs/detect_std_pmr.cc"
55+
)
56+
else()
57+
try_run(
58+
TILEDB_CAN_RUN_STD_PMR
59+
TILEDB_CAN_COMPILE_STD_PMR
60+
SOURCES "${CMAKE_SOURCE_DIR}/cmake/inputs/detect_std_pmr.cc"
61+
)
62+
endif()
63+
64+
if ("${TILEDB_CAN_COMPILE_STD_PMR}" AND "${TILEDB_CAN_RUN_STD_PMR}" EQUAL 0)
65+
message(STATUS "Using std::pmr for polymorphic allocators")
66+
else()
67+
set(TILEDB_USE_CPP17_PMR ON)
68+
message(STATUS "Using vendored cpp17::pmr for polymorphic allocators")
69+
endif()

cmake/TileDB-Superbuild.cmake

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,4 +197,4 @@ add_custom_target(package
197197
DEPENDS tiledb
198198
COMMAND ${CMAKE_CPACK_COMMAND} --config CPackConfig.cmake -G "$<IF:$<PLATFORM_ID:Windows>,ZIP,TGZ>"
199199
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/tiledb
200-
)
200+
)

cmake/inputs/detect_std_pmr.cc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
2+
#include <memory_resource>
3+
4+
int
5+
main() {
6+
auto resource = std::pmr::get_default_resource();
7+
}

tiledb/common/CMakeLists.txt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,11 @@ commence(object_library baseline)
6565
memory_tracker.cc
6666
pmr.cc
6767
)
68+
if (TILEDB_USE_CPP17_PMR)
69+
this_target_sources(polymorphic_allocator/polymorphic_allocator.cc)
70+
endif()
6871
find_package(Spdlog_EP REQUIRED)
69-
find_package(Boost REQUIRED COMPONENTS container)
7072
target_link_libraries(baseline PUBLIC spdlog::spdlog)
71-
target_link_libraries(baseline PUBLIC Boost::container)
7273
target_link_libraries(baseline PUBLIC common)
7374
conclude(object_library)
7475

tiledb/common/pmr.cc

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,11 @@
3535
namespace tiledb::common::pmr {
3636

3737
memory_resource* get_default_resource() {
38-
return boost::container::pmr::get_default_resource();
38+
#ifdef USE_CPP17_PMR
39+
return cpp17::pmr::get_default_resource();
40+
#else
41+
return std::pmr::get_default_resource();
42+
#endif
3943
}
4044

4145
} // namespace tiledb::common::pmr

tiledb/common/pmr.h

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -37,25 +37,39 @@
3737
#include <unordered_map>
3838
#include <vector>
3939

40-
#include <boost/container/pmr/memory_resource.hpp>
41-
#include <boost/container/pmr/polymorphic_allocator.hpp>
42-
#include <boost/container/pmr/vector.hpp>
40+
#ifdef USE_CPP17_PMR
41+
#include "polymorphic_allocator/polymorphic_allocator.h"
42+
#else
43+
#include <memory_resource>
44+
#endif
4345

4446
#include "common.h"
4547

4648
namespace tiledb::common::pmr {
4749

48-
using memory_resource = boost::container::pmr::memory_resource;
50+
#ifdef USE_CPP17_PMR
51+
52+
using memory_resource = cpp17::pmr::memory_resource;
53+
54+
template <class Tp>
55+
using polymorphic_allocator = cpp17::pmr::polymorphic_allocator<Tp>;
56+
57+
#else
58+
59+
using memory_resource = std::pmr::memory_resource;
60+
61+
template <class Tp>
62+
using polymorphic_allocator = std::pmr::polymorphic_allocator<Tp>;
63+
#endif
64+
65+
memory_resource* get_default_resource();
4966

5067
/* ********************************* */
5168
/* PMR VECTOR DECLARATION */
5269
/* ********************************* */
5370

5471
template <class Tp>
55-
using pmr_vector =
56-
std::vector<Tp, boost::container::pmr::polymorphic_allocator<Tp>>;
57-
58-
memory_resource* get_default_resource();
72+
using pmr_vector = std::vector<Tp, polymorphic_allocator<Tp>>;
5973

6074
template <class Tp>
6175
class vector : public pmr_vector<Tp> {
@@ -141,7 +155,7 @@ using pmr_unordered_map = std::unordered_map<
141155
T,
142156
Hash,
143157
KeyEqual,
144-
boost::container::pmr::polymorphic_allocator<std::pair<const Key, T>>>;
158+
polymorphic_allocator<std::pair<const Key, T>>>;
145159

146160
template <
147161
class Key,
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
Polymorphic Allocator Fallback Implementation
2+
===
3+
4+
This implementation of polymorphic_allocator was pulled from Pablo Halpern's
5+
C++11 implementation available here:
6+
7+
https://github.com/phalpern/CppCon2017Code/tree/d26e7f4f6c593fe135c6b454aee93486790726b7
8+
9+
I have a personal forked copy here in case that repository ever dissappears:
10+
11+
https://github.com/davisp/phalpern-CppCon2017Code/tree/d26e7f4f6c593fe135c6b454aee93486790726b7
12+
13+
The only changes from the original files in that repository are to reformat
14+
using TileDB coding style and adding a handful of `std::` namespace qualifiers
15+
to avoid symbol name clashes with internal TileDB symbols.
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/* polymorphic_allocator.cpp -*-C++-*-
2+
*
3+
* Copyright 2012 Pablo Halpern.
4+
* Distributed under the Boost Software License, Version 1.0.
5+
* (See accompanying file LICENSE_1_0.txt or copy at
6+
* http://www.boost.org/LICENSE_1_0.txt)
7+
*/
8+
9+
#include "polymorphic_allocator.h"
10+
11+
namespace cpp17 {
12+
13+
atomic<pmr::memory_resource*> pmr::memory_resource::s_default_resource(nullptr);
14+
15+
pmr::new_delete_resource* pmr::new_delete_resource_singleton() {
16+
// TBD: I think the standard makes this exception-safe, otherwise, we need
17+
// to use 'call_once()' in '<mutex>'.
18+
static new_delete_resource singleton;
19+
return &singleton;
20+
}
21+
22+
} // namespace cpp17
23+
24+
// end polymorphic_allocator.cpp

0 commit comments

Comments
 (0)