Merge pull request #54 from boostorg/fusion_adapters

Type Deducing Fusion adapters into develop
This commit is contained in:
Joel de Guzman
2015-02-11 06:53:28 +08:00
31 changed files with 1399 additions and 396 deletions

View File

@ -185,10 +185,20 @@ necessary boilerplate to make an arbitrary struct a model of
__random_access_sequence__. __random_access_sequence__.
[heading Synopsis] [heading Synopsis]
BOOST_FUSION_ADAPT_STRUCT(
struct_name,
member_name0,
member_name1,
member_name2,
...
)
// Without BOOST_PP_VARIADICS support :
BOOST_FUSION_ADAPT_STRUCT( BOOST_FUSION_ADAPT_STRUCT(
struct_name, struct_name,
(member_type0, member_name0) (member_type0, member_name0)
(member_type1, member_name1) (member_type1, member_name1)
(BOOST_FUSION_ADAPT_AUTO, member_name2)
... ...
) )
@ -196,9 +206,13 @@ __random_access_sequence__.
The above macro generates the necessary code to adapt `struct_name` The above macro generates the necessary code to adapt `struct_name`
as a model of __random_access_sequence__. as a model of __random_access_sequence__.
The sequence of `(member_typeN, member_nameN)`
pairs declares the type and names of each of the struct members that are The sequence of `member_nameN,` arguments or `(member_typeN, member_nameN)`
part of the sequence. pairs declares the type and names of each of the struct members that are part of
the sequence.
When member_typeN is omitted or set to BOOST_FUSION_ADAPT_AUTO, the type is
infered with Boost.TypeOf.
The macro should be used at global scope, and `struct_name` should be the fully The macro should be used at global scope, and `struct_name` should be the fully
namespace qualified name of the struct to be adapted. namespace qualified name of the struct to be adapted.
@ -208,7 +222,7 @@ namespace qualified name of the struct to be adapted.
#include <boost/fusion/adapted/struct/adapt_struct.hpp> #include <boost/fusion/adapted/struct/adapt_struct.hpp>
#include <boost/fusion/include/adapt_struct.hpp> #include <boost/fusion/include/adapt_struct.hpp>
[heading Example] [heading Example: BOOST_FUSION_ADAPT_STRUCT ]
namespace demo namespace demo
{ {
struct employee struct employee
@ -221,8 +235,15 @@ namespace qualified name of the struct to be adapted.
// demo::employee is now a Fusion sequence // demo::employee is now a Fusion sequence
BOOST_FUSION_ADAPT_STRUCT( BOOST_FUSION_ADAPT_STRUCT(
demo::employee, demo::employee,
(std::string, name) name,
(int, age)) age)
// Without BOOST_PP_VARIADICS support :
BOOST_FUSION_ADAPT_STRUCT(
demo::employee,
(BOOST_FUSION_ADAPT_AUTO, name)
(BOOST_FUSION_ADAPT_AUTO, age)
)
[endsect] [endsect]
@ -234,11 +255,21 @@ necessary boilerplate to make an arbitrary template struct a model of
__random_access_sequence__. __random_access_sequence__.
[heading Synopsis] [heading Synopsis]
BOOST_FUSION_ADAPT_TPL_STRUCT(
(template_param0)(template_param1)...,
(struct_name) (specialization_param0)(specialization_param1)...,
member_name0,
member_name1
...
)
// Without BOOST_PP_VARIADICS support :
BOOST_FUSION_ADAPT_TPL_STRUCT( BOOST_FUSION_ADAPT_TPL_STRUCT(
(template_param0)(template_param1)..., (template_param0)(template_param1)...,
(struct_name) (specialization_param0)(specialization_param1)..., (struct_name) (specialization_param0)(specialization_param1)...,
(member_type0, member_name0) (member_type0, member_name0)
(member_type1, member_name1) (member_type1, member_name1)
(BOOST_FUSION_ADAPT_AUTO, member_name2),
... ...
) )
@ -252,9 +283,12 @@ the template type parameters used.
The sequence `(specialization_param0)(specialization_param1)...` The sequence `(specialization_param0)(specialization_param1)...`
declares the template parameters of the actual specialization of `struct_name` declares the template parameters of the actual specialization of `struct_name`
that is adapted as a fusion sequence. that is adapted as a fusion sequence.
The sequence of `(member_typeN, member_nameN)` The sequence of `member_nameN,` arguments or `(member_typeN, member_nameN)`
pairs declares the type and names of each of the struct members that are pairs declares the type and names of each of the struct members that are part of
part of the sequence. the sequence.
When member_typeN is omitted or set to BOOST_FUSION_ADAPT_AUTO, the type is
infered with Boost.TypeOf.
The macro should be used at global scope, and `struct_name` should be the fully The macro should be used at global scope, and `struct_name` should be the fully
namespace qualified name of the struct to be adapted. namespace qualified name of the struct to be adapted.
@ -272,6 +306,7 @@ namespace qualified name of the struct to be adapted.
{ {
Name name; Name name;
Age age; Age age;
int employment_timestamp;
}; };
} }
@ -280,7 +315,16 @@ namespace qualified name of the struct to be adapted.
(Name)(Age), (Name)(Age),
(demo::employee) (Name)(Age), (demo::employee) (Name)(Age),
(Name, name) (Name, name)
(Age, age)) (Age, age)
(BOOST_FUSION_ADAPT_AUTO, employment_timestamp))
// Or by infering type completely
BOOST_FUSION_ADAPT_TPL_STRUCT(
(Name)(Age),
(demo::employee) (Name)(Age),
name,
age,
employment_timestamp)
[endsect] [endsect]
@ -293,10 +337,31 @@ arbitrary struct a model of __random_access_sequence__. The given struct is
adapted using the given name. adapted using the given name.
[heading Synopsis] [heading Synopsis]
BOOST_FUSION_ADAPT_STRUCT_NAMED(
struct_name, adapted_name,
member_name0,
member_name1,
member_name2,
...
)
BOOST_FUSION_ADAPT_STRUCT_NAMED_NS(
struct_name,
(namespace0)(namespace1)...,
adapted_name,
member_name0,
member_name1,
member_name2,
...
)
// Without BOOST_PP_VARIADICS support :
BOOST_FUSION_ADAPT_STRUCT_NAMED( BOOST_FUSION_ADAPT_STRUCT_NAMED(
struct_name, adapted_name, struct_name, adapted_name,
(member_type0, member_name0) (member_type0, member_name0)
(member_type1, member_name1) (member_type1, member_name1)
(BOOST_FUSION_ADAPT_AUTO, member_name2),
... ...
) )
@ -306,9 +371,12 @@ adapted using the given name.
adapted_name, adapted_name,
(member_type0, member_name0) (member_type0, member_name0)
(member_type1, member_name1) (member_type1, member_name1)
(BOOST_FUSION_ADAPT_AUTO, member_name2),
... ...
) )
[heading Semantics] [heading Semantics]
The above macros generate the necessary code to adapt `struct_name` The above macros generate the necessary code to adapt `struct_name`
@ -321,9 +389,12 @@ If an empty namespace sequence is given (that is a macro that expands to
nothing), the adapted view is placed in the global namespace. nothing), the adapted view is placed in the global namespace.
If no namespace sequence is given (i.e. `BOOST_FUSION_ADAPT_STRUCT_NAMED`), the If no namespace sequence is given (i.e. `BOOST_FUSION_ADAPT_STRUCT_NAMED`), the
adapted view is placed in the namespace `boost::fusion::adapted`. adapted view is placed in the namespace `boost::fusion::adapted`.
The sequence of `(member_typeN, member_nameN)` The sequence of `member_nameN,` arguments or `(member_typeN, member_nameN)`
pairs declares the type and names of each of the struct members that are pairs declares the type and names of each of the struct members that are part of
part of the sequence. the sequence.
When member_typeN is omitted or set to BOOST_FUSION_ADAPT_AUTO, the type is
infered with Boost.TypeOf.
The macros should be used at global scope, and `struct_name` should be the fully The macros should be used at global scope, and `struct_name` should be the fully
namespace qualified name of the struct to be converted. namespace qualified name of the struct to be converted.
@ -347,8 +418,14 @@ namespace qualified name of the struct to be converted.
// referring to demo::employee // referring to demo::employee
BOOST_FUSION_ADAPT_STRUCT_NAMED( BOOST_FUSION_ADAPT_STRUCT_NAMED(
demo::employee, adapted_employee, demo::employee, adapted_employee,
(std::string, name) name,
(int, age)) age)
// Without BOOST_PP_VARIADICS support :
BOOST_FUSION_ADAPT_STRUCT_NAMED(
demo::employee, adapted_employee,
(BOOST_FUSION_ADAPT_AUTO, name),
(BOOST_FUSION_ADAPT_AUTO, age))
[endsect] [endsect]
@ -362,8 +439,8 @@ __random_access_sequence__ and __associative_sequence__.
[heading Synopsis] [heading Synopsis]
BOOST_FUSION_ADAPT_ASSOC_STRUCT( BOOST_FUSION_ADAPT_ASSOC_STRUCT(
struct_name, struct_name,
(member_type0, member_name0, key_type0) ([member_type0,] member_name0, key_type0)
(member_type1, member_name1, key_type1) ([member_type1,] member_name1, key_type1)
... ...
) )
@ -371,10 +448,13 @@ __random_access_sequence__ and __associative_sequence__.
The above macro generates the necessary code to adapt `struct_name` The above macro generates the necessary code to adapt `struct_name`
as a model of __random_access_sequence__ and __associative_sequence__. as a model of __random_access_sequence__ and __associative_sequence__.
The sequence of `(member_typeN, member_nameN, key_typeN)` The sequence of `([member_typeN,] member_nameN, key_typeN)` tuples
triples declares the type, name and key type of each of the struct members declares the type, name and key type of each of the struct members
that are part of the sequence. that are part of the sequence.
When member_typeN is omitted or set to BOOST_FUSION_ADAPT_AUTO, the type is
infered with Boost.TypeOf.
The macro should be used at global scope, and `struct_name` should be the fully The macro should be used at global scope, and `struct_name` should be the fully
namespace qualified name of the struct to be adapted. namespace qualified name of the struct to be adapted.
@ -404,8 +484,14 @@ namespace qualified name of the struct to be adapted.
// keys keys::name and keys::age present. // keys keys::name and keys::age present.
BOOST_FUSION_ADAPT_ASSOC_STRUCT( BOOST_FUSION_ADAPT_ASSOC_STRUCT(
demo::employee, demo::employee,
(std::string, name, keys::name) (name, keys::name)
(int, age, keys::age)) (age, keys::age))
// Without BOOST_PP_VARIADICS support :
BOOST_FUSION_ADAPT_ASSOC_STRUCT(
demo::employee,
(BOOST_FUSION_ADAPT_AUTO, name, keys::name),
(BOOST_FUSION_ADAPT_AUTO, age, keys::name))
[endsect] [endsect]
@ -420,8 +506,8 @@ __random_access_sequence__ and __associative_sequence__.
BOOST_FUSION_ADAPT_ASSOC_TPL_STRUCT( BOOST_FUSION_ADAPT_ASSOC_TPL_STRUCT(
(template_param0)(template_param1)..., (template_param0)(template_param1)...,
(struct_name) (specialization_param0)(specialization_param1)..., (struct_name) (specialization_param0)(specialization_param1)...,
(member_type0, member_name0, key_type0) ([member_type0,] member_name0, key_type0)
(member_type1, member_name1, key_type1) ([member_type1,] member_name1, key_type1)
... ...
) )
@ -435,10 +521,13 @@ the template type parameters used.
The sequence `(specialization_param0)(specialization_param1)...` The sequence `(specialization_param0)(specialization_param1)...`
declares the template parameters of the actual specialization of `struct_name` declares the template parameters of the actual specialization of `struct_name`
that is adapted as a fusion sequence. that is adapted as a fusion sequence.
The sequence of `(member_typeN, member_nameN, key_typeN)` The sequence of `([member_typeN,] member_nameN, key_typeN)`
triples declares the type, name and key type of each of the struct members tuples declares the type, name and key type of each of the struct members
that are part of the sequence. that are part of the sequence.
When member_typeN is omitted or set to BOOST_FUSION_ADAPT_AUTO, the type is
infered with Boost.TypeOf.
The macro should be used at global scope, and `struct_name` should be the fully The macro should be used at global scope, and `struct_name` should be the fully
namespace qualified name of the struct to be adapted. namespace qualified name of the struct to be adapted.
@ -467,6 +556,13 @@ namespace qualified name of the struct to be adapted.
// Any instantiated demo::employee is now a Fusion sequence. // Any instantiated demo::employee is now a Fusion sequence.
// It is also an associative sequence with // It is also an associative sequence with
// keys keys::name and keys::age present. // keys keys::name and keys::age present.
BOOST_FUSION_ADAPT_ASSOC_TPL_STRUCT(
(Name)(Age),
(demo::employee) (Name)(Age),
(name, keys::name)
(age, keys::age))
// Without BOOST_PP_VARIADICS support :
BOOST_FUSION_ADAPT_ASSOC_TPL_STRUCT( BOOST_FUSION_ADAPT_ASSOC_TPL_STRUCT(
(Name)(Age), (Name)(Age),
(demo::employee) (Name)(Age), (demo::employee) (Name)(Age),
@ -486,8 +582,8 @@ __associative_sequence__. The given struct is adapted using the given name.
[heading Synopsis] [heading Synopsis]
BOOST_FUSION_ADAPT_ASSOC_STRUCT_NAMED( BOOST_FUSION_ADAPT_ASSOC_STRUCT_NAMED(
struct_name, adapted_name, struct_name, adapted_name,
(member_type0, member_name0, key_type0) ([member_type0,] member_name0, key_type0)
(member_type1, member_name1, key_type1) ([member_type1,] member_name1, key_type1)
... ...
) )
@ -495,8 +591,8 @@ __associative_sequence__. The given struct is adapted using the given name.
struct_name, struct_name,
(namespace0)(namespace1)..., (namespace0)(namespace1)...,
adapted_name, adapted_name,
(member_type0, member_name0, key_type0) ([member_type0,] member_name0, key_type0)
(member_type1, member_name1, key_type1) ([member_type1,] member_name1, key_type1)
... ...
) )
@ -516,6 +612,9 @@ The sequence of `(member_typeN, member_nameN, key_typeN)`
triples declares the type, name and key type of each of the struct members triples declares the type, name and key type of each of the struct members
that are part of the sequence. that are part of the sequence.
When member_typeN is omitted or set to BOOST_FUSION_ADAPT_AUTO, the type is
infered with Boost.TypeOf.
The macros should be used at global scope, and `struct_name` should be the fully The macros should be used at global scope, and `struct_name` should be the fully
namespace qualified name of the struct to be converted. namespace qualified name of the struct to be converted.
@ -544,8 +643,14 @@ namespace qualified name of the struct to be converted.
// referring to demo::employee // referring to demo::employee
BOOST_FUSION_ADAPT_ASSOC_STRUCT_NAMED( BOOST_FUSION_ADAPT_ASSOC_STRUCT_NAMED(
demo::employee, adapted_employee, demo::employee, adapted_employee,
(std::string, name, keys::name) (name, keys::name)
(int, age, keys::age)) (age, keys::age))
// Without BOOST_PP_VARIADICS support :
BOOST_FUSION_ADAPT_ASSOC_STRUCT_NAMED(
demo::employee, adapted_employee,
(BOOST_FUSION_ADAPT_AUTO, name, keys::name)
(BOOST_FUSION_ADAPT_AUTO, age, keys::age))
[endsect] [endsect]
@ -559,8 +664,8 @@ __random_access_sequence__.
BOOST_FUSION_ADAPT_ADT( BOOST_FUSION_ADAPT_ADT(
type_name, type_name,
(attribute_type0, attribute_const_type0, get_expr0, set_expr0) ([attribute_type0, attribute_const_type0,] get_expr0, set_expr0)
(attribute_type1, attribute_const_type1, get_expr1, set_expr1) ([attribute_type1, attribute_const_type1,] get_expr1, set_expr1)
... ...
) )
@ -569,7 +674,7 @@ __random_access_sequence__.
The above macro generates the necessary code to adapt `type_name` The above macro generates the necessary code to adapt `type_name`
as a model of __random_access_sequence__. as a model of __random_access_sequence__.
The sequence of The sequence of
[^(attribute_type['N], attribute_const_type['N], get_expr['N], set_expr['N])] [^([attribute_type['N], attribute_const_type['N],] get_expr['N], set_expr['N])]
quadruples declares the types, const types, get-expressions and set-expressions quadruples declares the types, const types, get-expressions and set-expressions
of the elements that are part of the adapted fusion sequence. of the elements that are part of the adapted fusion sequence.
[^get_expr['N]] is the expression that is invoked to get the ['N]th element [^get_expr['N]] is the expression that is invoked to get the ['N]th element
@ -577,7 +682,9 @@ of an instance of `type_name`. This expression may access a variable named
`obj` of type `type_name&` or `type_name const&` which represents the underlying `obj` of type `type_name&` or `type_name const&` which represents the underlying
instance of `type_name`. instance of `type_name`.
[^attribute_type['N]] and [^attribute_const_type['N]] may specify the types [^attribute_type['N]] and [^attribute_const_type['N]] may specify the types
that [^get_expr['N]] denotes to. that [^get_expr['N]] denotes to, when omitted the type is deduced from
[get_expr['N]] return type via BOOST_TYPEOF. On compiler missing support for
variadic macros BOOST_FUSION_ADAPT_AUTO can be used to avoid repeating the type.
[^set_expr['N]] is the expression that is invoked to set the ['N]th element [^set_expr['N]] is the expression that is invoked to set the ['N]th element
of an instance of `type_name`. This expression may access variables named of an instance of `type_name`. This expression may access variables named
`obj` of type `type_name&`, which represent the corresponding instance of `obj` of type `type_name&`, which represent the corresponding instance of
@ -635,8 +742,8 @@ namespace qualified name of the class type to be adapted.
BOOST_FUSION_ADAPT_ADT( BOOST_FUSION_ADAPT_ADT(
demo::employee, demo::employee,
(std::string const&, std::string const&, obj.get_name(), obj.set_name(val)) (obj.get_name(), obj.set_name(val))
(int, int, obj.get_age(), obj.set_age(val))) (obj.get_age(), obj.set_age(val)))
demo::employee e; demo::employee e;
front(e)="Edward Norton"; front(e)="Edward Norton";
@ -661,8 +768,8 @@ __random_access_sequence__.
BOOST_FUSION_ADAPT_TPL_ADT( BOOST_FUSION_ADAPT_TPL_ADT(
(template_param0)(template_param1)..., (template_param0)(template_param1)...,
(type_name) (specialization_param0)(specialization_param1)..., (type_name) (specialization_param0)(specialization_param1)...,
(attribute_type0, attribute_const_type0, get_expr0, set_expr0) ([attribute_type0, attribute_const_type0,] get_expr0, set_expr0)
(attribute_type1, attribute_const_type1, get_expr1, set_expr1) ([attribute_type1, attribute_const_type1,] get_expr1, set_expr1)
... ...
) )
@ -685,7 +792,9 @@ of an instance of `type_name`. This expression may access a variable named
`obj` of type `type_name&` or `type_name const&` which represents the underlying `obj` of type `type_name&` or `type_name const&` which represents the underlying
instance of `type_name`. instance of `type_name`.
[^attribute_type['N]] and [^attribute_const_type['N]] may specify the types [^attribute_type['N]] and [^attribute_const_type['N]] may specify the types
that [^get_expr['N]] denotes to. that [^get_expr['N]] denotes to, when omitted the type is deduced from
[get_expr['N]] return type via BOOST_TYPEOF. On compiler missing support for
variadic macros BOOST_FUSION_ADAPT_AUTO can be used to avoid repeating the type.
[^set_expr['N]] is the expression that is invoked to set the ['N]th element [^set_expr['N]] is the expression that is invoked to set the ['N]th element
of an instance of `type_name`. This expression may access variables named of an instance of `type_name`. This expression may access variables named
`obj` of type `type_name&`, which represent the corresponding instance of `obj` of type `type_name&`, which represent the corresponding instance of
@ -770,8 +879,8 @@ __random_access_sequence__ and __associative_sequence__.
BOOST_FUSION_ADAPT_ASSOC_ADT( BOOST_FUSION_ADAPT_ASSOC_ADT(
type_name, type_name,
(attribute_type0, attribute_const_type0, get_expr0, set_expr0, key_type0) ([attribute_type0, attribute_const_type0,] get_expr0, set_expr0, key_type0)
(attribute_type1, attribute_const_type1, get_expr1, set_expr1, key_type1) ([attribute_type1, attribute_const_type1,] get_expr1, set_expr1, key_type1)
... ...
) )
@ -788,7 +897,9 @@ of an instance of `type_name`. This expression may access a variable named
`obj` of type `type_name&` or `type_name const&` which represents the underlying `obj` of type `type_name&` or `type_name const&` which represents the underlying
instance of `type_name`. instance of `type_name`.
[^attribute_type['N]] and [^attribute_const_type['N]] may specify the types [^attribute_type['N]] and [^attribute_const_type['N]] may specify the types
that [^get_expr['N]] denotes to. that [^get_expr['N]] denotes to, when omitted the type is deduced from
[get_expr['N]] return type via BOOST_TYPEOF. On compiler missing support for
variadic macros BOOST_FUSION_ADAPT_AUTO can be used to avoid repeating the type.
[^set_expr['N]] is the expression that is invoked to set the ['N]th element [^set_expr['N]] is the expression that is invoked to set the ['N]th element
of an instance of `type_name`. This expression may access variables named of an instance of `type_name`. This expression may access variables named
`obj` of type `type_name&`, which represent the corresponding instance of `obj` of type `type_name&`, which represent the corresponding instance of
@ -852,8 +963,8 @@ namespace qualified name of the class type to be adapted.
BOOST_FUSION_ADAPT_ASSOC_ADT( BOOST_FUSION_ADAPT_ASSOC_ADT(
demo::employee, demo::employee,
(std::string const&, std::string const&, obj.get_name(), obj.set_name(val), keys::name) (obj.get_name(), obj.set_name(val), keys::name)
(int, int, obj.get_age(), obj.set_age(val), keys::age)) (obj.get_age(), obj.set_age(val), keys::age))
demo::employee e; demo::employee e;
at_key<keys::name>(e)="Edward Norton"; at_key<keys::name>(e)="Edward Norton";
@ -878,8 +989,8 @@ __random_access_sequence__ and __associative_sequence__.
BOOST_FUSION_ADAPT_ASSOC_TPL_ADT( BOOST_FUSION_ADAPT_ASSOC_TPL_ADT(
(template_param0)(template_param1)..., (template_param0)(template_param1)...,
(type_name) (specialization_param0)(specialization_param1)..., (type_name) (specialization_param0)(specialization_param1)...,
(attribute_type0, attribute_const_type0, get_expr0, set_expr0, key_type0) ([attribute_type0, attribute_const_type0,] get_expr0, set_expr0, key_type0)
(attribute_type1, attribute_const_type1, get_expr1, set_expr1, key_type1) ([attribute_type1, attribute_const_type1,] get_expr1, set_expr1, key_type1)
... ...
) )
@ -894,7 +1005,7 @@ The sequence `(specialization_param0)(specialization_param1)...`
declares the template parameters of the actual specialization of `type_name` declares the template parameters of the actual specialization of `type_name`
that is adapted as a fusion sequence. that is adapted as a fusion sequence.
The sequence of The sequence of
[^(attribute_type['N], attribute_const_type['N], get_expr['N], set_expr['N], key_type['N])] [^([attribute_type['N], attribute_const_type['N],] get_expr['N], set_expr['N], key_type['N])]
5-tuples declares the types, const types, get-expressions, set-expressions and key types 5-tuples declares the types, const types, get-expressions, set-expressions and key types
of the elements that are part of the adapted fusion sequence. of the elements that are part of the adapted fusion sequence.
[^get_expr['N]] is the expression that is invoked to get the ['N]th element [^get_expr['N]] is the expression that is invoked to get the ['N]th element
@ -902,7 +1013,9 @@ of an instance of `type_name`. This expression may access a variable named
`obj` of type `type_name&` or `type_name const&` which represents the underlying `obj` of type `type_name&` or `type_name const&` which represents the underlying
instance of `type_name`. instance of `type_name`.
[^attribute_type['N]] and [^attribute_const_type['N]] may specify the types [^attribute_type['N]] and [^attribute_const_type['N]] may specify the types
that [^get_expr['N]] denotes to. that [^get_expr['N]] denotes to, when omitted the type is deduced from
[get_expr['N]] return type via BOOST_TYPEOF. On compiler missing support for
variadic macros BOOST_FUSION_ADAPT_AUTO can be used to avoid repeating the type.
[^set_expr['N]] is the expression that is invoked to set the ['N]th element [^set_expr['N]] is the expression that is invoked to set the ['N]th element
of an instance of `type_name`. This expression may access variables named of an instance of `type_name`. This expression may access variables named
`obj` of type `type_name&`, which represent the corresponding instance of `obj` of type `type_name&`, which represent the corresponding instance of

View File

@ -2,6 +2,7 @@
Copyright (c) 2001-2009 Joel de Guzman Copyright (c) 2001-2009 Joel de Guzman
Copyright (c) 2009-2010 Hartmut Kaiser Copyright (c) 2009-2010 Hartmut Kaiser
Copyright (c) 2010-2011 Christopher Schmidt Copyright (c) 2010-2011 Christopher Schmidt
Copyright (c) 2013-2014 Damien Buhl
Distributed under the Boost Software License, Version 1.0. (See accompanying 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) file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -13,6 +14,9 @@
#include <boost/fusion/support/config.hpp> #include <boost/fusion/support/config.hpp>
#include <boost/preprocessor/cat.hpp> #include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/empty.hpp> #include <boost/preprocessor/empty.hpp>
#include <boost/preprocessor/control/if.hpp>
#include <boost/preprocessor/comparison/equal.hpp>
#include <boost/preprocessor/comparison/less.hpp>
#include <boost/type_traits/add_reference.hpp> #include <boost/type_traits/add_reference.hpp>
#include <boost/type_traits/is_const.hpp> #include <boost/type_traits/is_const.hpp>
#include <boost/type_traits/add_const.hpp> #include <boost/type_traits/add_const.hpp>
@ -22,6 +26,7 @@
#include <boost/fusion/adapted/struct/detail/adapt_base.hpp> #include <boost/fusion/adapted/struct/detail/adapt_base.hpp>
#include <boost/fusion/adapted/struct/detail/at_impl.hpp> #include <boost/fusion/adapted/struct/detail/at_impl.hpp>
#include <boost/fusion/adapted/struct/detail/is_view_impl.hpp> #include <boost/fusion/adapted/struct/detail/is_view_impl.hpp>
#include <boost/fusion/adapted/struct/detail/proxy_type.hpp>
#include <boost/fusion/adapted/struct/detail/is_sequence_impl.hpp> #include <boost/fusion/adapted/struct/detail/is_sequence_impl.hpp>
#include <boost/fusion/adapted/struct/detail/value_at_impl.hpp> #include <boost/fusion/adapted/struct/detail/value_at_impl.hpp>
#include <boost/fusion/adapted/struct/detail/category_of_impl.hpp> #include <boost/fusion/adapted/struct/detail/category_of_impl.hpp>
@ -32,17 +37,21 @@
#include <boost/fusion/adapted/struct/detail/deref_impl.hpp> #include <boost/fusion/adapted/struct/detail/deref_impl.hpp>
#include <boost/fusion/adapted/adt/detail/extension.hpp> #include <boost/fusion/adapted/adt/detail/extension.hpp>
#include <boost/fusion/adapted/adt/detail/adapt_base.hpp> #include <boost/fusion/adapted/adt/detail/adapt_base.hpp>
#include <boost/fusion/adapted/adt/detail/adapt_base_attr_filler.hpp>
#define BOOST_FUSION_ADAPT_ADT_FILLER_0(A, B, C, D)\ #define BOOST_FUSION_ADAPT_ADT_C( \
((A, B, C, D)) BOOST_FUSION_ADAPT_ADT_FILLER_1 TEMPLATE_PARAMS_SEQ, NAME_SEQ, IS_VIEW, I, ATTRIBUTE) \
#define BOOST_FUSION_ADAPT_ADT_FILLER_1(A, B, C, D)\ BOOST_FUSION_ADAPT_ADT_C_BASE( \
((A, B, C, D)) BOOST_FUSION_ADAPT_ADT_FILLER_0 TEMPLATE_PARAMS_SEQ, \
#define BOOST_FUSION_ADAPT_ADT_FILLER_0_END NAME_SEQ, \
#define BOOST_FUSION_ADAPT_ADT_FILLER_1_END I, \
BOOST_PP_IF(IS_VIEW, BOOST_FUSION_PROXY_PREFIX, BOOST_PP_EMPTY), \
#define BOOST_FUSION_ADAPT_ADT_C(TEMPLATE_PARAMS_SEQ, NAME_SEQ, I, ATTRIBUTE) \ BOOST_FUSION_ADAPT_ADT_WRAPPEDATTR(ATTRIBUTE), \
BOOST_FUSION_ADAPT_ADT_C_BASE( \ BOOST_FUSION_ADAPT_ADT_WRAPPEDATTR_SIZE(ATTRIBUTE), \
TEMPLATE_PARAMS_SEQ, NAME_SEQ, I, ATTRIBUTE, 4) BOOST_PP_IF( \
BOOST_PP_LESS( \
BOOST_FUSION_ADAPT_ADT_WRAPPEDATTR_SIZE(ATTRIBUTE), 4) \
, 1, 0))
#define BOOST_FUSION_ADAPT_TPL_ADT(TEMPLATE_PARAMS_SEQ, NAME_SEQ , ATTRIBUTES) \ #define BOOST_FUSION_ADAPT_TPL_ADT(TEMPLATE_PARAMS_SEQ, NAME_SEQ , ATTRIBUTES) \
BOOST_FUSION_ADAPT_STRUCT_BASE( \ BOOST_FUSION_ADAPT_STRUCT_BASE( \

View File

@ -2,6 +2,7 @@
Copyright (c) 2001-2009 Joel de Guzman Copyright (c) 2001-2009 Joel de Guzman
Copyright (c) 2007 Dan Marsden Copyright (c) 2007 Dan Marsden
Copyright (c) 2010-2011 Christopher Schmidt Copyright (c) 2010-2011 Christopher Schmidt
Copyright (c) 2013-2014 Damien Buhl
Distributed under the Boost Software License, Version 1.0. (See accompanying 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) file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -22,6 +23,7 @@
#include <boost/fusion/adapted/struct/detail/adapt_base.hpp> #include <boost/fusion/adapted/struct/detail/adapt_base.hpp>
#include <boost/fusion/adapted/struct/detail/at_impl.hpp> #include <boost/fusion/adapted/struct/detail/at_impl.hpp>
#include <boost/fusion/adapted/struct/detail/is_view_impl.hpp> #include <boost/fusion/adapted/struct/detail/is_view_impl.hpp>
#include <boost/fusion/adapted/struct/detail/proxy_type.hpp>
#include <boost/fusion/adapted/struct/detail/is_sequence_impl.hpp> #include <boost/fusion/adapted/struct/detail/is_sequence_impl.hpp>
#include <boost/fusion/adapted/struct/detail/value_at_impl.hpp> #include <boost/fusion/adapted/struct/detail/value_at_impl.hpp>
#include <boost/fusion/adapted/struct/detail/category_of_impl.hpp> #include <boost/fusion/adapted/struct/detail/category_of_impl.hpp>
@ -35,25 +37,29 @@
#include <boost/fusion/adapted/struct/detail/value_of_data_impl.hpp> #include <boost/fusion/adapted/struct/detail/value_of_data_impl.hpp>
#include <boost/fusion/adapted/adt/detail/extension.hpp> #include <boost/fusion/adapted/adt/detail/extension.hpp>
#include <boost/fusion/adapted/adt/detail/adapt_base.hpp> #include <boost/fusion/adapted/adt/detail/adapt_base.hpp>
#include <boost/fusion/adapted/adt/detail/adapt_base_assoc_attr_filler.hpp>
#define BOOST_FUSION_ADAPT_ASSOC_ADT_FILLER_0(A, B, C, D, E)\
((A, B, C, D, E)) BOOST_FUSION_ADAPT_ASSOC_ADT_FILLER_1
#define BOOST_FUSION_ADAPT_ASSOC_ADT_FILLER_1(A, B, C, D, E)\
((A, B, C, D, E)) BOOST_FUSION_ADAPT_ASSOC_ADT_FILLER_0
#define BOOST_FUSION_ADAPT_ASSOC_ADT_FILLER_0_END
#define BOOST_FUSION_ADAPT_ASSOC_ADT_FILLER_1_END
#define BOOST_FUSION_ADAPT_ASSOC_ADT_C( \ #define BOOST_FUSION_ADAPT_ASSOC_ADT_C( \
TEMPLATE_PARAMS_SEQ, NAME_SEQ, I, ATTRIBUTE) \ TEMPLATE_PARAMS_SEQ, NAME_SEQ, IS_VIEW, I, ATTRIBUTE) \
\ \
BOOST_FUSION_ADAPT_ADT_C_BASE(TEMPLATE_PARAMS_SEQ,NAME_SEQ,I,ATTRIBUTE,5) \ BOOST_FUSION_ADAPT_ADT_C_BASE( \
TEMPLATE_PARAMS_SEQ, \
NAME_SEQ, \
I, \
BOOST_PP_IF(IS_VIEW, BOOST_FUSION_PROXY_PREFIX, BOOST_PP_EMPTY), \
BOOST_FUSION_ADAPT_ADT_WRAPPEDATTR(ATTRIBUTE), \
BOOST_FUSION_ADAPT_ADT_WRAPPEDATTR_SIZE(ATTRIBUTE), \
BOOST_PP_IF( \
BOOST_PP_LESS( \
BOOST_FUSION_ADAPT_ADT_WRAPPEDATTR_SIZE(ATTRIBUTE), 5) \
, 1, 0)) \
\ \
template< \ template< \
BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS(TEMPLATE_PARAMS_SEQ) \ BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS(TEMPLATE_PARAMS_SEQ) \
> \ > \
struct struct_assoc_key<BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ), I> \ struct struct_assoc_key<BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ), I> \
{ \ { \
typedef BOOST_PP_TUPLE_ELEM(5, 4, ATTRIBUTE) type; \ typedef BOOST_FUSION_ADAPT_ASSOC_ADT_WRAPPEDATTR_GET_KEY(ATTRIBUTE) type;\
}; };
#define BOOST_FUSION_ADAPT_ASSOC_TPL_ADT( \ #define BOOST_FUSION_ADAPT_ASSOC_TPL_ADT( \

View File

@ -11,11 +11,18 @@
#define BOOST_FUSION_ADAPTED_ADT_DETAIL_ADAPT_BASE_HPP #define BOOST_FUSION_ADAPTED_ADT_DETAIL_ADAPT_BASE_HPP
#include <boost/fusion/support/config.hpp> #include <boost/fusion/support/config.hpp>
#include <boost/fusion/adapted/struct/detail/adapt_auto.hpp>
#include <boost/fusion/adapted/struct/detail/adapt_is_tpl.hpp>
#include <boost/preprocessor/control/if.hpp> #include <boost/preprocessor/control/if.hpp>
#include <boost/preprocessor/seq/seq.hpp> #include <boost/preprocessor/seq/seq.hpp>
#include <boost/preprocessor/seq/elem.hpp> #include <boost/preprocessor/seq/elem.hpp>
#include <boost/mpl/if.hpp> #include <boost/mpl/if.hpp>
#include <boost/type_traits/is_const.hpp> #include <boost/type_traits/is_const.hpp>
#include <boost/type_traits/add_const.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/typeof/typeof.hpp>
#define BOOST_FUSION_ADAPT_ADT_GET_IDENTITY_TEMPLATE_IMPL(TEMPLATE_PARAMS_SEQ) \ #define BOOST_FUSION_ADAPT_ADT_GET_IDENTITY_TEMPLATE_IMPL(TEMPLATE_PARAMS_SEQ) \
typename detail::get_identity< \ typename detail::get_identity< \
@ -28,8 +35,72 @@
\ \
boost::remove_const<boost::remove_reference<lvalue>::type>::type boost::remove_const<boost::remove_reference<lvalue>::type>::type
#define BOOST_FUSION_ADAPT_ADT_ATTRIBUTE_GETEXPR(ATTRIBUTE, \
ATTRIBUTE_TUPEL_SIZE, DEDUCE_TYPE) \
BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPEL_SIZE, \
BOOST_PP_IF(DEDUCE_TYPE, 0, 2), ATTRIBUTE)
#define BOOST_FUSION_ADAPT_ADT_ATTRIBUTE_SETEXPR(ATTRIBUTE, \
ATTRIBUTE_TUPEL_SIZE, DEDUCE_TYPE) \
BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPEL_SIZE, \
BOOST_PP_IF(DEDUCE_TYPE, 1, 3), ATTRIBUTE)
#ifdef BOOST_MSVC
# define BOOST_FUSION_DEDUCED_ATTR_TYPE(NAME_SEQ, ATTRIBUTE, \
ATTRIBUTE_TUPEL_SIZE, PREFIX, TEMPLATE_PARAMS_SEQ) \
\
BOOST_FUSION_ADAPT_STRUCT_MSVC_REDEFINE_TEMPLATE_PARAMS( \
TEMPLATE_PARAMS_SEQ) \
\
struct deduced_attr_type { \
static const BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ)& obj; \
typedef \
BOOST_PP_IF(BOOST_FUSION_ADAPT_IS_TPL(TEMPLATE_PARAMS_SEQ),typename,) \
BOOST_TYPEOF( PREFIX() BOOST_FUSION_ADAPT_ADT_ATTRIBUTE_GETEXPR( \
ATTRIBUTE, ATTRIBUTE_TUPEL_SIZE, 1)) type; \
};
#else
# define BOOST_FUSION_DEDUCED_ATTR_TYPE(NAME_SEQ, ATTRIBUTE, \
ATTRIBUTE_TUPEL_SIZE, PREFIX, TEMPLATE_PARAMS_SEQ) \
struct deduced_attr_type { \
static const BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ)& obj; \
typedef BOOST_TYPEOF( PREFIX() BOOST_FUSION_ADAPT_ADT_ATTRIBUTE_GETEXPR( \
ATTRIBUTE, ATTRIBUTE_TUPEL_SIZE, 1)) type; \
};
#endif
#define BOOST_FUSION_ADT_ATTRIBUTE_TYPEOF( \
NAME_SEQ, ATTRIBUTE, ATTRIBUTE_TUPEL_SIZE, PREFIX, TEMPLATE_PARAMS_SEQ) \
\
BOOST_FUSION_DEDUCED_ATTR_TYPE( \
NAME_SEQ, ATTRIBUTE, ATTRIBUTE_TUPEL_SIZE, PREFIX, TEMPLATE_PARAMS_SEQ) \
\
typedef \
BOOST_PP_IF(BOOST_FUSION_ADAPT_IS_TPL(TEMPLATE_PARAMS_SEQ),typename,) \
boost::remove_const< \
BOOST_PP_IF(BOOST_FUSION_ADAPT_IS_TPL(TEMPLATE_PARAMS_SEQ),typename,) \
deduced_attr_type::type \
>::type type; \
\
typedef \
BOOST_PP_IF(BOOST_FUSION_ADAPT_IS_TPL(TEMPLATE_PARAMS_SEQ),typename,) \
boost::add_const< \
BOOST_PP_IF(BOOST_FUSION_ADAPT_IS_TPL(TEMPLATE_PARAMS_SEQ),typename,) \
deduced_attr_type::type \
>::type const_type;
#define BOOST_FUSION_ADT_ATTRIBUTE_GIVENTYPE( \
NAME_SEQ, ATTRIBUTE, ATTRIBUTE_TUPEL_SIZE, PREFIX, TEMPLATE_PARAMS_SEQ) \
\
typedef BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPEL_SIZE, 0, ATTRIBUTE) type; \
typedef BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPEL_SIZE, 1, ATTRIBUTE) const_type;
#define BOOST_FUSION_ADAPT_ADT_C_BASE( \ #define BOOST_FUSION_ADAPT_ADT_C_BASE( \
TEMPLATE_PARAMS_SEQ,NAME_SEQ,I,ATTRIBUTE,ATTRIBUTE_TUPEL_SIZE) \ TEMPLATE_PARAMS_SEQ,NAME_SEQ,I,PREFIX, \
ATTRIBUTE,ATTRIBUTE_TUPEL_SIZE, DEDUCE_TYPE) \
\ \
template< \ template< \
BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS(TEMPLATE_PARAMS_SEQ) \ BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS(TEMPLATE_PARAMS_SEQ) \
@ -39,6 +110,16 @@
, I \ , I \
> \ > \
{ \ { \
\
BOOST_PP_IF(DEDUCE_TYPE, \
BOOST_FUSION_ADT_ATTRIBUTE_TYPEOF, \
BOOST_FUSION_ADT_ATTRIBUTE_GIVENTYPE)( \
NAME_SEQ, \
ATTRIBUTE, \
ATTRIBUTE_TUPEL_SIZE, \
PREFIX, \
TEMPLATE_PARAMS_SEQ) \
\
template<class Val> \ template<class Val> \
BOOST_FUSION_GPU_ENABLED \ BOOST_FUSION_GPU_ENABLED \
static void \ static void \
@ -46,23 +127,26 @@
BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ)& obj, \ BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ)& obj, \
Val const& val) \ Val const& val) \
{ \ { \
BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPEL_SIZE, 3, ATTRIBUTE); \ PREFIX() BOOST_FUSION_ADAPT_ADT_ATTRIBUTE_SETEXPR(ATTRIBUTE, \
ATTRIBUTE_TUPEL_SIZE, DEDUCE_TYPE); \
} \ } \
\ \
BOOST_FUSION_GPU_ENABLED \ BOOST_FUSION_GPU_ENABLED \
static BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPEL_SIZE, 0, ATTRIBUTE) \ static type \
boost_fusion_adapt_adt_impl_get( \ boost_fusion_adapt_adt_impl_get( \
BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ)& obj) \ BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ)& obj) \
{ \ { \
return BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPEL_SIZE, 2, ATTRIBUTE); \ return PREFIX() BOOST_FUSION_ADAPT_ADT_ATTRIBUTE_GETEXPR(ATTRIBUTE, \
ATTRIBUTE_TUPEL_SIZE, DEDUCE_TYPE); \
} \ } \
\ \
BOOST_FUSION_GPU_ENABLED \ BOOST_FUSION_GPU_ENABLED \
static BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPEL_SIZE, 1, ATTRIBUTE) \ static const_type \
boost_fusion_adapt_adt_impl_get( \ boost_fusion_adapt_adt_impl_get( \
BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) const& obj) \ BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) const& obj) \
{ \ { \
return BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPEL_SIZE, 2, ATTRIBUTE); \ return PREFIX() BOOST_FUSION_ADAPT_ADT_ATTRIBUTE_GETEXPR(ATTRIBUTE, \
ATTRIBUTE_TUPEL_SIZE, DEDUCE_TYPE); \
} \ } \
}; \ }; \
\ \
@ -75,7 +159,12 @@
, true \ , true \
> \ > \
{ \ { \
typedef BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPEL_SIZE, 1, ATTRIBUTE) type; \ typedef \
BOOST_PP_IF(BOOST_PP_SEQ_HEAD(TEMPLATE_PARAMS_SEQ), typename, ) \
access::adt_attribute_access< \
BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) \
, I \
>::const_type type; \
\ \
BOOST_FUSION_GPU_ENABLED \ BOOST_FUSION_GPU_ENABLED \
explicit \ explicit \
@ -111,7 +200,12 @@
, false \ , false \
> \ > \
{ \ { \
typedef BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPEL_SIZE, 0, ATTRIBUTE) type; \ typedef \
BOOST_PP_IF(BOOST_PP_SEQ_HEAD(TEMPLATE_PARAMS_SEQ), typename, ) \
access::adt_attribute_access< \
BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) \
, I \
>::type type; \
\ \
BOOST_FUSION_GPU_ENABLED \ BOOST_FUSION_GPU_ENABLED \
explicit \ explicit \
@ -158,7 +252,13 @@
, I \ , I \
> \ > \
{ \ { \
typedef BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPEL_SIZE, 0, ATTRIBUTE) lvalue; \ typedef BOOST_PP_IF(BOOST_PP_SEQ_HEAD(TEMPLATE_PARAMS_SEQ), typename, ) \
adt_attribute_proxy< \
BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ) \
, I \
, false \
>::type lvalue; \
\
BOOST_FUSION_ADAPT_STRUCT_MSVC_REDEFINE_TEMPLATE_PARAMS( \ BOOST_FUSION_ADAPT_STRUCT_MSVC_REDEFINE_TEMPLATE_PARAMS( \
TEMPLATE_PARAMS_SEQ) \ TEMPLATE_PARAMS_SEQ) \
\ \

View File

@ -0,0 +1,61 @@
/*=============================================================================
Copyright (c) 2013-2014 Damien Buhl
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_ADAPTER_ADT_DETAIL_ADAPT_BASE_ASSOC_ATTR_FILLER_HPP
#define BOOST_FUSION_ADAPTER_ADT_DETAIL_ADAPT_BASE_ASSOC_ATTR_FILLER_HPP
#include <boost/config.hpp>
#include <boost/fusion/adapted/adt/detail/adapt_base_attr_filler.hpp>
#include <boost/preprocessor/control/if.hpp>
#include <boost/preprocessor/variadic/size.hpp>
#include <boost/preprocessor/empty.hpp>
#include <boost/preprocessor/facilities/is_empty.hpp>
#if BOOST_PP_VARIADICS
#define BOOST_FUSION_ADAPT_ASSOC_ADT_FILLER_0(...) \
BOOST_FUSION_ADAPT_ASSOC_ADT_WRAP_ATTR(__VA_ARGS__) \
BOOST_FUSION_ADAPT_ASSOC_ADT_FILLER_1
#define BOOST_FUSION_ADAPT_ASSOC_ADT_FILLER_1(...) \
BOOST_FUSION_ADAPT_ASSOC_ADT_WRAP_ATTR(__VA_ARGS__) \
BOOST_FUSION_ADAPT_ASSOC_ADT_FILLER_0
#define BOOST_FUSION_ADAPT_ASSOC_ADT_WRAP_ATTR(...) \
((BOOST_PP_VARIADIC_SIZE(__VA_ARGS__), (__VA_ARGS__)))
#else // BOOST_PP_VARIADICS
#define BOOST_FUSION_ADAPT_ASSOC_ADT_FILLER_0(A, B, C, D, E) \
BOOST_FUSION_ADAPT_ASSOC_ADT_WRAP_ATTR(A, B, C, D, E) \
BOOST_FUSION_ADAPT_ASSOC_ADT_FILLER_1
#define BOOST_FUSION_ADAPT_ASSOC_ADT_FILLER_1(A, B, C, D, E) \
BOOST_FUSION_ADAPT_ASSOC_ADT_WRAP_ATTR(A, B, C, D, E) \
BOOST_FUSION_ADAPT_ASSOC_ADT_FILLER_0
#define BOOST_FUSION_ADAPT_ASSOC_ADT_WRAP_ATTR(A, B, C, D, E) \
BOOST_PP_IF(BOOST_PP_IS_EMPTY(A), \
((3, (C,D,E))), \
((5, (A,B,C,D,E))) \
)
#endif // BOOST_PP_VARIADICS
#define BOOST_FUSION_ADAPT_ASSOC_ADT_FILLER_0_END
#define BOOST_FUSION_ADAPT_ASSOC_ADT_FILLER_1_END
#define BOOST_FUSION_ADAPT_ASSOC_ADT_WRAPPEDATTR_GET_KEY(ATTRIBUTE) \
BOOST_PP_TUPLE_ELEM( \
BOOST_FUSION_ADAPT_ADT_WRAPPEDATTR_SIZE(ATTRIBUTE), \
BOOST_PP_SUB(BOOST_FUSION_ADAPT_ADT_WRAPPEDATTR_SIZE(ATTRIBUTE), 1), \
BOOST_FUSION_ADAPT_ADT_WRAPPEDATTR(ATTRIBUTE))
#endif

View File

@ -0,0 +1,90 @@
/*=============================================================================
Copyright (c) 2013-2014 Damien Buhl
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_ADT_DETAIL_ADAPT_BASE_ATTR_FILLER_HPP
#define BOOST_FUSION_ADAPTED_ADT_DETAIL_ADAPT_BASE_ATTR_FILLER_HPP
#include <boost/config.hpp>
#include <boost/fusion/adapted/struct/detail/preprocessor/is_seq.hpp>
#include <boost/preprocessor/arithmetic/sub.hpp>
#include <boost/preprocessor/control/if.hpp>
#include <boost/preprocessor/logical/or.hpp>
#include <boost/preprocessor/empty.hpp>
#include <boost/preprocessor/tuple/size.hpp>
#include <boost/preprocessor/tuple/elem.hpp>
#include <boost/preprocessor/facilities/is_empty.hpp>
#include <boost/preprocessor/variadic/to_seq.hpp>
#include <boost/preprocessor/variadic/to_tuple.hpp>
#include <boost/preprocessor/variadic/elem.hpp>
#include <boost/preprocessor/seq/for_each.hpp>
#include <boost/preprocessor/seq/push_front.hpp>
#include <boost/preprocessor/seq/rest_n.hpp>
#include <boost/preprocessor/tuple/reverse.hpp>
#define BOOST_FUSION_ADAPT_ADT_WRAPPEDATTR_SIZE(ATTRIBUTE) \
BOOST_PP_TUPLE_ELEM(2, 0, ATTRIBUTE)
#define BOOST_FUSION_ADAPT_ADT_WRAPPEDATTR(ATTRIBUTE) \
BOOST_PP_TUPLE_ELEM(2, 1, ATTRIBUTE)
#if BOOST_PP_VARIADICS
# define BOOST_FUSION_ADAPT_ADT_FILLER_0(...) \
BOOST_FUSION_ADAPT_ADT_FILLER(__VA_ARGS__) \
BOOST_FUSION_ADAPT_ADT_FILLER_1
# define BOOST_FUSION_ADAPT_ADT_FILLER_1(...) \
BOOST_FUSION_ADAPT_ADT_FILLER(__VA_ARGS__) \
BOOST_FUSION_ADAPT_ADT_FILLER_0
# define BOOST_FUSION_ADAPT_ADT_FILLER_0_END
# define BOOST_FUSION_ADAPT_ADT_FILLER_1_END
# define BOOST_FUSION_ADAPT_ADT_FILLER(...) \
BOOST_PP_IF( \
BOOST_PP_OR( \
BOOST_PP_IS_EMPTY(BOOST_PP_VARIADIC_ELEM(0, __VA_ARGS__)), \
BOOST_PP_IS_EMPTY(BOOST_PP_VARIADIC_ELEM(1, __VA_ARGS__))), \
BOOST_FUSION_ADAPT_ADT_WRAP_ATTR( \
BOOST_PP_VARIADIC_ELEM(2, __VA_ARGS__), \
BOOST_FUSION_WORKAROUND_VARIADIC_EMPTINESS_LAST_ELEM(__VA_ARGS__) \
), \
BOOST_FUSION_ADAPT_ADT_WRAP_ATTR(__VA_ARGS__))
# define BOOST_FUSION_ADAPT_ADT_WRAP_ATTR(...) \
((BOOST_PP_VARIADIC_SIZE(__VA_ARGS__), (__VA_ARGS__)))
# define BOOST_FUSION_WORKAROUND_VARIADIC_EMPTINESS_LAST_ELEM(...) \
BOOST_PP_SEQ_HEAD(BOOST_PP_SEQ_REST_N( \
BOOST_PP_SUB(BOOST_PP_VARIADIC_SIZE(__VA_ARGS__), 1), \
BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__)))
#else // BOOST_PP_VARIADICS
# define BOOST_FUSION_ADAPT_ADT_FILLER_0(A, B, C, D) \
BOOST_FUSION_ADAPT_ADT_WRAP_ATTR(A,B,C,D) \
BOOST_FUSION_ADAPT_ADT_FILLER_1
# define BOOST_FUSION_ADAPT_ADT_FILLER_1(A, B, C, D) \
BOOST_FUSION_ADAPT_ADT_WRAP_ATTR(A,B,C,D) \
BOOST_FUSION_ADAPT_ADT_FILLER_0
# define BOOST_FUSION_ADAPT_ADT_FILLER_0_END
# define BOOST_FUSION_ADAPT_ADT_FILLER_1_END
# define BOOST_FUSION_ADAPT_ADT_WRAP_ATTR(A, B, C, D) \
BOOST_PP_IF(BOOST_PP_IS_EMPTY(A), \
((2, (C,D))), \
((4, (A,B,C,D))) \
)
#endif // BOOST_PP_VARIADICS
#endif

View File

@ -21,6 +21,7 @@
#include <boost/fusion/adapted/struct/detail/extension.hpp> #include <boost/fusion/adapted/struct/detail/extension.hpp>
#include <boost/fusion/adapted/struct/detail/adapt_base.hpp> #include <boost/fusion/adapted/struct/detail/adapt_base.hpp>
#include <boost/fusion/adapted/struct/detail/adapt_base_assoc_attr_filler.hpp>
#include <boost/fusion/adapted/struct/detail/at_impl.hpp> #include <boost/fusion/adapted/struct/detail/at_impl.hpp>
#include <boost/fusion/adapted/struct/detail/is_view_impl.hpp> #include <boost/fusion/adapted/struct/detail/is_view_impl.hpp>
#include <boost/fusion/adapted/struct/detail/is_sequence_impl.hpp> #include <boost/fusion/adapted/struct/detail/is_sequence_impl.hpp>
@ -35,32 +36,35 @@
#include <boost/fusion/adapted/struct/detail/key_of_impl.hpp> #include <boost/fusion/adapted/struct/detail/key_of_impl.hpp>
#include <boost/fusion/adapted/struct/detail/value_of_data_impl.hpp> #include <boost/fusion/adapted/struct/detail/value_of_data_impl.hpp>
#define BOOST_FUSION_ADAPT_ASSOC_STRUCT_FILLER_0(X, Y, Z) \
((X, Y, Z)) BOOST_FUSION_ADAPT_ASSOC_STRUCT_FILLER_1
#define BOOST_FUSION_ADAPT_ASSOC_STRUCT_FILLER_1(X, Y, Z) \
((X, Y, Z)) BOOST_FUSION_ADAPT_ASSOC_STRUCT_FILLER_0
#define BOOST_FUSION_ADAPT_ASSOC_STRUCT_FILLER_0_END
#define BOOST_FUSION_ADAPT_ASSOC_STRUCT_FILLER_1_END
#define BOOST_FUSION_ADAPT_ASSOC_STRUCT_C_BASE( \ #define BOOST_FUSION_ADAPT_ASSOC_STRUCT_C_BASE( \
TEMPLATE_PARAMS_SEQ,NAME_SEQ,I,PREFIX,ATTRIBUTE) \ TEMPLATE_PARAMS_SEQ,NAME_SEQ,IS_VIEW,I,PREFIX,ATTRIBUTE) \
\ \
BOOST_FUSION_ADAPT_STRUCT_C_BASE( \ BOOST_FUSION_ADAPT_STRUCT_C_BASE( \
TEMPLATE_PARAMS_SEQ, NAME_SEQ, I, PREFIX, ATTRIBUTE, 3) \ TEMPLATE_PARAMS_SEQ, \
NAME_SEQ, \
IS_VIEW, \
I, \
PREFIX, \
BOOST_FUSION_ADAPT_STRUCT_WRAPPEDATTR(ATTRIBUTE), \
BOOST_FUSION_ADAPT_STRUCT_WRAPPEDATTR_SIZE(ATTRIBUTE), \
BOOST_PP_IF(BOOST_PP_LESS( \
BOOST_FUSION_ADAPT_STRUCT_WRAPPEDATTR_SIZE(ATTRIBUTE),3), 1, 0)) \
\ \
template< \ template< \
BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS(TEMPLATE_PARAMS_SEQ) \ BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS(TEMPLATE_PARAMS_SEQ) \
> \ > \
struct struct_assoc_key<BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ), I> \ struct struct_assoc_key<BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ), I> \
{ \ { \
typedef BOOST_PP_TUPLE_ELEM(3, 2, ATTRIBUTE) type; \ typedef \
BOOST_FUSION_ADAPT_ASSOC_STRUCT_WRAPPEDATTR_GET_KEY(ATTRIBUTE) type; \
}; };
#define BOOST_FUSION_ADAPT_ASSOC_STRUCT_C( \ #define BOOST_FUSION_ADAPT_ASSOC_STRUCT_C( \
TEMPLATE_PARAMS_SEQ,NAME_SEQ, I, ATTRIBUTE) \ TEMPLATE_PARAMS_SEQ,NAME_SEQ,IS_VIEW, I, ATTRIBUTE) \
\ \
BOOST_FUSION_ADAPT_ASSOC_STRUCT_C_BASE( \ BOOST_FUSION_ADAPT_ASSOC_STRUCT_C_BASE( \
TEMPLATE_PARAMS_SEQ,NAME_SEQ,I,BOOST_PP_EMPTY,ATTRIBUTE) TEMPLATE_PARAMS_SEQ,NAME_SEQ,IS_VIEW,I,BOOST_PP_EMPTY,ATTRIBUTE)
#define BOOST_FUSION_ADAPT_ASSOC_TPL_STRUCT( \ #define BOOST_FUSION_ADAPT_ASSOC_TPL_STRUCT( \
TEMPLATE_PARAMS_SEQ, NAME_SEQ, ATTRIBUTES) \ TEMPLATE_PARAMS_SEQ, NAME_SEQ, ATTRIBUTES) \

View File

@ -1,6 +1,7 @@
/*============================================================================= /*=============================================================================
Copyright (c) 2001-2007 Joel de Guzman Copyright (c) 2001-2007 Joel de Guzman
Copyright (c) 2009-2011 Christopher Schmidt Copyright (c) 2009-2011 Christopher Schmidt
Copyright (c) 2013-2014 Damien Buhl
Distributed under the Boost Software License, Version 1.0. (See accompanying 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) file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -10,8 +11,12 @@
#define BOOST_FUSION_ADAPTED_STRUCT_ADAPT_STRUCT_HPP #define BOOST_FUSION_ADAPTED_STRUCT_ADAPT_STRUCT_HPP
#include <boost/fusion/support/config.hpp> #include <boost/fusion/support/config.hpp>
#include <boost/preprocessor/config/config.hpp>
#include <boost/preprocessor/cat.hpp> #include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/empty.hpp> #include <boost/preprocessor/empty.hpp>
#include <boost/preprocessor/control/if.hpp>
#include <boost/preprocessor/comparison/less.hpp>
#include <boost/preprocessor/comparison/equal.hpp>
#include <boost/type_traits/add_reference.hpp> #include <boost/type_traits/add_reference.hpp>
#include <boost/type_traits/is_const.hpp> #include <boost/type_traits/is_const.hpp>
#include <boost/type_traits/add_const.hpp> #include <boost/type_traits/add_const.hpp>
@ -19,6 +24,7 @@
#include <boost/fusion/adapted/struct/detail/extension.hpp> #include <boost/fusion/adapted/struct/detail/extension.hpp>
#include <boost/fusion/adapted/struct/detail/adapt_base.hpp> #include <boost/fusion/adapted/struct/detail/adapt_base.hpp>
#include <boost/fusion/adapted/struct/detail/adapt_base_attr_filler.hpp>
#include <boost/fusion/adapted/struct/detail/at_impl.hpp> #include <boost/fusion/adapted/struct/detail/at_impl.hpp>
#include <boost/fusion/adapted/struct/detail/is_view_impl.hpp> #include <boost/fusion/adapted/struct/detail/is_view_impl.hpp>
#include <boost/fusion/adapted/struct/detail/is_sequence_impl.hpp> #include <boost/fusion/adapted/struct/detail/is_sequence_impl.hpp>
@ -30,43 +36,88 @@
#include <boost/fusion/adapted/struct/detail/value_of_impl.hpp> #include <boost/fusion/adapted/struct/detail/value_of_impl.hpp>
#include <boost/fusion/adapted/struct/detail/deref_impl.hpp> #include <boost/fusion/adapted/struct/detail/deref_impl.hpp>
#define BOOST_FUSION_ADAPT_STRUCT_FILLER_0(X, Y) \ #define BOOST_FUSION_ADAPT_STRUCT_C( \
((X, Y)) BOOST_FUSION_ADAPT_STRUCT_FILLER_1 TEMPLATE_PARAMS_SEQ, NAME_SEQ, IS_VIEW, I, ATTRIBUTE) \
#define BOOST_FUSION_ADAPT_STRUCT_FILLER_1(X, Y) \ BOOST_FUSION_ADAPT_STRUCT_C_BASE( \
((X, Y)) BOOST_FUSION_ADAPT_STRUCT_FILLER_0 TEMPLATE_PARAMS_SEQ, \
#define BOOST_FUSION_ADAPT_STRUCT_FILLER_0_END NAME_SEQ, \
#define BOOST_FUSION_ADAPT_STRUCT_FILLER_1_END IS_VIEW, \
I, \
BOOST_PP_IF(IS_VIEW, BOOST_FUSION_PROXY_PREFIX, BOOST_PP_EMPTY), \
BOOST_FUSION_ADAPT_STRUCT_WRAPPEDATTR(ATTRIBUTE), \
BOOST_FUSION_ADAPT_STRUCT_WRAPPEDATTR_SIZE(ATTRIBUTE), \
BOOST_PP_IF( \
BOOST_PP_LESS( \
BOOST_FUSION_ADAPT_STRUCT_WRAPPEDATTR_SIZE(ATTRIBUTE), 2) \
, 1, 0))
#define BOOST_FUSION_ADAPT_STRUCT_C(TEMPLATE_PARAMS_SEQ, NAME_SEQ, I, ATTRIBUTE)\
BOOST_FUSION_ADAPT_STRUCT_C_BASE( \
TEMPLATE_PARAMS_SEQ,NAME_SEQ,I,BOOST_PP_EMPTY,ATTRIBUTE,2)
#define BOOST_FUSION_ADAPT_TPL_STRUCT(TEMPLATE_PARAMS_SEQ,NAME_SEQ, ATTRIBUTES) \
BOOST_FUSION_ADAPT_STRUCT_BASE( \
(1)TEMPLATE_PARAMS_SEQ, \
(1)NAME_SEQ, \
struct_tag, \
0, \
((0,0)) BOOST_PP_CAT( \
BOOST_FUSION_ADAPT_STRUCT_FILLER_0 ATTRIBUTES,_END), \
BOOST_FUSION_ADAPT_STRUCT_C)
#define BOOST_FUSION_ADAPT_STRUCT(NAME, ATTRIBUTES) \ #if BOOST_PP_VARIADICS
BOOST_FUSION_ADAPT_STRUCT_BASE( \
(0), \
(0)(NAME), \
struct_tag, \
0, \
BOOST_PP_CAT(BOOST_FUSION_ADAPT_STRUCT_FILLER_0(0,0)ATTRIBUTES,_END), \
BOOST_FUSION_ADAPT_STRUCT_C)
#define BOOST_FUSION_ADAPT_STRUCT_AS_VIEW(NAME, ATTRIBUTES) \ # define BOOST_FUSION_ADAPT_TPL_STRUCT(TEMPLATE_PARAMS_SEQ,NAME_SEQ, ...) \
BOOST_FUSION_ADAPT_STRUCT_BASE( \ BOOST_FUSION_ADAPT_STRUCT_BASE( \
(0), \ (1)TEMPLATE_PARAMS_SEQ, \
(0)(NAME), \ (1)NAME_SEQ, \
struct_tag, \ struct_tag, \
1, \ 0, \
BOOST_PP_CAT(BOOST_FUSION_ADAPT_STRUCT_FILLER_0(0,0)ATTRIBUTES,_END), \ BOOST_FUSION_ADAPT_STRUCT_ATTRIBUTES_FILLER(__VA_ARGS__), \
BOOST_FUSION_ADAPT_STRUCT_C) BOOST_FUSION_ADAPT_STRUCT_C)
# define BOOST_FUSION_ADAPT_STRUCT(NAME, ...) \
BOOST_FUSION_ADAPT_STRUCT_BASE( \
(0), \
(0)(NAME), \
struct_tag, \
0, \
BOOST_FUSION_ADAPT_STRUCT_ATTRIBUTES_FILLER(__VA_ARGS__), \
BOOST_FUSION_ADAPT_STRUCT_C)
# define BOOST_FUSION_ADAPT_STRUCT_AS_VIEW(NAME, ...) \
BOOST_FUSION_ADAPT_STRUCT_BASE( \
(0), \
(0)(NAME), \
struct_tag, \
1, \
BOOST_FUSION_ADAPT_STRUCT_ATTRIBUTES_FILLER(__VA_ARGS__), \
BOOST_FUSION_ADAPT_STRUCT_C)
#else // BOOST_PP_VARIADICS
# define BOOST_FUSION_ADAPT_TPL_STRUCT( \
TEMPLATE_PARAMS_SEQ,NAME_SEQ, ATTRIBUTES) \
BOOST_FUSION_ADAPT_STRUCT_BASE( \
(1)TEMPLATE_PARAMS_SEQ, \
(1)NAME_SEQ, \
struct_tag, \
0, \
BOOST_PP_CAT( \
BOOST_FUSION_ADAPT_STRUCT_FILLER_0(0,0)ATTRIBUTES,_END), \
BOOST_FUSION_ADAPT_STRUCT_C)
# define BOOST_FUSION_ADAPT_STRUCT(NAME, ATTRIBUTES) \
BOOST_FUSION_ADAPT_STRUCT_BASE( \
(0), \
(0)(NAME), \
struct_tag, \
0, \
BOOST_PP_CAT( \
BOOST_FUSION_ADAPT_STRUCT_FILLER_0(0,0)ATTRIBUTES, \
_END), \
BOOST_FUSION_ADAPT_STRUCT_C)
# define BOOST_FUSION_ADAPT_STRUCT_AS_VIEW(NAME, ATTRIBUTES) \
BOOST_FUSION_ADAPT_STRUCT_BASE( \
(0), \
(0)(NAME), \
struct_tag, \
1, \
BOOST_PP_CAT( \
BOOST_FUSION_ADAPT_STRUCT_FILLER_0(0,0)ATTRIBUTES, \
_END), \
BOOST_FUSION_ADAPT_STRUCT_C)
#endif // BOOST_PP_VARIADICS
#endif #endif

View File

@ -15,26 +15,41 @@
#include <boost/fusion/adapted/struct/detail/proxy_type.hpp> #include <boost/fusion/adapted/struct/detail/proxy_type.hpp>
#include <boost/preprocessor/empty.hpp> #include <boost/preprocessor/empty.hpp>
#define BOOST_FUSION_ADAPT_STRUCT_NAMED_FILLER_0(X, Y) \ #ifdef BOOST_PP_VARIADICS
(X, obj.Y) BOOST_FUSION_ADAPT_STRUCT_NAMED_FILLER_1
#define BOOST_FUSION_ADAPT_STRUCT_NAMED_FILLER_1(X, Y) \
(X, obj.Y) BOOST_FUSION_ADAPT_STRUCT_NAMED_FILLER_0
#define BOOST_FUSION_ADAPT_STRUCT_NAMED_FILLER_0_END
#define BOOST_FUSION_ADAPT_STRUCT_NAMED_FILLER_1_END
#define BOOST_FUSION_ADAPT_STRUCT_NAMED_NS( \ # define BOOST_FUSION_ADAPT_STRUCT_NAMED_NS( \
WRAPPED_TYPE, NAMESPACE_SEQ, NAME, ATTRIBUTES) \ WRAPPED_TYPE, NAMESPACE_SEQ, NAME, ...) \
\ \
BOOST_FUSION_ADAPT_STRUCT_DEFINE_PROXY_TYPE_IMPL( \ BOOST_FUSION_ADAPT_STRUCT_DEFINE_PROXY_TYPE_IMPL( \
WRAPPED_TYPE,(0)NAMESPACE_SEQ,NAME) \ WRAPPED_TYPE,(0)NAMESPACE_SEQ,NAME) \
\ \
BOOST_FUSION_ADAPT_STRUCT_AS_VIEW( \ BOOST_FUSION_ADAPT_STRUCT_AS_VIEW( \
BOOST_FUSION_ADAPT_STRUCT_NAMESPACE_DECLARATION((0)NAMESPACE_SEQ)NAME, \ BOOST_FUSION_ADAPT_STRUCT_NAMESPACE_DECLARATION( \
BOOST_PP_CAT( \ (0)NAMESPACE_SEQ)NAME, \
BOOST_FUSION_ADAPT_STRUCT_NAMED_FILLER_0 ATTRIBUTES,_END)) __VA_ARGS__)
#define BOOST_FUSION_ADAPT_STRUCT_NAMED(WRAPPED_TYPE, NAME, ATTRIBUTES) \ # define BOOST_FUSION_ADAPT_STRUCT_NAMED(WRAPPED_TYPE, NAME, ...) \
BOOST_FUSION_ADAPT_STRUCT_NAMED_NS( \ BOOST_FUSION_ADAPT_STRUCT_NAMED_NS( \
WRAPPED_TYPE,(boost)(fusion)(adapted),NAME,ATTRIBUTES) WRAPPED_TYPE,(boost)(fusion)(adapted),NAME,__VA_ARGS__)
#else // BOOST_PP_VARIADICS
# define BOOST_FUSION_ADAPT_STRUCT_NAMED_NS( \
WRAPPED_TYPE, NAMESPACE_SEQ, NAME, ATTRIBUTES) \
\
BOOST_FUSION_ADAPT_STRUCT_DEFINE_PROXY_TYPE_IMPL( \
WRAPPED_TYPE,(0)NAMESPACE_SEQ,NAME) \
\
BOOST_FUSION_ADAPT_STRUCT_AS_VIEW( \
BOOST_FUSION_ADAPT_STRUCT_NAMESPACE_DECLARATION( \
(0)NAMESPACE_SEQ)NAME, \
ATTRIBUTES)
# define BOOST_FUSION_ADAPT_STRUCT_NAMED(WRAPPED_TYPE, NAME, ATTRIBUTES) \
BOOST_FUSION_ADAPT_STRUCT_NAMED_NS( \
WRAPPED_TYPE,(boost)(fusion)(adapted),NAME,ATTRIBUTES)
#endif
#endif #endif

View File

@ -12,6 +12,13 @@
#include <boost/fusion/adapted/struct/adapt_assoc_struct.hpp> #include <boost/fusion/adapted/struct/adapt_assoc_struct.hpp>
#include <boost/fusion/adapted/struct/detail/define_struct.hpp> #include <boost/fusion/adapted/struct/detail/define_struct.hpp>
#define BOOST_FUSION_DEFINE_ASSOC_STRUCT_FILLER_0(X, Y, Z) \
((X, Y, Z)) BOOST_FUSION_DEFINE_ASSOC_STRUCT_FILLER_1
#define BOOST_FUSION_DEFINE_ASSOC_STRUCT_FILLER_1(X, Y, Z) \
((X, Y, Z)) BOOST_FUSION_DEFINE_ASSOC_STRUCT_FILLER_0
#define BOOST_FUSION_DEFINE_ASSOC_STRUCT_FILLER_0_END
#define BOOST_FUSION_DEFINE_ASSOC_STRUCT_FILLER_1_END
#define BOOST_FUSION_DEFINE_ASSOC_TPL_STRUCT( \ #define BOOST_FUSION_DEFINE_ASSOC_TPL_STRUCT( \
TEMPLATE_PARAMS_SEQ, NAMESPACE_SEQ, NAME, ATTRIBUTES) \ TEMPLATE_PARAMS_SEQ, NAMESPACE_SEQ, NAME, ATTRIBUTES) \
\ \
@ -20,7 +27,7 @@
(0)NAMESPACE_SEQ, \ (0)NAMESPACE_SEQ, \
NAME, \ NAME, \
BOOST_PP_CAT( \ BOOST_PP_CAT( \
BOOST_FUSION_ADAPT_ASSOC_STRUCT_FILLER_0(0,0,0)ATTRIBUTES,_END), \ BOOST_FUSION_DEFINE_ASSOC_STRUCT_FILLER_0(0,0,0)ATTRIBUTES,_END), \
3) \ 3) \
\ \
BOOST_FUSION_ADAPT_ASSOC_TPL_STRUCT( \ BOOST_FUSION_ADAPT_ASSOC_TPL_STRUCT( \
@ -34,7 +41,7 @@
(0)NAMESPACE_SEQ, \ (0)NAMESPACE_SEQ, \
NAME, \ NAME, \
BOOST_PP_CAT( \ BOOST_PP_CAT( \
BOOST_FUSION_ADAPT_ASSOC_STRUCT_FILLER_0(0,0,0)ATTRIBUTES,_END), \ BOOST_FUSION_DEFINE_ASSOC_STRUCT_FILLER_0(0,0,0)ATTRIBUTES,_END), \
3) \ 3) \
\ \
BOOST_FUSION_ADAPT_ASSOC_STRUCT( \ BOOST_FUSION_ADAPT_ASSOC_STRUCT( \

View File

@ -19,7 +19,7 @@
TEMPLATE_PARAMS_SEQ, \ TEMPLATE_PARAMS_SEQ, \
(0)NAMESPACE_SEQ, \ (0)NAMESPACE_SEQ, \
NAME, \ NAME, \
BOOST_PP_CAT(BOOST_FUSION_ADAPT_STRUCT_FILLER_0(0,0)ATTRIBUTES,_END), \ BOOST_PP_CAT(BOOST_FUSION_DEFINE_STRUCT_FILLER_0(0,0)ATTRIBUTES,_END), \
2) \ 2) \
\ \
BOOST_FUSION_ADAPT_TPL_STRUCT( \ BOOST_FUSION_ADAPT_TPL_STRUCT( \
@ -32,7 +32,7 @@
BOOST_FUSION_DEFINE_STRUCT_IMPL( \ BOOST_FUSION_DEFINE_STRUCT_IMPL( \
(0)NAMESPACE_SEQ, \ (0)NAMESPACE_SEQ, \
NAME, \ NAME, \
BOOST_PP_CAT(BOOST_FUSION_ADAPT_STRUCT_FILLER_0(0,0)ATTRIBUTES,_END), \ BOOST_PP_CAT(BOOST_FUSION_DEFINE_STRUCT_FILLER_0(0,0)ATTRIBUTES,_END), \
2) \ 2) \
\ \
BOOST_FUSION_ADAPT_STRUCT( \ BOOST_FUSION_ADAPT_STRUCT( \

View File

@ -0,0 +1,15 @@
/*=============================================================================
Copyright (c) 2013-2014 Damien Buhl
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_STRUCT_DETAIL_ADAPT_AUTO_HPP
#define BOOST_FUSION_ADAPTED_STRUCT_DETAIL_ADAPT_AUTO_HPP
#include <boost/preprocessor/empty.hpp>
#define BOOST_FUSION_ADAPT_AUTO BOOST_PP_EMPTY()
#endif

View File

@ -2,6 +2,7 @@
Copyright (c) 2001-2009 Joel de Guzman Copyright (c) 2001-2009 Joel de Guzman
Copyright (c) 2005-2006 Dan Marsden Copyright (c) 2005-2006 Dan Marsden
Copyright (c) 2009-2011 Christopher Schmidt Copyright (c) 2009-2011 Christopher Schmidt
Copyright (c) 2013-2014 Damien Buhl
Distributed under the Boost Software License, Version 1.0. (See accompanying 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) file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -13,6 +14,8 @@
#include <boost/fusion/support/config.hpp> #include <boost/fusion/support/config.hpp>
#include <boost/config.hpp> #include <boost/config.hpp>
#include <boost/fusion/support/tag_of_fwd.hpp> #include <boost/fusion/support/tag_of_fwd.hpp>
#include <boost/fusion/adapted/struct/detail/adapt_auto.hpp>
#include <boost/fusion/adapted/struct/detail/adapt_is_tpl.hpp>
#include <boost/preprocessor/empty.hpp> #include <boost/preprocessor/empty.hpp>
#include <boost/preprocessor/stringize.hpp> #include <boost/preprocessor/stringize.hpp>
@ -25,12 +28,16 @@
#include <boost/preprocessor/tuple/eat.hpp> #include <boost/preprocessor/tuple/eat.hpp>
#include <boost/preprocessor/tuple/elem.hpp> #include <boost/preprocessor/tuple/elem.hpp>
#include <boost/preprocessor/arithmetic/dec.hpp> #include <boost/preprocessor/arithmetic/dec.hpp>
#include <boost/preprocessor/comparison/less.hpp>
#include <boost/mpl/bool.hpp> #include <boost/mpl/bool.hpp>
#include <boost/mpl/tag.hpp> #include <boost/mpl/tag.hpp>
#include <boost/mpl/eval_if.hpp> #include <boost/mpl/eval_if.hpp>
#include <boost/mpl/identity.hpp> #include <boost/mpl/identity.hpp>
#include <boost/type_traits/add_const.hpp> #include <boost/type_traits/add_const.hpp>
#include <boost/typeof/typeof.hpp>
#define BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME_TEMPLATE_PARAMS(SEQ) \ #define BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME_TEMPLATE_PARAMS(SEQ) \
BOOST_PP_SEQ_HEAD(SEQ)<BOOST_PP_SEQ_ENUM(BOOST_PP_SEQ_TAIL(SEQ))> \ BOOST_PP_SEQ_HEAD(SEQ)<BOOST_PP_SEQ_ENUM(BOOST_PP_SEQ_TAIL(SEQ))> \
BOOST_PP_EMPTY() BOOST_PP_EMPTY()
@ -55,6 +62,49 @@
BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS_IMPL, \ BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS_IMPL, \
BOOST_PP_TUPLE_EAT(1))(SEQ) BOOST_PP_TUPLE_EAT(1))(SEQ)
#ifdef BOOST_MSVC
# define BOOST_FUSION_ATTRIBUTE_TYPEOF( \
NAME_SEQ, ATTRIBUTE, ATTRIBUTE_TUPEL_SIZE, PREFIX, TEMPLATE_PARAMS_SEQ) \
\
BOOST_FUSION_ADAPT_STRUCT_MSVC_REDEFINE_TEMPLATE_PARAMS( \
TEMPLATE_PARAMS_SEQ) \
\
struct deduced_attr_type { \
static const BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ)& obj; \
typedef \
BOOST_PP_IF(BOOST_FUSION_ADAPT_IS_TPL(TEMPLATE_PARAMS_SEQ), typename, ) \
BOOST_TYPEOF( PREFIX() obj.BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPEL_SIZE, \
0, ATTRIBUTE)) \
type; \
}; \
\
typedef \
BOOST_PP_IF(BOOST_FUSION_ADAPT_IS_TPL(TEMPLATE_PARAMS_SEQ), typename, ) \
deduced_attr_type::type attribute_type;
#else
# define BOOST_FUSION_ATTRIBUTE_TYPEOF( \
NAME_SEQ, ATTRIBUTE, ATTRIBUTE_TUPEL_SIZE, PREFIX, TEMPLATE_PARAMS_SEQ) \
\
struct deduced_attr_type { \
static const BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ)& obj; \
typedef BOOST_TYPEOF( \
PREFIX() obj.BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPEL_SIZE, 0, ATTRIBUTE)) \
type; \
}; \
\
typedef \
BOOST_PP_IF(BOOST_FUSION_ADAPT_IS_TPL(TEMPLATE_PARAMS_SEQ), typename, ) \
deduced_attr_type::type attribute_type;
#endif
#define BOOST_FUSION_ATTRIBUTE_GIVENTYPE( \
NAME_SEQ, ATTRIBUTE, ATTRIBUTE_TUPEL_SIZE, PREFIX, TEMPLATE_PARAMS_SEQ) \
typedef \
BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPEL_SIZE, 0, ATTRIBUTE) attribute_type;
#ifdef BOOST_NO_PARTIAL_SPECIALIZATION_IMPLICIT_DEFAULT_ARGS #ifdef BOOST_NO_PARTIAL_SPECIALIZATION_IMPLICIT_DEFAULT_ARGS
# define BOOST_FUSION_ADAPT_STRUCT_TAG_OF_SPECIALIZATION( \ # define BOOST_FUSION_ADAPT_STRUCT_TAG_OF_SPECIALIZATION( \
MODIFIER, TEMPLATE_PARAMS_SEQ, NAME_SEQ, TAG) \ MODIFIER, TEMPLATE_PARAMS_SEQ, NAME_SEQ, TAG) \
@ -83,9 +133,10 @@
#endif #endif
#define BOOST_FUSION_ADAPT_STRUCT_BASE_UNPACK_AND_CALL(R,DATA,I,ATTRIBUTE) \ #define BOOST_FUSION_ADAPT_STRUCT_BASE_UNPACK_AND_CALL(R,DATA,I,ATTRIBUTE) \
BOOST_PP_TUPLE_ELEM(3,0,DATA)( \ BOOST_PP_TUPLE_ELEM(4,0,DATA)( \
BOOST_PP_TUPLE_ELEM(3,1,DATA), \ BOOST_PP_TUPLE_ELEM(4,1,DATA), \
BOOST_PP_TUPLE_ELEM(3,2,DATA), \ BOOST_PP_TUPLE_ELEM(4,2,DATA), \
BOOST_PP_TUPLE_ELEM(4,3,DATA), \
I, \ I, \
ATTRIBUTE) ATTRIBUTE)
@ -107,7 +158,9 @@
#endif #endif
#define BOOST_FUSION_ADAPT_STRUCT_C_BASE( \ #define BOOST_FUSION_ADAPT_STRUCT_C_BASE( \
TEMPLATE_PARAMS_SEQ,NAME_SEQ,I,PREFIX,ATTRIBUTE,ATTRIBUTE_TUPEL_SIZE) \ TEMPLATE_PARAMS_SEQ,NAME_SEQ,IS_VIEW, \
I,PREFIX,ATTRIBUTE,ATTRIBUTE_TUPEL_SIZE, \
DEDUCE_TYPE) \
\ \
template< \ template< \
BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS(TEMPLATE_PARAMS_SEQ) \ BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS(TEMPLATE_PARAMS_SEQ) \
@ -117,9 +170,14 @@
, I \ , I \
> \ > \
{ \ { \
typedef \ BOOST_PP_IF(DEDUCE_TYPE, \
BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPEL_SIZE, 0, ATTRIBUTE) \ BOOST_FUSION_ATTRIBUTE_TYPEOF, BOOST_FUSION_ATTRIBUTE_GIVENTYPE)( \
attribute_type; \ NAME_SEQ, \
ATTRIBUTE, \
ATTRIBUTE_TUPEL_SIZE, \
PREFIX, \
TEMPLATE_PARAMS_SEQ) \
\
BOOST_FUSION_ADAPT_STRUCT_MSVC_REDEFINE_TEMPLATE_PARAMS( \ BOOST_FUSION_ADAPT_STRUCT_MSVC_REDEFINE_TEMPLATE_PARAMS( \
TEMPLATE_PARAMS_SEQ) \ TEMPLATE_PARAMS_SEQ) \
\ \
@ -143,7 +201,8 @@
call(Seq& seq) \ call(Seq& seq) \
{ \ { \
return seq.PREFIX() \ return seq.PREFIX() \
BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPEL_SIZE, 1, ATTRIBUTE); \ BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPEL_SIZE, \
BOOST_PP_IF(DEDUCE_TYPE, 0, 1), ATTRIBUTE); \
} \ } \
}; \ }; \
}; \ }; \
@ -163,7 +222,9 @@
call() \ call() \
{ \ { \
return BOOST_PP_STRINGIZE( \ return BOOST_PP_STRINGIZE( \
BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPEL_SIZE,1,ATTRIBUTE)); \ BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPEL_SIZE, \
BOOST_PP_IF(DEDUCE_TYPE, 0, 1), \
ATTRIBUTE)); \
} \ } \
}; };
@ -195,7 +256,7 @@ namespace boost
BOOST_PP_TUPLE_EAT(4))( \ BOOST_PP_TUPLE_EAT(4))( \
1, \ 1, \
BOOST_FUSION_ADAPT_STRUCT_BASE_UNPACK_AND_CALL, \ BOOST_FUSION_ADAPT_STRUCT_BASE_UNPACK_AND_CALL, \
(ATTRIBUTES_CALLBACK,TEMPLATE_PARAMS_SEQ,NAME_SEQ), \ (ATTRIBUTES_CALLBACK,TEMPLATE_PARAMS_SEQ,NAME_SEQ, IS_VIEW),\
BOOST_PP_SEQ_TAIL(ATTRIBUTES_SEQ)) \ BOOST_PP_SEQ_TAIL(ATTRIBUTES_SEQ)) \
\ \
template< \ template< \

View File

@ -0,0 +1,63 @@
/*=============================================================================
Copyright (c) 2013-2014 Damien Buhl
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_STRUCT_DETAIL_ADAPT_BASE_ASSOC_ATTR_FILLER_HPP
#define BOOST_FUSION_ADAPTED_STRUCT_DETAIL_ADAPT_BASE_ASSOC_ATTR_FILLER_HPP
#include <boost/config.hpp>
#include <boost/fusion/adapted/struct/detail/adapt_base_attr_filler.hpp>
#include <boost/preprocessor/control/if.hpp>
#include <boost/preprocessor/arithmetic/sub.hpp>
#include <boost/preprocessor/variadic/size.hpp>
#include <boost/preprocessor/empty.hpp>
#include <boost/preprocessor/facilities/is_empty.hpp>
#if BOOST_PP_VARIADICS
#define BOOST_FUSION_ADAPT_ASSOC_STRUCT_FILLER_0(...) \
BOOST_FUSION_ADAPT_ASSOC_STRUCT_WRAP_ATTR(__VA_ARGS__) \
BOOST_FUSION_ADAPT_ASSOC_STRUCT_FILLER_1
#define BOOST_FUSION_ADAPT_ASSOC_STRUCT_FILLER_1(...) \
BOOST_FUSION_ADAPT_ASSOC_STRUCT_WRAP_ATTR(__VA_ARGS__) \
BOOST_FUSION_ADAPT_ASSOC_STRUCT_FILLER_0
#define BOOST_FUSION_ADAPT_ASSOC_STRUCT_WRAP_ATTR(...) \
((BOOST_PP_VARIADIC_SIZE(__VA_ARGS__), (__VA_ARGS__)))
#else // BOOST_PP_VARIADICS
#define BOOST_FUSION_ADAPT_ASSOC_STRUCT_FILLER_0(X, Y, Z) \
BOOST_FUSION_ADAPT_ASSOC_STRUCT_WRAP_ATTR(X, Y, Z) \
BOOST_FUSION_ADAPT_ASSOC_STRUCT_FILLER_1
#define BOOST_FUSION_ADAPT_ASSOC_STRUCT_FILLER_1(X, Y, Z) \
BOOST_FUSION_ADAPT_ASSOC_STRUCT_WRAP_ATTR(X, Y, Z) \
BOOST_FUSION_ADAPT_ASSOC_STRUCT_FILLER_0
#define BOOST_FUSION_ADAPT_ASSOC_STRUCT_WRAP_ATTR(X, Y, Z) \
BOOST_PP_IF(BOOST_PP_IS_EMPTY(X), \
((2, (Y,Z))), \
((3, (X,Y,Z))) \
)
#endif // BOOST_PP_VARIADICS
#define BOOST_FUSION_ADAPT_ASSOC_STRUCT_FILLER_0_END
#define BOOST_FUSION_ADAPT_ASSOC_STRUCT_FILLER_1_END
#define BOOST_FUSION_ADAPT_ASSOC_STRUCT_WRAPPEDATTR_GET_KEY(ATTRIBUTE) \
BOOST_PP_TUPLE_ELEM( \
BOOST_FUSION_ADAPT_STRUCT_WRAPPEDATTR_SIZE(ATTRIBUTE), \
BOOST_PP_SUB(BOOST_FUSION_ADAPT_STRUCT_WRAPPEDATTR_SIZE(ATTRIBUTE), 1), \
BOOST_FUSION_ADAPT_STRUCT_WRAPPEDATTR(ATTRIBUTE))
#endif

View File

@ -0,0 +1,64 @@
/*=============================================================================
Copyright (c) 2013-2014 Damien Buhl
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_STRUCT_DETAIL_ADAPT_BASE_ATTR_FILLER_HPP
#define BOOST_FUSION_ADAPTED_STRUCT_DETAIL_ADAPT_BASE_ATTR_FILLER_HPP
#include <boost/config.hpp>
#include <boost/fusion/adapted/struct/detail/preprocessor/is_seq.hpp>
#include <boost/preprocessor/empty.hpp>
#include <boost/preprocessor/tuple/size.hpp>
#include <boost/preprocessor/tuple/elem.hpp>
#include <boost/preprocessor/facilities/is_empty.hpp>
#include <boost/preprocessor/variadic/to_seq.hpp>
#include <boost/preprocessor/seq/for_each.hpp>
#include <boost/preprocessor/seq/push_front.hpp>
#define BOOST_FUSION_ADAPT_STRUCT_FILLER_0(X, Y) \
BOOST_FUSION_ADAPT_STRUCT_WRAP_ATTR(X,Y) \
BOOST_FUSION_ADAPT_STRUCT_FILLER_1
#define BOOST_FUSION_ADAPT_STRUCT_FILLER_1(X, Y) \
BOOST_FUSION_ADAPT_STRUCT_WRAP_ATTR(X,Y) \
BOOST_FUSION_ADAPT_STRUCT_FILLER_0
#define BOOST_FUSION_ADAPT_STRUCT_FILLER_0_END
#define BOOST_FUSION_ADAPT_STRUCT_FILLER_1_END
#define BOOST_FUSION_ADAPT_STRUCT_WRAP_ATTR(X, Y) \
BOOST_PP_IF(BOOST_PP_IS_EMPTY(X), \
((1, (Y))), \
((2, (X,Y))) \
)
#define BOOST_FUSION_ADAPT_STRUCT_WRAPPEDATTR_SIZE(ATTRIBUTE) \
BOOST_PP_TUPLE_ELEM(2, 0, ATTRIBUTE)
#define BOOST_FUSION_ADAPT_STRUCT_WRAPPEDATTR(ATTRIBUTE) \
BOOST_PP_TUPLE_ELEM(2, 1, ATTRIBUTE)
#if BOOST_PP_VARIADICS
# define BOOST_FUSION_ADAPT_STRUCT_ATTRIBUTES_FILLER_OP(r, unused, elem) \
BOOST_PP_IF(BOOST_FUSION_PP_IS_SEQ(elem), \
BOOST_PP_CAT( BOOST_FUSION_ADAPT_STRUCT_FILLER_0 elem ,_END), \
BOOST_FUSION_ADAPT_STRUCT_WRAP_ATTR(BOOST_FUSION_ADAPT_AUTO, \
elem))
# define BOOST_FUSION_ADAPT_STRUCT_ATTRIBUTES_FILLER(...) \
BOOST_PP_SEQ_PUSH_FRONT( \
BOOST_PP_SEQ_FOR_EACH( \
BOOST_FUSION_ADAPT_STRUCT_ATTRIBUTES_FILLER_OP, \
unused, BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__)), \
(0,0))
#endif // BOOST_PP_VARIADICS
#endif

View File

@ -0,0 +1,14 @@
/*=============================================================================
Copyright (c) 2013-2014 Damien Buhl
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_STRUCT_DETAIL_ADAPT_IS_TPL_HPP
#define BOOST_FUSION_ADAPTED_STRUCT_DETAIL_ADAPT_IS_TPL_HPP
#define BOOST_FUSION_ADAPT_IS_TPL(TEMPLATE_PARAMS_SEQ) \
BOOST_PP_SEQ_HEAD(TEMPLATE_PARAMS_SEQ)
#endif

View File

@ -34,6 +34,13 @@
#include <boost/type_traits/is_convertible.hpp> #include <boost/type_traits/is_convertible.hpp>
#include <boost/utility/enable_if.hpp> #include <boost/utility/enable_if.hpp>
#define BOOST_FUSION_DEFINE_STRUCT_FILLER_0(X, Y) \
((X, Y)) BOOST_FUSION_DEFINE_STRUCT_FILLER_1
#define BOOST_FUSION_DEFINE_STRUCT_FILLER_1(X, Y) \
((X, Y)) BOOST_FUSION_DEFINE_STRUCT_FILLER_0
#define BOOST_FUSION_DEFINE_STRUCT_FILLER_0_END
#define BOOST_FUSION_DEFINE_STRUCT_FILLER_1_END
#define BOOST_FUSION_DEFINE_STRUCT_COPY_CTOR_FILLER_I( \ #define BOOST_FUSION_DEFINE_STRUCT_COPY_CTOR_FILLER_I( \
R, ATTRIBUTE_TUPEL_SIZE, I, ATTRIBUTE) \ R, ATTRIBUTE_TUPEL_SIZE, I, ATTRIBUTE) \
\ \

View File

@ -301,7 +301,7 @@
#define BOOST_FUSION_DEFINE_STRUCT_INLINE_MEMBERS(NAME, ATTRIBUTES) \ #define BOOST_FUSION_DEFINE_STRUCT_INLINE_MEMBERS(NAME, ATTRIBUTES) \
BOOST_FUSION_DEFINE_STRUCT_MEMBERS_IMPL( \ BOOST_FUSION_DEFINE_STRUCT_MEMBERS_IMPL( \
NAME, \ NAME, \
BOOST_PP_CAT(BOOST_FUSION_ADAPT_STRUCT_FILLER_0 ATTRIBUTES,_END)) BOOST_PP_CAT(BOOST_FUSION_DEFINE_STRUCT_FILLER_0 ATTRIBUTES,_END))
// Note: can't compute BOOST_PP_SEQ_SIZE(ATTRIBUTES_SEQ) directly because // Note: can't compute BOOST_PP_SEQ_SIZE(ATTRIBUTES_SEQ) directly because
// ATTRIBUTES_SEQ may be empty and calling BOOST_PP_SEQ_SIZE on an empty // ATTRIBUTES_SEQ may be empty and calling BOOST_PP_SEQ_SIZE on an empty
@ -315,7 +315,7 @@
#define BOOST_FUSION_DEFINE_STRUCT_INLINE_ITERATOR(NAME, ATTRIBUTES) \ #define BOOST_FUSION_DEFINE_STRUCT_INLINE_ITERATOR(NAME, ATTRIBUTES) \
BOOST_FUSION_DEFINE_STRUCT_ITERATOR_IMPL( \ BOOST_FUSION_DEFINE_STRUCT_ITERATOR_IMPL( \
NAME, \ NAME, \
BOOST_PP_CAT(BOOST_FUSION_ADAPT_STRUCT_FILLER_0 ATTRIBUTES,_END)) BOOST_PP_CAT(BOOST_FUSION_DEFINE_STRUCT_FILLER_0 ATTRIBUTES,_END))
#define BOOST_FUSION_DEFINE_STRUCT_ITERATOR_IMPL(NAME, ATTRIBUTES_SEQ) \ #define BOOST_FUSION_DEFINE_STRUCT_ITERATOR_IMPL(NAME, ATTRIBUTES_SEQ) \
BOOST_FUSION_DEFINE_STRUCT_INLINE_ITERATOR_IMPL_IMPL( \ BOOST_FUSION_DEFINE_STRUCT_INLINE_ITERATOR_IMPL_IMPL( \

View File

@ -0,0 +1,41 @@
/*=============================================================================
BOOST_PP_VARIADICS version of BOOST_PP_IS_SEQ inspired from
boost/mpl/aux_/preprocessor/is_seq.hpp, original copyrights goes to :
Copyright Paul Mensonides 2003
Copyright Aleksey Gurtovoy 2003-2004
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_STRUCT_DETAIL_PREPROCESSOR_IS_SEQ_HPP
#define BOOST_FUSION_ADAPTED_STRUCT_DETAIL_PREPROCESSOR_IS_SEQ_HPP
#include <boost/preprocessor/seq/size.hpp>
#include <boost/preprocessor/arithmetic/dec.hpp>
#include <boost/preprocessor/punctuation/paren.hpp>
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/config/config.hpp>
#if BOOST_PP_VARIADICS
#define BOOST_FUSION_PP_IS_SEQ(seq) BOOST_PP_CAT(BOOST_FUSION_PP_IS_SEQ_, \
BOOST_FUSION_PP_IS_SEQ_0 seq BOOST_PP_RPAREN())
#define BOOST_FUSION_PP_IS_SEQ_0(...) \
BOOST_FUSION_PP_IS_SEQ_1(__VA_ARGS__
#define BOOST_FUSION_PP_IS_SEQ_ALWAYS_0(...) \
0
#define BOOST_FUSION_PP_IS_SEQ_BOOST_FUSION_PP_IS_SEQ_0 \
BOOST_FUSION_PP_IS_SEQ_ALWAYS_0(
#define BOOST_FUSION_PP_IS_SEQ_BOOST_FUSION_PP_IS_SEQ_1(...) \
1
#endif // BOOST_PP_VARIADICS
#endif

View File

@ -12,6 +12,8 @@
#include <boost/fusion/support/config.hpp> #include <boost/fusion/support/config.hpp>
#include <boost/fusion/adapted/struct/detail/namespace.hpp> #include <boost/fusion/adapted/struct/detail/namespace.hpp>
#define BOOST_FUSION_PROXY_PREFIX() obj.
#define BOOST_FUSION_ADAPT_STRUCT_DEFINE_PROXY_TYPE_IMPL( \ #define BOOST_FUSION_ADAPT_STRUCT_DEFINE_PROXY_TYPE_IMPL( \
WRAPPED_TYPE,NAMESPACE_SEQ,NAME) \ WRAPPED_TYPE,NAMESPACE_SEQ,NAME) \
\ \

View File

@ -38,18 +38,21 @@ namespace ns
{ {
public: public:
point() : x(0), y(0) {} point() : x(0), y(0), z(0) {}
point(int in_x, int in_y) : x(in_x), y(in_y) {} point(int in_x, int in_y, int in_z) : x(in_x), y(in_y), z(in_z) {}
int get_x() const { return x; } int get_x() const { return x; }
int get_y() const { return y; } int get_y() const { return y; }
int get_z() const { return z; }
void set_x(int x_) { x = x_; } void set_x(int x_) { x = x_; }
void set_y(int y_) { y = y_; } void set_y(int y_) { y = y_; }
void set_z(int z_) { z = z_; }
private: private:
int x; int x;
int y; int y;
int z;
}; };
#if !BOOST_WORKAROUND(__GNUC__,<4) #if !BOOST_WORKAROUND(__GNUC__,<4)
@ -58,17 +61,22 @@ namespace ns
friend struct boost::fusion::extension::access; friend struct boost::fusion::extension::access;
public: public:
point_with_private_members() : x(0), y(0) {} point_with_private_members() : x(0), y(0), z(0) {}
point_with_private_members(int x, int y) : x(x), y(y) {} point_with_private_members(int in_x, int in_y, int in_z)
: x(in_x), y(in_y), z(in_z) {}
private:
int get_x() const { return x; } int get_x() const { return x; }
int get_y() const { return y; } int get_y() const { return y; }
int get_z() const { return z; }
void set_x(int x_) { x = x_; } void set_x(int x_) { x = x_; }
void set_y(int y_) { y = y_; } void set_y(int y_) { y = y_; }
void set_z(int z_) { z = z_; }
private:
int x; int x;
int y; int y;
int z;
}; };
#endif #endif
@ -91,26 +99,56 @@ namespace ns
}; };
} }
BOOST_FUSION_ADAPT_ADT( #if BOOST_PP_VARIADICS
ns::point, BOOST_FUSION_ADAPT_ADT(
(int, int, obj.get_x(), obj.set_x(val)) ns::point,
(int, int, obj.get_y(), obj.set_y(val)) (int, int, obj.get_x(), obj.set_x(val))
) (BOOST_FUSION_ADAPT_AUTO, BOOST_FUSION_ADAPT_AUTO, obj.get_y(), obj.set_y(val))
(obj.get_z(), obj.set_z(val))
)
# if !BOOST_WORKAROUND(__GNUC__,<4)
BOOST_FUSION_ADAPT_ADT(
ns::point_with_private_members,
(obj.get_x(), obj.set_x(val))
(obj.get_y(), obj.set_y(val))
(obj.get_z(), obj.set_z(val))
)
# endif
BOOST_FUSION_ADAPT_ADT(
ns::name,
(obj.get_last(), obj.set_last(val))
(obj.get_first(), obj.set_first(val))
)
#else // BOOST_PP_VARIADICS
BOOST_FUSION_ADAPT_ADT(
ns::point,
(int, int, obj.get_x(), obj.set_x(val))
(BOOST_FUSION_ADAPT_AUTO, BOOST_FUSION_ADAPT_AUTO, obj.get_y(), obj.set_y(val))
(BOOST_FUSION_ADAPT_AUTO, BOOST_FUSION_ADAPT_AUTO, obj.get_z(), obj.set_z(val))
)
# if !BOOST_WORKAROUND(__GNUC__,<4)
BOOST_FUSION_ADAPT_ADT(
ns::point_with_private_members,
(BOOST_FUSION_ADAPT_AUTO, BOOST_FUSION_ADAPT_AUTO, obj.get_x(), obj.set_x(val))
(BOOST_FUSION_ADAPT_AUTO, BOOST_FUSION_ADAPT_AUTO, obj.get_y(), obj.set_y(val))
(BOOST_FUSION_ADAPT_AUTO, BOOST_FUSION_ADAPT_AUTO, obj.get_z(), obj.set_z(val))
)
# endif
BOOST_FUSION_ADAPT_ADT(
ns::name,
(const std::string&, const std::string&, obj.get_last(), obj.set_last(val))
(BOOST_FUSION_ADAPT_AUTO, BOOST_FUSION_ADAPT_AUTO, obj.get_first(), obj.set_first(val))
)
#if !BOOST_WORKAROUND(__GNUC__,<4)
BOOST_FUSION_ADAPT_ADT(
ns::point_with_private_members,
(int, int, obj.get_x(), obj.set_x(val))
(int, int, obj.get_y(), obj.set_y(val))
)
#endif #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 int
main() main()
{ {
@ -123,28 +161,30 @@ main()
{ {
BOOST_MPL_ASSERT_NOT((traits::is_view<ns::point>)); BOOST_MPL_ASSERT_NOT((traits::is_view<ns::point>));
ns::point p(123, 456); ns::point p(123, 456, 789);
std::cout << at_c<0>(p) << std::endl; std::cout << at_c<0>(p) << std::endl;
std::cout << at_c<1>(p) << std::endl; std::cout << at_c<1>(p) << std::endl;
std::cout << at_c<2>(p) << std::endl;
std::cout << p << std::endl; std::cout << p << std::endl;
BOOST_TEST(p == make_vector(123, 456)); BOOST_TEST(p == make_vector(123, 456, 789));
at_c<0>(p) = 6; at_c<0>(p) = 6;
at_c<1>(p) = 9; at_c<1>(p) = 9;
BOOST_TEST(p == make_vector(6, 9)); at_c<2>(p) = 12;
BOOST_TEST(p == make_vector(6, 9, 12));
BOOST_STATIC_ASSERT(boost::fusion::result_of::size<ns::point>::value == 2); BOOST_STATIC_ASSERT(boost::fusion::result_of::size<ns::point>::value == 3);
BOOST_STATIC_ASSERT(!boost::fusion::result_of::empty<ns::point>::value); BOOST_STATIC_ASSERT(!boost::fusion::result_of::empty<ns::point>::value);
BOOST_TEST(front(p) == 6); BOOST_TEST(front(p) == 6);
BOOST_TEST(back(p) == 9); BOOST_TEST(back(p) == 12);
} }
{ {
fusion::vector<int, float> v1(4, 2); fusion::vector<int, float, int> v1(4, 2, 2);
ns::point v2(5, 3); ns::point v2(5, 3, 3);
fusion::vector<long, double> v3(5, 4); fusion::vector<long, double, int> v3(5, 4, 4);
BOOST_TEST(v1 < v2); BOOST_TEST(v1 < v2);
BOOST_TEST(v1 <= v2); BOOST_TEST(v1 <= v2);
BOOST_TEST(v2 > v1); BOOST_TEST(v2 > v1);
@ -171,15 +211,15 @@ main()
{ {
// conversion from ns::point to vector // conversion from ns::point to vector
ns::point p(5, 3); ns::point p(5, 3, 3);
fusion::vector<int, long> v(p); fusion::vector<int, long, int> v(p);
v = p; v = p;
} }
{ {
// conversion from ns::point to list // conversion from ns::point to list
ns::point p(5, 3); ns::point p(5, 3, 3);
fusion::list<int, long> l(p); fusion::list<int, long, int> l(p);
l = p; l = p;
} }
@ -193,26 +233,29 @@ main()
#if !BOOST_WORKAROUND(__GNUC__,<4) #if !BOOST_WORKAROUND(__GNUC__,<4)
{ {
BOOST_MPL_ASSERT_NOT((traits::is_view<ns::point_with_private_members>)); BOOST_MPL_ASSERT_NOT((traits::is_view<ns::point_with_private_members>));
ns::point_with_private_members p(123, 456); ns::point_with_private_members p(123, 456, 789);
std::cout << at_c<0>(p) << std::endl; std::cout << at_c<0>(p) << std::endl;
std::cout << at_c<1>(p) << std::endl; std::cout << at_c<1>(p) << std::endl;
std::cout << at_c<2>(p) << std::endl;
std::cout << p << std::endl; std::cout << p << std::endl;
BOOST_TEST(p == make_vector(123, 456)); BOOST_TEST(p == make_vector(123, 456, 789));
at_c<0>(p) = 6; at_c<0>(p) = 6;
at_c<1>(p) = 9; at_c<1>(p) = 9;
BOOST_TEST(p == make_vector(6, 9)); at_c<2>(p) = 12;
BOOST_TEST(p == make_vector(6, 9, 12));
BOOST_STATIC_ASSERT(boost::fusion::result_of::size<ns::point_with_private_members>::value == 2); BOOST_STATIC_ASSERT(boost::fusion::result_of::size<ns::point_with_private_members>::value == 3);
BOOST_STATIC_ASSERT(!boost::fusion::result_of::empty<ns::point_with_private_members>::value); BOOST_STATIC_ASSERT(!boost::fusion::result_of::empty<ns::point_with_private_members>::value);
BOOST_TEST(front(p) == 6); BOOST_TEST(front(p) == 6);
BOOST_TEST(back(p) == 9); BOOST_TEST(back(p) == 12);
} }
#endif #endif
{ {
// Check types provided in case it's provided
BOOST_MPL_ASSERT(( BOOST_MPL_ASSERT((
boost::is_same< boost::is_same<
boost::fusion::result_of::front<ns::point>::type, boost::fusion::result_of::front<ns::point>::type,
@ -233,6 +276,28 @@ main()
boost::fusion::result_of::front<ns::point const>::type::type, boost::fusion::result_of::front<ns::point const>::type::type,
int int
>)); >));
// Check types provided in case it's deduced
BOOST_MPL_ASSERT((
boost::is_same<
boost::fusion::result_of::back<ns::point>::type,
boost::fusion::extension::adt_attribute_proxy<ns::point,2,false>
>));
BOOST_MPL_ASSERT((
boost::is_same<
boost::fusion::result_of::back<ns::point>::type::type,
int
>));
BOOST_MPL_ASSERT((
boost::is_same<
boost::fusion::result_of::back<ns::point const>::type,
boost::fusion::extension::adt_attribute_proxy<ns::point,2,true>
>));
BOOST_MPL_ASSERT((
boost::is_same<
boost::fusion::result_of::back<ns::point const>::type::type,
const int
>));
} }
return boost::report_errors(); return boost::report_errors();

View File

@ -37,28 +37,46 @@ namespace ns
{ {
public: public:
point() : x(0), y(0) {} point() : x(0), y(0), z(0) {}
point(int in_x, int in_y) : x(in_x), y(in_y) {} point(int in_x, int in_y, int in_z) : x(in_x), y(in_y), z(in_z) {}
int get_x() const { return x; } int get_x() const { return x; }
int get_y() const { return y; } int get_y() const { return y; }
int get_z() const { return z; }
void set_x(int x_) { x = x_; } void set_x(int x_) { x = x_; }
void set_y(int y_) { y = y_; } void set_y(int y_) { y = y_; }
void set_z(int z_) { z = z_; }
private: private:
int x; int x;
int y; int y;
int z;
}; };
} }
#if BOOST_PP_VARIADICS
// this creates a fusion view: boost::fusion::adapted::point // this creates a fusion view: boost::fusion::adapted::point
BOOST_FUSION_ADAPT_ADT_NAMED( BOOST_FUSION_ADAPT_ADT_NAMED(
ns::point, point, ns::point, point,
(int, int, obj.obj.get_x(), obj.obj.set_x(val)) (int, int, obj.get_x(), obj.set_x(val))
(int, int, obj.obj.get_y(), obj.obj.set_y(val)) (int, int, obj.get_y(), obj.set_y(val))
(obj.get_z(), obj.set_z(val))
) )
#else // BOOST_PP_VARIADICS
// this creates a fusion view: boost::fusion::adapted::point
BOOST_FUSION_ADAPT_ADT_NAMED(
ns::point, point,
(int, int, obj.get_x(), obj.set_x(val))
(int, int, obj.get_y(), obj.set_y(val))
(BOOST_FUSION_ADAPT_AUTO, BOOST_FUSION_ADAPT_AUTO, obj.get_z(), obj.set_z(val))
)
#endif // BOOST_PP_VARIADICS
int int
main() main()
{ {
@ -71,31 +89,33 @@ main()
{ {
BOOST_MPL_ASSERT((traits::is_view<adapted::point>)); BOOST_MPL_ASSERT((traits::is_view<adapted::point>));
ns::point basep(123, 456); ns::point basep(123, 456, 789);
adapted::point p(basep); adapted::point p(basep);
std::cout << at_c<0>(p) << std::endl; std::cout << at_c<0>(p) << std::endl;
std::cout << at_c<1>(p) << std::endl; std::cout << at_c<1>(p) << std::endl;
std::cout << at_c<2>(p) << std::endl;
std::cout << p << std::endl; std::cout << p << std::endl;
BOOST_TEST(p == make_vector(123, 456)); BOOST_TEST(p == make_vector(123, 456, 789));
at_c<0>(p) = 6; at_c<0>(p) = 6;
at_c<1>(p) = 9; at_c<1>(p) = 9;
BOOST_TEST(p == make_vector(6, 9)); at_c<2>(p) = 12;
BOOST_TEST(p == make_vector(6, 9, 12));
BOOST_STATIC_ASSERT(boost::fusion::result_of::size<adapted::point>::value == 2); BOOST_STATIC_ASSERT(boost::fusion::result_of::size<adapted::point>::value == 3);
BOOST_STATIC_ASSERT(!boost::fusion::result_of::empty<adapted::point>::value); BOOST_STATIC_ASSERT(!boost::fusion::result_of::empty<adapted::point>::value);
BOOST_TEST(front(p) == 6); BOOST_TEST(front(p) == 6);
BOOST_TEST(back(p) == 9); BOOST_TEST(back(p) == 12);
} }
{ {
fusion::vector<int, float> v1(4, 2); fusion::vector<int, float, int> v1(4, 2, 2);
ns::point basep(5, 3); ns::point basep(5, 3, 3);
adapted::point v2(basep); adapted::point v2(basep);
fusion::vector<long, double> v3(5, 4); fusion::vector<long, double, int> v3(5, 4, 4);
BOOST_TEST(v1 < v2); BOOST_TEST(v1 < v2);
BOOST_TEST(v1 <= v2); BOOST_TEST(v1 <= v2);
BOOST_TEST(v2 > v1); BOOST_TEST(v2 > v1);
@ -108,19 +128,19 @@ main()
{ {
// conversion from ns::point to vector // conversion from ns::point to vector
ns::point basep(5, 3); ns::point basep(5, 3, 3);
adapted::point p(basep); adapted::point p(basep);
fusion::vector<int, long> v(p); fusion::vector<int, long, int> v(p);
v = p; v = p;
} }
{ {
// conversion from ns::point to list // conversion from ns::point to list
ns::point basep(5, 3); ns::point basep(5, 3, 3);
adapted::point p(basep); adapted::point p(basep);
fusion::list<int, long> l(p); fusion::list<int, long, float> l(p);
l = p; l = p;
} }

View File

@ -26,31 +26,50 @@ namespace ns
struct y_member; struct y_member;
struct z_member; struct z_member;
struct non_member;
class point class point
{ {
public: public:
point() : x(0), y(0) {} point() : x(0), y(0), z(0) {}
point(int in_x, int in_y) : x(in_x), y(in_y) {} point(int in_x, int in_y, int in_z) : x(in_x), y(in_y), z(in_z) {}
int get_x() const { return x; } int get_x() const { return x; }
int get_y() const { return y; } int get_y() const { return y; }
int get_z() const { return z; }
void set_x(int x_) { x = x_; } void set_x(int x_) { x = x_; }
void set_y(int y_) { y = y_; } void set_y(int y_) { y = y_; }
void set_z(int z_) { z = z_; }
private: private:
int x; int x;
int y; int y;
int z;
}; };
} }
#if BOOST_PP_VARIADICS
BOOST_FUSION_ADAPT_ASSOC_ADT( BOOST_FUSION_ADAPT_ASSOC_ADT(
ns::point, ns::point,
(int, int, obj.get_x(), obj.set_x(val), ns::x_member) (int, int, obj.get_x(), obj.set_x(val), ns::x_member)
(int, int, obj.get_y(), obj.set_y(val), ns::y_member) (int, int, obj.get_y(), obj.set_y(val), ns::y_member)
(obj.get_z(), obj.set_z(val), ns::z_member)
) )
#else // BOOST_PP_VARIADICS
BOOST_FUSION_ADAPT_ASSOC_ADT(
ns::point,
(int, int, obj.get_x(), obj.set_x(val), ns::x_member)
(int, int, obj.get_y(), obj.set_y(val), ns::y_member)
(BOOST_FUSION_ADAPT_AUTO, BOOST_FUSION_ADAPT_AUTO, obj.get_z(), obj.set_z(val), ns::z_member)
)
#endif
int int
main() main()
{ {
@ -62,28 +81,30 @@ main()
{ {
BOOST_MPL_ASSERT_NOT((traits::is_view<ns::point>)); BOOST_MPL_ASSERT_NOT((traits::is_view<ns::point>));
ns::point p(123, 456); ns::point p(123, 456, 789);
std::cout << at_c<0>(p) << std::endl; std::cout << at_c<0>(p) << std::endl;
std::cout << at_c<1>(p) << std::endl; std::cout << at_c<1>(p) << std::endl;
std::cout << at_c<2>(p) << std::endl;
std::cout << p << std::endl; std::cout << p << std::endl;
BOOST_TEST(p == make_vector(123, 456)); BOOST_TEST(p == make_vector(123, 456, 789));
at_c<0>(p) = 6; at_c<0>(p) = 6;
at_c<1>(p) = 9; at_c<1>(p) = 9;
BOOST_TEST(p == make_vector(6, 9)); at_c<2>(p) = 12;
BOOST_TEST(p == make_vector(6, 9, 12));
BOOST_STATIC_ASSERT(boost::fusion::result_of::size<ns::point>::value == 2); BOOST_STATIC_ASSERT(boost::fusion::result_of::size<ns::point>::value == 3);
BOOST_STATIC_ASSERT(!boost::fusion::result_of::empty<ns::point>::value); BOOST_STATIC_ASSERT(!boost::fusion::result_of::empty<ns::point>::value);
BOOST_TEST(front(p) == 6); BOOST_TEST(front(p) == 6);
BOOST_TEST(back(p) == 9); BOOST_TEST(back(p) == 12);
} }
{ {
boost::fusion::vector<int, float> v1(4, 2); boost::fusion::vector<int, float, int> v1(4, 2, 2);
ns::point v2(5, 3); ns::point v2(5, 3, 3);
boost::fusion::vector<long, double> v3(5, 4); boost::fusion::vector<long, double, int> v3(5, 4, 4);
BOOST_TEST(v1 < v2); BOOST_TEST(v1 < v2);
BOOST_TEST(v1 <= v2); BOOST_TEST(v1 <= v2);
BOOST_TEST(v2 > v1); BOOST_TEST(v2 > v1);
@ -96,15 +117,15 @@ main()
{ {
// conversion from ns::point to vector // conversion from ns::point to vector
ns::point p(5, 3); ns::point p(5, 3, 3);
boost::fusion::vector<int, long> v(p); boost::fusion::vector<int, long, int> v(p);
v = p; v = p;
} }
{ {
// conversion from ns::point to list // conversion from ns::point to list
ns::point p(5, 3); ns::point p(5, 3, 3);
boost::fusion::list<int, long> l(p); boost::fusion::list<int, long, int> l(p);
l = p; l = p;
} }
@ -119,15 +140,19 @@ main()
// assoc stuff // assoc stuff
BOOST_MPL_ASSERT((boost::fusion::result_of::has_key<ns::point, ns::x_member>)); BOOST_MPL_ASSERT((boost::fusion::result_of::has_key<ns::point, ns::x_member>));
BOOST_MPL_ASSERT((boost::fusion::result_of::has_key<ns::point, ns::y_member>)); BOOST_MPL_ASSERT((boost::fusion::result_of::has_key<ns::point, ns::y_member>));
BOOST_MPL_ASSERT((boost::mpl::not_<boost::fusion::result_of::has_key<ns::point, ns::z_member> >)); BOOST_MPL_ASSERT((boost::fusion::result_of::has_key<ns::point, ns::z_member>));
BOOST_MPL_ASSERT((boost::mpl::not_<boost::fusion::result_of::has_key<ns::point, ns::non_member> >));
BOOST_MPL_ASSERT((boost::is_same<boost::fusion::result_of::value_at_key<ns::point, ns::x_member>::type, int>)); BOOST_MPL_ASSERT((boost::is_same<boost::fusion::result_of::value_at_key<ns::point, ns::x_member>::type, int>));
BOOST_MPL_ASSERT((boost::is_same<boost::fusion::result_of::value_at_key<ns::point, ns::y_member>::type, int>)); BOOST_MPL_ASSERT((boost::is_same<boost::fusion::result_of::value_at_key<ns::point, ns::y_member>::type, int>));
BOOST_MPL_ASSERT((boost::is_same<boost::fusion::result_of::value_at_key<ns::point, ns::z_member>::type, int>));
ns::point p(5, 3); ns::point p(5, 3, 1);
BOOST_TEST(at_key<ns::x_member>(p) == 5); BOOST_TEST(at_key<ns::x_member>(p) == 5);
BOOST_TEST(at_key<ns::y_member>(p) == 3); BOOST_TEST(at_key<ns::y_member>(p) == 3);
BOOST_TEST(at_key<ns::z_member>(p) == 1);
} }
return boost::report_errors(); return boost::report_errors();

View File

@ -48,8 +48,8 @@ namespace ns
BOOST_FUSION_ADAPT_ASSOC_ADT_NAMED( BOOST_FUSION_ADAPT_ASSOC_ADT_NAMED(
ns::point, ns::point,
point, point,
(int, int, obj.obj.get_x(), obj.obj.set_x(val), ns::x_member) (int, int, obj.get_x(), obj.set_x(val), ns::x_member)
(int, int, obj.obj.get_y(), obj.obj.set_y(val), ns::y_member) (int, int, obj.get_y(), obj.set_y(val), ns::y_member)
) )
int int

View File

@ -30,6 +30,7 @@
#include <boost/fusion/mpl.hpp> #include <boost/fusion/mpl.hpp>
#include <boost/fusion/support/is_view.hpp> #include <boost/fusion/support/is_view.hpp>
#include <boost/mpl/front.hpp> #include <boost/mpl/front.hpp>
#include <boost/mpl/back.hpp>
#include <boost/mpl/is_sequence.hpp> #include <boost/mpl/is_sequence.hpp>
#include <boost/mpl/assert.hpp> #include <boost/mpl/assert.hpp>
#include <boost/mpl/not.hpp> #include <boost/mpl/not.hpp>
@ -42,19 +43,33 @@ namespace ns
struct x_member; struct x_member;
struct y_member; struct y_member;
struct z_member; struct z_member;
struct non_member;
struct point struct point
{ {
int x; int x;
int y; int y;
int z;
}; };
} }
BOOST_FUSION_ADAPT_ASSOC_STRUCT( #if BOOST_PP_VARIADICS
ns::point, BOOST_FUSION_ADAPT_ASSOC_STRUCT(
(int, x, ns::x_member) ns::point,
(int, y, ns::y_member) (x, ns::x_member)
) (y, ns::y_member)
(int, z, ns::z_member)
)
#else // BOOST_PP_VARIADICS
BOOST_FUSION_ADAPT_ASSOC_STRUCT(
ns::point,
(BOOST_FUSION_ADAPT_AUTO, x, ns::x_member)
(BOOST_FUSION_ADAPT_AUTO, y, ns::y_member)
(int, z, ns::z_member)
)
#endif
int int
main() main()
@ -68,28 +83,30 @@ main()
{ {
BOOST_MPL_ASSERT_NOT((traits::is_view<ns::point>)); BOOST_MPL_ASSERT_NOT((traits::is_view<ns::point>));
ns::point p = {123, 456}; ns::point p = {123, 456, 789};
std::cout << at_c<0>(p) << std::endl; std::cout << at_c<0>(p) << std::endl;
std::cout << at_c<1>(p) << std::endl; std::cout << at_c<1>(p) << std::endl;
std::cout << at_c<2>(p) << std::endl;
std::cout << p << std::endl; std::cout << p << std::endl;
BOOST_TEST(p == make_vector(123, 456)); BOOST_TEST(p == make_vector(123, 456, 789));
at_c<0>(p) = 6; at_c<0>(p) = 6;
at_c<1>(p) = 9; at_c<1>(p) = 9;
BOOST_TEST(p == make_vector(6, 9)); at_c<2>(p) = 12;
BOOST_TEST(p == make_vector(6, 9, 12));
BOOST_STATIC_ASSERT(boost::fusion::result_of::size<ns::point>::value == 2); BOOST_STATIC_ASSERT(boost::fusion::result_of::size<ns::point>::value == 3);
BOOST_STATIC_ASSERT(!boost::fusion::result_of::empty<ns::point>::value); BOOST_STATIC_ASSERT(!boost::fusion::result_of::empty<ns::point>::value);
BOOST_TEST(front(p) == 6); BOOST_TEST(front(p) == 6);
BOOST_TEST(back(p) == 9); BOOST_TEST(back(p) == 12);
} }
{ {
fusion::vector<int, float> v1(4, 2); fusion::vector<int, float, int> v1(4, 2, 2);
ns::point v2 = {5, 3}; ns::point v2 = {5, 3, 3};
fusion::vector<long, double> v3(5, 4); fusion::vector<long, double, int> v3(5, 4, 4);
BOOST_TEST(v1 < v2); BOOST_TEST(v1 < v2);
BOOST_TEST(v1 <= v2); BOOST_TEST(v1 <= v2);
BOOST_TEST(v2 > v1); BOOST_TEST(v2 > v1);
@ -102,15 +119,15 @@ main()
{ {
// conversion from ns::point to vector // conversion from ns::point to vector
ns::point p = {5, 3}; ns::point p = {5, 3, 3};
fusion::vector<int, long> v(p); fusion::vector<int, long, int> v(p);
v = p; v = p;
} }
{ {
// conversion from ns::point to list // conversion from ns::point to list
ns::point p = {5, 3}; ns::point p = {5, 3, 3};
fusion::list<int, long> l(p); fusion::list<int, long, int> l(p);
l = p; l = p;
} }
@ -118,15 +135,18 @@ main()
// assoc stuff // assoc stuff
BOOST_MPL_ASSERT((boost::fusion::result_of::has_key<ns::point, ns::x_member>)); BOOST_MPL_ASSERT((boost::fusion::result_of::has_key<ns::point, ns::x_member>));
BOOST_MPL_ASSERT((boost::fusion::result_of::has_key<ns::point, ns::y_member>)); BOOST_MPL_ASSERT((boost::fusion::result_of::has_key<ns::point, ns::y_member>));
BOOST_MPL_ASSERT((mpl::not_<boost::fusion::result_of::has_key<ns::point, ns::z_member> >)); BOOST_MPL_ASSERT((boost::fusion::result_of::has_key<ns::point, ns::z_member>));
BOOST_MPL_ASSERT((mpl::not_<boost::fusion::result_of::has_key<ns::point, ns::non_member> >));
BOOST_MPL_ASSERT((boost::is_same<boost::fusion::result_of::value_at_key<ns::point, ns::x_member>::type, int>)); BOOST_MPL_ASSERT((boost::is_same<boost::fusion::result_of::value_at_key<ns::point, ns::x_member>::type, int>));
BOOST_MPL_ASSERT((boost::is_same<boost::fusion::result_of::value_at_key<ns::point, ns::y_member>::type, int>)); BOOST_MPL_ASSERT((boost::is_same<boost::fusion::result_of::value_at_key<ns::point, ns::y_member>::type, int>));
BOOST_MPL_ASSERT((boost::is_same<boost::fusion::result_of::value_at_key<ns::point, ns::z_member>::type, int>));
ns::point p = {5, 3}; ns::point p = {5, 3, 9};
BOOST_TEST(at_key<ns::x_member>(p) == 5); BOOST_TEST(at_key<ns::x_member>(p) == 5);
BOOST_TEST(at_key<ns::y_member>(p) == 3); BOOST_TEST(at_key<ns::y_member>(p) == 3);
BOOST_TEST(at_key<ns::z_member>(p) == 9);
} }
{ {
@ -134,6 +154,9 @@ main()
BOOST_MPL_ASSERT((boost::is_same< BOOST_MPL_ASSERT((boost::is_same<
boost::fusion::result_of::value_at_c<ns::point,0>::type boost::fusion::result_of::value_at_c<ns::point,0>::type
, mpl::front<ns::point>::type>)); , mpl::front<ns::point>::type>));
BOOST_MPL_ASSERT((boost::is_same<
boost::fusion::result_of::value_at_c<ns::point,2>::type
, mpl::back<ns::point>::type>));
} }
return boost::report_errors(); return boost::report_errors();

View File

@ -26,39 +26,57 @@ namespace ns
struct y_member; struct y_member;
struct z_member; struct z_member;
template<typename X, typename Y> struct non_member;
template<typename X, typename Y, typename Z>
class point class point
{ {
public: public:
point() : x(0), y(0) {} point() : x(0), y(0), z(0) {}
point(X in_x, Y in_y) : x(in_x), y(in_y) {} point(X in_x, Y in_y, Z in_z) : x(in_x), y(in_y), z(in_z) {}
X get_x() const { return x; } X get_x() const { return x; }
Y get_y() const { return y; } Y get_y() const { return y; }
Z get_z() const { return z; }
void set_x(X x_) { x = x_; } void set_x(X x_) { x = x_; }
void set_y(Y y_) { y = y_; } void set_y(Y y_) { y = y_; }
void set_z(Z z_) { z = z_; }
private: private:
X x; X x;
Y y; Y y;
Z z;
}; };
} }
#if BOOST_PP_VARIADICS
BOOST_FUSION_ADAPT_ASSOC_TPL_ADT( BOOST_FUSION_ADAPT_ASSOC_TPL_ADT(
(X)(Y), (X)(Y)(Z),
(ns::point)(X)(Y), (ns::point)(X)(Y)(Z),
(X, X, obj.get_x(), obj.set_x(val), ns::x_member) (X, X, obj.get_x(), obj.set_x(val), ns::x_member)
(Y, Y, obj.get_y(), obj.set_y(val), ns::y_member) (Y, Y, obj.get_y(), obj.set_y(val), ns::y_member)
(obj.get_z(), obj.set_z(val), ns::z_member)
) )
#else // BOOST_PP_VARIADICS
BOOST_FUSION_ADAPT_ASSOC_TPL_ADT(
(X)(Y)(Z),
(ns::point)(X)(Y)(Z),
(X, X, obj.get_x(), obj.set_x(val), ns::x_member)
(Y, Y, obj.get_y(), obj.set_y(val), ns::y_member)
(BOOST_FUSION_ADAPT_AUTO, BOOST_FUSION_ADAPT_AUTO, obj.get_z(), obj.set_z(val), ns::z_member)
)
#endif
int int
main() main()
{ {
using namespace boost::fusion; using namespace boost::fusion;
typedef ns::point<int,int> point; typedef ns::point<int,int,long> point;
std::cout << tuple_open('['); std::cout << tuple_open('[');
std::cout << tuple_close(']'); std::cout << tuple_close(']');
@ -66,28 +84,30 @@ main()
{ {
BOOST_MPL_ASSERT_NOT((traits::is_view<point>)); BOOST_MPL_ASSERT_NOT((traits::is_view<point>));
point p(123, 456); point p(123, 456, 789);
std::cout << at_c<0>(p) << std::endl; std::cout << at_c<0>(p) << std::endl;
std::cout << at_c<1>(p) << std::endl; std::cout << at_c<1>(p) << std::endl;
std::cout << at_c<2>(p) << std::endl;
std::cout << p << std::endl; std::cout << p << std::endl;
BOOST_TEST(p == make_vector(123, 456)); BOOST_TEST(p == make_vector(123, 456, 789));
at_c<0>(p) = 6; at_c<0>(p) = 6;
at_c<1>(p) = 9; at_c<1>(p) = 9;
BOOST_TEST(p == make_vector(6, 9)); at_c<2>(p) = 12;
BOOST_TEST(p == make_vector(6, 9, 12));
BOOST_STATIC_ASSERT(boost::fusion::result_of::size<point>::value == 2); BOOST_STATIC_ASSERT(boost::fusion::result_of::size<point>::value == 3);
BOOST_STATIC_ASSERT(!boost::fusion::result_of::empty<point>::value); BOOST_STATIC_ASSERT(!boost::fusion::result_of::empty<point>::value);
BOOST_TEST(front(p) == 6); BOOST_TEST(front(p) == 6);
BOOST_TEST(back(p) == 9); BOOST_TEST(back(p) == 12);
} }
{ {
boost::fusion::vector<int, float> v1(4, 2); boost::fusion::vector<int, float, long> v1(4, 2, 2);
point v2(5, 3); point v2(5, 3, 3);
boost::fusion::vector<long, double> v3(5, 4); boost::fusion::vector<long, double, long> v3(5, 4, 4);
BOOST_TEST(v1 < v2); BOOST_TEST(v1 < v2);
BOOST_TEST(v1 <= v2); BOOST_TEST(v1 <= v2);
BOOST_TEST(v2 > v1); BOOST_TEST(v2 > v1);
@ -100,15 +120,15 @@ main()
{ {
// conversion from point to vector // conversion from point to vector
point p(5, 3); point p(5, 3, 3);
boost::fusion::vector<int, long> v(p); boost::fusion::vector<int, long, int> v(p);
v = p; v = p;
} }
{ {
// conversion from point to list // conversion from point to list
point p(5, 3); point p(5, 3, 3);
boost::fusion::list<int, long> l(p); boost::fusion::list<int, long, int> l(p);
l = p; l = p;
} }
@ -123,15 +143,18 @@ main()
// assoc stuff // assoc stuff
BOOST_MPL_ASSERT((boost::fusion::result_of::has_key<point, ns::x_member>)); BOOST_MPL_ASSERT((boost::fusion::result_of::has_key<point, ns::x_member>));
BOOST_MPL_ASSERT((boost::fusion::result_of::has_key<point, ns::y_member>)); BOOST_MPL_ASSERT((boost::fusion::result_of::has_key<point, ns::y_member>));
BOOST_MPL_ASSERT((boost::mpl::not_<boost::fusion::result_of::has_key<point, ns::z_member> >)); BOOST_MPL_ASSERT((boost::fusion::result_of::has_key<point, ns::z_member>));
BOOST_MPL_ASSERT((boost::mpl::not_<boost::fusion::result_of::has_key<point, ns::non_member> >));
BOOST_MPL_ASSERT((boost::is_same<boost::fusion::result_of::value_at_key<point, ns::x_member>::type, int>)); BOOST_MPL_ASSERT((boost::is_same<boost::fusion::result_of::value_at_key<point, ns::x_member>::type, int>));
BOOST_MPL_ASSERT((boost::is_same<boost::fusion::result_of::value_at_key<point, ns::y_member>::type, int>)); BOOST_MPL_ASSERT((boost::is_same<boost::fusion::result_of::value_at_key<point, ns::y_member>::type, int>));
BOOST_MPL_ASSERT((boost::is_same<boost::fusion::result_of::value_at_key<point, ns::z_member>::type, long>));
point p(5, 3); point p(5, 3, 1);
BOOST_TEST(at_key<ns::x_member>(p) == 5); BOOST_TEST(at_key<ns::x_member>(p) == 5);
BOOST_TEST(at_key<ns::y_member>(p) == 3); BOOST_TEST(at_key<ns::y_member>(p) == 3);
BOOST_TEST(at_key<ns::z_member>(p) == 1);
} }
return boost::report_errors(); return boost::report_errors();

View File

@ -39,27 +39,42 @@ namespace ns
struct y_member; struct y_member;
struct z_member; struct z_member;
template<typename X, typename Y> struct non_member;
template<typename X, typename Y, typename Z>
struct point struct point
{ {
X x; X x;
Y y; Y y;
Z z;
}; };
} }
BOOST_FUSION_ADAPT_ASSOC_TPL_STRUCT( #if BOOST_PP_VARIADICS
(X)(Y), BOOST_FUSION_ADAPT_ASSOC_TPL_STRUCT(
(ns::point)(X)(Y), (X)(Y)(Z),
(int, x, ns::x_member) (ns::point)(X)(Y)(Z),
(int, y, ns::y_member) (int, x, ns::x_member)
) (Y, y, ns::y_member)
(z, ns::z_member)
)
#else // BOOST_PP_VARIADICS
BOOST_FUSION_ADAPT_ASSOC_TPL_STRUCT(
(X)(Y)(Z),
(ns::point)(X)(Y)(Z),
(int, x, ns::x_member)
(Y, y, ns::y_member)
(BOOST_FUSION_ADAPT_AUTO, z, ns::z_member)
)
#endif
int int
main() main()
{ {
using namespace boost::fusion; using namespace boost::fusion;
typedef ns::point<int,int> point; typedef ns::point<int,int,float> point;
std::cout << tuple_open('['); std::cout << tuple_open('[');
std::cout << tuple_close(']'); std::cout << tuple_close(']');
@ -67,28 +82,30 @@ main()
{ {
BOOST_MPL_ASSERT_NOT((traits::is_view<point>)); BOOST_MPL_ASSERT_NOT((traits::is_view<point>));
point p = {123, 456}; point p = {123, 456, 789.43f};
std::cout << at_c<0>(p) << std::endl; std::cout << at_c<0>(p) << std::endl;
std::cout << at_c<1>(p) << std::endl; std::cout << at_c<1>(p) << std::endl;
std::cout << at_c<2>(p) << std::endl;
std::cout << p << std::endl; std::cout << p << std::endl;
BOOST_TEST(p == make_vector(123, 456)); BOOST_TEST(p == make_vector(123, 456, 789.43f));
at_c<0>(p) = 6; at_c<0>(p) = 6;
at_c<1>(p) = 9; at_c<1>(p) = 9;
BOOST_TEST(p == make_vector(6, 9)); at_c<2>(p) = 12;
BOOST_TEST(p == make_vector(6, 9, 12));
BOOST_STATIC_ASSERT(boost::fusion::result_of::size<point>::value == 2); BOOST_STATIC_ASSERT(boost::fusion::result_of::size<point>::value == 3);
BOOST_STATIC_ASSERT(!boost::fusion::result_of::empty<point>::value); BOOST_STATIC_ASSERT(!boost::fusion::result_of::empty<point>::value);
BOOST_TEST(front(p) == 6); BOOST_TEST(front(p) == 6);
BOOST_TEST(back(p) == 9); BOOST_TEST(back(p) == 12);
} }
{ {
vector<int, float> v1(4, 2); vector<int, float, int> v1(4, 2, 2);
point v2 = {5, 3}; point v2 = {5, 3, 3};
vector<long, double> v3(5, 4); vector<long, double, float> v3(5, 4, 4.13f);
BOOST_TEST(v1 < v2); BOOST_TEST(v1 < v2);
BOOST_TEST(v1 <= v2); BOOST_TEST(v1 <= v2);
BOOST_TEST(v2 > v1); BOOST_TEST(v2 > v1);
@ -101,15 +118,15 @@ main()
{ {
// conversion from point to vector // conversion from point to vector
point p = {5, 3}; point p = {5, 3, 3};
vector<int, long> v(p); vector<int, long, int> v(p);
v = p; v = p;
} }
{ {
// conversion from point to list // conversion from point to list
point p = {5, 3}; point p = {5, 3, 3};
list<int, long> l(p); list<int, long, int> l(p);
l = p; l = p;
} }
@ -117,15 +134,18 @@ main()
// assoc stuff // assoc stuff
BOOST_MPL_ASSERT((boost::fusion::result_of::has_key<point, ns::x_member>)); BOOST_MPL_ASSERT((boost::fusion::result_of::has_key<point, ns::x_member>));
BOOST_MPL_ASSERT((boost::fusion::result_of::has_key<point, ns::y_member>)); BOOST_MPL_ASSERT((boost::fusion::result_of::has_key<point, ns::y_member>));
BOOST_MPL_ASSERT((boost::mpl::not_<boost::fusion::result_of::has_key<point, ns::z_member> >)); BOOST_MPL_ASSERT((boost::fusion::result_of::has_key<point, ns::z_member>));
BOOST_MPL_ASSERT((boost::mpl::not_<boost::fusion::result_of::has_key<point, ns::non_member> >));
BOOST_MPL_ASSERT((boost::is_same<boost::fusion::result_of::value_at_key<point, ns::x_member>::type, int>)); BOOST_MPL_ASSERT((boost::is_same<boost::fusion::result_of::value_at_key<point, ns::x_member>::type, int>));
BOOST_MPL_ASSERT((boost::is_same<boost::fusion::result_of::value_at_key<point, ns::y_member>::type, int>)); BOOST_MPL_ASSERT((boost::is_same<boost::fusion::result_of::value_at_key<point, ns::y_member>::type, int>));
BOOST_MPL_ASSERT((boost::is_same<boost::fusion::result_of::value_at_key<point, ns::z_member>::type, float>));
point p = {5, 3}; point p = {5, 3, 9};
BOOST_TEST(at_key<ns::x_member>(p) == 5); BOOST_TEST(at_key<ns::x_member>(p) == 5);
BOOST_TEST(at_key<ns::y_member>(p) == 3); BOOST_TEST(at_key<ns::y_member>(p) == 3);
BOOST_TEST(at_key<ns::z_member>(p) == 9);
} }
return boost::report_errors(); return boost::report_errors();

View File

@ -38,6 +38,7 @@ namespace ns
{ {
int x; int x;
int y; int y;
int z;
}; };
#if !BOOST_WORKAROUND(__GNUC__,<4) #if !BOOST_WORKAROUND(__GNUC__,<4)
@ -48,9 +49,10 @@ namespace ns
private: private:
int x; int x;
int y; int y;
int z;
public: public:
point_with_private_attributes(int x, int y):x(x),y(y) point_with_private_attributes(int x, int y, int z):x(x),y(y),z(z)
{} {}
}; };
#endif #endif
@ -67,63 +69,99 @@ namespace ns
}; };
} }
BOOST_FUSION_ADAPT_STRUCT( #if BOOST_PP_VARIADICS
ns::point,
(int, x) BOOST_FUSION_ADAPT_STRUCT(
(int, y) ns::point,
) x,
y,
z
)
# if !BOOST_WORKAROUND(__GNUC__,<4)
BOOST_FUSION_ADAPT_STRUCT(
ns::point_with_private_attributes,
x,
y,
z
)
# endif
struct s { int m; };
BOOST_FUSION_ADAPT_STRUCT(s, m)
BOOST_FUSION_ADAPT_STRUCT(
ns::bar,
foo_.x, // test that adapted members can actually be expressions
y
)
#else // BOOST_PP_VARIADICS
BOOST_FUSION_ADAPT_STRUCT(
ns::point,
(int, x)
(int, y)
(BOOST_FUSION_ADAPT_AUTO, z)
)
# if !BOOST_WORKAROUND(__GNUC__,<4)
BOOST_FUSION_ADAPT_STRUCT(
ns::point_with_private_attributes,
(int, x)
(int, y)
(BOOST_FUSION_ADAPT_AUTO, z)
)
# endif
struct s { int m; };
BOOST_FUSION_ADAPT_STRUCT(s, (BOOST_FUSION_ADAPT_AUTO, m))
BOOST_FUSION_ADAPT_STRUCT(
ns::bar,
(BOOST_FUSION_ADAPT_AUTO, foo_.x) // test that adapted members can actually be expressions
(BOOST_FUSION_ADAPT_AUTO, y)
)
#if !BOOST_WORKAROUND(__GNUC__,<4)
BOOST_FUSION_ADAPT_STRUCT(
ns::point_with_private_attributes,
(int, x)
(int, y)
)
#endif #endif
struct s { int m; };
BOOST_FUSION_ADAPT_STRUCT(s, (int, m))
BOOST_FUSION_ADAPT_STRUCT(
ns::bar,
(int, foo_.x) // test that adapted members can actually be expressions
(int, y)
)
int int
main() main()
{ {
using namespace boost::fusion; using namespace boost::fusion;
using namespace boost; using namespace boost;
using ns::point;
std::cout << tuple_open('['); std::cout << tuple_open('[');
std::cout << tuple_close(']'); std::cout << tuple_close(']');
std::cout << tuple_delimiter(", "); std::cout << tuple_delimiter(", ");
{ {
BOOST_MPL_ASSERT_NOT((traits::is_view<ns::point>)); BOOST_MPL_ASSERT_NOT((traits::is_view<point>));
ns::point p = {123, 456}; point p = {123, 456, 789};
std::cout << at_c<0>(p) << std::endl; std::cout << at_c<0>(p) << std::endl;
std::cout << at_c<1>(p) << std::endl; std::cout << at_c<1>(p) << std::endl;
std::cout << at_c<2>(p) << std::endl;
std::cout << p << std::endl; std::cout << p << std::endl;
BOOST_TEST(p == make_vector(123, 456)); BOOST_TEST(p == make_vector(123, 456, 789));
at_c<0>(p) = 6; at_c<0>(p) = 6;
at_c<1>(p) = 9; at_c<1>(p) = 9;
BOOST_TEST(p == make_vector(6, 9)); at_c<2>(p) = 12;
BOOST_TEST(p == make_vector(6, 9, 12));
BOOST_STATIC_ASSERT(boost::fusion::result_of::size<ns::point>::value == 2); BOOST_STATIC_ASSERT(boost::fusion::result_of::size<point>::value == 3);
BOOST_STATIC_ASSERT(!boost::fusion::result_of::empty<ns::point>::value); BOOST_STATIC_ASSERT(!boost::fusion::result_of::empty<point>::value);
BOOST_TEST(front(p) == 6); BOOST_TEST(front(p) == 6);
BOOST_TEST(back(p) == 9); BOOST_TEST(back(p) == 12);
} }
{ {
fusion::vector<int, float> v1(4, 2); vector<int, float, int> v1(4, 2, 2);
ns::point v2 = {5, 3}; point v2 = {5, 3, 3};
fusion::vector<long, double> v3(5, 4); vector<long, double, int> v3(5, 4, 4);
BOOST_TEST(v1 < v2); BOOST_TEST(v1 < v2);
BOOST_TEST(v1 <= v2); BOOST_TEST(v1 <= v2);
BOOST_TEST(v2 > v1); BOOST_TEST(v2 > v1);
@ -135,16 +173,16 @@ main()
} }
{ {
// conversion from ns::point to vector // conversion from point to vector
ns::point p = {5, 3}; point p = {5, 3, 3};
fusion::vector<int, long> v(p); vector<int, long, int> v(p);
v = p; v = p;
} }
{ {
// conversion from ns::point to list // conversion from point to list
ns::point p = {5, 3}; point p = {5, 3, 3};
fusion::list<int, long> l(p); list<int, long, int> l(p);
l = p; l = p;
} }
@ -167,12 +205,13 @@ main()
#if !BOOST_WORKAROUND(__GNUC__,<4) #if !BOOST_WORKAROUND(__GNUC__,<4)
{ {
ns::point_with_private_attributes p(123, 456); ns::point_with_private_attributes p(123, 456, 789);
std::cout << at_c<0>(p) << std::endl; std::cout << at_c<0>(p) << std::endl;
std::cout << at_c<1>(p) << std::endl; std::cout << at_c<1>(p) << std::endl;
std::cout << at_c<2>(p) << std::endl;
std::cout << p << std::endl; std::cout << p << std::endl;
BOOST_TEST(p == make_vector(123, 456)); BOOST_TEST(p == make_vector(123, 456, 789));
} }
#endif #endif

View File

@ -37,19 +37,39 @@ namespace ns
{ {
int x; int x;
int y; int y;
int z;
}; };
} }
// this creates a fusion view: boost::fusion::adapted::point #if BOOST_PP_VARIADICS
BOOST_FUSION_ADAPT_STRUCT_NAMED(
ns::point, point,
(int, x)
(int, y)
)
// this creates a fusion view: ns1::s1 // this creates a fusion view: boost::fusion::adapted::point
struct s { int m; }; BOOST_FUSION_ADAPT_STRUCT_NAMED(
BOOST_FUSION_ADAPT_STRUCT_NAMED_NS(s, (ns1), s1, (int, m)) ns::point, point,
x,
y,
z
)
// this creates a fusion view: ns1::s1
struct s { int m; };
BOOST_FUSION_ADAPT_STRUCT_NAMED_NS(s, (ns1), s1, m)
#else // BOOST_PP_VARIADICS
// this creates a fusion view: boost::fusion::adapted::point
BOOST_FUSION_ADAPT_STRUCT_NAMED(
ns::point, point,
(int, x)
(int, y)
(BOOST_FUSION_ADAPT_AUTO, z)
)
// this creates a fusion view: ns1::s1
struct s { int m; };
BOOST_FUSION_ADAPT_STRUCT_NAMED_NS(s, (ns1), s1, (BOOST_FUSION_ADAPT_AUTO, m))
#endif
int int
main() main()
@ -63,31 +83,33 @@ main()
{ {
BOOST_MPL_ASSERT((traits::is_view<adapted::point>)); BOOST_MPL_ASSERT((traits::is_view<adapted::point>));
ns::point basep = {123, 456}; ns::point basep = {123, 456, 789};
adapted::point p(basep); adapted::point p(basep);
std::cout << at_c<0>(p) << std::endl; std::cout << at_c<0>(p) << std::endl;
std::cout << at_c<1>(p) << std::endl; std::cout << at_c<1>(p) << std::endl;
std::cout << at_c<2>(p) << std::endl;
std::cout << p << std::endl; std::cout << p << std::endl;
BOOST_TEST(p == make_vector(123, 456)); BOOST_TEST(p == make_vector(123, 456, 789));
at_c<0>(p) = 6; at_c<0>(p) = 6;
at_c<1>(p) = 9; at_c<1>(p) = 9;
BOOST_TEST(p == make_vector(6, 9)); at_c<2>(p) = 12;
BOOST_TEST(p == make_vector(6, 9, 12));
BOOST_STATIC_ASSERT(boost::fusion::result_of::size<adapted::point>::value == 2); BOOST_STATIC_ASSERT(boost::fusion::result_of::size<adapted::point>::value == 3);
BOOST_STATIC_ASSERT(!boost::fusion::result_of::empty<adapted::point>::value); BOOST_STATIC_ASSERT(!boost::fusion::result_of::empty<adapted::point>::value);
BOOST_TEST(front(p) == 6); BOOST_TEST(front(p) == 6);
BOOST_TEST(back(p) == 9); BOOST_TEST(back(p) == 12);
} }
{ {
fusion::vector<int, float> v1(4, 2); fusion::vector<int, float, int> v1(4, 2, 2);
ns::point p = {5, 3}; ns::point p = {5, 3, 3};
adapted::point v2(p); adapted::point v2(p);
fusion::vector<long, double> v3(5, 4); fusion::vector<long, double, int> v3(5, 4, 4);
BOOST_TEST(v1 < v2); BOOST_TEST(v1 < v2);
BOOST_TEST(v1 <= v2); BOOST_TEST(v1 <= v2);
BOOST_TEST(v2 > v1); BOOST_TEST(v2 > v1);
@ -100,17 +122,17 @@ main()
{ {
// conversion from adapted::point to vector // conversion from adapted::point to vector
ns::point basep = {5, 3}; ns::point basep = {5, 3, 3};
adapted::point p(basep); adapted::point p(basep);
fusion::vector<int, long> v(p); fusion::vector<int, long, int> v(p);
v = p; v = p;
} }
{ {
// conversion from adapted::point to list // conversion from adapted::point to list
ns::point basep = {5, 3}; ns::point basep = {5, 3, 3};
adapted::point p(basep); adapted::point p(basep);
fusion::list<int, long> l(p); fusion::list<int, long, int> l(p);
l = p; l = p;
} }

View File

@ -39,27 +39,45 @@ namespace ns
{ {
public: public:
point() : x(0), y(0) {} point() : x(0), y(0), z(0) {}
point(X x_, Y y_) : x(x_), y(y_) {} point(X x_, Y y_, int z_) : x(x_), y(y_), z(z_) {}
X get_x() const { return x; } X get_x() const { return x; }
Y get_y() const { return y; } Y get_y() const { return y; }
int get_z() const { return z; }
void set_x(X x_) { x = x_; } void set_x(X x_) { x = x_; }
void set_y(Y y_) { y = y_; } void set_y(Y y_) { y = y_; }
void set_z(int z_) { z = z_; }
private: private:
X x; X x;
Y y; Y y;
int z;
}; };
} }
BOOST_FUSION_ADAPT_TPL_ADT(
(X)(Y), #if BOOST_PP_VARIADICS
(ns::point)(X)(Y),
(X, X, obj.get_x(), obj.set_x(val)) BOOST_FUSION_ADAPT_TPL_ADT(
(Y, Y, obj.get_y(), obj.set_y(val)) (X)(Y),
) (ns::point)(X)(Y),
(X, X, obj.get_x(), obj.set_x(val))
(Y, Y, obj.get_y(), obj.set_y(val))
(obj.get_z(), obj.set_z(val))
)
#else // BOOST_PP_VARIADICS
BOOST_FUSION_ADAPT_TPL_ADT(
(X)(Y),
(ns::point)(X)(Y),
(X, X, obj.get_x(), obj.set_x(val))
(Y, Y, obj.get_y(), obj.set_y(val))
(BOOST_FUSION_ADAPT_AUTO, BOOST_FUSION_ADAPT_AUTO, obj.get_z(), obj.set_z(val))
)
#endif
int int
main() main()
@ -75,28 +93,30 @@ main()
{ {
BOOST_MPL_ASSERT_NOT((traits::is_view<point>)); BOOST_MPL_ASSERT_NOT((traits::is_view<point>));
point p(123, 456); point p(123, 456, 789);
std::cout << at_c<0>(p) << std::endl; std::cout << at_c<0>(p) << std::endl;
std::cout << at_c<1>(p) << std::endl; std::cout << at_c<1>(p) << std::endl;
std::cout << at_c<2>(p) << std::endl;
std::cout << p << std::endl; std::cout << p << std::endl;
BOOST_TEST(p == make_vector(123, 456)); BOOST_TEST(p == make_vector(123, 456, 789));
at_c<0>(p) = 6; at_c<0>(p) = 6;
at_c<1>(p) = 9; at_c<1>(p) = 9;
BOOST_TEST(p == make_vector(6, 9)); at_c<2>(p) = 12;
BOOST_TEST(p == make_vector(6, 9, 12));
BOOST_STATIC_ASSERT(boost::fusion::result_of::size<point>::value == 2); BOOST_STATIC_ASSERT(boost::fusion::result_of::size<point>::value == 3);
BOOST_STATIC_ASSERT(!boost::fusion::result_of::empty<point>::value); BOOST_STATIC_ASSERT(!boost::fusion::result_of::empty<point>::value);
BOOST_TEST(front(p) == 6); BOOST_TEST(front(p) == 6);
BOOST_TEST(back(p) == 9); BOOST_TEST(back(p) == 12);
} }
{ {
boost::fusion::vector<int, float> v1(4, 2); boost::fusion::vector<int, float, int> v1(4, 2, 2);
point v2(5, 3); point v2(5, 3, 3);
boost::fusion::vector<long, double> v3(5, 4); boost::fusion::vector<long, double, int> v3(5, 4, 4);
BOOST_TEST(v1 < v2); BOOST_TEST(v1 < v2);
BOOST_TEST(v1 <= v2); BOOST_TEST(v1 <= v2);
BOOST_TEST(v2 > v1); BOOST_TEST(v2 > v1);
@ -108,9 +128,9 @@ main()
} }
{ {
boost::fusion::vector<std::string, std::string> v1("Lincoln", "Abraham"); boost::fusion::vector<std::string, std::string, int> v1("Lincoln", "Abraham", 3);
name v2("Roosevelt", "Franklin"); name v2("Roosevelt", "Franklin", 3);
name v3("Roosevelt", "Theodore"); name v3("Roosevelt", "Theodore", 3);
BOOST_TEST(v1 < v2); BOOST_TEST(v1 < v2);
BOOST_TEST(v1 <= v2); BOOST_TEST(v1 <= v2);
BOOST_TEST(v2 > v1); BOOST_TEST(v2 > v1);
@ -123,15 +143,15 @@ main()
{ {
// conversion from point to vector // conversion from point to vector
point p(5, 3); point p(5, 3, 3);
boost::fusion::vector<int, long> v(p); boost::fusion::vector<int, long, int> v(p);
v = p; v = p;
} }
{ {
// conversion from point to list // conversion from point to list
point p(5, 3); point p(5, 3, 3);
boost::fusion::list<int, long> l(p); boost::fusion::list<int, long, int> l(p);
l = p; l = p;
} }

View File

@ -35,19 +35,40 @@ namespace ns
{ {
X x; X x;
Y y; Y y;
int z;
}; };
} }
BOOST_FUSION_ADAPT_TPL_STRUCT( #if BOOST_PP_VARIADICS
(X)(Y),
(ns::point)(X)(Y), BOOST_FUSION_ADAPT_TPL_STRUCT(
(X, x) (X)(Y),
(Y, y) (ns::point)(X)(Y),
) x,
(BOOST_FUSION_ADAPT_AUTO, y)
(int, z)
)
template<typename M>
struct s { M m; };
BOOST_FUSION_ADAPT_TPL_STRUCT((M), (s)(M), m)
#else // BOOST_PP_VARIADICS
BOOST_FUSION_ADAPT_TPL_STRUCT(
(X)(Y),
(ns::point)(X)(Y),
(X, x)
(Y, y)
(BOOST_FUSION_ADAPT_AUTO, z)
)
template<typename M>
struct s { M m; };
BOOST_FUSION_ADAPT_TPL_STRUCT((M), (s)(M), (BOOST_FUSION_ADAPT_AUTO, m))
#endif
template<typename M>
struct s { M m; };
BOOST_FUSION_ADAPT_TPL_STRUCT((M), (s)(M), (M, m))
int int
main() main()
@ -62,28 +83,30 @@ main()
{ {
BOOST_MPL_ASSERT_NOT((traits::is_view<point>)); BOOST_MPL_ASSERT_NOT((traits::is_view<point>));
point p = {123, 456}; point p = {123, 456, 789};
std::cout << at_c<0>(p) << std::endl; std::cout << at_c<0>(p) << std::endl;
std::cout << at_c<1>(p) << std::endl; std::cout << at_c<1>(p) << std::endl;
std::cout << at_c<2>(p) << std::endl;
std::cout << p << std::endl; std::cout << p << std::endl;
BOOST_TEST(p == make_vector(123, 456)); BOOST_TEST(p == make_vector(123, 456, 789));
at_c<0>(p) = 6; at_c<0>(p) = 6;
at_c<1>(p) = 9; at_c<1>(p) = 9;
BOOST_TEST(p == make_vector(6, 9)); at_c<2>(p) = 12;
BOOST_TEST(p == make_vector(6, 9, 12));
BOOST_STATIC_ASSERT(boost::fusion::result_of::size<point>::value == 2); BOOST_STATIC_ASSERT(boost::fusion::result_of::size<point>::value == 3);
BOOST_STATIC_ASSERT(!boost::fusion::result_of::empty<point>::value); BOOST_STATIC_ASSERT(!boost::fusion::result_of::empty<point>::value);
BOOST_TEST(front(p) == 6); BOOST_TEST(front(p) == 6);
BOOST_TEST(back(p) == 9); BOOST_TEST(back(p) == 12);
} }
{ {
vector<int, float> v1(4, 2); vector<int, float, int> v1(4, 2, 2);
point v2 = {5, 3}; point v2 = {5, 3, 3};
vector<long, double> v3(5, 4); vector<long, double, int> v3(5, 4, 4);
BOOST_TEST(v1 < v2); BOOST_TEST(v1 < v2);
BOOST_TEST(v1 <= v2); BOOST_TEST(v1 <= v2);
BOOST_TEST(v2 > v1); BOOST_TEST(v2 > v1);
@ -96,14 +119,14 @@ main()
{ {
// conversion from point to vector // conversion from point to vector
point p = {5, 3}; point p = {5, 3, 3};
vector<int, long> v(p); vector<int, long, int> v(p);
v = p; v = p;
} }
{ {
// conversion from point to list // conversion from point to list
point p = {5, 3}; point p = {5, 3, 3};
list<int, long> l(p); list<int, long> l(p);
l = p; l = p;
} }