LCOV - code coverage report
Current view: top level - capy/detail - thread_local_ptr.hpp (source / functions) Coverage Total Hit
Test: coverage_remapped.info Lines: 100.0 % 12 12
Test Date: 2026-02-17 18:14:47 Functions: 100.0 % 8 8

           TLA  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 HIT          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