Unverified Commit 41bf982d authored by Paul Fultz II's avatar Paul Fultz II Committed by GitHub
Browse files

Add serialization of tuples and optional types (#1495)

* Add serialization of tuples and optional types
parent fc9ebb06
......@@ -28,6 +28,7 @@
#include <migraphx/value.hpp>
#include <migraphx/reflect.hpp>
#include <migraphx/requires.hpp>
#include <migraphx/optional.hpp>
#include <migraphx/rank.hpp>
#include <type_traits>
......@@ -60,11 +61,12 @@ value to_value_impl(rank<0>, const T&)
return value::object{};
}
template <class T, class U>
value to_value_impl(rank<1>, const std::pair<T, U>& x)
template <class T>
auto to_value_impl(rank<1>, const T& x) -> decltype(std::tuple_size<T>{}, value{})
{
return {x.first, x.second};
value result = value::array{};
repeat_c<std::tuple_size<T>{}>([&](auto i) { result.push_back(to_value(std::get<i>(x))); });
return result;
}
template <class T>
......@@ -86,46 +88,55 @@ value to_value_impl(rank<3>, const T& x)
return result;
}
template <class T>
auto to_value_impl(rank<4>, const optional<T>& x)
{
value result{};
if(x.has_value())
return to_value(*x);
return result;
}
template <class T, MIGRAPHX_REQUIRES(std::is_signed<T>{})>
value to_value_impl(rank<4>, const T& x)
value to_value_impl(rank<5>, const T& x)
{
return std::int64_t{x};
}
template <class T, MIGRAPHX_REQUIRES(std::is_unsigned<T>{})>
value to_value_impl(rank<5>, const T& x)
value to_value_impl(rank<6>, const T& x)
{
return std::uint64_t{x};
}
template <class T, MIGRAPHX_REQUIRES(std::is_floating_point<T>{})>
value to_value_impl(rank<6>, const T& x)
value to_value_impl(rank<7>, const T& x)
{
return double{x};
}
template <class T, MIGRAPHX_REQUIRES(std::is_enum<T>{})>
value to_value_impl(rank<7>, const T& x)
value to_value_impl(rank<8>, const T& x)
{
return x;
}
inline value to_value_impl(rank<8>, const std::string& x) { return x; }
inline value to_value_impl(rank<9>, const std::string& x) { return x; }
template <class T>
auto to_value_impl(rank<9>, const T& x) -> decltype(migraphx_to_value(x))
auto to_value_impl(rank<10>, const T& x) -> decltype(migraphx_to_value(x))
{
return migraphx_to_value(x);
}
template <class T>
auto to_value_impl(rank<10>, const T& x) -> decltype(x.to_value())
auto to_value_impl(rank<11>, const T& x) -> decltype(x.to_value())
{
return x.to_value();
}
template <class T>
auto to_value_impl(rank<11>, const T& x)
auto to_value_impl(rank<12>, const T& x)
-> decltype(migraphx_to_value(std::declval<value&>(), x), value{})
{
value v;
......@@ -144,7 +155,14 @@ void from_value_impl(rank<0>, const value& v, T& x)
}
template <class T>
auto from_value_impl(rank<1>, const value& v, T& x)
auto from_value_impl(rank<1>, const value& v, T& x) -> decltype(std::tuple_size<T>{}, void())
{
repeat_c<std::tuple_size<T>{}>(
[&](auto i) { std::get<i>(x) = from_value<std::tuple_element_t<i, T>>(v[i]); });
}
template <class T>
auto from_value_impl(rank<2>, const value& v, T& x)
-> decltype(x.insert(x.end(), *x.begin()), void())
{
x.clear();
......@@ -153,7 +171,7 @@ auto from_value_impl(rank<1>, const value& v, T& x)
}
template <class T, MIGRAPHX_REQUIRES(std::is_arithmetic<typename T::value_type>{})>
auto from_value_impl(rank<2>, const value& v, T& x)
auto from_value_impl(rank<3>, const value& v, T& x)
-> decltype(x.insert(x.end(), *x.begin()), void())
{
x.clear();
......@@ -170,7 +188,7 @@ auto from_value_impl(rank<2>, const value& v, T& x)
}
template <class T>
auto from_value_impl(rank<3>, const value& v, T& x) -> decltype(x.insert(*x.begin()), void())
auto from_value_impl(rank<4>, const value& v, T& x) -> decltype(x.insert(*x.begin()), void())
{
x.clear();
for(auto&& e : v)
......@@ -178,7 +196,7 @@ auto from_value_impl(rank<3>, const value& v, T& x) -> decltype(x.insert(*x.begi
}
template <class T, MIGRAPHX_REQUIRES(is_reflectable<T>{})>
void from_value_impl(rank<4>, const value& v, T& x)
void from_value_impl(rank<5>, const value& v, T& x)
{
reflect_each(x, [&](auto& y, const std::string& name) {
using type = std::decay_t<decltype(y)>;
......@@ -187,28 +205,29 @@ void from_value_impl(rank<4>, const value& v, T& x)
});
}
template <class T, MIGRAPHX_REQUIRES(std::is_arithmetic<T>{})>
void from_value_impl(rank<5>, const value& v, T& x)
template <class T>
void from_value_impl(rank<6>, const value& v, optional<T>& x)
{
x = v.to<T>();
if(not v.is_null())
x = from_value<T>(v);
}
template <class T, MIGRAPHX_REQUIRES(std::is_enum<T>{})>
void from_value_impl(rank<6>, const value& v, T& x)
template <class T, MIGRAPHX_REQUIRES(std::is_arithmetic<T>{} or std::is_enum<T>{})>
void from_value_impl(rank<7>, const value& v, T& x)
{
x = v.to<T>();
}
inline void from_value_impl(rank<7>, const value& v, std::string& x) { x = v.to<std::string>(); }
inline void from_value_impl(rank<8>, const value& v, std::string& x) { x = v.to<std::string>(); }
template <class T>
auto from_value_impl(rank<8>, const value& v, T& x) -> decltype(x.from_value(v), void())
auto from_value_impl(rank<9>, const value& v, T& x) -> decltype(x.from_value(v), void())
{
x.from_value(v);
}
template <class T>
auto from_value_impl(rank<9>, const value& v, T& x) -> decltype(migraphx_from_value(v, x), void())
auto from_value_impl(rank<10>, const value& v, T& x) -> decltype(migraphx_from_value(v, x), void())
{
migraphx_from_value(v, x);
}
......@@ -218,13 +237,13 @@ auto from_value_impl(rank<9>, const value& v, T& x) -> decltype(migraphx_from_va
template <class T>
value to_value(const T& x)
{
return detail::to_value_impl(rank<11>{}, x);
return detail::to_value_impl(rank<12>{}, x);
}
template <class T>
void from_value(const value& v, T& x)
{
detail::from_value_impl(rank<9>{}, v, x);
detail::from_value_impl(rank<10>{}, v, x);
}
} // namespace MIGRAPHX_INLINE_NS
......
......@@ -60,7 +60,9 @@ struct reflectable_type
return migraphx::pack(f(self.value, "value"));
}
};
std::vector<nested_type> nested_types = {};
std::vector<nested_type> nested_types = {};
std::tuple<int, nested_type, std::string> tuple_items = std::make_tuple(0, nested_type{0}, "");
migraphx::optional<int> opt_value = migraphx::nullopt;
template <class Self, class F>
static auto reflect(Self& self, F f)
......@@ -71,7 +73,8 @@ struct reflectable_type
f(self.et, "et"),
f(self.se, "se"),
f(self.ce, "ce"),
f(self.nested_types, "nested_types"));
f(self.nested_types, "nested_types"),
f(self.tuple_items, "tuple_items"));
}
};
......@@ -83,7 +86,9 @@ TEST_CASE(serialize_reflectable_type)
{},
reflectable_type::simple1,
reflectable_type::class_enum::class2,
{{1}, {2}}};
{{1}, {2}},
{5, {4}, "hello"},
{migraphx::nullopt}};
migraphx::value v1 = migraphx::to_value(t1);
reflectable_type t2 = migraphx::from_value<reflectable_type>(v1);
migraphx::value v2 = migraphx::to_value(t2);
......@@ -125,6 +130,21 @@ TEST_CASE(serialize_empty_struct)
EXPECT(v.at("a").to<int>() == 1);
}
TEST_CASE(serialize_empty_optional)
{
migraphx::optional<int> x{};
migraphx::value v = migraphx::to_value(x);
EXPECT(v.is_null());
}
TEST_CASE(serialize_optional)
{
migraphx::optional<int> x{2};
migraphx::value v = migraphx::to_value(x);
EXPECT(v.is_int64());
EXPECT(v.to<int>() == 2);
}
TEST_CASE(from_value_binary)
{
std::vector<std::uint8_t> data(10);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment