1212
1313#include < boost/capy/detail/config.hpp>
1414#include < boost/capy/detail/frame_memory_resource.hpp>
15+ #include < boost/capy/detail/service_slot.hpp>
1516#include < boost/capy/detail/type_id.hpp>
1617#include < boost/capy/concept/executor.hpp>
18+ #include < atomic>
1719#include < concepts>
1820#include < memory>
1921#include < memory_resource>
@@ -223,6 +225,14 @@ class BOOST_CAPY_DECL
223225 template <class T >
224226 T* find_service () const noexcept
225227 {
228+ auto id = detail::service_slot<T>();
229+ if (id < max_service_slots)
230+ {
231+ auto * p = slots_[id].load (
232+ std::memory_order_acquire);
233+ if (p)
234+ return static_cast <T*>(p);
235+ }
226236 std::lock_guard<std::mutex> lock (mutex_);
227237 return static_cast <T*>(find_impl (detail::type_id<T>()));
228238 }
@@ -255,6 +265,24 @@ class BOOST_CAPY_DECL
255265 " T must derive from service" );
256266 static_assert (std::is_constructible<T, execution_context&>::value,
257267 " T must be constructible from execution_context&" );
268+ if constexpr (get_key<T>::value)
269+ {
270+ static_assert (
271+ std::is_convertible<T&, typename get_key<T>::type&>::value,
272+ " T& must be convertible to key_type&" );
273+ }
274+
275+ // Fast path: O(1) slot lookup
276+ {
277+ auto id = detail::service_slot<T>();
278+ if (id < max_service_slots)
279+ {
280+ auto * p = slots_[id].load (
281+ std::memory_order_acquire);
282+ if (p)
283+ return static_cast <T&>(*p);
284+ }
285+ }
258286
259287 struct impl : factory
260288 {
@@ -263,7 +291,11 @@ class BOOST_CAPY_DECL
263291 detail::type_id<T>(),
264292 get_key<T>::value
265293 ? detail::type_id<typename get_key<T>::type>()
266- : detail::type_id<T>())
294+ : detail::type_id<T>(),
295+ detail::service_slot<T>(),
296+ get_key<T>::value
297+ ? detail::service_slot<typename get_key<T>::type>()
298+ : detail::service_slot<T>())
267299 {
268300 }
269301
@@ -325,7 +357,11 @@ class BOOST_CAPY_DECL
325357 detail::type_id<T>(),
326358 get_key<T>::value
327359 ? detail::type_id<typename get_key<T>::type>()
328- : detail::type_id<T>())
360+ : detail::type_id<T>(),
361+ detail::service_slot<T>(),
362+ get_key<T>::value
363+ ? detail::service_slot<typename get_key<T>::type>()
364+ : detail::service_slot<T>())
329365 , args_(std::forward<Args>(a)...)
330366 {
331367 }
@@ -505,11 +541,16 @@ class BOOST_CAPY_DECL
505541 detail::type_index t0;
506542 detail::type_index t1;
507543 BOOST_CAPY_MSVC_WARNING_POP
544+ std::size_t slot0;
545+ std::size_t slot1;
508546
509547 factory (
510548 detail::type_info const & t0_,
511- detail::type_info const & t1_)
549+ detail::type_info const & t1_,
550+ std::size_t s0,
551+ std::size_t s1)
512552 : t0(t0_), t1(t1_)
553+ , slot0(s0), slot1(s1)
513554 {
514555 }
515556
@@ -523,7 +564,7 @@ class BOOST_CAPY_DECL
523564 service& use_service_impl (factory& f);
524565 service& make_service_impl (factory& f);
525566
526- // warning C4251: std::mutex, std::shared_ptr need dll-interface
567+ // warning C4251: std::mutex, std::shared_ptr, std::atomic need dll-interface
527568 BOOST_CAPY_MSVC_WARNING_PUSH
528569 BOOST_CAPY_MSVC_WARNING_DISABLE (4251 )
529570 mutable std::mutex mutex_;
@@ -532,6 +573,12 @@ class BOOST_CAPY_DECL
532573 std::pmr::memory_resource* frame_alloc_ = nullptr ;
533574 service* head_ = nullptr ;
534575 bool shutdown_ = false ;
576+
577+ static constexpr std::size_t max_service_slots = 32 ;
578+ BOOST_CAPY_MSVC_WARNING_PUSH
579+ BOOST_CAPY_MSVC_WARNING_DISABLE (4251 )
580+ std::atomic<service*> slots_[max_service_slots] = {};
581+ BOOST_CAPY_MSVC_WARNING_POP
535582};
536583
537584template < typename Derived >
0 commit comments