Boost logo

Boost :

From: Gennadiy Rozental (gennadiy.rozental_at_[hidden])
Date: 2004-11-20 20:26:52


> 4. Non-optional parameters
>
> The only 'bad' thing about runtime checking is that for required
parameters
> fact that one is missing better be detected at compile time (Note that I
> don't consider runtime reports that awful either). I believe the solution
> could be (if necessary) to separate notion of required and optional
> parameters, by adding template parameter is_required to template keyword.

Just for the hell of it, here is the version (65 lines) that gives compile
time errors on required parameters and runtime time errors for optional.

template<typename NP1,typename NP2> struct named_parameter_combine;
template<typename T, typename unique_id> struct named_parameter;
template<typename unique_id,bool optional> struct keyword;

struct nil {
    template<typename T> operator T() { throw "access_to_invalid_parameter";
return *(T*)0; }
};

template<typename Derived>
struct named_parameter_base {
    template<typename NP>
    named_parameter_combine<NP,Derived>
    operator,( NP const& np ) { return
named_parameter_combine<NP,Derived>( np, *static_cast<Derived*>(this) ); }
};

template <class NP, class Rest = nil>
struct named_parameter_combine : Rest,
named_parameter_base<named_parameter_combine<NP,Rest> > {
    named_parameter_combine(NP const& np, Rest const& r )
    : Rest( r ), m_param( np ) {}

    typename NP::data_type const& operator[]( keyword<typename NP::id,true>
kw ) const { return m_param[kw]; }
    typename NP::data_type const& operator[]( keyword<typename NP::id,false>
kw ) const { return m_param[kw]; }
    using Rest::operator[];
    template<typename UnknownId>
    nil operator[]( keyword<UnknownId,true> kw ) const { return nil(); }

    bool is_present( keyword<typename NP::id,true> ) const { return true; }
    using Rest::is_present;
    template<typename UnknownId>
    bool is_present( keyword<UnknownId,true> ) const { return false; }

    using named_parameter_base<named_parameter_combine<NP,Rest>
>::operator,;

    NP m_param;
};

template<typename T, typename unique_id>
struct named_parameter : named_parameter_base<named_parameter<T, unique_id>
> {
    typedef T data_type;
    typedef unique_id id;

    explicit named_parameter( T const& v ) : m_value( v ) {}

    T const& operator[]( keyword<unique_id,true> ) const { return m_value; }
    T const& operator[]( keyword<unique_id,false> ) const { return
m_value; }
    bool is_present( keyword<unique_id,true> ) const { return true; }

    T const& m_value;
};

template<typename unique_id,bool optional = true>
struct keyword {
    typedef unique_id id;

    template<typename T>
    named_parameter<T,unique_id>
    operator=( T const& t ) const { return named_parameter<T,unique_id>(
t ); }
};

template<typename T, typename unique_id,bool optional = true>
struct typed_keyword : keyword<unique_id,optional> {
    named_parameter<T,unique_id>
    operator=( T const& t ) const { return named_parameter<T,unique_id>(
t ); }
};

Gennadiy


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