Coverage Report

Created: 2026-01-17 06:21

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/tomlplusplus/include/toml++/impl/path.hpp
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
#include "forward_declarations.hpp"
8
#include "std_vector.hpp"
9
#include "header_start.hpp"
10
11
TOML_NAMESPACE_START
12
{
13
  /// \brief Indicates type of path component, either a key, an index in an array, or invalid
14
  enum class TOML_CLOSED_ENUM path_component_type : uint8_t
15
  {
16
    key     = 0x1,
17
    array_index = 0x2
18
  };
19
20
  /// \brief Represents a single component of a complete 'TOML-path': either a key or an array index
21
  class TOML_EXPORTED_CLASS path_component
22
  {
23
    /// \cond
24
    struct storage_t
25
    {
26
      static constexpr size_t size =
27
        (sizeof(size_t) < sizeof(std::string) ? sizeof(std::string) : sizeof(size_t));
28
      static constexpr size_t align =
29
        (alignof(size_t) < alignof(std::string) ? alignof(std::string) : alignof(size_t));
30
31
      alignas(align) unsigned char bytes[size];
32
    };
33
    alignas(storage_t::align) mutable storage_t value_storage_;
34
35
    path_component_type type_;
36
37
    TOML_PURE_GETTER
38
    TOML_EXPORTED_STATIC_FUNCTION
39
    static bool TOML_CALLCONV equal(const path_component&, const path_component&) noexcept;
40
41
    template <typename Type>
42
    TOML_PURE_INLINE_GETTER
43
    static Type* get_as(storage_t& s) noexcept
44
0
    {
45
0
      return TOML_LAUNDER(reinterpret_cast<Type*>(s.bytes));
46
0
    }
Unexecuted instantiation: std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >* toml::v3::path_component::get_as<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(toml::v3::path_component::storage_t&)
Unexecuted instantiation: unsigned long* toml::v3::path_component::get_as<unsigned long>(toml::v3::path_component::storage_t&)
Unexecuted instantiation: unsigned long const* toml::v3::path_component::get_as<unsigned long const>(toml::v3::path_component::storage_t&)
Unexecuted instantiation: std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const* toml::v3::path_component::get_as<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const>(toml::v3::path_component::storage_t&)
47
48
    static void store_key(std::string_view key, storage_t& storage_)
49
0
    {
50
0
      ::new (static_cast<void*>(storage_.bytes)) std::string{ key };
51
0
    }
52
53
    static void store_index(size_t index, storage_t& storage_) noexcept
54
0
    {
55
0
      ::new (static_cast<void*>(storage_.bytes)) std::size_t{ index };
56
0
    }
57
58
    void destroy() noexcept
59
0
    {
60
0
      if (type_ == path_component_type::key)
61
0
        get_as<std::string>(value_storage_)->~basic_string();
62
0
    }
63
64
    TOML_NODISCARD
65
    size_t& index_ref() noexcept
66
0
    {
67
0
      TOML_ASSERT_ASSUME(type_ == path_component_type::array_index);
68
0
      return *get_as<size_t>(value_storage_);
69
0
    }
70
71
    TOML_NODISCARD
72
    std::string& key_ref() noexcept
73
0
    {
74
0
      TOML_ASSERT_ASSUME(type_ == path_component_type::key);
75
0
      return *get_as<std::string>(value_storage_);
76
0
    }
77
    /// \endcond
78
79
    public:
80
    /// \brief  Default constructor (creates an empty key).
81
    TOML_NODISCARD_CTOR
82
    TOML_EXPORTED_MEMBER_FUNCTION
83
    path_component();
84
85
    /// \brief  Constructor for a path component that is an array index
86
    TOML_NODISCARD_CTOR
87
    TOML_EXPORTED_MEMBER_FUNCTION
88
    path_component(size_t index) noexcept;
89
90
    /// \brief  Constructor for a path component that is a key string
91
    TOML_NODISCARD_CTOR
92
    TOML_EXPORTED_MEMBER_FUNCTION
93
    path_component(std::string_view key);
94
95
#if TOML_ENABLE_WINDOWS_COMPAT
96
97
    /// \brief  Constructor for a path component that is a key string
98
    ///
99
    /// \availability This constructor is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
100
    TOML_NODISCARD_CTOR
101
    TOML_EXPORTED_MEMBER_FUNCTION
102
    path_component(std::wstring_view key);
103
104
#endif
105
106
    /// \brief  Copy constructor.
107
    TOML_NODISCARD_CTOR
108
    TOML_EXPORTED_MEMBER_FUNCTION
109
    path_component(const path_component& pc);
110
111
    /// \brief  Move constructor.
112
    TOML_NODISCARD_CTOR
113
    TOML_EXPORTED_MEMBER_FUNCTION
114
    path_component(path_component&& pc) noexcept;
115
116
    /// \brief  Copy-assignment operator.
117
    TOML_EXPORTED_MEMBER_FUNCTION
118
    path_component& operator=(const path_component& rhs);
119
120
    /// \brief  Move-assignment operator.
121
    TOML_EXPORTED_MEMBER_FUNCTION
122
    path_component& operator=(path_component&& rhs) noexcept;
123
124
    /// \brief Assigns an array index to this path component.
125
    TOML_EXPORTED_MEMBER_FUNCTION
126
    path_component& operator=(size_t new_index) noexcept;
127
128
    /// \brief Assigns a path key to this path component.
129
    TOML_EXPORTED_MEMBER_FUNCTION
130
    path_component& operator=(std::string_view new_key);
131
132
#if TOML_ENABLE_WINDOWS_COMPAT
133
134
    /// \brief Assigns a path key to this path component.
135
    ///
136
    /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
137
    TOML_EXPORTED_MEMBER_FUNCTION
138
    path_component& operator=(std::wstring_view new_key);
139
140
#endif
141
142
    /// \brief  Destructor.
143
    ~path_component() noexcept
144
0
    {
145
0
      destroy();
146
0
    }
147
148
    /// \name Array index accessors
149
    /// \warning It is undefined behaviour to call these functions when the path component does not represent an array index.
150
    /// Check #type() to determine the component's value type.
151
    /// @{
152
153
    /// \brief  Returns the array index (const lvalue overload).
154
    TOML_PURE_GETTER
155
    size_t index() const noexcept
156
0
    {
157
0
      TOML_ASSERT_ASSUME(type_ == path_component_type::array_index);
158
0
      return *get_as<const size_t>(value_storage_);
159
0
    }
160
161
    /// \brief  Returns the array index (const lvalue).
162
    TOML_PURE_INLINE_GETTER
163
    explicit operator size_t() const noexcept
164
0
    {
165
0
      return index();
166
0
    }
167
168
    /// @}
169
170
    /// \name Key accessors
171
    /// \warning It is undefined behaviour to call these functions when the path component does not represent a key.
172
    /// Check #type() to determine the component's value type.
173
    /// @{
174
175
    /// \brief  Returns the key string.
176
    TOML_PURE_GETTER
177
    const std::string& key() const noexcept
178
0
    {
179
0
      TOML_ASSERT_ASSUME(type_ == path_component_type::key);
180
0
      return *get_as<const std::string>(value_storage_);
181
0
    }
182
183
    /// \brief  Returns the key string.
184
    TOML_PURE_INLINE_GETTER
185
    explicit operator const std::string&() const noexcept
186
0
    {
187
0
      return key();
188
0
    }
189
190
    /// @}
191
192
    /// \brief Retrieve the type of this path component, either path_component::key or path_component::array_index
193
    TOML_PURE_INLINE_GETTER
194
    path_component_type type() const noexcept
195
0
    {
196
0
      return type_;
197
0
    }
198
199
    /// \name Equality
200
    /// @{
201
202
    /// \brief  Returns true if two path components represent the same key or array index.
203
    TOML_PURE_INLINE_GETTER
204
    friend bool operator==(const path_component& lhs, const path_component& rhs) noexcept
205
0
    {
206
0
      return equal(lhs, rhs);
207
0
    }
208
209
    /// \brief  Returns true if two path components do not represent the same key or array index.
210
    TOML_PURE_INLINE_GETTER
211
    friend bool operator!=(const path_component& lhs, const path_component& rhs) noexcept
212
0
    {
213
0
      return !equal(lhs, rhs);
214
0
    }
215
216
    /// @}
217
  };
218
219
  /// \brief  A TOML path.
220
  ///
221
  /// \detail This type parses and represents a path to a TOML node. It validates
222
  ///         the syntax of the path but does not ensure that the path refers to
223
  ///         a valid node in any particular TOML document. If parsing fails,
224
  ///         the object will evaluate as 'falsy', and will be empty.
225
  ///
226
  /// \cpp
227
  /// toml::path the_path("animals.cats[1]");
228
  ///
229
  /// // can use with tbl.at_path or operator[]
230
  /// std::cout << "second cat: " << tbl[the_path] << "\n";
231
  /// std::cout << "cats: " << tbl.at_path(the_path.parent_path()) << "\n";
232
  /// \ecpp
233
  ///
234
  /// \out
235
  /// second cat: lion
236
  /// cats: ['tiger', 'lion', 'puma']
237
  /// \eout
238
  class TOML_EXPORTED_CLASS path
239
  {
240
    private:
241
    /// \cond
242
243
    std::vector<path_component> components_;
244
245
    TOML_EXPORTED_MEMBER_FUNCTION
246
    void print_to(std::ostream&) const;
247
248
    TOML_PURE_GETTER
249
    TOML_EXPORTED_STATIC_FUNCTION
250
    static bool TOML_CALLCONV equal(const path&, const path&) noexcept;
251
252
    /// \endcond
253
254
    public:
255
    /// \brief  Default constructor.
256
    TOML_NODISCARD_CTOR
257
    path() noexcept = default;
258
259
    /// \brief Construct a path by parsing from a string.
260
    TOML_NODISCARD_CTOR
261
    TOML_EXPORTED_MEMBER_FUNCTION
262
    explicit path(std::string_view);
263
264
#if TOML_ENABLE_WINDOWS_COMPAT
265
266
    /// \brief Construct a path by parsing from a string.
267
    ///
268
    /// \availability This constructor is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
269
    TOML_NODISCARD_CTOR
270
    TOML_EXPORTED_MEMBER_FUNCTION
271
    explicit path(std::wstring_view);
272
273
#endif
274
275
    /// \brief  Default destructor.
276
    ~path() noexcept = default;
277
278
    /// \brief  Copy constructor.
279
    TOML_NODISCARD_CTOR
280
    path(const path&) = default;
281
282
    /// \brief  Move constructor.
283
    TOML_NODISCARD_CTOR
284
    path(path&&) noexcept = default;
285
286
    /// \brief Returns the number of components in the path.
287
    TOML_PURE_INLINE_GETTER
288
    size_t size() const noexcept
289
0
    {
290
0
      return components_.size();
291
0
    }
292
293
    /// \brief Returns true if the path has one or more components.
294
    TOML_PURE_INLINE_GETTER
295
    explicit operator bool() const noexcept
296
0
    {
297
0
      return !components_.empty();
298
0
    }
299
300
    /// \brief Whether (true) or not (false) the path is empty
301
    TOML_PURE_INLINE_GETTER
302
    bool empty() const noexcept
303
0
    {
304
0
      return components_.empty();
305
0
    }
306
307
    /// \brief Fetch a path component by index.
308
    TOML_PURE_INLINE_GETTER
309
    path_component& operator[](size_t index) noexcept
310
0
    {
311
0
      TOML_ASSERT(index < size());
312
0
      return components_[index];
313
0
    }
314
315
    /// \brief Fetch a path component by index (const overload).
316
    TOML_PURE_INLINE_GETTER
317
    const path_component& operator[](size_t index) const noexcept
318
0
    {
319
0
      TOML_ASSERT(index < size());
320
0
      return components_[index];
321
0
    }
322
323
    /// \name Assignment
324
    /// @{
325
326
    /// \brief  Copy-assignment operator.
327
    path& operator=(const path&) = default;
328
329
    /// \brief  Move-assignment operator.
330
    path& operator=(path&&) noexcept = default;
331
332
    /// \brief  Replaces the contents of the path by parsing from a string.
333
    TOML_EXPORTED_MEMBER_FUNCTION
334
    path& operator=(std::string_view);
335
336
#if TOML_ENABLE_WINDOWS_COMPAT
337
338
    /// \brief  Replaces the contents of the path by parsing from a string.
339
    ///
340
    /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
341
    TOML_EXPORTED_MEMBER_FUNCTION
342
    path& operator=(std::wstring_view);
343
344
#endif
345
346
    /// \brief  Replaces the contents of the path with that of another.
347
    TOML_ALWAYS_INLINE
348
    path& assign(const path& p)
349
0
    {
350
0
      return *this = p;
351
0
    }
352
353
    /// \brief  Replaces the contents of the path with that of another.
354
    TOML_ALWAYS_INLINE
355
    path& assign(path&& p) noexcept
356
0
    {
357
0
      return *this = std::move(p);
358
0
    }
359
360
    /// \brief  Replaces the contents of the path object by a new path
361
    TOML_ALWAYS_INLINE
362
    path& assign(std::string_view str)
363
0
    {
364
0
      return *this = str;
365
0
    }
366
367
#if TOML_ENABLE_WINDOWS_COMPAT
368
369
    /// \brief  Replaces the contents of the path object by a new path
370
    ///
371
    /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
372
    TOML_ALWAYS_INLINE
373
    path& assign(std::wstring_view str)
374
    {
375
      return *this = str;
376
    }
377
378
#endif
379
380
    /// @}
381
382
    /// \name Appending
383
    /// @{
384
385
    /// \brief  Appends another path onto the end of this one.
386
    TOML_EXPORTED_MEMBER_FUNCTION
387
    path& operator+=(const path&);
388
389
    /// \brief  Appends another path onto the end of this one.
390
    TOML_EXPORTED_MEMBER_FUNCTION
391
    path& operator+=(path&&);
392
393
    /// \brief  Parses a path and appends it onto the end of this one.
394
    TOML_EXPORTED_MEMBER_FUNCTION
395
    path& operator+=(std::string_view);
396
397
#if TOML_ENABLE_WINDOWS_COMPAT
398
399
    /// \brief  Parses a path and appends it onto the end of this one.
400
    ///
401
    /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
402
    TOML_EXPORTED_MEMBER_FUNCTION
403
    path& operator+=(std::wstring_view);
404
405
#endif
406
407
    /// \brief  Appends another path onto the end of this one.
408
    TOML_ALWAYS_INLINE
409
    path& append(const path& p)
410
0
    {
411
0
      return *this += p;
412
0
    }
413
414
    /// \brief  Appends another path onto the end of this one.
415
    TOML_ALWAYS_INLINE
416
    path& append(path&& p)
417
0
    {
418
0
      return *this += std::move(p);
419
0
    }
420
421
    /// \brief  Parses a path and appends it onto the end of this one.
422
    TOML_ALWAYS_INLINE
423
    path& append(std::string_view str)
424
0
    {
425
0
      return *this += str;
426
0
    }
427
428
#if TOML_ENABLE_WINDOWS_COMPAT
429
430
    /// \brief  Parses a path and appends it onto the end of this one.
431
    ///
432
    /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
433
    TOML_ALWAYS_INLINE
434
    path& append(std::wstring_view str)
435
    {
436
      return *this += str;
437
    }
438
439
#endif
440
441
    /// @}
442
443
    /// \name Prepending
444
    /// @{
445
446
    /// \brief  Prepends another path onto the beginning of this one.
447
    TOML_EXPORTED_MEMBER_FUNCTION
448
    path& prepend(const path&);
449
450
    /// \brief  Prepends another path onto the beginning of this one.
451
    TOML_EXPORTED_MEMBER_FUNCTION
452
    path& prepend(path&&);
453
454
    /// \brief  Parses a path and prepends it onto the beginning of this one.
455
    TOML_EXPORTED_MEMBER_FUNCTION
456
    path& prepend(std::string_view);
457
458
#if TOML_ENABLE_WINDOWS_COMPAT
459
460
    /// \brief  Parses a path and prepends it onto the beginning of this one.
461
    ///
462
    /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
463
    TOML_EXPORTED_MEMBER_FUNCTION
464
    path& prepend(std::wstring_view);
465
466
#endif
467
468
    /// @}
469
470
    /// \name Concatenation
471
    /// @{
472
473
    /// \brief  Concatenates two paths.
474
    TOML_NODISCARD
475
    friend path operator+(const path& lhs, const path& rhs)
476
0
    {
477
0
      path result = lhs;
478
0
      result += rhs;
479
0
      return result;
480
0
    }
481
482
    /// \brief  Concatenates two paths.
483
    TOML_NODISCARD
484
    friend path operator+(const path& lhs, std::string_view rhs)
485
0
    {
486
0
      path result = lhs;
487
0
      result += rhs;
488
0
      return result;
489
0
    }
490
491
    /// \brief  Concatenates two paths.
492
    TOML_NODISCARD
493
    friend path operator+(std::string_view lhs, const path& rhs)
494
0
    {
495
0
      path result = rhs;
496
0
      result.prepend(lhs);
497
0
      return result;
498
0
    }
499
500
#if TOML_ENABLE_WINDOWS_COMPAT
501
502
    /// \brief  Concatenates two paths.
503
    ///
504
    /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
505
    TOML_NODISCARD
506
    friend path operator+(const path& lhs, std::wstring_view rhs)
507
    {
508
      path result = lhs;
509
      result += rhs;
510
      return result;
511
    }
512
513
    /// \brief  Concatenates two paths.
514
    ///
515
    /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
516
    TOML_NODISCARD
517
    friend path operator+(std::wstring_view lhs, const path& rhs)
518
    {
519
      path result = rhs;
520
      result.prepend(lhs);
521
      return result;
522
    }
523
524
#endif
525
526
    /// @}
527
528
    /// \name String conversion
529
    /// @{
530
531
    /// \brief  Prints the string representation of a #toml::path out to a stream.
532
    TOML_ALWAYS_INLINE
533
    friend std::ostream& operator<<(std::ostream& os, const path& rhs)
534
0
    {
535
0
      rhs.print_to(os);
536
0
      return os;
537
0
    }
538
539
    /// \brief Returns a string representation of this path.
540
    TOML_NODISCARD
541
    TOML_EXPORTED_MEMBER_FUNCTION
542
    std::string str() const;
543
544
    /// \brief Returns a string representation of this path.
545
    TOML_NODISCARD
546
    TOML_ALWAYS_INLINE
547
    explicit operator std::string() const
548
0
    {
549
0
      return str();
550
0
    }
551
552
#if TOML_ENABLE_WINDOWS_COMPAT
553
554
    /// \brief Returns a string representation of this path.
555
    ///
556
    /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
557
    TOML_NODISCARD
558
    TOML_EXPORTED_MEMBER_FUNCTION
559
    std::wstring wide_str() const;
560
561
    /// \brief Returns a string representation of this path.
562
    ///
563
    /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
564
    TOML_NODISCARD
565
    TOML_ALWAYS_INLINE
566
    explicit operator std::wstring() const
567
    {
568
      return wide_str();
569
    }
570
571
#endif
572
573
    /// @}
574
575
    /// \name Equality
576
    /// @{
577
578
    /// \brief Returns whether two paths are the same.
579
    TOML_PURE_INLINE_GETTER
580
    friend bool operator==(const path& lhs, const path& rhs) noexcept
581
0
    {
582
0
      return equal(lhs, rhs);
583
0
    }
584
585
    /// \brief Returns whether two paths are not the same.
586
    TOML_PURE_INLINE_GETTER
587
    friend bool operator!=(const path& lhs, const path& rhs) noexcept
588
0
    {
589
0
      return !equal(lhs, rhs);
590
0
    }
591
592
    /// \brief Returns whether two paths are the same.
593
    TOML_NODISCARD
594
    TOML_ALWAYS_INLINE
595
    friend bool operator==(const path& lhs, std::string_view rhs)
596
0
    {
597
0
      return lhs == path{ rhs };
598
0
    }
599
600
    /// \brief Returns whether two paths are the same.
601
    TOML_NODISCARD
602
    TOML_ALWAYS_INLINE
603
    friend bool operator==(std::string_view lhs, const path& rhs)
604
0
    {
605
0
      return rhs == lhs;
606
0
    }
607
608
    /// \brief Returns whether two paths are not the same.
609
    TOML_NODISCARD
610
    TOML_ALWAYS_INLINE
611
    friend bool operator!=(const path& lhs, std::string_view rhs)
612
0
    {
613
0
      return lhs != path{ rhs };
614
0
    }
615
616
    /// \brief Returns whether two paths are not the same.
617
    TOML_NODISCARD
618
    TOML_ALWAYS_INLINE
619
    friend bool operator!=(std::string_view lhs, const path& rhs)
620
0
    {
621
0
      return rhs != lhs;
622
0
    }
623
624
#if TOML_ENABLE_WINDOWS_COMPAT
625
626
    /// \brief Returns whether two paths are the same.
627
    ///
628
    /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
629
    TOML_NODISCARD
630
    TOML_ALWAYS_INLINE
631
    friend bool operator==(const path& lhs, std::wstring_view rhs)
632
    {
633
      return lhs == path{ rhs };
634
    }
635
636
    /// \brief Returns whether two paths are the same.
637
    ///
638
    /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
639
    TOML_NODISCARD
640
    TOML_ALWAYS_INLINE
641
    friend bool operator==(std::wstring_view lhs, const path& rhs)
642
    {
643
      return rhs == lhs;
644
    }
645
646
    /// \brief Returns whether two paths are not the same.
647
    ///
648
    /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
649
    TOML_NODISCARD
650
    TOML_ALWAYS_INLINE
651
    friend bool operator!=(const path& lhs, std::wstring_view rhs)
652
    {
653
      return lhs != path{ rhs };
654
    }
655
656
    /// \brief Returns whether two paths are not the same.
657
    ///
658
    /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
659
    TOML_NODISCARD
660
    TOML_ALWAYS_INLINE
661
    friend bool operator!=(std::wstring_view lhs, const path& rhs)
662
    {
663
      return rhs != lhs;
664
    }
665
666
#endif // TOML_ENABLE_WINDOWS_COMPAT
667
668
    /// @}
669
670
    /// \name Iteration
671
    /// @{
672
673
    /// An iterator for iterating over the components in the path.
674
    /// \see #toml::path_component
675
    using iterator = std::vector<path_component>::iterator;
676
677
    /// A const iterator for iterating over the components in the path.
678
    /// \see #toml::path_component
679
    using const_iterator = std::vector<path_component>::const_iterator;
680
681
    /// \brief  Returns an iterator to the first component in the path.
682
    /// \see #toml::path_component
683
    TOML_PURE_INLINE_GETTER
684
    iterator begin() noexcept
685
0
    {
686
0
      return components_.begin();
687
0
    }
688
689
    /// \brief  Returns an iterator to one-past-the-last component in the path.
690
    /// \see #toml::path_component
691
    TOML_PURE_INLINE_GETTER
692
    iterator end() noexcept
693
0
    {
694
0
      return components_.end();
695
0
    }
696
697
    /// \brief  Returns a const iterator to the first component in the path.
698
    /// \see #toml::path_component
699
    TOML_PURE_INLINE_GETTER
700
    const_iterator begin() const noexcept
701
0
    {
702
0
      return components_.begin();
703
0
    }
704
705
    /// \brief  Returns a const iterator to one-past-the-last component in the path.
706
    /// \see #toml::path_component
707
    TOML_PURE_INLINE_GETTER
708
    const_iterator end() const noexcept
709
0
    {
710
0
      return components_.end();
711
0
    }
712
713
    /// \brief  Returns a const iterator to the first component in the path.
714
    /// \see #toml::path_component
715
    TOML_PURE_INLINE_GETTER
716
    const_iterator cbegin() const noexcept
717
0
    {
718
0
      return components_.begin();
719
0
    }
720
721
    /// \brief  Returns a const iterator to one-past-the-last component in the path.
722
    /// \see #toml::path_component
723
    TOML_PURE_INLINE_GETTER
724
    const_iterator cend() const noexcept
725
0
    {
726
0
      return components_.end();
727
0
    }
728
729
    /// @}
730
731
    /// \name Subpaths and Truncation
732
    /// @{
733
734
    /// \brief  Erases the contents of the path.
735
    TOML_EXPORTED_MEMBER_FUNCTION
736
    void clear() noexcept;
737
738
    /// \brief Removes the number of terminal path components specified by n
739
    TOML_EXPORTED_MEMBER_FUNCTION
740
    path& truncate(size_t n);
741
742
    /// \brief Returns a toml::path object which has had n terminal path components removed
743
    TOML_NODISCARD
744
    TOML_EXPORTED_MEMBER_FUNCTION
745
    path truncated(size_t n) const;
746
747
    /// \brief  Returns a toml::path object representing the path of the parent node
748
    TOML_NODISCARD
749
    TOML_EXPORTED_MEMBER_FUNCTION
750
    path parent() const;
751
752
    /// \brief  Returns a toml::path object representing terminal n-parts of a TOML path
753
    TOML_NODISCARD
754
    TOML_EXPORTED_MEMBER_FUNCTION
755
    path leaf(size_t n = 1) const;
756
757
    /// \brief  Returns a toml::path object that is a specified subpath of the current path, representing the
758
    /// range of path components from [start, end).
759
    TOML_NODISCARD
760
    TOML_EXPORTED_MEMBER_FUNCTION
761
    path subpath(const_iterator start, const_iterator end) const;
762
763
    /// \brief  Returns a toml::path object that is a specified subpath of the current path, representing the
764
    /// range of path components with indexes from [start, start + length].
765
    TOML_NODISCARD
766
    TOML_EXPORTED_MEMBER_FUNCTION
767
    path subpath(size_t start, size_t length) const;
768
769
    /// @}
770
  };
771
772
  inline namespace literals
773
  {
774
    /// \brief  Parses a TOML path from a string literal.
775
    ///
776
    /// \detail \cpp
777
    /// using namespace toml::literals;
778
    ///
779
    /// auto path = "main.settings.devices[2]"_tpath;
780
    /// std::cout << path.parent_path() << "\n";
781
    /// \ecpp
782
    ///
783
    /// \out
784
    /// main.settings.devices
785
    /// \eout
786
    ///
787
    /// \param  str The string data.
788
    /// \param  len The string length.
789
    ///
790
    /// \returns  A #toml::path generated from the string literal.
791
    TOML_NODISCARD
792
    TOML_ALWAYS_INLINE
793
    path operator""_tpath(const char* str, size_t len)
794
0
    {
795
0
      return path(std::string_view{ str, len });
796
0
    }
797
  }
798
799
  /// \brief Returns a view of the node matching a fully-qualified "TOML path".
800
  ///
801
  /// \detail \cpp
802
  /// auto config = toml::parse(R"(
803
  ///
804
  /// [foo]
805
  /// bar = [ 0, 1, 2, [ 3 ], { kek = 4 } ]
806
  ///
807
  /// )"sv);
808
  ///
809
  /// toml::path path1("foo.bar[2]");
810
  /// toml::path path2("foo.bar[4].kek");
811
  /// std::cout << toml::at_path(config, path1) << "\n";
812
  /// std::cout << toml::at_path(config, path1.parent_path()) << "\n";
813
  /// std::cout << toml::at_path(config, path2) << "\n";
814
  /// std::cout << toml::at_path(config, path2.parent_path()) << "\n";
815
  /// \ecpp
816
  ///
817
  /// \out
818
  /// 2
819
  /// [ 0, 1, 2, [ 3 ], { kek = 4 } ]
820
  /// 4
821
  /// { kek  = 4 }
822
  /// \eout
823
  ///
824
  ///
825
  /// \note Keys in paths are interpreted literally, so whitespace (or lack thereof) matters:
826
  /// \cpp
827
  /// toml::at_path(config, toml::path("foo.bar"))  // same as config["foo"]["bar"]
828
  /// toml::at_path(config, toml::path("foo. bar")) // same as config["foo"][" bar"]
829
  /// toml::at_path(config, toml::path("foo..bar")) // same as config["foo"][""]["bar"]
830
  /// toml::at_path(config, toml::path(".foo.bar")) // same as config[""]["foo"]["bar"]
831
  /// \ecpp
832
  /// <br>
833
  /// Additionally, TOML allows '.' (period) characters to appear in keys if they are quoted strings.
834
  /// This function makes no allowance for this, instead treating all period characters as sub-table delimiters.
835
  ///
836
  /// \param root   The root node from which the path will be traversed.
837
  /// \param path   The "TOML path" to traverse.
838
  TOML_NODISCARD
839
  TOML_EXPORTED_FREE_FUNCTION
840
  node_view<node> TOML_CALLCONV at_path(node & root, const toml::path& path) noexcept;
841
842
  /// \brief Returns a const view of the node matching a fully-qualified "TOML path".
843
  ///
844
  /// \see #toml::at_path(node&, const toml::path& path)
845
  TOML_NODISCARD
846
  TOML_EXPORTED_FREE_FUNCTION
847
  node_view<const node> TOML_CALLCONV at_path(const node& root, const toml::path& path) noexcept;
848
}
849
TOML_NAMESPACE_END;
850
851
#include "header_end.hpp"