Matter SDK Coverage Report
Current view: top level - lib/support - FixedBuffer.h (source / functions) Coverage Total Hit
Test: SHA:4a1dff731dfd17f3623faad23ee07f07df60cba7 Lines: 97.2 % 106 103
Test Date: 2026-02-11 08:13:42 Functions: 100.0 % 72 72

            Line data    Source code
       1              : /*
       2              :  *
       3              :  *    Copyright (c) 2026 Project CHIP Authors
       4              :  *
       5              :  *    Licensed under the Apache License, Version 2.0 (the "License");
       6              :  *    you may not use this file except in compliance with the License.
       7              :  *    You may obtain a copy of the License at
       8              :  *
       9              :  *        http://www.apache.org/licenses/LICENSE-2.0
      10              :  *
      11              :  *    Unless required by applicable law or agreed to in writing, software
      12              :  *    distributed under the License is distributed on an "AS IS" BASIS,
      13              :  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      14              :  *    See the License for the specific language governing permissions and
      15              :  *    limitations under the License.
      16              :  */
      17              : 
      18              : #pragma once
      19              : 
      20              : #include <algorithm>
      21              : #include <array>
      22              : #include <cstddef>
      23              : #include <cstdint>
      24              : #include <cstdlib>
      25              : #include <cstring>
      26              : #include <iterator>
      27              : #include <limits>
      28              : #include <type_traits>
      29              : 
      30              : #include <lib/support/Span.h>
      31              : 
      32              : namespace chip {
      33              : 
      34              : /**
      35              :  *  @brief
      36              :  *    A fixed-capacity, size-tracked buffer container.
      37              :  *
      38              :  *  This provides a lightweight container abstraction for the common
      39              :  *  pattern of a fixed-size backing array paired with a logical length
      40              :  *  (that is, count or size). The container never allocates, never
      41              :  *  grows beyond its compile-time capacity, and supports efficient
      42              :  *  assignment/appending from raw memory.
      43              :  *
      44              :  *  The container models a "logical (used) prefix" of the backing
      45              :  *  storage:
      46              :  *
      47              :  *    * The backing store is always @p N elements.
      48              :  *    * The logical size is tracked in @p mSize and is always in the
      49              :  *      range [0, N].
      50              :  *    * Iteration and comparisons operate on the logical (used)
      51              :  *      portion.
      52              :  *
      53              :  *  Operations that may fail (e.g. assign/append/resize) return @c
      54              :  *  bool and do not modify the logical size on failure.
      55              :  *
      56              :  *  @tparam T
      57              :  *    The element type stored in the backing array.
      58              :  *
      59              :  *  @tparam N
      60              :  *    The fixed element capacity of the buffer.
      61              :  *
      62              :  *  @tparam SizeT
      63              :  *    An integral type used to represent the logical size. This may be
      64              :  *    selected smaller than @c std::size_t (e.g. @c uint8_t) to reduce
      65              :  *    object footprint.
      66              :  *
      67              :  */
      68              : template <typename T, std::size_t N, typename SizeT = std::size_t>
      69              : class FixedBuffer
      70              : {
      71              :     static_assert(N > 0, "FixedBuffer capacity must be > 0");
      72              :     static_assert(std::is_unsigned<SizeT>::value, "FixedBuffer size type must be an unsigned type");
      73              : 
      74              : public:
      75              :     using value_type             = T;
      76              :     using size_type              = SizeT;
      77              :     using difference_type        = std::ptrdiff_t;
      78              :     using reference              = value_type &;
      79              :     using const_reference        = const value_type &;
      80              :     using pointer                = value_type *;
      81              :     using const_pointer          = const value_type *;
      82              :     using iterator               = pointer;
      83              :     using const_iterator         = const_pointer;
      84              :     using reverse_iterator       = std::reverse_iterator<iterator>;
      85              :     using const_reverse_iterator = std::reverse_iterator<const_iterator>;
      86              : 
      87              :     /**
      88              :      *  Mutable and immutable views over the fixed buffer logical
      89              :      *  (used) prefix size.
      90              :      */
      91              :     using span_type       = Span<value_type>;
      92              :     using const_span_type = Span<const value_type>;
      93              : 
      94              :     /**
      95              :      *  Mutable and immutable views over the fixed buffer capacity
      96              :      *  size.
      97              :      */
      98              :     using fixed_span_type       = FixedSpan<value_type, N>;
      99              :     using const_fixed_span_type = FixedSpan<const value_type, N>;
     100              : 
     101              : public:
     102              :     // Construction
     103              : 
     104           21 :     FixedBuffer(void) noexcept : mData{}, mSize(0) {}
     105           17 :     FixedBuffer(const std::initializer_list<value_type> & inData) noexcept : mData{}, mSize(0)
     106              :     {
     107              :         // assign will return false if @a inData.begin() is null, @a
     108              :         // inData.size() is zero (0) or greater than the number of
     109              :         // allowed elements, or if @a inData.size() exceeds the
     110              :         // maximum representable size for this buffer's @c size_type.
     111              :         //
     112              :         // Since this is a constructor and is marked 'noexcept', there
     113              :         // is no error status that can be returned or thrown;
     114              :         // likewise, to avoid propagating project-internal assertion
     115              :         // macros into integrating projects or products, we elide the
     116              :         // return status.
     117              : 
     118           17 :         (void) assign(inData.begin(), inData.size());
     119           17 :     }
     120              : 
     121            2 :     FixedBuffer(const value_type * inData, const std::size_t & inSize) noexcept : mData{}, mSize(0)
     122              :     {
     123              :         // assign will return false if @a inData is null, @a inSzie is
     124              :         // zero (0) or greater than the number of allowed elements, or
     125              :         // if @a inSize exceeds the maximum representable size for
     126              :         // this buffer's @c size_type.
     127              :         //
     128              :         // Since this is a constructor and is marked 'noexcept', there
     129              :         // is no error status that can be returned or thrown;
     130              :         // likewise, to avoid propagating project-internal assertion
     131              :         // macros into integrating projects or products, we elide the
     132              :         // return status.
     133              : 
     134            2 :         (void) assign(inData, inSize);
     135            2 :     }
     136              : 
     137            1 :     FixedBuffer(const FixedBuffer & inFixedBuffer) noexcept : mData{}, mSize(0)
     138              :     {
     139              :         // assign will return false if @a inFixedBuffer.begin() is null, @a
     140              :         // inFixedBuffer.size() is zero (0) or greater than the number of
     141              :         // allowed elements, or if @a inFixedBuffer.size() exceeds the
     142              :         // maximum representable size for this buffer's @c size_type.
     143              :         //
     144              :         // Since this is a constructor and is marked 'noexcept', there
     145              :         // is no error status that can be returned or thrown;
     146              :         // likewise, to avoid propagating project-internal assertion
     147              :         // macros into integrating projects or products, we elide the
     148              :         // return status.
     149              : 
     150            1 :         (void) assign(inFixedBuffer.data(), static_cast<std::size_t>(inFixedBuffer.size()));
     151            1 :     }
     152              : 
     153            9 :     FixedBuffer(const const_span_type & inSpan) noexcept : mData{}, mSize(0)
     154              :     {
     155              :         // assign will return false if @a inSpan.data() is null and @a
     156              :         // inSpan.size() != 0, if @a inSpan.size() > capacity(), or if
     157              :         // @a inSpan.size() exceeds the maximum representable size for
     158              :         // this buffer's @c size_type.
     159              :         //
     160              :         // Since this is a constructor and is marked 'noexcept', there
     161              :         // is no error status that can be returned or thrown;
     162              :         // likewise, to avoid propagating project-internal assertion
     163              :         // macros into integrating projects or products, we elide the
     164              :         // return status.
     165              : 
     166            9 :         (void) assign(inSpan);
     167            9 :     }
     168              : 
     169              :     // Destruction
     170              : 
     171              :     ~FixedBuffer(void) noexcept = default;
     172              : 
     173              :     // Assignment
     174              : 
     175            1 :     FixedBuffer & operator=(const std::initializer_list<value_type> & inData) noexcept
     176              :     {
     177              :         // assign will return false if @a inData.begin() is null, @a
     178              :         // inData.size() is zero (0) or greater than the number of
     179              :         // allowed elements, or if @a inData.size() exceeds the
     180              :         // maximum representable size for this buffer's @c size_type.
     181              :         //
     182              :         // Since this is an assignment operator and is marked
     183              :         // 'noexcept', there is no error status that can be returned
     184              :         // or thrown; likewise, to avoid propagating project-internal
     185              :         // assertion macros into integrating projects or products, we
     186              :         // elide the return status.
     187              : 
     188            1 :         (void) assign(inData.begin(), inData.size());
     189              : 
     190            1 :         return *this;
     191              :     }
     192              : 
     193            1 :     FixedBuffer & operator=(const FixedBuffer & inFixedBuffer) noexcept
     194              :     {
     195            1 :         if (this != &inFixedBuffer)
     196              :         {
     197              :             // assign will return false if @a inFixedBuffer.begin() is
     198              :             // null, @a inFixedBuffer.size() is zero (0) or greater
     199              :             // than the number of allowed elements, or if @a
     200              :             // inFixedBuffer.size() exceeds the maximum representable
     201              :             // size for this buffer's @c size_type.
     202              :             //
     203              :             // Since this is an assignment operator and is marked
     204              :             // 'noexcept', there is no error status that can be
     205              :             // returned or thrown; likewise, to avoid propagating
     206              :             // project-internal assertion macros into integrating
     207              :             // projects or products, we elide the return status.
     208              : 
     209            1 :             (void) assign(inFixedBuffer.data(), static_cast<std::size_t>(inFixedBuffer.size()));
     210              :         }
     211              : 
     212            1 :         return *this;
     213              :     }
     214              : 
     215            1 :     FixedBuffer & operator=(const const_span_type & inSpan) noexcept
     216              :     {
     217              :         // assign will return false if @a inSpan.data() is null and @a
     218              :         // inSpan.size() != 0, if @a inSpan.size() > capacity(), or if
     219              :         // @a inSpan.size() exceeds the maximum representable size for
     220              :         // this buffer's @c size_type.
     221              :         //
     222              :         // Since this is an assignment operator and is marked
     223              :         // 'noexcept', there is no error status that can be returned
     224              :         // or thrown; likewise, to avoid propagating project-internal
     225              :         // assertion macros into integrating projects or products, we
     226              :         // elide the return status.
     227              : 
     228            1 :         (void) assign(inSpan);
     229              : 
     230            1 :         return *this;
     231              :     }
     232              : 
     233              :     // Introspection
     234              : 
     235            8 :     bool empty(void) const noexcept { return (mSize == 0); }
     236              : 
     237            8 :     bool full(void) const noexcept { return (mSize == capacity()); }
     238              : 
     239              :     // Equality
     240              : 
     241           12 :     bool operator==(const FixedBuffer & inFixedBuffer) const noexcept
     242              :     {
     243           12 :         if (mSize != inFixedBuffer.mSize)
     244              :         {
     245            2 :             return false;
     246              :         }
     247              :         else
     248              :         {
     249           10 :             const std::size_t lSize = static_cast<std::size_t>(mSize);
     250              : 
     251           10 :             if (lSize == 0)
     252              :             {
     253            2 :                 return true;
     254              :             }
     255              :             else if constexpr (std::is_trivially_copyable<value_type>::value)
     256              :             {
     257            8 :                 return memcmp(mData.data(), inFixedBuffer.mData.data(), lSize * sizeof(value_type)) == 0;
     258              :             }
     259              :             else
     260              :             {
     261              :                 return std::equal(begin(), end(), inFixedBuffer.begin());
     262              :             }
     263              :         }
     264              :     }
     265              : 
     266           24 :     bool operator==(const const_span_type & inSpan) const noexcept
     267              :     {
     268           24 :         if (static_cast<std::size_t>(mSize) != inSpan.size())
     269              :         {
     270            4 :             return false;
     271              :         }
     272              :         else
     273              :         {
     274           20 :             const std::size_t lSize = inSpan.size();
     275              : 
     276           20 :             if (lSize == 0)
     277              :             {
     278            4 :                 return true;
     279              :             }
     280              :             else if constexpr (std::is_trivially_copyable<value_type>::value)
     281              :             {
     282           16 :                 return memcmp(mData.data(), inSpan.data(), lSize * sizeof(value_type)) == 0;
     283              :             }
     284              :             else
     285              :             {
     286              :                 return std::equal(begin(), end(), inSpan.begin());
     287              :             }
     288              :         }
     289              :     }
     290              : 
     291            6 :     bool operator!=(const FixedBuffer & inFixedBuffer) const noexcept { return !(*this == inFixedBuffer); }
     292           12 :     bool operator!=(const const_span_type & inSpan) const noexcept { return !(*this == inSpan); }
     293              : 
     294              :     // Observation
     295              : 
     296            3 :     pointer at_ptr(const std::size_t & inPosition) noexcept
     297              :     {
     298            3 :         return (inPosition < static_cast<std::size_t>(mSize)) ? (mData.data() + inPosition) : nullptr;
     299              :     }
     300              : 
     301            1 :     const_pointer at_ptr(const std::size_t & inPosition) const noexcept
     302              :     {
     303            1 :         return (inPosition < static_cast<std::size_t>(mSize)) ? (mData.data() + inPosition) : nullptr;
     304              :     }
     305              : 
     306            4 :     size_type available(void) const noexcept { return capacity() - mSize; }
     307              : 
     308           21 :     static constexpr size_type capacity(void) noexcept { return static_cast<size_type>(N); }
     309              : 
     310           35 :     pointer data(void) noexcept { return mData.data(); }
     311              : 
     312           17 :     const_pointer data(void) const noexcept { return mData.data(); }
     313              : 
     314           10 :     reference operator[](const std::size_t & inPosition) noexcept { return mData[inPosition]; }
     315              : 
     316           74 :     const_reference operator[](const std::size_t & inPosition) const noexcept { return mData[inPosition]; }
     317              : 
     318           61 :     size_type size(void) const noexcept { return mSize; }
     319              : 
     320            3 :     span_type span(void) noexcept { return span_type(data(), static_cast<std::size_t>(size())); }
     321            2 :     const_span_type span(void) const noexcept { return const_span_type(data(), static_cast<std::size_t>(size())); }
     322              :     fixed_span_type fixed_span(void) noexcept { return fixed_span_type(mData); }
     323              :     const_fixed_span_type fixed_span(void) const noexcept { return const_fixed_span_type(mData); }
     324              : 
     325              :     // Mutation
     326              : 
     327              :     /**
     328              :      *  @brief
     329              :      *    Append span to the fixed buffer.
     330              :      *
     331              :      *  This attempts to append @a inSpan to the fixed buffer,
     332              :      *  starting at the tail.
     333              :      *
     334              :      *  @param[in]  inSpan
     335              :      *    A reference to the immutable span to append to the fixed
     336              :      *    buffer.
     337              :      *
     338              :      *  @returns
     339              :      *    True if the @a inSpan was successfully appended to this
     340              :      *    fixed buffer; otherwise, false if @a inSpan.data() was null,
     341              :      *    @a inSpan.size() was zero (0) or greater than the number of
     342              :      *    available elements, or if the current size plus @a
     343              :      *    inSpan.size() would exceed the maximum representable size
     344              :      *    for this buffer's @c size_type.
     345              :      *
     346              :      */
     347            4 :     bool append(const const_span_type & inSpan) noexcept { return append(inSpan.data(), inSpan.size()); }
     348              : 
     349              :     /**
     350              :      *  @brief
     351              :      *    Append elements to the fixed buffer.
     352              :      *
     353              :      *  This attempts to append @a inSize elements at @a inData to the
     354              :      *  fixed buffer, starting at the tail.
     355              :      *
     356              :      *  @param[in]  inData
     357              :      *    A pointer to the immutable elements to append to the fixed
     358              :      *    buffer.
     359              :      *
     360              :      *  @param[in]  inSize
     361              :      *    A reference to the immutable number of elements in @a inData
     362              :      *    to append to the fixed buffer.
     363              :      *
     364              :      *  @returns
     365              :      *    True if the @a inSize elements at @a inData were
     366              :      *    successfully appended to this fixed buffer; otherwise, false
     367              :      *    if @a inData was null, @a inSize was zero (0) or greater
     368              :      *    than the number of available elements, or if the current
     369              :      *    size plus @a inSize would exceed the maximum representable
     370              :      *    size for this buffer's @c size_type.
     371              :      *
     372              :      */
     373            9 :     bool append(const value_type * inData, const std::size_t & inSize) noexcept
     374              :     {
     375            9 :         const std::size_t lCurSize = static_cast<std::size_t>(mSize);
     376            9 :         const std::size_t lNewSize = lCurSize + inSize;
     377              : 
     378            9 :         if (inData == nullptr && inSize != 0)
     379              :         {
     380            1 :             return false;
     381              :         }
     382              : 
     383            8 :         if (inSize > (N - lCurSize))
     384              :         {
     385            2 :             return false;
     386              :         }
     387              : 
     388            6 :         if (lNewSize > static_cast<std::size_t>(std::numeric_limits<size_type>::max()))
     389              :         {
     390            0 :             return false;
     391              :         }
     392              : 
     393            6 :         if (inSize > 0)
     394              :         {
     395            6 :             memmove(mData.data() + lCurSize, inData, inSize * sizeof(value_type));
     396              :         }
     397              : 
     398            6 :         mSize = static_cast<size_type>(lNewSize);
     399              : 
     400            6 :         return true;
     401              :     }
     402              : 
     403              :     /**
     404              :      *  @brief
     405              :      *    Assign span to the fixed buffer.
     406              :      *
     407              :      *  This attempts to assign @a inSpan to the fixed buffer,
     408              :      *  starting at the head.
     409              :      *
     410              :      *  @param[in]  inSpan
     411              :      *    A reference to the immutable span to assign to the fixed
     412              :      *    buffer.
     413              :      *
     414              :      *  @returns
     415              :      *    True if the @a inSpan was successfully assigned to this
     416              :      *    fixed buffer; otherwise, false if @a inSpan.data() was null,
     417              :      *    @a inSpan.size() was zero (0) or greater than the number of
     418              :      *    allowed elements, or if @a inSpan.size() exceeds the maximum
     419              :      *    representable size for this buffer's @c size_type.
     420              :      *
     421              :      */
     422           19 :     bool assign(const const_span_type & inSpan) noexcept { return assign(inSpan.data(), inSpan.size()); }
     423              : 
     424              :     /**
     425              :      *  @brief
     426              :      *    Assign elements to the fixed buffer.
     427              :      *
     428              :      *  This attempts to assign @a inSize elements at @a inData to the
     429              :      *  fixed buffer, starting at the head.
     430              :      *
     431              :      *  @param[in]  inData
     432              :      *    A pointer to the immutable elements to assign to the fixed
     433              :      *    buffer.
     434              :      *
     435              :      *  @param[in]  inSize
     436              :      *    A reference to the immutable number of elements in @a inData
     437              :      *    to assign to the fixed buffer.
     438              :      *
     439              :      *  @returns
     440              :      *    True if the @a inSize elements at @a inData were
     441              :      *    successfully assigned to this fixed buffer; otherwise, false
     442              :      *    if @a inData was null, @a inSize was zero (0) or greater
     443              :      *    than the number of allowed elements, or if @a inSize exceeds
     444              :      *    the maximum representable size for this buffer's @c
     445              :      *    size_type.
     446              :      *
     447              :      */
     448           53 :     bool assign(const value_type * inData, const std::size_t & inSize) noexcept
     449              :     {
     450           53 :         if (inData == nullptr && inSize != 0)
     451              :         {
     452            1 :             return false;
     453              :         }
     454              : 
     455           52 :         if (inSize > N)
     456              :         {
     457            2 :             return false;
     458              :         }
     459              : 
     460           50 :         if (inSize > static_cast<std::size_t>(std::numeric_limits<size_type>::max()))
     461              :         {
     462            0 :             return false;
     463              :         }
     464              : 
     465           50 :         if (inSize > 0)
     466              :         {
     467           49 :             memmove(mData.data(), inData, inSize * sizeof(value_type));
     468              :         }
     469              : 
     470           50 :         mSize = static_cast<size_type>(inSize);
     471              : 
     472           50 :         return true;
     473              :     }
     474              : 
     475              :     /**
     476              :      *  @brief
     477              :      *    Remove all elements from the fixed buffer.
     478              :      *
     479              :      *  This removes all elements from the fixed buffer, resetting the
     480              :      *  size to zero (0) and invalidating all pointers, references,
     481              :      *  and iterators to the fixed buffer contents.
     482              :      *
     483              :      *  @sa fill
     484              :      *  @sa reset
     485              :      *
     486              :      */
     487            1 :     void clear(void) noexcept { mSize = 0; }
     488              : 
     489              :     /**
     490              :      *  @brief
     491              :      *    Assigns the specified value to all elements in the fixed
     492              :      *    buffer.
     493              :      *
     494              :      *  This assigns the specified value to all elements in the fixed
     495              :      *  buffer and sets the size to the fixed buffer capacity. Callers
     496              :      *  looking to do the same but @b without setting the size to
     497              :      *  capacity and instead setting the size to zero (0) should use
     498              :      *  #reset.
     499              :      *
     500              :      *  @param[in]  inValue
     501              :      *    A reference to the immutable value to assign to the elements
     502              :      *    of the fixed buffer.
     503              :      *
     504              :      *  @sa clear
     505              :      *  @sa reset
     506              :      *
     507              :      */
     508            5 :     void fill(const_reference inValue) noexcept
     509              :     {
     510            5 :         mData.fill(inValue);
     511              : 
     512            5 :         mSize = capacity();
     513            5 :     }
     514              : 
     515              :     /**
     516              :      *  @brief
     517              :      *    Assigns the default value to all elements in the fixed
     518              :      *    buffer.
     519              :      *
     520              :      *  This assigns the default value for @c value_type to all
     521              :      *  elements in the fixed buffer and sets the size to zero
     522              :      *  (0). Callers looking to do the same but @b without setting the
     523              :      *  size to zero (0) and instead setting the size to capacity
     524              :      *  should use #fill.
     525              :      *
     526              :      *  @sa clear
     527              :      *  @sa fill
     528              :      *
     529              :      */
     530              :     void reset(void) noexcept { reset(value_type{}); }
     531              : 
     532              :     /**
     533              :      *  @brief
     534              :      *    Assigns the specified value to all elements in the fixed
     535              :      *    buffer.
     536              :      *
     537              :      *  This assigns the specified value to all elements in the fixed
     538              :      *  buffer and sets the size to zero (0). Callers
     539              :      *  looking to do the same but @b without setting the size to
     540              :      *  zero (0) and instead setting the size to capacity should use
     541              :      *  #fill.
     542              :      *
     543              :      *  @param[in]  inValue
     544              :      *    A reference to the immutable value to assign to the elements
     545              :      *    of the fixed buffer.
     546              :      *
     547              :      *  @sa clear
     548              :      *  @sa fill
     549              :      *
     550              :      */
     551            1 :     void reset(const_reference inValue) noexcept
     552              :     {
     553            1 :         mData.fill(inValue);
     554            1 :         mSize = 0;
     555            1 :     }
     556              : 
     557              :     /**
     558              :      *  @brief
     559              :      *    Resize the fixed buffer.
     560              :      *
     561              :      *  This attempts to resize the fixed buffer to @a inSize.
     562              :      *
     563              :      *  @note
     564              :      *    No attempt is made to fill or otherwise invalidate elements
     565              :      *    between the tail of the former size and that of @a inSize.
     566              :      *
     567              :      *  @param[in]  inSize
     568              :      *    A reference to the immutable size, in number of elements, to
     569              :      *    set the fixed buffer to.
     570              :      *
     571              :      *  @returns
     572              :      *    True if the fixed buffer was resized to @a inSize elements;
     573              :      *    otherwise, false if @a inSize was greater than the number of
     574              :      *    allowed elements or if @a inSize exceeds the maximum
     575              :      *    representable size for this buffer's @c size_type.
     576              :      *
     577              :      *  @sa append
     578              :      *  @sa assign
     579              :      *  @sa available
     580              :      *  @sa capacity
     581              :      *  @sa clear
     582              :      *  @sa fill
     583              :      *  @sa reset
     584              :      *  @sa size
     585              :      *
     586              :      */
     587            3 :     bool resize(const std::size_t & inSize) noexcept
     588              :     {
     589            3 :         if (inSize > N)
     590              :         {
     591            1 :             return false;
     592              :         }
     593              : 
     594            2 :         if (inSize > static_cast<std::size_t>(std::numeric_limits<size_type>::max()))
     595              :         {
     596            0 :             return false;
     597              :         }
     598              : 
     599            2 :         mSize = static_cast<size_type>(inSize);
     600              : 
     601            2 :         return true;
     602              :     }
     603              : 
     604              :     // Iteration
     605              : 
     606           10 :     iterator begin(void) noexcept { return data(); }
     607            5 :     const_iterator begin(void) const noexcept { return data(); }
     608            1 :     const_iterator cbegin(void) const noexcept { return data(); }
     609           10 :     iterator end(void) noexcept { return data() + static_cast<std::size_t>(mSize); }
     610            1 :     const_iterator end(void) const noexcept { return data() + static_cast<std::size_t>(mSize); }
     611            5 :     const_iterator cend(void) const noexcept { return data() + static_cast<std::size_t>(mSize); }
     612              : 
     613            2 :     reverse_iterator rbegin(void) noexcept { return reverse_iterator(end()); }
     614            1 :     const_reverse_iterator rbegin(void) const noexcept { return const_reverse_iterator(end()); }
     615              :     const_reverse_iterator crbegin(void) const noexcept { return const_reverse_iterator(end()); }
     616            6 :     reverse_iterator rend(void) noexcept { return reverse_iterator(begin()); }
     617            5 :     const_reverse_iterator rend(void) const noexcept { return const_reverse_iterator(begin()); }
     618              :     const_reverse_iterator crend(void) const noexcept { return const_reverse_iterator(begin()); }
     619              : 
     620              : private:
     621              :     std::array<value_type, N> mData;
     622              :     size_type mSize;
     623              : };
     624              : 
     625              : /**
     626              :  *  @brief
     627              :  *    A fixed-capacity, size-tracked buffer of bytes.
     628              :  *
     629              :  *  This specializes and extends @c FixedBuffer as a fixed-capacity,
     630              :  *  size-tracked buffer of bytes.
     631              :  *
     632              :  *  @tparam N
     633              :  *    The fixed byte capacity of the buffer.
     634              :  *
     635              :  *  @tparam SizeT
     636              :  *    An integral type used to represent the logical size.
     637              :  *
     638              :  */
     639              : template <std::size_t N, typename SizeT = std::size_t>
     640              : using FixedByteBuffer = FixedBuffer<std::uint8_t, N, SizeT>;
     641              : 
     642              : /**
     643              :  *  @brief
     644              :  *    A fixed-capacity, size-tracked buffer of characters.
     645              :  *
     646              :  *  This specializes and extends @c FixedBuffer as a fixed-capacity,
     647              :  *  size-tracked buffer of characters.
     648              :  *
     649              :  *  @tparam N
     650              :  *    The fixed character capacity of the buffer.
     651              :  *
     652              :  *  @tparam SizeT
     653              :  *    An integral type used to represent the logical size.
     654              :  *
     655              :  */
     656              : template <std::size_t N, typename SizeT = std::size_t>
     657              : using FixedCharBuffer = FixedBuffer<char, N, SizeT>;
     658              : 
     659              : } // namespace chip
        

Generated by: LCOV version 2.0-1