1  
//
1  
//
2  
// Copyright (c) 2026 Michael Vandeberg
2  
// Copyright (c) 2026 Michael Vandeberg
3  
//
3  
//
4  
// Distributed under the Boost Software License, Version 1.0. (See accompanying
4  
// Distributed under the Boost Software License, Version 1.0. (See accompanying
5  
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5  
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6  
//
6  
//
7  
// Official repository: https://github.com/cppalliance/capy
7  
// Official repository: https://github.com/cppalliance/capy
8  
//
8  
//
9  

9  

10  
#ifndef BOOST_CAPY_DETAIL_SERVICE_SLOT_HPP
10  
#ifndef BOOST_CAPY_DETAIL_SERVICE_SLOT_HPP
11  
#define BOOST_CAPY_DETAIL_SERVICE_SLOT_HPP
11  
#define BOOST_CAPY_DETAIL_SERVICE_SLOT_HPP
12  

12  

13  
#include <atomic>
13  
#include <atomic>
14  
#include <cstddef>
14  
#include <cstddef>
15  

15  

16  
namespace boost {
16  
namespace boost {
17  
namespace capy {
17  
namespace capy {
18  
namespace detail {
18  
namespace detail {
19  

19  

20  
/* Slot ID infrastructure for O(1) service lookup.
20  
/* Slot ID infrastructure for O(1) service lookup.
21  

21  

22  
   Each distinct service type T gets a unique integer index via
22  
   Each distinct service type T gets a unique integer index via
23  
   service_slot<T>(). The index is assigned on first call from a
23  
   service_slot<T>(). The index is assigned on first call from a
24  
   global atomic counter and cached in a function-local static.
24  
   global atomic counter and cached in a function-local static.
25  
   Cross-DLL safety relies on COMDAT deduplication (same mechanism
25  
   Cross-DLL safety relies on COMDAT deduplication (same mechanism
26  
   as type_id_impl<T>::tag).
26  
   as type_id_impl<T>::tag).
27  
*/
27  
*/
28  

28  

29  
inline std::atomic<std::size_t> next_service_slot{0};
29  
inline std::atomic<std::size_t> next_service_slot{0};
30  

30  

31  
template<class T>
31  
template<class T>
32  
std::size_t
32  
std::size_t
33  
service_slot() noexcept
33  
service_slot() noexcept
34  
{
34  
{
35  
    static const std::size_t id =
35  
    static const std::size_t id =
36  
        next_service_slot.fetch_add(1, std::memory_order_relaxed);
36  
        next_service_slot.fetch_add(1, std::memory_order_relaxed);
37  
    return id;
37  
    return id;
38  
}
38  
}
39  

39  

40  
} // namespace detail
40  
} // namespace detail
41  
} // namespace capy
41  
} // namespace capy
42  
} // namespace boost
42  
} // namespace boost
43  

43  

44  
#endif
44  
#endif