diff --git a/typeidx.cpp b/typeidx.cpp index cbd99c2b..5cc349ac 100644 --- a/typeidx.cpp +++ b/typeidx.cpp @@ -11,9 +11,17 @@ #include /////////////////////////////////////////////////////////////////////////////// +static std::atomic counter; + + +//----------------------------------------------------------------------------- int cruft::detail::typeidx_next () { - static std::atomic counter = 0; - return counter++; + // We can't return zero, but we want to optimise access to the static + // (which means we can't have it locally due to initialisation locking). + // + // Ensure we use pre-increment so that we can utilise zero static + // initialisation instead. + return ++counter; } diff --git a/typeidx.hpp b/typeidx.hpp index 0782b73b..eacc7136 100644 --- a/typeidx.hpp +++ b/typeidx.hpp @@ -3,29 +3,31 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * - * Copyright 2017 Danny Robson + * Copyright 2017-2019 Danny Robson */ -#ifndef CRUFT_UTIL_TYPEIDX_HPP -#define CRUFT_UTIL_TYPEIDX_HPP +#pragma once #include namespace cruft { namespace detail { int typeidx_next (void); } - /// return a globally unique runtime ID for a given type. + /// Return a globally unique runtime ID for a given type. /// - /// this is intended to be used as a lightweight type check for variants + /// This is intended to be used as a lightweight type check for variants /// and such without requiring RTTI. /// - /// the identifier is constructed at runtime and is not guaranteed to be + /// The identifier is constructed at runtime and is not guaranteed to be /// stable across executions (particularly in the case of threads and - /// other non-determinism). however it _is_ threadsafe to call this. + /// other non-determinism). However it _is_ threadsafe to call this. /// - /// the range of identifiers is _probably_ contiguous starting from zero. - /// this should not be relied upon for correctness, but may be used for - /// performance concerns. + /// The value 0 will never be returned from this function and can be used + /// to indicate an 'unknown' state. + /// + /// The range of identifiers is _probably_ contiguous. This should not + /// be relied upon for correctness, but may be used for performance + /// concerns. template int typeidx (void) @@ -34,5 +36,3 @@ namespace cruft { return id; } } - -#endif