annotate dep/toml11/toml/region.hpp @ 324:5d3c9b31aa6e

anime: add completed date member
author Paper <paper@paper.us.eu.org>
date Wed, 12 Jun 2024 23:03:22 -0400
parents 3b355fa948c7
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
318
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
1 // Copyright Toru Niina 2017.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
2 // Distributed under the MIT License.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
3 #ifndef TOML11_REGION_HPP
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
4 #define TOML11_REGION_HPP
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
5 #include <memory>
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
6 #include <vector>
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
7 #include <algorithm>
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
8 #include <initializer_list>
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
9 #include <iterator>
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
10 #include <iomanip>
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
11 #include <cassert>
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
12 #include "color.hpp"
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
13
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
14 namespace toml
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
15 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
16 namespace detail
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
17 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
18
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
19 // helper function to avoid std::string(0, 'c') or std::string(iter, iter)
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
20 template<typename Iterator>
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
21 std::string make_string(Iterator first, Iterator last)
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
22 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
23 if(first == last) {return "";}
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
24 return std::string(first, last);
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
25 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
26 inline std::string make_string(std::size_t len, char c)
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
27 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
28 if(len == 0) {return "";}
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
29 return std::string(len, c);
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
30 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
31
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
32 // region_base is a base class of location and region that are defined below.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
33 // it will be used to generate better error messages.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
34 struct region_base
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
35 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
36 region_base() = default;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
37 virtual ~region_base() = default;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
38 region_base(const region_base&) = default;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
39 region_base(region_base&& ) = default;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
40 region_base& operator=(const region_base&) = default;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
41 region_base& operator=(region_base&& ) = default;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
42
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
43 virtual bool is_ok() const noexcept {return false;}
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
44 virtual char front() const noexcept {return '\0';}
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
45
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
46 virtual std::string str() const {return std::string("unknown region");}
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
47 virtual std::string name() const {return std::string("unknown file");}
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
48 virtual std::string line() const {return std::string("unknown line");}
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
49 virtual std::string line_num() const {return std::string("?");}
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
50
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
51 // length of the region
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
52 virtual std::size_t size() const noexcept {return 0;}
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
53 // number of characters in the line before the region
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
54 virtual std::size_t before() const noexcept {return 0;}
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
55 // number of characters in the line after the region
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
56 virtual std::size_t after() const noexcept {return 0;}
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
57
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
58 virtual std::vector<std::string> comments() const {return {};}
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
59 // ```toml
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
60 // # comment_before
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
61 // key = "value" # comment_inline
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
62 // ```
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
63 };
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
64
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
65 // location represents a position in a container, which contains a file content.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
66 // it can be considered as a region that contains only one character.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
67 //
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
68 // it contains pointer to the file content and iterator that points the current
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
69 // location.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
70 struct location final : public region_base
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
71 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
72 using const_iterator = typename std::vector<char>::const_iterator;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
73 using difference_type = typename std::iterator_traits<const_iterator>::difference_type;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
74 using source_ptr = std::shared_ptr<const std::vector<char>>;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
75
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
76 location(std::string source_name, std::vector<char> cont)
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
77 : source_(std::make_shared<std::vector<char>>(std::move(cont))),
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
78 line_number_(1), source_name_(std::move(source_name)), iter_(source_->cbegin())
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
79 {}
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
80 location(std::string source_name, const std::string& cont)
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
81 : source_(std::make_shared<std::vector<char>>(cont.begin(), cont.end())),
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
82 line_number_(1), source_name_(std::move(source_name)), iter_(source_->cbegin())
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
83 {}
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
84
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
85 location(const location&) = default;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
86 location(location&&) = default;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
87 location& operator=(const location&) = default;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
88 location& operator=(location&&) = default;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
89 ~location() = default;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
90
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
91 bool is_ok() const noexcept override {return static_cast<bool>(source_);}
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
92 char front() const noexcept override {return *iter_;}
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
93
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
94 // this const prohibits codes like `++(loc.iter())`.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
95 std::add_const<const_iterator>::type iter() const noexcept {return iter_;}
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
96
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
97 const_iterator begin() const noexcept {return source_->cbegin();}
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
98 const_iterator end() const noexcept {return source_->cend();}
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
99
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
100 // XXX `location::line_num()` used to be implemented using `std::count` to
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
101 // count a number of '\n'. But with a long toml file (typically, 10k lines),
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
102 // it becomes intolerably slow because each time it generates error messages,
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
103 // it counts '\n' from thousands of characters. To workaround it, I decided
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
104 // to introduce `location::line_number_` member variable and synchronize it
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
105 // to the location changes the point to look. So an overload of `iter()`
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
106 // which returns mutable reference is removed and `advance()`, `retrace()`
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
107 // and `reset()` is added.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
108 void advance(difference_type n = 1) noexcept
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
109 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
110 this->line_number_ += static_cast<std::size_t>(
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
111 std::count(this->iter_, std::next(this->iter_, n), '\n'));
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
112 this->iter_ += n;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
113 return;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
114 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
115 void retrace(difference_type n = 1) noexcept
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
116 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
117 this->line_number_ -= static_cast<std::size_t>(
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
118 std::count(std::prev(this->iter_, n), this->iter_, '\n'));
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
119 this->iter_ -= n;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
120 return;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
121 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
122 void reset(const_iterator rollback) noexcept
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
123 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
124 // since c++11, std::distance works in both ways for random-access
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
125 // iterators and returns a negative value if `first > last`.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
126 if(0 <= std::distance(rollback, this->iter_)) // rollback < iter
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
127 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
128 this->line_number_ -= static_cast<std::size_t>(
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
129 std::count(rollback, this->iter_, '\n'));
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
130 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
131 else // iter < rollback [[unlikely]]
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
132 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
133 this->line_number_ += static_cast<std::size_t>(
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
134 std::count(this->iter_, rollback, '\n'));
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
135 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
136 this->iter_ = rollback;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
137 return;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
138 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
139
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
140 std::string str() const override {return make_string(1, *this->iter());}
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
141 std::string name() const override {return source_name_;}
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
142
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
143 std::string line_num() const override
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
144 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
145 return std::to_string(this->line_number_);
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
146 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
147
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
148 std::string line() const override
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
149 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
150 return make_string(this->line_begin(), this->line_end());
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
151 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
152
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
153 const_iterator line_begin() const noexcept
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
154 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
155 using reverse_iterator = std::reverse_iterator<const_iterator>;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
156 return std::find(reverse_iterator(this->iter()),
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
157 reverse_iterator(this->begin()), '\n').base();
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
158 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
159 const_iterator line_end() const noexcept
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
160 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
161 return std::find(this->iter(), this->end(), '\n');
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
162 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
163
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
164 // location is always points a character. so the size is 1.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
165 std::size_t size() const noexcept override
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
166 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
167 return 1u;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
168 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
169 std::size_t before() const noexcept override
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
170 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
171 const auto sz = std::distance(this->line_begin(), this->iter());
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
172 assert(sz >= 0);
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
173 return static_cast<std::size_t>(sz);
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
174 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
175 std::size_t after() const noexcept override
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
176 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
177 const auto sz = std::distance(this->iter(), this->line_end());
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
178 assert(sz >= 0);
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
179 return static_cast<std::size_t>(sz);
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
180 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
181
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
182 source_ptr const& source() const& noexcept {return source_;}
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
183 source_ptr&& source() && noexcept {return std::move(source_);}
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
184
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
185 private:
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
186
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
187 source_ptr source_;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
188 std::size_t line_number_;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
189 std::string source_name_;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
190 const_iterator iter_;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
191 };
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
192
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
193 // region represents a range in a container, which contains a file content.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
194 //
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
195 // it contains pointer to the file content and iterator that points the first
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
196 // and last location.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
197 struct region final : public region_base
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
198 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
199 using const_iterator = typename std::vector<char>::const_iterator;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
200 using source_ptr = std::shared_ptr<const std::vector<char>>;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
201
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
202 // delete default constructor. source_ never be null.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
203 region() = delete;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
204
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
205 explicit region(const location& loc)
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
206 : source_(loc.source()), source_name_(loc.name()),
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
207 first_(loc.iter()), last_(loc.iter())
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
208 {}
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
209 explicit region(location&& loc)
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
210 : source_(loc.source()), source_name_(loc.name()),
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
211 first_(loc.iter()), last_(loc.iter())
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
212 {}
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
213
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
214 region(const location& loc, const_iterator f, const_iterator l)
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
215 : source_(loc.source()), source_name_(loc.name()), first_(f), last_(l)
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
216 {}
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
217 region(location&& loc, const_iterator f, const_iterator l)
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
218 : source_(loc.source()), source_name_(loc.name()), first_(f), last_(l)
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
219 {}
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
220
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
221 region(const region&) = default;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
222 region(region&&) = default;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
223 region& operator=(const region&) = default;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
224 region& operator=(region&&) = default;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
225 ~region() = default;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
226
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
227 region& operator+=(const region& other)
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
228 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
229 // different regions cannot be concatenated
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
230 assert(this->source_ == other.source_ && this->last_ == other.first_);
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
231
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
232 this->last_ = other.last_;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
233 return *this;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
234 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
235
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
236 bool is_ok() const noexcept override {return static_cast<bool>(source_);}
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
237 char front() const noexcept override {return *first_;}
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
238
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
239 std::string str() const override {return make_string(first_, last_);}
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
240 std::string line() const override
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
241 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
242 if(this->contain_newline())
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
243 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
244 return make_string(this->line_begin(),
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
245 std::find(this->line_begin(), this->last(), '\n'));
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
246 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
247 return make_string(this->line_begin(), this->line_end());
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
248 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
249 std::string line_num() const override
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
250 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
251 return std::to_string(1 + std::count(this->begin(), this->first(), '\n'));
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
252 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
253
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
254 std::size_t size() const noexcept override
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
255 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
256 const auto sz = std::distance(first_, last_);
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
257 assert(sz >= 0);
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
258 return static_cast<std::size_t>(sz);
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
259 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
260 std::size_t before() const noexcept override
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
261 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
262 const auto sz = std::distance(this->line_begin(), this->first());
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
263 assert(sz >= 0);
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
264 return static_cast<std::size_t>(sz);
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
265 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
266 std::size_t after() const noexcept override
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
267 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
268 const auto sz = std::distance(this->last(), this->line_end());
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
269 assert(sz >= 0);
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
270 return static_cast<std::size_t>(sz);
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
271 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
272
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
273 bool contain_newline() const noexcept
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
274 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
275 return std::find(this->first(), this->last(), '\n') != this->last();
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
276 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
277
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
278 const_iterator line_begin() const noexcept
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
279 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
280 using reverse_iterator = std::reverse_iterator<const_iterator>;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
281 return std::find(reverse_iterator(this->first()),
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
282 reverse_iterator(this->begin()), '\n').base();
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
283 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
284 const_iterator line_end() const noexcept
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
285 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
286 return std::find(this->last(), this->end(), '\n');
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
287 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
288
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
289 const_iterator begin() const noexcept {return source_->cbegin();}
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
290 const_iterator end() const noexcept {return source_->cend();}
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
291 const_iterator first() const noexcept {return first_;}
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
292 const_iterator last() const noexcept {return last_;}
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
293
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
294 source_ptr const& source() const& noexcept {return source_;}
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
295 source_ptr&& source() && noexcept {return std::move(source_);}
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
296
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
297 std::string name() const override {return source_name_;}
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
298
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
299 std::vector<std::string> comments() const override
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
300 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
301 // assuming the current region (`*this`) points a value.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
302 // ```toml
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
303 // a = "value"
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
304 // ^^^^^^^- this region
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
305 // ```
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
306 using rev_iter = std::reverse_iterator<const_iterator>;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
307
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
308 std::vector<std::string> com{};
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
309 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
310 // find comments just before the current region.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
311 // ```toml
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
312 // # this should be collected.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
313 // # this also.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
314 // a = value # not this.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
315 // ```
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
316
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
317 // # this is a comment for `a`, not array elements.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
318 // a = [1, 2, 3, 4, 5]
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
319 if(this->first() == std::find_if(this->line_begin(), this->first(),
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
320 [](const char c) noexcept -> bool {return c == '[' || c == '{';}))
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
321 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
322 auto iter = this->line_begin(); // points the first character
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
323 while(iter != this->begin())
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
324 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
325 iter = std::prev(iter);
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
326
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
327 // range [line_start, iter) represents the previous line
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
328 const auto line_start = std::find(
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
329 rev_iter(iter), rev_iter(this->begin()), '\n').base();
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
330 const auto comment_found = std::find(line_start, iter, '#');
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
331 if(comment_found == iter)
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
332 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
333 break; // comment not found.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
334 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
335
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
336 // exclude the following case.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
337 // > a = "foo" # comment // <-- this is not a comment for b but a.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
338 // > b = "current value"
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
339 if(std::all_of(line_start, comment_found,
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
340 [](const char c) noexcept -> bool {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
341 return c == ' ' || c == '\t';
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
342 }))
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
343 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
344 // unwrap the first '#' by std::next.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
345 auto s = make_string(std::next(comment_found), iter);
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
346 if(!s.empty() && s.back() == '\r') {s.pop_back();}
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
347 com.push_back(std::move(s));
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
348 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
349 else
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
350 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
351 break;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
352 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
353 iter = line_start;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
354 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
355 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
356 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
357
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
358 if(com.size() > 1)
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
359 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
360 std::reverse(com.begin(), com.end());
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
361 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
362
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
363 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
364 // find comments just after the current region.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
365 // ```toml
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
366 // # not this.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
367 // a = value # this one.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
368 // a = [ # not this (technically difficult)
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
369 //
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
370 // ] # and this.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
371 // ```
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
372 // The reason why it's difficult is that it requires parsing in the
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
373 // following case.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
374 // ```toml
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
375 // a = [ 10 # this comment is for `10`. not for `a` but `a[0]`.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
376 // # ...
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
377 // ] # this is apparently a comment for a.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
378 //
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
379 // b = [
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
380 // 3.14 ] # there is no way to add a comment to `3.14` currently.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
381 //
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
382 // c = [
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
383 // 3.14 # do this if you need a comment here.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
384 // ]
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
385 // ```
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
386 const auto comment_found =
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
387 std::find(this->last(), this->line_end(), '#');
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
388 if(comment_found != this->line_end()) // '#' found
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
389 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
390 // table = {key = "value"} # what is this for?
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
391 // the above comment is not for "value", but {key="value"}.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
392 if(comment_found == std::find_if(this->last(), comment_found,
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
393 [](const char c) noexcept -> bool {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
394 return !(c == ' ' || c == '\t' || c == ',');
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
395 }))
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
396 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
397 // unwrap the first '#' by std::next.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
398 auto s = make_string(std::next(comment_found), this->line_end());
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
399 if(!s.empty() && s.back() == '\r') {s.pop_back();}
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
400 com.push_back(std::move(s));
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
401 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
402 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
403 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
404 return com;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
405 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
406
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
407 private:
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
408
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
409 source_ptr source_;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
410 std::string source_name_;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
411 const_iterator first_, last_;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
412 };
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
413
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
414 } // detail
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
415 } // toml
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
416 #endif// TOML11_REGION_H