LCOV - code coverage report
Current view: top level - http_proto/detail - workspace.hpp (source / functions) Hit Total Coverage
Test: coverage_filtered.info Lines: 37 37 100.0 %
Date: 2023-01-26 23:44:13 Functions: 23 25 92.0 %

          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_WORKSPACE_HPP
      11             : #define BOOST_HTTP_PROTO_DETAIL_WORKSPACE_HPP
      12             : 
      13             : #include <boost/http_proto/detail/except.hpp>
      14             : #include <boost/assert.hpp>
      15             : #include <cstdlib>
      16             : #include <new>
      17             : #include <utility>
      18             : #include <stddef.h> // ::max_align_t
      19             : 
      20             : namespace boost {
      21             : namespace http_proto {
      22             : namespace detail {
      23             : 
      24             : class workspace
      25             : {
      26          37 :     struct any
      27             :     {
      28             :         any* next = nullptr;
      29             : 
      30             :         BOOST_HTTP_PROTO_DECL
      31             :         virtual ~any() = 0;
      32             :     };
      33             : 
      34             :     unsigned char* begin_ = nullptr;
      35             :     unsigned char* end_;
      36             :     unsigned char* head_;
      37             : 
      38             : public:
      39             :     ~workspace();
      40             : 
      41         744 :     workspace() = default;
      42             :     workspace(workspace&&) noexcept;
      43             :     workspace& operator=(
      44             :         workspace&&) noexcept;
      45             : 
      46             :     explicit
      47             :     workspace(
      48             :         std::size_t n);
      49             : 
      50             :     void*
      51        7523 :     data() noexcept
      52             :     {
      53        7523 :         return begin_;
      54             :     }
      55             : 
      56             :     std::size_t
      57          14 :     size() const noexcept
      58             :     {
      59          14 :         return head_ - begin_;
      60             :     }
      61             : 
      62             :     BOOST_HTTP_PROTO_DECL
      63             :     void
      64             :     clear() noexcept;
      65             : 
      66             :     BOOST_HTTP_PROTO_DECL
      67             :     void*
      68             :     reserve(std::size_t n);
      69             : 
      70             :     template<class T>
      71             :     auto
      72             :     push(T&& t) ->
      73             :         typename std::decay<T>::type&;
      74             : 
      75             :     template<class T>
      76             :     T*
      77             :     push_array(
      78             :         std::size_t n,
      79             :         T const& t);
      80             : 
      81             : private:
      82             :     BOOST_HTTP_PROTO_DECL
      83             :     void*
      84             :     bump_down(
      85             :         std::size_t size,
      86             :         std::size_t align);
      87             : };
      88             : 
      89             : template<class T>
      90             : auto
      91          13 : workspace::
      92             : push(T&& t) ->
      93             :     typename std::decay<T>::type&
      94             : {
      95             :     struct alignas(alignof(::max_align_t))
      96             :         U : any
      97             :     {
      98             :         typename std::decay<T>::type v_;
      99             : 
     100             :         U() = delete;
     101             :         U(U&&) = default;
     102             : 
     103          13 :         explicit U(T&& t)
     104          13 :             : v_(std::move(t))
     105             :         {
     106          13 :         }
     107             :     };
     108             : 
     109          13 :     auto p = ::new(bump_down(
     110             :         sizeof(U), alignof(U))) U(
     111          13 :             std::forward<T>(t));
     112          13 :     p->next = reinterpret_cast<
     113          13 :         any*>(head_);
     114          13 :     head_ = reinterpret_cast<
     115             :         unsigned char*>(p);
     116          13 :     return p->v_;
     117             : }
     118             : 
     119             : template<class T>
     120             : T*
     121          24 : workspace::
     122             : push_array(
     123             :     std::size_t n,
     124             :     T const& t)
     125             : {
     126             :     struct alignas(alignof(::max_align_t))
     127          24 :         U : any
     128             :     {
     129             :         std::size_t n_ = 0;
     130             : 
     131             :         U() = default;
     132          24 :         ~U()
     133             :         {
     134          70 :             for(std::size_t i = n_;
     135          70 :                     i-- > 0;)
     136          46 :                 data()[i].~T();
     137          48 :         }
     138             : 
     139          24 :         U(  std::size_t n,
     140             :             T const& t)
     141          24 :             : U()
     142             :         {
     143          70 :             while(n_ < n)
     144             :             {
     145          46 :                 new(&data()[n_]) T(t);
     146          46 :                 ++n_;
     147             :             }
     148          24 :         }
     149             : 
     150         116 :         T* data() noexcept
     151             :         {
     152             :             return reinterpret_cast<
     153         116 :                 T*>(this + 1);
     154             :         }
     155             :     };
     156             : 
     157          24 :     auto p = ::new(bump_down(
     158          24 :         sizeof(U) + n * sizeof(T),
     159             :             alignof(::max_align_t))) U(n, t);
     160          24 :     p->next = reinterpret_cast<
     161          24 :         any*>(head_);
     162          24 :     head_ = reinterpret_cast<
     163             :         unsigned char*>(p);
     164          24 :     return p->data();
     165             : }
     166             : 
     167             : } // detail
     168             : } // http_proto
     169             : } // boost
     170             : 
     171             : #endif

Generated by: LCOV version 1.15