You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I am trying to extern template instantiate the boost::geometry::rtree with boost::interprocess allocator, since I need it in multiple translation units and the (very appreciated) rtree implementation generates a lot of code bloat.
When using a stateless allocator, such as std::allocator, this works. However when using a stateful allocator such as boost::interprocess, it does not compile due to three default constructors around the rtree code that call the default constructor of the allocator, which does not exist for stateful allocators for obvious reasons.
Here is a basic example that does not compile when the extern template declaration and respective initialization are uncommented (sometimes the code compilation gives timeout, then retry, or compile it locally): https://godbolt.org/z/EbGohf167
Also attached: project-2024 04 2610 46 28.zip
The error message is here:
Open to review
Step cmake returned: 0
-- The C compiler identification is GNU 13.2.0
-- The CXX compiler identification is GNU 13.2.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /opt/compiler-explorer/gcc-13.2.0/bin/gcc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /opt/compiler-explorer/gcc-13.2.0/bin/g++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done (0.3s)
-- Generating done (0.0s)
-- Build files have been written to: /app/build
Step build returned: 2
[ 33%] Building CXX object CMakeFiles/index.dir/main.cpp.o
[ 66%] Building CXX object CMakeFiles/index.dir/index.cpp.o
In file included from /opt/compiler-explorer/libs/boost_1_84_0/boost/geometry/index/detail/rtree/node/node.hpp:37,
from /opt/compiler-explorer/libs/boost_1_84_0/boost/geometry/index/rtree.hpp:64,
from /opt/compiler-explorer/libs/boost_1_84_0/boost/geometry/algorithms/detail/within/multi_point.hpp:38,
from /opt/compiler-explorer/libs/boost_1_84_0/boost/geometry/algorithms/detail/within/implementation.hpp:30,
from /opt/compiler-explorer/libs/boost_1_84_0/boost/geometry/algorithms/detail/covered_by/implementation.hpp:26,
from /opt/compiler-explorer/libs/boost_1_84_0/boost/geometry/algorithms/covered_by.hpp:24,
from /opt/compiler-explorer/libs/boost_1_84_0/boost/geometry/algorithms/detail/buffer/buffered_piece_collection.hpp:32,
from /opt/compiler-explorer/libs/boost_1_84_0/boost/geometry/algorithms/detail/buffer/buffer_inserter.hpp:30,
from /opt/compiler-explorer/libs/boost_1_84_0/boost/geometry/algorithms/detail/buffer/implementation.hpp:24,
from /opt/compiler-explorer/libs/boost_1_84_0/boost/geometry/algorithms/buffer.hpp:22,
from /opt/compiler-explorer/libs/boost_1_84_0/boost/geometry/geometry.hpp:63,
from /opt/compiler-explorer/libs/boost_1_84_0/boost/geometry.hpp:17,
from /app/index.hpp:3,
from /app/index.cpp:1:
/opt/compiler-explorer/libs/boost_1_84_0/boost/geometry/index/detail/rtree/node/variant_static.hpp: In instantiation of 'boost::geometry::index::detail::rtree::allocators<Allocator, Value, Parameters, Box, boost::geometry::index::detail::rtree::node_variant_static_tag>::allocators() [with Allocator = boost::interprocess::allocator<std::pair<boost::geometry::model::point<double, 2, boost::geometry::cs::cartesian>, long unsigned int>, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family>, boost::interprocess::iset_index> >; Value = std::pair<boost::geometry::model::point<double, 2, boost::geometry::cs::cartesian>, long unsigned int>; Parameters = boost::geometry::index::rstar<16>; Box = boost::geometry::model::box<boost::geometry::model::point<double, 2, boost::geometry::cs::cartesian> >]':
/opt/compiler-explorer/libs/boost_1_84_0/boost/geometry/index/rtree.hpp:290:21: required from 'boost::geometry::index::rtree<Value, Options, IndexableGetter, EqualTo, Allocator>::members_holder::members_holder(const IndGet&, const ValEq&, const Parameters&) [with IndGet = boost::geometry::index::indexable<std::pair<boost::geometry::model::point<double, 2, boost::geometry::cs::cartesian>, long unsigned int> >; ValEq = boost::geometry::index::equal_to<std::pair<boost::geometry::model::point<double, 2, boost::geometry::cs::cartesian>, long unsigned int> >; Value = std::pair<boost::geometry::model::point<double, 2, boost::geometry::cs::cartesian>, long unsigned int>; Parameters = boost::geometry::index::rstar<16>; IndexableGetter = boost::geometry::index::indexable<std::pair<boost::geometry::model::point<double, 2, boost::geometry::cs::cartesian>, long unsigned int> >; EqualTo = boost::geometry::index::equal_to<std::pair<boost::geometry::model::point<double, 2, boost::geometry::cs::cartesian>, long unsigned int> >; Allocator = boost::interprocess::allocator<std::pair<boost::geometry::model::point<double, 2, boost::geometry::cs::cartesian>, long unsigned int>, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family>, boost::interprocess::iset_index> >]'
/opt/compiler-explorer/libs/boost_1_84_0/boost/geometry/index/rtree.hpp:367:11: required from 'boost::geometry::index::rtree<Value, Options, IndexableGetter, EqualTo, Allocator>::rtree(const parameters_type&, const indexable_getter&, const value_equal&) [with Value = std::pair<boost::geometry::model::point<double, 2, boost::geometry::cs::cartesian>, long unsigned int>; Parameters = boost::geometry::index::rstar<16>; IndexableGetter = boost::geometry::index::indexable<std::pair<boost::geometry::model::point<double, 2, boost::geometry::cs::cartesian>, long unsigned int> >; EqualTo = boost::geometry::index::equal_to<std::pair<boost::geometry::model::point<double, 2, boost::geometry::cs::cartesian>, long unsigned int> >; Allocator = boost::interprocess::allocator<std::pair<boost::geometry::model::point<double, 2, boost::geometry::cs::cartesian>, long unsigned int>, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family>, boost::interprocess::iset_index> >; parameters_type = boost::geometry::index::rstar<16>; indexable_getter = boost::geometry::index::indexable<std::pair<boost::geometry::model::point<double, 2, boost::geometry::cs::cartesian>, long unsigned int> >; value_equal = boost::geometry::index::equal_to<std::pair<boost::geometry::model::point<double, 2, boost::geometry::cs::cartesian>, long unsigned int> >]'
/app/index.cpp:13:31: required from here
/opt/compiler-explorer/libs/boost_1_84_0/boost/geometry/index/detail/rtree/node/variant_static.hpp:129:31: error: no matching function for call to 'boost::interprocess::allocator<boost::variant<boost::geometry::index::detail::rtree::variant_leaf<std::pair<boost::geometry::model::point<double, 2, boost::geometry::cs::cartesian>, long unsigned int>, boost::geometry::index::rstar<16>, boost::geometry::model::box<boost::geometry::model::point<double, 2, boost::geometry::cs::cartesian> >, boost::geometry::index::detail::rtree::allocators<boost::interprocess::allocator<std::pair<boost::geometry::model::point<double, 2, boost::geometry::cs::cartesian>, long unsigned int>, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family>, boost::interprocess::iset_index> >, std::pair<boost::geometry::model::point<double, 2, boost::geometry::cs::cartesian>, long unsigned int>, boost::geometry::index::rstar<16>, boost::geometry::model::box<boost::geometry::model::point<double, 2, boost::geometry::cs::cartesian> >, boost::geometry::index::detail::rtree::node_variant_static_tag>, boost::geometry::index::detail::rtree::node_variant_static_tag>, boost::geometry::index::detail::rtree::variant_internal_node<std::pair<boost::geometry::model::point<double, 2, boost::geometry::cs::cartesian>, long unsigned int>, boost::geometry::index::rstar<16, 4, 4, 32>, boost::geometry::model::box<boost::geometry::model::point<double, 2, boost::geometry::cs::cartesian> >, boost::geometry::index::detail::rtree::allocators<boost::interprocess::allocator<std::pair<boost::geometry::model::point<double, 2, boost::geometry::cs::cartesian>, long unsigned int>, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void, long int, long unsigned int, 0>, 0>, boost::interprocess::iset_index> >, std::pair<boost::geometry::model::point<double, 2, boost::geometry::cs::cartesian>, long unsigned int>, boost::geometry::index::rstar<16, 4, 4, 32>, boost::geometry::model::box<boost::geometry::model::point<double, 2, boost::geometry::cs::cartesian> >, boost::geometry::index::detail::rtree::node_variant_static_tag>, boost::geometry::index::detail::rtree::node_variant_static_tag> >, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family>, boost::interprocess::iset_index> >::allocator()'
129 | : node_allocator_type()
| ^
In file included from /opt/compiler-explorer/libs/boost_1_84_0/boost/interprocess/segment_manager.hpp:38,
from /opt/compiler-explorer/libs/boost_1_84_0/boost/interprocess/detail/managed_memory_impl.hpp:30,
from /opt/compiler-explorer/libs/boost_1_84_0/boost/interprocess/managed_shared_memory.hpp:25,
from /app/index.hpp:7:
/opt/compiler-explorer/libs/boost_1_84_0/boost/interprocess/allocators/allocator.hpp:142:4: note: candidate: 'template<class T2> boost::interprocess::allocator<T, SegmentManager>::allocator(const boost::interprocess::allocator<T2, SegmentManager>&) [with T = boost::variant<boost::geometry::index::detail::rtree::variant_leaf<std::pair<boost::geometry::model::point<double, 2, boost::geometry::cs::cartesian>, long unsigned int>, boost::geometry::index::rstar<16>, boost::geometry::model::box<boost::geometry::model::point<double, 2, boost::geometry::cs::cartesian> >, boost::geometry::index::detail::rtree::allocators<boost::interprocess::allocator<std::pair<boost::geometry::model::point<double, 2, boost::geometry::cs::cartesian>, long unsigned int>, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family>, boost::interprocess::iset_index> >, std::pair<boost::geometry::model::point<double, 2, boost::geometry::cs::cartesian>, long unsigned int>, boost::geometry::index::rstar<16>, boost::geometry::model::box<boost::geometry::model::point<double, 2, boost::geometry::cs::cartesian> >, boost::geometry::index::detail::rtree::node_variant_static_tag>, boost::geometry::index::detail::rtree::node_variant_static_tag>, boost::geometry::index::detail::rtree::variant_internal_node<std::pair<boost::geometry::model::point<double, 2, boost::geometry::cs::cartesian>, long unsigned int>, boost::geometry::index::rstar<16, 4, 4, 32>, boost::geometry::model::box<boost::geometry::model::point<double, 2, boost::geometry::cs::cartesian> >, boost::geometry::index::detail::rtree::allocators<boost::interprocess::allocator<std::pair<boost::geometry::model::point<double, 2, boost::geometry::cs::cartesian>, long unsigned int>, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void, long int, long unsigned int, 0>, 0>, boost::interprocess::iset_index> >, std::pair<boost::geometry::model::point<double, 2, boost::geometry::cs::cartesian>, long unsigned int>, boost::geometry::index::rstar<16, 4, 4, 32>, boost::geometry::model::box<boost::geometry::model::point<double, 2, boost::geometry::cs::cartesian> >, boost::geometry::index::detail::rtree::node_variant_static_tag>, boost::geometry::index::detail::rtree::node_variant_static_tag> >; SegmentManager = boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family>, boost::interprocess::iset_index>]'
142 | allocator(const allocator<T2, SegmentManager> &other)
| ^~~~~~~~~
/opt/compiler-explorer/libs/boost_1_84_0/boost/interprocess/allocators/allocator.hpp:142:4: note: template argument deduction/substitution failed:
/opt/compiler-explorer/libs/boost_1_84_0/boost/geometry/index/detail/rtree/node/variant_static.hpp:129:31: note: candidate expects 1 argument, 0 provided
129 | : node_allocator_type()
| ^
/opt/compiler-explorer/libs/boost_1_84_0/boost/interprocess/allocators/allocator.hpp:136:4: note: candidate: 'boost::interprocess::allocator<T, SegmentManager>::allocator(const boost::interprocess::allocator<T, SegmentManager>&) [with T = boost::variant<boost::geometry::index::detail::rtree::variant_leaf<std::pair<boost::geometry::model::point<double, 2, boost::geometry::cs::cartesian>, long unsigned int>, boost::geometry::index::rstar<16>, boost::geometry::model::box<boost::geometry::model::point<double, 2, boost::geometry::cs::cartesian> >, boost::geometry::index::detail::rtree::allocators<boost::interprocess::allocator<std::pair<boost::geometry::model::point<double, 2, boost::geometry::cs::cartesian>, long unsigned int>, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family>, boost::interprocess::iset_index> >, std::pair<boost::geometry::model::point<double, 2, boost::geometry::cs::cartesian>, long unsigned int>, boost::geometry::index::rstar<16>, boost::geometry::model::box<boost::geometry::model::point<double, 2, boost::geometry::cs::cartesian> >, boost::geometry::index::detail::rtree::node_variant_static_tag>, boost::geometry::index::detail::rtree::node_variant_static_tag>, boost::geometry::index::detail::rtree::variant_internal_node<std::pair<boost::geometry::model::point<double, 2, boost::geometry::cs::cartesian>, long unsigned int>, boost::geometry::index::rstar<16, 4, 4, 32>, boost::geometry::model::box<boost::geometry::model::point<double, 2, boost::geometry::cs::cartesian> >, boost::geometry::index::detail::rtree::allocators<boost::interprocess::allocator<std::pair<boost::geometry::model::point<double, 2, boost::geometry::cs::cartesian>, long unsigned int>, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void, long int, long unsigned int, 0>, 0>, boost::interprocess::iset_index> >, std::pair<boost::geometry::model::point<double, 2, boost::geometry::cs::cartesian>, long unsigned int>, boost::geometry::index::rstar<16, 4, 4, 32>, boost::geometry::model::box<boost::geometry::model::point<double, 2, boost::geometry::cs::cartesian> >, boost::geometry::index::detail::rtree::node_variant_static_tag>, boost::geometry::index::detail::rtree::node_variant_static_tag> >; SegmentManager = boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family>, boost::interprocess::iset_index>]'
136 | allocator(const allocator &other)
| ^~~~~~~~~
/opt/compiler-explorer/libs/boost_1_84_0/boost/interprocess/allocators/allocator.hpp:136:4: note: candidate expects 1 argument, 0 provided
/opt/compiler-explorer/libs/boost_1_84_0/boost/interprocess/allocators/allocator.hpp:131:4: note: candidate: 'boost::interprocess::allocator<T, SegmentManager>::allocator(segment_manager*) [with T = boost::variant<boost::geometry::index::detail::rtree::variant_leaf<std::pair<boost::geometry::model::point<double, 2, boost::geometry::cs::cartesian>, long unsigned int>, boost::geometry::index::rstar<16>, boost::geometry::model::box<boost::geometry::model::point<double, 2, boost::geometry::cs::cartesian> >, boost::geometry::index::detail::rtree::allocators<boost::interprocess::allocator<std::pair<boost::geometry::model::point<double, 2, boost::geometry::cs::cartesian>, long unsigned int>, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family>, boost::interprocess::iset_index> >, std::pair<boost::geometry::model::point<double, 2, boost::geometry::cs::cartesian>, long unsigned int>, boost::geometry::index::rstar<16>, boost::geometry::model::box<boost::geometry::model::point<double, 2, boost::geometry::cs::cartesian> >, boost::geometry::index::detail::rtree::node_variant_static_tag>, boost::geometry::index::detail::rtree::node_variant_static_tag>, boost::geometry::index::detail::rtree::variant_internal_node<std::pair<boost::geometry::model::point<double, 2, boost::geometry::cs::cartesian>, long unsigned int>, boost::geometry::index::rstar<16, 4, 4, 32>, boost::geometry::model::box<boost::geometry::model::point<double, 2, boost::geometry::cs::cartesian> >, boost::geometry::index::detail::rtree::allocators<boost::interprocess::allocator<std::pair<boost::geometry::model::point<double, 2, boost::geometry::cs::cartesian>, long unsigned int>, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void, long int, long unsigned int, 0>, 0>, boost::interprocess::iset_index> >, std::pair<boost::geometry::model::point<double, 2, boost::geometry::cs::cartesian>, long unsigned int>, boost::geometry::index::rstar<16, 4, 4, 32>, boost::geometry::model::box<boost::geometry::model::point<double, 2, boost::geometry::cs::cartesian> >, boost::geometry::index::detail::rtree::node_variant_static_tag>, boost::geometry::index::detail::rtree::node_variant_static_tag> >; SegmentManager = boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family>, boost::interprocess::iset_index>; segment_manager = boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family>, boost::interprocess::iset_index>]'
131 | allocator(segment_manager *segment_mngr)
| ^~~~~~~~~
/opt/compiler-explorer/libs/boost_1_84_0/boost/interprocess/allocators/allocator.hpp:131:4: note: candidate expects 1 argument, 0 provided
gmake[2]: *** [CMakeFiles/index.dir/build.make:90: CMakeFiles/index.dir/index.cpp.o] Error 1
gmake[1]: *** [CMakeFiles/Makefile2:83: CMakeFiles/index.dir/all] Error 2
gmake: *** [Makefile:91: all] Error 2
When no explicit template instantiation is used, the code compiles for obvious reasons, since the client code in the main.cpp does not use the default constructor of the rtree but the explicit one with allocators, however the explicit instantiation wants to compile the default constructors.
There need to be made three changes by applying std::enable_if to three constructors. The error message only shows the first error, after fixing it, two more arise. I attached the changes as patch file here: index.patch
The idea is to enable the constructors that call the default allocator constructor only when the given allocator template is default initializable. So the idea is to disable every rtree and node constructor that calls a non-existing constructor of the allocator.
Then the code compiles without error, since the default constructor of the allocator is not called anymore. Please feel free to adapt the style to your liking!
I know that this solution has its caveats, however I don't know any other solution to this problem besides C++20 requires clauses.
Thank you!
The text was updated successfully, but these errors were encountered:
Dear friends,
I am trying to extern template instantiate the boost::geometry::rtree with boost::interprocess allocator, since I need it in multiple translation units and the (very appreciated) rtree implementation generates a lot of code bloat.
When using a stateless allocator, such as std::allocator, this works. However when using a stateful allocator such as boost::interprocess, it does not compile due to three default constructors around the rtree code that call the default constructor of the allocator, which does not exist for stateful allocators for obvious reasons.
Here is a basic example that does not compile when the extern template declaration and respective initialization are uncommented (sometimes the code compilation gives timeout, then retry, or compile it locally):
https://godbolt.org/z/EbGohf167
Also attached:
project-2024 04 2610 46 28.zip
The error message is here:
Open to review
When no explicit template instantiation is used, the code compiles for obvious reasons, since the client code in the main.cpp does not use the default constructor of the rtree but the explicit one with allocators, however the explicit instantiation wants to compile the default constructors.
There need to be made three changes by applying std::enable_if to three constructors. The error message only shows the first error, after fixing it, two more arise. I attached the changes as patch file here:
index.patch
The idea is to enable the constructors that call the default allocator constructor only when the given allocator template is default initializable. So the idea is to disable every rtree and node constructor that calls a non-existing constructor of the allocator.
Then the code compiles without error, since the default constructor of the allocator is not called anymore. Please feel free to adapt the style to your liking!
I know that this solution has its caveats, however I don't know any other solution to this problem besides C++20 requires clauses.
Thank you!
The text was updated successfully, but these errors were encountered: