最低要求c++17 static inline实现head only
#pragma once
#include <atomic>
template<typename Traits>
class AllocImpl;
template<typename Traits>
inline auto Next() {
return AllocImpl<Traits>::Next();
}
template<typename Traits>
class AllocImpl {
public:
using Type = typename Traits::Type;
static Type Next() {
if (current < max) {
return current++;
}
return SlowNext();
}
private:
static Type SlowNext();
private:
static inline std::atomic<Type> global{Traits::kMin};
static inline thread_local Type current = 0;
static inline thread_local Type max = 0;
};
template<typename Traits>
typename AllocImpl<Traits>::Type AllocImpl<Traits>::SlowNext() {
static_assert(Traits::kMin < Traits::kMax);
static_assert(Traits::kBatchSize > 0);
static_assert(Traits::kMin + Traits::kBatchSize < Traits::kMax,
"Not supported due to implementation limitations.");
static_assert(Traits::kBatchSize > 1,
"Not supported due to implementation limitations.");
// Get more IDs from global counter...
Type read, next;
do {
read = global.load(std::memory_order_relaxed);
current = read;
if (read > Traits::kMax - Traits::kBatchSize /* Overflowing */) {
next = Traits::kMin;
max = Traits::kMax;
}
else {
next = read + Traits::kBatchSize;
max = next;
}
} while (
!global.compare_exchange_weak(read, next, std::memory_order_relaxed));
// ... and retry.
return Next();
}
使用时指定1个traits.
struct ClientIdAllocTraits {
using Type = std::uint64_t;
static constexpr const Type kMin = 0;
static constexpr const Type kMax = 999999999999999;
static constexpr const Type kBatchSize = 200;
};
int main()
{
while (true) {
std::cout << Next<ClientIdAllocTraits>() << std::endl;
}
return 0;
}