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-05-23 18:56:44 Functions: 96.3 % 27 26

            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 BOOST_HTTP_PROTO_DECL workspace::any
      25              : {
      26              :     any* next = nullptr;
      27              : 
      28              :     virtual ~any() = 0;
      29              : };
      30              : 
      31              : template<class U>
      32              : struct alignas(alignof(::max_align_t))
      33              :     workspace::any_impl : any
      34              : {
      35              :     U u;
      36              : 
      37              :     any_impl() = default;
      38              :     any_impl(any_impl const&) = delete;
      39              :     any_impl(any_impl&&) = delete;
      40              : 
      41              :     template<class... Args>
      42          314 :     explicit any_impl(Args&&... args)
      43          314 :         : u(std::forward<Args>(args)...)
      44              :     {
      45          314 :     }
      46              : };
      47              : 
      48              : struct workspace::undo
      49              : {
      50              :     explicit
      51          347 :     undo(workspace& ws0) noexcept
      52          347 :         : ws_(ws0)
      53          347 :         , head_(ws0.head_)
      54              :     {
      55          347 :     }
      56              : 
      57          347 :     ~undo()
      58              :     {
      59          347 :         if(head_)
      60            0 :             ws_.head_ = head_;
      61          347 :     }
      62              : 
      63              :     void
      64          347 :     commit() noexcept
      65              :     {
      66          347 :         head_ = nullptr;
      67          347 :     }
      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, class... Args>
      90              : auto
      91          314 : workspace::
      92              : emplace(Args&&... args) ->
      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<Args>(args)...);
     106          314 :     u.commit();
     107          314 :     p->next = reinterpret_cast<
     108          314 :         any*>(head_);
     109          314 :     head_ = reinterpret_cast<
     110              :         unsigned char*>(p);
     111          314 :     return p->u;
     112          314 : }
     113              : 
     114              : template<class T>
     115              : T*
     116           33 : workspace::
     117              : push_array(
     118              :     std::size_t n,
     119              :     T const& t)
     120              : {
     121              :     struct alignas(alignof(::max_align_t))
     122              :         U : any
     123              :     {
     124              :         std::size_t n_ = 0;
     125              : 
     126           33 :         U() = default;
     127           33 :         ~U()
     128              :         {
     129           33 :             for(std::size_t i = n_;
     130          106 :                     i-- > 0;)
     131           73 :                 data()[i].~T();
     132           66 :         }
     133              : 
     134           33 :         U(  std::size_t n,
     135              :             T const& t)
     136           33 :             : U()
     137              :         {
     138          106 :             while(n_ < n)
     139              :             {
     140           73 :                 new(&data()[n_]) T(t);
     141           73 :                 ++n_;
     142              :             }
     143           33 :         }
     144              : 
     145          179 :         T* data() noexcept
     146              :         {
     147              :             return reinterpret_cast<
     148          179 :                 T*>(this + 1);
     149              :         }
     150              :     };
     151              : 
     152           33 :     undo u(*this);
     153           33 :     auto p = ::new(bump_down(
     154           33 :         sizeof(U) + n * sizeof(T),
     155              :             alignof(::max_align_t))) U(n, t);
     156           33 :     u.commit();
     157           33 :     p->next = reinterpret_cast<
     158           33 :         any*>(head_);
     159           33 :     head_ = reinterpret_cast<
     160              :         unsigned char*>(p);
     161           66 :     return p->data();
     162           33 : }
     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 2.1