diff --git a/include/boost/fusion/sequence/adapted/struct.hpp b/include/boost/fusion/sequence/adapted/struct.hpp index 1b52fd7c..f4aed34e 100644 --- a/include/boost/fusion/sequence/adapted/struct.hpp +++ b/include/boost/fusion/sequence/adapted/struct.hpp @@ -8,6 +8,9 @@ #if !defined(BOOST_FUSION_STRUCT_24122005_1744) #define BOOST_FUSION_STD_STRUCT_24122005_1744 +#include +#include +#include #include #include #include diff --git a/include/boost/fusion/sequence/adapted/struct/adapt_struct.hpp b/include/boost/fusion/sequence/adapted/struct/adapt_struct.hpp new file mode 100644 index 00000000..3afea18c --- /dev/null +++ b/include/boost/fusion/sequence/adapted/struct/adapt_struct.hpp @@ -0,0 +1,75 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + 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_ADAPT_STRUCT_APRIL_2_2007_1158AM) +#define BOOST_FUSION_ADAPT_STRUCT_APRIL_2_2007_1158AM + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define BOOST_SPIRIT_ADAPT_STRUCT(name, bseq) \ + BOOST_SPIRIT_ADAPT_STRUCT_I( \ + name, BOOST_PP_CAT(BOOST_SPIRIT_ADAPT_STRUCT_X bseq, 0)) \ + /***/ + +#define BOOST_SPIRIT_ADAPT_STRUCT_X(x, y) ((x, y)) BOOST_SPIRIT_ADAPT_STRUCT_Y +#define BOOST_SPIRIT_ADAPT_STRUCT_Y(x, y) ((x, y)) BOOST_SPIRIT_ADAPT_STRUCT_X +#define BOOST_SPIRIT_ADAPT_STRUCT_X0 +#define BOOST_SPIRIT_ADAPT_STRUCT_Y0 + +// BOOST_SPIRIT_ADAPT_STRUCT_I generates the overarching structure and uses +// SEQ_FOR_EACH_I to generate the "linear" substructures. +// Thanks to Paul Mensonides for the PP macro help + +#define BOOST_SPIRIT_ADAPT_STRUCT_I(name, seq) \ + namespace boost { namespace fusion { namespace traits \ + { \ + template <> \ + struct tag_of \ + { \ + typedef struct_tag type; \ + }; \ + }}} \ + namespace boost { namespace fusion { namespace extension \ + { \ + template <> \ + struct struct_size : mpl::int_ {}; \ + BOOST_PP_SEQ_FOR_EACH_I(BOOST_SPIRIT_ADAPT_STRUCT_C, name, seq) \ + }}} \ + /***/ + +#define BOOST_SPIRIT_ADAPT_STRUCT_C(r, name, i, xy) \ + template <> \ + struct struct_member \ + { \ + typedef BOOST_PP_TUPLE_ELEM(2, 0, xy) type; \ + static type& call(name& struct_) \ + { \ + return struct_.BOOST_PP_TUPLE_ELEM(2, 1, xy); \ + }; \ + }; \ + /***/ + +#endif diff --git a/test/Jamfile b/test/Jamfile index c916c1b7..5e388632 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -107,6 +107,8 @@ import testing ; [ run sequence/zip_view_ignore.cpp : : : : ] [ run sequence/repetitive_view.cpp : : : : ] [ run sequence/deduce_sequence.cpp : : : : ] + [ run sequence/adapt_struct.cpp : : : : ] + [ run functional/fused.cpp : : : : ] [ run functional/fused_function_object.cpp : : : : ] [ run functional/fused_procedure.cpp : : : : ] @@ -125,7 +127,7 @@ import testing ; [ run functional/invoke_procedure.cpp : : : : ] # [ compile-fail xxx.cpp : : : : ] - + ; } diff --git a/test/sequence/adapt_struct.cpp b/test/sequence/adapt_struct.cpp new file mode 100644 index 00000000..91104b31 --- /dev/null +++ b/test/sequence/adapt_struct.cpp @@ -0,0 +1,106 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + 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 + +namespace ns +{ + struct point + { + int x; + int y; + }; +} + +BOOST_SPIRIT_ADAPT_STRUCT( + ns::point, + (int, x) + (int, y) +) + +int +main() +{ + using namespace boost::fusion; + using namespace boost; + using namespace std; + + std::cout << tuple_open('['); + std::cout << tuple_close(']'); + std::cout << tuple_delimiter(", "); + + { + BOOST_MPL_ASSERT_NOT((traits::is_view)); + ns::point p = {123, 456}; + + std::cout << at_c<0>(p) << std::endl; + std::cout << at_c<1>(p) << std::endl; + std::cout << p << std::endl; + BOOST_TEST(p == make_vector(123, 456)); + + at_c<0>(p) = 6; + at_c<1>(p) = 9; + BOOST_TEST(p == make_vector(6, 9)); + + BOOST_STATIC_ASSERT(result_of::size::value == 2); + BOOST_STATIC_ASSERT(!result_of::empty::value); + + BOOST_TEST(front(p) == 6); + BOOST_TEST(back(p) == 9); + } + + { + fusion::vector v1(4, 2); + ns::point v2 = {5, 3}; + fusion::vector v3(5, 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 ns::point to vector + ns::point p = {5, 3}; + fusion::vector v(p); + v = p; + } + + { + // conversion from ns::point to list + ns::point p = {5, 3}; + fusion::list l(p); + l = p; + } + + return boost::report_errors(); +} +