LCOV - code coverage report
Current view: top level - snapdev - string_literal_length.h (source / functions) Coverage Total Hit
Test: coverage.info Lines: 100.0 % 4 4
Test Date: 2026-02-16 17:48:13 Functions: 100.0 % 10 10
Legend: Lines: hit not hit

            Line data    Source code
       1              : // Copyright (c) 2026  Made to Order Software Corp.  All Rights Reserved
       2              : //
       3              : // https://snapwebsites.org/project/snapdev
       4              : // contact@m2osw.com
       5              : //
       6              : // This program is free software: you can redistribute it and/or modify
       7              : // it under the terms of the GNU General Public License as published by
       8              : // the Free Software Foundation, either version 3 of the License, or
       9              : // (at your option) any later version.
      10              : //
      11              : // This program is distributed in the hope that it will be useful,
      12              : // but WITHOUT ANY WARRANTY; without even the implied warranty of
      13              : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14              : // GNU General Public License for more details.
      15              : //
      16              : // You should have received a copy of the GNU General Public License
      17              : // along with this program.  If not, see <https://www.gnu.org/licenses/>.
      18              : #pragma once
      19              : 
      20              : /** \file
      21              :  * \brief Determine the length of a string literal at compile time.
      22              :  *
      23              :  * This template is used to retrieve the length of a string literal at
      24              :  * compile time:
      25              :  *
      26              :  * \code
      27              :  *     if(snapdev::string_literal_length(str) > 3) ...
      28              :  * \endcode
      29              :  *
      30              :  * The function makes sure that the input string is a `char`, `wchar_t`,
      31              :  * `char8_t`, `char16_t`, and `char32_t`.
      32              :  *
      33              :  * \note
      34              :  * The `char8_t` type is only available since C++20.
      35              :  */
      36              : 
      37              : // self
      38              : //
      39              : #include    <snapdev/is_nonnull.h>
      40              : #include    <snapdev/is_string_literal.h>
      41              : 
      42              : 
      43              : // C++
      44              : //
      45              : #include    <type_traits>
      46              : 
      47              : 
      48              : 
      49              : namespace snapdev
      50              : {
      51              : 
      52              : 
      53              : 
      54              : /** \brief Get the length of a string literal at compile time.
      55              :  *
      56              :  * This template is used to get a string literal length at compile time.
      57              :  * It gives the size of the character array and also verifies that the
      58              :  * type is indeed a character type (char, wchar_t, char8_t, char16_t,
      59              :  * or char32_t).
      60              :  *
      61              :  * \warning
      62              :  * Note that any character buffer is viewed as a "string literal".
      63              :  * So a definition as follow will return true even though you may
      64              :  * see it as a buffer rather than a string literal:
      65              :  * \warning
      66              :  * \code
      67              :  *     constexpr std::uint8_t const g_buffer[5] = { 1, 2, 3, 4, 5 };
      68              :  * \endcode
      69              :  * \warning
      70              :  * Furher, a character buffer may have a size which is not the length
      71              :  * of the string as in:
      72              :  * \warning
      73              :  * \code
      74              :  *     constexpr char const g_buffer[256] = { 'O', 'o', 'p', 's' };
      75              :  * \endcode
      76              :  * \warning
      77              :  * as a string of 4 characters in a buffer of 256 chars so this function
      78              :  * returns 255. In that latter case, you may want to consider using the
      79              :  * string_length() template function instead.
      80              :  *
      81              :  * \tparam T  The type of the array element.
      82              :  * \tparam N  The size of the array.
      83              :  *
      84              :  * \sa string_length()
      85              :  * \sa is_string_literal
      86              :  * \sa is_a_string_literal
      87              :  */
      88              : template<typename T, std::size_t N>
      89              : std::enable_if_t<is_string_literal<T[N]>::value, std::size_t>
      90           10 : string_literal_length(T const (&)[N])
      91              : {
      92           10 :     return N - 1;
      93              : }
      94              : 
      95              : 
      96              : /** \brief Compute the length of a string at compile time.
      97              :  *
      98              :  * This function is similar to the string_literal_length() except that
      99              :  * it works with a buffer of any size and works like strlen() as in,
     100              :  * it stops at the first `'\0'` character.
     101              :  *
     102              :  * The template also verifies that the array type is of a character
     103              :  * type (char, wchar_t, char8_t, char16_t, char32_t).
     104              :  *
     105              :  * \exception found_nullptr
     106              :  * If the input pointer is a null pointer, then this exception is raised.
     107              :  *
     108              :  * \tparam T  The type of the string.
     109              :  */
     110              : template<typename T>
     111              : constexpr std::enable_if_t<std::disjunction_v<
     112              :               std::is_same<T, char>
     113              :             , std::is_same<T, wchar_t>
     114              :             , std::is_same<T, char8_t>
     115              :             , std::is_same<T, char16_t>
     116              :             , std::is_same<T, char32_t>>, std::size_t>
     117          110 : string_length(T const * s)
     118              : {
     119          110 :     return *is_nonnull(s) == '\0' ? 0 : 1 + string_length(s + 1);
     120              : }
     121              : 
     122              : 
     123              : 
     124              : } // namespace snapdev
     125              : // vim: ts=4 sw=4 et
        

Generated by: LCOV version 2.0-1

Snap C++ | List of projects | List of versions