LCOV - code coverage report
Current view: top level - boost/http_proto/detail/impl/workspace.hpp (source / functions) Coverage Total Hit
Test: coverage_filtered.info Lines: 97.9 % 48 47
Test Date: 2024-06-29 21:11:41 Functions: 96.6 % 29 28

            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              : 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          394 :     explicit any_impl(Args&&... args)
      44          394 :         : u(std::forward<Args>(args)...)
      45              :     {
      46          394 :     }
      47              : };
      48              : 
      49              : struct workspace::undo
      50              : {
      51              :     explicit
      52          490 :     undo(workspace& ws0) noexcept
      53          490 :         : ws_(ws0)
      54          490 :         , head_(ws0.head_)
      55              :     {
      56          490 :     }
      57              : 
      58          490 :     ~undo()
      59              :     {
      60          490 :         if(head_)
      61            0 :             ws_.head_ = head_;
      62          490 :     }
      63              : 
      64              :     void
      65          490 :     commit() noexcept
      66              :     {
      67          490 :         head_ = nullptr;
      68          490 :     }
      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          394 : 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          394 :     undo u(*this);
     104          394 :     auto p = ::new(bump_down(
     105              :         sizeof(U), alignof(U))) U(
     106          394 :             std::forward<Args>(args)...);
     107          394 :     u.commit();
     108          394 :     p->next = reinterpret_cast<
     109          394 :         any*>(head_);
     110          394 :     head_ = reinterpret_cast<
     111              :         unsigned char*>(p);
     112          394 :     return p->u;
     113          394 : }
     114              : 
     115              : template<class T>
     116              : T*
     117           96 : workspace::
     118              : push_array(
     119              :     std::size_t n,
     120              :     T const& t)
     121              : {
     122              :     struct alignas(alignof(::max_align_t))
     123              :         U : any
     124              :     {
     125              :         std::size_t n_ = 0;
     126              : 
     127           96 :         U() = default;
     128           96 :         ~U()
     129              :         {
     130           96 :             for(std::size_t i = n_;
     131          782 :                     i-- > 0;)
     132          686 :                 data()[i].~T();
     133          192 :         }
     134              : 
     135           96 :         U(  std::size_t n,
     136              :             T const& t)
     137           96 :             : U()
     138              :         {
     139          782 :             while(n_ < n)
     140              :             {
     141          686 :                 new(&data()[n_]) T(t);
     142          686 :                 ++n_;
     143              :             }
     144           96 :         }
     145              : 
     146         1468 :         T* data() noexcept
     147              :         {
     148              :             return reinterpret_cast<
     149         1468 :                 T*>(this + 1);
     150              :         }
     151              :     };
     152              : 
     153           96 :     undo u(*this);
     154           96 :     auto p = ::new(bump_down(
     155           96 :         sizeof(U) + n * sizeof(T),
     156              :             alignof(::max_align_t))) U(n, t);
     157           96 :     u.commit();
     158           96 :     p->next = reinterpret_cast<
     159           96 :         any*>(head_);
     160           96 :     head_ = reinterpret_cast<
     161              :         unsigned char*>(p);
     162          192 :     return p->data();
     163           96 : }
     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 2.1