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-09-20 16:11:51 Functions: 90.9 % 33 30

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