LCOV - code coverage report
Current view: top level - opt/homebrew/include/boost/test/utils - named_params.hpp (source / functions) Hit Total Coverage
Test: test_dash_coverage.info Lines: 35 42 83.3 %
Date: 2026-06-25 07:23:51 Functions: 581 614 94.6 %

          Line data    Source code
       1             : //  (C) Copyright Gennadiy Rozental 2001.
       2             : //  Distributed under the Boost Software License, Version 1.0.
       3             : //  (See accompanying file LICENSE_1_0.txt or copy at
       4             : //  http://www.boost.org/LICENSE_1_0.txt)
       5             : 
       6             : //  See http://www.boost.org/libs/test for the library home page.
       7             : //
       8             : //  File        : $RCSfile$
       9             : //
      10             : //  Version     : $Revision$
      11             : //
      12             : //  Description : named function parameters library
      13             : // ***************************************************************************
      14             : 
      15             : #ifndef BOOST_TEST_UTILS_NAMED_PARAM
      16             : #define BOOST_TEST_UTILS_NAMED_PARAM
      17             : 
      18             : // Boost
      19             : #include <boost/config.hpp>
      20             : #include <boost/detail/workaround.hpp>
      21             : 
      22             : // Boost.Test
      23             : #include <boost/test/utils/rtti.hpp>
      24             : #include <boost/test/utils/assign_op.hpp>
      25             : 
      26             : #include <boost/type_traits/remove_reference.hpp>
      27             : #include <boost/type_traits/remove_cv.hpp>
      28             : 
      29             : #include <boost/test/detail/throw_exception.hpp>
      30             : 
      31             : // Boost
      32             : #include <boost/mpl/if.hpp>
      33             : #include <boost/mpl/or.hpp>
      34             : #include <boost/type_traits/is_same.hpp>
      35             : #include <boost/type_traits/remove_cv.hpp>
      36             : #include <boost/utility/enable_if.hpp>
      37             : #include <boost/mpl/bool.hpp>
      38             : 
      39             : #include <boost/test/detail/suppress_warnings.hpp>
      40             : 
      41             : //____________________________________________________________________________//
      42             : 
      43             : namespace boost {
      44             : namespace nfp { // named function parameters
      45             : 
      46             : // ************************************************************************** //
      47             : // **************             forward declarations             ************** //
      48             : // ************************************************************************** //
      49             : 
      50             : template<typename unique_id, bool required>                     struct keyword;
      51             : template<typename T, typename unique_id, bool required = false> struct typed_keyword;
      52             : 
      53             : template<typename T, typename unique_id, typename RefType=T&>   struct named_parameter;
      54             : template<typename NP1,typename NP2>                             struct named_parameter_combine;
      55             : 
      56             : // ************************************************************************** //
      57             : // **************              is_named_param_pack             ************** //
      58             : // ************************************************************************** //
      59             : 
      60             : /// is_named_param_pack<T>::value is true if T is parameters pack
      61             : 
      62             : template<typename T>
      63             : struct is_named_param_pack : public mpl::false_ {};
      64             : 
      65             : template<typename T, typename unique_id, typename RefType>
      66             : struct is_named_param_pack<named_parameter<T,unique_id,RefType> > : public mpl::true_ {};
      67             : 
      68             : template<typename NP, typename Rest>
      69             : struct is_named_param_pack<named_parameter_combine<NP,Rest> > : public mpl::true_ {};
      70             : 
      71             : // ************************************************************************** //
      72             : // **************                  param_type                  ************** //
      73             : // ************************************************************************** //
      74             : 
      75             : /// param_type<Params,Keyword,Default>::type is the type of the parameter
      76             : /// corresponding to the Keyword (if parameter is present) or Default
      77             : 
      78             : template<typename NP, typename Keyword, typename DefaultType=void>
      79             : struct param_type
      80             : : mpl::if_<typename is_same<typename NP::id,typename Keyword::id>::type,
      81             :            typename remove_cv<typename NP::data_type>::type,
      82             :            DefaultType> {};
      83             : 
      84             : template<typename NP, typename Rest, typename Keyword, typename DefaultType>
      85             : struct param_type<named_parameter_combine<NP,Rest>,Keyword,DefaultType>
      86             : : mpl::if_<typename is_same<typename NP::id,typename Keyword::id>::type,
      87             :            typename remove_cv<typename NP::data_type>::type,
      88             :            typename param_type<Rest,Keyword,DefaultType>::type> {};
      89             : 
      90             : // ************************************************************************** //
      91             : // **************                  has_param                   ************** //
      92             : // ************************************************************************** //
      93             : 
      94             : /// has_param<Params,Keyword>::value is true if Params has parameter corresponding
      95             : /// to the Keyword
      96             : 
      97             : template<typename NP, typename Keyword>
      98             : struct has_param : is_same<typename NP::id,typename Keyword::id> {};
      99             : 
     100             : template<typename NP, typename Rest, typename Keyword>
     101             : struct has_param<named_parameter_combine<NP,Rest>,Keyword>
     102             : : mpl::or_<typename is_same<typename NP::id,typename Keyword::id>::type,
     103             :            typename has_param<Rest,Keyword>::type> {};
     104             : 
     105             : // ************************************************************************** //
     106             : // **************          access_to_invalid_parameter         ************** //
     107             : // ************************************************************************** //
     108             : 
     109             : namespace nfp_detail {
     110             : 
     111             : struct access_to_invalid_parameter {};
     112             : 
     113             : //____________________________________________________________________________//
     114             : 
     115             : inline void
     116           0 : report_access_to_invalid_parameter( bool v )
     117             : {
     118           0 :     BOOST_TEST_I_ASSRT( !v, access_to_invalid_parameter() );
     119           0 : }
     120             : 
     121             : } // namespace nfp_detail
     122             : 
     123             : // ************************************************************************** //
     124             : // **************                      nil                     ************** //
     125             : // ************************************************************************** //
     126             : 
     127             : struct nil {
     128             :     template<typename T>
     129             : #if defined(__GNUC__) || defined(__HP_aCC) || defined(__EDG__) || defined(__SUNPRO_CC) || defined(BOOST_EMBTC)
     130             :     operator T() const
     131             : #else
     132             :     operator T const&() const
     133             : #endif
     134             :     { nfp_detail::report_access_to_invalid_parameter(true); BOOST_TEST_UNREACHABLE_RETURN(*static_cast<T*>(0)); }
     135             : 
     136             :     template<typename T>
     137           0 :     T any_cast() const
     138           0 :     { nfp_detail::report_access_to_invalid_parameter(true); BOOST_TEST_UNREACHABLE_RETURN(*static_cast<typename std::remove_reference<T>::type*>(0)); }
     139             : 
     140             :     template<typename Arg1>
     141             :     nil operator()( Arg1 const& )
     142             :     { nfp_detail::report_access_to_invalid_parameter(true); return nil(); }
     143             : 
     144             :     template<typename Arg1,typename Arg2>
     145             :     nil operator()( Arg1 const&, Arg2 const& )
     146             :     { nfp_detail::report_access_to_invalid_parameter(true); return nil(); }
     147             : 
     148             :     template<typename Arg1,typename Arg2,typename Arg3>
     149             :     nil operator()( Arg1 const&, Arg2 const&, Arg3 const& )
     150             :     { nfp_detail::report_access_to_invalid_parameter(true); return nil(); }
     151             : 
     152             :     // Visitation support
     153             :     template<typename Visitor>
     154             :     void            apply_to( Visitor& /*v*/ ) const {}
     155             : 
     156           0 :     static nil&     inst() { static nil s_inst; return s_inst; }
     157             : private:
     158           0 :     nil() {}
     159             : };
     160             : 
     161             : // ************************************************************************** //
     162             : // **************             named_parameter_base             ************** //
     163             : // ************************************************************************** //
     164             : 
     165             : namespace nfp_detail {
     166             : 
     167             : template<typename Derived>
     168             : struct named_parameter_base {
     169             :     template<typename NP>
     170             :     named_parameter_combine<NP,Derived>
     171       18834 :     operator,( NP const& np ) const { return named_parameter_combine<NP,Derived>( np, *static_cast<Derived const*>(this) ); }
     172             : };
     173             : 
     174             : } // namespace nfp_detail
     175             : 
     176             : // ************************************************************************** //
     177             : // **************            named_parameter_combine           ************** //
     178             : // ************************************************************************** //
     179             : 
     180             : template<typename NP, typename Rest = nil>
     181             : struct named_parameter_combine
     182             : : Rest
     183             : , nfp_detail::named_parameter_base<named_parameter_combine<NP,Rest> > {
     184             :     typedef typename NP::ref_type  res_type;
     185             :     typedef named_parameter_combine<NP,Rest> self_type;
     186             : 
     187             :     // Constructor
     188       37668 :     named_parameter_combine( NP const& np, Rest const& r )
     189       18834 :     : Rest( r )
     190       18834 :     , m_param( np )
     191       18834 :     {
     192       37668 :     }
     193             : 
     194             :     // Access methods
     195             :     res_type    operator[]( keyword<typename NP::id,true> kw ) const    { return m_param[kw]; }
     196       16498 :     res_type    operator[]( keyword<typename NP::id,false> kw ) const   { return m_param[kw]; }
     197             :     using       Rest::operator[];
     198             : 
     199        7738 :     bool        has( keyword<typename NP::id,false> kw ) const          { return m_param.has( kw ); }
     200             :     using       Rest::has;
     201             : 
     202             :     void        erase( keyword<typename NP::id,false> kw ) const        { m_param.erase( kw ); }
     203             :     using       Rest::erase;
     204             : 
     205             :     using       nfp_detail::named_parameter_base<named_parameter_combine<NP,Rest> >::operator,;
     206             : 
     207             :     // Visitation support
     208             :     template<typename Visitor>
     209             :     void            apply_to( Visitor& V ) const
     210             :     {
     211             :         m_param.apply_to( V );
     212             : 
     213             :         Rest::apply_to( V );
     214             :     }
     215             : private:
     216             :     // Data members
     217             :     NP          m_param;
     218             : };
     219             : 
     220             : // ************************************************************************** //
     221             : // **************                named_parameter               ************** //
     222             : // ************************************************************************** //
     223             : 
     224             : template<typename T, typename unique_id, typename RefType>
     225             : struct named_parameter
     226             : : nfp_detail::named_parameter_base<named_parameter<T,unique_id,RefType> >
     227             : {
     228             :     typedef T               data_type;
     229             :     typedef RefType         ref_type;
     230             :     typedef unique_id       id;
     231             : 
     232             :     // Constructor
     233       49786 :     explicit        named_parameter( ref_type v )
     234       24966 :     : m_value( v )
     235       24966 :     , m_erased( false )
     236       49786 :     {}
     237      124246 :     named_parameter( named_parameter const& np )
     238       72124 :     : m_value( np.m_value )
     239       72124 :     , m_erased( np.m_erased )
     240      124246 :     {}
     241             : 
     242             :     // Access methods
     243             :     ref_type        operator[]( keyword<unique_id,true> ) const     { return m_erased ? nil::inst().template any_cast<ref_type>() :  m_value; }
     244       21170 :     ref_type        operator[]( keyword<unique_id,false> ) const    { return m_erased ? nil::inst().template any_cast<ref_type>() :  m_value; }
     245             :     template<typename UnknownId>
     246             :     nil             operator[]( keyword<UnknownId,false> ) const    { return nil::inst(); }
     247             : 
     248        8176 :     bool            has( keyword<unique_id,false> ) const           { return !m_erased; }
     249             :     template<typename UnknownId>
     250        5694 :     bool            has( keyword<UnknownId,false> ) const           { return false; }
     251             : 
     252             :     void            erase( keyword<unique_id,false> ) const         { m_erased = true; }
     253             :     template<typename UnknownId>
     254             :     void            erase( keyword<UnknownId,false> ) const         {}
     255             : 
     256             :     // Visitation support
     257             :     template<typename Visitor>
     258             :     void            apply_to( Visitor& V ) const
     259             :     {
     260             :         V.set_parameter( rtti::type_id<unique_id>(), m_value );
     261             :     }
     262             : 
     263             : private:
     264             :     // Data members
     265             :     ref_type        m_value;
     266             :     mutable bool    m_erased;
     267             : };
     268             : 
     269             : // ************************************************************************** //
     270             : // **************                   no_params                  ************** //
     271             : // ************************************************************************** //
     272             : 
     273             : typedef named_parameter<char, struct no_params_type_t,char> no_params_type;
     274             : 
     275             : namespace {
     276             : no_params_type no_params( '\0' );
     277             : } // local namespace
     278             : 
     279             : // ************************************************************************** //
     280             : // **************                    keyword                   ************** //
     281             : // ************************************************************************** //
     282             : 
     283             : template<typename unique_id, bool required = false>
     284             : struct keyword {
     285             :     typedef unique_id id;
     286             : 
     287             :     template<typename T>
     288             :     named_parameter<T const,unique_id>
     289       10512 :     operator=( T const& t ) const       { return named_parameter<T const,unique_id>( t ); }
     290             : 
     291             :     template<typename T>
     292             :     named_parameter<T,unique_id>
     293             :     operator=( T& t ) const             { return named_parameter<T,unique_id>( t ); }
     294             : 
     295             :     named_parameter<char const*,unique_id,char const*>
     296         438 :     operator=( char const* t ) const    { return named_parameter<char const*,unique_id,char const*>( t ); }
     297             : };
     298             : 
     299             : //____________________________________________________________________________//
     300             : 
     301             : // ************************************************************************** //
     302             : // **************                 typed_keyword                ************** //
     303             : // ************************************************************************** //
     304             : 
     305             : template<typename T, typename unique_id, bool required>
     306             : struct typed_keyword : keyword<unique_id,required> {
     307             :     named_parameter<T const,unique_id>
     308       13724 :     operator=( T const& t ) const       { return named_parameter<T const,unique_id>( t ); }
     309             : 
     310             :     named_parameter<T,unique_id>
     311             :     operator=( T& t ) const             { return named_parameter<T,unique_id>( t ); }
     312             : };
     313             : 
     314             : //____________________________________________________________________________//
     315             : 
     316             : template<typename unique_id, bool required>
     317             : struct typed_keyword<bool,unique_id,required>
     318             : : keyword<unique_id,required>
     319             : , named_parameter<bool,unique_id,bool> {
     320             :     typedef unique_id id;
     321             : 
     322         292 :     typed_keyword() : named_parameter<bool,unique_id,bool>( true ) {}
     323             : 
     324             :     named_parameter<bool,unique_id,bool>
     325             :     operator!() const           { return named_parameter<bool,unique_id,bool>( false ); }
     326             : };
     327             : 
     328             : // ************************************************************************** //
     329             : // **************                  opt_assign                  ************** //
     330             : // ************************************************************************** //
     331             : 
     332             : template<typename T, typename Params, typename Keyword>
     333             : inline typename enable_if_c<!has_param<Params,Keyword>::value,void>::type
     334       10220 : opt_assign( T& /*target*/, Params const& /*p*/, Keyword /*k*/ )
     335             : {
     336       10220 : }
     337             : 
     338             : //____________________________________________________________________________//
     339             : 
     340             : template<typename T, typename Params, typename Keyword>
     341             : inline typename enable_if_c<has_param<Params,Keyword>::value,void>::type
     342       18542 : opt_assign( T& target, Params const& p, Keyword k )
     343             : {
     344             :     using namespace unit_test;
     345             : 
     346       18542 :     assign_op( target, p[k], static_cast<int>(0) );
     347       18542 : }
     348             : 
     349             : // ************************************************************************** //
     350             : // **************                    opt_get                   ************** //
     351             : // ************************************************************************** //
     352             : 
     353             : template<typename T, typename Params, typename Keyword>
     354             : inline T
     355       28032 : opt_get( Params const& p, Keyword k, T default_val )
     356             : {
     357       28032 :     opt_assign( default_val, p, k );
     358             : 
     359       28032 :     return default_val;
     360             : }
     361             : 
     362             : // ************************************************************************** //
     363             : // **************                    opt_get                   ************** //
     364             : // ************************************************************************** //
     365             : 
     366             : template<typename Params, typename NP>
     367             : inline typename enable_if_c<!has_param<Params,keyword<typename NP::id> >::value,
     368             : named_parameter_combine<NP,Params> >::type
     369        6424 : opt_append( Params const& params, NP const& np )
     370             : {
     371        6424 :     return (params,np);
     372             : }
     373             : 
     374             : //____________________________________________________________________________//
     375             : 
     376             : template<typename Params, typename NP>
     377             : inline typename enable_if_c<has_param<Params,keyword<typename NP::id> >::value,Params>::type
     378        1168 : opt_append( Params const& params, NP const& )
     379             : {
     380        1168 :     return params;
     381             : }
     382             : 
     383             : } // namespace nfp
     384             : } // namespace boost
     385             : 
     386             : #include <boost/test/detail/enable_warnings.hpp>
     387             : 
     388             : #endif // BOOST_TEST_UTILS_NAMED_PARAM

Generated by: LCOV version 1.16