• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

STEllAR-GROUP / hpx / #882

31 Aug 2023 07:44PM UTC coverage: 41.798% (-44.7%) from 86.546%
#882

push

19442 of 46514 relevant lines covered (41.8%)

126375.38 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

90.7
/libs/core/format/src/format.cpp
1
///////////////////////////////////////////////////////////////////////////////
2
//  Copyright (c) 2017-2018 Agustin Berge
3
//  Copyright (c) 2024-2025 Hartmut Kaiser
4
//
5
//  SPDX-License-Identifier: BSL-1.0
6
//  Distributed under the Boost Software License, Version 1.0. (See accompanying
7
//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
8

9
#include <hpx/format/api.hpp>
10

11
#include <algorithm>
12
#include <cstddef>
13
#include <cstdlib>
14
#include <cstring>
15
#include <limits>
16
#include <ostream>
17
#include <sstream>
18
#include <stdexcept>
19
#include <string>
20
#include <string_view>
21

22
namespace hpx::util::detail {
23

24
    ///////////////////////////////////////////////////////////////////////////
25
    inline std::size_t format_atoi(
17,526✔
26
        std::string_view str, std::size_t* pos = nullptr) noexcept
27
    {
28
        // copy input to a null terminated buffer
29
        static constexpr std::size_t digits10 =
30
            std::numeric_limits<std::size_t>::digits10 + 1;
31
        char buffer[digits10 + 1] = {};
17,526✔
32
        std::memcpy(buffer, str.data(), (std::min) (str.size(), digits10));
17,526✔
33

34
        char const* first = buffer;
35
        char* last = buffer;
17,526✔
36
        std::size_t const r = std::strtoull(first, &last, 10);
17,526✔
37
        if (pos != nullptr)
17,526✔
38
            *pos = last - first;
×
39
        return r;
17,526✔
40
    }
41

42
    inline std::string_view format_substr(std::string_view str,
43
        std::size_t start, std::size_t end = std::string_view::npos) noexcept
44
    {
45
        return start < str.size() ? str.substr(start, end - start) :
17,532✔
46
                                    std::string_view{};
47
    }
48

49
    ///////////////////////////////////////////////////////////////////////////
50
    // replacement-field ::= '{' [arg-id] [':' format-spec] '}'
51
    struct format_field
52
    {
53
        std::size_t arg_id;
54
        std::string_view spec;
55
    };
56

57
    inline format_field parse_field(std::string_view field) noexcept
17,526✔
58
    {
59
        std::size_t const sep = field.find(':');
17,526✔
60
        if (sep != std::string_view::npos)
17,526✔
61
        {
62
            std::string_view const arg_id = format_substr(field, 0, sep);
6✔
63
            std::string_view const spec = format_substr(field, sep + 1);
6✔
64

65
            std::size_t const id = format_atoi(arg_id);
6✔
66
            return format_field{id, spec};
6✔
67
        }
68
        else
69
        {
70
            std::size_t const id = format_atoi(field);
17,520✔
71
            return format_field{id, ""};
17,520✔
72
        }
73
    }
74

75
    void format_to(std::ostream& os, std::string_view format_str,
17,076✔
76
        format_arg const* args, std::size_t count)
77
    {
78
        std::size_t index = 0;
79
        while (!format_str.empty())
44,709✔
80
        {
81
            if (format_str[0] == '{' || format_str[0] == '}')
27,633✔
82
            {
83
                if (format_str[1] == format_str[0])
17,532✔
84
                {
85
                    // NOLINTNEXTLINE(bugprone-suspicious-stringview-data-usage)
6✔
86
                    os.write(format_str.data(), 1);    // '{' or '}'
87
                }
88
                else
89
                {
17,526✔
90
                    if (format_str[0] == '}')
91
                    {
×
92
                        throw std::runtime_error("bad format string");
93
                    }
17,526✔
94
                    std::size_t const end = format_str.find('}');
95
                    std::string_view const field_str =
17,526✔
96
                        format_substr(format_str, 1, end);
17,526✔
97
                    format_field const field = parse_field(field_str);
17,526✔
98
                    format_str.remove_prefix(end - 1);
99

100
                    std::size_t const id =
17,526✔
101
                        field.arg_id ? field.arg_id - 1 : index;
17,526✔
102
                    if (id >= count)
103
                    {
×
104
                        throw std::runtime_error(
×
105
                            "bad format string (wrong number of arguments)");
106
                    }
107

17,526✔
108
                    args[id](os, field.spec);
17,526✔
109
                    ++index;
110
                }
111
                format_str.remove_prefix(2);
112
            }
113
            else
114
            {
115
                std::size_t const next = format_str.find_first_of("{}");
116
                std::size_t const cnt =
10,101✔
117
                    next != std::string_view::npos ? next : format_str.size();
118

10,101✔
119
                // NOLINTNEXTLINE(bugprone-suspicious-stringview-data-usage)
120
                os.write(format_str.data(), static_cast<std::streamsize>(cnt));
121
                format_str.remove_prefix(cnt);
122
            }
17,076✔
123
        }
124
    }
16,929✔
125

126
    HPX_CORE_EXPORT std::string format(
127
        std::string_view format_str, format_arg const* args, std::size_t count)
16,929✔
128
    {
16,929✔
129
        std::ostringstream os;
16,929✔
130
        detail::format_to(os, format_str, args, count);
16,929✔
131
        return os.str();
132
    }
133
}    // namespace hpx::util::detail
134

135
namespace hpx::util {
136

137
    std::string const& format()
138
    {
139
        static std::string empty;
140
        return empty;
141
    }
142
}    // namespace hpx::util
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc