simdjson  3.11.0
Ridiculously Fast JSON
concepts.h
1 #ifndef SIMDJSON_CONCEPTS_H
2 #define SIMDJSON_CONCEPTS_H
3 #if SIMDJSON_SUPPORTS_DESERIALIZATION
4 
5 #include <concepts>
6 #include <type_traits>
7 
8 namespace simdjson {
9 namespace concepts {
10 
11 namespace details {
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, \
17  T obj) { \
18  obj.method(std::move(val)); \
19  requires !requires { obj = std::move(val); }; \
20  }; \
21  };
22 
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+=);
31 
32 #undef SIMDJSON_IMPL_CONCEPT
33 } // namespace details
34 
37 template <typename T>
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>;
43 
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)...);
63  } else {
64  static_assert(!sizeof(T *),
65  "We don't know how to add things to this container");
66  }
67 }
68 
72 template <typename T>
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) {
76  {
77  emplace_one(obj, std::move(val))
78  } -> std::same_as<typename std::remove_cvref_t<T>::reference>;
79  };
80 };
81 
82 template <typename T>
83 concept smart_pointer = requires(std::remove_cvref_t<T> ptr) {
84  // Check if T has a member type named element_type
85  typename std::remove_cvref_t<T>::element_type;
86 
87  // Check if T has a get() member function
88  {
89  ptr.get()
90  } -> std::same_as<typename std::remove_cvref_t<T>::element_type *>;
91 
92  // Check if T can be dereferenced
93  { *ptr } -> std::same_as<typename std::remove_cvref_t<T>::element_type &>;
94 };
95 
96 template <typename T>
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);
103  {
104  obj.value_or(val)
105  } -> std::convertible_to<typename std::remove_cvref_t<T>::value_type>;
106  };
107  { static_cast<bool>(obj) } -> std::same_as<bool>; // convertible to bool
108 };
109 
110 } // namespace concepts
111 } // namespace simdjson
112 #endif // SIMDJSON_SUPPORTS_DESERIALIZATION
113 #endif // SIMDJSON_CONCEPTS_H
The top level simdjson namespace, containing everything the library provides.
Definition: base.h:8