$darkmode
number.hpp
Go to the documentation of this file.
1 /*
2  * Copyright 2020 Robert Bosch GmbH
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  * SPDX-License-Identifier: Apache-2.0
17  */
24 #pragma once
25 
26 #include <initializer_list> // for initializer_list<>
27 #include <set> // for set<>
28 #include <string> // for string
29 #include <type_traits> // for enable_if_t<>, is_arithmetic<>
30 
31 #include <fable/schema/interface.hpp> // for Base<>
32 
33 namespace fable::schema {
34 
35 template <typename T>
36 class Number : public Base<Number<T>> {
37  static_assert(std::is_arithmetic_v<T>, "arithmetic value required");
38 
39  public: // Types and Constructors
40  using Type = T;
41 
42  template <typename X = T, std::enable_if_t<std::is_integral_v<X> && std::is_unsigned_v<X>, int> = 0>
43  Number(Type* ptr, std::string desc)
44  : Base<Number<T>>(JsonType::number_unsigned, std::move(desc)), ptr_(ptr) {}
45 
46  template <typename X = T, std::enable_if_t<std::is_integral_v<X> && std::is_signed_v<X>, int> = 0>
47  Number(Type* ptr, std::string desc)
48  : Base<Number<T>>(JsonType::number_integer, std::move(desc)), ptr_(ptr) {}
49 
50  template <typename X = T, std::enable_if_t<std::is_floating_point_v<X>, int> = 0>
51  Number(Type* ptr, std::string desc)
52  : Base<Number<T>>(JsonType::number_float, std::move(desc)), ptr_(ptr) {}
53 
54  public: // Special
55  [[nodiscard]] T minimum() const { return value_min_; }
56  void set_minimum(T value);
57  [[nodiscard]] Number<T> minimum(T value) &&;
58 
59  [[nodiscard]] bool exclusive_minimum() const { return exclusive_min_; }
60  void set_exclusive_minimum(T value);
61  [[nodiscard]] Number<T> exclusive_minimum(T value) &&;
62 
63  [[nodiscard]] T maximum() const { return value_max_; }
64  void set_maximum(T value);
65  [[nodiscard]] Number<T> maximum(T value) &&;
66 
67  [[nodiscard]] bool exclusive_maximum() const { return exclusive_max_; }
68  void set_exclusive_maximum(T value);
69  [[nodiscard]] Number<T> exclusive_maximum(T value) &&;
70 
71  [[nodiscard]] std::pair<T, T> bounds() const;
72  void set_bounds(T min, T max);
73  [[nodiscard]] Number<T> bounds(T min, T max) &&;
74 
75  void set_bounds_with(T min, T max, std::initializer_list<T> whitelisted);
76  [[nodiscard]] Number<T> bounds_with(T min, T max, std::initializer_list<T> whitelisted) &&;
77 
78  [[nodiscard]] const std::set<T>& whitelist() const { return whitelist_; }
79  void insert_whitelist(T x);
80  [[nodiscard]] Number<T> whitelist(T x) &&;
81  void reset_whitelist(std::initializer_list<T> xs = {});
82  void extend_whitelist(std::initializer_list<T> xs);
83  [[nodiscard]] Number<T> whitelist(std::initializer_list<T> xs) &&;
84 
85  [[nodiscard]] const std::set<T>& blacklist() const { return blacklist_; }
86  void insert_blacklist(T x);
87  [[nodiscard]] Number<T> blacklist(T x) &&;
88  void reset_blacklist(std::initializer_list<T> xs = {});
89  void extend_blacklist(std::initializer_list<T> xs);
90  [[nodiscard]] Number<T> blacklist(std::initializer_list<T> xs) &&;
91 
92  public: // Overrides
93  [[nodiscard]] Json json_schema() const override;
94  bool validate(const Conf& c, std::optional<SchemaError>& err) const override;
95  using Interface::to_json;
96  void to_json(Json& j) const override;
97  void from_conf(const Conf& c) override;
98  [[nodiscard]] Json serialize(const Type& x) const;
99  [[nodiscard]] Type deserialize(const Conf& c) const;
100  void serialize_into(Json& j, const Type& x) const;
101  void deserialize_into(const Conf& c, Type& x) const;
102  void reset_ptr() override;
103 
104  private:
105  template <typename B>
106  bool validate_bounds(const Conf& c, std::optional<SchemaError>& err) const;
107 
108  private:
109  bool exclusive_min_{false};
110  bool exclusive_max_{false};
111  T value_min_{std::numeric_limits<T>::lowest()};
112  T value_max_{std::numeric_limits<T>::max()};
113  std::set<T> whitelist_{};
114  std::set<T> blacklist_{};
115  Type* ptr_{nullptr};
116 };
117 
118 template <typename T, typename S, std::enable_if_t<std::is_arithmetic_v<T> && !std::is_enum_v<T>, int> = 0>
119 Number<T> make_schema(T* ptr, S&& desc) {
120  return {ptr, std::forward<S>(desc)};
121 }
122 
123 } // namespace fable::schema
Definition: conf.hpp:82
Definition: interface.hpp:398
virtual Json to_json() const
Definition: interface.hpp:254
Definition: number.hpp:36
void from_conf(const Conf &c) override
Definition: number_impl.hpp:245
virtual Json to_json() const
Definition: interface.hpp:254
Json json_schema() const override
Definition: number_impl.hpp:194
void reset_ptr() override
Definition: number_impl.hpp:271
bool validate(const Conf &c, std::optional< SchemaError > &err) const override
Definition: number_impl.hpp:221
nlohmann::json Json
Definition: fable_fwd.hpp:35