LCOV - code coverage report
Current view: top level - boost/http_proto/detail/impl - workspace.hpp (source / functions) Hit Total Coverage
Test: coverage_filtered.info Lines: 47 48 97.9 %
Date: 2024-03-18 23:12:48 Functions: 27 29 93.1 %

          Line data    Source code
       1             : //
       2             : // Copyright (c) 2019 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/http_proto
       8             : //
       9             : 
      10             : #ifndef BOOST_HTTP_PROTO_DETAIL_IMPL_WORKSPACE_HPP
      11             : #define BOOST_HTTP_PROTO_DETAIL_IMPL_WORKSPACE_HPP
      12             : 
      13             : #include <boost/config.hpp>
      14             : 
      15             : namespace boost {
      16             : namespace http_proto {
      17             : namespace detail {
      18             : 
      19             : #if defined(BOOST_MSVC)
      20             : #pragma warning(push)
      21             : #pragma warning(disable : 4324) /* structure was padded due to __declspec(align()) */
      22             : #endif
      23             : 
      24         340 : struct workspace::any
      25             : {
      26             :     any* next = nullptr;
      27             : 
      28             :     BOOST_HTTP_PROTO_DECL
      29             :     virtual ~any() = 0;
      30             : };
      31             : 
      32             : template<class U>
      33             : struct alignas(alignof(::max_align_t))
      34             :     workspace::any_impl : any
      35             : {
      36             :     U u;
      37             : 
      38             :     any_impl() = delete;
      39             :     any_impl(any_impl&&) = default;
      40             : 
      41             :     template<class U_>
      42         314 :     explicit any_impl(U_&& u_)
      43         314 :         : u(std::move(u_))
      44             :     {
      45         314 :     }
      46             : };
      47             : 
      48             : struct workspace::undo
      49             : {
      50             :     explicit
      51         340 :     undo(workspace& ws0) noexcept
      52         340 :         : ws_(ws0)
      53         340 :         , head_(ws0.head_)
      54             :     {
      55         340 :     }
      56             : 
      57         340 :     ~undo()
      58         340 :     {
      59         340 :         if(head_)
      60           0 :             ws_.head_ = head_;
      61         340 :     }
      62             : 
      63             :     void
      64         340 :     commit() noexcept
      65             :     {
      66         340 :         head_ = nullptr;
      67         340 :     }
      68             : 
      69             : private:
      70             :     workspace& ws_;
      71             :     unsigned char* head_;
      72             : };
      73             : 
      74             : template<class T>
      75             : constexpr
      76             : std::size_t
      77             : workspace::
      78             : space_needed()
      79             : {
      80             :     using U = typename std::decay<T>::type;
      81             : 
      82             :     static_assert(
      83             :         alignof(U) <= alignof(::max_align_t),
      84             :         "Overaligned types not supported");
      85             : 
      86             :     return sizeof(any_impl<U>);
      87             : }
      88             : 
      89             : template<class T>
      90             : auto
      91         314 : workspace::
      92             : push(T&& t) ->
      93             :     typename std::decay<T>::type&
      94             : {
      95             :     static_assert(
      96             :         alignof(T) <= alignof(::max_align_t),
      97             :         "Overaligned types not supported");
      98             : 
      99             :     using U = any_impl<typename
     100             :         std::decay<T>::type>;
     101             : 
     102         314 :     undo u(*this);
     103         314 :     auto p = ::new(bump_down(
     104             :         sizeof(U), alignof(U))) U(
     105         314 :             std::forward<T>(t));
     106         314 :     u.commit();
     107         314 :     p->next = reinterpret_cast<
     108         314 :         any*>(head_);
     109         314 :     head_ = reinterpret_cast<
     110             :         unsigned char*>(p);
     111         628 :     return p->u;
     112             : }
     113             : 
     114             : template<class T>
     115             : T*
     116          26 : workspace::
     117             : push_array(
     118             :     std::size_t n,
     119             :     T const& t)
     120             : {
     121             :     struct alignas(alignof(::max_align_t))
     122          26 :         U : any
     123             :     {
     124             :         std::size_t n_ = 0;
     125             : 
     126             :         U() = default;
     127          26 :         ~U()
     128             :         {
     129          78 :             for(std::size_t i = n_;
     130          78 :                     i-- > 0;)
     131          52 :                 data()[i].~T();
     132          52 :         }
     133             : 
     134          26 :         U(  std::size_t n,
     135             :             T const& t)
     136          26 :             : U()
     137             :         {
     138          78 :             while(n_ < n)
     139             :             {
     140          52 :                 new(&data()[n_]) T(t);
     141          52 :                 ++n_;
     142             :             }
     143          26 :         }
     144             : 
     145         130 :         T* data() noexcept
     146             :         {
     147             :             return reinterpret_cast<
     148         130 :                 T*>(this + 1);
     149             :         }
     150             :     };
     151             : 
     152          52 :     undo u(*this);
     153          26 :     auto p = ::new(bump_down(
     154          26 :         sizeof(U) + n * sizeof(T),
     155             :             alignof(::max_align_t))) U(n, t);
     156          26 :     u.commit();
     157          26 :     p->next = reinterpret_cast<
     158          26 :         any*>(head_);
     159          26 :     head_ = reinterpret_cast<
     160             :         unsigned char*>(p);
     161          52 :     return p->data();
     162             : }
     163             : 
     164             : #if defined(BOOST_MSVC)
     165             : #pragma warning(pop) /* C4324 */
     166             : #endif
     167             : 
     168             : } // detail
     169             : } // http_proto
     170             : } // boost
     171             : 
     172             : #endif

Generated by: LCOV version 1.15