diff --git a/doc/adapted.qbk b/doc/adapted.qbk index fd8237cd..93aa1703 100644 --- a/doc/adapted.qbk +++ b/doc/adapted.qbk @@ -658,7 +658,7 @@ __random_access_sequence__. [heading Synopsis] - BOOST_FUSION_ADAPT_ADT( + BOOST_FUSION_ADAPT_TPL_ADT( (template_param0)(template_param1)..., (type_name) (specialization_param0)(specialization_param1)..., (attribute_type0, attribute_const_type0, get_expr0, set_expr0) @@ -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/include/boost/fusion/adapted/struct/detail/define_struct_inline.hpp b/include/boost/fusion/adapted/struct/detail/define_struct_inline.hpp index 84eccca6..a7961ec3 100644 --- a/include/boost/fusion/adapted/struct/detail/define_struct_inline.hpp +++ b/include/boost/fusion/adapted/struct/detail/define_struct_inline.hpp @@ -29,6 +29,27 @@ #define BOOST_FUSION_MAKE_DEFAULT_INIT_LIST_ENTRY(R, DATA, N, ATTRIBUTE) \ BOOST_PP_COMMA_IF(N) BOOST_PP_TUPLE_ELEM(2, 1, ATTRIBUTE)() +#define BOOST_FUSION_MAKE_DEFAULT_INIT_LIST(ATTRIBUTES_SEQ) \ + : BOOST_PP_SEQ_FOR_EACH_I( \ + BOOST_FUSION_MAKE_DEFAULT_INIT_LIST_ENTRY, \ + ~, \ + ATTRIBUTES_SEQ) \ + +#define BOOST_FUSION_IGNORE_1(ARG1) +#define BOOST_FUSION_IGNORE_2(ARG1, ARG2) + +#define BOOST_FUSION_MAKE_COPY_CONSTRUCTOR(NAME, ATTRIBUTES_SEQ) \ + NAME(BOOST_PP_SEQ_FOR_EACH_I( \ + BOOST_FUSION_MAKE_CONST_REF_PARAM, \ + ~, \ + ATTRIBUTES_SEQ)) \ + : BOOST_PP_SEQ_FOR_EACH_I( \ + BOOST_FUSION_MAKE_INIT_LIST_ENTRY, \ + ~, \ + ATTRIBUTES_SEQ) \ + { \ + } \ + #define BOOST_FUSION_MAKE_CONST_REF_PARAM(R, DATA, N, ATTRIBUTE) \ BOOST_PP_COMMA_IF(N) \ BOOST_PP_TUPLE_ELEM(2, 0, ATTRIBUTE) const& \ @@ -162,23 +183,19 @@ NAME, ATTRIBUTES_SEQ, ATTRIBUTES_SEQ_SIZE) \ \ NAME() \ - : BOOST_PP_SEQ_FOR_EACH_I( \ - BOOST_FUSION_MAKE_DEFAULT_INIT_LIST_ENTRY, \ - ~, \ - ATTRIBUTES_SEQ) \ + BOOST_PP_IF( \ + BOOST_PP_SEQ_SIZE(ATTRIBUTES_SEQ), \ + BOOST_FUSION_MAKE_DEFAULT_INIT_LIST, \ + BOOST_FUSION_IGNORE_1) \ + (ATTRIBUTES_SEQ) \ { \ } \ \ - NAME(BOOST_PP_SEQ_FOR_EACH_I( \ - BOOST_FUSION_MAKE_CONST_REF_PARAM, \ - ~, \ - ATTRIBUTES_SEQ)) \ - : BOOST_PP_SEQ_FOR_EACH_I( \ - BOOST_FUSION_MAKE_INIT_LIST_ENTRY, \ - ~, \ - ATTRIBUTES_SEQ) \ - { \ - } \ + BOOST_PP_IF( \ + BOOST_PP_SEQ_SIZE(ATTRIBUTES_SEQ), \ + BOOST_FUSION_MAKE_COPY_CONSTRUCTOR, \ + BOOST_FUSION_IGNORE_2) \ + (NAME, ATTRIBUTES_SEQ) \ \ template \ NAME(const boost_fusion_uglified_Seq& rhs) \ diff --git a/include/boost/fusion/container/deque/detail/deque_keyed_values.hpp b/include/boost/fusion/container/deque/detail/deque_keyed_values.hpp deleted file mode 100644 index 898bc46b..00000000 --- a/include/boost/fusion/container/deque/detail/deque_keyed_values.hpp +++ /dev/null @@ -1,102 +0,0 @@ -/*============================================================================= - Copyright (c) 2005-2011 Joel de Guzman - Copyright (c) 2005-2006 Dan Marsden - - 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_DEQUE_DETAIL_DEQUE_KEYED_VALUES_26112006_1330) -#define BOOST_FUSION_DEQUE_DETAIL_DEQUE_KEYED_VALUES_26112006_1330 - -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#define FUSION_VOID(z, n, _) void_ - -namespace boost { namespace fusion -{ - struct void_; -}} - -#if !defined(BOOST_FUSION_DONT_USE_PREPROCESSED_FILES) -#include -#else -#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES) -#pragma wave option(preserve: 2, line: 0, output: "preprocessed/deque_keyed_values" FUSION_MAX_DEQUE_SIZE_STR ".hpp") -#endif - -/*============================================================================= - Copyright (c) 2001-2011 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) - - This is an auto-generated file. Do not edit! -==============================================================================*/ - -#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES) -#pragma wave option(preserve: 1) -#endif - -namespace boost { namespace fusion { namespace detail -{ - template - struct keyed_element; - - struct nil_keyed_element; - - template - struct deque_keyed_values_impl; - - template - struct deque_keyed_values_impl - { - typedef nil_keyed_element type; - - static type call() - { - return type(); - } - }; - - template - struct deque_keyed_values_impl - { - typedef mpl::int_ >::value> next_index; - - typedef typename deque_keyed_values_impl< - next_index, - BOOST_PP_ENUM_SHIFTED_PARAMS(FUSION_MAX_DEQUE_SIZE, T)>::type tail; - typedef keyed_element type; - -#include - - }; - - template - struct deque_keyed_values - : deque_keyed_values_impl, BOOST_PP_ENUM_PARAMS(FUSION_MAX_DEQUE_SIZE, T)> - {}; - -}}} - -#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES) -#pragma wave option(output: null) -#endif - -#endif // BOOST_FUSION_DONT_USE_PREPROCESSED_FILES - -#undef FUSION_VOID - -#endif diff --git a/include/boost/fusion/include/repetetive_view.hpp b/include/boost/fusion/include/repetitive_view.hpp similarity index 100% rename from include/boost/fusion/include/repetetive_view.hpp rename to include/boost/fusion/include/repetitive_view.hpp diff --git a/include/boost/fusion/tuple/detail/preprocessed/make_tuple.hpp b/include/boost/fusion/tuple/detail/preprocessed/make_tuple.hpp index 53306dab..6abb0336 100644 --- a/include/boost/fusion/tuple/detail/preprocessed/make_tuple.hpp +++ b/include/boost/fusion/tuple/detail/preprocessed/make_tuple.hpp @@ -18,4 +18,4 @@ #include #else #error "FUSION_MAX_VECTOR_SIZE out of bounds for preprocessed headers" -#endif \ No newline at end of file +#endif diff --git a/include/boost/fusion/tuple/detail/preprocessed/tuple_fwd.hpp b/include/boost/fusion/tuple/detail/preprocessed/tuple_fwd.hpp index ec01d4b7..234936c5 100644 --- a/include/boost/fusion/tuple/detail/preprocessed/tuple_fwd.hpp +++ b/include/boost/fusion/tuple/detail/preprocessed/tuple_fwd.hpp @@ -18,4 +18,4 @@ #include #else #error "FUSION_MAX_VECTOR_SIZE out of bounds for preprocessed headers" -#endif \ No newline at end of file +#endif diff --git a/include/boost/fusion/tuple/detail/preprocessed/tuple_tie.hpp b/include/boost/fusion/tuple/detail/preprocessed/tuple_tie.hpp index 02fd8f7f..5898c6b9 100644 --- a/include/boost/fusion/tuple/detail/preprocessed/tuple_tie.hpp +++ b/include/boost/fusion/tuple/detail/preprocessed/tuple_tie.hpp @@ -18,4 +18,4 @@ #include #else #error "FUSION_MAX_VECTOR_SIZE out of bounds for preprocessed headers" -#endif \ No newline at end of file +#endif diff --git a/test/sequence/adapt_adt.cpp b/test/sequence/adapt_adt.cpp index 73868367..f8762b03 100644 --- a/test/sequence/adapt_adt.cpp +++ b/test/sequence/adapt_adt.cpp @@ -71,6 +71,24 @@ namespace ns int y; }; #endif + + // A sequence that has data members defined in an unrelated namespace + // (std, in this case). This allows testing ADL issues. + class name + { + public: + name() {} + name(const std::string& last, const std::string& first) + : last(last), first(first) {} + + const std::string& get_last() const { return last; } + const std::string& get_first() const { return first; } + void set_last(const std::string& last_) { last = last_; } + void set_first(const std::string& first_) { first = first_; } + private: + std::string last; + std::string first; + }; } BOOST_FUSION_ADAPT_ADT( @@ -87,6 +105,12 @@ BOOST_FUSION_ADAPT_ADT( ) #endif +BOOST_FUSION_ADAPT_ADT( + ns::name, + (const std::string&, const std::string&, obj.get_last(), obj.set_last(val)) + (const std::string&, const std::string&, obj.get_first(), obj.set_first(val)) +) + int main() { @@ -131,6 +155,20 @@ main() BOOST_TEST(v3 >= v2); } + { + fusion::vector v1("Lincoln", "Abraham"); + ns::name v2("Roosevelt", "Franklin"); + ns::name v3("Roosevelt", "Theodore"); + 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); diff --git a/test/sequence/adapt_tpl_adt.cpp b/test/sequence/adapt_tpl_adt.cpp index 2f0d4c6b..aeb0f721 100644 --- a/test/sequence/adapt_tpl_adt.cpp +++ b/test/sequence/adapt_tpl_adt.cpp @@ -67,6 +67,7 @@ main() using namespace boost::fusion; typedef ns::point point; + typedef ns::point name; std::cout << tuple_open('['); std::cout << tuple_close(']'); @@ -106,6 +107,20 @@ main() BOOST_TEST(v3 >= v2); } + { + boost::fusion::vector v1("Lincoln", "Abraham"); + name v2("Roosevelt", "Franklin"); + name v3("Roosevelt", "Theodore"); + 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);