Line data Source code
1 : // 2 : // Copyright 2024 OpenModelViewer Authors 3 : // 4 : // Licensed under the Apache License, Version 2.0 (the "License"); 5 : // you may not use this file except in compliance with the License. 6 : // You may obtain a copy of the License at 7 : // 8 : // http://www.apache.org/licenses/LICENSE-2.0 9 : // 10 : // Unless required by applicable law or agreed to in writing, software 11 : // distributed under the License is distributed on an "AS IS" BASIS, 12 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 : // See the License for the specific language governing permissions and 14 : // limitations under the License. 15 : // 16 : 17 : #include "openmodelviewer/core/id/atomic_id_generator.hpp" 18 : 19 : #include <limits> 20 : #include <stdexcept> 21 : 22 : namespace openmodelviewer::core::id 23 : { 24 120 : AtomicIdGenerator::AtomicIdGenerator(AtomicIdType min, bool allowWrap) : 25 120 : m_counter(min), 26 120 : m_allowWrap(allowWrap) 27 : { 28 120 : if(min <= 0) 29 : { 30 1 : throw std::invalid_argument("AtomicIdGenerator initialized with min = 0, value reserved."); 31 : } 32 : 33 119 : if (min >= std::numeric_limits<AtomicIdType>::max()) 34 : { 35 1 : throw std::invalid_argument("AtomicIdGenerator initialized with min = AtomicIdType max value."); 36 : } 37 : 38 118 : m_start = min; 39 118 : } 40 : 41 97346 : AtomicIdType AtomicIdGenerator::generate() 42 : { 43 : // Relaxed: no need for visibility or ordering across threads, just uniqueness 44 97346 : auto val = m_counter.fetch_add(1, std::memory_order_relaxed); 45 : 46 97346 : if (val >= std::numeric_limits<AtomicIdType>::max()) 47 : { 48 2 : if (m_allowWrap) 49 : { 50 1 : m_counter.store(m_start, std::memory_order_relaxed); 51 : } 52 : else 53 : { 54 1 : throw std::runtime_error("AtomicIdGenerator overflow: AtomicIdType max value reached."); 55 : } 56 : } 57 : 58 97838 : return val; 59 : } 60 : }