LCOV - code coverage report
Current view: top level - boost/capy/core - thread_local_ptr.hpp (source / functions) Coverage Total Hit
Test: coverage_filtered.info Lines: 100.0 % 12 12
Test Date: 2026-01-15 18:27:21 Functions: 100.0 % 8 8

            Line data    Source code
       1              : //
       2              : // Copyright (c) 2025 Vinnie Falco (vinnie.falco@gmail.com)
       3              : //
       4              : // Distributed under the Boost Software License, Version 1.0. (See accompanying
       5              : // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
       6              : //
       7              : // Official repository: https://github.com/cppalliance/capy
       8              : //
       9              : 
      10              : #ifndef BOOST_CAPY_THREAD_LOCAL_PTR_HPP
      11              : #define BOOST_CAPY_THREAD_LOCAL_PTR_HPP
      12              : 
      13              : #include <boost/capy/detail/config.hpp>
      14              : 
      15              : #include <type_traits>
      16              : 
      17              : namespace boost {
      18              : namespace capy {
      19              : 
      20              : /** A thread-local pointer.
      21              : 
      22              :     This class provides thread-local storage for a pointer to T.
      23              :     Each thread has its own independent pointer value, initially
      24              :     nullptr. The user is responsible for managing the lifetime
      25              :     of the pointed-to objects.
      26              : 
      27              :     The storage is static per type T. All instances of
      28              :     `thread_local_ptr<T>` share the same underlying slot.
      29              : 
      30              :     The implementation uses the most efficient available mechanism:
      31              :     1. Compiler keyword (__declspec(thread) or __thread) - enforces POD
      32              :     2. C++11 thread_local (fallback)
      33              : 
      34              :     @tparam T The pointed-to type.
      35              : 
      36              :     @par Declaration
      37              : 
      38              :     Typically declared at namespace or class scope. The object
      39              :     is stateless, so local variables work but are redundant.
      40              : 
      41              :     @code
      42              :     // Recommended: namespace scope
      43              :     namespace {
      44              :     thread_local_ptr<session> current_session;
      45              :     }
      46              : 
      47              :     // Also works: static class member
      48              :     class server {
      49              :         static thread_local_ptr<request> current_request_;
      50              :     };
      51              : 
      52              :     // Works but unusual: local variable (still accesses static storage)
      53              :     void foo() {
      54              :         thread_local_ptr<context> ctx;  // same slot on every call
      55              :         ctx = new context();
      56              :     }
      57              :     @endcode
      58              : 
      59              :     @note The user is responsible for deleting pointed-to objects
      60              :     before threads exit to avoid memory leaks.
      61              : */
      62              : template<class T>
      63              : class thread_local_ptr;
      64              : 
      65              : //------------------------------------------------------------------------------
      66              : 
      67              : #if defined(BOOST_CAPY_TLS_KEYWORD)
      68              : 
      69              : // Use compiler-specific keyword (__declspec(thread) or __thread)
      70              : // Most efficient: static linkage, no dynamic init, enforces POD
      71              : 
      72              : template<class T>
      73              : class thread_local_ptr
      74              : {
      75              :     static BOOST_CAPY_TLS_KEYWORD T* ptr_;
      76              : 
      77              : public:
      78              :     thread_local_ptr() = default;
      79              :     ~thread_local_ptr() = default;
      80              : 
      81              :     thread_local_ptr(thread_local_ptr const&) = delete;
      82              :     thread_local_ptr& operator=(thread_local_ptr const&) = delete;
      83              : 
      84              :     /** Return the pointer for this thread.
      85              : 
      86              :         @return The stored pointer, or nullptr if not set.
      87              :     */
      88              :     T*
      89           13 :     get() const noexcept
      90              :     {
      91           13 :         return ptr_;
      92              :     }
      93              : 
      94              :     /** Set the pointer for this thread.
      95              : 
      96              :         @param p The pointer to store. The user manages its lifetime.
      97              :     */
      98              :     void
      99            2 :     set(T* p) noexcept
     100              :     {
     101            2 :         ptr_ = p;
     102            2 :     }
     103              : 
     104              :     /** Dereference the stored pointer.
     105              : 
     106              :         @pre get() != nullptr
     107              :     */
     108              :     T&
     109            2 :     operator*() const noexcept
     110              :     {
     111            2 :         return *ptr_;
     112              :     }
     113              : 
     114              :     /** Member access through the stored pointer.
     115              : 
     116              :         @pre get() != nullptr
     117              :     */
     118              :     T*
     119            5 :     operator->() const noexcept
     120              :         requires std::is_class_v<T>
     121              :     {
     122            5 :         return ptr_;
     123              :     }
     124              : 
     125              :     /** Assign a pointer value.
     126              : 
     127              :         @param p The pointer to store.
     128              :         @return The stored pointer.
     129              :     */
     130              :     T*
     131            9 :     operator=(T* p) noexcept
     132              :     {
     133            9 :         ptr_ = p;
     134            9 :         return p;
     135              :     }
     136              : };
     137              : 
     138              : template<class T>
     139              : BOOST_CAPY_TLS_KEYWORD T* thread_local_ptr<T>::ptr_ = nullptr;
     140              : 
     141              : //------------------------------------------------------------------------------
     142              : 
     143              : #else
     144              : 
     145              : // Use C++11 thread_local keyword (fallback)
     146              : 
     147              : template<class T>
     148              : class thread_local_ptr
     149              : {
     150              :     static thread_local T* ptr_;
     151              : 
     152              : public:
     153              :     thread_local_ptr() = default;
     154              :     ~thread_local_ptr() = default;
     155              : 
     156              :     thread_local_ptr(thread_local_ptr const&) = delete;
     157              :     thread_local_ptr& operator=(thread_local_ptr const&) = delete;
     158              : 
     159              :     T*
     160              :     get() const noexcept
     161              :     {
     162              :         return ptr_;
     163              :     }
     164              : 
     165              :     void
     166              :     set(T* p) noexcept
     167              :     {
     168              :         ptr_ = p;
     169              :     }
     170              : 
     171              :     T&
     172              :     operator*() const noexcept
     173              :     {
     174              :         return *ptr_;
     175              :     }
     176              : 
     177              :     T*
     178              :     operator->() const noexcept
     179              :         requires std::is_class_v<T>
     180              :     {
     181              :         return ptr_;
     182              :     }
     183              : 
     184              :     T*
     185              :     operator=(T* p) noexcept
     186              :     {
     187              :         ptr_ = p;
     188              :         return p;
     189              :     }
     190              : };
     191              : 
     192              : template<class T>
     193              : thread_local T* thread_local_ptr<T>::ptr_ = nullptr;
     194              : 
     195              : #endif
     196              : 
     197              : } // namespace capy
     198              : } // namespace boost
     199              : 
     200              : #endif
        

Generated by: LCOV version 2.3