Skip to content

Commit 368ef14

Browse files
committed
fable: Use [[nodiscard]] where relevant
Implementing this also highlighted some errors and inconsistencies in the interfaces, which have been resolved.
1 parent e6b94dc commit 368ef14

27 files changed

+421
-286
lines changed

fable/include/fable/conf.hpp

+20-20
Original file line numberDiff line numberDiff line change
@@ -82,17 +82,17 @@ class Conf {
8282
* c) network
8383
* - This method should not throw.
8484
*/
85-
bool is_from_file() const { return !file_.empty(); }
85+
[[nodiscard]] bool is_from_file() const { return !file_.empty(); }
8686

8787
/**
8888
* Return the file associated with this configuration.
8989
*/
90-
const std::string& file() const { return file_; }
90+
[[nodiscard]] const std::string& file() const { return file_; }
9191

9292
/**
9393
* Return whether this configuration is empty.
9494
*/
95-
bool is_empty() const { return data_.is_null(); }
95+
[[nodiscard]] bool is_empty() const { return data_.is_null(); }
9696

9797
/**
9898
* Return a reference to the JSON.
@@ -113,25 +113,25 @@ class Conf {
113113
/**
114114
* Return the root of the current JSON as a JSON pointer.
115115
*/
116-
std::string root() const { return (root_.empty() ? "/" : root_); }
116+
[[nodiscard]] std::string root() const { return (root_.empty() ? "/" : root_); }
117117

118118
/**
119119
* Return whether the key is present in the configuration.
120120
*
121121
* - This method should not throw.
122122
*/
123-
bool has(const std::string& key) const { return data_.count(key) != 0; }
124-
bool has(const JsonPointer& key) const;
125-
bool has_pointer(const std::string& key) const { return has(JsonPointer(key)); }
123+
[[nodiscard]] bool has(const std::string& key) const { return data_.count(key) != 0; }
124+
[[nodiscard]] bool has(const JsonPointer& key) const;
125+
[[nodiscard]] bool has_pointer(const std::string& key) const { return has(JsonPointer(key)); }
126126

127127
/**
128128
* Return a new Conf basing off the JSON pointer.
129129
*
130130
* - Throws a ConfError if the key cannot be found.
131131
*/
132-
Conf at(const std::string& key) const;
133-
Conf at(const JsonPointer& key) const;
134-
Conf at_pointer(const std::string& key) const { return at(JsonPointer(key)); }
132+
[[nodiscard]] Conf at(const std::string& key) const;
133+
[[nodiscard]] Conf at(const JsonPointer& key) const;
134+
[[nodiscard]] Conf at_pointer(const std::string& key) const { return at(JsonPointer(key)); }
135135

136136
/**
137137
* Erase a key from the Conf if it exists and return the number of elements
@@ -146,15 +146,15 @@ class Conf {
146146
*
147147
* - Throws a ConfError if the object is not an array.
148148
*/
149-
std::vector<Conf> to_array() const;
149+
[[nodiscard]] std::vector<Conf> to_array() const;
150150

151151
/**
152152
* Return a value of type T.
153153
*
154154
* - Throws a ConfError if the key is of the wrong type.
155155
*/
156156
template <typename T>
157-
T get() const {
157+
[[nodiscard]] T get() const {
158158
try {
159159
return data_.get<T>();
160160
} catch (nlohmann::detail::type_error&) {
@@ -168,7 +168,7 @@ class Conf {
168168
* - Throws a ConfError if the key cannot be found or is wrong type.
169169
*/
170170
template <typename T>
171-
T get(const std::string& key) const {
171+
[[nodiscard]] T get(const std::string& key) const {
172172
try {
173173
return data_.at(key).get<T>();
174174
} catch (nlohmann::detail::out_of_range&) {
@@ -179,7 +179,7 @@ class Conf {
179179
}
180180

181181
template <typename T>
182-
T get(const JsonPointer& key) const {
182+
[[nodiscard]] T get(const JsonPointer& key) const {
183183
try {
184184
return data_.at(key).get<T>();
185185
} catch (nlohmann::detail::out_of_range&) {
@@ -190,7 +190,7 @@ class Conf {
190190
}
191191

192192
template <typename T>
193-
T get_pointer(const std::string& key) const {
193+
[[nodiscard]] T get_pointer(const std::string& key) const {
194194
return get<T>(JsonPointer(key));
195195
}
196196

@@ -199,7 +199,7 @@ class Conf {
199199
* key cannot be found.
200200
*/
201201
template <typename T>
202-
T get_or(const std::string& key, T def) const {
202+
[[nodiscard]] T get_or(const std::string& key, T def) const {
203203
if (!data_.count(key)) {
204204
return def;
205205
}
@@ -211,7 +211,7 @@ class Conf {
211211
}
212212

213213
template <typename T>
214-
T get_or(const JsonPointer& key, T def) const {
214+
[[nodiscard]] T get_or(const JsonPointer& key, T def) const {
215215
try {
216216
return data_.at(key).get<T>();
217217
} catch (nlohmann::detail::out_of_range&) {
@@ -222,7 +222,7 @@ class Conf {
222222
}
223223

224224
template <typename T>
225-
T get_pointer_or(const std::string& key, T def) const {
225+
[[nodiscard]] T get_pointer_or(const std::string& key, T def) const {
226226
return get_or(key, def);
227227
}
228228

@@ -318,8 +318,8 @@ class Conf {
318318
* - If the path is relative and file is not stdin, return relative to
319319
* the file.
320320
*/
321-
std::filesystem::path resolve_file(const std::filesystem::path& filename) const;
322-
std::string resolve_file(const std::string& filename) const;
321+
[[nodiscard]] std::filesystem::path resolve_file(const std::filesystem::path& filename) const;
322+
[[nodiscard]] std::string resolve_file(const std::string& filename) const;
323323

324324
template <typename... Args>
325325
[[noreturn]] void throw_error(std::string_view format, Args&&... args) const {

fable/include/fable/confable.hpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -66,15 +66,15 @@ class Confable {
6666
* This method uses `schema_impl` under the hood, which the object should
6767
* implement.
6868
*/
69-
Schema& schema();
69+
[[nodiscard]] Schema& schema();
7070

7171
/**
7272
* Return the object schema for description and validation.
7373
*
7474
* This method uses `schema_impl` under the hood, which the object should
7575
* implement.
7676
*/
77-
const Schema& schema() const;
77+
[[nodiscard]] const Schema& schema() const;
7878

7979
/**
8080
* Validate a Conf without applying it.
@@ -128,7 +128,7 @@ class Confable {
128128
/**
129129
* Serialize a Confable to Json.
130130
*/
131-
Json to_json() const;
131+
[[nodiscard]] Json to_json() const;
132132

133133
protected:
134134
/**
@@ -138,7 +138,7 @@ class Confable {
138138
* object is created or moved, since Schema contains references to fields
139139
* that (should be) in the object.
140140
*/
141-
virtual Schema schema_impl();
141+
[[nodiscard]] virtual Schema schema_impl();
142142

143143
private:
144144
mutable std::unique_ptr<Schema> schema_;

fable/include/fable/environment.hpp

+17-13
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,10 @@ class Environment {
4242
Environment(std::map<std::string, std::string>&& defines) : defines_(std::move(defines)) {}
4343
~Environment() = default;
4444

45-
bool prefer_external() const { return prefer_external_; }
45+
[[nodiscard]] bool prefer_external() const { return prefer_external_; }
4646
void prefer_external(bool value) { prefer_external_ = value; }
4747

48-
bool allow_undefined() const { return allow_undefined_; }
48+
[[nodiscard]] bool allow_undefined() const { return allow_undefined_; }
4949
void allow_undefined(bool value) { allow_undefined_ = value; }
5050

5151
void insert(const std::string& key, const std::string& value) {
@@ -64,10 +64,10 @@ class Environment {
6464
*
6565
* This is roughly equivalent to ${KEY}.
6666
*/
67-
std::optional<std::string> get(const std::string& key) const {
67+
[[nodiscard]] std::optional<std::string> get(const std::string& key) const {
6868
return get(key, prefer_external_);
6969
}
70-
std::optional<std::string> get(const std::string& key, bool prefer_external) const;
70+
[[nodiscard]] std::optional<std::string> get(const std::string& key, bool prefer_external) const;
7171

7272
/**
7373
* Return the value of a literal key, trying both environment and internal
@@ -77,11 +77,11 @@ class Environment {
7777
*
7878
* This is equivalent to ${KEY-ALTERNATIVE}, and cannot fail.
7979
*/
80-
std::string get_or(const std::string& key, const std::string& alternative) const {
80+
[[nodiscard]] std::string get_or(const std::string& key, const std::string& alternative) const {
8181
return get(key).value_or(alternative);
8282
}
83-
std::string get_or(const std::string& key, const std::string& alternative,
84-
bool prefer_external) const {
83+
[[nodiscard]] std::string get_or(const std::string& key, const std::string& alternative,
84+
bool prefer_external) const {
8585
return get(key, prefer_external).value_or(alternative);
8686
}
8787

@@ -93,30 +93,34 @@ class Environment {
9393
*
9494
* This is roughly equivalent to ${KEY?out_of_range}.
9595
*/
96-
std::string require(const std::string& key) const { return require(key, prefer_external_); }
97-
std::string require(const std::string& key, bool prefer_external) const;
96+
[[nodiscard]] std::string require(const std::string& key) const {
97+
return require(key, prefer_external_);
98+
}
99+
[[nodiscard]] std::string require(const std::string& key, bool prefer_external) const;
98100

99101
/**
100102
* Evaluate a single variable, such as "KEY" or "KEY-ALTERNATIVE".
101103
*
102104
* Throws std::out_of_range if allow_undefined() is false and
103105
* std::invalid_argument if a malformed string is supplied.
104106
*/
105-
std::string evaluate(const std::string& s) const {
107+
[[nodiscard]] std::string evaluate(const std::string& s) const {
106108
return evaluate(s, prefer_external_, allow_undefined_);
107109
}
108-
std::string evaluate(const std::string& s, bool prefer_external, bool allow_undefined) const;
110+
[[nodiscard]] std::string evaluate(const std::string& s, bool prefer_external,
111+
bool allow_undefined) const;
109112

110113
/**
111114
* Interpolate a string will evaluate all variable instances in a string.
112115
*
113116
* Throws std::out_of_range if allow_undefined() is false and
114117
* std::invalid_argument if a malformed string is supplied.
115118
*/
116-
std::string interpolate(const std::string& s) const {
119+
[[nodiscard]] std::string interpolate(const std::string& s) const {
117120
return interpolate(s, prefer_external_, allow_undefined_);
118121
}
119-
std::string interpolate(const std::string& s, bool prefer_external, bool allow_undefined) const;
122+
[[nodiscard]] std::string interpolate(const std::string& s, bool prefer_external,
123+
bool allow_undefined) const;
120124

121125
private:
122126
bool prefer_external_{true};

fable/include/fable/error.hpp

+7-7
Original file line numberDiff line numberDiff line change
@@ -66,12 +66,12 @@ class ConfError : public Error {
6666
ConfError(const Conf& c, std::string_view format, Args&&... args)
6767
: Error(format, std::forward<Args>(args)...), data_(c) {}
6868

69-
std::string file() const { return data_.file(); }
70-
std::string root() const { return data_.root(); }
71-
const Conf& conf() const { return data_; }
72-
const Json& data() const { return *data_; }
69+
[[nodiscard]] std::string file() const noexcept { return data_.file(); }
70+
[[nodiscard]] std::string root() const noexcept { return data_.root(); }
71+
[[nodiscard]] const Conf& conf() const noexcept { return data_; }
72+
[[nodiscard]] const Json& data() const noexcept { return *data_; }
7373

74-
virtual std::string message() const {
74+
[[nodiscard]] virtual std::string message() const {
7575
return fmt::format("{}:{}: {}", file(), root(), this->what());
7676
}
7777

@@ -170,8 +170,8 @@ class SchemaError : public ConfError {
170170
: ConfError(c, format, std::forward<Args>(args)...), schema_(s), context_(ctx) {}
171171

172172
public: // Special
173-
const Json& schema() const { return schema_; }
174-
const Json& context() const { return context_; }
173+
[[nodiscard]] const Json& schema() const { return schema_; }
174+
[[nodiscard]] const Json& context() const { return context_; }
175175

176176
friend void to_json(Json& j, const SchemaError& e) {
177177
j = Json{

fable/include/fable/schema.hpp

+13-11
Original file line numberDiff line numberDiff line change
@@ -229,13 +229,13 @@ class Schema : public schema::Interface {
229229
return std::move(*this);
230230
}
231231

232-
Json json_schema_qualified() const {
232+
[[nodiscard]] Json json_schema_qualified() const {
233233
Json j = impl_->json_schema();
234234
j["$schema"] = "http://json-schema.org/draft-07/schema#";
235235
return j;
236236
}
237237

238-
Json json_schema_qualified(const std::string& id) const {
238+
[[nodiscard]] Json json_schema_qualified(const std::string& id) const {
239239
Json j = json_schema_qualified();
240240
j["$id"] = id;
241241
return j;
@@ -245,16 +245,18 @@ class Schema : public schema::Interface {
245245

246246
public: // Overrides
247247
using Interface::to_json;
248-
operator schema::Box() const { return schema::Box{impl_}; }
249-
Interface* clone() const override { return impl_->clone(); }
250-
JsonType type() const override { return impl_->type(); }
251-
std::string type_string() const override { return impl_->type_string(); }
252-
bool is_required() const override { return impl_->is_required(); }
253-
const std::string& description() const override { return impl_->description(); }
248+
[[nodiscard]] operator schema::Box() const { return schema::Box{impl_}; }
249+
[[nodiscard]] Interface* clone() const override { return impl_->clone(); }
250+
[[nodiscard]] JsonType type() const override { return impl_->type(); }
251+
[[nodiscard]] std::string type_string() const override { return impl_->type_string(); }
252+
[[nodiscard]] bool is_required() const override { return impl_->is_required(); }
253+
[[nodiscard]] const std::string& description() const override { return impl_->description(); }
254254
void set_description(std::string s) override { return impl_->set_description(std::move(s)); }
255-
Json usage() const override { return impl_->usage(); }
256-
Json json_schema() const override { return impl_->json_schema(); }
257-
bool validate(const Conf& c, std::optional<SchemaError>& err) const override { return impl_->validate(c, err); }
255+
[[nodiscard]] Json usage() const override { return impl_->usage(); }
256+
[[nodiscard]] Json json_schema() const override { return impl_->json_schema(); }
257+
bool validate(const Conf& c, std::optional<SchemaError>& err) const override {
258+
return impl_->validate(c, err);
259+
}
258260
void to_json(Json& j) const override { impl_->to_json(j); }
259261
void from_conf(const Conf& c) override { impl_->from_conf(c); }
260262
void reset_ptr() override { impl_->reset_ptr(); }

fable/include/fable/schema/array.hpp

+8-8
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ class Array : public Base<Array<T, N, P>> {
115115
*
116116
* By default, this is false.
117117
*/
118-
bool require_all() const { return option_require_all_; }
118+
[[nodiscard]] bool require_all() const { return option_require_all_; }
119119

120120
/**
121121
* Set whether deserialization requires setting the entire array.
@@ -144,15 +144,15 @@ class Array : public Base<Array<T, N, P>> {
144144
*
145145
* \see set_require_all(bool)
146146
*/
147-
Array<T, N, P> require_all(bool value) && {
147+
[[nodiscard]] Array<T, N, P> require_all(bool value) && {
148148
this->set_require_all(value);
149149
return std::move(*this);
150150
}
151151

152152
public: // Overrides
153-
std::string type_string() const override { return "array of " + prototype_.type_string(); }
153+
[[nodiscard]] std::string type_string() const override { return "array of " + prototype_.type_string(); }
154154

155-
Json json_schema() const override {
155+
[[nodiscard]] Json json_schema() const override {
156156
Json j;
157157
if (option_require_all_) {
158158
j = this->json_schema_array();
@@ -203,7 +203,7 @@ class Array : public Base<Array<T, N, P>> {
203203
this->deserialize_into(c, *ptr_);
204204
}
205205

206-
Json serialize(const Type& xs) const {
206+
[[nodiscard]] Json serialize(const Type& xs) const {
207207
Json j = Json::array();
208208
serialize_into(j, xs);
209209
return j;
@@ -225,7 +225,7 @@ class Array : public Base<Array<T, N, P>> {
225225
* Because it's not pre-existing, we can't guarantee that it will be
226226
* initialized and therefore only support setting the full array.
227227
*/
228-
Type deserialize(const Conf& c) const {
228+
[[nodiscard]] Type deserialize(const Conf& c) const {
229229
Type array;
230230
this->deserialize_into(c, array);
231231
return array;
@@ -244,7 +244,7 @@ class Array : public Base<Array<T, N, P>> {
244244
void reset_ptr() override { ptr_ = nullptr; }
245245

246246
private:
247-
Json json_schema_array() const {
247+
[[nodiscard]] Json json_schema_array() const {
248248
return Json::object({
249249
{"type", "array"},
250250
{"items", prototype_.json_schema()},
@@ -253,7 +253,7 @@ class Array : public Base<Array<T, N, P>> {
253253
});
254254
}
255255

256-
Json json_schema_object() const {
256+
[[nodiscard]] Json json_schema_object() const {
257257
return Json::object({
258258
{"type", "object"},
259259
{"additionalProperties", false},

0 commit comments

Comments
 (0)