From 74dcf5c4e59fabd83f3594df2ff88e7539f48f52 Mon Sep 17 00:00:00 2001 From: denzor200 Date: Mon, 24 Jan 2022 01:50:18 +0400 Subject: [PATCH] [pfr_extension] Implemented macro adapter --- CMakeLists.txt | 1 + appveyor.yml | 1 + include/boost/fusion/adapted.hpp | 8 + include/boost/fusion/adapted/pfr.hpp | 21 +++ .../boost/fusion/adapted/pfr/adapt_pfr.hpp | 99 +++++++++++ .../fusion/adapted/pfr/detail/at_impl.hpp | 43 +++++ .../fusion/adapted/pfr/detail/begin_impl.hpp | 43 +++++ .../adapted/pfr/detail/category_of_impl.hpp | 34 ++++ .../fusion/adapted/pfr/detail/end_impl.hpp | 43 +++++ .../adapted/pfr/detail/is_sequence_impl.hpp | 31 ++++ .../adapted/pfr/detail/is_view_impl.hpp | 31 ++++ .../fusion/adapted/pfr/detail/size_impl.hpp | 34 ++++ .../adapted/pfr/detail/value_at_impl.hpp | 34 ++++ include/boost/fusion/include/adapt_pfr.hpp | 13 ++ test/Jamfile | 11 ++ test/include/_adapt_pfr.cpp | 13 ++ test/sequence/adapt_pfr.cpp | 154 ++++++++++++++++++ test/sequence/adapt_pfr_empty.cpp | 94 +++++++++++ test/sequence/adapt_tpl_pfr.cpp | 120 ++++++++++++++ test/sequence/adapt_tpl_pfr_empty.cpp | 95 +++++++++++ 20 files changed, 923 insertions(+) create mode 100644 include/boost/fusion/adapted/pfr.hpp create mode 100644 include/boost/fusion/adapted/pfr/adapt_pfr.hpp create mode 100644 include/boost/fusion/adapted/pfr/detail/at_impl.hpp create mode 100644 include/boost/fusion/adapted/pfr/detail/begin_impl.hpp create mode 100644 include/boost/fusion/adapted/pfr/detail/category_of_impl.hpp create mode 100644 include/boost/fusion/adapted/pfr/detail/end_impl.hpp create mode 100644 include/boost/fusion/adapted/pfr/detail/is_sequence_impl.hpp create mode 100644 include/boost/fusion/adapted/pfr/detail/is_view_impl.hpp create mode 100644 include/boost/fusion/adapted/pfr/detail/size_impl.hpp create mode 100644 include/boost/fusion/adapted/pfr/detail/value_at_impl.hpp create mode 100644 include/boost/fusion/include/adapt_pfr.hpp create mode 100644 test/include/_adapt_pfr.cpp create mode 100644 test/sequence/adapt_pfr.cpp create mode 100644 test/sequence/adapt_pfr_empty.cpp create mode 100644 test/sequence/adapt_tpl_pfr.cpp create mode 100644 test/sequence/adapt_tpl_pfr_empty.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 707b4f898..527d69400 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,4 +23,5 @@ target_link_libraries(boost_fusion Boost::type_traits Boost::typeof Boost::utility + Boost::pfr ) diff --git a/appveyor.yml b/appveyor.yml index debd336bb..539f1a331 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -82,6 +82,7 @@ install: - git submodule init libs/type_traits - git submodule init libs/typeof - git submodule init libs/utility + - git submodule init libs/pfr - git submodule init libs/headers tools/boost_install tools/build - git submodule update diff --git a/include/boost/fusion/adapted.hpp b/include/boost/fusion/adapted.hpp index 5bc33899c..43cdeff2b 100644 --- a/include/boost/fusion/adapted.hpp +++ b/include/boost/fusion/adapted.hpp @@ -23,4 +23,12 @@ #include #endif +// Unfortunately, there is no way to determine the compatibility of the pfr library with the current compiler. +// The "boost/fusion/adapted/pfr.hpp" include has been commented out to ensure backward compatibility +// Please include it manually in your project + +// #if !defined(BOOST_FUSION_NO_PFR) +// #include +// #endif + #endif diff --git a/include/boost/fusion/adapted/pfr.hpp b/include/boost/fusion/adapted/pfr.hpp new file mode 100644 index 000000000..f6498e870 --- /dev/null +++ b/include/boost/fusion/adapted/pfr.hpp @@ -0,0 +1,21 @@ +/*============================================================================= + Copyright (c) 2022 Denis Mikhailov + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ + +#ifndef BOOST_FUSION_ADAPTED_PFR_HPP +#define BOOST_FUSION_ADAPTED_PFR_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif diff --git a/include/boost/fusion/adapted/pfr/adapt_pfr.hpp b/include/boost/fusion/adapted/pfr/adapt_pfr.hpp new file mode 100644 index 000000000..f870f98a4 --- /dev/null +++ b/include/boost/fusion/adapted/pfr/adapt_pfr.hpp @@ -0,0 +1,99 @@ +/*============================================================================= + Copyright (c) 2022 Denis Mikhailov + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ + +#if !defined(BOOST_FUSION_ADAPTED_STRUCT_ADAPT_PFR_HPP) +#define BOOST_FUSION_ADAPTED_STRUCT_ADAPT_PFR_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define BOOST_FUSION_ADAPT_PFR(NAME) \ + \ + namespace boost { namespace fusion { \ + struct pfr_tag; \ + struct fusion_sequence_tag; \ + \ + namespace traits \ + { \ + template<> \ + struct tag_of \ + { \ + using type = pfr_tag; \ + }; \ + template<> \ + struct tag_of \ + { \ + using type = pfr_tag; \ + }; \ + } \ + }} \ + \ + namespace boost { namespace mpl \ + { \ + template \ + struct sequence_tag; \ + \ + template<> \ + struct sequence_tag \ + { \ + using type = fusion::fusion_sequence_tag; \ + }; \ + \ + template<> \ + struct sequence_tag \ + { \ + using type = fusion::fusion_sequence_tag; \ + }; \ + }} + +#define BOOST_FUSION_ADAPT_TPL_PFR(NAME) \ + \ + namespace boost { namespace fusion { \ + struct pfr_tag; \ + struct fusion_sequence_tag; \ + \ + namespace traits \ + { \ + template \ + struct tag_of> \ + { \ + using type = pfr_tag; \ + }; \ + template \ + struct tag_of const> \ + { \ + using type = pfr_tag; \ + }; \ + } \ + }} \ + \ + namespace boost { namespace mpl \ + { \ + template \ + struct sequence_tag; \ + \ + template \ + struct sequence_tag> \ + { \ + using type = fusion::fusion_sequence_tag; \ + }; \ + \ + template \ + struct sequence_tag const> \ + { \ + using type = fusion::fusion_sequence_tag; \ + }; \ + }} + +#endif diff --git a/include/boost/fusion/adapted/pfr/detail/at_impl.hpp b/include/boost/fusion/adapted/pfr/detail/at_impl.hpp new file mode 100644 index 000000000..07278a137 --- /dev/null +++ b/include/boost/fusion/adapted/pfr/detail/at_impl.hpp @@ -0,0 +1,43 @@ +/*============================================================================= + Copyright (c) 2022 Denis Mikhailov + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ + +#if !defined(BOOST_FUSION_ADAPTED_PFR_DETAIL_AT_IMPL_HPP) +#define BOOST_FUSION_ADAPTED_PFR_DETAIL_AT_IMPL_HPP + +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + struct pfr_tag; + + namespace extension + { + template + struct at_impl; + + template<> + struct at_impl + { + template + struct apply + { + using type = typename result_of::at< pfr_fields_view, N >::type; + + constexpr BOOST_FUSION_GPU_ENABLED + static type + call(Aggregate& seq) + { + return at(pfr_fields(seq)); + } + }; + }; + } +}} + +#endif diff --git a/include/boost/fusion/adapted/pfr/detail/begin_impl.hpp b/include/boost/fusion/adapted/pfr/detail/begin_impl.hpp new file mode 100644 index 000000000..b75c3f9a6 --- /dev/null +++ b/include/boost/fusion/adapted/pfr/detail/begin_impl.hpp @@ -0,0 +1,43 @@ +/*============================================================================= + Copyright (c) 2022 Denis Mikhailov + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ + +#if !defined(BOOST_FUSION_ADAPTED_PFR_DETAIL_BEGIN_IMPL_HPP) +#define BOOST_FUSION_ADAPTED_PFR_DETAIL_BEGIN_IMPL_HPP + +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + struct pfr_tag; + + namespace extension + { + template + struct begin_impl; + + template <> + struct begin_impl + { + template + struct apply + { + using type = typename result_of::begin< pfr_fields_view >::type; + + constexpr BOOST_FUSION_GPU_ENABLED + static type + call(Aggregate& seq) + { + return begin(pfr_fields(seq)); + } + }; + }; + } +}} + +#endif diff --git a/include/boost/fusion/adapted/pfr/detail/category_of_impl.hpp b/include/boost/fusion/adapted/pfr/detail/category_of_impl.hpp new file mode 100644 index 000000000..febd79c08 --- /dev/null +++ b/include/boost/fusion/adapted/pfr/detail/category_of_impl.hpp @@ -0,0 +1,34 @@ +/*============================================================================= + Copyright (c) 2022 Denis Mikhailov + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ + +#if !defined(BOOST_FUSION_ADAPTED_PFR_DETAIL_CATEGORY_OF_IMPL_HPP) +#define BOOST_FUSION_ADAPTED_PFR_DETAIL_CATEGORY_OF_IMPL_HPP + +#include + +namespace boost { namespace fusion +{ + struct pfr_tag; + struct random_access_traversal_tag; + + namespace extension + { + template + struct category_of_impl; + + template<> + struct category_of_impl + { + template + struct apply + { + using type = random_access_traversal_tag; + }; + }; + } +}} + +#endif diff --git a/include/boost/fusion/adapted/pfr/detail/end_impl.hpp b/include/boost/fusion/adapted/pfr/detail/end_impl.hpp new file mode 100644 index 000000000..f2dc134ef --- /dev/null +++ b/include/boost/fusion/adapted/pfr/detail/end_impl.hpp @@ -0,0 +1,43 @@ +/*============================================================================= + Copyright (c) 2022 Denis Mikhailov + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ + +#if !defined(BOOST_FUSION_ADAPTED_PFR_DETAIL_END_IMPL_HPP) +#define BOOST_FUSION_ADAPTED_PFR_DETAIL_END_IMPL_HPP + +#include +#include +#include +#include + +namespace boost { namespace fusion +{ + struct pfr_tag; + + namespace extension + { + template + struct end_impl; + + template<> + struct end_impl + { + template + struct apply + { + using type = typename result_of::end< pfr_fields_view >::type; + + constexpr BOOST_FUSION_GPU_ENABLED + static type + call(Aggregate& seq) + { + return end(pfr_fields(seq)); + } + }; + }; + } +}} + +#endif diff --git a/include/boost/fusion/adapted/pfr/detail/is_sequence_impl.hpp b/include/boost/fusion/adapted/pfr/detail/is_sequence_impl.hpp new file mode 100644 index 000000000..bcbc06ef4 --- /dev/null +++ b/include/boost/fusion/adapted/pfr/detail/is_sequence_impl.hpp @@ -0,0 +1,31 @@ +/*============================================================================= + Copyright (c) 2022 Denis Mikhailov + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ + +#if !defined(BOOST_FUSION_ADAPTED_PFR_DETAIL_IS_SEQUENCE_IMPL_HPP) +#define BOOST_FUSION_ADAPTED_PFR_DETAIL_IS_SEQUENCE_IMPL_HPP + +#include +#include + +namespace boost { namespace fusion +{ + struct pfr_tag; + + namespace extension + { + template + struct is_sequence_impl; + + template<> + struct is_sequence_impl + { + template + struct apply : mpl::true_ {}; + }; + } +}} + +#endif diff --git a/include/boost/fusion/adapted/pfr/detail/is_view_impl.hpp b/include/boost/fusion/adapted/pfr/detail/is_view_impl.hpp new file mode 100644 index 000000000..77d622a37 --- /dev/null +++ b/include/boost/fusion/adapted/pfr/detail/is_view_impl.hpp @@ -0,0 +1,31 @@ +/*============================================================================= + Copyright (c) 2022 Denis Mikhailov + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ + +#if !defined(BOOST_FUSION_ADAPTED_PFR_DETAIL_IS_VIEW_IMPL_HPP) +#define BOOST_FUSION_ADAPTED_PFR_DETAIL_IS_VIEW_IMPL_HPP + +#include +#include + +namespace boost { namespace fusion +{ + struct pfr_tag; + + namespace extension + { + template + struct is_view_impl; + + template<> + struct is_view_impl + { + template + struct apply : mpl::false_ {}; + }; + } +}} + +#endif diff --git a/include/boost/fusion/adapted/pfr/detail/size_impl.hpp b/include/boost/fusion/adapted/pfr/detail/size_impl.hpp new file mode 100644 index 000000000..1c0737cfe --- /dev/null +++ b/include/boost/fusion/adapted/pfr/detail/size_impl.hpp @@ -0,0 +1,34 @@ +/*============================================================================= + Copyright (c) 2022 Denis Mikhailov + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ + +#if !defined(BOOST_FUSION_ADAPTED_PFR_DETAIL_VIEW_IMPL_HPP) +#define BOOST_FUSION_ADAPTED_PFR_DETAIL_VIEW_IMPL_HPP + +#include +#include +#include + +namespace boost { namespace fusion +{ + struct pfr_tag; + + namespace extension + { + template + struct size_impl; + + template<> + struct size_impl + { + template + struct apply : result_of::size< pfr_fields_view > + { + }; + }; + } +}} + +#endif diff --git a/include/boost/fusion/adapted/pfr/detail/value_at_impl.hpp b/include/boost/fusion/adapted/pfr/detail/value_at_impl.hpp new file mode 100644 index 000000000..65b11c0f0 --- /dev/null +++ b/include/boost/fusion/adapted/pfr/detail/value_at_impl.hpp @@ -0,0 +1,34 @@ +/*============================================================================= + Copyright (c) 2022 Denis Mikhailov + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ + +#if !defined(BOOST_FUSION_ADAPTED_PFR_DETAIL_VALUE_AT_IMPL_HPP) +#define BOOST_FUSION_ADAPTED_PFR_DETAIL_VALUE_AT_IMPL_HPP + +#include +#include +#include + +namespace boost { namespace fusion +{ + struct pfr_tag; + + namespace extension + { + template + struct value_at_impl; + + template<> + struct value_at_impl + { + template + struct apply : result_of::value_at< pfr_fields_view, N > + { + }; + }; + } +}} + +#endif diff --git a/include/boost/fusion/include/adapt_pfr.hpp b/include/boost/fusion/include/adapt_pfr.hpp new file mode 100644 index 000000000..813703f5b --- /dev/null +++ b/include/boost/fusion/include/adapt_pfr.hpp @@ -0,0 +1,13 @@ +/*============================================================================= + Copyright (c) 2022 Denis Mikhailov + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ + +#ifndef BOOST_FUSION_INCLUDE_ADAPT_PFR_HPP +#define BOOST_FUSION_INCLUDE_ADAPT_PFR_HPP + +#include +#include + +#endif diff --git a/test/Jamfile b/test/Jamfile index 13dd35c55..2474dd1f1 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -68,6 +68,9 @@ project [ run algorithm/flatten.cpp ] [ compile algorithm/ticket-5490.cpp ] + [ compile include/_adapt_pfr.cpp + : [ requires cxx14_constexpr ] ] + [ run sequence/as_deque.cpp ] [ run sequence/as_list.cpp ] [ run sequence/as_map.cpp ] @@ -207,6 +210,14 @@ project [ run sequence/adapt_tpl_adt_empty.cpp ] [ run sequence/adapt_tpl_struct.cpp ] [ run sequence/adapt_tpl_struct_empty.cpp ] + [ run sequence/adapt_pfr.cpp : : + : [ requires cxx14_constexpr ] ] + [ run sequence/adapt_pfr_empty.cpp : : + : [ requires cxx14_constexpr ] ] + [ run sequence/adapt_tpl_pfr.cpp : : + : [ requires cxx14_constexpr ] ] + [ run sequence/adapt_tpl_pfr_empty.cpp : : + : [ requires cxx14_constexpr ] ] [ run sequence/adt_attribute_proxy.cpp ] [ run sequence/define_struct.cpp ] [ run sequence/define_struct_empty.cpp ] diff --git a/test/include/_adapt_pfr.cpp b/test/include/_adapt_pfr.cpp new file mode 100644 index 000000000..75cee9918 --- /dev/null +++ b/test/include/_adapt_pfr.cpp @@ -0,0 +1,13 @@ +/*============================================================================= + Copyright (c) 2022 Denis Mikhailov + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#include +#include + +int +main() +{ + return boost::report_errors(); +} \ No newline at end of file diff --git a/test/sequence/adapt_pfr.cpp b/test/sequence/adapt_pfr.cpp new file mode 100644 index 000000000..231c44958 --- /dev/null +++ b/test/sequence/adapt_pfr.cpp @@ -0,0 +1,154 @@ +/*============================================================================= + Copyright (c) 2021-2022 Denis Mikhailov + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace namespaced_type { + typedef int integer; +} + +namespace ns { + struct point { + int x; + int y; + namespaced_type::integer z; + }; + + // Testing non-constexpr compatible types +#if BOOST_PFR_USE_CPP17 != 0 + struct employee { + std::string name; + std::string nickname; + }; +#endif // BOOST_PFR_USE_CPP17 +} + +BOOST_FUSION_ADAPT_PFR(ns::point); +#if BOOST_PFR_USE_CPP17 != 0 +BOOST_FUSION_ADAPT_PFR(ns::employee); +#endif // BOOST_PFR_USE_CPP17 + +struct s { int m; }; +BOOST_FUSION_ADAPT_PFR(s); + +struct empty_struct {}; +BOOST_FUSION_ADAPT_PFR(empty_struct); + +int +main() +{ + using namespace boost::fusion; + using namespace boost; + using ns::point; + + std::cout << tuple_open('['); + std::cout << tuple_close(']'); + std::cout << tuple_delimiter(", "); + + { + BOOST_MPL_ASSERT_NOT((traits::is_view)); + BOOST_STATIC_ASSERT(!traits::is_view::value); + point p = {123, 456, 789}; + + std::cout << at_c<0>(p) << std::endl; + std::cout << at_c<1>(p) << std::endl; + std::cout << at_c<2>(p) << std::endl; + std::cout << p << std::endl; + BOOST_TEST(p == make_vector(123, 456, 789)); + + at_c<0>(p) = 6; + at_c<1>(p) = 9; + at_c<2>(p) = 12; + BOOST_TEST(p == make_vector(6, 9, 12)); + + BOOST_STATIC_ASSERT(boost::fusion::result_of::size::value == 3); + BOOST_STATIC_ASSERT(!boost::fusion::result_of::empty::value); + + BOOST_TEST(front(p) == 6); + BOOST_TEST(back(p) == 12); + } + + { + vector v1(4, 2.f, 2); + point v2 = {5, 3, 3}; + vector v3(5, 4., 4); + BOOST_TEST(v1 < v2); + BOOST_TEST(v1 <= v2); + BOOST_TEST(v2 > v1); + BOOST_TEST(v2 >= v1); + BOOST_TEST(v2 < v3); + BOOST_TEST(v2 <= v3); + BOOST_TEST(v3 > v2); + BOOST_TEST(v3 >= v2); + } + + { + // conversion from point to vector + point p = {5, 3, 3}; + vector v(p); + v = p; + } + + { + // conversion from point to list + point p = {5, 3, 3}; + list l(p); + l = p; + } + + { // begin/end + using namespace boost::fusion; + using boost::is_same; + + typedef boost::fusion::result_of::begin::type b; + typedef boost::fusion::result_of::end::type e; + // this fails + BOOST_MPL_ASSERT((is_same::type, e>)); + } + + { + BOOST_MPL_ASSERT((mpl::is_sequence)); + BOOST_MPL_ASSERT((boost::is_same< + boost::fusion::result_of::value_at_c::type + , mpl::front::type>)); + } + +#if BOOST_PFR_USE_CPP17 != 0 + { + ns::employee emp{"John Doe", "jdoe"}; + std::cout << at_c<0>(emp) << std::endl; + std::cout << at_c<1>(emp) << std::endl; + + fusion::vector v1("John Doe", "jdoe"); + BOOST_TEST(emp == v1); + } +#endif // BOOST_PFR_USE_CPP17 + + return boost::report_errors(); +} \ No newline at end of file diff --git a/test/sequence/adapt_pfr_empty.cpp b/test/sequence/adapt_pfr_empty.cpp new file mode 100644 index 000000000..0aad8b548 --- /dev/null +++ b/test/sequence/adapt_pfr_empty.cpp @@ -0,0 +1,94 @@ +/*============================================================================= + Copyright (c) 2021-2022 Denis Mikhailov + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct empty_struct {}; +BOOST_FUSION_ADAPT_PFR(empty_struct); + +int +main() +{ + using namespace boost::fusion; + using namespace boost; + + std::cout << tuple_open('['); + std::cout << tuple_close(']'); + std::cout << tuple_delimiter(", "); + + { + BOOST_MPL_ASSERT_NOT((traits::is_view)); + BOOST_STATIC_ASSERT(!traits::is_view::value); + empty_struct e; + + std::cout << e << std::endl; + BOOST_TEST(e == make_vector()); + + BOOST_STATIC_ASSERT(fusion::result_of::size::value == 0); + BOOST_MPL_ASSERT((fusion::result_of::empty)); + + BOOST_MPL_ASSERT((fusion::result_of::equal_to< + fusion::result_of::begin::type, + fusion::result_of::end::type>)); + } + + { + int counter = 0; + empty_struct empty; + boost::fusion::for_each(empty, [&](){counter+=1;}); + BOOST_TEST(counter == 0); + } + + { + fusion::vector<> v; + empty_struct e; + BOOST_TEST(v == e); + BOOST_TEST_NOT(e != v); + BOOST_TEST_NOT(v < e); + BOOST_TEST(v <= e); + BOOST_TEST_NOT(e > v); + BOOST_TEST(e >= v); + } + + { + empty_struct e; + + // conversion from empty_struct to vector + fusion::vector<> v(e); + v = e; + + // FIXME + // conversion from empty_struct to list + //fusion::list<> l(e); + //l = e; + } + + BOOST_MPL_ASSERT((mpl::is_sequence)); + + return boost::report_errors(); +} \ No newline at end of file diff --git a/test/sequence/adapt_tpl_pfr.cpp b/test/sequence/adapt_tpl_pfr.cpp new file mode 100644 index 000000000..49c168494 --- /dev/null +++ b/test/sequence/adapt_tpl_pfr.cpp @@ -0,0 +1,120 @@ +/*============================================================================= + Copyright (c) 2021-2022 Denis Mikhailov + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace ns +{ + template + struct point + { + X x; + Y y; + int z; + }; +} + +BOOST_FUSION_ADAPT_TPL_PFR(ns::point); + +template +struct s { M m; }; +BOOST_FUSION_ADAPT_TPL_PFR(s); + +int +main() +{ + using namespace boost::fusion; + + typedef ns::point point; + + std::cout << tuple_open('['); + std::cout << tuple_close(']'); + std::cout << tuple_delimiter(", "); + + { + BOOST_MPL_ASSERT_NOT((traits::is_view)); + BOOST_STATIC_ASSERT(!traits::is_view::value); + point p = {123, 456, 789}; + + std::cout << at_c<0>(p) << std::endl; + std::cout << at_c<1>(p) << std::endl; + std::cout << at_c<2>(p) << std::endl; + std::cout << p << std::endl; + BOOST_TEST(p == make_vector(123, 456, 789)); + + at_c<0>(p) = 6; + at_c<1>(p) = 9; + at_c<2>(p) = 12; + BOOST_TEST(p == make_vector(6, 9, 12)); + + BOOST_STATIC_ASSERT(boost::fusion::result_of::size::value == 3); + BOOST_STATIC_ASSERT(!boost::fusion::result_of::empty::value); + + BOOST_TEST(front(p) == 6); + BOOST_TEST(back(p) == 12); + } + + { + vector v1(4, 2.f, 2); + point v2 = {5, 3, 3}; + vector v3(5, 4., 4); + BOOST_TEST(v1 < v2); + BOOST_TEST(v1 <= v2); + BOOST_TEST(v2 > v1); + BOOST_TEST(v2 >= v1); + BOOST_TEST(v2 < v3); + BOOST_TEST(v2 <= v3); + BOOST_TEST(v3 > v2); + BOOST_TEST(v3 >= v2); + } + + { + // conversion from point to vector + point p = {5, 3, 3}; + vector v(p); + v = p; + } + + { + // conversion from point to list + point p = {5, 3, 3}; + list l(p); + l = p; + } + + { // begin/end + using namespace boost::fusion; + + typedef boost::fusion::result_of::begin >::type b; + typedef boost::fusion::result_of::end >::type e; + // this fails + BOOST_MPL_ASSERT((boost::is_same::type, e>)); + } + + return boost::report_errors(); +} diff --git a/test/sequence/adapt_tpl_pfr_empty.cpp b/test/sequence/adapt_tpl_pfr_empty.cpp new file mode 100644 index 000000000..9549fbfcc --- /dev/null +++ b/test/sequence/adapt_tpl_pfr_empty.cpp @@ -0,0 +1,95 @@ +/*============================================================================= + Copyright (c) 2021-2022 Denis Mikhailov + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +template +class empty_struct{}; +BOOST_FUSION_ADAPT_TPL_PFR(empty_struct); + +int +main() +{ + using namespace boost::fusion; + using namespace boost; + + std::cout << tuple_open('['); + std::cout << tuple_close(']'); + std::cout << tuple_delimiter(", "); + + { + BOOST_MPL_ASSERT_NOT((traits::is_view >)); + BOOST_STATIC_ASSERT(!traits::is_view >::value); + empty_struct e; + + std::cout << e << std::endl; + BOOST_TEST(e == make_vector()); + + BOOST_STATIC_ASSERT(fusion::result_of::size >::value == 0); + BOOST_MPL_ASSERT((fusion::result_of::empty >)); + + BOOST_MPL_ASSERT((fusion::result_of::equal_to< + fusion::result_of::begin >::type, + fusion::result_of::end >::type>)); + } + + { + int counter = 0; + empty_struct empty; + boost::fusion::for_each(empty, [&](){counter+=1;}); + BOOST_TEST(counter == 0); + } + + { + fusion::vector<> v; + empty_struct e; + BOOST_TEST(v == e); + BOOST_TEST_NOT(v != e); + BOOST_TEST_NOT(v < e); + BOOST_TEST(v <= e); + BOOST_TEST_NOT(v > e); + BOOST_TEST(v >= e); + } + + { + empty_struct e; + + // conversion from empty_struct to vector + fusion::vector<> v(e); + v = e; + + // FIXME + // conversion from empty_struct to list + //fusion::list<> l(e); + //l = e; + } + + BOOST_MPL_ASSERT((mpl::is_sequence >)); + + return boost::report_errors(); +} \ No newline at end of file