// (C) Copyright Gennadiy Rozental 2001. // 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) // See http://www.boost.org/libs/test for the library home page. // // File : $RCSfile$ // // Version : $Revision$ // // Description : named function parameters library // *************************************************************************** #ifndef BOOST_TEST_UTILS_NAMED_PARAM #define BOOST_TEST_UTILS_NAMED_PARAM // Boost #include #include // Boost.Test #include #include #include #include #include // Boost #include #include #include #include #include #include #include //____________________________________________________________________________// namespace boost { namespace nfp { // named function parameters // ************************************************************************** // // ************** forward declarations ************** // // ************************************************************************** // template struct keyword; template struct typed_keyword; template struct named_parameter; template struct named_parameter_combine; // ************************************************************************** // // ************** is_named_param_pack ************** // // ************************************************************************** // /// is_named_param_pack::value is true if T is parameters pack template struct is_named_param_pack : public mpl::false_ {}; template struct is_named_param_pack > : public mpl::true_ {}; template struct is_named_param_pack > : public mpl::true_ {}; // ************************************************************************** // // ************** param_type ************** // // ************************************************************************** // /// param_type::type is is the type of the parameter /// corresponding to the Keyword (if parameter is present) or Default template struct param_type : mpl::if_::type, typename remove_cv::type, DefaultType> {}; template struct param_type,Keyword,DefaultType> : mpl::if_::type, typename remove_cv::type, typename param_type::type> {}; // ************************************************************************** // // ************** has_param ************** // // ************************************************************************** // /// has_param::value is true id Params has parameter corresponding /// to the Keyword template struct has_param : is_same {}; template struct has_param,Keyword> : mpl::or_::type, typename has_param::type> {}; // ************************************************************************** // // ************** access_to_invalid_parameter ************** // // ************************************************************************** // namespace nfp_detail { struct access_to_invalid_parameter {}; //____________________________________________________________________________// inline void report_access_to_invalid_parameter( bool v ) { BOOST_TEST_I_ASSRT( !v, access_to_invalid_parameter() ); } } // namespace nfp_detail // ************************************************************************** // // ************** nil ************** // // ************************************************************************** // struct nil { template #if defined(__GNUC__) || defined(__HP_aCC) || defined(__EDG__) || defined(__SUNPRO_CC) operator T() const #else operator T const&() const #endif { nfp_detail::report_access_to_invalid_parameter(true); static T* v = 0; return *v; } template T any_cast() const { nfp_detail::report_access_to_invalid_parameter(true); static typename remove_reference::type* v = 0; return *v; } template nil operator()( Arg1 const& ) { nfp_detail::report_access_to_invalid_parameter(true); return nil(); } template nil operator()( Arg1 const&, Arg2 const& ) { nfp_detail::report_access_to_invalid_parameter(true); return nil(); } template nil operator()( Arg1 const&, Arg2 const&, Arg3 const& ) { nfp_detail::report_access_to_invalid_parameter(true); return nil(); } // Visitation support template void apply_to( Visitor& /*v*/ ) const {} static nil& inst() { static nil s_inst; return s_inst; } private: nil() {} }; // ************************************************************************** // // ************** named_parameter_base ************** // // ************************************************************************** // namespace nfp_detail { template struct named_parameter_base { template named_parameter_combine operator,( NP const& np ) const { return named_parameter_combine( np, *static_cast(this) ); } }; } // namespace nfp_detail // ************************************************************************** // // ************** named_parameter_combine ************** // // ************************************************************************** // template struct named_parameter_combine : Rest , nfp_detail::named_parameter_base > { typedef typename NP::ref_type res_type; typedef named_parameter_combine self_type; // Constructor named_parameter_combine( NP const& np, Rest const& r ) : Rest( r ) , m_param( np ) { } // Access methods res_type operator[]( keyword kw ) const { return m_param[kw]; } res_type operator[]( keyword kw ) const { return m_param[kw]; } using Rest::operator[]; bool has( keyword kw ) const { return m_param.has( kw ); } using Rest::has; void erase( keyword kw ) const { m_param.erase( kw ); } using Rest::erase; using nfp_detail::named_parameter_base >::operator,; // Visitation support template void apply_to( Visitor& V ) const { m_param.apply_to( V ); Rest::apply_to( V ); } private: // Data members NP m_param; }; // ************************************************************************** // // ************** named_parameter ************** // // ************************************************************************** // template struct named_parameter : nfp_detail::named_parameter_base > { typedef T data_type; typedef RefType ref_type; typedef unique_id id; // Constructor explicit named_parameter( ref_type v ) : m_value( v ) , m_erased( false ) {} named_parameter( named_parameter const& np ) : m_value( np.m_value ) , m_erased( np.m_erased ) {} // Access methods ref_type operator[]( keyword ) const { return m_erased ? nil::inst().template any_cast() : m_value; } ref_type operator[]( keyword ) const { return m_erased ? nil::inst().template any_cast() : m_value; } template nil operator[]( keyword ) const { return nil::inst(); } bool has( keyword ) const { return !m_erased; } template bool has( keyword ) const { return false; } void erase( keyword ) const { m_erased = true; } template void erase( keyword ) const {} // Visitation support template void apply_to( Visitor& V ) const { V.set_parameter( rtti::type_id(), m_value ); } private: // Data members ref_type m_value; mutable bool m_erased; }; // ************************************************************************** // // ************** no_params ************** // // ************************************************************************** // typedef named_parameter no_params_type; namespace { no_params_type no_params( '\0' ); } // local namespace // ************************************************************************** // // ************** keyword ************** // // ************************************************************************** // template struct keyword { typedef unique_id id; template named_parameter operator=( T const& t ) const { return named_parameter( t ); } template named_parameter operator=( T& t ) const { return named_parameter( t ); } named_parameter operator=( char const* t ) const { return named_parameter( t ); } }; //____________________________________________________________________________// // ************************************************************************** // // ************** typed_keyword ************** // // ************************************************************************** // template struct typed_keyword : keyword { named_parameter operator=( T const& t ) const { return named_parameter( t ); } named_parameter operator=( T& t ) const { return named_parameter( t ); } }; //____________________________________________________________________________// template struct typed_keyword : keyword , named_parameter { typedef unique_id id; typed_keyword() : named_parameter( true ) {} named_parameter operator!() const { return named_parameter( false ); } }; // ************************************************************************** // // ************** opt_assign ************** // // ************************************************************************** // template inline typename enable_if_c::value,void>::type opt_assign( T& /*target*/, Params const& /*p*/, Keyword /*k*/ ) { } //____________________________________________________________________________// template inline typename enable_if_c::value,void>::type opt_assign( T& target, Params const& p, Keyword k ) { using namespace unit_test; assign_op( target, p[k], static_cast(0) ); } // ************************************************************************** // // ************** opt_get ************** // // ************************************************************************** // template inline T opt_get( Params const& p, Keyword k, T default_val ) { opt_assign( default_val, p, k ); return default_val; } // ************************************************************************** // // ************** opt_get ************** // // ************************************************************************** // template inline typename enable_if_c >::value, named_parameter_combine >::type opt_append( Params const& params, NP const& np ) { return (params,np); } //____________________________________________________________________________// template inline typename enable_if_c >::value,Params>::type opt_append( Params const& params, NP const& ) { return params; } } // namespace nfp } // namespace boost #include #endif // BOOST_TEST_UTILS_NAMED_PARAM