最低要求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;}
