|
3 | 3 |
|
4 | 4 | #include <sourcemeta/core/json_value.h>
|
5 | 5 |
|
6 |
| -#include <concepts> // std::same_as, std::constructible_from |
7 |
| -#include <functional> // std::function |
8 |
| -#include <optional> // std::optional |
9 |
| -#include <tuple> // std::tuple, std::apply |
10 |
| -#include <type_traits> // std::false_type, std::true_type, std::void_t, std::is_enum_v, std::underlying_type_t, std::is_same_v |
| 6 | +#include <concepts> // std::same_as, std::constructible_from |
| 7 | +#include <functional> // std::function |
| 8 | +#include <optional> // std::optional |
| 9 | +#include <tuple> // std::tuple, std::apply, std::tuple_element_t, std::tuple_size, std::tuple_size_v |
| 10 | +#include <type_traits> // std::false_type, std::true_type, std::void_t, std::is_enum_v, std::underlying_type_t, std::is_same_v, std::is_base_of_v, std::remove_cvref_t |
11 | 11 | #include <utility> // std::pair
|
12 | 12 |
|
13 | 13 | namespace sourcemeta::core {
|
@@ -203,17 +203,37 @@ auto to_json(
|
203 | 203 | template <typename L, typename R>
|
204 | 204 | auto to_json(const std::pair<L, R> &value) -> JSON {
|
205 | 205 | auto tuple{JSON::make_array()};
|
206 |
| - tuple.push_back(to_json<L>(value.first)); |
207 |
| - tuple.push_back(to_json<R>(value.second)); |
| 206 | + tuple.push_back(to_json(value.first)); |
| 207 | + tuple.push_back(to_json(value.second)); |
208 | 208 | return tuple;
|
209 | 209 | }
|
210 | 210 |
|
| 211 | +// Handle 1-element tuples |
211 | 212 | /// @ingroup json
|
212 |
| -template <typename... Args> |
213 |
| -auto to_json(const std::tuple<Args...> &value) -> JSON { |
214 |
| - auto tuple{JSON::make_array()}; |
| 213 | +template <typename T> |
| 214 | + requires(std::tuple_size_v<std::remove_cvref_t<std::tuple<T>>> == 1) |
| 215 | +auto to_json(const std::tuple<T> &value) -> JSON { |
| 216 | + auto tuple = JSON::make_array(); |
| 217 | + std::apply([&](const T &element) { tuple.push_back(to_json(element)); }, |
| 218 | + value); |
| 219 | + return tuple; |
| 220 | +} |
| 221 | + |
| 222 | +// We have to do this mess because MSVC seems confuses `std::pair` |
| 223 | +// of 2 elements with this overload |
| 224 | +/// @ingroup json |
| 225 | +template <typename TupleT> |
| 226 | + requires(requires { |
| 227 | + typename std::tuple_size<std::remove_cvref_t<TupleT>>::type; |
| 228 | + } && (std::tuple_size_v<std::remove_cvref_t<TupleT>> >= 2) && |
| 229 | + (!std::is_base_of_v< |
| 230 | + std::pair<std::tuple_element_t<0, std::remove_cvref_t<TupleT>>, |
| 231 | + std::tuple_element_t<1, std::remove_cvref_t<TupleT>>>, |
| 232 | + std::remove_cvref_t<TupleT>>)) |
| 233 | +auto to_json(const TupleT &value) -> JSON { |
| 234 | + auto tuple = JSON::make_array(); |
215 | 235 | std::apply(
|
216 |
| - [&tuple](const Args &...elements) { |
| 236 | + [&tuple](const auto &...elements) { |
217 | 237 | (tuple.push_back(to_json(elements)), ...);
|
218 | 238 | },
|
219 | 239 | value);
|
|
0 commit comments