diff --git a/doc/adapted.qbk b/doc/adapted.qbk index 7d07a6d8..f762a049 100644 --- a/doc/adapted.qbk +++ b/doc/adapted.qbk @@ -1115,6 +1115,100 @@ defined in __random_access_sequence__. [endsect] +[section:define_struct_inline BOOST_FUSION_DEFINE_STRUCT_INLINE] + +[heading Description] + +BOOST_FUSION_DEFINE_STRUCT_INLINE is a macro that can be used to generate all +the necessary boilerplate to define and adapt an arbitrary struct as a model of +__random_access_sequence__. Unlike BOOST_FUSION_DEFINE_STRUCT, it can be used +at class or namespace scope. + +[heading Synopsis] + + BOOST_FUSION_DEFINE_STRUCT_INLINE( + struct_name, + (member_type0, member_name0) + (member_type1, member_name1) + ... + ) + +[heading Expression Semantics] + +The semantics of BOOST_FUSION_DEFINE_STRUCT_INLINE are identical to those of +BOOST_FUSION_DEFINE_STRUCT, with two differences: + +# BOOST_FUSION_DEFINE_STRUCT_INLINE can be used at class or namespace scope, and + thus does not take a namespace list parameter. +# The structure generated by BOOST_FUSION_DEFINE_STRUCT_INLINE has a base class, + and is thus not POD in C++03. + +[heading Header] + + #include + #include + +[heading Example] + + // enclosing::employee is a Fusion sequence + class enclosing + { + BOOST_FUSION_DEFINE_STRUCT_INLINE( + employee, + (std::string, name) + (int, age)) + }; + + +[endsect] + +[section:define_tpl_struct_inline BOOST_FUSION_DEFINE_TPL_STRUCT_INLINE] + +[heading Description] + +BOOST_FUSION_DEFINE_TPL_STRUCT_INLINE is a macro that can be used to generate +all the necessary boilerplate to define and adapt an arbitrary template struct +as a model of __random_access_sequence__. Unlike BOOST_FUSION_DEFINE_TPL_STRUCT, +it can be used at class or namespace scope. + +[heading Synopsis] + + BOOST_FUSION_DEFINE_TPL_STRUCT_INLINE( + (template_param0)(template_param1)..., + struct_name, + (member_type0, member_name0) + (member_type1, member_name1) + ... + ) + +[heading Expression Semantics] + +The semantics of BOOST_FUSION_DEFINE_TPL_STRUCT_INLINE are identical to those of +BOOST_FUSION_DEFINE_TPL_STRUCT, with two differences: + +# BOOST_FUSION_DEFINE_TPL_STRUCT_INLINE can be used at class or namespace scope, + and thus does not take a namespace list parameter. +# The structure generated by BOOST_FUSION_DEFINE_TPL_STRUCT_INLINE has a base + class, and is thus not POD in C++03. + +[heading Header] + + #include + #include + +[heading Example] + + // Any instantiated enclosing::employee is a Fusion sequence + class enclosing + { + BOOST_FUSION_DEFINE_TPL_STRUCT( + (Name)(Age), employee, + (Name, name) + (Age, age)) + }; + +[endsect] + [section:define_assoc_struct BOOST_FUSION_DEFINE_ASSOC_STRUCT] [heading Description] diff --git a/test/Jamfile b/test/Jamfile index 3cea5ecf..59ec32b2 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -132,8 +132,10 @@ import testing ; [ run sequence/adapt_tpl_struct.cpp : : : : ] [ run sequence/adt_attribute_proxy.cpp : : : : ] [ run sequence/define_struct.cpp : : : : ] + [ run sequence/define_struct_inline.cpp : : : : ] [ run sequence/define_assoc_struct.cpp : : : : ] - [ run sequence/define_tpl_struct.cpp : : : : ] + [ run sequence/define_tpl_struct.cpp : : : : ] + [ run sequence/define_tpl_struct_inline.cpp : : : : ] [ run sequence/define_assoc_tpl_struct.cpp : : : : ] [ run sequence/std_tuple_iterator.cpp : : : : ] diff --git a/test/sequence/define_struct_inline.cpp b/test/sequence/define_struct_inline.cpp new file mode 100644 index 00000000..8885275d --- /dev/null +++ b/test/sequence/define_struct_inline.cpp @@ -0,0 +1,110 @@ +/*============================================================================= + Copyright (c) 2010, 2012 Christopher Schmidt, Nathan Ridge + + Distributed under the Boost Software Liceclse, Version 1.0. (See accompanying + file LICEclsE_1_0.txt or copy at http://www.boost.org/LICEclsE_1_0.txt) +==============================================================================*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct cls +{ + BOOST_FUSION_DEFINE_STRUCT_INLINE( + point, + (int, x) + (int, y) + ) +}; + +namespace ns +{ + BOOST_FUSION_DEFINE_STRUCT_INLINE(s, (int, m)) +} + +int +main() +{ + using namespace boost::fusion; + + std::cout << tuple_open('['); + std::cout << tuple_close(']'); + std::cout << tuple_delimiter(", "); + + { + BOOST_MPL_ASSERT_NOT((traits::is_view)); + cls::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(boost::fusion::result_of::size::value == 2); + BOOST_STATIC_ASSERT(!boost::fusion::result_of::empty::value); + + BOOST_TEST(front(p) == 6); + BOOST_TEST(back(p) == 9); + } + + { + vector v1(4, 2); + cls::point v2(5, 3); + 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 cls::point to vector + cls::point p(5, 3); + vector v(p); + v = p; + } + + { + // conversion from cls::point to list + cls::point p(5, 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>)); + } + + { + cls::point p = make_list(5,3); + BOOST_TEST(p == make_vector(5,3)); + + p = make_list(3,5); + BOOST_TEST(p == make_vector(3,5)); + } + + return boost::report_errors(); +} + diff --git a/test/sequence/define_tpl_struct_inline.cpp b/test/sequence/define_tpl_struct_inline.cpp new file mode 100644 index 00000000..9aa574a0 --- /dev/null +++ b/test/sequence/define_tpl_struct_inline.cpp @@ -0,0 +1,114 @@ +/*============================================================================= + Copyright (c) 2010, 2012 Christopher Schmidt, nathan Ridge + + 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 + +struct cls +{ + BOOST_FUSION_DEFINE_TPL_STRUCT_INLINE( + (X)(Y), + point, + (X, x) + (Y, y) + ) +}; + +namespace ns +{ + BOOST_FUSION_DEFINE_TPL_STRUCT_INLINE((M), s, (M, m)) +} + +int +main() +{ + using namespace boost::fusion; + + typedef cls::point point; + + std::cout << tuple_open('['); + std::cout << tuple_close(']'); + std::cout << tuple_delimiter(", "); + + { + BOOST_MPL_ASSERT_NOT((traits::is_view)); + 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(boost::fusion::result_of::size::value == 2); + BOOST_STATIC_ASSERT(!boost::fusion::result_of::empty::value); + + BOOST_TEST(front(p) == 6); + BOOST_TEST(back(p) == 9); + } + + { + vector v1(4, 2); + point v2(5, 3); + 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 point to vector + point p(5, 3); + vector v(p); + v = p; + } + + { + // conversion from point to list + point p(5, 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>)); + } + + + { + point p = make_list(5,3); + BOOST_TEST(p == make_vector(5,3)); + + p = make_list(3,5); + BOOST_TEST(p == make_vector(3,5)); + } + + return boost::report_errors(); +} +