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-04-23 20:44:52 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         347 : 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 const&) = delete;
      40             :     any_impl(any_impl&&) = delete;
      41             : 
      42             :     template<class... Args>
      43         314 :     explicit any_impl(Args&&... args)
      44         314 :         : u(std::forward<Args>(args)...)
      45             :     {
      46         314 :     }
      47             : };
      48             : 
      49             : struct workspace::undo
      50             : {
      51             :     explicit
      52         347 :     undo(workspace& ws0) noexcept
      53         347 :         : ws_(ws0)
      54         347 :         , head_(ws0.head_)
      55             :     {
      56         347 :     }
      57             : 
      58         347 :     ~undo()
      59         347 :     {
      60         347 :         if(head_)
      61           0 :             ws_.head_ = head_;
      62         347 :     }
      63             : 
      64             :     void
      65         347 :     commit() noexcept
      66             :     {
      67         347 :         head_ = nullptr;
      68         347 :     }
      69             : 
      70             : private:
      71             :     workspace& ws_;
      72             :     unsigned char* head_;
      73             : };
      74             : 
      75             : template<class T>
      76             : constexpr
      77             : std::size_t
      78             : workspace::
      79             : space_needed()
      80             : {
      81             :     using U = typename std::decay<T>::type;
      82             : 
      83             :     static_assert(
      84             :         alignof(U) <= alignof(::max_align_t),
      85             :         "Overaligned types not supported");
      86             : 
      87             :     return sizeof(any_impl<U>);
      88             : }
      89             : 
      90             : template<class T, class... Args>
      91             : auto
      92         314 : workspace::
      93             : emplace(Args&&... args) ->
      94             :     typename std::decay<T>::type&
      95             : {
      96             :     static_assert(
      97             :         alignof(T) <= alignof(::max_align_t),
      98             :         "Overaligned types not supported");
      99             : 
     100             :     using U = any_impl<typename
     101             :         std::decay<T>::type>;
     102             : 
     103         314 :     undo u(*this);
     104         314 :     auto p = ::new(bump_down(
     105             :         sizeof(U), alignof(U))) U(
     106         314 :             std::forward<Args>(args)...);
     107         314 :     u.commit();
     108         314 :     p->next = reinterpret_cast<
     109         314 :         any*>(head_);
     110         314 :     head_ = reinterpret_cast<
     111             :         unsigned char*>(p);
     112         628 :     return p->u;
     113             : }
     114             : 
     115             : template<class T>
     116             : T*
     117          33 : workspace::
     118             : push_array(
     119             :     std::size_t n,
     120             :     T const& t)
     121             : {
     122             :     struct alignas(alignof(::max_align_t))
     123          33 :         U : any
     124             :     {
     125             :         std::size_t n_ = 0;
     126             : 
     127             :         U() = default;
     128          33 :         ~U()
     129             :         {
     130         106 :             for(std::size_t i = n_;
     131         106 :                     i-- > 0;)
     132          73 :                 data()[i].~T();
     133          66 :         }
     134             : 
     135          33 :         U(  std::size_t n,
     136             :             T const& t)
     137          33 :             : U()
     138             :         {
     139         106 :             while(n_ < n)
     140             :             {
     141          73 :                 new(&data()[n_]) T(t);
     142          73 :                 ++n_;
     143             :             }
     144          33 :         }
     145             : 
     146         179 :         T* data() noexcept
     147             :         {
     148             :             return reinterpret_cast<
     149         179 :                 T*>(this + 1);
     150             :         }
     151             :     };
     152             : 
     153          66 :     undo u(*this);
     154          33 :     auto p = ::new(bump_down(
     155          33 :         sizeof(U) + n * sizeof(T),
     156             :             alignof(::max_align_t))) U(n, t);
     157          33 :     u.commit();
     158          33 :     p->next = reinterpret_cast<
     159          33 :         any*>(head_);
     160          33 :     head_ = reinterpret_cast<
     161             :         unsigned char*>(p);
     162          66 :     return p->data();
     163             : }
     164             : 
     165             : #if defined(BOOST_MSVC)
     166             : #pragma warning(pop) /* C4324 */
     167             : #endif
     168             : 
     169             : } // detail
     170             : } // http_proto
     171             : } // boost
     172             : 
     173             : #endif

Generated by: LCOV version 1.15