A class template for thread local storage.

// Defined in header <tbb/enumerable_thread_specific.h>

namespace tbb {

    enum ets_key_usage_type {

    template <typename T,
        typename Allocator=cache_aligned_allocator<T>,
        ets_key_usage_type ETS_key_type=ets_no_key >
    class enumerable_thread_specific {
        // Basic types
        using value_type = T;
        using reference = T&;
        using const_reference = const T&;
        using pointer = T*;
        using size_type = /* implementation-defined */;
        using difference_type = /* implementation-defined */;
        using allocator_type = Allocator;

        // Iterator types
        using iterator = /* implementation-defined */;
        using const_iterator = /* implementation-defined */;

        // Parallel range types
        using range_type = /* implementation-defined */;
        using const_range_type = /* implementation-defined */;

        // Construction
        template <typename Finit>
        explicit enumerable_thread_specific( Finit finit );
        explicit enumerable_thread_specific( const T& exemplar );
        explicit enumerable_thread_specific( T&& exemplar );
        template <typename... Args>
        enumerable_thread_specific( Args&&... args );

        // Destruction

        // Copy constructors
        enumerable_thread_specific( const enumerable_thread_specific& other);
        template<typename Alloc, ets_key_usage_type Cachetype>
        enumerable_thread_specific( const enumerable_thread_specific<T, Alloc, Cachetype>& other);
        // Copy assignments
        enumerable_thread_specific& operator=( const enumerable_thread_specific& other );
        template<typename Alloc, ets_key_usage_type Cachetype>
        enumerable_thread_specific& operator=( const enumerable_thread_specific<T, Alloc, Cachetype>& other );

        // Move constructors
        enumerable_thread_specific( enumerable_thread_specific&& other);
        template<typename Alloc, ets_key_usage_type Cachetype>
        enumerable_thread_specific( enumerable_thread_specific<T, Alloc, Cachetype>&& other);
        // Move assignments
        enumerable_thread_specific& operator=( enumerable_thread_specific&& other );
        template<typename Alloc, ets_key_usage_type Cachetype>
        enumerable_thread_specific& operator=( enumerable_thread_specific<T, Alloc, Cachetype>&& other );

        // Other whole container operations
        void clear();

        // Concurrent operations
        reference local();
        reference local( bool& exists );
        size_type size() const;
        bool empty() const;

        // Combining
        template<typename BinaryFunc> T combine( BinaryFunc f );
        template<typename UnaryFunc> void combine_each( UnaryFunc f );

        // Parallel iteration
        range_type range( size_t grainsize=1 );
        const_range_type range( size_t grainsize=1 ) const;

        // Iterators
        iterator begin();
        iterator end();
        const_iterator begin() const;
        const_iterator end() const;

} // namespace tbb

A class template enumerable_thread_specific provides thread local storage (TLS) for elements of type T. A class template enumerable_thread_specific acts as a container by providing iterators and ranges across all of the thread-local elements.

The thread-local elements are created lazily. A freshly constructed enumerable_thread_specific has no elements. When a thread requests access to an enumerable_thread_specific, it creates an element corresponding to that thread. The number of elements is equal to the number of distinct threads that have accessed the enumerable_thread_specific and not necessarily the number of threads in use by the application. Clearing an enumerable_thread_specific removes all its elements.

The ETS_key_usage_type parameter type can be used to select an underlying implementation.


enumerable_thread_specific uses the OS-specific value returned by std::this_thread::get_id() to identify threads. This value is not guaranteed to be unique except for the life of the thread. A newly created thread may get an OS-specific ID equal to that of an already destroyed thread. The number of elements of the enumerable_thread_specific may therefore be less than the number of actual distinct threads that have called local(), and the element returned by the first reference by a thread to the enumerable_thread_specific may not be newly-constructed.

Non-member types and constants

enum ets_key_usage_type::ets_key_per_instance

Enumeration parameter type used to select an implementation that consumes 1 native TLS key per enumerable_thread_specific instance. The number of native TLS keys may be limited and can be fairly small.

enum ets_key_usage_type::ets_no_key

Enumeration parameter type used to select an implementation that consumes no native TLS keys. If no ETS_key_usage_type parameter type is provided, ets_no_key is used by default.

enum ets_key_usage_type::ets_suspend_aware

tbb::task::suspend function can change the value of enumerable_thread_specific object. In order to avoid this problem, ets_suspend_aware enumeration parameter type should be used. The local() value can be the same for different threads, but no two distinct threads can access the same value simultaneously.