123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388 |
- // (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 <boost/config.hpp>
- #include <boost/detail/workaround.hpp>
- // Boost.Test
- #include <boost/test/utils/rtti.hpp>
- #include <boost/test/utils/assign_op.hpp>
- #include <boost/type_traits/remove_reference.hpp>
- #include <boost/type_traits/remove_cv.hpp>
- #include <boost/test/detail/throw_exception.hpp>
- // Boost
- #include <boost/mpl/if.hpp>
- #include <boost/mpl/or.hpp>
- #include <boost/type_traits/is_same.hpp>
- #include <boost/type_traits/remove_cv.hpp>
- #include <boost/utility/enable_if.hpp>
- #include <boost/mpl/bool.hpp>
- #include <boost/test/detail/suppress_warnings.hpp>
- //____________________________________________________________________________//
- namespace boost {
- namespace nfp { // named function parameters
- // ************************************************************************** //
- // ************** forward declarations ************** //
- // ************************************************************************** //
- template<typename unique_id, bool required> struct keyword;
- template<typename T, typename unique_id, bool required = false> struct typed_keyword;
- template<typename T, typename unique_id, typename RefType=T&> struct named_parameter;
- template<typename NP1,typename NP2> struct named_parameter_combine;
- // ************************************************************************** //
- // ************** is_named_param_pack ************** //
- // ************************************************************************** //
- /// is_named_param_pack<T>::value is true if T is parameters pack
- template<typename T>
- struct is_named_param_pack : public mpl::false_ {};
- template<typename T, typename unique_id, typename RefType>
- struct is_named_param_pack<named_parameter<T,unique_id,RefType> > : public mpl::true_ {};
- template<typename NP, typename Rest>
- struct is_named_param_pack<named_parameter_combine<NP,Rest> > : public mpl::true_ {};
- // ************************************************************************** //
- // ************** param_type ************** //
- // ************************************************************************** //
- /// param_type<Params,Keyword,Default>::type is the type of the parameter
- /// corresponding to the Keyword (if parameter is present) or Default
- template<typename NP, typename Keyword, typename DefaultType=void>
- struct param_type
- : mpl::if_<typename is_same<typename NP::id,typename Keyword::id>::type,
- typename remove_cv<typename NP::data_type>::type,
- DefaultType> {};
- template<typename NP, typename Rest, typename Keyword, typename DefaultType>
- struct param_type<named_parameter_combine<NP,Rest>,Keyword,DefaultType>
- : mpl::if_<typename is_same<typename NP::id,typename Keyword::id>::type,
- typename remove_cv<typename NP::data_type>::type,
- typename param_type<Rest,Keyword,DefaultType>::type> {};
- // ************************************************************************** //
- // ************** has_param ************** //
- // ************************************************************************** //
- /// has_param<Params,Keyword>::value is true if Params has parameter corresponding
- /// to the Keyword
- template<typename NP, typename Keyword>
- struct has_param : is_same<typename NP::id,typename Keyword::id> {};
- template<typename NP, typename Rest, typename Keyword>
- struct has_param<named_parameter_combine<NP,Rest>,Keyword>
- : mpl::or_<typename is_same<typename NP::id,typename Keyword::id>::type,
- typename has_param<Rest,Keyword>::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<typename T>
- #if defined(__GNUC__) || defined(__HP_aCC) || defined(__EDG__) || defined(__SUNPRO_CC) || defined(BOOST_EMBTC)
- operator T() const
- #else
- operator T const&() const
- #endif
- { nfp_detail::report_access_to_invalid_parameter(true); static T* v = 0; return *v; }
- template<typename T>
- T any_cast() const
- { nfp_detail::report_access_to_invalid_parameter(true); static typename remove_reference<T>::type* v = 0; return *v; }
- template<typename Arg1>
- nil operator()( Arg1 const& )
- { nfp_detail::report_access_to_invalid_parameter(true); return nil(); }
- template<typename Arg1,typename Arg2>
- nil operator()( Arg1 const&, Arg2 const& )
- { nfp_detail::report_access_to_invalid_parameter(true); return nil(); }
- template<typename Arg1,typename Arg2,typename Arg3>
- nil operator()( Arg1 const&, Arg2 const&, Arg3 const& )
- { nfp_detail::report_access_to_invalid_parameter(true); return nil(); }
- // Visitation support
- template<typename Visitor>
- 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<typename Derived>
- struct named_parameter_base {
- template<typename NP>
- named_parameter_combine<NP,Derived>
- operator,( NP const& np ) const { return named_parameter_combine<NP,Derived>( np, *static_cast<Derived const*>(this) ); }
- };
- } // namespace nfp_detail
- // ************************************************************************** //
- // ************** named_parameter_combine ************** //
- // ************************************************************************** //
- template<typename NP, typename Rest = nil>
- struct named_parameter_combine
- : Rest
- , nfp_detail::named_parameter_base<named_parameter_combine<NP,Rest> > {
- typedef typename NP::ref_type res_type;
- typedef named_parameter_combine<NP,Rest> self_type;
- // Constructor
- named_parameter_combine( NP const& np, Rest const& r )
- : Rest( r )
- , m_param( np )
- {
- }
- // Access methods
- res_type operator[]( keyword<typename NP::id,true> kw ) const { return m_param[kw]; }
- res_type operator[]( keyword<typename NP::id,false> kw ) const { return m_param[kw]; }
- using Rest::operator[];
- bool has( keyword<typename NP::id,false> kw ) const { return m_param.has( kw ); }
- using Rest::has;
- void erase( keyword<typename NP::id,false> kw ) const { m_param.erase( kw ); }
- using Rest::erase;
- using nfp_detail::named_parameter_base<named_parameter_combine<NP,Rest> >::operator,;
- // Visitation support
- template<typename Visitor>
- void apply_to( Visitor& V ) const
- {
- m_param.apply_to( V );
- Rest::apply_to( V );
- }
- private:
- // Data members
- NP m_param;
- };
- // ************************************************************************** //
- // ************** named_parameter ************** //
- // ************************************************************************** //
- template<typename T, typename unique_id, typename RefType>
- struct named_parameter
- : nfp_detail::named_parameter_base<named_parameter<T,unique_id,RefType> >
- {
- 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<unique_id,true> ) const { return m_erased ? nil::inst().template any_cast<ref_type>() : m_value; }
- ref_type operator[]( keyword<unique_id,false> ) const { return m_erased ? nil::inst().template any_cast<ref_type>() : m_value; }
- template<typename UnknownId>
- nil operator[]( keyword<UnknownId,false> ) const { return nil::inst(); }
- bool has( keyword<unique_id,false> ) const { return !m_erased; }
- template<typename UnknownId>
- bool has( keyword<UnknownId,false> ) const { return false; }
- void erase( keyword<unique_id,false> ) const { m_erased = true; }
- template<typename UnknownId>
- void erase( keyword<UnknownId,false> ) const {}
- // Visitation support
- template<typename Visitor>
- void apply_to( Visitor& V ) const
- {
- V.set_parameter( rtti::type_id<unique_id>(), m_value );
- }
- private:
- // Data members
- ref_type m_value;
- mutable bool m_erased;
- };
- // ************************************************************************** //
- // ************** no_params ************** //
- // ************************************************************************** //
- typedef named_parameter<char, struct no_params_type_t,char> no_params_type;
- namespace {
- no_params_type no_params( '\0' );
- } // local namespace
- // ************************************************************************** //
- // ************** keyword ************** //
- // ************************************************************************** //
- template<typename unique_id, bool required = false>
- struct keyword {
- typedef unique_id id;
- template<typename T>
- named_parameter<T const,unique_id>
- operator=( T const& t ) const { return named_parameter<T const,unique_id>( t ); }
- template<typename T>
- named_parameter<T,unique_id>
- operator=( T& t ) const { return named_parameter<T,unique_id>( t ); }
- named_parameter<char const*,unique_id,char const*>
- operator=( char const* t ) const { return named_parameter<char const*,unique_id,char const*>( t ); }
- };
- //____________________________________________________________________________//
- // ************************************************************************** //
- // ************** typed_keyword ************** //
- // ************************************************************************** //
- template<typename T, typename unique_id, bool required>
- struct typed_keyword : keyword<unique_id,required> {
- named_parameter<T const,unique_id>
- operator=( T const& t ) const { return named_parameter<T const,unique_id>( t ); }
- named_parameter<T,unique_id>
- operator=( T& t ) const { return named_parameter<T,unique_id>( t ); }
- };
- //____________________________________________________________________________//
- template<typename unique_id, bool required>
- struct typed_keyword<bool,unique_id,required>
- : keyword<unique_id,required>
- , named_parameter<bool,unique_id,bool> {
- typedef unique_id id;
- typed_keyword() : named_parameter<bool,unique_id,bool>( true ) {}
- named_parameter<bool,unique_id,bool>
- operator!() const { return named_parameter<bool,unique_id,bool>( false ); }
- };
- // ************************************************************************** //
- // ************** opt_assign ************** //
- // ************************************************************************** //
- template<typename T, typename Params, typename Keyword>
- inline typename enable_if_c<!has_param<Params,Keyword>::value,void>::type
- opt_assign( T& /*target*/, Params const& /*p*/, Keyword /*k*/ )
- {
- }
- //____________________________________________________________________________//
- template<typename T, typename Params, typename Keyword>
- inline typename enable_if_c<has_param<Params,Keyword>::value,void>::type
- opt_assign( T& target, Params const& p, Keyword k )
- {
- using namespace unit_test;
- assign_op( target, p[k], static_cast<int>(0) );
- }
- // ************************************************************************** //
- // ************** opt_get ************** //
- // ************************************************************************** //
- template<typename T, typename Params, typename Keyword>
- inline T
- opt_get( Params const& p, Keyword k, T default_val )
- {
- opt_assign( default_val, p, k );
- return default_val;
- }
- // ************************************************************************** //
- // ************** opt_get ************** //
- // ************************************************************************** //
- template<typename Params, typename NP>
- inline typename enable_if_c<!has_param<Params,keyword<typename NP::id> >::value,
- named_parameter_combine<NP,Params> >::type
- opt_append( Params const& params, NP const& np )
- {
- return (params,np);
- }
- //____________________________________________________________________________//
- template<typename Params, typename NP>
- inline typename enable_if_c<has_param<Params,keyword<typename NP::id> >::value,Params>::type
- opt_append( Params const& params, NP const& )
- {
- return params;
- }
- } // namespace nfp
- } // namespace boost
- #include <boost/test/detail/enable_warnings.hpp>
- #endif // BOOST_TEST_UTILS_NAMED_PARAM
|