LCOV - code coverage report
Current view: top level - boost/beast2/server/fixed_array.hpp (source / functions) Coverage Total Hit
Test: coverage_filtered.info Lines: 0.0 % 29 0
Test Date: 2025-11-13 15:50:43 Functions: 0.0 % 8 0

            Line data    Source code
       1              : //
       2              : // Copyright (c) 2022 Vinnie Falco (vinnie dot falco at gmail dot 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/beast2
       8              : //
       9              : 
      10              : #ifndef BOOST_BEAST2_SERVER_FIXED_ARRAY_HPP
      11              : #define BOOST_BEAST2_SERVER_FIXED_ARRAY_HPP
      12              : 
      13              : #include <boost/beast2/detail/config.hpp>
      14              : #include <boost/core/span.hpp>
      15              : #include <boost/assert.hpp>
      16              : #include <cstddef>
      17              : #include <cstdlib>
      18              : #include <memory>
      19              : #include <new>
      20              : #include <stdexcept>
      21              : #include <utility>
      22              : 
      23              : template<class T>
      24              : class fixed_array;
      25              : 
      26              : /** A type-erased fixed_array
      27              : */
      28              : class any_fixed_array
      29              : {
      30              : public:
      31              :     /** Destructor
      32              : 
      33              :         All elements are destroyed in reverse order.
      34              :     */
      35              :     ~any_fixed_array()
      36              :     {
      37              :         if(t_)
      38              :             destroy_(this);
      39              :     }
      40              : 
      41              :     /** Constructor
      42              :     */
      43              :     any_fixed_array() = default;
      44              : 
      45              :     /** Constructor
      46              : 
      47              :         Ownership of all elements in the moved-from object is transferred.
      48              :     */
      49              :     any_fixed_array(
      50              :         any_fixed_array&& other) noexcept
      51              :         : any_fixed_array()
      52              :     {
      53              :         swap(*this, other);
      54              :     }
      55              : 
      56              :     /** Constructor
      57              : 
      58              :         Ownership of all elements in the moved-from object is transferred.
      59              : 
      60              :         @par Postconditions
      61              :         @code
      62              :         other.size() == 0 && other.capacity() == 0
      63              :         @endcode
      64              :     */
      65              :     template<class T>
      66              :     any_fixed_array(
      67              :         fixed_array<T>&& other) noexcept
      68              :         : t_(other.t_)
      69              :         , n_(other.n_)
      70              :         , cap_(other.cap_)
      71              :         , destroy_(&destroy<T>)
      72              :     {
      73              :         other.t_ = nullptr;
      74              :         other.n_ = 0;
      75              :         other.cap_ = 0;
      76              :     }
      77              : 
      78              :     /** Constructor
      79              : 
      80              :         Ownership of all elements in the moved-from object is transferred.
      81              : 
      82              :         @par Postconditions
      83              :         @code
      84              :         other.size() == 0 && other.capacity() == 0
      85              :         @endcode
      86              :     */
      87              :     any_fixed_array&
      88              :     operator=(
      89              :         any_fixed_array&& other) noexcept
      90              :     {
      91              :         any_fixed_array temp;
      92              :         swap(*this, temp);
      93              :         swap(other, *this);
      94              :         return *this;
      95              :     }
      96              : 
      97              :     /** Return the number of elements
      98              :     */
      99              :     std::size_t size() const noexcept
     100              :     {
     101              :         return n_;
     102              :     }
     103              : 
     104              :     /** Return a typed span of elements
     105              : 
     106              :         This function returns the span of elements contained in the array.
     107              :         The specified type `T` must match the type of element used
     108              :         to construct the array, or else the behavior is undefined.
     109              : 
     110              :         @tparam T The type of element used to construct the array.
     111              :     */
     112              :     template<class T>
     113              :     boost::span<T>
     114              :     to_span() noexcept
     115              :     {
     116              :         return { reinterpret_cast<T*>(t_), n_ };
     117              :     }
     118              : 
     119              :     /** Swap objects
     120              :     */
     121              :     friend void swap(
     122              :         any_fixed_array& a0,
     123              :         any_fixed_array& a1) noexcept
     124              :     {
     125              :         std::swap(a0.t_, a1.t_);
     126              :         std::swap(a0.n_, a1.n_);
     127              :         std::swap(a0.cap_, a1.cap_);
     128              :         std::swap(a0.destroy_, a1.destroy_);
     129              :     }
     130              : 
     131              : private:
     132              :     template<class T>
     133              :     friend class fixed_array;
     134              : 
     135              :     template<class T>
     136              :     static void destroy(any_fixed_array* p)
     137              :     {
     138              :         fixed_array<T> v(*p);
     139              :     }
     140              : 
     141              :     void* t_ = nullptr;
     142              :     std::size_t n_ = 0;
     143              :     std::size_t cap_ = 0;
     144              :     void(*destroy_)(any_fixed_array*) = 0;
     145              : };
     146              : 
     147              : //------------------------------------------------
     148              : 
     149              : /** An append-only array with a fixed capacity
     150              : 
     151              :     This container is used to hold elements which
     152              :     are all constructed at once, where the elements
     153              :     do not require move constructability or assignability.
     154              : */
     155              : template<class T>
     156              : class fixed_array
     157              : {
     158              : public:
     159              :     using value_type = T;
     160              :     using reference = T&;
     161              :     using pointer = T*;
     162              :     using iterator = T*;
     163              :     using const_reference = T const&;
     164              :     using const_pointer = T const*;
     165              :     using const_iterator = T const*;
     166              :     using difference_type = std::ptrdiff_t;
     167              :     using size_type = std::size_t;
     168              : 
     169            0 :     ~fixed_array()
     170              :     {
     171            0 :         if(! t_)
     172            0 :             return;
     173            0 :         while(n_--)
     174            0 :             t_[n_].~T();
     175            0 :         std::allocator<T>{}.deallocate(t_, cap_);
     176            0 :     }
     177              : 
     178              :     /** Constructor
     179              : 
     180              :         The moved-from object will have zero
     181              :         capacity and zero size.
     182              :     */
     183              :     fixed_array(fixed_array&& other) noexcept
     184              :     {
     185              :         t_ = other.t_;
     186              :         n_ = other.n_;
     187              :         cap_ = other.cap_;
     188              :         other.t_ = nullptr;
     189              :         other.n_ = 0;
     190              :         other.cap_ = 0;
     191              :     }
     192              : 
     193              :     /** Constructor
     194              : 
     195              :         The array will have the specified capacity.
     196              : 
     197              :         @par Postconditions
     198              :         ```
     199              :         size() == 0 &&  capacity() == cap
     200              :         ```
     201              :     */
     202              :     explicit
     203            0 :     fixed_array(std::size_t cap)
     204            0 :         : t_(std::allocator<T>{}.allocate(cap))
     205            0 :         , n_(0)
     206            0 :         , cap_(cap)
     207              :     {
     208            0 :     }
     209              : 
     210              :     std::size_t
     211              :     capacity() const noexcept
     212              :     {
     213              :         return cap_;
     214              :     }
     215              : 
     216              :     std::size_t
     217            0 :     size() const noexcept
     218              :     {
     219            0 :         return n_;
     220              :     }
     221              : 
     222              :     bool
     223            0 :     is_full() const noexcept
     224              :     {
     225            0 :         return n_ >= cap_;
     226              :     }
     227              : 
     228              :     /** Return a pointer to the beginning of the array
     229              :     */
     230            0 :     T* data() noexcept
     231              :     {
     232            0 :         return t_;
     233              :     }
     234              : 
     235              :     /** Return a pointer to the beginning of the array
     236              :     */
     237              :     T const* data() const noexcept
     238              :     {
     239              :         return t_;
     240              :     }   
     241              : 
     242              :     reference operator[](std::size_t i)
     243              :     {
     244              :         BOOST_ASSERT(i < n_);
     245              :         return t_[i];
     246              :     }
     247              : 
     248              :     const_reference operator[](std::size_t i) const
     249              :     {
     250              :         BOOST_ASSERT(i < n_);
     251              :         return t_[i];
     252              :     }
     253              : 
     254              :     reference at(std::size_t i)
     255              :     {
     256              :         if(i < n_)
     257              :             return t_[i];
     258              :         // VFALCO use detail::throw_out_of_range when it is available
     259              :         throw std::out_of_range("i >= size()");
     260              :     }
     261              : 
     262              :     const_reference at(std::size_t i) const
     263              :     {
     264              :         if(i < n_)
     265              :             return t_[i];
     266              :         // VFALCO use detail::throw_out_of_range when it is available
     267              :         throw std::out_of_range("i >= size()");
     268              :     }
     269              : 
     270              :     template<class... Args>
     271            0 :     T& emplace_back(Args&&... args)
     272              :     {
     273            0 :         if(is_full())
     274              :             // VFALCO use detail::throw_out_of_range when it is available
     275            0 :             throw std::out_of_range("full");
     276            0 :         auto p = t_ + n_;
     277            0 :         ::new(p) T(std::forward<Args>(args)...);
     278            0 :         ++n_;
     279            0 :         return *p;
     280              :     }
     281              : 
     282              :     const_iterator
     283              :     begin() const noexcept
     284              :     {
     285              :         return t_;
     286              :     }
     287              : 
     288              :     const_iterator
     289              :     end() const noexcept
     290              :     {
     291              :         return t_ + n_;
     292              :     }
     293              : 
     294              :     iterator
     295            0 :     begin() noexcept
     296              :     {
     297            0 :         return t_;
     298              :     }
     299              : 
     300              :     iterator
     301            0 :     end() noexcept
     302              :     {
     303            0 :         return t_ + n_;
     304              :     }
     305              : 
     306              : private:
     307              : #if 0
     308              : //#if __cplusplus < 201703L // gcc nonconforming
     309              :     static_assert(
     310              :         alignof(T) <=
     311              :             alignof(std::max_align_t),
     312              :         "T must not be overaligned");
     313              : //#endif
     314              : #endif
     315              : 
     316              :     friend class any_fixed_array;
     317              : 
     318              :     fixed_array(
     319              :         any_fixed_array& v) noexcept
     320              :         : t_(reinterpret_cast<T*>(v.t_))
     321              :         , n_(v.n_)
     322              :         , cap_(v.cap_)
     323              :     {
     324              :     }
     325              : 
     326              :     T* t_ = nullptr;
     327              :     std::size_t n_;
     328              :     std::size_t cap_;
     329              : };
     330              : 
     331              : #endif
        

Generated by: LCOV version 2.1