BOOST_FUSION_ADAPT_ASSOC_TPL_ADT

| Home | Libraries | People | FAQ | More

### BOOST_FUSION_ADAPT_ASSOC_TPL_ADT

BOOST_FUSION_ADAPT_ASSOC_TPL_ADT is a macro than can be used to generate all the necessary boilerplate to adapt an arbitrary template class type as a model of Random Access Sequence and Associative Sequence.

##### Synopsis

    BOOST_FUSION_ADAPT_ASSOC_TPL_ADT(
        (template_param0)(template_param1)...,
        (type_name) (specialization_param0)(specialization_param1)...,
        ([attribute_type0, attribute_const_type0,] get_expr0, set_expr0, key_type0)
        ([attribute_type1, attribute_const_type1,] get_expr1, set_expr1, key_type1)
        ...
        )

##### Expression Semantics

The above macro generates the necessary code to adapt `type_name` or an arbitrary specialization of `type_name` as a model of Random Access Sequence and Associative Sequence. The sequence `(template_param0)(template_param1)...` declares the names of the template type parameters used. The sequence `(specialization_param0)(specialization_param1)...` declares the template parameters of the actual specialization of `type_name` that is adapted as a fusion sequence. The sequence of `([attribute_typeN, attribute_const_typeN,` get_exprN, set_exprN, key_typeN)] 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. `get_exprN` is the expression that is invoked to get the Nth element 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 instance of `type_name`. `attribute_typeN` and `attribute_const_typeN` may specify the types that `get_exprN` denotes to, when omitted the type is deduced from [get_exprN] return type via BOOST_TYPEOF. On compiler missing support for variadic macros auto can be used to avoid repeating the type. `set_exprN` is the expression that is invoked to set the Nth element of an instance of `type_name`. This expression may access variables named `obj` of type `type_name&`, which represent the corresponding instance of `type_name`, and `val` of an arbitrary const-qualified reference template type parameter `Val`, which represents the right operand of the assignment expression.

The actual return type of fusion's intrinsic sequence access (meta-)functions when in invoked with (an instance of) `type_name` is a proxy type. This type is implicitly convertible to the attribute type via `get_exprN` and forwards assignment to the underlying element via `set_exprN`. The value type (that is the type returned by `result_of::value_of`, `result_of::value_of_data`, `result_of::value_at`, `result_of::value_at_c` and `result_of::value_at_key`) of the Nth element is `attribute_typeN` with const-qualifier and reference removed.

The macro should be used at global scope, and `type_name` should be the fully namespace qualified name of the template class type to be adapted.

##### Header

    #include <boost/fusion/adapted/adt/adapt_assoc_adt.hpp>
    #include <boost/fusion/include/adapt_assoc_adt.hpp>

##### Example

    namespace demo
    {
        template<typename Name, typename Age>
        struct employee
        {
        private:
            Name name;
            Age age;

        public:
            void set_name(Name const& n)
            {
                name=n;
            }

            void set_age(Age const& a)
            {
                age=a;
            }

            Name const& get_name()const
            {
                return name;
            }

            Age const& get_age()const
            {
                return age;
            }
        };
    }

    namespace keys
    {
        struct name;
        struct age;
    }

    BOOST_FUSION_ADAPT_ASSOC_TPL_ADT(
        (Name)(Age),
        (demo::employee) (Name)(Age),
        (Name const&, Name const&, obj.get_name(), obj.set_name(val), keys::name)
        (Age const&, Age const&, obj.get_age(), obj.set_age(val), keys::age))

    demo::employee<std::string, int> e;
    at_key<keys::name>(e)="Edward Norton";
    at_key<keys::age>(e)=41;
    //Prints 'Edward Norton is 41 years old'
    std::cout << e.get_name() << " is " << e.get_age() << " years old" << std::endl;

##### See also

`adt_attribute_proxy`