Boost logo

Boost :

From: Gennadiy Rozental (rogeeff_at_[hidden])
Date: 2002-05-04 15:27:25


Hi,

Since nobody wanted to take responsibility to do this and I need this for
smart_ptr, I spent some time and took named template parameters
implementation out of iterator adaptor details. I made couple changes also
to make it generic component. Here short usage decryption for those
unfamiliar with iterator adaptor internals.

To use named template parameters with your class you should:

1. Define distinguishable tags for each named parameter, like this:
struct arg1_tag {};
...

2. Use boost::ntp::default_argument as a default parameter, like this:
template <typename Arg1 = boost::ntp::default_argument,
                typename Arg2 = boost::ntp::default_argument>
struct test_type
{
....

3. Form an associative list out of the template parameters. Use
boost::ntp::cons_type as a building block for the list. Use
boost::ntp::make_arg as the list value generator. It expects two parameters:
argument tag and supplied argument value. If the argument is a normal
parameter (not named) then make_arg creates a key-value pair. If the
argument is a named parameter, then make_arg extracts the key-value pair
defined inside the named parameter.

    typedef boost::ntp::cons_type<typename boost::ntp::make_arg<arg1_tag,
Arg1>::type,
                boost::ntp::cons_type<typename
boost::ntp::make_arg<arg2_tag, Arg2>::type,
                boost::ntp::end_of_list> > arg_list;

4. Use boost::ntp::find_param algorithm to search the list for particular
parameters. It expects two parameters: list itself and searched argument
tag.
    typedef typename boost::ntp::find_param<arg_list, arg1_tag>::type Arg1_;
    typedef typename boost::ntp::find_param<arg_list, arg2_tag>::type Arg2_;

5. Use boost::ntp::resolve_default to compute the defaults if necessary.
resolve_default expects 2 required arguments: found by find param argument
type and argument tag; and 2 optional arguments that will be passed to
default value generator if necessary.
    typedef typename boost::ntp::resolve_default<Arg1_,arg1_tag>::type
arg1_type;
    typedef typename boost::ntp::resolve_default<Arg2_,arg2_tag,char>::type
arg2_type;

6. Define parameters specificators. It should inherit boost::ntp::base and
use boost::ntp::cons_type to define pair of argument key and argument value,
like this:
template <class Arg1>
struct arg1_is : public boost::ntp::base
{
    typedef boost::ntp::cons_type<arg1_tag, Arg1> type;
};

7. Define default value generator for each argument. It should include class
template default_is with two optional template parameters, that could be
ignored if not used
struct arg1_default_value_generator
{
    template<typename GenParam1,typename GenParam2>
    struct default_is
    {
        typedef char type;
    };
};

8. Connect default value generators by specializing class template
boost::ntp::default_generator for every argument tag, like this:

namespace boost { namespace ntp {
template<> struct default_generator<arg1_tag> { typedef
arg1_default_value_generator type; };
}}

That's it. Step 1 should be done before class specification. Steps 2-5
inside class specification. Steps 6-8 could be done after class
specification

Example usage will look like this:
test_type<> - the same as
test_type<char,std::pair<char,int> >
test_type<arg1_is<float> > - the same as
test_type<float,std::pair<char,int> >
test_type<arg2_is<float> > - the same as
test_type<char,float>
test_type<arg2_is<float>, arg1_is<void*> > - the same as
test_type<void*,float>

Implementation and example are located here:
http://groups.yahoo.com/group/boost/files/Policy%20based%20smart_ptr/

Regards,

Gennadiy.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk