Coverage Report

Created: 2026-08-31 07:01

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/tomlplusplus/include/toml++/impl/table.inl
Line
Count
Source
1
//# This file is a part of toml++ and is subject to the the terms of the MIT license.
2
//# Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
3
//# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
4
// SPDX-License-Identifier: MIT
5
#pragma once
6
7
//# {{
8
#include "preprocessor.hpp"
9
#if !TOML_IMPLEMENTATION
10
#error This is an implementation-only header.
11
#endif
12
//# }}
13
14
#include "table.hpp"
15
#include "node_view.hpp"
16
#include "header_start.hpp"
17
18
TOML_NAMESPACE_START
19
{
20
  TOML_EXTERNAL_LINKAGE
21
  table::table() noexcept
22
1.14M
  {
23
#if TOML_LIFETIME_HOOKS
24
    TOML_TABLE_CREATED;
25
#endif
26
1.14M
  }
27
28
  TOML_EXTERNAL_LINKAGE
29
  table::~table() noexcept
30
1.15M
  {
31
#if TOML_LIFETIME_HOOKS
32
    TOML_TABLE_DESTROYED;
33
#endif
34
1.15M
  }
35
36
  TOML_EXTERNAL_LINKAGE
37
  table::table(const impl::table_init_pair* b, const impl::table_init_pair* e)
38
  {
39
#if TOML_LIFETIME_HOOKS
40
    TOML_TABLE_CREATED;
41
#endif
42
43
    TOML_ASSERT_ASSUME(b);
44
    TOML_ASSERT_ASSUME(e);
45
    TOML_ASSERT_ASSUME(b <= e);
46
47
    if TOML_UNLIKELY(b == e)
48
      return;
49
50
    for (; b != e; b++)
51
    {
52
      if (!b->value) // empty node_views
53
        continue;
54
55
      map_.insert_or_assign(std::move(b->key), std::move(b->value));
56
    }
57
  }
58
59
  TOML_EXTERNAL_LINKAGE
60
  table::table(const table& other) //
61
    : node(other),
62
      inline_{ other.inline_ }
63
  {
64
    for (auto&& [k, v] : other.map_)
65
      map_.emplace_hint(map_.end(), k, impl::make_node(*v));
66
67
#if TOML_LIFETIME_HOOKS
68
    TOML_TABLE_CREATED;
69
#endif
70
  }
71
72
  TOML_EXTERNAL_LINKAGE
73
  table::table(table && other) noexcept //
74
3.62k
    : node(std::move(other)),
75
3.62k
      map_{ std::move(other.map_) },
76
3.62k
      inline_{ other.inline_ }
77
3.62k
  {
78
#if TOML_LIFETIME_HOOKS
79
    TOML_TABLE_CREATED;
80
#endif
81
3.62k
  }
82
83
  TOML_EXTERNAL_LINKAGE
84
  table& table::operator=(const table& rhs)
85
0
  {
86
0
    if (&rhs != this)
87
0
    {
88
0
      node::operator=(rhs);
89
0
      map_.clear();
90
0
      for (auto&& [k, v] : rhs.map_)
91
0
        map_.emplace_hint(map_.end(), k, impl::make_node(*v));
92
0
      inline_ = rhs.inline_;
93
0
    }
94
0
    return *this;
95
0
  }
96
97
  TOML_EXTERNAL_LINKAGE
98
  table& table::operator=(table&& rhs) noexcept
99
0
  {
100
0
    if (&rhs != this)
101
0
    {
102
0
      node::operator=(std::move(rhs));
103
0
      map_  = std::move(rhs.map_);
104
0
      inline_ = rhs.inline_;
105
0
    }
106
0
    return *this;
107
0
  }
108
109
  TOML_PURE_GETTER
110
  TOML_EXTERNAL_LINKAGE
111
  bool table::is_homogeneous(node_type ntype) const noexcept
112
0
  {
113
0
    if (map_.empty())
114
0
      return false;
115
116
0
    if (ntype == node_type::none)
117
0
      ntype = map_.cbegin()->second->type();
118
119
0
    for (auto&& [k, v] : map_)
120
0
    {
121
0
      TOML_UNUSED(k);
122
0
      if (v->type() != ntype)
123
0
        return false;
124
0
    }
125
126
0
    return true;
127
0
  }
128
129
  TOML_NODISCARD
130
  TOML_EXTERNAL_LINKAGE
131
  bool table::is_homogeneous(node_type ntype, node * &first_nonmatch) noexcept
132
0
  {
133
0
    if (map_.empty())
134
0
    {
135
0
      first_nonmatch = {};
136
0
      return false;
137
0
    }
138
0
    if (ntype == node_type::none)
139
0
      ntype = map_.cbegin()->second->type();
140
0
    for (const auto& [k, v] : map_)
141
0
    {
142
0
      TOML_UNUSED(k);
143
0
      if (v->type() != ntype)
144
0
      {
145
0
        first_nonmatch = v.get();
146
0
        return false;
147
0
      }
148
0
    }
149
0
    return true;
150
0
  }
151
152
  TOML_NODISCARD
153
  TOML_EXTERNAL_LINKAGE
154
  bool table::is_homogeneous(node_type ntype, const node*& first_nonmatch) const noexcept
155
0
  {
156
0
    node* fnm     = nullptr;
157
0
    const auto result = const_cast<table&>(*this).is_homogeneous(ntype, fnm);
158
0
    first_nonmatch    = fnm;
159
0
    return result;
160
0
  }
161
162
  TOML_PURE_GETTER
163
  TOML_EXTERNAL_LINKAGE
164
  node* table::get(std::string_view key) noexcept
165
0
  {
166
0
    if (auto it = map_.find(key); it != map_.end())
167
0
      return it->second.get();
168
0
    return nullptr;
169
0
  }
170
171
  TOML_EXTERNAL_LINKAGE
172
  node& table::at(std::string_view key)
173
0
  {
174
0
    auto n = get(key);
175
0
176
0
#if TOML_COMPILER_HAS_EXCEPTIONS
177
0
178
0
    if (!n)
179
0
    {
180
0
      auto err = "key '"s;
181
0
      err.append(key);
182
0
      err.append("' not found in table"sv);
183
0
      throw std::out_of_range{ err };
184
0
    }
185
0
186
0
#else
187
0
188
0
    TOML_ASSERT_ASSUME(n && "key not found in table!");
189
0
190
0
#endif
191
0
192
0
    return *n;
193
0
  }
194
195
  TOML_PURE_GETTER
196
  TOML_EXTERNAL_LINKAGE
197
  table::map_iterator table::get_lower_bound(std::string_view key) noexcept
198
1.44M
  {
199
1.44M
    return map_.lower_bound(key);
200
1.44M
  }
201
202
  TOML_PURE_GETTER
203
  TOML_EXTERNAL_LINKAGE
204
  table::iterator table::find(std::string_view key) noexcept
205
0
  {
206
0
    return iterator{ map_.find(key) };
207
0
  }
208
209
  TOML_PURE_GETTER
210
  TOML_EXTERNAL_LINKAGE
211
  table::const_iterator table::find(std::string_view key) const noexcept
212
0
  {
213
0
    return const_iterator{ map_.find(key) };
214
0
  }
215
216
  TOML_EXTERNAL_LINKAGE
217
  table::map_iterator table::erase(const_map_iterator pos) noexcept
218
0
  {
219
0
    return map_.erase(pos);
220
0
  }
221
222
  TOML_EXTERNAL_LINKAGE
223
  table::map_iterator table::erase(const_map_iterator begin, const_map_iterator end) noexcept
224
0
  {
225
0
    return map_.erase(begin, end);
226
0
  }
227
228
  TOML_EXTERNAL_LINKAGE
229
  size_t table::erase(std::string_view key) noexcept
230
0
  {
231
0
    if (auto it = map_.find(key); it != map_.end())
232
0
    {
233
0
      map_.erase(it);
234
0
      return size_t{ 1 };
235
0
    }
236
0
    return size_t{};
237
0
  }
238
239
  TOML_EXTERNAL_LINKAGE
240
  table& table::prune(bool recursive)& noexcept
241
0
  {
242
0
    if (map_.empty())
243
0
      return *this;
244
0
245
0
    for (auto it = map_.begin(); it != map_.end();)
246
0
    {
247
0
      if (auto arr = it->second->as_array())
248
0
      {
249
0
        if (recursive)
250
0
          arr->prune(true);
251
0
252
0
        if (arr->empty())
253
0
        {
254
0
          it = map_.erase(it);
255
0
          continue;
256
0
        }
257
0
      }
258
0
      else if (auto tbl = it->second->as_table())
259
0
      {
260
0
        if (recursive)
261
0
          tbl->prune(true);
262
0
263
0
        if (tbl->empty())
264
0
        {
265
0
          it = map_.erase(it);
266
0
          continue;
267
0
        }
268
0
      }
269
0
      it++;
270
0
    }
271
0
272
0
    return *this;
273
0
  }
274
275
  TOML_EXTERNAL_LINKAGE
276
  void table::clear() noexcept
277
0
  {
278
0
    map_.clear();
279
0
  }
280
281
  TOML_EXTERNAL_LINKAGE
282
  table::map_iterator table::insert_with_hint(const_iterator hint, key && k, impl::node_ptr && v)
283
1.13M
  {
284
1.13M
    return map_.emplace_hint(const_map_iterator{ hint }, std::move(k), std::move(v));
285
1.13M
  }
286
287
  TOML_PURE_GETTER
288
  TOML_EXTERNAL_LINKAGE
289
  bool TOML_CALLCONV table::equal(const table& lhs, const table& rhs) noexcept
290
0
  {
291
0
    if (&lhs == &rhs)
292
0
      return true;
293
0
    if (lhs.map_.size() != rhs.map_.size())
294
0
      return false;
295
0
296
0
    for (auto l = lhs.map_.begin(), r = rhs.map_.begin(), e = lhs.map_.end(); l != e; l++, r++)
297
0
    {
298
0
      if (l->first != r->first)
299
0
        return false;
300
0
301
0
      const auto lhs_type = l->second->type();
302
0
      const node& rhs_  = *r->second;
303
0
      const auto rhs_type = rhs_.type();
304
0
      if (lhs_type != rhs_type)
305
0
        return false;
306
0
307
0
      const bool equal = l->second->visit(
308
0
        [&](const auto& lhs_) noexcept
309
0
        { return lhs_ == *static_cast<std::remove_reference_t<decltype(lhs_)>*>(&rhs_); });
310
0
      if (!equal)
311
0
        return false;
312
0
    }
313
0
    return true;
314
0
  }
315
}
316
TOML_NAMESPACE_END;
317
318
#include "header_end.hpp"