JWTXX
C++ library for JWT
Loading...
Searching...
No Matches
value.h
1#pragma once
2
3#include "error.h"
4
5#include <variant>
6#include <string>
7#include <vector>
8#include <unordered_map>
9#include <numeric> // std::accumulate
10#include <type_traits> // std::decay_t, std::is_same_v
11#include <utility> // std::move
12#include <cstdint> // int64_t
13
14namespace JWTXX
15{
16
23class Value
24{
25 public:
30 {
34 explicit Error(const std::string& message) noexcept : JWTXX::Error(message) {}
35 };
36
40 struct Null {};
41
45 using Array = std::vector<Value>;
46
50 using Object = std::unordered_map<std::string, Value>;
51
53 Value() noexcept : m_value(Null{}) {}
54
58 explicit Value(bool v) noexcept : m_value(v) {}
59
63 explicit Value(int64_t v) noexcept : m_value(v) {}
64
68 explicit Value(const char* v) noexcept : m_value(std::string(v)) {}
69
73 explicit Value(std::string v) noexcept : m_value(std::move(v)) {}
74
78 explicit Value(std::initializer_list<Array::value_type> vs) noexcept : m_value(Array(std::move(vs))) {}
79
83 explicit Value(Array v) noexcept : m_value(std::move(v)) {}
84
88 explicit Value(std::initializer_list<Object::value_type> vs) noexcept : m_value(Object(std::move(vs))) {}
89
93 explicit Value(Object v) noexcept : m_value(std::move(v)) {}
94
100 static Value number(double v) noexcept { return Value(std::in_place, V{v}); }
101
103 Value(const Value&) = default;
104
106 Value(Value&&) = default;
107
109 Value& operator=(const Value&) = default;
110
112 Value& operator=(Value&&) = default;
113
115 ~Value() = default;
116
120 bool isNull() const noexcept { return std::holds_alternative<Null>(m_value); }
121
125 bool isBool() const noexcept { return std::holds_alternative<bool>(m_value); }
126
130 bool isInteger() const noexcept { return std::holds_alternative<int64_t>(m_value); }
131
135 bool isString() const noexcept { return std::holds_alternative<std::string>(m_value); }
136
140 bool isArray() const noexcept { return std::holds_alternative<Array>(m_value); }
141
145 bool isObject() const noexcept { return std::holds_alternative<Object>(m_value); }
146
151 bool getBool() const { return get<bool>("Not a boolean value"); }
152
157 int64_t getInteger() const { return get<int64_t>("Not an integer value"); }
158
163 std::string getString() const { return get<std::string>("Not a string value"); }
164
169 Array getArray() const { return get<Array>("Not an array value"); }
170
175 Object getObject() const { return get<Object>("Not an object value"); }
176
181 std::string toString() const;
182
188 template <typename F>
189 auto visit(F&& f) const { return std::visit(f, m_value); }
190 private:
191 using V = std::variant<Null, bool, int64_t, std::string, Array, Object, double>;
192
193 V m_value;
194
195 Value(std::in_place_t /*tag*/, V&& v) noexcept : m_value(std::move(v)) {}
196
197 template <typename T>
198 T get(const std::string& onError) const
199 {
200 const auto* res = std::get_if<T>(&m_value);
201 if (res == nullptr)
202 throw Error(onError);
203 return *res;
204 }
205};
206
207inline
208std::string Value::toString() const
209{
210 return std::visit([](auto&& v) -> std::string {
211 using T = std::decay_t<decltype(v)>;
212 if constexpr (std::is_same_v<T, Null>) {
213 return "null";
214 } else if constexpr (std::is_same_v<T, bool>) {
215 if (v)
216 return "true";
217 return "false";
218 } else if constexpr (std::is_same_v<T, std::string>) {
219 return "\"" + v + "\"";
220 } else if constexpr (std::is_same_v<T, Array>) {
221 return "[" +
222 std::accumulate(v.begin(), v.end(), std::string{}, [](const auto& a, const auto& i){
223 if (a.empty())
224 return i.toString();
225 return a + "," + i.toString();
226 }) +
227 "]";
228 } else if constexpr (std::is_same_v<T, Object>) {
229 return "{" +
230 std::accumulate(v.begin(), v.end(), std::string{}, [](const auto& a, const auto& i){
231 if (a.empty())
232 return "\"" + i.first + "\":" + i.second.toString();
233 return a + ",\"" + i.first + "\":" + i.second.toString();
234 }) +
235 "}";
236 } else {
237 return std::to_string(v);
238 }
239 }, m_value);
240}
241
242}
bool getBool() const
Gets the boolean value.
Definition value.h:151
int64_t getInteger() const
Gets the integer value.
Definition value.h:157
bool isNull() const noexcept
Checks if the value is null.
Definition value.h:120
std::string getString() const
Gets the string value.
Definition value.h:163
bool isObject() const noexcept
Checks if the value is an object.
Definition value.h:145
bool isString() const noexcept
Checks if the value is a string.
Definition value.h:135
static Value number(double v) noexcept
Creates a floating point number Value.
Definition value.h:100
Value(std::string v) noexcept
String constructor.
Definition value.h:73
Value(Object v) noexcept
Object constructor.
Definition value.h:93
Value(const char *v) noexcept
C-string constructor.
Definition value.h:68
Value(Value &&)=default
Move constructor.
bool isInteger() const noexcept
Checks if the value is an integer.
Definition value.h:130
Array getArray() const
Gets the array value.
Definition value.h:169
Object getObject() const
Gets the object value.
Definition value.h:175
Value() noexcept
Default constructor. Creates a null value.
Definition value.h:53
Value(std::initializer_list< Object::value_type > vs) noexcept
Object initializer list constructor.
Definition value.h:88
auto visit(F &&f) const
Applies a visitor function to the value.
Definition value.h:189
std::vector< Value > Array
Represents a JSON array (vector of Values).
Definition value.h:45
Value(Array v) noexcept
Array constructor.
Definition value.h:83
std::string toString() const
Converts the value to its JSON string representation.
Definition value.h:208
Value(int64_t v) noexcept
Integer constructor.
Definition value.h:63
Value(bool v) noexcept
Boolean constructor.
Definition value.h:58
Value & operator=(const Value &)=default
Copy assignment operator.
Value(const Value &)=default
Copy constructor.
bool isBool() const noexcept
Checks if the value is a boolean.
Definition value.h:125
Value & operator=(Value &&)=default
Move assignment operator.
Value(std::initializer_list< Array::value_type > vs) noexcept
Array initializer list constructor.
Definition value.h:78
std::unordered_map< std::string, Value > Object
Represents a JSON object (string to Value map).
Definition value.h:50
bool isArray() const noexcept
Checks if the value is an array.
Definition value.h:140
~Value()=default
Destructor.
All classes, functions and constants are here.
Definition error.h:6
Base class for all exceptions in the library.
Definition error.h:12
Error(const std::string &message) noexcept
Constructor.
Definition value.h:34
Represents a JSON null value.
Definition value.h:40