#include #include #include struct reflect_test_base { int x = 1; char y = 'a'; }; struct reflect_test_derived : reflect_test_base { double z = 3.14; }; struct reflect_layer_1 { reflect_test_base b; int32_t n; }; struct reflect_layer_2 { reflect_layer_1 l1; reflect_test_derived d; }; struct reflect_layer_3 { reflect_layer_2 l2; int32_t i; }; FC_REFLECT( reflect_test_base, (x)(y) ); FC_REFLECT_DERIVED( reflect_test_derived, (reflect_test_base), (z) ); FC_REFLECT( reflect_layer_1, (b)(n) ); FC_REFLECT( reflect_layer_2, (l1)(d) ); FC_REFLECT( reflect_layer_3, (l2)(i) ); BOOST_AUTO_TEST_SUITE( fc_reflection ) BOOST_AUTO_TEST_CASE( reflection_static_tests ) { // These are all compile-time tests, nothing actually happens here at runtime using base_reflection = fc::reflector; using derived_reflection = fc::reflector; static_assert(fc::typelist::length() == 2, ""); static_assert(fc::typelist::length() == 3, ""); static_assert(fc::typelist::at::is_derived, ""); static_assert(std::is_same::field_container, reflect_test_base>::value, ""); static_assert(fc::typelist::at::is_derived, ""); static_assert(std::is_same::field_container, reflect_test_base>::value, ""); static_assert(fc::typelist::at::is_derived == false, ""); static_assert(std::is_same, 0, 1>, fc::typelist::list>::value, ""); static_assert(std::is_same, 0, 2>, fc::typelist::list>::value, ""); static_assert(std::is_same, 0, 3>, fc::typelist::list>::value, ""); static_assert(std::is_same, 1, 3>, fc::typelist::list>::value, ""); static_assert(std::is_same, 2, 3>, fc::typelist::list>::value, ""); static_assert(std::is_same, 1, 2>, fc::typelist::list>::value, ""); static_assert(std::is_same, 1>, fc::typelist::list>::value, ""); static_assert(std::is_same, fc::typelist::list<>>::value, ""); static_assert(std::is_same, fc::typelist::list>>::value, ""); static_assert(std::is_same, fc::typelist::list, std::integral_constant>>::value, ""); static_assert(std::is_same, fc::typelist::list, std::integral_constant, std::integral_constant>>::value, ""); static_assert(std::is_same, fc::typelist::list<>>, fc::typelist::list<>>::value, ""); static_assert(std::is_same, fc::typelist::list>, fc::typelist::list>>::value, ""); static_assert(std::is_same, fc::typelist::list>, fc::typelist::list, fc::typelist::list>>::value, ""); static_assert(std::is_same>, fc::typelist::list<>>::value, ""); static_assert(std::is_same>, fc::typelist::list, int>, fc::typelist::list, bool>, fc::typelist::list, char>, fc::typelist::list, double>> >::value, ""); } BOOST_AUTO_TEST_CASE( typelist_dispatch_test ) { using list = fc::typelist::list; auto get_name = [](auto t) -> std::string { return fc::get_typename::name(); }; BOOST_CHECK_EQUAL(fc::typelist::runtime::dispatch(list(), 0ul, get_name), "float"); BOOST_CHECK_EQUAL(fc::typelist::runtime::dispatch(list(), 1ul, get_name), "bool"); BOOST_CHECK_EQUAL(fc::typelist::runtime::dispatch(list(), 2ul, get_name), "char"); } // Helper template to use fc::typelist::at without a comma, for macro friendliness template struct index_from { template using at = fc::typelist::at; }; BOOST_AUTO_TEST_CASE( reflection_get_test ) { try { reflect_test_derived derived; reflect_test_base& base = derived; using base_reflector = fc::reflector; using derived_reflector = fc::reflector; BOOST_CHECK(index_from::at<0>::get(base) == 1); BOOST_CHECK(index_from::at<1>::get(base) == 'a'); fc::typelist::at::get(base) = 5; fc::typelist::at::get(base) = 'q'; BOOST_CHECK(index_from::at<0>::get(base) == 5); BOOST_CHECK(index_from::at<1>::get(base) == 'q'); BOOST_CHECK(index_from::at<0>::get(derived) == 5); BOOST_CHECK(index_from::at<1>::get(derived) == 'q'); BOOST_CHECK(index_from::at<2>::get(derived) == 3.14); fc::typelist::at::get(derived) = 'X'; BOOST_CHECK(index_from::at<1>::get(base) == 'X'); reflect_layer_3 l3; BOOST_CHECK(index_from::members>::at<0> ::reflector::members>::at<0>::reflector::members>::at<0>::reflector::members>::at<1>::get(l3.l2.l1.b) == 'a'); BOOST_CHECK(index_from::members>::at<0>::reflector::members> ::at<1>::reflector::members>::at<1>::get(l3.l2.d) == 'a'); BOOST_CHECK(index_from::members>::at<0>::reflector::members> ::at<1>::reflector::members>::at<2>::get(l3.l2.d) == 3.14); } FC_CAPTURE_LOG_AND_RETHROW( (0) ) } BOOST_AUTO_TEST_SUITE_END()