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

Generated by: LCOV version 2.3