Skip to content

Commit 589641b

Browse files
authored
Add support of multi-dim C-style array member of struct. (#4262)
* Add support of multi-dim C-style array. * Support up to 4 dimensional array. * Suppress clang-tidy checks for C-style arrays
1 parent f385fe2 commit 589641b

File tree

3 files changed

+158
-0
lines changed

3 files changed

+158
-0
lines changed

include/nlohmann/detail/conversions/from_json.hpp

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,54 @@ auto from_json(const BasicJsonType& j, T (&arr)[N]) // NOLINT(cppcoreguidelines
212212
}
213213
}
214214

215+
template<typename BasicJsonType, typename T, std::size_t N1, std::size_t N2>
216+
auto from_json(const BasicJsonType& j, T (&arr)[N1][N2]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
217+
-> decltype(j.template get<T>(), void())
218+
{
219+
for (std::size_t i1 = 0; i1 < N1; ++i1)
220+
{
221+
for (std::size_t i2 = 0; i2 < N2; ++i2)
222+
{
223+
arr[i1][i2] = j.at(i1).at(i2).template get<T>();
224+
}
225+
}
226+
}
227+
228+
template<typename BasicJsonType, typename T, std::size_t N1, std::size_t N2, std::size_t N3>
229+
auto from_json(const BasicJsonType& j, T (&arr)[N1][N2][N3]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
230+
-> decltype(j.template get<T>(), void())
231+
{
232+
for (std::size_t i1 = 0; i1 < N1; ++i1)
233+
{
234+
for (std::size_t i2 = 0; i2 < N2; ++i2)
235+
{
236+
for (std::size_t i3 = 0; i3 < N3; ++i3)
237+
{
238+
arr[i1][i2][i3] = j.at(i1).at(i2).at(i3).template get<T>();
239+
}
240+
}
241+
}
242+
}
243+
244+
template<typename BasicJsonType, typename T, std::size_t N1, std::size_t N2, std::size_t N3, std::size_t N4>
245+
auto from_json(const BasicJsonType& j, T (&arr)[N1][N2][N3][N4]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
246+
-> decltype(j.template get<T>(), void())
247+
{
248+
for (std::size_t i1 = 0; i1 < N1; ++i1)
249+
{
250+
for (std::size_t i2 = 0; i2 < N2; ++i2)
251+
{
252+
for (std::size_t i3 = 0; i3 < N3; ++i3)
253+
{
254+
for (std::size_t i4 = 0; i4 < N4; ++i4)
255+
{
256+
arr[i1][i2][i3][i4] = j.at(i1).at(i2).at(i3).at(i4).template get<T>();
257+
}
258+
}
259+
}
260+
}
261+
}
262+
215263
template<typename BasicJsonType>
216264
inline void from_json_array_impl(const BasicJsonType& j, typename BasicJsonType::array_t& arr, priority_tag<3> /*unused*/)
217265
{

single_include/nlohmann/json.hpp

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4885,6 +4885,54 @@ auto from_json(const BasicJsonType& j, T (&arr)[N]) // NOLINT(cppcoreguidelines
48854885
}
48864886
}
48874887

4888+
template<typename BasicJsonType, typename T, std::size_t N1, std::size_t N2>
4889+
auto from_json(const BasicJsonType& j, T (&arr)[N1][N2]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
4890+
-> decltype(j.template get<T>(), void())
4891+
{
4892+
for (std::size_t i1 = 0; i1 < N1; ++i1)
4893+
{
4894+
for (std::size_t i2 = 0; i2 < N2; ++i2)
4895+
{
4896+
arr[i1][i2] = j.at(i1).at(i2).template get<T>();
4897+
}
4898+
}
4899+
}
4900+
4901+
template<typename BasicJsonType, typename T, std::size_t N1, std::size_t N2, std::size_t N3>
4902+
auto from_json(const BasicJsonType& j, T (&arr)[N1][N2][N3]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
4903+
-> decltype(j.template get<T>(), void())
4904+
{
4905+
for (std::size_t i1 = 0; i1 < N1; ++i1)
4906+
{
4907+
for (std::size_t i2 = 0; i2 < N2; ++i2)
4908+
{
4909+
for (std::size_t i3 = 0; i3 < N3; ++i3)
4910+
{
4911+
arr[i1][i2][i3] = j.at(i1).at(i2).at(i3).template get<T>();
4912+
}
4913+
}
4914+
}
4915+
}
4916+
4917+
template<typename BasicJsonType, typename T, std::size_t N1, std::size_t N2, std::size_t N3, std::size_t N4>
4918+
auto from_json(const BasicJsonType& j, T (&arr)[N1][N2][N3][N4]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
4919+
-> decltype(j.template get<T>(), void())
4920+
{
4921+
for (std::size_t i1 = 0; i1 < N1; ++i1)
4922+
{
4923+
for (std::size_t i2 = 0; i2 < N2; ++i2)
4924+
{
4925+
for (std::size_t i3 = 0; i3 < N3; ++i3)
4926+
{
4927+
for (std::size_t i4 = 0; i4 < N4; ++i4)
4928+
{
4929+
arr[i1][i2][i3][i4] = j.at(i1).at(i2).at(i3).at(i4).template get<T>();
4930+
}
4931+
}
4932+
}
4933+
}
4934+
}
4935+
48884936
template<typename BasicJsonType>
48894937
inline void from_json_array_impl(const BasicJsonType& j, typename BasicJsonType::array_t& arr, priority_tag<3> /*unused*/)
48904938
{

tests/src/unit-conversions.cpp

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,68 @@ TEST_CASE("value conversion")
369369
CHECK(std::equal(std::begin(nbs), std::end(nbs), std::begin(nbs2)));
370370
}
371371

372+
SECTION("built-in arrays: 2D")
373+
{
374+
const int nbs[][3] = {{0, 1, 2}, {3, 4, 5}}; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
375+
int nbs2[][3] = {{0, 0, 0}, {0, 0, 0}}; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
376+
377+
const json j2 = nbs;
378+
j2.get_to(nbs2);
379+
CHECK(std::equal(std::begin(nbs[0]), std::end(nbs[1]), std::begin(nbs2[0])));
380+
}
381+
382+
SECTION("built-in arrays: 3D")
383+
{
384+
// NOLINTBEGIN(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
385+
const int nbs[][2][3] = {\
386+
{{0, 1, 2}, {3, 4, 5}}, \
387+
{{10, 11, 12}, {13, 14, 15}}\
388+
};
389+
int nbs2[][2][3] = {\
390+
{{0, 0, 0}, {0, 0, 0}}, \
391+
{{0, 0, 0}, {0, 0, 0}}\
392+
};
393+
// NOLINTEND(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
394+
395+
const json j2 = nbs;
396+
j2.get_to(nbs2);
397+
CHECK(std::equal(std::begin(nbs[0][0]), std::end(nbs[1][1]), std::begin(nbs2[0][0])));
398+
}
399+
400+
SECTION("built-in arrays: 4D")
401+
{
402+
// NOLINTBEGIN(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
403+
const int nbs[][2][2][3] = {\
404+
{
405+
\
406+
{{0, 1, 2}, {3, 4, 5}}, \
407+
{{10, 11, 12}, {13, 14, 15}}\
408+
}, \
409+
{
410+
\
411+
{{20, 21, 22}, {23, 24, 25}}, \
412+
{{30, 31, 32}, {33, 34, 35}}\
413+
}\
414+
};
415+
int nbs2[][2][2][3] = {\
416+
{
417+
\
418+
{{0, 0, 0}, {0, 0, 0}}, \
419+
{{0, 0, 0}, {0, 0, 0}}\
420+
}, \
421+
{
422+
\
423+
{{0, 0, 0}, {0, 0, 0}}, \
424+
{{0, 0, 0}, {0, 0, 0}}\
425+
}\
426+
};
427+
// NOLINTEND(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
428+
429+
const json j2 = nbs;
430+
j2.get_to(nbs2);
431+
CHECK(std::equal(std::begin(nbs[0][0][0]), std::end(nbs[1][1][1]), std::begin(nbs2[0][0][0])));
432+
}
433+
372434
SECTION("std::deque<json>")
373435
{
374436
std::deque<json> a{"previous", "value"};

0 commit comments

Comments
 (0)