// Copyright Daniel Wallin, David Abrahams 2005. // Copyright Cromwell D. Enage 2017. // 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) #ifndef BOOST_PARAMETER_TAGGED_ARGUMENT_050328_HPP #define BOOST_PARAMETER_TAGGED_ARGUMENT_050328_HPP namespace boost { namespace parameter { namespace aux { struct error_const_lvalue_bound_to_out_parameter; struct error_lvalue_bound_to_consume_parameter; struct error_rvalue_bound_to_out_parameter; }}} // namespace boost::parameter::aux #include #include #include #include #include #if defined(BOOST_PARAMETER_CAN_USE_MP11) #include #include #include #endif namespace boost { namespace parameter { namespace aux { template #if defined(BOOST_PARAMETER_CAN_USE_MP11) using tagged_argument_type = ::boost::mp11::mp_if< ::boost::mp11::mp_if< ::std::is_scalar , ::boost::mp11::mp_false , ::std::is_same< typename Keyword::qualifier , ::boost::parameter::consume_reference > > , ::boost::parameter::aux::error_lvalue_bound_to_consume_parameter , ::boost::mp11::mp_if< ::std::is_const , ::boost::mp11::mp_if< ::std::is_same< typename Keyword::qualifier , ::boost::parameter::out_reference > , ::boost::parameter::aux ::error_const_lvalue_bound_to_out_parameter , ::std::remove_const > , ::boost::mp11::mp_identity > >; #else // !defined(BOOST_PARAMETER_CAN_USE_MP11) struct tagged_argument_type : ::boost::mpl::eval_if< ::boost::is_same< typename Keyword::qualifier , ::boost::parameter::out_reference > , ::boost::parameter::aux::error_const_lvalue_bound_to_out_parameter , ::boost::remove_const > { }; #endif // BOOST_PARAMETER_CAN_USE_MP11 }}} // namespace boost::parameter::aux #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if defined(BOOST_NO_CXX11_HDR_FUNCTIONAL) #include #else #include #endif #if defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING) #include #include namespace boost { namespace parameter { namespace aux { // Holds an lvalue reference to an argument of type Arg associated with // keyword Keyword template class tagged_argument : public ::boost::parameter::aux::tagged_argument_base { #if defined(BOOST_PARAMETER_CAN_USE_MP11) using arg_type = typename ::boost::parameter::aux ::tagged_argument_type::type; #else typedef typename ::boost::mpl::eval_if< typename ::boost::mpl::eval_if< ::boost::is_scalar , ::boost::mpl::false_ , ::boost::is_same< typename Keyword::qualifier , ::boost::parameter::consume_reference > >::type , ::boost::parameter::aux::error_lvalue_bound_to_consume_parameter , ::boost::mpl::eval_if< ::boost::is_const , ::boost::parameter::aux::tagged_argument_type , ::boost::mpl::identity > >::type arg_type; #endif // BOOST_PARAMETER_CAN_USE_MP11 public: typedef Keyword key_type; // Wrap plain (non-UDT) function objects in either // a boost::function or a std::function. -- Cromwell D. Enage #if defined(BOOST_PARAMETER_CAN_USE_MP11) using value_type = ::boost::mp11::mp_if< ::std::is_function , ::std::function , Arg >; #else // !defined(BOOST_PARAMETER_CAN_USE_MP11) typedef typename ::boost::mpl::if_< ::boost::is_function #if defined(BOOST_NO_CXX11_HDR_FUNCTIONAL) , ::boost::function #else , ::std::function #endif , Arg >::type value_type; #endif // BOOST_PARAMETER_CAN_USE_MP11 // If Arg is void_, then this type will evaluate to void_&. If the // supplied argument is a plain function, then this type will evaluate // to a reference-to-const function wrapper type. If the supplied // argument is an lvalue, then Arg will be deduced to the lvalue // reference. -- Cromwell D. Enage #if defined(BOOST_PARAMETER_CAN_USE_MP11) using reference = ::boost::mp11::mp_if< ::std::is_function , value_type const& , Arg& >; #else typedef typename ::boost::mpl::if_< ::boost::is_function , value_type const& , Arg& >::type reference; #endif private: // Store plain functions by value, everything else by reference. // -- Cromwell D. Enage #if defined(BOOST_PARAMETER_CAN_USE_MP11) ::boost::mp11::mp_if< ::std::is_function , value_type , reference > value; #else typename ::boost::mpl::if_< ::boost::is_function , value_type , reference >::type value; #endif public: inline explicit BOOST_CONSTEXPR tagged_argument(reference x) : value(x) { } inline BOOST_CONSTEXPR tagged_argument(tagged_argument const& copy) : value(copy.value) { } // A metafunction class that, given a keyword and a default type, // returns the appropriate result type for a keyword lookup given // that default. struct binding { template struct apply : ::boost::mpl::eval_if< ::boost::is_same , ::boost::mpl::if_ , ::boost::mpl::identity > { }; #if defined(BOOST_PARAMETER_CAN_USE_MP11) template using fn = ::boost::mp11::mp_if< ::std::is_same , ::boost::mp11::mp_if , Default >; #endif }; #if !defined(BOOST_PARAMETER_CAN_USE_MP11) // Comma operator to compose argument list without using parameters<>. // Useful for argument lists with undetermined length. template inline BOOST_CONSTEXPR ::boost::parameter::aux::arg_list< ::boost::parameter::aux::tagged_argument , ::boost::parameter::aux::arg_list< ::boost::parameter::aux::tagged_argument > > operator,( ::boost::parameter::aux ::tagged_argument const& x ) const { return ::boost::parameter::aux::arg_list< ::boost::parameter::aux::tagged_argument , ::boost::parameter::aux::arg_list< ::boost::parameter::aux::tagged_argument > >( *this , ::boost::parameter::aux::arg_list< ::boost::parameter::aux::tagged_argument >(x, ::boost::parameter::aux::empty_arg_list()) ); } template inline BOOST_CONSTEXPR ::boost::parameter::aux::arg_list< ::boost::parameter::aux::tagged_argument , ::boost::parameter::aux::arg_list< ::boost::parameter::aux::tagged_argument_rref > > operator,( ::boost::parameter::aux ::tagged_argument_rref const& x ) const { return ::boost::parameter::aux::arg_list< ::boost::parameter::aux::tagged_argument , boost::parameter::aux::arg_list< boost::parameter::aux::tagged_argument_rref > >( *this , ::boost::parameter::aux::arg_list< ::boost::parameter::aux ::tagged_argument_rref >(x, ::boost::parameter::aux::empty_arg_list()) ); } #endif // BOOST_PARAMETER_CAN_USE_MP11 // Accessor interface. inline BOOST_CONSTEXPR reference get_value() const { return this->value; } inline BOOST_CONSTEXPR reference operator[](::boost::parameter::keyword const&) const { return this->get_value(); } template inline BOOST_CONSTEXPR reference operator[]( ::boost::parameter::aux::default_ const& ) const { return this->get_value(); } template inline BOOST_CONSTEXPR reference operator[]( ::boost::parameter::aux::lazy_default const& ) const { return this->get_value(); } template inline BOOST_CONSTEXPR Default& operator[]( ::boost::parameter::aux::default_ const& x ) const { return x.value; } template inline BOOST_CONSTEXPR Default&& operator[]( ::boost::parameter::aux::default_r_ const& x ) const { return ::std::forward(x.value); } template inline BOOST_CONSTEXPR typename ::boost::parameter::aux::result_of0::type operator[]( ::boost::parameter::aux::lazy_default const& x ) const { return x.compute_default(); } template static BOOST_CONSTEXPR typename ParameterRequirements::has_default satisfies(ParameterRequirements*); template static BOOST_CONSTEXPR typename ::boost::mpl::apply_wrap1::type satisfies( ::boost::parameter::aux::parameter_requirements< key_type , Predicate , HasDefault >* ); // MPL sequence support // Convenience for users typedef ::boost::parameter::aux::tagged_argument type; // For the benefit of iterators typedef ::boost::parameter::aux::empty_arg_list tail_type; // For dispatching to sequence intrinsics typedef ::boost::parameter::aux::arg_list_tag tag; }; #if defined(BOOST_PARAMETER_CAN_USE_MP11) template using tagged_argument_rref_key = ::boost::mp11::mp_if< ::std::is_same< typename Keyword::qualifier , ::boost::parameter::out_reference > , ::boost::parameter::aux::error_rvalue_bound_to_out_parameter , ::boost::mp11::mp_identity >; #endif // Holds an rvalue reference to an argument of type Arg associated with // keyword Keyword template struct tagged_argument_rref : ::boost::parameter::aux::tagged_argument_base { #if defined(BOOST_PARAMETER_CAN_USE_MP11) using key_type = typename ::boost::parameter::aux ::tagged_argument_rref_key::type; #else typedef typename ::boost::mpl::eval_if< ::boost::is_same< typename Keyword::qualifier , ::boost::parameter::out_reference > , ::boost::parameter::aux::error_rvalue_bound_to_out_parameter , ::boost::mpl::identity >::type key_type; #endif typedef Arg value_type; typedef Arg&& reference; private: reference value; public: inline explicit BOOST_CONSTEXPR tagged_argument_rref(reference x) : value(::std::forward(x)) { } inline BOOST_CONSTEXPR tagged_argument_rref( tagged_argument_rref const& copy ) : value(::std::forward(copy.value)) { } // A metafunction class that, given a keyword and a default type, // returns the appropriate result type for a keyword lookup given // that default. struct binding { template struct apply { typedef typename ::boost::mpl::eval_if< ::boost::is_same , ::boost::mpl::if_ , ::boost::mpl::identity >::type type; }; #if defined(BOOST_PARAMETER_CAN_USE_MP11) template using fn = ::boost::mp11::mp_if< ::std::is_same , ::boost::mp11::mp_if , Default >; #endif }; #if !defined(BOOST_PARAMETER_CAN_USE_MP11) // Comma operator to compose argument list without using parameters<>. // Useful for argument lists with undetermined length. template inline BOOST_CONSTEXPR ::boost::parameter::aux::arg_list< ::boost::parameter::aux::tagged_argument_rref , ::boost::parameter::aux::arg_list< ::boost::parameter::aux::tagged_argument > > operator,( ::boost::parameter::aux ::tagged_argument const& x ) const { return boost::parameter::aux::arg_list< ::boost::parameter::aux::tagged_argument_rref , ::boost::parameter::aux::arg_list< ::boost::parameter::aux::tagged_argument > >( *this , ::boost::parameter::aux::arg_list< ::boost::parameter::aux::tagged_argument >(x, ::boost::parameter::aux::empty_arg_list()) ); } template inline BOOST_CONSTEXPR ::boost::parameter::aux::arg_list< ::boost::parameter::aux::tagged_argument_rref , ::boost::parameter::aux::arg_list< ::boost::parameter::aux::tagged_argument_rref > > operator,( ::boost::parameter::aux ::tagged_argument_rref const& x ) const { return ::boost::parameter::aux::arg_list< ::boost::parameter::aux::tagged_argument_rref , ::boost::parameter::aux::arg_list< ::boost::parameter::aux ::tagged_argument_rref > >( *this , ::boost::parameter::aux::arg_list< ::boost::parameter::aux::tagged_argument_rref< Keyword2 , Arg2 > >(x, ::boost::parameter::aux::empty_arg_list()) ); } #endif // BOOST_PARAMETER_CAN_USE_MP11 // Accessor interface. inline BOOST_CONSTEXPR reference get_value() const { return ::std::forward(this->value); } inline BOOST_CONSTEXPR reference operator[](::boost::parameter::keyword const&) const { return this->get_value(); } template inline BOOST_CONSTEXPR reference operator[]( ::boost::parameter::aux::default_ const& ) const { return this->get_value(); } template inline BOOST_CONSTEXPR reference operator[]( ::boost::parameter::aux::default_r_ const& ) const { return this->get_value(); } template inline BOOST_CONSTEXPR reference operator[]( ::boost::parameter::aux::lazy_default const& ) const { return this->get_value(); } template inline BOOST_CONSTEXPR Default& operator[]( ::boost::parameter::aux::default_ const& x ) const { return x.value; } template inline BOOST_CONSTEXPR Default&& operator[]( ::boost::parameter::aux::default_r_ const& x ) const { return ::std::forward(x.value); } template inline BOOST_CONSTEXPR typename ::boost::parameter::aux::result_of0::type operator[]( ::boost::parameter::aux::lazy_default const& x ) const { return x.compute_default(); } template static BOOST_CONSTEXPR typename ParameterRequirements::has_default satisfies(ParameterRequirements*); template static BOOST_CONSTEXPR typename ::boost::mpl::apply_wrap1::type satisfies( ::boost::parameter::aux::parameter_requirements< key_type , Predicate , HasDefault >* ); // MPL sequence support // Convenience for users typedef ::boost::parameter::aux ::tagged_argument_rref type; // For the benefit of iterators typedef ::boost::parameter::aux::empty_arg_list tail_type; // For dispatching to sequence intrinsics typedef ::boost::parameter::aux::arg_list_tag tag; }; }}} // namespace boost::parameter::aux #else // !defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING) namespace boost { namespace parameter { namespace aux { // Holds an lvalue reference to an argument of type Arg associated with // keyword Keyword template class tagged_argument : public ::boost::parameter::aux::tagged_argument_base { typedef typename ::boost::remove_const::type arg_type; public: typedef Keyword key_type; // Wrap plain (non-UDT) function objects in either // a boost::function or a std::function. -- Cromwell D. Enage typedef typename ::boost::mpl::if_< ::boost::is_function #if defined(BOOST_NO_CXX11_HDR_FUNCTIONAL) , ::boost::function #else , ::std::function #endif , Arg >::type value_type; // If Arg is void_, then this type will evaluate to void_&. If the // supplied argument is a plain function, then this type will evaluate // to a reference-to-const function wrapper type. If the supplied // argument is an lvalue, then Arg will be deduced to the lvalue // reference. -- Cromwell D. Enage typedef typename ::boost::mpl::if_< ::boost::is_function , value_type const& , Arg& >::type reference; private: // Store plain functions by value, everything else by reference. // -- Cromwell D. Enage typename ::boost::mpl::if_< ::boost::is_function , value_type , reference >::type value; public: inline explicit BOOST_CONSTEXPR tagged_argument(reference x) : value(x) { } inline BOOST_CONSTEXPR tagged_argument(tagged_argument const& copy) : value(copy.value) { } // A metafunction class that, given a keyword and a default type, // returns the appropriate result type for a keyword lookup given // that default. struct binding { template struct apply { typedef typename ::boost::mpl::eval_if< ::boost::is_same , ::boost::mpl::if_ , ::boost::mpl::identity >::type type; }; }; // Comma operator to compose argument list without using parameters<>. // Useful for argument lists with undetermined length. template inline ::boost::parameter::aux::arg_list< ::boost::parameter::aux::tagged_argument , ::boost::parameter::aux::arg_list< ::boost::parameter::aux::tagged_argument > > operator,( ::boost::parameter::aux ::tagged_argument const& x ) const { return ::boost::parameter::aux::arg_list< ::boost::parameter::aux::tagged_argument , ::boost::parameter::aux::arg_list< ::boost::parameter::aux::tagged_argument > >( *this , ::boost::parameter::aux::arg_list< ::boost::parameter::aux::tagged_argument >(x, ::boost::parameter::aux::empty_arg_list()) ); } // Accessor interface. inline BOOST_CONSTEXPR reference get_value() const { return this->value; } inline BOOST_CONSTEXPR reference operator[](::boost::parameter::keyword const&) const { return this->get_value(); } #if defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) || \ BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) template inline BOOST_CONSTEXPR Default& get_with_default( ::boost::parameter::aux::default_ const& x , int ) const { return x.value; } template inline BOOST_CONSTEXPR reference get_with_default( ::boost::parameter::aux::default_ const& , long ) const { return this->get_value(); } template inline BOOST_CONSTEXPR typename ::boost::mpl::apply_wrap3< binding , KW , Default& , ::boost::mpl::true_ >::type operator[]( ::boost::parameter::aux::default_ const& x ) const { return this->get_with_default(x, 0L); } template inline BOOST_CONSTEXPR typename ::boost::parameter::aux::result_of0::type get_with_lazy_default( ::boost::parameter::aux::lazy_default const& x , int ) const { return x.compute_default(); } template inline BOOST_CONSTEXPR reference get_with_lazy_default( ::boost::parameter::aux::lazy_default const& , long ) const { return this->get_value(); } template inline BOOST_CONSTEXPR typename ::boost::mpl::apply_wrap3< binding , KW , typename ::boost::parameter::aux::result_of0::type , ::boost::mpl::true_ >::type operator[]( ::boost::parameter::aux::lazy_default const& x ) const { return this->get_with_lazy_default(x, 0L); } #else // No function template ordering or Borland workarounds needed. template inline BOOST_CONSTEXPR reference operator[]( ::boost::parameter::aux::default_ const& ) const { return this->get_value(); } template inline BOOST_CONSTEXPR reference operator[]( ::boost::parameter::aux::lazy_default const& ) const { return this->get_value(); } template inline BOOST_CONSTEXPR Default& operator[]( ::boost::parameter::aux::default_ const& x ) const { return x.value; } template inline BOOST_CONSTEXPR typename ::boost::parameter::aux::result_of0::type operator[]( ::boost::parameter::aux::lazy_default const& x ) const { return x.compute_default(); } template static BOOST_CONSTEXPR typename ParameterRequirements::has_default satisfies(ParameterRequirements*); template static BOOST_CONSTEXPR typename ::boost::mpl::apply_wrap1::type satisfies( ::boost::parameter::aux::parameter_requirements< key_type , Predicate , HasDefault >* ); #endif // Function template ordering, Borland workarounds needed. // MPL sequence support // Convenience for users typedef ::boost::parameter::aux::tagged_argument type; // For the benefit of iterators typedef ::boost::parameter::aux::empty_arg_list tail_type; // For dispatching to sequence intrinsics typedef ::boost::parameter::aux::arg_list_tag tag; #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1310)) // warning suppression private: void operator=(type const&); #endif }; }}} // namespace boost::parameter::aux #endif // BOOST_PARAMETER_HAS_PERFECT_FORWARDING #if defined(BOOST_PARAMETER_CAN_USE_MP11) namespace boost { namespace parameter { namespace aux { template struct tagged_argument_list_of_1 : public TaggedArg { using base_type = TaggedArg; inline explicit BOOST_CONSTEXPR tagged_argument_list_of_1( typename base_type::reference x ) : base_type(static_cast(x)) { } inline BOOST_CONSTEXPR tagged_argument_list_of_1( tagged_argument_list_of_1 const& copy ) : base_type(static_cast(copy)) { } using base_type::operator[]; using base_type::satisfies; template inline BOOST_CONSTEXPR ::boost::parameter::aux::flat_like_arg_list< ::boost::parameter::aux ::flat_like_arg_tuple , ::boost::parameter::aux::flat_like_arg_tuple< typename TA2::base_type::key_type , typename TA2::base_type > > operator,(TA2 const& x) const { return boost::parameter::aux::flat_like_arg_list< ::boost::parameter::aux ::flat_like_arg_tuple , ::boost::parameter::aux::flat_like_arg_tuple< typename TA2::base_type::key_type , typename TA2::base_type > >( static_cast(*this) , ::boost::parameter::aux::arg_list( static_cast(x) , ::boost::parameter::aux::empty_arg_list() ) ); } }; }}} // namespace boost::parameter::aux #endif // BOOST_PARAMETER_CAN_USE_MP11 #endif // include guard