1 #ifndef SIMDJSON_CONCEPTS_H
2 #define SIMDJSON_CONCEPTS_H
3 #if SIMDJSON_SUPPORTS_DESERIALIZATION
12 #define SIMDJSON_IMPL_CONCEPT(name, method) \
13 template <typename T> \
14 concept supports_##name = !std::is_const_v<T> && requires { \
15 typename std::remove_cvref_t<T>::value_type; \
16 requires requires(typename std::remove_cvref_t<T>::value_type &&val, \
18 obj.method(std::move(val)); \
19 requires !requires { obj = std::move(val); }; \
23 SIMDJSON_IMPL_CONCEPT(emplace_back, emplace_back);
24 SIMDJSON_IMPL_CONCEPT(emplace, emplace);
25 SIMDJSON_IMPL_CONCEPT(push_back, push_back);
26 SIMDJSON_IMPL_CONCEPT(add, add);
27 SIMDJSON_IMPL_CONCEPT(push, push);
28 SIMDJSON_IMPL_CONCEPT(append, append);
29 SIMDJSON_IMPL_CONCEPT(insert, insert);
30 SIMDJSON_IMPL_CONCEPT(op_append,
operator+=);
32 #undef SIMDJSON_IMPL_CONCEPT
38 concept appendable_containers =
39 details::supports_emplace_back<T> || details::supports_emplace<T> ||
40 details::supports_push_back<T> || details::supports_push<T> ||
41 details::supports_add<T> || details::supports_append<T> ||
42 details::supports_insert<T>;
45 template <appendable_containers T,
typename... Args>
46 constexpr decltype(
auto) emplace_one(T &vec, Args &&...args) {
47 if constexpr (details::supports_emplace_back<T>) {
48 return vec.emplace_back(std::forward<Args>(args)...);
49 }
else if constexpr (details::supports_emplace<T>) {
50 return vec.emplace(std::forward<Args>(args)...);
51 }
else if constexpr (details::supports_push_back<T>) {
52 return vec.push_back(std::forward<Args>(args)...);
53 }
else if constexpr (details::supports_push<T>) {
54 return vec.push(std::forward<Args>(args)...);
55 }
else if constexpr (details::supports_add<T>) {
56 return vec.add(std::forward<Args>(args)...);
57 }
else if constexpr (details::supports_append<T>) {
58 return vec.append(std::forward<Args>(args)...);
59 }
else if constexpr (details::supports_insert<T>) {
60 return vec.insert(std::forward<Args>(args)...);
61 }
else if constexpr (details::supports_op_append<T> &&
sizeof...(Args) == 1) {
62 return vec.operator+=(std::forward<Args>(args)...);
64 static_assert(!
sizeof(T *),
65 "We don't know how to add things to this container");
73 concept returns_reference = appendable_containers<T> && requires {
74 typename std::remove_cvref_t<T>::reference;
75 requires requires(
typename std::remove_cvref_t<T>::value_type &&val, T obj) {
77 emplace_one(obj, std::move(val))
78 } -> std::same_as<typename std::remove_cvref_t<T>::reference>;
83 concept smart_pointer = requires(std::remove_cvref_t<T> ptr) {
85 typename std::remove_cvref_t<T>::element_type;
90 } -> std::same_as<typename std::remove_cvref_t<T>::element_type *>;
93 { *ptr } -> std::same_as<typename std::remove_cvref_t<T>::element_type &>;
97 concept optional_type = requires(std::remove_cvref_t<T> obj) {
98 typename std::remove_cvref_t<T>::value_type;
99 { obj.value() } -> std::same_as<typename std::remove_cvref_t<T>::value_type&>;
100 requires requires(
typename std::remove_cvref_t<T>::value_type &&val) {
101 obj.emplace(std::move(val));
102 obj = std::move(val);
105 } -> std::convertible_to<typename std::remove_cvref_t<T>::value_type>;
107 {
static_cast<bool>(obj) } -> std::same_as<bool>;
The top level simdjson namespace, containing everything the library provides.