FEATURE: Type deduction for BOOST_FUSION_ADAPT_STRUCT_C_BASE, with preliminary support for providing or deducing the type.

This commit is contained in:
Damien Buhl (alias daminetreg)
2014-05-09 13:25:38 +02:00
parent 3ca94f5762
commit 7e1c6cdf47
3 changed files with 64 additions and 9 deletions

View File

@ -6,12 +6,16 @@
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#define BOOST_PP_VARIADICS 1
#ifndef BOOST_FUSION_ADAPTED_STRUCT_ADAPT_STRUCT_HPP
#define BOOST_FUSION_ADAPTED_STRUCT_ADAPT_STRUCT_HPP
#include <boost/fusion/support/config.hpp>
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/empty.hpp>
#include <boost/preprocessor/variadic/to_seq.hpp>
#include <boost/preprocessor/variadic/size.hpp>
#include <boost/type_traits/add_reference.hpp>
#include <boost/type_traits/is_const.hpp>
#include <boost/type_traits/add_const.hpp>
@ -41,6 +45,15 @@
BOOST_FUSION_ADAPT_STRUCT_C_BASE( \
TEMPLATE_PARAMS_SEQ,NAME_SEQ,I,BOOST_PP_EMPTY,ATTRIBUTE,2)
#define BOOST_FUSION_ADAPT_STRUCT_C_AUTO(TEMPLATE_PARAMS_SEQ, NAME_SEQ, I, ATTRIBUTE) \
BOOST_FUSION_ADAPT_STRUCT_C_BASE( \
TEMPLATE_PARAMS_SEQ, \
NAME_SEQ, \
I, \
BOOST_PP_EMPTY, \
ATTRIBUTE, \
1)
#define BOOST_FUSION_ADAPT_TPL_STRUCT(TEMPLATE_PARAMS_SEQ,NAME_SEQ, ATTRIBUTES) \
BOOST_FUSION_ADAPT_STRUCT_BASE( \
(1)TEMPLATE_PARAMS_SEQ, \
@ -60,6 +73,34 @@
BOOST_PP_CAT(BOOST_FUSION_ADAPT_STRUCT_FILLER_0(0,0)ATTRIBUTES,_END), \
BOOST_FUSION_ADAPT_STRUCT_C)
#define BOOST_FUSION_ADAPT_STRUCT_FILLER_NEWAPI__0(...) \
((__VA_ARGS__)) BOOST_FUSION_ADAPT_STRUCT_FILLER_NEWAPI__1
#define BOOST_FUSION_ADAPT_STRUCT_FILLER_NEWAPI__1(...) \
((__VA_ARGS__)) BOOST_FUSION_ADAPT_STRUCT_FILLER_NEWAPI__0
#define BOOST_FUSION_ADAPT_STRUCT_FILLER_NEWAPI__0_END
#define BOOST_FUSION_ADAPT_STRUCT_FILLER_NEWAPI__1_END
#define BOOST_FUSION_ADAPT_STRUCT_NEWAPI(NAME, ATTRIBUTES) \
BOOST_FUSION_ADAPT_STRUCT_BASE( \
(0), \
(0)(NAME), \
struct_tag, \
0, \
BOOST_PP_CAT(BOOST_FUSION_ADAPT_STRUCT_FILLER_NEWAPI__0(0,0)ATTRIBUTES,_END), \
BOOST_FUSION_ADAPT_STRUCT_C_AUTO)
#define BOOST_FUSION_ADAPT_STRUCT_AS_VIEW(NAME, ATTRIBUTES) \
BOOST_FUSION_ADAPT_STRUCT_BASE( \
(0), \

View File

@ -31,6 +31,9 @@
#include <boost/mpl/identity.hpp>
#include <boost/type_traits/add_const.hpp>
#include <boost/typeof/typeof.hpp>
#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_EMPTY()
@ -55,6 +58,13 @@
BOOST_FUSION_ADAPT_STRUCT_UNPACK_TEMPLATE_PARAMS_IMPL, \
BOOST_PP_TUPLE_EAT(1))(SEQ)
#define BOOST_FUSION_ATTRIBUTE_TYPE_DEDUCE(NAME_SEQ, ATTRIBUTE, ATTRIBUTE_TUPEL_SIZE)\
BOOST_TYPEOF(BOOST_FUSION_ADAPT_STRUCT_UNPACK_NAME(NAME_SEQ)::BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPEL_SIZE, 0, ATTRIBUTE) \
)
#define BOOST_FUSION_GET_GIVEN_TYPE(NAME_SEQ, ATTRIBUTE, ATTRIBUTE_TUPEL_SIZE) \
BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPEL_SIZE, 0, ATTRIBUTE)
#ifdef BOOST_NO_PARTIAL_SPECIALIZATION_IMPLICIT_DEFAULT_ARGS
# define BOOST_FUSION_ADAPT_STRUCT_TAG_OF_SPECIALIZATION( \
MODIFIER, TEMPLATE_PARAMS_SEQ, NAME_SEQ, TAG) \
@ -118,7 +128,9 @@
> \
{ \
typedef \
BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPEL_SIZE, 0, ATTRIBUTE) \ //TODO: DAM Typeof can be added here
BOOST_PP_IF(BOOST_PP_LESS(/*ATTRIBUTE_TUPEL_SIZE*/1,2), \
BOOST_FUSION_ATTRIBUTE_TYPE_DEDUCE, BOOST_FUSION_GET_GIVEN_TYPE \
)(NAME_SEQ, ATTRIBUTE, ATTRIBUTE_TUPEL_SIZE) \
attribute_type; \
BOOST_FUSION_ADAPT_STRUCT_MSVC_REDEFINE_TEMPLATE_PARAMS( \
TEMPLATE_PARAMS_SEQ) \
@ -143,7 +155,9 @@
call(Seq& seq) \
{ \
return seq.PREFIX() \
BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPEL_SIZE, 1, ATTRIBUTE); \
BOOST_PP_TUPLE_ELEM(ATTRIBUTE_TUPEL_SIZE, \
BOOST_PP_IF(BOOST_PP_LESS(ATTRIBUTE_TUPEL_SIZE,2), 0, 1),\
ATTRIBUTE); \
} \
}; \
}; \

View File

@ -56,22 +56,22 @@ namespace ns
#endif
}
BOOST_FUSION_ADAPT_STRUCT(
BOOST_FUSION_ADAPT_STRUCT_NEWAPI(
ns::point,
(int, x)
(int, y)
(x)
(y)
)
#if !BOOST_WORKAROUND(__GNUC__,<4)
BOOST_FUSION_ADAPT_STRUCT(
BOOST_FUSION_ADAPT_STRUCT_NEWAPI(
ns::point_with_private_attributes,
(int, x)
(int, y)
(x)
(y)
)
#endif
struct s { int m; };
BOOST_FUSION_ADAPT_STRUCT(s, (int, m))
BOOST_FUSION_ADAPT_STRUCT_NEWAPI(s, (m))
int
main()