diff --git a/.travis.yml b/.travis.yml index 54f19d4..f5cd52d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -202,6 +202,17 @@ matrix: - ubuntu-toolchain-r-test - llvm-toolchain-trusty-5.0 + - os: linux + compiler: clang++-6.0 + env: TOOLSET=clang COMPILER=clang++-6.0 CXXSTD=03,11,14,1z + addons: + apt: + packages: + - clang-6.0 + sources: + - ubuntu-toolchain-r-test + - llvm-toolchain-trusty-6.0 + - os: linux compiler: clang++ env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,14,1z diff --git a/doc/html/index.html b/doc/html/index.html index 7d1ad60..5246f89 100644 --- a/doc/html/index.html +++ b/doc/html/index.html @@ -187,24 +187,24 @@ id="id39">5   Portability Considerations
  • 5.1   Perfect Forwarding Support
  • 5.2   No SFINAE Support
  • +id="id42">5.2   No SFINAE Support
  • 5.3   No Support for +id="id43">5.3   No Support for result_of
  • 5.4   Compiler Can't See References In Unnamed +id="id44">5.4   Compiler Can't See References In Unnamed Namespace
  • 6   Python Binding
  • +id="id45">6   Python Binding
  • 7   Reference
  • +id="id46">7   Reference
  • 8   Glossary
  • +id="id47">8   Glossary
  • 9   Acknowledgements
  • +id="id48">9   Acknowledgements
    @@ -849,7 +849,7 @@ prints the arguments:

    #include <boost/graph/depth_first_search.hpp> // for dfs_visitor BOOST_PARAMETER_FUNCTION( - (void), depth_first_search, tag + (bool), depth_first_search, tag …signature goes here… ) { @@ -863,16 +863,20 @@ BOOST_PARAMETER_FUNCTION( std::cout << std::endl; std::cout << "color_map=" << color_map; std::cout << std::endl; + return true; } +#include <boost/core/lightweight_test.hpp> + int main() { + char const* g = "1"; depth_first_search(1, 2, 3, 4, 5); - depth_first_search( - "1", '2', _color_map = '5', + g, '2', _color_map = '5', _index_map = "4", _root_vertex = "3" ); + return boost::report_errors(); }

    Despite the fact that default expressions such as +#include +#include + int main() { typedef boost::adjacency_list< @@ -1175,9 +1200,10 @@ int main() depth_first_search(g); depth_first_search(g, _root_vertex = static_cast(x)); + return boost::report_errors(); } ''') --> - +

    It usually isn't necessary to so completely encode the type requirements on arguments to generic functions. However, doing so is worth the effort: your code will be more self-documenting and will often provide a better user @@ -1271,33 +1297,42 @@ specify parameter names for those arguments. To generate this interface using enclose the deduced parameters in a (deduced …) clause, as follows:

    -namespace mpl = boost::mpl;
    +char const*& blank_char_ptr()
    +{
    +    static char const* larr = "";
    +    return larr;
    +}
     
     BOOST_PARAMETER_FUNCTION(
    -    (void), def, tag,
    +    (bool), def, tag,
     
         (required (name, (char const*)) (func,*) )  // nondeduced
     
         (deduced
             (optional
    -            (docstring, (char const*), "")
    +            (docstring, (char const*), blank_char_ptr())
     
                 (keywords
                     // see 5
    -              , *(is_keyword_expression<mpl::_>)
    +              , *(is_keyword_expression<boost::mpl::_>)
                   , no_keywords()
                 )
     
                 (policies
    -              , *(mpl::not_<
    -                    mpl::or_<
    -                        boost::is_convertible<mpl::_, char const*>
    -                        // see 5
    -                      , is_keyword_expression<mpl::_>
    -                    >
    -                >)
    +                            is_keyword_expression<boost::mpl::_>
    +                          , boost::mpl::false_
    +                          , boost::mpl::true_
    +                        >
    +                    >
    +                )
                   , default_call_policies()
                 )
             )
    @@ -1307,7 +1342,7 @@ href="#is-keyword-expression" id="id14">5
         
     }
     
    - +

    Syntax Note

    @@ -1358,13 +1398,16 @@ parameters at the outer level.

    With the declaration above, the following two calls are equivalent:

    +char const* f_name = "f";
     def(
    -    "f", &f
    +    f_name
    +  , &f
       , some_policies
       , "Documentation for f"
     );
     def(
    -    "f", &f
    +    f_name
    +  , &f
       , "Documentation for f"
       , some_policies
     );
    @@ -1379,7 +1422,8 @@ argument that was also, for some reason, convertible to
     parameter name explicitly, as follows:

     def(
    -    "f", &f
    +    f_name
    +  , &f
       , _policies = some_policies
       , "Documentation for f"
     );
    @@ -1416,13 +1460,23 @@ struct callable2
             std::cout << std::endl;
         }
     };
    +
    +#include <boost/core/lightweight_test.hpp>
    +
    +int main()
    +{
    +    callable2 c2;
    +    callable2 const& c2_const = c2;
    +    c2_const.call(1, 2);
    +    return boost::report_errors();
    +}
     
    - +

    These macros don't directly allow a function's interface to be separated from its implementation, but you can always forward arguments on to a separate implementation function:

    @@ -1433,8 +1487,9 @@ struct callable2 (void), call, tag, (required (arg1,(int))(arg2,(int))) ) { - call_impl(arg1,arg2); + call_impl(arg1, arg2); } + private: void call_impl(int, int); // implemented elsewhere. }; @@ -1463,13 +1518,22 @@ struct somebody std::cout << arg1 << std::endl; } }; + +#include <boost/core/lightweight_test.hpp> + +int main() +{ + somebody::f(); + somebody::f(4); + return boost::report_errors(); +}
    - +
    @@ -1497,13 +1561,23 @@ struct callable2 std::cout << second_arg << std::endl; } }; + +#include <boost/core/lightweight_test.hpp> + +int main() +{ + callable2 c2; + callable2 const& c2_const = c2; + c2_const(1, 2); + return boost::report_errors(); +} - +

    2.4   Parameter-Enabled @@ -1514,8 +1588,8 @@ href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1986.pdf" >http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1986.pdf) limits somewhat the quality of interface this library can provide for defining parameter-enabled constructors. The usual workaround for a lack of -constructor delegation applies: one must factor the common logic into a base -class.

    +constructor delegation applies: one must factor the common logic into one or +more base classes.

    Let's build a parameter-enabled constructor that simply prints its arguments. The first step is to write a base class whose constructor accepts a single argument known as an - +

    For more on ArgumentPack manipulation, see the Advanced Topics @@ -2010,8 +2088,7 @@ BOOST_PARAMETER_NAME( ( object-name , tag-namespace - ) -parameter-name + ) parameter-name ) @@ -2544,15 +2621,15 @@ aware of the following issues and workarounds for particular compilers.

    Forwarding Support

    If your compiler supports perfect forwarding, then the Parameter library will -#define the macro -perfect forwarding, then the Parameter library will #define the macro BOOST_PARAMETER_HAS_PERFECT_FORWARDING unless you disable it manually. If your compiler does not provide this support, then parameter::parameters::operator() will treat rvalue references as lvalue -const references to work around the const references to work around the +forwarding problem, so in certain cases you must wrap

    -

    5.2   No SFINAE +

    5.2   No SFINAE Support

    Some older compilers don't support SFINAE. If your compiler meets that criterion, then Boost headers will @@ -2578,7 +2655,7 @@ functions won't be removed from the overload set based on their signatures.

    -

    5.3   No Support +

    5.3   No Support for result_of

    @@ -2626,7 +2703,7 @@ are unspecified, the workaround is to use .. |BOOST_PARAMETER_MATCH| replace:: ``BOOST_PARAMETER_MATCH`` -->

    -

    5.3   Compiler Can't +

    5.4   Compiler Can't See References In Unnamed Namespace

    If you use Microsoft Visual C++ 6.x, you may find that the compiler has trouble finding your keyword objects. This problem has been observed, but @@ -2647,7 +2724,7 @@ namespace graphs {

    -

    6   Python +

    6   Python Binding

    Follow this link for @@ -2656,12 +2733,12 @@ with Boost.Python.

    -

    7   Reference

    +

    7   Reference

    Follow this link to the Boost.Parameter reference documentation.

    -

    8   Glossary

    +

    8   Glossary

    @@ -2702,7 +2779,7 @@ int y = f(3);
    -

    9   Acknowledgements

    The authors would like to thank all the Boosters who participated in the review of this library and its documentation, most especially our review diff --git a/doc/html/reference.html b/doc/html/reference.html index af3d724..51d8eb1 100644 --- a/doc/html/reference.html +++ b/doc/html/reference.html @@ -103,107 +103,163 @@ src="../../../../boost.png" />

    >5.2   lazy_binding
  • 5.3   value_type
  • -
  • 5.4   are_tagged_arguments
  • +
  • 5.5   is_argument_pack
  • -
  • 6   Code Generation Macros

  • @@ -341,7 +397,12 @@ href="../../../mpl/doc/refmanual/associative-sequence.html">MPL Associative Sequence consisting of the keyword tag types in its tagged -references.

    +references. The test/singular.cpp, test/compose.cpp, and test/mpl.cpp test programs demonstrate this +functionality.

    Requirements

    In the table below,

    @@ -366,8 +427,7 @@ default with tag type
  • z is an ArgumentPack containing a single element (as created by keyword<…>::operator=)
  • +>keyword
    <…>::operator=)

    Any exceptions are thrown from the invocation of w's value @@ -391,8 +451,7 @@ will be propagated to the caller.

    x[u] -binding<A,K>::type +binding<A,K>::type x contains an element b whose keyword is K @@ -400,8 +459,7 @@ class="pre">binding<A,K>::type
    x[u] -binding<A,L,D>::type +binding<A,L,D>::type none If x contains an element b whose keyword is the same as @@ -410,8 +468,7 @@ reference). Otherwise, returns u's value. x[w] -lazy_binding<A,M,E>::type +lazy_binding<A,M,E>::type none If x contains an element b whose keyword is the same as @@ -525,670 +582,361 @@ class="reference external" href="../../../../boost/parameter/keyword.hpp" -

    If BOOST_PARAMETER_HAS_PERFECT_FORWARDING is -#defined, then:

     template <typename Tag>
     struct keyword
     {
         typedef Tag tag;
     
    +    constexpr keyword()
    +    {
    +    }
    +
         template <typename T>
    -    typename boost::enable_if<
    +    constexpr typename boost::enable_if<
             typename boost::mpl::eval_if<
    +href="../../../mpl/doc/refmanual/eval-if.html">eval_if<
                 boost::is_scalar<T>
    +href="../../../type_traits/doc/html/boost_typetraits/is_scalar.html"
    +>is_scalar<T>
               , boost::mpl::true_
    +href="../../../mpl/doc/refmanual/bool.html">true_
               , boost::mpl::eval_if<
    +href="../../../mpl/doc/refmanual/eval-if.html">eval_if<
                     boost::is_same<
    +href="../../../type_traits/doc/html/boost_typetraits/is_same.html"
    +>is_same<
                         typename Tag::qualifier
                       , boost::parameter::in_reference
                     >
                   , boost::mpl::true_
    +href="../../../mpl/doc/refmanual/bool.html">true_
                   , boost::mpl::if_<
    +href="../../../mpl/doc/refmanual/if.html">if_<
                         boost::is_same<
    +href="../../../type_traits/doc/html/boost_typetraits/is_same.html"
    +>is_same<
                             typename Tag::qualifier
                           , boost::parameter::forward_reference
                         >
                       , boost::mpl::true_
    +href="../../../mpl/doc/refmanual/bool.html">true_
                       , boost::mpl::false_
    +href="../../../mpl/doc/refmanual/bool.html">false_
                     >
                 >
             >::type
           , ArgumentPack
    -    >::type constexpr
    +    >::type
             operator=(T const& value) const;
     
         template <typename T>
    -    typename boost::enable_if<
    +    constexpr typename boost::enable_if<
             typename boost::mpl::eval_if<
    +href="../../../mpl/doc/refmanual/eval-if.html">eval_if<
                 typename boost::mpl::eval_if<
    +href="../../../mpl/doc/refmanual/eval-if.html">eval_if<
                     boost::is_same<
    +href="../../../type_traits/doc/html/boost_typetraits/is_same.html"
    +>is_same<
                         typename Tag::qualifier
                       , boost::parameter::out_reference
                     >
                   , boost::mpl::true_
    +href="../../../mpl/doc/refmanual/bool.html">true_
                   , boost::mpl::if_<
    +href="../../../mpl/doc/refmanual/if.html">if_<
                         boost::is_same<
    +href="../../../type_traits/doc/html/boost_typetraits/is_same.html"
    +>is_same<
                             typename Tag::qualifier
                           , boost::parameter::forward_reference
                         >
                       , boost::mpl::true_
    +href="../../../mpl/doc/refmanual/bool.html">true_
                       , boost::mpl::false_
    +href="../../../mpl/doc/refmanual/bool.html">false_
                     >
                 >
               , boost::mpl::if_<
    +href="../../../mpl/doc/refmanual/if.html">if_<
                     boost::is_const<T>
    +href="../../../type_traits/doc/html/boost_typetraits/is_const.html"
    +>is_const<T>
                   , boost::mpl::false_
    +href="../../../mpl/doc/refmanual/bool.html">false_
                   , boost::mpl::true_
    +href="../../../mpl/doc/refmanual/bool.html">true_
                 >
               , boost::mpl::false_
    +href="../../../mpl/doc/refmanual/bool.html">false_
             >::type
           , ArgumentPack
    -    >::type constexpr
    +    >::type
             operator=(T& value) const;
     
         template <typename T>
    -    typename boost::enable_if<
    +    constexpr typename boost::enable_if<
             typename boost::mpl::eval_if<
    +href="../../../mpl/doc/refmanual/eval-if.html">eval_if<
                 boost::is_scalar<T>
    +href="../../../type_traits/doc/html/boost_typetraits/is_scalar.html"
    +>is_scalar<T>
               , boost::mpl::false_
    +href="../../../mpl/doc/refmanual/bool.html">false_
               , boost::mpl::eval_if<
    +href="../../../mpl/doc/refmanual/eval-if.html">eval_if<
                     boost::is_same<
    +href="../../../type_traits/doc/html/boost_typetraits/is_same.html"
    +>is_same<
                         typename Tag::qualifier
                       , boost::parameter::in_reference
                     >
                   , boost::mpl::true_
    +href="../../../mpl/doc/refmanual/bool.html">true_
                   , boost::mpl::if_<
    +href="../../../mpl/doc/refmanual/if.html">if_<
                         boost::is_same<
    +href="../../../type_traits/doc/html/boost_typetraits/is_same.html"
    +>is_same<
                             typename Tag::qualifier
                           , boost::parameter::forward_reference
                         >
                       , boost::mpl::true_
    +href="../../../mpl/doc/refmanual/bool.html">true_
                       , boost::mpl::false_
    +href="../../../mpl/doc/refmanual/bool.html">false_
                     >
                 >
             >::type
           , ArgumentPack
    -    >::type constexpr
    +    >::type
             operator=(T const&& value) const;
     
         template <typename T>
    -    typename boost::enable_if<
    +    constexpr typename boost::enable_if<
             typename boost::mpl::eval_if<
    +href="../../../mpl/doc/refmanual/eval-if.html">eval_if<
                 boost::is_scalar<T>
    +href="../../../type_traits/doc/html/boost_typetraits/is_scalar.html"
    +>is_scalar<T>
               , boost::mpl::false_
    +href="../../../mpl/doc/refmanual/bool.html">false_
               , boost::mpl::eval_if<
    +href="../../../mpl/doc/refmanual/eval-if.html">eval_if<
                     boost::is_same<
    +href="../../../type_traits/doc/html/boost_typetraits/is_same.html"
    +>is_same<
                         typename Tag::qualifier
                       , boost::parameter::consume_reference
                     >
                   , boost::mpl::true_
    +href="../../../mpl/doc/refmanual/bool.html">true_
                   , boost::mpl::if_<
    +href="../../../mpl/doc/refmanual/if.html">if_<
                         boost::is_same<
    +href="../../../type_traits/doc/html/boost_typetraits/is_same.html"
    +>is_same<
                             typename Tag::qualifier
                           , boost::parameter::forward_reference
                         >
                       , boost::mpl::true_
    +href="../../../mpl/doc/refmanual/bool.html">true_
                       , boost::mpl::false_
    +href="../../../mpl/doc/refmanual/bool.html">false_
                     >
                 >
             >::type
           , ArgumentPack
    -    >::type constexpr
    +    >::type
             operator=(T&& value) const;
     
         template <typename T>
    -    typename boost::enable_if<
    +    constexpr typename boost::enable_if<
             typename boost::mpl::eval_if<
    +href="../../../mpl/doc/refmanual/eval-if.html">eval_if<
                 boost::is_scalar<T>
    +href="../../../type_traits/doc/html/boost_typetraits/is_scalar.html"
    +>is_scalar<T>
               , boost::mpl::true_
    +href="../../../mpl/doc/refmanual/bool.html">true_
               , boost::mpl::eval_if<
    +href="../../../mpl/doc/refmanual/eval-if.html">eval_if<
                     boost::is_same<
    +href="../../../type_traits/doc/html/boost_typetraits/is_same.html"
    +>is_same<
                         typename Tag::qualifier
                       , boost::parameter::in_reference
                     >
                   , boost::mpl::true_
    +href="../../../mpl/doc/refmanual/bool.html">true_
                   , boost::mpl::if_<
    +href="../../../mpl/doc/refmanual/if.html">if_<
                         boost::is_same<
    +href="../../../type_traits/doc/html/boost_typetraits/is_same.html"
    +>is_same<
                             typename Tag::qualifier
                           , boost::parameter::forward_reference
                         >
                       , boost::mpl::true_
    +href="../../../mpl/doc/refmanual/bool.html">true_
                       , boost::mpl::false_
    +href="../../../mpl/doc/refmanual/bool.html">false_
                     >
                 >
             >::type
           , tagged default
    -    >::type constexpr
    +    >::type
             operator|(T const& x) const;
     
         template <typename T>
    -    typename boost::enable_if<
    +    constexpr typename boost::enable_if<
             typename boost::mpl::eval_if<
    +href="../../../mpl/doc/refmanual/eval-if.html">eval_if<
                 typename boost::mpl::eval_if<
    +href="../../../mpl/doc/refmanual/eval-if.html">eval_if<
                     boost::is_same<
    +href="../../../type_traits/doc/html/boost_typetraits/is_same.html"
    +>is_same<
                         typename Tag::qualifier
                       , boost::parameter::out_reference
                     >
                   , boost::mpl::true_
    +href="../../../mpl/doc/refmanual/bool.html">true_
                   , boost::mpl::if_<
    +href="../../../mpl/doc/refmanual/if.html">if_<
                         boost::is_same<
    +href="../../../type_traits/doc/html/boost_typetraits/is_same.html"
    +>is_same<
                             typename Tag::qualifier
                           , boost::parameter::forward_reference
                         >
                       , boost::mpl::true_
    +href="../../../mpl/doc/refmanual/bool.html">true_
                       , boost::mpl::false_
    +href="../../../mpl/doc/refmanual/bool.html">false_
                     >
                 >
               , boost::mpl::if_<
                     boost::is_const<T>
    +href="../../../type_traits/doc/html/boost_typetraits/is_const.html"
    +>is_const<T>
                   , boost::mpl::false_
    +href="../../../mpl/doc/refmanual/bool.html">false_
                   , boost::mpl::true_
    +href="../../../mpl/doc/refmanual/bool.html">true_
                 >
               , boost::mpl::false_
    +href="../../../mpl/doc/refmanual/bool.html">false_
             >::type
           , tagged default
    -    >::type constexpr
    +    >::type
             operator|(T& x) const;
     
         template <typename T>
    -    typename boost::enable_if<
    +    constexpr typename boost::enable_if<
             typename boost::mpl::eval_if<
    +href="../../../mpl/doc/refmanual/eval-if.html">eval_if<
                 boost::is_scalar<T>
    +href="../../../type_traits/doc/html/boost_typetraits/is_scalar.html"
    +>is_scalar<T>
               , boost::mpl::false_
    +href="../../../mpl/doc/refmanual/bool.html">false_
               , boost::mpl::eval_if<
    +href="../../../mpl/doc/refmanual/eval-if.html">eval_if<
                     boost::is_same<
    +href="../../../type_traits/doc/html/boost_typetraits/is_same.html"
    +>is_same<
                         typename Tag::qualifier
                       , boost::parameter::in_reference
                     >
                   , boost::mpl::true_
    +href="../../../mpl/doc/refmanual/bool.html">true_
                   , boost::mpl::if_<
    +href="../../../mpl/doc/refmanual/if.html">if_<
                         boost::is_same<
    +href="../../../type_traits/doc/html/boost_typetraits/is_same.html"
    +>is_same<
                             typename Tag::qualifier
                           , boost::parameter::forward_reference
                         >
                       , boost::mpl::true_
    +href="../../../mpl/doc/refmanual/bool.html">true_
                       , boost::mpl::false_
    +href="../../../mpl/doc/refmanual/bool.html">false_
                     >
                 >
             >::type
           , tagged default
    -    >::type constexpr
    +    >::type
             operator|(T const&& x) const;
     
         template <typename T>
    -    typename boost::enable_if<
    +    constexpr typename boost::enable_if<
             typename boost::mpl::eval_if<
    +href="../../../mpl/doc/refmanual/eval-if.html">eval_if<
                 boost::is_scalar<T>
    +href="../../../type_traits/doc/html/boost_typetraits/is_scalar.html"
    +>is_scalar<T>
               , boost::mpl::false_
    +href="../../../mpl/doc/refmanual/bool.html">false_
               , boost::mpl::eval_if<
    +href="../../../mpl/doc/refmanual/eval-if.html">eval_if<
                     boost::is_same<
    +href="../../../type_traits/doc/html/boost_typetraits/is_same.html"
    +>is_same<
                         typename Tag::qualifier
                       , boost::parameter::consume_reference
                     >
                   , boost::mpl::true_
    +href="../../../mpl/doc/refmanual/bool.html">true_
                   , boost::mpl::if_<
    +href="../../../mpl/doc/refmanual/if.html">if_<
                         boost::is_same<
    +href="../../../type_traits/doc/html/boost_typetraits/is_same.html"
    +>is_same<
                             typename Tag::qualifier
                           , boost::parameter::forward_reference
                         >
                       , boost::mpl::true_
    +href="../../../mpl/doc/refmanual/bool.html">true_
                       , boost::mpl::false_
    +href="../../../mpl/doc/refmanual/bool.html">false_
                     >
                 >
             >::type
           , tagged default
    -    >::type constexpr
    +    >::type
             operator|(T&& x) const;
     
         template <typename F>
    -    tagged lazy default tagged lazy default operator||(F const&) const;
     
         template <typename F>
    -    tagged lazy default operator||(F&) const;
    -
    -    static keyword<Tag> const& instance;
    -
    -    static keyword<Tag>& get();
    -};
    -
    -

    If BOOST_PARAMETER_HAS_PERFECT_FORWARDING is not -#defined, then:

    -
    -template <typename Tag>
    -struct keyword
    -{
    -    typedef Tag tag;
    -
    -    template <typename T>
    -    typename boost::enable_if<
    -        typename boost::mpl::eval_if<
    -            boost::is_scalar<T>
    -          , boost::mpl::true_
    -          , boost::mpl::eval_if<
    -                boost::is_same<
    -                    typename Tag::qualifier
    -                  , boost::parameter::in_reference
    -                >
    -              , boost::mpl::true_
    -              , boost::mpl::if_<
    -                    boost::is_same<
    -                        typename Tag::qualifier
    -                      , boost::parameter::forward_reference
    -                    >
    -                  , boost::mpl::true_
    -                  , boost::mpl::false_
    -                >
    -            >
    -        >::type
    -      , ArgumentPack
    -    >::type constexpr
    -        operator=(T const& value) const;
    -
    -    template <typename T>
    -    typename boost::enable_if<
    -        typename boost::mpl::eval_if<
    -            typename boost::mpl::eval_if<
    -                boost::is_same<
    -                    typename Tag::qualifier
    -                  , boost::parameter::out_reference
    -                >
    -              , boost::mpl::true_
    -              , boost::mpl::if_<
    -                    boost::is_same<
    -                        typename Tag::qualifier
    -                      , boost::parameter::forward_reference
    -                    >
    -                  , boost::mpl::true_
    -                  , boost::mpl::false_
    -                >
    -            >
    -          , boost::mpl::if_<
    -                boost::is_const<T>
    -              , boost::mpl::false_
    -              , boost::mpl::true_
    -            >
    -          , boost::mpl::false_
    -        >::type
    -      , ArgumentPack
    -    >::type constexpr
    -        operator=(T& value) const;
    -
    -    template <typename T>
    -    typename boost::enable_if<
    -        typename boost::mpl::eval_if<
    -            boost::is_scalar<T>
    -          , boost::mpl::true_
    -          , boost::mpl::eval_if<
    -                boost::is_same<
    -                    typename Tag::qualifier
    -                  , boost::parameter::in_reference
    -                >
    -              , boost::mpl::true_
    -              , boost::mpl::if_<
    -                    boost::is_same<
    -                        typename Tag::qualifier
    -                      , boost::parameter::forward_reference
    -                    >
    -                  , boost::mpl::true_
    -                  , boost::mpl::false_
    -                >
    -            >
    -        >::type
    -      , tagged default
    -    >::type constexpr
    -        operator|(T const& x) const;
    -
    -    template <typename T>
    -    typename boost::enable_if<
    -        typename boost::mpl::eval_if<
    -            typename boost::mpl::eval_if<
    -                boost::is_same<
    -                    typename Tag::qualifier
    -                  , boost::parameter::out_reference
    -                >
    -              , boost::mpl::true_
    -              , boost::mpl::if_<
    -                    boost::is_same<
    -                        typename Tag::qualifier
    -                      , boost::parameter::forward_reference
    -                    >
    -                  , boost::mpl::true_
    -                  , boost::mpl::false_
    -                >
    -            >
    -          , boost::mpl::if_<
    -                boost::is_const<T>
    -              , boost::mpl::false_
    -              , boost::mpl::true_
    -            >
    -          , boost::mpl::false_
    -        >::type
    -      , tagged default
    -    >::type constexpr
    -        operator|(T& x) const;
    -
    -    template <typename F>
    -    tagged lazy default operator||(F const&) const;
    -
    -    template <typename F>
    -    tagged lazy default tagged lazy default operator||(F&) const;
     
         static keyword<Tag> const& get();
     
    operator=
    -template <typename T> ArgumentPack operator=(T const& value) const;
    -template <typename T> ArgumentPack operator=(T& value) const;
    -
    -

    If BOOST_PARAMETER_HAS_PERFECT_FORWARDING is -#defined, then:

    -
    -template <typename T> ArgumentPackArgumentPack operator=(T const& value) const;
    +
    +template <typename T>
    +constexpr ArgumentPack operator=(T& value) const;
    +
    +template <typename T>
    +constexpr ArgumentPack operator=(T const&& value) const;
    -template <typename T> ArgumentPack operator=(T&& value) const;
    +
    +template <typename T>
    +constexpr ArgumentPack operator=(T&& value) const;
     
    @@ -1274,20 +1020,17 @@ reference to value with
    operator|
    -template <typename T> tagged default operator|(T const& x) const;
    -template <typename T> tagged default operator|(T& x) const;
    -
    -

    If BOOST_PARAMETER_HAS_PERFECT_FORWARDING is -#defined, then:

    -
    -template <typename T> tagged default operator|(T const&& x) const;
    -template <typename T> tagged default operator|(T&& x) const;
    +template <typename T>
    +constexpr tagged default operator|(T const& x) const;
    +
    +template <typename T>
    +constexpr tagged default operator|(T& x) const;
    +
    +template <typename T>
    +constexpr tagged default operator|(T const&& x) const;
    +
    +template <typename T>
    +constexpr tagged default operator|(T&& x) const;
     
    @@ -1342,10 +1085,11 @@ href="#tagged-default">tagged default with value
    operator||
    -template <typename F> tagged lazy default operator||(F const& g) const;
    -template <typename F> tagged lazy default operator||(F& g) const;
    +template <typename F>
    +constexpr tagged lazy default operator||(F const& g) const;
    +
    +template <typename F>
    +constexpr tagged lazy default operator||(F& g) const;
     
    @@ -1402,7 +1146,7 @@ static keyword<Tag>& get();

    Deprecated

    -

    This macro has been deprecated in favor of +

    This function has been deprecated in favor of instance.

    @@ -1465,8 +1209,8 @@ class="docutils literal">parametersforwarding function into an ArgumentPack, in which any positional arguments will be tagged according to the -corresponding template argument to -parameters.

    +corresponding template argument to parameters.

    @@ -1479,10 +1223,6 @@ href="../../../../boost/parameter/parameters.hpp"
    -

    If BOOST_PARAMETER_HAS_PERFECT_FORWARDING is -#defined, then:

     template <typename ...PSpec>
     struct parameters
    @@ -1496,7 +1236,7 @@ struct parameters
         template <typename ...Args>
         ArgumentPack operator()(Args&... args) const;
    +href="#id13">operator()(Args&&... args) const;
     };
     
    @@ -1567,119 +1307,6 @@ href="#keyword-tag-type">keyword tag type. -

    If BOOST_PARAMETER_HAS_PERFECT_FORWARDING is not -#defined, then:

    -
    -template <
    -    typename P0 = unspecified
    -  , typename P1 = unspecified
    -  , …
    -  , typename P ## β = unspecified
    ->
    -struct parameters
    -{
    -    template <
    -        typename A0
    -      , typename A1 = unspecified
    -      , …
    -      , typename A ## β = unspecified
    -    >
    -    struct match
    -    {
    -        typedef … type;
    -    };
    -
    -    template <typename A0>
    -    ArgumentPack operator()(A0& a0) const;
    -
    -    template <typename A0, typename A1>
    -    ArgumentPack operator()(A0& a0, A1& a1) const;
    -
    -    
    -
    -    template <typename A0, typename A1, …, typename A ## β>
    -    ArgumentPack
    -    operator()(A0& a0, A1& a1, …, A ## β & a ## β) const;
    -};
    -
    -
    --- - - - - - -
    Requires:P0, -P1, …, P -## β are models of ParameterSpec.
    -
    -

    Note

    -

    In this section, R ## i and -K ## i are defined as follows: for -any argument type A ## i:

    -
    -
    -
    let D0 the set [d0, …, d -## j] of all deduced parameter specs in -[P0, …, P -## β]
    -
    R ## i is the -intended argument -type of A ## i
    -

    -
    if A ## i is a -result type of keyword<T>::operator=
    -
    then
    -
    -
    K ## i is -T
    -
    -
    else
    -
    -
    if some A ## j -where ji is a result type of keyword<T>::operator=
    -
    or some P ## -j in ji is deduced
    -
    then
    -
    -
    if some parameter spec dj in D ## i matches -Ai
    -
    then
    -
    -
    K ## i is d ## j's keyword tag type.
    -
    Di+1 is -D ## i - -[d ## j]
    -
    -
    -
    else
    -
    -
    K ## i is P ## i's keyword tag type.
    -
    -
    -
    -
    -
    match
    @@ -1688,10 +1315,6 @@ href="../../../mpl/doc/refmanual/metafunction.html">Metafunction used to remove a forwarding function from overload resolution.

    -

    If BOOST_PARAMETER_HAS_PERFECT_FORWARDING is -#defined, then:

    @@ -1741,87 +1364,16 @@ default -

    If BOOST_PARAMETER_HAS_PERFECT_FORWARDING is not -#defined, then:

    -
    --- - - - - - -
    Returns:if P0, P1, …, are -satisfied (see below), then parameters<P0,P1,…,Pβ>. Otherwise, -match<A0,A1,…,Aβ>::type is not defined.
    -

    P0, P1, -…, are satisfied if, for -every j in 0…β, either:

    -
      -
    • P ## j is the -unspecified default
    • -
    • or, P ## j is -a keyword tag type
    • -
    • or, P ## j is -optional<X,F> and either -
        -
      • X is not K ## i for any i,
      • -
      • or X is some -K ## i and -mpl::apply<F,R -## i>::type::value is true
      • -
      -
    • -
    • or, P ## j is -required<X,F>, and -
        -
      • X is some K ## i, and
      • -
      • mpl::apply<F,R ## i>::type::value is -true
      • -
      -
    • -
    operator()
    -

    If BOOST_PARAMETER_HAS_PERFECT_FORWARDING is -#defined, then:

    -template <typename ...Args> ArgumentPack operator()(Args&&... args) const;
     
    -

    Else:

    -
    -template <typename A0> ArgumentPack operator()(A0 const& a0) const;
    -
    -
    -
    -template <typename A0, …, typename A ## β> ArgumentPack operator()(A0 const& a0, …, A ## β const& a ## β) const;
    -
    @@ -1885,8 +1437,14 @@ struct required;

    The default value of Predicate is an unspecified MPL Binary -Metafunction Class that returns mpl::true_ for any argument.

    +Metafunction Class that returns mpl::true_ for any argument. If BOOST_PARAMETER_CAN_USE_MP11 is defined, then the default value of +Predicate is also a Boost.MP11-style that returns mp11::mp_true for any argument.

    4.5    K, if any. If no such tagged reference exists, returns D. Equivalent to:

    -typename remove_reference<
    -    typename binding<A, K, D>::type
    +typename boost::remove_reference<
    +    typename binding<A, K, D>::type
     >::type
     

    … when D is not a reference @@ -2084,8 +1645,89 @@ type.

    -
    +

    5.4   are_tagged_arguments

    + +++ + + + + + +
    Defined in:boost/parameter/are_tagged_arguments.hpp
    +
    +template <typename T0, typename ...Pack>
    +struct are_tagged_arguments  // : mpl::true_ or mpl::false_
    +{
    +};
    +
    + +++ + + + + + + + + + + + + + + + +
    Returns:
     mpl::true_ if T0 and all elements in parameter pack Pack are tagged reference types, mpl::false_ otherwise.
    Example usage:
      +

    When implementing a Boost.Parameter-enabled constructor for a +container that conforms to the C++ standard, one needs to remember that the +standard requires the presence of other constructors that are typically +defined as templates, such as range constructors. To avoid overload +ambiguities between the two constructors, use this metafunction in conjunction +with disable_if to define the range +constructor.

    +
    +template <typename B>
    +class frontend : public B
    +{
    +    struct _enabler
    +    {
    +    };
    +
    + public:
    +    BOOST_PARAMETER_NO_SPEC_CONSTRUCTOR(frontend, (B))
    +
    +    template <typename Iterator>
    +    frontend(
    +        Iterator itr
    +      , Iterator itr_end
    +      , typename boost::disable_if<
    +            are_tagged_arguments<Iterator>
    +          , _enabler
    +        >::type = _enabler()
    +    ) : B(itr, itr_end)
    +    {
    +    }
    +};
    +
    +
    +
    +
    +

    5.5   is_argument_pack

    @@ -2110,13 +1752,193 @@ struct is_argument_pack // : mpl::true_ or mpl::false_ + + + + + + + + + + + + + + +
    Returns:
     mpl::true_ if T is a model of ArgumentPack, mpl::false_ otherwise.
    Example usage:
      +

    To avoid overload ambiguities between a constructor that +takes in an ArgumentPack and a templated conversion +constructor, use this metafunction in conjunction with enable_if.

    +
    +BOOST_PARAMETER_NAME(a0)
    +
    +template <typename T>
    +class backend0
    +{
    +    struct _enabler
    +    {
    +    };
    +
    +    T a0;
    +
    + public:
    +    template <typename ArgPack>
    +    explicit backend0(
    +        ArgPack const& args
    +      , typename boost::enable_if<
    +            is_argument_pack<ArgPack>
    +          , _enabler
    +        >::type = _enabler()
    +    ) : a0(args[_a0])
    +    {
    +    }
    +
    +    template <typename U>
    +    backend0(
    +        backend0<U> const& copy
    +      , typename boost::enable_if<
    +            boost::is_convertible<U,T>
    +          , _enabler
    +        >::type = _enabler()
    +    ) : a0(copy.get_a0())
    +    {
    +    }
    +
    +    T const& get_a0() const
    +    {
    +        return this->a0;
    +    }
    +};
    +
    +
    +
    +
    +
    +
    +

    6   Function +Templates

    +
    +

    6.1   compose

    + +++ + + + + + +
    Defined in:boost/parameter/compose.hpp
    +
    +constexpr empty ArgumentPack compose();
    +
    +template <typename T0, typename ...Pack>
    +constexpr typename boost::enable_if<
    +    are_tagged_arguments<T0,Pack...>
    +  , ArgumentPack
    +>::type
    +    compose(T0 const& t0, Pack const&... args);
    +
    +

    This function facilitates easier variadic argument composition. It is used +by the BOOST_PARAMETER_NO_SPEC_FUNCTION, BOOST_PARAMETER_NO_SPEC_MEMBER_FUNCTION, BOOST_PARAMETER_NO_SPEC_CONST_MEMBER_FUNCTION, BOOST_PARAMETER_NO_SPEC_FUNCTION_CALL_OPERATOR, BOOST_PARAMETER_NO_SPEC_CONST_FUNCTION_CALL_OPERATOR, BOOST_PARAMETER_NO_SPEC_CONSTRUCTOR, and BOOST_PARAMETER_NO_SPEC_NO_BASE_CONSTRUCTOR +code generation macros. You can use it to write your own code generation +macros if the ones provided by this library do not suffice.

    +

    Unlike the tagged +reference comma operator, the compose() +function is variadic, as mentioned before. However, the tagged reference comma +operator can be invoked indefinitely and therefore does not limit the size of +the resulting ArgumentPack, while the compose() function cannot take in more than BOOST_PARAMETER_MAX_ARITY arguments +for compilers that do not support perfect forwarding.

    + +++ + + + + + - + + + + + + +
    Requires: +

    t0 and all elements in args must be tagged reference objects, if specified.

    +
    Returns:mpl::true_ if T is a model of -ArgumentPack, mpl::false_ otherwise. -exists, returns D. +

    An ArgumentPack containing t0 and all elements in args, if specified; an empty ArgumentPack otherwise.

    +
    Example usage:
    +
    +BOOST_PARAMETER_NAME(name)
    +
    +template <typename ArgumentPack>
    +int print_name_and_index(ArgumentPack const& args)
    +{
    +    std::cout << "index = " << args[_index];
    +    std::cout << "name = " << args[_name];
    +    std::cout << "; " << std::endl;
    +    return 0;
    +}
    +
    +int y = print_name_and_index(compose(_index = 3, _name = "jones"));
    +
    +

    The test/compose.cpp test program shows more examples using this +function.

    +
    @@ -2124,13 +1946,13 @@ exists, returns D.

    -

    6   Code Generation +

    7   Code Generation Macros

    Macros in this section can be used to ease the writing of code using the Parameter libray by eliminating repetitive boilerplate.

    -

    6.1   7.1   BOOST_PARAMETER_FUNCTION(result, name, tag_namespace, arguments)

    @@ -2145,23 +1967,259 @@ href="../../../../boost/parameter/preprocessor.hpp"
    +

    Generates a function that can take in positional arguments, composed +arguments, named arguments, and deduced arguments.

    - + + + + + + + + @@ -2248,33 +2306,6 @@ type.
    Requires:Example usage:
      -

    result is the parenthesized -return type of the function. name is the -base name of the function, this is the name of the generated forwarding -functions. tag_namespace is the namespace -in which the keywords used by the function -resides. arguments is a list of -argument specifiers, as defined below.

    +

    The return type of each of the following function templates falls under a +different value category.

    +
    +template <std::size_t N>
    +std::bitset<N + 1> rvalue_bitset()
    +{
    +    return std::bitset<N + 1>();
    +}
    +
    +template <std::size_t N>
    +std::bitset<N + 1> const rvalue_const_bitset()
    +{
    +    return std::bitset<N + 1>();
    +}
    +
    +template <std::size_t N>
    +std::bitset<N + 1>& lvalue_bitset()
    +{
    +    static std::bitset<N + 1> lset = std::bitset<N + 1>();
    +    return lset;
    +}
    +
    +template <std::size_t N>
    +std::bitset<N + 1> const& lvalue_const_bitset()
    +{
    +    static std::bitset<N + 1> const clset = std::bitset<N + 1>();
    +    return clset;
    +}
    +
    +

    The U::evaluate_category static member +function template has a simple job: to return the correct value category when +passed in an object returned by one of the functions defined above. Assume +that BOOST_PARAMETER_HAS_PERFECT_FORWARDING is defined.

    +
    +enum invoked
    +{
    +    passed_by_lvalue_reference_to_const
    +  , passed_by_lvalue_reference
    +  , passed_by_rvalue_reference_to_const
    +  , passed_by_rvalue_reference
    +};
    +
    +struct U
    +{
    +    template <std::size_t N>
    +    static invoked evaluate_category(std::bitset<N + 1> const&)
    +    {
    +        return passed_by_lvalue_reference_to_const;
    +    }
    +
    +    template <std::size_t N>
    +    static invoked evaluate_category(std::bitset<N + 1>&)
    +    {
    +        return passed_by_lvalue_reference;
    +    }
    +
    +    template <std::size_t N>
    +    static invoked evaluate_category(std::bitset<N + 1> const&&)
    +    {
    +        return passed_by_rvalue_reference_to_const;
    +    }
    +
    +    template <std::size_t N>
    +    static invoked evaluate_category(std::bitset<N + 1>&&)
    +    {
    +        return passed_by_rvalue_reference;
    +    }
    +};
    +
    +

    Define the named parameters that will comprise the argument specification +that this macro will use. Ensure that all their tag types are in the same +namespace, which is kw in this case. The +identifiers with leading underscores can be passed to the bracket operator of +args to extract the same argument to which +the corresponding named parameter (without underscores) is bound, as will be +shown later.

    +
    +BOOST_PARAMETER_NAME((_lrc, kw) in(lrc))
    +BOOST_PARAMETER_NAME((_lr, kw) in_out(lr))
    +BOOST_PARAMETER_NAME((_rrc, kw) in(rrc))
    +BOOST_PARAMETER_NAME((_rr, kw) consume(rr))
    +
    +

    Use the macro as a substitute for a normal function header. Enclose the +return type bool in parentheses. For each +parameter, also enclose the expected value type in parentheses. Since the +value types are mutually exclusive, you can wrap the parameters in a (deduced …) clause. Otherwise, just as with a +normal function, the order in which you specify the parameters determines +their position. Also, just as with a normal function, optional parameters +have default values, whereas required parameters do not. Within the function +body, either simply use the parameter name or pass the matching identifier +with the leading underscore to the bracket operator of args to extract the corresponding +argument. Note that the second method doesn't require std::forward to preserve value categories.

    +
    +BOOST_PARAMETER_FUNCTION((bool), evaluate, kw,
    +    (deduced
    +        (required
    +            (lrc, (std::bitset<1>))
    +            (lr, (std::bitset<2>))
    +        )
    +        (optional
    +            (rrc, (std::bitset<3>), rvalue_const_bitset<2>())
    +            (rr, (std::bitset<4>), rvalue_bitset<3>())
    +        )
    +    )
    +)
    +{
    +    BOOST_TEST_EQ(
    +        passed_by_lvalue_reference_to_const
    +      , U::evaluate_category<0>(lrc)
    +    );
    +    BOOST_TEST_EQ(
    +        passed_by_lvalue_reference
    +      , U::evaluate_category<1>(lr)
    +    );
    +    BOOST_TEST_EQ(
    +        passed_by_rvalue_reference_to_const
    +      , U::evaluate_category<2>(std::forward<rrc0_type>(rrc0))
    +    );
    +    BOOST_TEST_EQ(
    +        passed_by_rvalue_reference
    +      , U::evaluate_category<3>(args[_rr0])
    +    );
    +
    +    return true;
    +}
    +
    +

    The following function calls are legal.

    +
    +evaluate(  // positional arguments
    +    lvalue_const_bitset<0>()
    +  , lvalue_bitset<1>()
    +  , rvalue_const_bitset<2>()
    +  , rvalue_bitset<3>()
    +);
    +evaluate(  // positional arguments
    +    lvalue_const_bitset<0>()
    +  , lvalue_bitset<1>()
    +);
    +evaluate((  // composed arguments
    +    _rr0 = rvalue_bitset<3>()
    +  , _lrc0 = lvalue_const_bitset<0>()
    +  , _lr0 = lvalue_bitset<1>()
    +  , _rrc0 = rvalue_const_bitset<2>()
    +));
    +evaluate(  // named arguments
    +    _rr0 = rvalue_bitset<3>()
    +  , _lrc0 = lvalue_const_bitset<0>()
    +  , _lr0 = lvalue_bitset<1>()
    +  , _rrc0 = rvalue_const_bitset<2>()
    +);
    +evaluate(  // named arguments
    +    _lr0 = lvalue_bitset<1>()
    +  , _lrc0 = lvalue_const_bitset<0>()
    +);
    +
    +

    Because the parameters were wrapped in a (deduced …) clause, the following function calls are also legal.

    +
    +evaluate(  // deduced arguments
    +    rvalue_bitset<3>()
    +  , lvalue_const_bitset<0>()
    +  , lvalue_bitset<1>()
    +  , rvalue_const_bitset<2>()
    +);
    +evaluate(  // deduced arguments
    +    lvalue_bitset<1>()
    +  , lvalue_const_bitset<0>()
    +);
    +
    +

    The test/preprocessor.cpp, test/preprocessor_deduced.cpp, +and test/preprocessor_eval_category.cpp test programs demonstrate proper +usage of this macro.

    +
    Macro parameters:
      +
      +
    • result is the parenthesized return type +of the function.
    • +
    • name is the base name of the function; +it determines the name of the generated forwarding functions.
    • +
    • tag_namespace is the namespace in which +the keywords used by the function resides.
    • +
    • arguments is a list of argument +specifiers, as defined below.
    • +
    - --- - - - - - - - - -
    Generated names in enclosing scope:
      -
      -
    • boost_param_result_ ## __LINE__ ## -name
    • -
    • boost_param_params_ ## __LINE__ ## -name
    • -
    • boost_param_parameters_ ## __LINE__ ## -name
    • -
    • boost_param_impl ## name
    • -
    • boost_param_dispatch_0boost_ ## __LINE__ ## -name
    • -
    • boost_param_dispatch_1boost_ ## __LINE__ ## -name
    • -
    -
    Approximate expansion:
    @@ -2285,10 +2316,6 @@ determined from arguments.
  • m denotes the maximum arity, as determined from arguments.
  • -

    If BOOST_PARAMETER_HAS_PERFECT_FORWARDING is -#defined, then:

     template <typename T>
     struct boost_param_result_ ## __LINE__ ## name
    @@ -2297,7 +2324,7 @@ struct boost_param_result_ ## __LINE__ ## name
     };
     
     struct boost_param_params_ ## __LINE__ ## name
    -  : boost::parameter::parameters<
    +  : parameters<
             list of parameter specifications, based on arguments
         >
     {
    @@ -2308,8 +2335,8 @@ typedef boost_param_params_ ## __LINE__ ## name
     
     template <typename Args>
     typename boost_param_result_ ## __LINE__ ## name<Args>::type
    -    boost_param_impl ## name(Args const&);
    +>name ## _<Args>::type
    +    boost_param_impl ## __LINE__ ## name(Args const&);
     
     template <typename A0, …, typename A ## n>
     result type
    @@ -2317,22 +2344,21 @@ template <typename A0, …, typename A ## n>
             A0&& a0, …, A ## n && a ## n
           , typename boost_param_parameters_ ## __LINE__ ## name::match<
    -            A0, …, A ## n
    -        >::type = boost_param_parameters_ ## __LINE__ ## name
    +        ::match<A0, …, A ## n>::type
    +        = boost_param_parameters_ ## __LINE__ ## name()
         )
     {
    -    return boost_param_impl ## name(
    +    return boost_param_impl ## __LINE__ ## name(
             boost_param_parameters_ ## __LINE__ ## name()(
                 std::forward<A0>(a0)
    +href="http://en.cppreference.com/w/cpp/utility/forward"
    +>forward<A0>(a0)
               , …
               , std::forward<A ## n>(a ## n)
    +href="http://en.cppreference.com/w/cpp/utility/forward"
    +>forward<A ## n>(a ## n)
             )
         );
     }
    @@ -2345,22 +2371,21 @@ template <typename A0, …, typename A ## m>
             A0&& a0, …, A ## m && a ## m
           , typename boost_param_parameters_ ## __LINE__ ## name::match<
    -            A0, …, A ## m
    -        >::type = boost_param_parameters_ ## __LINE__ ## name
    +        ::match<A0, …, A ## m>::type
    +        = boost_param_parameters_ ## __LINE__ ## name()
         )
     {
    -    return boost_param_impl ## name(
    +    return boost_param_impl ## __LINE__ ## name(
             boost_param_parameters_ ## __LINE__ ## name()(
                 std::forward<A0>(a0)
    +href="http://en.cppreference.com/w/cpp/utility/forward"
    +>forward<A0>(a0)
               , …
               , std::forward<A ## m>(a ## m)
    +href="http://en.cppreference.com/w/cpp/utility/forward"
    +>forward<A ## m>(a ## m)
             )
         );
     }
    @@ -2406,15 +2431,21 @@ ResultType
     template <typename Args>
     typename boost_param_result_ ## __LINE__ ## name<Args>::type
    -    boost_param_impl ## name(Args const& args)
    +    boost_param_impl ## __LINE__ ## name(Args const& args)
     {
         return boost_param_dispatch_0boost_ ## __LINE__ ## name(
    -        static_cast<ResultType(*)()>(std::nullptr)
    +        static_cast<
    +            typename boost_param_result_ ## __LINE__ ## name<
    +                Args
    +            >::type(*)()
    +        >(std::nullptr)
           , args
           , std::forward<
    -            typename boost::parameter::value_type<
    +href="http://en.cppreference.com/w/cpp/utility/forward">forward<
    +            typename value_type<
                     Args
                   , keyword tag type of required parameter ## 0
    @@ -2423,9 +2454,9 @@ class="docutils literal">forward<
     >0])
           , …
           , std::forward<
    -            typename boost::parameter::value_type<
    +href="http://en.cppreference.com/w/cpp/utility/forward">forward<
    +            typename value_type<
                     Args
                   , keyword tag type of required parameter ## n
    @@ -2454,29 +2485,28 @@ ResultType
         )
     {
         return boost_param_dispatch_0boost_ ## __LINE__ ## name(
    -        static_cast<ResultType(*)()>(std::nullptr)
    +        static_cast<ResultType(*)()>(std::nullptr)
           , (args, keyword object of optional parameter ## n + 1 =
                 default value of optional parameter ## n + 1
             )
           , std::forward< forward< argument name ## 0 ## _type>(
                 argument name ## 0
             )
           , …
           , std::forward< forward< argument name ## n ## _type>(
                 argument name ## n
             )
           , std::forward<
    -            typename boost::parameter::value_type<
    +href="http://en.cppreference.com/w/cpp/utility/forward">forward<
    +            typename value_type<
                     Args
                   , keyword tag type of optional parameter ## n + 1
    @@ -2506,234 +2536,12 @@ ResultType
     >argument name ## m
         )
     
    -

    If BOOST_PARAMETER_HAS_PERFECT_FORWARDING is not -#defined, then:

    -
    -template <typename T>
    -struct boost_param_result_ ## __LINE__ ## name
    -{
    -    typedef result type;
    -};
    -
    -struct boost_param_params_ ## __LINE__ ## name
    -  : boost::parameter::parameters<
    -        list of parameter specifications, based on arguments
    -    >
    -{
    -};
    -
    -typedef boost_param_params_ ## __LINE__ ## name
    -    boost_param_parameters_ ## __LINE__ ## name;
    -
    -template <typename Args>
    -typename boost_param_result_ ## __LINE__ ## name<Args>::type
    -    boost_param_impl ## name(Args const&);
    -
    -template <typename A0, …, typename A ## n>
    -result type
    -    name(
    -        A0 const& a0, …, A ## n const& a ## n
    -      , typename boost_param_parameters_ ## __LINE__ ## name::match<
    -            A0 const, …, A ## n const
    -        >::type = boost_param_parameters_ ## __LINE__ ## name()
    -    )
    -{
    -    return boost_param_impl ## name(
    -        boost_param_parameters_ ## __LINE__ ## name()(
    -            a0, …, a ## n
    -        )
    -    );
    -}
    -
    -… exponential number of overloads …
    -
    -
    -template <typename A0, …, typename A ## n>
    -result type
    -    name(
    -        A0& a0, …, A ## n & a ## n
    -      , typename boost_param_parameters_ ## __LINE__ ## name::match<
    -            A0, …, A ## n
    -        >::type = boost_param_parameters_ ## __LINE__ ## name()
    -    )
    -{
    -    return boost_param_impl ## name(
    -        boost_param_parameters_ ## __LINE__ ## name()(
    -            a0, …, a ## n
    -        )
    -    );
    -}
    -
    -
    -
    -template <typename A0, …, typename A ## m>
    -result type
    -    name(
    -        A0 const& a0, …, A ## m const& ## ; am
    -      , typename boost_param_parameters_ ## __LINE__ ## name::match<
    -            A0 const, …, A ## m const
    -        >::type = boost_param_parameters_ ## __LINE__ ## name()
    -    )
    -{
    -    return boost_param_impl ## name(
    -        boost_param_parameters_ ## __LINE__ ## name()(
    -            a0, …, a ## m
    -        )
    -    );
    -}
    -
    -… exponential number of overloads …
    -
    -
    -template <typename A0, …, typename A ## m>
    -result type
    -    name(
    -        A0& a0, …, A ## m & ## ; am
    -      , typename boost_param_parameters_ ## __LINE__ ## name::match<
    -            A0, …, A ## m
    -        >::type = boost_param_parameters_ ## __LINE__ ## name()
    -    )
    -{
    -    return boost_param_impl ## name(
    -        boost_param_parameters_ ## __LINE__ ## name()(
    -            a0, …, a ## m
    -        )
    -    );
    -}
    -
    -template <
    -    typename ResultType
    -  , typename Args
    -  , typename argument name ## 0 ## _type
    -  , …
    -  , typename argument name ## n ## _type
    ->
    -ResultType
    -    boost_param_dispatch_0boost_ ## __LINE__ ## name(
    -        (ResultType(*)())
    -      , Args const& args
    -      , argument name ## 0 ## _type& argument name ## 0
    -      , …
    -      , argument name ## n ## _type& argument name ## n
    -    );
    -
    -
    -
    -template <
    -    typename ResultType
    -  , typename Args
    -  , typename argument name ## 0 ## _type
    -  , …
    -  , typename argument name ## m ## _type
    ->
    -ResultType
    -    boost_param_dispatch_0boost_ ## __LINE__ ## name(
    -        (ResultType(*)())
    -      , Args const& args
    -      , argument name ## 0 ## _type& argument name ## 0
    -      , …
    -      , argument name ## m ## _type& argument name ## m
    -    );
    -
    -template <typename Args>
    -typename boost_param_result_ ## __LINE__ ## name<Args>::type
    -    boost_param_impl ## name(Args const& args)
    -{
    -    return boost_param_dispatch_0boost_ ## __LINE__ ## name(
    -        static_cast<ResultType(*)()>(std::nullptr)
    -      , args
    -      , args[ keyword object of required parameter ## 0]
    -      , …
    -      , args[ keyword object of required parameter ## n]
    -    );
    -}
    -
    -template <
    -    typename ResultType
    -  , typename Args
    -  , typename argument name ## 0 ## _type
    -  , …
    -  , typename argument name ## n ## _type
    ->
    -ResultType
    -    boost_param_dispatch_0boost_ ## __LINE__ ## name(
    -        (ResultType(*)())
    -      , Args const& args
    -      , argument name ## 0 ## _type& argument name ## 0
    -      , …
    -      , argument name ## n ## _type& argument name ## n
    -    )
    -{
    -    return boost_param_dispatch_0boost_ ## __LINE__ ## name(
    -        static_cast<ResultType(*)()>(std::nullptr)
    -      , (args, keyword object of optional parameter ## n + 1 =
    -            default value of optional parameter ## n + 1
    -        )
    -      , argument name ## 0
    -      , …
    -      , argument name ## n
    -      , default value of optional parameter ## n + 1
    -    );
    -}
    -
    -
    -
    -template <
    -    typename ResultType
    -  , typename Args
    -  , typename argument name ## 0 ## _type
    -  , …
    -  , typename argument name ## m ## _type
    ->
    -ResultType
    -    boost_param_dispatch_0boost_ ## __LINE__ ## name(
    -        (ResultType(*)())
    -      , Args const& args
    -      , argument name ## 0 ## _type& argument name ## 0
    -      , …
    -      , argument name ## m ## _type& argument name ## m
    -    )
    -
    -

    The test/preprocessor.cpp, test/preprocessor_deduced.cpp, -and test/preprocessor_eval_category.cpp test programs demonstrate proper -usage of this macro.

    -

    6.2   7.2   BOOST_PARAMETER_MEMBER_FUNCTION(result, name, tag_namespace, arguments)

    @@ -2748,181 +2556,345 @@ href="../../../../boost/parameter/preprocessor.hpp"
    -

    Same as BOOST_PARAMETER_FUNCTION, except:

    -
      -
    • name may be qualified by the -static keyword to declare the member -function and its helpers as not associated with any object of the enclosing -type.
    • -
    • Expansion of this macro omits all forward declarations of the front-end -implementation and dispatch functions.
    • -
    +

    Generates a member function that can take in positional arguments, composed +arguments, named arguments, and deduced arguments.

    + +++ + + + + + +
    Example usage:
      +

    The return type of each of the following function templates falls under a +different value category.

    +
    +template <std::size_t N>
    +std::bitset<N + 1> rvalue_bitset()
    +{
    +    return std::bitset<N + 1>();
    +}
    +
    +template <std::size_t N>
    +std::bitset<N + 1> const rvalue_const_bitset()
    +{
    +    return std::bitset<N + 1>();
    +}
    +
    +template <std::size_t N>
    +std::bitset<N + 1>& lvalue_bitset()
    +{
    +    static std::bitset<N + 1> lset = std::bitset<N + 1>();
    +    return lset;
    +}
    +
    +template <std::size_t N>
    +std::bitset<N + 1> const& lvalue_const_bitset()
    +{
    +    static std::bitset<N + 1> const clset = std::bitset<N + 1>();
    +    return clset;
    +}
    +
    +

    The U::evaluate_category static member +function template has a simple job: to return the correct value category when +passed in an object returned by one of the functions defined above. Assume +that BOOST_PARAMETER_HAS_PERFECT_FORWARDING is defined.

    +
    +enum invoked
    +{
    +    passed_by_lvalue_reference_to_const
    +  , passed_by_lvalue_reference
    +  , passed_by_rvalue_reference_to_const
    +  , passed_by_rvalue_reference
    +};
    +
    +struct U
    +{
    +    template <std::size_t N>
    +    static invoked evaluate_category(std::bitset<N + 1> const&)
    +    {
    +        return passed_by_lvalue_reference_to_const;
    +    }
    +
    +    template <std::size_t N>
    +    static invoked evaluate_category(std::bitset<N + 1>&)
    +    {
    +        return passed_by_lvalue_reference;
    +    }
    +
    +    template <std::size_t N>
    +    static invoked evaluate_category(std::bitset<N + 1> const&&)
    +    {
    +        return passed_by_rvalue_reference_to_const;
    +    }
    +
    +    template <std::size_t N>
    +    static invoked evaluate_category(std::bitset<N + 1>&&)
    +    {
    +        return passed_by_rvalue_reference;
    +    }
    +};
    +
    +

    Define the named parameters that will comprise the argument specification +that this macro will use. Ensure that all their tag types are in the same +namespace, which is kw in this case. The +identifiers with leading underscores can be passed to the bracket operator of +args to extract the same argument to which +the corresponding named parameter (without underscores) is bound, as will be +shown later.

    +
    +BOOST_PARAMETER_NAME((_lrc, kw) in(lrc))
    +BOOST_PARAMETER_NAME((_lr, kw) in_out(lr))
    +BOOST_PARAMETER_NAME((_rrc, kw) in(rrc))
    +BOOST_PARAMETER_NAME((_rr, kw) consume(rr))
    +
    +

    Use the macro as a substitute for a normal static member function header. Enclose the return type bool in parentheses. For each parameter, also +enclose the expected value type in parentheses. Since the value types are +mutually exclusive, you can wrap the parameters in a (deduced …) clause. Otherwise, just as with a +normal function, the order in which you specify the parameters determines +their position. Also, just as with a normal function, optional parameters +have default values, whereas required parameters do not. Within the function +body, either simply use the parameter name or pass the matching identifier +with the leading underscore to the bracket operator of args to extract the corresponding +argument. Note that the second method doesn't require std::forward to preserve value categories.

    +
    +struct B
    +{
    +    BOOST_PARAMETER_MEMBER_FUNCTION((bool), static evaluate, kw,
    +        (deduced
    +            (required
    +                (lrc, (std::bitset<1>))
    +                (lr, (std::bitset<2>))
    +            )
    +            (optional
    +                (rrc, (std::bitset<3>), rvalue_const_bitset<2>())
    +                (rr, (std::bitset<4>), rvalue_bitset<3>())
    +            )
    +        )
    +    )
    +    {
    +        BOOST_TEST_EQ(
    +            passed_by_lvalue_reference_to_const
    +          , U::evaluate_category<0>(lrc)
    +        );
    +        BOOST_TEST_EQ(
    +            passed_by_lvalue_reference
    +          , U::evaluate_category<1>(lr)
    +        );
    +        BOOST_TEST_EQ(
    +            passed_by_rvalue_reference_to_const
    +          , U::evaluate_category<2>(std::forward<rrc0_type>(rrc0))
    +        );
    +        BOOST_TEST_EQ(
    +            passed_by_rvalue_reference
    +          , U::evaluate_category<3>(args[_rr0])
    +        );
    +
    +        return true;
    +    }
    +};
    +
    +

    The following function calls are legal.

    +
    +B::evaluate(  // positional arguments
    +    lvalue_const_bitset<0>()
    +  , lvalue_bitset<1>()
    +  , rvalue_const_bitset<2>()
    +  , rvalue_bitset<3>()
    +);
    +B::evaluate(  // positional arguments
    +    lvalue_const_bitset<0>()
    +  , lvalue_bitset<1>()
    +);
    +B::evaluate((  // composed arguments
    +    _rr0 = rvalue_bitset<3>()
    +  , _lrc0 = lvalue_const_bitset<0>()
    +  , _lr0 = lvalue_bitset<1>()
    +  , _rrc0 = rvalue_const_bitset<2>()
    +));
    +B::evaluate(  // named arguments
    +    _rr0 = rvalue_bitset<3>()
    +  , _lrc0 = lvalue_const_bitset<0>()
    +  , _lr0 = lvalue_bitset<1>()
    +  , _rrc0 = rvalue_const_bitset<2>()
    +);
    +B::evaluate(  // named arguments
    +    _lr0 = lvalue_bitset<1>()
    +  , _lrc0 = lvalue_const_bitset<0>()
    +);
    +
    +

    Because the parameters were wrapped in a (deduced …) clause, the following function calls are also legal.

    +
    +B::evaluate(  // deduced arguments
    +    rvalue_bitset<3>()
    +  , lvalue_const_bitset<0>()
    +  , lvalue_bitset<1>()
    +  , rvalue_const_bitset<2>()
    +);
    +B::evaluate(  // deduced arguments
    +    lvalue_bitset<1>()
    +  , lvalue_const_bitset<0>()
    +);
    +

    The test/preprocessor.cpp and test/preprocessor_eval_category.cpp test programs demonstrate proper usage of this macro.

    - -
    -

    6.3   BOOST_PARAMETER_CONST_MEMBER_FUNCTION(result, name, -tag_namespace, arguments)

    - --- - - - + - -
    Defined in:boost/parameter/preprocessor.hpp
    -

    Same as BOOST_PARAMETER_MEMBER_FUNCTION, -except that the overloaded forwarding member functions and their helper -methods are const-qualified.

    -

    The test/preprocessor.cpp test program demonstrates proper usage of this -macro.

    -
    -
    -

    6.4   BOOST_PARAMETER_FUNCTION_CALL_OPERATOR(result, -tag_ns, arguments)

    - --- - - - - -
    Defined in:boost/parameter/preprocessor.hpp
    -

    Same as BOOST_PARAMETER_MEMBER_FUNCTION, -except that the name of the forwarding member function overloads is -operator().

    - --- - - + - -
    Generated names in enclosing scope:Macro parameters:
      -
      -
    • boost_param_result_ ## __LINE__ ## -operator
    • -
    • boost_param_params_ ## __LINE__ ## -operator
    • -
    • boost_param_parameters_ ## __LINE__ ## -operator
    • -
    • boost_param_impl ## operator
    • -
    • boost_param_dispatch_0boost_ ## __LINE__ ## -operator
    • -
    • boost_param_dispatch_1boost_ ## __LINE__ ## -operator
    • +
        +
      • result is the parenthesized return type +of the function.
      • +
      • name is the base name of the function; +it determines the name of the generated forwarding functions. name may be qualified by the static keyword to declare the member function +and its helpers as not associated with any object of the enclosing type.
      • +
      • tag_namespace is the namespace in which +the keywords used by the function resides.
      • +
      • arguments is a list of argument +specifiers, as defined below.
    -

    The test/preprocessor.cpp test program demonstrates proper usage of this -macro.

    -
    -
    -

    6.5   BOOST_PARAMETER_CONST_FUNCTION_CALL_OPERATOR(result, -tag_ns, arguments)

    - --- - - - - -
    Defined in:boost/parameter/preprocessor.hpp
    -

    Same as BOOST_PARAMETER_FUNCTION_CALL_OPERATOR, -except that the overloaded function call operators and their helper methods -are const-qualified.

    -

    The test/preprocessor.cpp and test/preprocessor_eval_cat_8.cpp test programs demonstrate proper usage -of this macro.

    -
    -
    -

    6.6   BOOST_PARAMETER_CONSTRUCTOR(cls, impl, tag_namespace, -arguments)

    - --- - - - - - -
    Defined in:boost/parameter/preprocessor.hpp
    - --- - - + - - - - - - - @@ -2938,125 +2910,1998 @@ determined from arguments.
  • m denotes the maximum arity, as determined from arguments.
  • -

    If BOOST_PARAMETER_HAS_PERFECT_FORWARDING is -#defined, then:

    -struct boost_param_params_ ## __LINE__ ## ctor
    -  : boost::parameter::parameters<
    +template <typename T>
    +struct boost_param_result_ ## __LINE__ ## name
    +{
    +    typedef result type;
    +};
    +
    +struct boost_param_params_ ## __LINE__ ## name
    +  : parameters<
             list of parameter specifications, based on arguments
         >
     {
     };
     
     typedef boost_param_params_ ## __LINE__ ## name
    -    constructor_parameters ## __LINE__;
    +    boost_param_parameters_ ## __LINE__ ## name;
     
     template <typename A0, …, typename A ## n>
    -cls(A0&& a0, …, A ## n && a ## n)
    -  : impl(
    -        constructor_parameters ## __LINE__(
    -            std::forward<A0>(a0)
    -          , …
    -          , std::forward<A ## n>(a ## n)
    -        )
    +result type
    +    name(
    +        A0&& a0, …, A ## n && a ## n
    +      , typename boost_param_parameters_ ## __LINE__ ## name
    +        ::match<A0, …, A ## n>::type
    +        = boost_param_parameters_ ## __LINE__ ## name()
         )
     {
    -}
    -
    -
    -
    -template <typename A0, …, typename A ## m>
    -cls(A0&& a0, …, A ## m&& a ## m)
    -  : impl(
    -        constructor_parameters ## __LINE__(
    +    return this->boost_param_impl ## __LINE__ ## name(
    +        boost_param_parameters_ ## __LINE__ ## name()(
                 std::forward<A0>(a0)
    +href="http://en.cppreference.com/w/cpp/utility/forward"
    +>forward<A0>(a0)
               , …
               , std::forward<A ## m>(a ## m)
    +href="http://en.cppreference.com/w/cpp/utility/forward"
    +>forward<A ## n>(a ## n)
             )
    +    );
    +}
    +
    +
    +
    +template <typename A0, …, typename A ## m>
    +result type
    +    name(
    +        A0&& a0, …, A ## m && a ## m
    +      , typename boost_param_parameters_ ## __LINE__ ## name
    +        ::match<A0, …, A ## m>::type
    +        = boost_param_parameters_ ## __LINE__ ## name()
         )
     {
    -}
    -
    -

    If BOOST_PARAMETER_HAS_PERFECT_FORWARDING is not -#defined, then:

    -
    -struct boost_param_params_ ## __LINE__ ## ctor
    -  : boost::parameter::parameters<
    -        list of parameter specifications, based on arguments
    -    >
    -{
    -};
    -
    -typedef boost_param_params_ ## __LINE__ ## name
    -    constructor_parameters ## __LINE__;
    -
    -template <typename A0, …, typename A ## n>
    -cls(A0 const& a0, …, A ## n const& a ## n)
    -  : impl(constructor_parameters ## __LINE__(a0, …, a ## n))
    -{
    +    return this->boost_param_impl ## __LINE__ ## name(
    +        boost_param_parameters_ ## __LINE__ ## name()(
    +            std::forward<A0>(a0)
    +          , …
    +          , std::forward<A ## m>(a ## m)
    +        )
    +    );
     }
     
    -… exponential number of overloads …
    -
    -
    -template <typename A0, …, typename A ## n>
    -cls(A0& a0, …, A ## n & a ## n)
    -  : impl(constructor_parameters ## __LINE__(a0, …, a ## n))
    +template <typename Args>
    +typename boost_param_result_ ## __LINE__ ## name<Args>::type
    +    boost_param_impl ## __LINE__ ## name(Args const& args)
     {
    +    return this->boost_param_dispatch_0boost_ ## __LINE__ ## name(
    +        static_cast<
    +            typename boost_param_result_ ## __LINE__ ## name<
    +                Args
    +            >::type(*)()
    +        >(std::nullptr)
    +      , args
    +      , std::forward<
    +            typename value_type<
    +                Args
    +              , keyword tag type of required parameter ## 0
    +            >::type
    +        >(args[ keyword object of required parameter ## 0])
    +      , …
    +      , std::forward<
    +            typename value_type<
    +                Args
    +              , keyword tag type of required parameter ## n
    +            >::type
    +        >(args[ keyword object of required parameter ## n])
    +    );
    +}
    +
    +template <
    +    typename ResultType
    +  , typename Args
    +  , typename argument name ## 0 ## _type
    +  , …
    +  , typename argument name ## n ## _type
    +>
    +ResultType
    +    boost_param_dispatch_0boost_ ## __LINE__ ## name(
    +        (ResultType(*)())
    +      , Args const& args
    +      , argument name ## 0 ## _type&& argument name ## 0
    +      , …
    +      , argument name ## n ## _type&& argument name ## n
    +    )
    +{
    +    return this->boost_param_dispatch_0boost_ ## __LINE__ ## name(
    +        static_cast<ResultType(*)()>(std::nullptr)
    +      , (args, keyword object of optional parameter ## n + 1 =
    +            default value of optional parameter ## n + 1
    +        )
    +      , std::forward< argument name ## 0 ## _type>(
    +            argument name ## 0
    +        )
    +      , …
    +      , std::forward< argument name ## n ## _type>(
    +            argument name ## n
    +        )
    +      , std::forward<
    +            typename value_type<
    +                Args
    +              , keyword tag type of optional parameter ## n + 1
    +            >::type
    +        >(default value of optional parameter ## n + 1)
    +    );
     }
     
     
     
    -template <typename A0, …, typename A ## m>
    -cls(A0 const& a0, …, A ## m const& a ## m)
    -  : impl(constructor_parameters ## __LINE__(a0, …, a ## m))
    -{
    -}
    -
    -… exponential number of overloads …
    -
    -
    -template <typename A0, …, typename A ## m>
    -cls(A0& a0, …, A ## m & a ## m)
    -  : impl(constructor_parameters ## __LINE__(a0, …, a ## m))
    -{
    -}
    +template <
    +    typename ResultType
    +  , typename Args
    +  , typename argument name ## 0 ## _type
    +  , …
    +  , typename argument name ## m ## _type
    +>
    +ResultType
    +    boost_param_dispatch_0boost_ ## __LINE__ ## name(
    +        (ResultType(*)())
    +      , Args const& args
    +      , argument name ## 0 ## _type&& argument name ## 0
    +      , …
    +      , argument name ## m ## _type&& argument name ## m
    +    )
     
    + +
    Requires:Argument specifiers syntax:
      -

    cls is the name of this -class. impl is the parenthesized -implementation base class for cls. tag_namespace is the namespace -in which the keywords used by the function resides. arguments is a list of -argument-specifiers, as defined in BOOST_PARAMETER_FUNCTION except that -optional-specifier no longer includes default-value. It is -up to the delegate constructor in impl to -determine the default value of all optional arguments.

    -
    Generated names in enclosing scope:
      -
      -
    • boost_param_params_ ## __LINE__ ## -ctor
    • -
    • constructor_parameters ## __LINE__
    • +
      +argument-specifiers ::= specifier-group0 {specifier-group0}
      +
      +specifier-group0 ::= specifier-group1 |
      +    (
      +        '(' 'deduced'
      +            specifier-group1 {specifier-group1}
      +        ')'
      +    )
      +
      +specifier-group1 ::=
      +    (
      +        '(' 'optional'
      +            optional-specifier {optional-specifier}
      +        ')'
      +    ) | (
      +        '(' 'required'
      +            required-specifier {required-specifier}
      +        ')'
      +    )
      +
      +optional-specifier ::=
      +    '('
      +        argument-name ',' restriction ',' default-value
      +    ')'
      +
      +required-specifier ::=
      +    '(' argument-name ',' restriction ')'
      +
      +restriction ::=
      +    ( '*' '(' mfc ')' ) |
      +    ( '(' typename ')' ) |
      +    '*'
      +
      +
        +
      • argument-name is any valid C++ +identifier.
      • +
      • default-value is any valid C++ +expression; if necessary, user code can compute it in terms of +previous-name ## _type, where +previous-name is the +argument-name in a previous +specifier-group0 or +specifier-group1. This expression will +be invoked exactly once.
      • +
      • mfc is an MPL Binary +Metafunction Class whose first argument will be the type of the +corresponding argument-name, whose second +argument will be the entire ArgumentPack, and whose return type is a +Boolean Integral +Concept; however, user code cannot compute +mfc in terms of +previous-name ## _type.
      • +
      • type-name is either the name of a +target type or an MPL Binary +Metafunction Class whose first argument will be the type of the +corresponding argument-name, whose second +argument will be the entire ArgumentPack, and whose return type is the +target type. If restriction uses this form, then the type of the generated name argument-name ## _type will be computed in terms +of the target type, and the generated reference +argument-name (but not its corresponding +entry in args) will be cast to that +type.
    +++ + + + + + +
    Defined in:boost/parameter/preprocessor.hpp
    +

    Generates a member function that can take in positional arguments, composed +arguments, named arguments, and deduced arguments.

    + +++ + + + + + + + + + + + + + + + + + + + + + + +
    Example usage:
      +

    The return type of each of the following function templates falls under a +different value category.

    +
    +template <std::size_t N>
    +std::bitset<N + 1> rvalue_bitset()
    +{
    +    return std::bitset<N + 1>();
    +}
    +
    +template <std::size_t N>
    +std::bitset<N + 1> const rvalue_const_bitset()
    +{
    +    return std::bitset<N + 1>();
    +}
    +
    +template <std::size_t N>
    +std::bitset<N + 1>& lvalue_bitset()
    +{
    +    static std::bitset<N + 1> lset = std::bitset<N + 1>();
    +    return lset;
    +}
    +
    +template <std::size_t N>
    +std::bitset<N + 1> const& lvalue_const_bitset()
    +{
    +    static std::bitset<N + 1> const clset = std::bitset<N + 1>();
    +    return clset;
    +}
    +
    +

    The U::evaluate_category static member +function template has a simple job: to return the correct value category when +passed in an object returned by one of the functions defined above. Assume +that BOOST_PARAMETER_HAS_PERFECT_FORWARDING is defined.

    +
    +enum invoked
    +{
    +    passed_by_lvalue_reference_to_const
    +  , passed_by_lvalue_reference
    +  , passed_by_rvalue_reference_to_const
    +  , passed_by_rvalue_reference
    +};
    +
    +struct U
    +{
    +    template <std::size_t N>
    +    static invoked evaluate_category(std::bitset<N + 1> const&)
    +    {
    +        return passed_by_lvalue_reference_to_const;
    +    }
    +
    +    template <std::size_t N>
    +    static invoked evaluate_category(std::bitset<N + 1>&)
    +    {
    +        return passed_by_lvalue_reference;
    +    }
    +
    +    template <std::size_t N>
    +    static invoked evaluate_category(std::bitset<N + 1> const&&)
    +    {
    +        return passed_by_rvalue_reference_to_const;
    +    }
    +
    +    template <std::size_t N>
    +    static invoked evaluate_category(std::bitset<N + 1>&&)
    +    {
    +        return passed_by_rvalue_reference;
    +    }
    +};
    +
    +

    Define the named parameters that will comprise the argument specification +that this macro will use. Ensure that all their tag types are in the same +namespace, which is kw in this case. The +identifiers with leading underscores can be passed to the bracket operator of +args to extract the same argument to which +the corresponding named parameter (without underscores) is bound, as will be +shown later.

    +
    +BOOST_PARAMETER_NAME((_lrc, kw) in(lrc))
    +BOOST_PARAMETER_NAME((_lr, kw) in_out(lr))
    +BOOST_PARAMETER_NAME((_rrc, kw) in(rrc))
    +BOOST_PARAMETER_NAME((_rr, kw) consume(rr))
    +
    +

    Use the macro as a substitute for a normal const member function header. Enclose the return type bool in parentheses. For each parameter, also +enclose the expected value type in parentheses. Since the value types are +mutually exclusive, you can wrap the parameters in a (deduced …) clause. Otherwise, just as with a +normal function, the order in which you specify the parameters determines +their position. Also, just as with a normal function, optional parameters +have default values, whereas required parameters do not. Within the function +body, either simply use the parameter name or pass the matching identifier +with the leading underscore to the bracket operator of args to extract the corresponding +argument. Note that the second method doesn't require std::forward to preserve value categories.

    +
    +struct B
    +{
    +    B()
    +    {
    +    }
    +
    +    BOOST_PARAMETER_CONST_MEMBER_FUNCTION((bool), evaluate, kw,
    +        (deduced
    +            (required
    +                (lrc, (std::bitset<1>))
    +                (lr, (std::bitset<2>))
    +            )
    +            (optional
    +                (rrc, (std::bitset<3>), rvalue_const_bitset<2>())
    +                (rr, (std::bitset<4>), rvalue_bitset<3>())
    +            )
    +        )
    +    )
    +    {
    +        BOOST_TEST_EQ(
    +            passed_by_lvalue_reference_to_const
    +          , U::evaluate_category<0>(lrc)
    +        );
    +        BOOST_TEST_EQ(
    +            passed_by_lvalue_reference
    +          , U::evaluate_category<1>(lr)
    +        );
    +        BOOST_TEST_EQ(
    +            passed_by_rvalue_reference_to_const
    +          , U::evaluate_category<2>(std::forward<rrc0_type>(rrc0))
    +        );
    +        BOOST_TEST_EQ(
    +            passed_by_rvalue_reference
    +          , U::evaluate_category<3>(args[_rr0])
    +        );
    +
    +        return true;
    +    }
    +};
    +
    +

    The following function calls are legal.

    +
    +B const b = B();
    +b.evaluate(  // positional arguments
    +    lvalue_const_bitset<0>()
    +  , lvalue_bitset<1>()
    +  , rvalue_const_bitset<2>()
    +  , rvalue_bitset<3>()
    +);
    +b.evaluate(  // positional arguments
    +    lvalue_const_bitset<0>()
    +  , lvalue_bitset<1>()
    +);
    +b.evaluate((  // composed arguments
    +    _rr0 = rvalue_bitset<3>()
    +  , _lrc0 = lvalue_const_bitset<0>()
    +  , _lr0 = lvalue_bitset<1>()
    +  , _rrc0 = rvalue_const_bitset<2>()
    +));
    +b.evaluate(  // named arguments
    +    _rr0 = rvalue_bitset<3>()
    +  , _lrc0 = lvalue_const_bitset<0>()
    +  , _lr0 = lvalue_bitset<1>()
    +  , _rrc0 = rvalue_const_bitset<2>()
    +);
    +b.evaluate(  // named arguments
    +    _lr0 = lvalue_bitset<1>()
    +  , _lrc0 = lvalue_const_bitset<0>()
    +);
    +
    +

    Because the parameters were wrapped in a (deduced …) clause, the following function calls are also legal.

    +
    +b.evaluate(  // deduced arguments
    +    rvalue_bitset<3>()
    +  , lvalue_const_bitset<0>()
    +  , lvalue_bitset<1>()
    +  , rvalue_const_bitset<2>()
    +);
    +b.evaluate(  // deduced arguments
    +    lvalue_bitset<1>()
    +  , lvalue_const_bitset<0>()
    +);
    +
    +

    The test/preprocessor.cpp test program demonstrates proper usage of this +macro.

    +
    Macro parameters:
      +
      +
    • result is the parenthesized return type +of the function.
    • +
    • name is the base name of the function; +it determines the name of the generated forwarding functions.
    • +
    • tag_namespace is the namespace in which +the keywords used by the function resides.
    • +
    • arguments is a list of argument +specifiers, as defined below.
    • +
    +
    Argument specifiers syntax:
      +
    +argument-specifiers ::= specifier-group0 {specifier-group0}
    +
    +specifier-group0 ::= specifier-group1 |
    +    (
    +        '(' 'deduced'
    +            specifier-group1 {specifier-group1}
    +        ')'
    +    )
    +
    +specifier-group1 ::=
    +    (
    +        '(' 'optional'
    +            optional-specifier {optional-specifier}
    +        ')'
    +    ) | (
    +        '(' 'required'
    +            required-specifier {required-specifier}
    +        ')'
    +    )
    +
    +optional-specifier ::=
    +    '('
    +        argument-name ',' restriction ',' default-value
    +    ')'
    +
    +required-specifier ::=
    +    '(' argument-name ',' restriction ')'
    +
    +restriction ::=
    +    ( '*' '(' mfc ')' ) |
    +    ( '(' typename ')' ) |
    +    '*'
    +
    +
      +
    • argument-name is any valid C++ +identifier.
    • +
    • default-value is any valid C++ +expression; if necessary, user code can compute it in terms of +previous-name ## _type, where +previous-name is the +argument-name in a previous +specifier-group0 or +specifier-group1. This expression will +be invoked exactly once.
    • +
    • mfc is an MPL Binary +Metafunction Class whose first argument will be the type of the +corresponding argument-name, whose second +argument will be the entire ArgumentPack, and whose return type is a +Boolean Integral +Concept; however, user code cannot compute +mfc in terms of +previous-name ## _type.
    • +
    • type-name is either the name of a +target type or an MPL Binary +Metafunction Class whose first argument will be the type of the +corresponding argument-name, whose second +argument will be the entire ArgumentPack, and whose return type is the +target type. If restriction uses this form, then the type of the generated name argument-name ## _type will be computed in terms +of the target type, and the generated reference +argument-name (but not its corresponding +entry in args) will be cast to that +type.
    • +
    +
    +
    +
    Approximate expansion:
    +
    +

    Where:

    +
      +
    • n denotes the minimum arity, as +determined from arguments.
    • +
    • m denotes the maximum arity, as +determined from arguments.
    • +
    +
    +template <typename T>
    +struct boost_param_result_const_ ## __LINE__ ## name
    +{
    +    typedef result type;
    +};
    +
    +struct boost_param_params_const_ ## __LINE__ ## name
    +  : parameters<
    +        list of parameter specifications, based on arguments
    +    >
    +{
    +};
    +
    +typedef boost_param_params_const_ ## __LINE__ ## name
    +    boost_param_parameters_const_ ## __LINE__ ## name;
    +
    +template <typename A0, …, typename A ## n>
    +result type
    +    name(
    +        A0&& a0, …, A ## n && a ## n
    +      , typename boost_param_parameters_const_ ## __LINE__ ## name
    +        ::match<A0, …, A ## n>::type
    +        = boost_param_parameters_const_ ## __LINE__ ## name()
    +    ) const
    +{
    +    return this->boost_param_impl_const ## __LINE__ ## name(
    +        boost_param_parameters_const_ ## __LINE__ ## name()(
    +            std::forward<A0>(a0)
    +          , …
    +          , std::forward<A ## n>(a ## n)
    +        )
    +    );
    +}
    +
    +
    +
    +template <typename A0, …, typename A ## m>
    +result type
    +    name(
    +        A0&& a0, …, A ## m && a ## m
    +      , typename boost_param_parameters_const_ ## __LINE__ ## name
    +        ::match<A0, …, A ## m>::type
    +        = boost_param_parameters_const_ ## __LINE__ ## name()
    +    ) const
    +{
    +    return this->boost_param_impl_const ## __LINE__ ## name(
    +        boost_param_parameters_const_ ## __LINE__ ## name()(
    +            std::forward<A0>(a0)
    +          , …
    +          , std::forward<A ## m>(a ## m)
    +        )
    +    );
    +}
    +
    +template <typename Args>
    +typename boost_param_result_const_ ## __LINE__ ## name<Args>::type
    +    boost_param_impl_const ## __LINE__ ## name(Args const& args) const
    +{
    +    return this->
    +    boost_param_dispatch_const_0boost_ ## __LINE__ ## name(
    +        static_cast<
    +            typename boost_param_result_const_ ## __LINE__ ## name<
    +                Args
    +            >::type(*)()
    +        >(std::nullptr)
    +      , args
    +      , std::forward<
    +            typename value_type<
    +                Args
    +              , keyword tag type of required parameter ## 0
    +            >::type
    +        >(args[ keyword object of required parameter ## 0])
    +      , …
    +      , std::forward<
    +            typename value_type<
    +                Args
    +              , keyword tag type of required parameter ## n
    +            >::type
    +        >(args[ keyword object of required parameter ## n])
    +    );
    +}
    +
    +template <
    +    typename ResultType
    +  , typename Args
    +  , typename argument name ## 0 ## _type
    +  , …
    +  , typename argument name ## n ## _type
    +>
    +ResultType
    +    boost_param_dispatch_const_0boost_ ## __LINE__ ## name(
    +        (ResultType(*)())
    +      , Args const& args
    +      , argument name ## 0 ## _type&& argument name ## 0
    +      , …
    +      , argument name ## n ## _type&& argument name ## n
    +    ) const
    +{
    +    return this->
    +    boost_param_dispatch_const_0boost_ ## __LINE__ ## name(
    +        static_cast<ResultType(*)()>(std::nullptr)
    +      , (args, keyword object of optional parameter ## n + 1 =
    +            default value of optional parameter ## n + 1
    +        )
    +      , std::forward< argument name ## 0 ## _type>(
    +            argument name ## 0
    +        )
    +      , …
    +      , std::forward< argument name ## n ## _type>(
    +            argument name ## n
    +        )
    +      , std::forward<
    +            typename value_type<
    +                Args
    +              , keyword tag type of optional parameter ## n + 1
    +            >::type
    +        >(default value of optional parameter ## n + 1)
    +    );
    +}
    +
    +
    +
    +template <
    +    typename ResultType
    +  , typename Args
    +  , typename argument name ## 0 ## _type
    +  , …
    +  , typename argument name ## m ## _type
    +>
    +ResultType
    +    boost_param_dispatch_const_0boost_ ## __LINE__ ## name(
    +        (ResultType(*)())
    +      , Args const& args
    +      , argument name ## 0 ## _type&& argument name ## 0
    +      , …
    +      , argument name ## m ## _type&& argument name ## m
    +    ) const
    +
    +
    +
    +
    +
    +

    7.4   BOOST_PARAMETER_FUNCTION_CALL_OPERATOR(result, +tag_ns, arguments)

    + +++ + + + + + +
    Defined in:boost/parameter/preprocessor.hpp
    +

    Generates a function call operator that can take in positional arguments, +composed arguments, named arguments, and deduced arguments.

    + +++ + + + + + + + + + + + + + + + + + + + + + + +
    Example usage:
      +

    Define the named parameters that will comprise the argument specification +that this macro will use. Ensure that all their tag types are in the same +namespace, which is tag by default.

    +
    +BOOST_PARAMETER_NAME(y)
    +BOOST_PARAMETER_NAME(z)
    +
    +

    Use the macro as a substitute for a normal function call operator +header. Enclose the return type in parentheses. For each parameter, also +enclose the expected value type in parentheses. Since the value types are +mutually exclusive, you can wrap the parameters in a (deduced …) clause. This is especially useful +when implementing multiple Boost.Parameter-enabled function call operator +overloads.

    +
    +class char_reader
    +{
    +    int index;
    +    char const* key;
    +
    + public:
    +    explicit char_reader(char const* k) : index(0), key(k)
    +    {
    +    }
    +
    +    BOOST_PARAMETER_FUNCTION_CALL_OPERATOR((void), tag,
    +        (deduced
    +            (required
    +                (y, (int))
    +                (z, (char const*))
    +            )
    +        )
    +    )
    +    {
    +        this->index = y;
    +        this->key = z;
    +    }
    +
    +    BOOST_PARAMETER_CONST_FUNCTION_CALL_OPERATOR((char), tag,
    +        (deduced
    +            (required
    +                (y, (bool))
    +                (z, (std::map<char const*,std::string>))
    +            )
    +        )
    +    )
    +    {
    +        return y ? (
    +            (z.find(this->key)->second)[this->index]
    +        ) : this->key[this->index];
    +    }
    +};
    +
    +

    As with regular argument-dependent lookup, the value types of the arguments +passed in determine which function call operator overload gets invoked.

    +
    +char const* keys[] = {"foo", "bar", "baz"};
    +std::map<char const*,std::string> k2s;
    +k2s[keys[0]] = std::string>("qux");
    +k2s[keys[1]] = std::string>("wmb");
    +k2s[keys[2]] = std::string>("zxc");
    +char_reader r(keys[0]);
    +
    +// positional arguments
    +BOOST_TEST_EQ('q', (r(true, k2s)));
    +BOOST_TEST_EQ('f', (r(false, k2s)));
    +
    +// named arguments
    +r(_z = keys[1], _y = 1);
    +BOOST_TEST_EQ('m', (r(_z = k2s, _y = true)));
    +BOOST_TEST_EQ('a', (r(_z = k2s, _y = false)));
    +
    +// deduced arguments
    +r(keys[2], 2);
    +BOOST_TEST_EQ('c', (r(k2s, true)));
    +BOOST_TEST_EQ('z', (r(k2s, false)));
    +
    +

    The test/preprocessor.cpp and test/preprocessor_deduced.cpp +test programs demonstrate proper usage of this macro.

    +
    Macro parameters:
      +
      +
    • result is the parenthesized return type +of the function call operator.
    • +
    • tag_namespace is the namespace in which +the keywords used by the function call operator resides.
    • +
    • arguments is a list of argument +specifiers, as defined below.
    • +
    +
    Argument specifiers syntax:
      +
    +argument-specifiers ::= specifier-group0 {specifier-group0}
    +
    +specifier-group0 ::= specifier-group1 |
    +    (
    +        '(' 'deduced'
    +            specifier-group1 {specifier-group1}
    +        ')'
    +    )
    +
    +specifier-group1 ::=
    +    (
    +        '(' 'optional'
    +            optional-specifier {optional-specifier}
    +        ')'
    +    ) | (
    +        '(' 'required'
    +            required-specifier {required-specifier}
    +        ')'
    +    )
    +
    +optional-specifier ::=
    +    '('
    +        argument-name ',' restriction ',' default-value
    +    ')'
    +
    +required-specifier ::=
    +    '(' argument-name ',' restriction ')'
    +
    +restriction ::=
    +    ( '*' '(' mfc ')' ) |
    +    ( '(' typename ')' ) |
    +    '*'
    +
    +
      +
    • argument-name is any valid C++ +identifier.
    • +
    • default-value is any valid C++ +expression; if necessary, user code can compute it in terms of +previous-name ## _type, where +previous-name is the +argument-name in a previous +specifier-group0 or +specifier-group1. This expression will +be invoked exactly once.
    • +
    • mfc is an MPL Binary +Metafunction Class whose first argument will be the type of the +corresponding argument-name, whose second +argument will be the entire ArgumentPack, and whose return type is a +Boolean Integral +Concept; however, user code cannot compute +mfc in terms of +previous-name ## _type.
    • +
    • type-name is either the name of a +target type or an MPL Binary +Metafunction Class whose first argument will be the type of the +corresponding argument-name, whose second +argument will be the entire ArgumentPack, and whose return type is the +target type. If restriction uses this form, then the type of the generated name argument-name ## _type will be computed in terms +of the target type, and the generated reference +argument-name (but not its corresponding +entry in args) will be cast to that +type.
    • +
    +
    +
    +
    Approximate expansion:
    +
    +

    Where:

    +
      +
    • n denotes the minimum arity, as +determined from arguments.
    • +
    • m denotes the maximum arity, as +determined from arguments.
    • +
    +
    +template <typename T>
    +struct boost_param_result_ ## __LINE__ ## operator
    +{
    +    typedef result type;
    +};
    +
    +struct boost_param_params_ ## __LINE__ ## operator
    +  : parameters<
    +        list of parameter specifications, based on arguments
    +    >
    +{
    +};
    +
    +typedef boost_param_params_ ## __LINE__ ## operator
    +    boost_param_parameters_ ## __LINE__ ## operator;
    +
    +template <typename A0, …, typename A ## n>
    +result type
    +    operator()(
    +        A0&& a0, …, A ## n && a ## n
    +      , typename boost_param_parameters_ ## __LINE__ ## operator
    +        ::match<A0, …, A ## n>::type
    +        = boost_param_parameters_ ## __LINE__ ## operator()
    +    )
    +{
    +    return this->boost_param_impl ## __LINE__ ## operator(
    +        boost_param_parameters_ ## __LINE__ ## operator()(
    +            std::forward<A0>(a0)
    +          , …
    +          , std::forward<A ## n>(a ## n)
    +        )
    +    );
    +}
    +
    +
    +
    +template <typename A0, …, typename A ## m>
    +result type
    +    operator()(
    +        A0&& a0, …, A ## m && a ## m
    +      , typename boost_param_parameters_ ## __LINE__ ## operator
    +        ::match<A0, …, A ## m>::type
    +        = boost_param_parameters_ ## __LINE__ ## operator()
    +    )
    +{
    +    return this->boost_param_impl ## __LINE__ ## operator(
    +        boost_param_parameters_ ## __LINE__ ## operator()(
    +            std::forward<A0>(a0)
    +          , …
    +          , std::forward<A ## m>(a ## m)
    +        )
    +    );
    +}
    +
    +template <typename Args>
    +typename boost_param_result_ ## __LINE__ ## operator<Args>::type
    +    boost_param_impl ## __LINE__ ## operator(Args const& args)
    +{
    +    return this->boost_param_dispatch_0boost_ ## __LINE__ ## operator(
    +        static_cast<
    +            typename boost_param_result_ ## __LINE__ ## operator<
    +                Args
    +            >::type(*)()
    +        >(std::nullptr)
    +      , args
    +      , std::forward<
    +            typename value_type<
    +                Args
    +              , keyword tag type of required parameter ## 0
    +            >::type
    +        >(args[ keyword object of required parameter ## 0])
    +      , …
    +      , std::forward<
    +            typename value_type<
    +                Args
    +              , keyword tag type of required parameter ## n
    +            >::type
    +        >(args[ keyword object of required parameter ## n])
    +    );
    +}
    +
    +template <
    +    typename ResultType
    +  , typename Args
    +  , typename argument name ## 0 ## _type
    +  , …
    +  , typename argument name ## n ## _type
    +>
    +ResultType
    +    boost_param_dispatch_0boost_ ## __LINE__ ## operator(
    +        (ResultType(*)())
    +      , Args const& args
    +      , argument name ## 0 ## _type&& argument name ## 0
    +      , …
    +      , argument name ## n ## _type&& argument name ## n
    +    )
    +{
    +    return this->boost_param_dispatch_0boost_ ## __LINE__ ## operator(
    +        static_cast<ResultType(*)()>(std::nullptr)
    +      , (args, keyword object of optional parameter ## n + 1 =
    +            default value of optional parameter ## n + 1
    +        )
    +      , std::forward< argument name ## 0 ## _type>(
    +            argument name ## 0
    +        )
    +      , …
    +      , std::forward< argument name ## n ## _type>(
    +            argument name ## n
    +        )
    +      , std::forward<
    +            typename value_type<
    +                Args
    +              , keyword tag type of optional parameter ## n + 1
    +            >::type
    +        >(default value of optional parameter ## n + 1)
    +    );
    +}
    +
    +
    +
    +template <
    +    typename ResultType
    +  , typename Args
    +  , typename argument name ## 0 ## _type
    +  , …
    +  , typename argument name ## m ## _type
    +>
    +ResultType
    +    boost_param_dispatch_0boost_ ## __LINE__ ## operator(
    +        (ResultType(*)())
    +      , Args const& args
    +      , argument name ## 0 ## _type&& argument name ## 0
    +      , …
    +      , argument name ## m ## _type&& argument name ## m
    +    )
    +
    +
    +
    +
    +
    +

    7.5   BOOST_PARAMETER_CONST_FUNCTION_CALL_OPERATOR(result, +tag_ns, arguments)

    + +++ + + + + + +
    Defined in:boost/parameter/preprocessor.hpp
    +

    Generates a function call operator that can take in positional arguments, +composed arguments, named arguments, and deduced arguments.

    + +++ + + + + + + + + + + + + + + + + + + + + + + +
    Example usage:
      +

    The return type of each of the following function templates falls under a +different value category.

    +
    +template <std::size_t N>
    +std::bitset<N + 1> rvalue_bitset()
    +{
    +    return std::bitset<N + 1>();
    +}
    +
    +template <std::size_t N>
    +std::bitset<N + 1> const rvalue_const_bitset()
    +{
    +    return std::bitset<N + 1>();
    +}
    +
    +template <std::size_t N>
    +std::bitset<N + 1>& lvalue_bitset()
    +{
    +    static std::bitset<N + 1> lset = std::bitset<N + 1>();
    +    return lset;
    +}
    +
    +template <std::size_t N>
    +std::bitset<N + 1> const& lvalue_const_bitset()
    +{
    +    static std::bitset<N + 1> const clset = std::bitset<N + 1>();
    +    return clset;
    +}
    +
    +

    The U::evaluate_category static member +function template has a simple job: to return the correct value category when +passed in an object returned by one of the functions defined above. Assume +that BOOST_PARAMETER_HAS_PERFECT_FORWARDING is defined.

    +
    +enum invoked
    +{
    +    passed_by_lvalue_reference_to_const
    +  , passed_by_lvalue_reference
    +  , passed_by_rvalue_reference_to_const
    +  , passed_by_rvalue_reference
    +};
    +
    +struct U
    +{
    +    template <std::size_t N>
    +    static invoked evaluate_category(std::bitset<N + 1> const&)
    +    {
    +        return passed_by_lvalue_reference_to_const;
    +    }
    +
    +    template <std::size_t N>
    +    static invoked evaluate_category(std::bitset<N + 1>&)
    +    {
    +        return passed_by_lvalue_reference;
    +    }
    +
    +    template <std::size_t N>
    +    static invoked evaluate_category(std::bitset<N + 1> const&&)
    +    {
    +        return passed_by_rvalue_reference_to_const;
    +    }
    +
    +    template <std::size_t N>
    +    static invoked evaluate_category(std::bitset<N + 1>&&)
    +    {
    +        return passed_by_rvalue_reference;
    +    }
    +};
    +
    +

    Define the named parameters that will comprise the argument specification +that this macro will use. Ensure that all their tag types are in the same +namespace, which is kw in this case. The +identifiers with leading underscores can be passed to the bracket operator of +args to extract the same argument to which +the corresponding named parameter (without underscores) is bound, as will be +shown later.

    +
    +BOOST_PARAMETER_NAME((_lrc, kw) in(lrc))
    +BOOST_PARAMETER_NAME((_lr, kw) in_out(lr))
    +BOOST_PARAMETER_NAME((_rrc, kw) in(rrc))
    +BOOST_PARAMETER_NAME((_rr, kw) consume(rr))
    +
    +

    Use the macro as a substitute for a normal const function call operator header. Enclose the return type bool in parentheses. For each parameter, also +enclose the expected value type in parentheses. Since the value types are +mutually exclusive, you can wrap the parameters in a (deduced …) clause. Otherwise, just as with a +normal function, the order in which you specify the parameters determines +their position. Also, just as with a normal function, optional parameters +have default values, whereas required parameters do not. Within the function +body, either simply use the parameter name or pass the matching identifier +with the leading underscore to the bracket operator of args to extract the corresponding +argument. Note that the second method doesn't require std::forward to preserve value categories.

    +
    +struct B
    +{
    +    B()
    +    {
    +    }
    +
    +    BOOST_PARAMETER_CONST_FUNCTION_CALL_OPERATOR((bool), kw,
    +        (deduced
    +            (required
    +                (lrc, (std::bitset<1>))
    +                (lr, (std::bitset<2>))
    +            )
    +            (optional
    +                (rrc, (std::bitset<3>), rvalue_const_bitset<2>())
    +                (rr, (std::bitset<4>), rvalue_bitset<3>())
    +            )
    +        )
    +    )
    +    {
    +        BOOST_TEST_EQ(
    +            passed_by_lvalue_reference_to_const
    +          , U::evaluate_category<0>(lrc)
    +        );
    +        BOOST_TEST_EQ(
    +            passed_by_lvalue_reference
    +          , U::evaluate_category<1>(lr)
    +        );
    +        BOOST_TEST_EQ(
    +            passed_by_rvalue_reference_to_const
    +          , U::evaluate_category<2>(std::forward<rrc0_type>(rrc0))
    +        );
    +        BOOST_TEST_EQ(
    +            passed_by_rvalue_reference
    +          , U::evaluate_category<3>(args[_rr0])
    +        );
    +
    +        return true;
    +    }
    +};
    +
    +

    The following function calls are legal.

    +
    +B const b = B();
    +b(  // positional arguments
    +    lvalue_const_bitset<0>()
    +  , lvalue_bitset<1>()
    +  , rvalue_const_bitset<2>()
    +  , rvalue_bitset<3>()
    +);
    +b(  // positional arguments
    +    lvalue_const_bitset<0>()
    +  , lvalue_bitset<1>()
    +);
    +b((  // composed arguments
    +    _rr0 = rvalue_bitset<3>()
    +  , _lrc0 = lvalue_const_bitset<0>()
    +  , _lr0 = lvalue_bitset<1>()
    +  , _rrc0 = rvalue_const_bitset<2>()
    +));
    +b(  // named arguments
    +    _rr0 = rvalue_bitset<3>()
    +  , _lrc0 = lvalue_const_bitset<0>()
    +  , _lr0 = lvalue_bitset<1>()
    +  , _rrc0 = rvalue_const_bitset<2>()
    +);
    +b(  // named arguments
    +    _lr0 = lvalue_bitset<1>()
    +  , _lrc0 = lvalue_const_bitset<0>()
    +);
    +
    +

    Because the parameters were wrapped in a (deduced …) clause, the following function calls are also legal.

    +
    +b(  // deduced arguments
    +    rvalue_bitset<3>()
    +  , lvalue_const_bitset<0>()
    +  , lvalue_bitset<1>()
    +  , rvalue_const_bitset<2>()
    +);
    +b(  // deduced arguments
    +    lvalue_bitset<1>()
    +  , lvalue_const_bitset<0>()
    +);
    +
    +

    The test/preprocessor.cpp, test/preprocessor_deduced.cpp, +and test/preprocessor_eval_cat_8.cpp test programs demonstrate proper usage +of this macro.

    +
    Macro parameters:
      +
      +
    • result is the parenthesized return type +of the function call operator.
    • +
    • tag_namespace is the namespace in which +the keywords used by the function call operator resides.
    • +
    • arguments is a list of argument +specifiers, as defined below.
    • +
    +
    Argument specifiers syntax:
      +
    +argument-specifiers ::= specifier-group0 {specifier-group0}
    +
    +specifier-group0 ::= specifier-group1 |
    +    (
    +        '(' 'deduced'
    +            specifier-group1 {specifier-group1}
    +        ')'
    +    )
    +
    +specifier-group1 ::=
    +    (
    +        '(' 'optional'
    +            optional-specifier {optional-specifier}
    +        ')'
    +    ) | (
    +        '(' 'required'
    +            required-specifier {required-specifier}
    +        ')'
    +    )
    +
    +optional-specifier ::=
    +    '('
    +        argument-name ',' restriction ',' default-value
    +    ')'
    +
    +required-specifier ::=
    +    '(' argument-name ',' restriction ')'
    +
    +restriction ::=
    +    ( '*' '(' mfc ')' ) |
    +    ( '(' typename ')' ) |
    +    '*'
    +
    +
      +
    • argument-name is any valid C++ +identifier.
    • +
    • default-value is any valid C++ +expression; if necessary, user code can compute it in terms of +previous-name ## _type, where +previous-name is the +argument-name in a previous +specifier-group0 or +specifier-group1. This expression will +be invoked exactly once.
    • +
    • mfc is an MPL Binary +Metafunction Class whose first argument will be the type of the +corresponding argument-name, whose second +argument will be the entire ArgumentPack, and whose return type is a +Boolean Integral +Concept; however, user code cannot compute +mfc in terms of +previous-name ## _type.
    • +
    • type-name is either the name of a +target type or an MPL Binary +Metafunction Class whose first argument will be the type of the +corresponding argument-name, whose second +argument will be the entire ArgumentPack, and whose return type is the +target type. If restriction uses this form, then the type of the generated name argument-name ## _type will be computed in terms +of the target type, and the generated reference +argument-name (but not its corresponding +entry in args) will be cast to that +type.
    • +
    +
    +
    +
    Approximate expansion:
    +
    +

    Where:

    +
      +
    • n denotes the minimum arity, as +determined from arguments.
    • +
    • m denotes the maximum arity, as +determined from arguments.
    • +
    +
    +template <typename T>
    +struct boost_param_result_const_ ## __LINE__ ## operator
    +{
    +    typedef result type;
    +};
    +
    +struct boost_param_params_const_ ## __LINE__ ## operator
    +  : parameters<
    +        list of parameter specifications, based on arguments
    +    >
    +{
    +};
    +
    +typedef boost_param_params_const_ ## __LINE__ ## operator
    +    boost_param_parameters_const_ ## __LINE__ ## operator;
    +
    +template <typename A0, …, typename A ## n>
    +result type
    +    operator()(
    +        A0&& a0, …, A ## n && a ## n
    +      , typename boost_param_parameters_const_ ## __LINE__ ## operator
    +        ::match<A0, …, A ## n>::type
    +        = boost_param_parameters_const_ ## __LINE__ ## operator()
    +    ) const
    +{
    +    return this->boost_param_impl_const ## __LINE__ ## operator(
    +        boost_param_parameters_const_ ## __LINE__ ## operator()(
    +            std::forward<A0>(a0)
    +          , …
    +          , std::forward<A ## n>(a ## n)
    +        )
    +    );
    +}
    +
    +
    +
    +template <typename A0, …, typename A ## m>
    +result type
    +    operator()(
    +        A0&& a0, …, A ## m && a ## m
    +      , typename boost_param_parameters_const_ ## __LINE__ ## operator
    +        ::match<A0, …, A ## m>::type
    +        = boost_param_parameters_const_ ## __LINE__ ## operator()
    +    ) const
    +{
    +    return this->boost_param_impl_const ## __LINE__ ## operator(
    +        boost_param_parameters_const_ ## __LINE__ ## operator()(
    +            std::forward<A0>(a0)
    +          , …
    +          , std::forward<A ## m>(a ## m)
    +        )
    +    );
    +}
    +
    +template <typename Args>
    +typename boost_param_result_const_ ## __LINE__ ## operator<Args>::type
    +    boost_param_impl_const ## __LINE__ ## operator(Args const& args) const
    +{
    +    return this->
    +    boost_param_dispatch_const_0boost_ ## __LINE__ ## operator(
    +        static_cast<
    +            typename boost_param_result_const_ ## __LINE__ ## operator<
    +                Args
    +            >::type(*)()
    +        >(std::nullptr)
    +      , args
    +      , std::forward<
    +            typename value_type<
    +                Args
    +              , keyword tag type of required parameter ## 0
    +            >::type
    +        >(args[ keyword object of required parameter ## 0])
    +      , …
    +      , std::forward<
    +            typename value_type<
    +                Args
    +              , keyword tag type of required parameter ## n
    +            >::type
    +        >(args[ keyword object of required parameter ## n])
    +    );
    +}
    +
    +template <
    +    typename ResultType
    +  , typename Args
    +  , typename argument name ## 0 ## _type
    +  , …
    +  , typename argument name ## n ## _type
    +>
    +ResultType
    +    boost_param_dispatch_const_0boost_ ## __LINE__ ## operator(
    +        (ResultType(*)())
    +      , Args const& args
    +      , argument name ## 0 ## _type&& argument name ## 0
    +      , …
    +      , argument name ## n ## _type&& argument name ## n
    +    ) const
    +{
    +    return this->
    +    boost_param_dispatch_const_0boost_ ## __LINE__ ## operator(
    +        static_cast<ResultType(*)()>(std::nullptr)
    +      , (args, keyword object of optional parameter ## n + 1 =
    +            default value of optional parameter ## n + 1
    +        )
    +      , std::forward< argument name ## 0 ## _type>(
    +            argument name ## 0
    +        )
    +      , …
    +      , std::forward< argument name ## n ## _type>(
    +            argument name ## n
    +        )
    +      , std::forward<
    +            typename value_type<
    +                Args
    +              , keyword tag type of optional parameter ## n + 1
    +            >::type
    +        >(default value of optional parameter ## n + 1)
    +    );
    +}
    +
    +
    +
    +template <
    +    typename ResultType
    +  , typename Args
    +  , typename argument name ## 0 ## _type
    +  , …
    +  , typename argument name ## m ## _type
    +>
    +ResultType
    +    boost_param_dispatch_const_0boost_ ## __LINE__ ## operator(
    +        (ResultType(*)())
    +      , Args const& args
    +      , argument name ## 0 ## _type&& argument name ## 0
    +      , …
    +      , argument name ## m ## _type&& argument name ## m
    +    ) const
    +
    +
    +
    +
    +
    +

    7.6   BOOST_PARAMETER_CONSTRUCTOR(cls, impl, tag_namespace, +arguments)

    + +++ + + + + + +
    Defined in:boost/parameter/preprocessor.hpp
    +

    Generates a constructor that can take in positional arguments, composed +arguments, named arguments, and deduced arguments.

    + +++ + + + + + + + + + + + + + + + + + + + + + + +
    Example usage:
      +

    Define the named parameters that will comprise the argument specification +that this macro will use. Ensure that all their tag types are in the same +namespace, which is tag by default.

    +
    +BOOST_PARAMETER_NAME(y)
    +BOOST_PARAMETER_NAME(z)
    +
    +

    In the base class, implement a delegate constructor template that takes in +an ArgumentPack. You must pass the identifiers with leading +underscores to args in order to extract the +corresponding arguments.

    +
    +class char_read_base
    +{
    +    int index;
    +    char const* key;
    +
    + public:
    +    template <typename Args>
    +    explicit char_read_base(Args const& args)
    +      : index(args[_y]), key(args[_z])
    +    {
    +    }
    +
    +    BOOST_PARAMETER_FUNCTION_CALL_OPERATOR((void), tag,
    +        (deduced
    +            (required
    +                (y, (int))
    +                (z, (char const*))
    +            )
    +        )
    +    )
    +    {
    +        this->index = y;
    +        this->key = z;
    +    }
    +
    +    BOOST_PARAMETER_CONST_FUNCTION_CALL_OPERATOR((char), tag,
    +        (deduced
    +            (required
    +                (y, (bool))
    +                (z, (std::map<char const*,std::string>))
    +            )
    +        )
    +    )
    +    {
    +        return y ? (
    +            (z.find(this->key)->second)[this->index]
    +        ) : this->key[this->index];
    +    }
    +};
    +
    +

    Use the macro as a substitute for a normal constructor definition. Note +the lack of an explicit body. Enclose the base type in parentheses. For each +parameter, also enclose the expected value type in parentheses. Since the +value types are mutually exclusive, you can wrap the parameters in a (deduced …) clause.

    +
    +struct char_reader : public char_read_base
    +{
    +    BOOST_PARAMETER_CONSTRUCTOR(char_reader, (char_read_base), tag,
    +        (deduced
    +            (required
    +                (y, (int))
    +                (z, (char const*))
    +            )
    +        )
    +    )
    +};
    +
    +

    The following char_reader constructor +calls are legal.

    +
    +char const* keys[] = {"foo", "bar", "baz"};
    +std::map<char const*,std::string> k2s;
    +k2s[keys[0]] = std::string>("qux");
    +k2s[keys[1]] = std::string>("wmb");
    +k2s[keys[2]] = std::string>("zxc");
    +
    +// positional arguments
    +char_reader r0(0, keys[0]);
    +BOOST_TEST_EQ('q', (r0(true, k2s)));
    +BOOST_TEST_EQ('f', (r0(false, k2s)));
    +
    +// named arguments
    +char_reader r1(_z = keys[1], _y = 1);
    +BOOST_TEST_EQ('m', (r1(_z = k2s, _y = true)));
    +BOOST_TEST_EQ('a', (r1(_z = k2s, _y = false)));
    +
    +// deduced arguments
    +char_reader r2(keys[2], 2);
    +BOOST_TEST_EQ('c', (r2(k2s, true)));
    +BOOST_TEST_EQ('z', (r2(k2s, false)));
    +

    The test/preprocessor.cpp and test/preprocessor_eval_category.cpp test programs demonstrate proper usage of this macro.

    +
    Macro parameters:
      +
      +
    • cls is the name of the enclosing +class.
    • +
    • impl is the parenthesized implementation +base class for cls.
    • +
    • tag_namespace is the namespace in which +the keywords used by the constructor resides.
    • +
    • arguments is a list of argument +specifiers, as defined below.
    • +
    +
    Argument specifiers syntax:
      +
    +argument-specifiers ::= specifier-group0 {specifier-group0}
    +
    +specifier-group0 ::= specifier-group1 |
    +    (
    +        '(' 'deduced'
    +            specifier-group1 {specifier-group1}
    +        ')'
    +    )
    +
    +specifier-group1 ::=
    +    (
    +        '(' 'optional'
    +            specifier {specifier}
    +        ')'
    +    ) | (
    +        '(' 'required'
    +            specifier {specifier}
    +        ')'
    +    )
    +
    +specifier ::=
    +    '(' argument-name ',' restriction ')'
    +
    +restriction ::=
    +    ( '*' '(' mfc ')' ) |
    +    ( '(' typename ')' ) |
    +    '*'
    +
    +
      +
    • argument-name is any valid C++ +identifier.
    • +
    • mfc is an MPL Binary +Metafunction Class whose first argument will be the type of the +corresponding argument-name, whose second +argument will be the entire ArgumentPack, and whose return type is a +Boolean Integral +Concept; however, user code cannot compute +mfc in terms of +previous-name ## _type.
    • +
    • type-name is either the name of a +target type or an MPL Binary +Metafunction Class whose first argument will be the type of the +corresponding argument-name, whose second +argument will be the entire ArgumentPack, and whose return type is the +target type.
    • +
    +

    Note that specifier does not include default-value. It +is up to the delegate constructor in impl to +determine the default value of all optional arguments.

    +
    +
    +
    Approximate expansion:
    +
    +

    Where:

    +
      +
    • n denotes the minimum arity, as +determined from arguments.
    • +
    • m denotes the maximum arity, as +determined from arguments.
    • +
    +
    +struct boost_param_params_ ## __LINE__ ## ctor
    +  : parameters<
    +        list of parameter specifications, based on arguments
    +    >
    +{
    +};
    +
    +typedef boost_param_params_ ## __LINE__ ## ctor
    +    constructor_parameters ## __LINE__;
    +
    +template <typename A0, …, typename A ## n>
    +cls(A0&& a0, …, A ## n && a ## n)
    +  : impl(
    +        constructor_parameters ## __LINE__(
    +            std::forward<A0>(a0)
    +          , …
    +          , std::forward<A ## n>(a ## n)
    +        )
    +    )
    +{
    +}
    +
    +
    +
    +template <typename A0, …, typename A ## m>
    +cls(A0&& a0, …, A ## m&& a ## m)
    +  : impl(
    +        constructor_parameters ## __LINE__(
    +            std::forward<A0>(a0)
    +          , …
    +          , std::forward<A ## m>(a ## m)
    +        )
    +    )
    +{
    +}
    +
    +
    +
    -

    6.7   7.7   BOOST_PARAMETER_BASIC_FUNCTION(result, name, tag_namespace, arguments)

    @@ -3071,34 +4916,423 @@ href="../../../../boost/parameter/preprocessor.hpp"
    -

    Same as BOOST_PARAMETER_FUNCTION, except:

    -
      -
    • For the argument specifiers syntax, optional-specifier no longer -includes default-value. It is up to the function body to determine -the default value of all optional arguments.
    • -
    • Generated names in the enclosing scope no longer include -boost_param_dispatch_0boost_ ## __LINE__ ## -name or boost_param_dispatch_1boost_ ## -__LINE__ ## name.
    • -
    • Expansion of this macro omits all overloads of boost_param_dispatch_0boost_ ## __LINE__ ## name -and boost_param_dispatch_1boost_ ## __LINE__ ## -name and stops at the header of boost_param_impl ## name. Therefore, only the ArgumentPack type Args and its -object instance args are available for use -within the function body.
    • -
    +

    Generates a function that can take in positional arguments, composed +arguments, named arguments, and deduced arguments.

    + +++ + + + + + + + + + + + + + + + + + + + + + + +
    Example usage:
      +

    The return type of each of the following function templates falls under a +different value category.

    +
    +template <std::size_t N>
    +std::bitset<N + 1> rvalue_bitset()
    +{
    +    return std::bitset<N + 1>();
    +}
    +
    +template <std::size_t N>
    +std::bitset<N + 1> const rvalue_const_bitset()
    +{
    +    return std::bitset<N + 1>();
    +}
    +
    +template <std::size_t N>
    +std::bitset<N + 1>& lvalue_bitset()
    +{
    +    static std::bitset<N + 1> lset = std::bitset<N + 1>();
    +    return lset;
    +}
    +
    +template <std::size_t N>
    +std::bitset<N + 1> const& lvalue_const_bitset()
    +{
    +    static std::bitset<N + 1> const clset = std::bitset<N + 1>();
    +    return clset;
    +}
    +
    +

    The U::evaluate_category static member +function template has a simple job: to return the correct value category when +passed in an object returned by one of the functions defined above. Assume +that BOOST_PARAMETER_HAS_PERFECT_FORWARDING is defined.

    +
    +enum invoked
    +{
    +    passed_by_lvalue_reference_to_const
    +  , passed_by_lvalue_reference
    +  , passed_by_rvalue_reference_to_const
    +  , passed_by_rvalue_reference
    +};
    +
    +struct U
    +{
    +    template <std::size_t N>
    +    static invoked evaluate_category(std::bitset<N + 1> const&)
    +    {
    +        return passed_by_lvalue_reference_to_const;
    +    }
    +
    +    template <std::size_t N>
    +    static invoked evaluate_category(std::bitset<N + 1>&)
    +    {
    +        return passed_by_lvalue_reference;
    +    }
    +
    +    template <std::size_t N>
    +    static invoked evaluate_category(std::bitset<N + 1> const&&)
    +    {
    +        return passed_by_rvalue_reference_to_const;
    +    }
    +
    +    template <std::size_t N>
    +    static invoked evaluate_category(std::bitset<N + 1>&&)
    +    {
    +        return passed_by_rvalue_reference;
    +    }
    +};
    +
    +

    Define the named parameters that will comprise the argument specification +that this macro will use. Ensure that all their tag types are in the same +namespace, which is kw in this case. The +identifiers with leading underscores can be passed to the bracket operator of +args to extract the same argument to which +the corresponding named parameter (without underscores) is bound, as will be +shown later.

    +
    +BOOST_PARAMETER_NAME((_lrc, kw) in(lrc))
    +BOOST_PARAMETER_NAME((_lr, kw) in_out(lr))
    +BOOST_PARAMETER_NAME((_rrc, kw) in(rrc))
    +BOOST_PARAMETER_NAME((_rr, kw) consume(rr))
    +
    +

    Use the macro as a substitute for a normal function header. Enclose the +return type bool in parentheses. For each +parameter, also enclose the expected value type in parentheses. Since the +value types are mutually exclusive, you can wrap the parameters in a (deduced …) clause. Otherwise, just as with a +normal function, the order in which you specify the parameters determines +their position. However, unlike a normal function, default values must be +specified within the function body. Also within the function body, you must +pass the matching identifier with the leading underscore to the bracket +operator of args to extract the +corresponding argument, but at least this doesn't require std::forward to preserve value categories.

    +
    +BOOST_PARAMETER_BASIC_FUNCTION((bool), evaluate, kw,
    +    (deduced
    +        (required
    +            (lrc, (std::bitset<1>))
    +            (lr, (std::bitset<2>))
    +        )
    +        (optional
    +            (rrc, (std::bitset<3>))
    +            (rr, (std::bitset<4>))
    +        )
    +    )
    +)
    +{
    +    BOOST_TEST_EQ(
    +        passed_by_lvalue_reference_to_const
    +      , U::evaluate_category<0>(args[_lrc])
    +    );
    +    BOOST_TEST_EQ(
    +        passed_by_lvalue_reference
    +      , U::evaluate_category<1>(args[_lr])
    +    );
    +    BOOST_TEST_EQ(
    +        passed_by_rvalue_reference_to_const
    +      , U::evaluate_category<2>(
    +            args[_rrc0 | rvalue_const_bitset<2>()]
    +        )
    +    );
    +    BOOST_TEST_EQ(
    +        passed_by_rvalue_reference
    +      , U::evaluate_category<3>(args[_rr0 | rvalue_bitset<3>()])
    +    );
    +
    +    return true;
    +}
    +
    +

    The following function calls are legal.

    +
    +evaluate(  // positional arguments
    +    lvalue_const_bitset<0>()
    +  , lvalue_bitset<1>()
    +  , rvalue_const_bitset<2>()
    +  , rvalue_bitset<3>()
    +);
    +evaluate(  // positional arguments
    +    lvalue_const_bitset<0>()
    +  , lvalue_bitset<1>()
    +);
    +evaluate((  // composed arguments
    +    _rr0 = rvalue_bitset<3>()
    +  , _lrc0 = lvalue_const_bitset<0>()
    +  , _lr0 = lvalue_bitset<1>()
    +  , _rrc0 = rvalue_const_bitset<2>()
    +));
    +evaluate(  // named arguments
    +    _rr0 = rvalue_bitset<3>()
    +  , _lrc0 = lvalue_const_bitset<0>()
    +  , _lr0 = lvalue_bitset<1>()
    +  , _rrc0 = rvalue_const_bitset<2>()
    +);
    +evaluate(  // named arguments
    +    _lr0 = lvalue_bitset<1>()
    +  , _lrc0 = lvalue_const_bitset<0>()
    +);
    +
    +

    Because the parameters were wrapped in a (deduced …) clause, the following function calls are also legal.

    +
    +evaluate(  // deduced arguments
    +    rvalue_bitset<3>()
    +  , lvalue_const_bitset<0>()
    +  , lvalue_bitset<1>()
    +  , rvalue_const_bitset<2>()
    +);
    +evaluate(  // deduced arguments
    +    lvalue_bitset<1>()
    +  , lvalue_const_bitset<0>()
    +);
    +

    The test/preprocessor.cpp test program demonstrates proper usage of this macro.

    +
    Macro parameters:
      +
      +
    • result is the parenthesized return type +of the function.
    • +
    • name is the base name of the function; +it determines the name of the generated forwarding functions.
    • +
    • tag_namespace is the namespace in which +the keywords used by the function resides.
    • +
    • arguments is a list of argument +specifiers, as defined below.
    • +
    +
    Argument specifiers syntax:
      +
    +argument-specifiers ::= specifier-group0 {specifier-group0}
    +
    +specifier-group0 ::= specifier-group1 |
    +    (
    +        '(' 'deduced'
    +            specifier-group1 {specifier-group1}
    +        ')'
    +    )
    +
    +specifier-group1 ::=
    +    (
    +        '(' 'optional'
    +            specifier {specifier}
    +        ')'
    +    ) | (
    +        '(' 'required'
    +            specifier {specifier}
    +        ')'
    +    )
    +
    +specifier ::=
    +    '(' argument-name ',' restriction ')'
    +
    +restriction ::=
    +    ( '*' '(' mfc ')' ) |
    +    ( '(' typename ')' ) |
    +    '*'
    +
    +
      +
    • argument-name is any valid C++ +identifier.
    • +
    • mfc is an MPL Binary +Metafunction Class whose first argument will be the type of the +corresponding argument-name, whose second +argument will be the entire ArgumentPack, and whose return type is a +Boolean Integral +Concept; however, user code cannot compute +mfc in terms of +previous-name ## _type.
    • +
    • type-name is either the name of a +target type or an MPL Binary +Metafunction Class whose first argument will be the type of the +corresponding argument-name, whose second +argument will be the entire ArgumentPack, and whose return type is the +target type.
    • +
    +

    Note that specifier does not include default-value. It +is up to the function body to determine the default value of all optional +arguments.

    +
    +
    +
    Approximate expansion:
    +
    +

    Where:

    +
      +
    • n denotes the minimum arity, as +determined from arguments.
    • +
    • m denotes the maximum arity, as +determined from arguments.
    • +
    +
    +template <typename T>
    +struct boost_param_result_ ## __LINE__ ## name
    +{
    +    typedef result type;
    +};
    +
    +struct boost_param_params_ ## __LINE__ ## name
    +  : parameters<
    +        list of parameter specifications, based on arguments
    +    >
    +{
    +};
    +
    +typedef boost_param_params_ ## __LINE__ ## name
    +    boost_param_parameters_ ## __LINE__ ## name;
    +
    +template <typename Args>
    +typename boost_param_result_ ## __LINE__ ## name<Args>::type
    +    boost_param_impl ## __LINE__ ## name(Args const&);
    +
    +template <typename A0, …, typename A ## n>
    +result type
    +    name(
    +        A0&& a0, …, A ## n && a ## n
    +      , typename boost_param_parameters_ ## __LINE__ ## name::match<
    +            A0, …, A ## n
    +        >::type = boost_param_parameters_ ## __LINE__ ## name()
    +    )
    +{
    +    return boost_param_impl ## __LINE__ ## name(
    +        boost_param_parameters_ ## __LINE__ ## name()(
    +            std::forward<A0>(a0)
    +          , …
    +          , std::forward<A ## n>(a ## n)
    +        )
    +    );
    +}
    +
    +
    +
    +template <typename A0, …, typename A ## m>
    +result type
    +    name(
    +        A0&& a0, …, A ## m && a ## m
    +      , typename boost_param_parameters_ ## __LINE__ ## name::match<
    +            A0, …, A ## m
    +        >::type = boost_param_parameters_ ## __LINE__ ## name()
    +    )
    +{
    +    return boost_param_impl ## __LINE__ ## name(
    +        boost_param_parameters_ ## __LINE__ ## name()(
    +            std::forward<A0>(a0)
    +          , …
    +          , std::forward<A ## m>(a ## m)
    +        )
    +    );
    +}
    +
    +template <typename Args>
    +typename boost_param_result_ ## __LINE__ ## name<Args>::type
    +    boost_param_impl ## __LINE__ ## name(Args const& args)
    +
    +

    Only the ArgumentPack type Args and its object instance args are +available for use within the function body.

    +
    +
    -

    6.8   7.8   BOOST_PARAMETER_BASIC_MEMBER_FUNCTION(result, name, tag_namespace, arguments)

    @@ -3113,25 +5347,427 @@ href="../../../../boost/parameter/preprocessor.hpp"
    -

    Same as BOOST_PARAMETER_BASIC_FUNCTION, -except that:

    -
      -
    • name may be qualified by the -static keyword to declare the member -function and its helpers as not associated with any object of the enclosing -type.
    • -
    • Expansion of this macro omits the forward declaration of the -implementation function.
    • -
    +

    Generates a member function that can take in positional arguments, composed +arguments, named arguments, and deduced arguments.

    + +++ + + + + + + + + + + + + + + + + + + + + + + +
    Example usage:
      +

    The return type of each of the following function templates falls under a +different value category.

    +
    +template <std::size_t N>
    +std::bitset<N + 1> rvalue_bitset()
    +{
    +    return std::bitset<N + 1>();
    +}
    +
    +template <std::size_t N>
    +std::bitset<N + 1> const rvalue_const_bitset()
    +{
    +    return std::bitset<N + 1>();
    +}
    +
    +template <std::size_t N>
    +std::bitset<N + 1>& lvalue_bitset()
    +{
    +    static std::bitset<N + 1> lset = std::bitset<N + 1>();
    +    return lset;
    +}
    +
    +template <std::size_t N>
    +std::bitset<N + 1> const& lvalue_const_bitset()
    +{
    +    static std::bitset<N + 1> const clset = std::bitset<N + 1>();
    +    return clset;
    +}
    +
    +

    The U::evaluate_category static member +function template has a simple job: to return the correct value category when +passed in an object returned by one of the functions defined above. Assume +that BOOST_PARAMETER_HAS_PERFECT_FORWARDING is defined.

    +
    +enum invoked
    +{
    +    passed_by_lvalue_reference_to_const
    +  , passed_by_lvalue_reference
    +  , passed_by_rvalue_reference_to_const
    +  , passed_by_rvalue_reference
    +};
    +
    +struct U
    +{
    +    template <std::size_t N>
    +    static invoked evaluate_category(std::bitset<N + 1> const&)
    +    {
    +        return passed_by_lvalue_reference_to_const;
    +    }
    +
    +    template <std::size_t N>
    +    static invoked evaluate_category(std::bitset<N + 1>&)
    +    {
    +        return passed_by_lvalue_reference;
    +    }
    +
    +    template <std::size_t N>
    +    static invoked evaluate_category(std::bitset<N + 1> const&&)
    +    {
    +        return passed_by_rvalue_reference_to_const;
    +    }
    +
    +    template <std::size_t N>
    +    static invoked evaluate_category(std::bitset<N + 1>&&)
    +    {
    +        return passed_by_rvalue_reference;
    +    }
    +};
    +
    +

    Define the named parameters that will comprise the argument specification +that this macro will use. Ensure that all their tag types are in the same +namespace, which is kw in this case. The +identifiers with leading underscores can be passed to the bracket operator of +args to extract the same argument to which +the corresponding named parameter (without underscores) is bound, as will be +shown later.

    +
    +BOOST_PARAMETER_NAME((_lrc, kw) in(lrc))
    +BOOST_PARAMETER_NAME((_lr, kw) in_out(lr))
    +BOOST_PARAMETER_NAME((_rrc, kw) in(rrc))
    +BOOST_PARAMETER_NAME((_rr, kw) consume(rr))
    +
    +

    Use the macro as a substitute for a normal static member function header. Enclose the return type bool in parentheses. For each parameter, also +enclose the expected value type in parentheses. Since the value types are +mutually exclusive, you can wrap the parameters in a (deduced …) clause. Otherwise, just as with a +normal function, the order in which you specify the parameters determines +their position. However, unlike a normal function, default values must be +specified within the function body. Also within the function body, you must +pass the matching identifier with the leading underscore to the bracket +operator of args to extract the +corresponding argument, but at least this doesn't require std::forward to preserve value categories.

    +
    +struct B
    +{
    +    BOOST_PARAMETER_BASIC_MEMBER_FUNCTION((bool), static evaluate, kw,
    +        (deduced
    +            (required
    +                (lrc, (std::bitset<1>))
    +                (lr, (std::bitset<2>))
    +            )
    +            (optional
    +                (rrc, (std::bitset<3>))
    +                (rr, (std::bitset<4>))
    +            )
    +        )
    +    )
    +    {
    +        BOOST_TEST_EQ(
    +            passed_by_lvalue_reference_to_const
    +          , U::evaluate_category<0>(args[_lrc])
    +        );
    +        BOOST_TEST_EQ(
    +            passed_by_lvalue_reference
    +          , U::evaluate_category<1>(args[_lr])
    +        );
    +        BOOST_TEST_EQ(
    +            passed_by_rvalue_reference_to_const
    +          , U::evaluate_category<2>(
    +                args[_rrc0 | rvalue_const_bitset<2>()]
    +            )
    +        );
    +        BOOST_TEST_EQ(
    +            passed_by_rvalue_reference
    +          , U::evaluate_category<3>(
    +                args[_rr0 | rvalue_bitset<3>()]
    +            )
    +        );
    +
    +        return true;
    +    }
    +};
    +
    +

    The following function calls are legal.

    +
    +B::evaluate(  // positional arguments
    +    lvalue_const_bitset<0>()
    +  , lvalue_bitset<1>()
    +  , rvalue_const_bitset<2>()
    +  , rvalue_bitset<3>()
    +);
    +B::evaluate(  // positional arguments
    +    lvalue_const_bitset<0>()
    +  , lvalue_bitset<1>()
    +);
    +B::evaluate((  // composed arguments
    +    _rr0 = rvalue_bitset<3>()
    +  , _lrc0 = lvalue_const_bitset<0>()
    +  , _lr0 = lvalue_bitset<1>()
    +  , _rrc0 = rvalue_const_bitset<2>()
    +));
    +B::evaluate(  // named arguments
    +    _rr0 = rvalue_bitset<3>()
    +  , _lrc0 = lvalue_const_bitset<0>()
    +  , _lr0 = lvalue_bitset<1>()
    +  , _rrc0 = rvalue_const_bitset<2>()
    +);
    +B::evaluate(  // named arguments
    +    _lr0 = lvalue_bitset<1>()
    +  , _lrc0 = lvalue_const_bitset<0>()
    +);
    +
    +

    Because the parameters were wrapped in a (deduced …) clause, the following function calls are also legal.

    +
    +B::evaluate(  // deduced arguments
    +    rvalue_bitset<3>()
    +  , lvalue_const_bitset<0>()
    +  , lvalue_bitset<1>()
    +  , rvalue_const_bitset<2>()
    +);
    +B::evaluate(  // deduced arguments
    +    lvalue_bitset<1>()
    +  , lvalue_const_bitset<0>()
    +);
    +

    The test/preprocessor.cpp test program demonstrates proper usage of this macro.

    +
    Macro parameters:
      +
      +
    • result is the parenthesized return type +of the function.
    • +
    • name is the base name of the function; +it determines the name of the generated forwarding functions. name may be qualified by the static keyword to declare the member function +and its helpers as not associated with any object of the enclosing type.
    • +
    • tag_namespace is the namespace in which +the keywords used by the function resides.
    • +
    • arguments is a list of argument +specifiers, as defined below.
    • +
    +
    Argument specifiers syntax:
      +
    +argument-specifiers ::= specifier-group0 {specifier-group0}
    +
    +specifier-group0 ::= specifier-group1 |
    +    (
    +        '(' 'deduced'
    +            specifier-group1 {specifier-group1}
    +        ')'
    +    )
    +
    +specifier-group1 ::=
    +    (
    +        '(' 'optional'
    +            specifier {specifier}
    +        ')'
    +    ) | (
    +        '(' 'required'
    +            specifier {specifier}
    +        ')'
    +    )
    +
    +specifier ::=
    +    '(' argument-name ',' restriction ')'
    +
    +restriction ::=
    +    ( '*' '(' mfc ')' ) |
    +    ( '(' typename ')' ) |
    +    '*'
    +
    +
      +
    • argument-name is any valid C++ +identifier.
    • +
    • mfc is an MPL Binary +Metafunction Class whose first argument will be the type of the +corresponding argument-name, whose second +argument will be the entire ArgumentPack, and whose return type is a +Boolean Integral +Concept; however, user code cannot compute +mfc in terms of +previous-name ## _type.
    • +
    • type-name is either the name of a +target type or an MPL Binary +Metafunction Class whose first argument will be the type of the +corresponding argument-name, whose second +argument will be the entire ArgumentPack, and whose return type is the +target type.
    • +
    +

    Note that specifier does not include default-value. It +is up to the function body to determine the default value of all optional +arguments.

    +
    +
    +
    Approximate expansion:
    +
    +

    Where:

    +
      +
    • n denotes the minimum arity, as +determined from arguments.
    • +
    • m denotes the maximum arity, as +determined from arguments.
    • +
    +
    +template <typename T>
    +struct boost_param_result_ ## __LINE__ ## name
    +{
    +    typedef result type;
    +};
    +
    +struct boost_param_params_ ## __LINE__ ## name
    +  : parameters<
    +        list of parameter specifications, based on arguments
    +    >
    +{
    +};
    +
    +typedef boost_param_params_ ## __LINE__ ## name
    +    boost_param_parameters_ ## __LINE__ ## name;
    +
    +template <typename A0, …, typename A ## n>
    +result type
    +    name(
    +        A0&& a0, …, A ## n && a ## n
    +      , typename boost_param_parameters_ ## __LINE__ ## name::match<
    +            A0, …, A ## n
    +        >::type = boost_param_parameters_ ## __LINE__ ## name()
    +    )
    +{
    +    return this->boost_param_impl ## __LINE__ ## name(
    +        boost_param_parameters_ ## __LINE__ ## name()(
    +            std::forward<A0>(a0)
    +          , …
    +          , std::forward<A ## n>(a ## n)
    +        )
    +    );
    +}
    +
    +
    +
    +template <typename A0, …, typename A ## m>
    +result type
    +    name(
    +        A0&& a0, …, A ## m && a ## m
    +      , typename boost_param_parameters_ ## __LINE__ ## name::match<
    +            A0, …, A ## m
    +        >::type = boost_param_parameters_ ## __LINE__ ## name()
    +    )
    +{
    +    return this->boost_param_impl ## __LINE__ ## name(
    +        boost_param_parameters_ ## __LINE__ ## name()(
    +            std::forward<A0>(a0)
    +          , …
    +          , std::forward<A ## m>(a ## m)
    +        )
    +    );
    +}
    +
    +template <typename Args>
    +typename boost_param_result_ ## __LINE__ ## name<Args>::type
    +    boost_param_impl ## __LINE__ ## name(Args const& args)
    +
    +

    Only the ArgumentPack type Args and its object instance args are +available for use within the function body.

    +
    +
    -

    6.9   7.9   BOOST_PARAMETER_BASIC_CONST_MEMBER_FUNCTION(result, name, tag_namespace, arguments)

    @@ -3146,17 +5782,2872 @@ href="../../../../boost/parameter/preprocessor.hpp"
    -

    Same as BOOST_PARAMETER_BASIC_MEMBER_FUNCTION, -except that the overloaded forwarding member functions and their helper -methods are const-qualified.

    +

    Generates a member function that can take in positional arguments, composed +arguments, named arguments, and deduced arguments.

    + +++ + + + + + + + + + + + + + + + + + + + + + + +
    Example usage:
      +

    The return type of each of the following function templates falls under a +different value category.

    +
    +template <std::size_t N>
    +std::bitset<N + 1> rvalue_bitset()
    +{
    +    return std::bitset<N + 1>();
    +}
    +
    +template <std::size_t N>
    +std::bitset<N + 1> const rvalue_const_bitset()
    +{
    +    return std::bitset<N + 1>();
    +}
    +
    +template <std::size_t N>
    +std::bitset<N + 1>& lvalue_bitset()
    +{
    +    static std::bitset<N + 1> lset = std::bitset<N + 1>();
    +    return lset;
    +}
    +
    +template <std::size_t N>
    +std::bitset<N + 1> const& lvalue_const_bitset()
    +{
    +    static std::bitset<N + 1> const clset = std::bitset<N + 1>();
    +    return clset;
    +}
    +
    +

    The U::evaluate_category static member +function template has a simple job: to return the correct value category when +passed in an object returned by one of the functions defined above. Assume +that BOOST_PARAMETER_HAS_PERFECT_FORWARDING is defined.

    +
    +enum invoked
    +{
    +    passed_by_lvalue_reference_to_const
    +  , passed_by_lvalue_reference
    +  , passed_by_rvalue_reference_to_const
    +  , passed_by_rvalue_reference
    +};
    +
    +struct U
    +{
    +    template <std::size_t N>
    +    static invoked evaluate_category(std::bitset<N + 1> const&)
    +    {
    +        return passed_by_lvalue_reference_to_const;
    +    }
    +
    +    template <std::size_t N>
    +    static invoked evaluate_category(std::bitset<N + 1>&)
    +    {
    +        return passed_by_lvalue_reference;
    +    }
    +
    +    template <std::size_t N>
    +    static invoked evaluate_category(std::bitset<N + 1> const&&)
    +    {
    +        return passed_by_rvalue_reference_to_const;
    +    }
    +
    +    template <std::size_t N>
    +    static invoked evaluate_category(std::bitset<N + 1>&&)
    +    {
    +        return passed_by_rvalue_reference;
    +    }
    +};
    +
    +

    Define the named parameters that will comprise the argument specification +that this macro will use. Ensure that all their tag types are in the same +namespace, which is kw in this case. The +identifiers with leading underscores can be passed to the bracket operator of +args to extract the same argument to which +the corresponding named parameter (without underscores) is bound, as will b +shown later.

    +
    +BOOST_PARAMETER_NAME((_lrc, kw) in(lrc))
    +BOOST_PARAMETER_NAME((_lr, kw) in_out(lr))
    +BOOST_PARAMETER_NAME((_rrc, kw) in(rrc))
    +BOOST_PARAMETER_NAME((_rr, kw) consume(rr))
    +
    +

    Use the macro as a substitute for a normal const member function header. Enclose the return type bool in parentheses. For each parameter, also +enclose the expected value type in parentheses. Since the value types are +mutually exclusive, you can wrap the parameters in a (deduced …) clause. Otherwise, just as with a +normal function, the order in which you specify the parameters determines +their position. However, unlike a normal function, default values must be +specified within the function body. Also within the function body, you must +pass the matching identifier with the leading underscore to the bracket +operator of args to extract the +corresponding argument, but at least this doesn't require std::forward to preserve value categories.

    +
    +struct B
    +{
    +    B()
    +    {
    +    }
    +
    +    BOOST_PARAMETER_BASIC_CONST_MEMBER_FUNCTION((bool), evaluate, kw,
    +        (deduced
    +            (required
    +                (lrc, (std::bitset<1>))
    +                (lr, (std::bitset<2>))
    +            )
    +            (optional
    +                (rrc, (std::bitset<3>))
    +                (rr, (std::bitset<4>))
    +            )
    +        )
    +    )
    +    {
    +        BOOST_TEST_EQ(
    +            passed_by_lvalue_reference_to_const
    +          , U::evaluate_category<0>(args[_lrc])
    +        );
    +        BOOST_TEST_EQ(
    +            passed_by_lvalue_reference
    +          , U::evaluate_category<1>(args[_lr])
    +        );
    +        BOOST_TEST_EQ(
    +            passed_by_rvalue_reference_to_const
    +          , U::evaluate_category<2>(
    +                args[_rrc0 | rvalue_const_bitset<2>()]
    +            )
    +        );
    +        BOOST_TEST_EQ(
    +            passed_by_rvalue_reference
    +          , U::evaluate_category<3>(
    +                args[_rr0 | rvalue_bitset<3>()]
    +            )
    +        );
    +
    +        return true;
    +    }
    +};
    +
    +

    The following function calls are legal.

    +
    +B const b = B();
    +b.evaluate(  // positional arguments
    +    lvalue_const_bitset<0>()
    +  , lvalue_bitset<1>()
    +  , rvalue_const_bitset<2>()
    +  , rvalue_bitset<3>()
    +);
    +b.evaluate(  // positional arguments
    +    lvalue_const_bitset<0>()
    +  , lvalue_bitset<1>()
    +);
    +b.evaluate((  // composed arguments
    +    _rr0 = rvalue_bitset<3>()
    +  , _lrc0 = lvalue_const_bitset<0>()
    +  , _lr0 = lvalue_bitset<1>()
    +  , _rrc0 = rvalue_const_bitset<2>()
    +));
    +b.evaluate(  // named arguments
    +    _rr0 = rvalue_bitset<3>()
    +  , _lrc0 = lvalue_const_bitset<0>()
    +  , _lr0 = lvalue_bitset<1>()
    +  , _rrc0 = rvalue_const_bitset<2>()
    +);
    +b.evaluate(  // named arguments
    +    _lr0 = lvalue_bitset<1>()
    +  , _lrc0 = lvalue_const_bitset<0>()
    +);
    +
    +

    Because the parameters were wrapped in a (deduced …) clause, the following function calls are also legal.

    +
    +b.evaluate(  // deduced arguments
    +    rvalue_bitset<3>()
    +  , lvalue_const_bitset<0>()
    +  , lvalue_bitset<1>()
    +  , rvalue_const_bitset<2>()
    +);
    +b.evaluate(  // deduced arguments
    +    lvalue_bitset<1>()
    +  , lvalue_const_bitset<0>()
    +);
    +

    The test/preprocessor.cpp test program demonstrates proper usage of this macro.

    +
    Macro parameters:
      +
      +
    • result is the parenthesized return type +of the function.
    • +
    • name is the base name of the function; +it determines the name of the generated forwarding functions.
    • +
    • tag_namespace is the namespace in which +the keywords used by the function resides.
    • +
    • arguments is a list of argument +specifiers, as defined below.
    • +
    +
    Argument specifiers syntax:
      +
    +argument-specifiers ::= specifier-group0 {specifier-group0}
    +
    +specifier-group0 ::= specifier-group1 |
    +    (
    +        '(' 'deduced'
    +            specifier-group1 {specifier-group1}
    +        ')'
    +    )
    +
    +specifier-group1 ::=
    +    (
    +        '(' 'optional'
    +            specifier {specifier}
    +        ')'
    +    ) | (
    +        '(' 'required'
    +            specifier {specifier}
    +        ')'
    +    )
    +
    +specifier ::=
    +    '(' argument-name ',' restriction ')'
    +
    +restriction ::=
    +    ( '*' '(' mfc ')' ) |
    +    ( '(' typename ')' ) |
    +    '*'
    +
    +
      +
    • argument-name is any valid C++ +identifier.
    • +
    • mfc is an MPL Binary +Metafunction Class whose first argument will be the type of the +corresponding argument-name, whose second +argument will be the entire ArgumentPack, and whose return type is a +Boolean Integral +Concept; however, user code cannot compute +mfc in terms of +previous-name ## _type.
    • +
    • type-name is either the name of a +target type or an MPL Binary +Metafunction Class whose first argument will be the type of the +corresponding argument-name, whose second +argument will be the entire ArgumentPack, and whose return type is the +target type.
    • +
    +

    Note that specifier does not include default-value. It +is up to the function body to determine the default value of all optional +arguments.

    +
    +
    +
    Approximate expansion:
    +
    +

    Where:

    +
      +
    • n denotes the minimum arity, as +determined from arguments.
    • +
    • m denotes the maximum arity, as +determined from arguments.
    • +
    +
    +template <typename T>
    +struct boost_param_result_const_ ## __LINE__ ## name
    +{
    +    typedef result type;
    +};
    +
    +struct boost_param_params_const_ ## __LINE__ ## name
    +  : parameters<
    +        list of parameter specifications, based on arguments
    +    >
    +{
    +};
    +
    +typedef boost_param_params_const_ ## __LINE__ ## name
    +    boost_param_parameters_const_ ## __LINE__ ## name;
    +
    +template <typename A0, …, typename A ## n>
    +result type
    +    name(
    +        A0&& a0, …, A ## n && a ## n
    +      , typename boost_param_parameters_const_ ## __LINE__ ## name::match<
    +            A0, …, A ## n
    +        >::type = boost_param_parameters_const_ ## __LINE__ ## name()
    +    ) const
    +{
    +    return this->boost_param_impl_const ## __LINE__ ## name(
    +        boost_param_parameters_const_ ## __LINE__ ## name()(
    +            std::forward<A0>(a0)
    +          , …
    +          , std::forward<A ## n>(a ## n)
    +        )
    +    );
    +}
    +
    +
    +
    +template <typename A0, …, typename A ## m>
    +result type
    +    name(
    +        A0&& a0, …, A ## m && a ## m
    +      , typename boost_param_parameters_const_ ## __LINE__ ## name::match<
    +            A0, …, A ## m
    +        >::type = boost_param_parameters_const_ ## __LINE__ ## name()
    +    ) const
    +{
    +    return this->boost_param_impl_const ## __LINE__ ## name(
    +        boost_param_parameters_const_ ## __LINE__ ## name()(
    +            std::forward<A0>(a0)
    +          , …
    +          , std::forward<A ## m>(a ## m)
    +        )
    +    );
    +}
    +
    +template <typename Args>
    +typename boost_param_result_const_ ## __LINE__ ## name<Args>::type
    +    boost_param_impl_const ## __LINE__ ## name(Args const& args) const
    +
    +

    Only the ArgumentPack type Args and its object instance args are +available for use within the function body.

    +
    +
    +
    +
    +

    7.10   BOOST_PARAMETER_BASIC_FUNCTION_CALL_OPERATOR(result, +tag_ns, arguments)

    + +++ + + + + + +
    Defined in:boost/parameter/preprocessor.hpp
    +

    Generates a function call operator that can take in positional arguments, +composed arguments, named arguments, and deduced arguments.

    + +++ + + + + + + + + + + + + + + + + + + + + + + +
    Example usage:
      +

    Define the named parameters that will comprise the argument specification +that this macro will use. Ensure that all their tag types are in the same +namespace, which is tag by default.

    +
    +BOOST_PARAMETER_NAME(y)
    +BOOST_PARAMETER_NAME(z)
    +
    +

    Use the macro as a substitute for a normal function call operator +header. Enclose the return type in parentheses. For each parameter, also +enclose the expected value type in parentheses. Since the value types are +mutually exclusive, you can wrap the parameters in a (deduced …) clause. This is especially useful +when implementing multiple Boost.Parameter-enabled function call operator +overloads.

    +
    +class char_reader
    +{
    +    int index;
    +    char const* key;
    +
    + public:
    +    explicit char_reader(char const* k) : index(0), key(k)
    +    {
    +    }
    +
    +    BOOST_PARAMETER_BASIC_FUNCTION_CALL_OPERATOR((void), tag,
    +        (deduced
    +            (required
    +                (y, (int))
    +                (z, (char const*))
    +            )
    +        )
    +    )
    +    {
    +        this->index = args[_y];
    +        this->key = args[_z];
    +    }
    +
    +    BOOST_PARAMETER_BASIC_CONST_FUNCTION_CALL_OPERATOR((char), tag,
    +        (deduced
    +            (required
    +                (y, (bool))
    +                (z, (std::map<char const*,std::string>))
    +            )
    +        )
    +    )
    +    {
    +        return args[_y] ? (
    +            (args[_z].find(this->key)->second)[this->index]
    +        ) : this->key[this->index];
    +    }
    +};
    +
    +

    As with regular argument-dependent lookup, the value types of the arguments +passed in determine which function call operator overload gets invoked.

    +
    +char const* keys[] = {"foo", "bar", "baz"};
    +std::map<char const*,std::string> k2s;
    +k2s[keys[0]] = std::string>("qux");
    +k2s[keys[1]] = std::string>("wmb");
    +k2s[keys[2]] = std::string>("zxc");
    +char_reader r(keys[0]);
    +
    +// positional arguments
    +BOOST_TEST_EQ('q', (r(true, k2s)));
    +BOOST_TEST_EQ('f', (r(false, k2s)));
    +
    +// named arguments
    +r(_z = keys[1], _y = 1);
    +BOOST_TEST_EQ('m', (r(_z = k2s, _y = true)));
    +BOOST_TEST_EQ('a', (r(_z = k2s, _y = false)));
    +
    +// deduced arguments
    +r(keys[2], 2);
    +BOOST_TEST_EQ('c', (r(k2s, true)));
    +BOOST_TEST_EQ('z', (r(k2s, false)));
    +
    +

    The test/preprocessor.cpp test program demonstrates proper usage of this +macro.

    +
    Macro parameters:
      +
      +
    • result is the parenthesized return type +of the function call operator.
    • +
    • tag_namespace is the namespace in which +the keywords used by the function call operator resides.
    • +
    • arguments is a list of argument +specifiers, as defined below.
    • +
    +
    Argument specifiers syntax:
      +
    +argument-specifiers ::= specifier-group0 {specifier-group0}
    +
    +specifier-group0 ::= specifier-group1 |
    +    (
    +        '(' 'deduced'
    +            specifier-group1 {specifier-group1}
    +        ')'
    +    )
    +
    +specifier-group1 ::=
    +    (
    +        '(' 'optional'
    +            specifier {specifier}
    +        ')'
    +    ) | (
    +        '(' 'required'
    +            specifier {specifier}
    +        ')'
    +    )
    +
    +specifier ::=
    +    '(' argument-name ',' restriction ')'
    +
    +restriction ::=
    +    ( '*' '(' mfc ')' ) |
    +    ( '(' typename ')' ) |
    +    '*'
    +
    +
      +
    • argument-name is any valid C++ +identifier.
    • +
    • mfc is an MPL Binary +Metafunction Class whose first argument will be the type of the +corresponding argument-name, whose second +argument will be the entire ArgumentPack, and whose return type is a +Boolean Integral +Concept; however, user code cannot compute +mfc in terms of +previous-name ## _type.
    • +
    • type-name is either the name of a +target type or an MPL Binary +Metafunction Class whose first argument will be the type of the +corresponding argument-name, whose second +argument will be the entire ArgumentPack, and whose return type is the +target type.
    • +
    +

    Note that specifier does not include default-value. It +is up to the function body to determine the default value of all optional +arguments.

    +
    +
    +
    Approximate expansion:
    +
    +

    Where:

    +
      +
    • n denotes the minimum arity, as +determined from arguments.
    • +
    • m denotes the maximum arity, as +determined from arguments.
    • +
    +
    +template <typename T>
    +struct boost_param_result_ ## __LINE__ ## operator
    +{
    +    typedef result type;
    +};
    +
    +struct boost_param_params_ ## __LINE__ ## operator
    +  : parameters<
    +        list of parameter specifications, based on arguments
    +    >
    +{
    +};
    +
    +typedef boost_param_params_ ## __LINE__ ## operator
    +    boost_param_parameters_ ## __LINE__ ## operator;
    +
    +template <typename A0, …, typename A ## n>
    +result type
    +    operator()(
    +        A0&& a0, …, A ## n && a ## n
    +      , typename boost_param_parameters_ ## __LINE__ ## operator
    +        ::match<A0, …, A ## n>::type
    +        = boost_param_parameters_ ## __LINE__ ## operator()
    +    )
    +{
    +    return this->boost_param_impl ## __LINE__ ## operator(
    +        boost_param_parameters_ ## __LINE__ ## operator()(
    +            std::forward<A0>(a0)
    +          , …
    +          , std::forward<A ## n>(a ## n)
    +        )
    +    );
    +}
    +
    +
    +
    +template <typename A0, …, typename A ## m>
    +result type
    +    operator()(
    +        A0&& a0, …, A ## m && a ## m
    +      , typename boost_param_parameters_ ## __LINE__ ## operator
    +        ::match<A0, …, A ## m>::type
    +        = boost_param_parameters_ ## __LINE__ ## operator()
    +    )
    +{
    +    return this->boost_param_impl ## __LINE__ ## operator(
    +        boost_param_parameters_ ## __LINE__ ## operator()(
    +            std::forward<A0>(a0)
    +          , …
    +          , std::forward<A ## m>(a ## m)
    +        )
    +    );
    +}
    +
    +template <typename Args>
    +typename boost_param_result_ ## __LINE__ ## operator<Args>::type
    +    boost_param_impl ## __LINE__ ## operator(Args const& args)
    +
    +
    +
    +
    +
    +

    7.11   BOOST_PARAMETER_BASIC_CONST_FUNCTION_CALL_OPERATOR(result, tag_ns, +args)

    + +++ + + + + + +
    Defined in:boost/parameter/preprocessor.hpp
    +

    Generates a function call operator that can take in positional arguments, +composed arguments, named arguments, and deduced arguments.

    + +++ + + + + + + + + + + + + + + + + + + + + + + +
    Example usage:
      +

    The return type of each of the following function templates falls under a +different value category.

    +
    +template <std::size_t N>
    +std::bitset<N + 1> rvalue_bitset()
    +{
    +    return std::bitset<N + 1>();
    +}
    +
    +template <std::size_t N>
    +std::bitset<N + 1> const rvalue_const_bitset()
    +{
    +    return std::bitset<N + 1>();
    +}
    +
    +template <std::size_t N>
    +std::bitset<N + 1>& lvalue_bitset()
    +{
    +    static std::bitset<N + 1> lset = std::bitset<N + 1>();
    +    return lset;
    +}
    +
    +template <std::size_t N>
    +std::bitset<N + 1> const& lvalue_const_bitset()
    +{
    +    static std::bitset<N + 1> const clset = std::bitset<N + 1>();
    +    return clset;
    +}
    +
    +

    The U::evaluate_category static member +function template has a simple job: to return the correct value category when +passed in an object returned by one of the functions defined above. Assume +that BOOST_PARAMETER_HAS_PERFECT_FORWARDING is defined.

    +
    +enum invoked
    +{
    +    passed_by_lvalue_reference_to_const
    +  , passed_by_lvalue_reference
    +  , passed_by_rvalue_reference_to_const
    +  , passed_by_rvalue_reference
    +};
    +
    +struct U
    +{
    +    template <std::size_t N>
    +    static invoked evaluate_category(std::bitset<N + 1> const&)
    +    {
    +        return passed_by_lvalue_reference_to_const;
    +    }
    +
    +    template <std::size_t N>
    +    static invoked evaluate_category(std::bitset<N + 1>&)
    +    {
    +        return passed_by_lvalue_reference;
    +    }
    +
    +    template <std::size_t N>
    +    static invoked evaluate_category(std::bitset<N + 1> const&&)
    +    {
    +        return passed_by_rvalue_reference_to_const;
    +    }
    +
    +    template <std::size_t N>
    +    static invoked evaluate_category(std::bitset<N + 1>&&)
    +    {
    +        return passed_by_rvalue_reference;
    +    }
    +};
    +
    +

    Define the named parameters that will comprise the argument specification +that this macro will use. Ensure that all their tag types are in the same +namespace, which is kw in this case. The +identifiers with leading underscores can be passed to the bracket operator of +args to extract the same argument to which +the corresponding named parameter (without underscores) is bound, as will be +shown later.

    +
    +BOOST_PARAMETER_NAME((_lrc, kw) in(lrc))
    +BOOST_PARAMETER_NAME((_lr, kw) in_out(lr))
    +BOOST_PARAMETER_NAME((_rrc, kw) in(rrc))
    +BOOST_PARAMETER_NAME((_rr, kw) consume(rr))
    +
    +

    Use the macro as a substitute for a normal const function call operator header. Enclose the return type bool in parentheses. For each parameter, also +enclose the expected value type in parentheses. Since the value types are +mutually exclusive, you can wrap the parameters in a (deduced …) clause. Otherwise, just as with a +normal function, the order in which you specify the parameters determines +their position. However, unlike a normal function, default values must be +specified within the function body. Also within the function body, you must +pass the matching identifier with the leading underscore to the bracket +operator of args to extract the +corresponding argument, but at least this doesn't require std::forward to preserve value categories.

    +
    +struct B
    +{
    +    B()
    +    {
    +    }
    +
    +    BOOST_PARAMETER_BASIC_CONST_FUNCTION_CALL_OPERATOR((bool), kw,
    +        (deduced
    +            (required
    +                (lrc, (std::bitset<1>))
    +                (lr, (std::bitset<2>))
    +            )
    +            (optional
    +                (rrc, (std::bitset<3>))
    +                (rr, (std::bitset<4>))
    +            )
    +        )
    +    )
    +    {
    +        BOOST_TEST_EQ(
    +            passed_by_lvalue_reference_to_const
    +          , U::evaluate_category<0>(args[_lrc])
    +        );
    +        BOOST_TEST_EQ(
    +            passed_by_lvalue_reference
    +          , U::evaluate_category<1>(args[_lr])
    +        );
    +        BOOST_TEST_EQ(
    +            passed_by_rvalue_reference_to_const
    +          , U::evaluate_category<2>(
    +                args[_rrc0 | rvalue_const_bitset<2>()]
    +            )
    +        );
    +        BOOST_TEST_EQ(
    +            passed_by_rvalue_reference
    +          , U::evaluate_category<3>(
    +                args[_rr0 | rvalue_bitset<3>()]
    +            )
    +        );
    +
    +        return true;
    +    }
    +};
    +
    +

    The following function calls are legal.

    +
    +B const b = B();
    +b(  // positional arguments
    +    lvalue_const_bitset<0>()
    +  , lvalue_bitset<1>()
    +  , rvalue_const_bitset<2>()
    +  , rvalue_bitset<3>()
    +);
    +b(  // positional arguments
    +    lvalue_const_bitset<0>()
    +  , lvalue_bitset<1>()
    +);
    +b((  // composed arguments
    +    _rr0 = rvalue_bitset<3>()
    +  , _lrc0 = lvalue_const_bitset<0>()
    +  , _lr0 = lvalue_bitset<1>()
    +  , _rrc0 = rvalue_const_bitset<2>()
    +));
    +b(  // named arguments
    +    _rr0 = rvalue_bitset<3>()
    +  , _lrc0 = lvalue_const_bitset<0>()
    +  , _lr0 = lvalue_bitset<1>()
    +  , _rrc0 = rvalue_const_bitset<2>()
    +);
    +b(  // named arguments
    +    _lr0 = lvalue_bitset<1>()
    +  , _lrc0 = lvalue_const_bitset<0>()
    +);
    +
    +

    Because the parameters were wrapped in a (deduced …) clause, the following function calls are also legal.

    +
    +b(  // deduced arguments
    +    rvalue_bitset<3>()
    +  , lvalue_const_bitset<0>()
    +  , lvalue_bitset<1>()
    +  , rvalue_const_bitset<2>()
    +);
    +b(  // deduced arguments
    +    lvalue_bitset<1>()
    +  , lvalue_const_bitset<0>()
    +);
    +
    +

    The test/preprocessor.cpp test program demonstrates proper usage of this +macro.

    +
    Macro parameters:
      +
      +
    • result is the parenthesized return type +of the function call operator.
    • +
    • tag_namespace is the namespace in which +the keywords used by the function call operator resides.
    • +
    • arguments is a list of argument +specifiers, as defined below.
    • +
    +
    Argument specifiers syntax:
      +
    +argument-specifiers ::= specifier-group0 {specifier-group0}
    +
    +specifier-group0 ::= specifier-group1 |
    +    (
    +        '(' 'deduced'
    +            specifier-group1 {specifier-group1}
    +        ')'
    +    )
    +
    +specifier-group1 ::=
    +    (
    +        '(' 'optional'
    +            specifier {specifier}
    +        ')'
    +    ) | (
    +        '(' 'required'
    +            specifier {specifier}
    +        ')'
    +    )
    +
    +specifier ::=
    +    '(' argument-name ',' restriction ')'
    +
    +restriction ::=
    +    ( '*' '(' mfc ')' ) |
    +    ( '(' typename ')' ) |
    +    '*'
    +
    +
      +
    • argument-name is any valid C++ +identifier.
    • +
    • mfc is an MPL Binary +Metafunction Class whose first argument will be the type of the +corresponding argument-name, whose second +argument will be the entire ArgumentPack, and whose return type is a +Boolean Integral +Concept; however, user code cannot compute +mfc in terms of +previous-name ## _type.
    • +
    • type-name is either the name of a +target type or an MPL Binary +Metafunction Class whose first argument will be the type of the +corresponding argument-name, whose second +argument will be the entire ArgumentPack, and whose return type is the +target type.
    • +
    +

    Note that specifier does not include default-value. It +is up to the function body to determine the default value of all optional +arguments.

    +
    +
    +
    Approximate expansion:
    +
    +

    Where:

    +
      +
    • n denotes the minimum arity, as +determined from arguments.
    • +
    • m denotes the maximum arity, as +determined from arguments.
    • +
    +
    +template <typename T>
    +struct boost_param_result_const_ ## __LINE__ ## operator
    +{
    +    typedef result type;
    +};
    +
    +struct boost_param_params_const_ ## __LINE__ ## operator
    +  : parameters<
    +        list of parameter specifications, based on arguments
    +    >
    +{
    +};
    +
    +typedef boost_param_params_const_ ## __LINE__ ## operator
    +    boost_param_parameters_const_ ## __LINE__ ## operator;
    +
    +template <typename A0, …, typename A ## n>
    +result type
    +    operator()(
    +        A0&& a0, …, A ## n && a ## n
    +      , typename boost_param_parameters_const_ ## __LINE__ ## operator
    +        ::match<A0, …, A ## n>::type
    +        = boost_param_parameters_const_ ## __LINE__ ## operator()
    +    ) const
    +{
    +    return this->boost_param_impl_const ## __LINE__ ## operator(
    +        boost_param_parameters_const_ ## __LINE__ ## operator()(
    +            std::forward<A0>(a0)
    +          , …
    +          , std::forward<A ## n>(a ## n)
    +        )
    +    );
    +}
    +
    +
    +
    +template <typename A0, …, typename A ## m>
    +result type
    +    operator()(
    +        A0&& a0, …, A ## m && a ## m
    +      , typename boost_param_parameters_const_ ## __LINE__ ## operator
    +        ::match<A0, …, A ## m>::type
    +        = boost_param_parameters_const_ ## __LINE__ ## operator()
    +    ) const
    +{
    +    return this->boost_param_impl_const ## __LINE__ ## operator(
    +        boost_param_parameters_const_ ## __LINE__ ## operator()(
    +            std::forward<A0>(a0)
    +          , …
    +          , std::forward<A ## m>(a ## m)
    +        )
    +    );
    +}
    +
    +template <typename Args>
    +typename boost_param_result_const_ ## __LINE__ ## operator<Args>::type
    +    boost_param_impl_const ## __LINE__ ## operator(Args const& args) const
    +
    +
    +
    +
    +
    +

    7.12   BOOST_PARAMETER_NO_SPEC_FUNCTION(result, +name)

    + +++ + + + + + +
    Defined in:boost/parameter/preprocessor_no_spec.hpp
    +

    Generates a function that can take in named arguments.

    + +++ + + + + + + + + + + + + + + + + + + + + + + +
    Example usage:
      +

    The return type of each of the following function templates falls under a +different value category.

    +
    +template <std::size_t N>
    +std::bitset<N + 1> rvalue_bitset()
    +{
    +    return std::bitset<N + 1>();
    +}
    +
    +template <std::size_t N>
    +std::bitset<N + 1> const rvalue_const_bitset()
    +{
    +    return std::bitset<N + 1>();
    +}
    +
    +template <std::size_t N>
    +std::bitset<N + 1>& lvalue_bitset()
    +{
    +    static std::bitset<N + 1> lset = std::bitset<N + 1>();
    +    return lset;
    +}
    +
    +template <std::size_t N>
    +std::bitset<N + 1> const& lvalue_const_bitset()
    +{
    +    static std::bitset<N + 1> const clset = std::bitset<N + 1>();
    +    return clset;
    +}
    +
    +

    The U::evaluate_category static member +function template has a simple job: to return the correct value category when +passed in an object returned by one of the functions defined above. Assume +that BOOST_PARAMETER_HAS_PERFECT_FORWARDING is defined.

    +
    +enum invoked
    +{
    +    passed_by_lvalue_reference_to_const
    +  , passed_by_lvalue_reference
    +  , passed_by_rvalue_reference_to_const
    +  , passed_by_rvalue_reference
    +};
    +
    +struct U
    +{
    +    template <std::size_t N>
    +    static invoked evaluate_category(std::bitset<N + 1> const&)
    +    {
    +        return passed_by_lvalue_reference_to_const;
    +    }
    +
    +    template <std::size_t N>
    +    static invoked evaluate_category(std::bitset<N + 1>&)
    +    {
    +        return passed_by_lvalue_reference;
    +    }
    +
    +    template <std::size_t N>
    +    static invoked evaluate_category(std::bitset<N + 1> const&&)
    +    {
    +        return passed_by_rvalue_reference_to_const;
    +    }
    +
    +    template <std::size_t N>
    +    static invoked evaluate_category(std::bitset<N + 1>&&)
    +    {
    +        return passed_by_rvalue_reference;
    +    }
    +};
    +
    +

    Named parameters are required when invoking the function; however, none of +their tags need to be in the same namespace.

    +
    +BOOST_PARAMETER_NAME((_lrc, kw0) in(lrc))
    +BOOST_PARAMETER_NAME((_lr, kw1) in_out(lr))
    +BOOST_PARAMETER_NAME((_rrc, kw2) in(rrc))
    +BOOST_PARAMETER_NAME((_rr, kw3) consume(rr))
    +
    +

    Use the macro as a substitute for a variadic function header. Enclose the +return type bool in parentheses.

    +
    +BOOST_PARAMETER_NO_SPEC_FUNCTION((bool), evaluate)
    +{
    +    BOOST_TEST_EQ(
    +        passed_by_lvalue_reference_to_const
    +      , U::evaluate_category<0>(args[_lrc])
    +    );
    +    BOOST_TEST_EQ(
    +        passed_by_lvalue_reference
    +      , U::evaluate_category<1>(args[_lr])
    +    );
    +    BOOST_TEST_EQ(
    +        passed_by_rvalue_reference_to_const
    +      , U::evaluate_category<2>(
    +            args[_rrc0 | rvalue_const_bitset<2>()]
    +        )
    +    );
    +    BOOST_TEST_EQ(
    +        passed_by_rvalue_reference
    +      , U::evaluate_category<3>(args[_rr0 | rvalue_bitset<3>()])
    +    );
    +
    +    return true;
    +}
    +
    +

    To invoke the function, bind all its arguments to named parameters.

    +
    +evaluate(
    +    _rr0 = rvalue_bitset<3>()
    +  , _lrc0 = lvalue_const_bitset<0>()
    +  , _lr0 = lvalue_bitset<1>()
    +  , _rrc0 = rvalue_const_bitset<2>()
    +);
    +evaluate(
    +    _lr0 = lvalue_bitset<1>()
    +  , _lrc0 = lvalue_const_bitset<0>()
    +);
    +
    +

    The test/preprocessor_eval_cat_no_spec.cpp test program demonstrates proper +usage of this macro.

    +
    Macro parameters:
      +
      +
    • result is the parenthesized return type +of the function.
    • +
    • name is the base name of the function; +it determines the name of the generated implementation function.
    • +
    +
    Argument specifiers syntax:
     None.
    +
    +
    Approximate expansion:
    +
    +
    +template <typename TaggedArg0, typename ...TaggedArgs>
    +struct boost_param_no_spec_result_ ## __LINE__ ## name
    +{
    +    typedef result type;
    +};
    +
    +template <typename ResultType, typename Args>
    +ResultType
    +    boost_param_no_spec_impl ## __LINE__ ## name(
    +        (ResultType(*)())
    +      , Args const& args
    +    );
    +
    +template <typename TaggedArg0, typename ...TaggedArgs>
    +inline typename boost::lazy_enable_if<
    +    are_tagged_arguments<TaggedArg0,TaggedArgs...>
    +  , boost_param_no_spec_result_ ## __LINE__ ## name<
    +        TaggedArg0
    +      , TaggedArgs...
    +    >
    +>::type
    +    name(TaggedArg0 const& arg0, TaggedArgs const&... args)
    +{
    +    return boost_param_no_spec_impl ## __LINE__ ## name(
    +        static_cast<
    +            typename
    +            boost_param_no_spec_result_ ## __LINE__ ## name<
    +                TaggedArg0
    +              , TaggedArgs...
    +            >::type(*)()
    +        >(std::nullptr)
    +      , compose(arg0, args...)
    +    );
    +}
    +
    +template <typename ResultType, typename Args>
    +ResultType
    +    boost_param_no_spec_impl ## __LINE__ ## name(
    +        (ResultType(*)())
    +      , Args const& args
    +    )
    +
    +

    Only the ArgumentPack type Args and its object instance args are +available for use within the function body.

    +
    +
    +
    +
    +

    7.13   BOOST_PARAMETER_NO_SPEC_MEMBER_FUNCTION(result, +name)

    + +++ + + + + + +
    Defined in:boost/parameter/preprocessor_no_spec.hpp
    +

    Generates a member function that can take in named arguments.

    + +++ + + + + + + + + + + + + + + + + + + + + + + +
    Example usage:
      +

    When designing a front-end class template whose back-end is configurable +via parameterized inheritance, it can be useful to omit argument specifiers +from a named-parameter member function so that the delegate member functions +of the back-end classes can enforce their own specifications.

    +
    +template <typename B>
    +struct frontend : B
    +{
    +    frontend() : B()
    +    {
    +    }
    +
    +    BOOST_PARAMETER_NO_SPEC_MEMBER_FUNCTION((void), initialize)
    +    {
    +        this->initialize_impl(args);
    +    }
    +};
    +
    +

    Named parameters are required when invoking the member function; however, +none of their tags need to be in the same namespace.

    +
    +BOOST_PARAMETER_NAME(a0)
    +BOOST_PARAMETER_NAME(a1)
    +BOOST_PARAMETER_NAME(a2)
    +
    +

    For this example, each of the back-end class templates requires its own +parameter to be present in the argument pack. In practice, such parameters +should be optional, with default values.

    +
    +template <typename T>
    +class backend0
    +{
    +    T a0;
    +
    + public:
    +    backend0() : a0()
    +    {
    +    }
    +
    +    T const& get_a0() const
    +    {
    +        return this->a0;
    +    }
    +
    + protected:
    +    template <typename ArgPack>
    +    void initialize_impl(ArgPack const& args)
    +    {
    +        this->a0 = args[_a0];
    +    }
    +};
    +
    +template <typename B, typename T>
    +class backend1 : public B
    +{
    +    T a1;
    +
    + public:
    +    backend1() : B(), a1()
    +    {
    +    }
    +
    +    T const& get_a1() const
    +    {
    +        return this->a1;
    +    }
    +
    + protected:
    +    template <typename ArgPack>
    +    void initialize_impl(ArgPack const& args)
    +    {
    +        B::initialize_impl(args);
    +        this->a1 = args[_a1];
    +    }
    +};
    +
    +template <typename B, typename T>
    +class backend2 : public B
    +{
    +    T a2;
    +
    + public:
    +    backend2() : B(), a2()
    +    {
    +    }
    +
    +    T const& get_a2() const
    +    {
    +        return this->a2;
    +    }
    +
    + protected:
    +    template <typename ArgPack>
    +    void initialize_impl(ArgPack const& args)
    +    {
    +        B::initialize_impl(args);
    +        this->a2 = args[_a2];
    +    }
    +};
    +
    +

    This example shows that while backend0 +must always be the root base class template and that frontend must always be the most derived class +template, the other back-ends can be chained together in different orders.

    +
    +char const* p = "foo";
    +frontend<
    +    backend2<backend1<backend0<char const*>, char>, int>
    +> composed_obj0;
    +frontend<
    +    backend1<backend2<backend0<char const*>, int>, char>
    +> composed_obj1;
    +composed_obj0.initialize(_a2 = 4, _a1 = ' ', _a0 = p);
    +composed_obj1.initialize(_a0 = p, _a1 = ' ', _a2 = 4);
    +BOOST_TEST_EQ(composed_obj0.get_a0(), composed_obj1.get_a0());
    +BOOST_TEST_EQ(composed_obj0.get_a1(), composed_obj1.get_a1());
    +BOOST_TEST_EQ(composed_obj0.get_a2(), composed_obj1.get_a2());
    +
    +

    The test/parameterized_inheritance.cpp and test/preprocessor_eval_cat_no_spec.cpp test programs demonstrate proper +usage of this macro.

    +
    Macro parameters:
      +
      +
    • result is the parenthesized return type +of the function.
    • +
    • name is the base name of the function; +it determines the name of the generated implementation function. name may be qualified by the static keyword to declare the member function +and its helpers as not associated with any object of the enclosing type.
    • +
    +
    Argument specifiers syntax:
     None.
    +
    +
    Approximate expansion:
    +
    +
    +template <typename TaggedArg0, typename ...TaggedArgs>
    +struct boost_param_no_spec_result_ ## __LINE__ ## name
    +{
    +    typedef result type;
    +};
    +
    +template <typename TaggedArg0, typename ...TaggedArgs>
    +inline typename boost::lazy_enable_if<
    +    are_tagged_arguments<TaggedArg0,TaggedArgs...>
    +  , boost_param_no_spec_result_ ## __LINE__ ## name<
    +        TaggedArg0
    +      , TaggedArgs...
    +    >
    +>::type
    +    name(TaggedArg0 const& arg0, TaggedArgs const&... args)
    +{
    +    return this->boost_param_no_spec_impl ## __LINE__ ## name(
    +        static_cast<
    +            typename
    +            boost_param_no_spec_result_ ## __LINE__ ## name<
    +                TaggedArg0
    +              , TaggedArgs...
    +            >::type(*)()
    +        >(std::nullptr)
    +      , compose(arg0, args...)
    +    );
    +}
    +
    +template <typename ResultType, typename Args>
    +ResultType
    +    boost_param_no_spec_impl ## __LINE__ ## name(
    +        (ResultType(*)())
    +      , Args const& args
    +    )
    +
    +

    Only the ArgumentPack type Args and its object instance args are +available for use within the function body.

    +
    +
    +
    +
    +

    7.14   BOOST_PARAMETER_NO_SPEC_CONST_MEMBER_FUNCTION(result, +name)

    + +++ + + + + + +
    Defined in:boost/parameter/preprocessor_no_spec.hpp
    +

    Generates a member function that can take in named arguments.

    + +++ + + + + + + + + + + + + + + + + + + + + + + +
    Example usage:
      +

    The return type of each of the following function templates falls under a +different value category.

    +
    +template <std::size_t N>
    +std::bitset<N + 1> rvalue_bitset()
    +{
    +    return std::bitset<N + 1>();
    +}
    +
    +template <std::size_t N>
    +std::bitset<N + 1> const rvalue_const_bitset()
    +{
    +    return std::bitset<N + 1>();
    +}
    +
    +template <std::size_t N>
    +std::bitset<N + 1>& lvalue_bitset()
    +{
    +    static std::bitset<N + 1> lset = std::bitset<N + 1>();
    +    return lset;
    +}
    +
    +template <std::size_t N>
    +std::bitset<N + 1> const& lvalue_const_bitset()
    +{
    +    static std::bitset<N + 1> const clset = std::bitset<N + 1>();
    +    return clset;
    +}
    +
    +

    The U::evaluate_category static member +function template has a simple job: to return the correct value category when +passed in an object returned by one of the functions defined above. Assume +that BOOST_PARAMETER_HAS_PERFECT_FORWARDING is defined.

    +
    +enum invoked
    +{
    +    passed_by_lvalue_reference_to_const
    +  , passed_by_lvalue_reference
    +  , passed_by_rvalue_reference_to_const
    +  , passed_by_rvalue_reference
    +};
    +
    +struct U
    +{
    +    template <std::size_t N>
    +    static invoked evaluate_category(std::bitset<N + 1> const&)
    +    {
    +        return passed_by_lvalue_reference_to_const;
    +    }
    +
    +    template <std::size_t N>
    +    static invoked evaluate_category(std::bitset<N + 1>&)
    +    {
    +        return passed_by_lvalue_reference;
    +    }
    +
    +    template <std::size_t N>
    +    static invoked evaluate_category(std::bitset<N + 1> const&&)
    +    {
    +        return passed_by_rvalue_reference_to_const;
    +    }
    +
    +    template <std::size_t N>
    +    static invoked evaluate_category(std::bitset<N + 1>&&)
    +    {
    +        return passed_by_rvalue_reference;
    +    }
    +};
    +
    +

    Named parameters are required when invoking the member function; however, +none of their tags need to be in the same namespace.

    +
    +BOOST_PARAMETER_NAME((_lrc, kw0) in(lrc))
    +BOOST_PARAMETER_NAME((_lr, kw1) in_out(lr))
    +BOOST_PARAMETER_NAME((_rrc, kw2) in(rrc))
    +BOOST_PARAMETER_NAME((_rr, kw3) consume(rr))
    +
    +

    Use the macro as a substitute for a variadic function header. Enclose the +return type bool in parentheses. The macro +will qualify the function with the const +keyword.

    +
    +struct D
    +{
    +    D()
    +    {
    +    }
    +
    +    BOOST_PARAMETER_NO_SPEC_CONST_MEMBER_FUNCTION((bool), evaluate_m)
    +    {
    +        BOOST_TEST_EQ(
    +            passed_by_lvalue_reference_to_const
    +          , U::evaluate_category<0>(args[_lrc])
    +        );
    +        BOOST_TEST_EQ(
    +            passed_by_lvalue_reference
    +          , U::evaluate_category<1>(args[_lr])
    +        );
    +        BOOST_TEST_EQ(
    +            passed_by_rvalue_reference_to_const
    +          , U::evaluate_category<2>(
    +                args[_rrc0 | rvalue_const_bitset<2>()]
    +            )
    +        );
    +        BOOST_TEST_EQ(
    +            passed_by_rvalue_reference
    +          , U::evaluate_category<3>(
    +                args[_rr0 | rvalue_bitset<3>()]
    +            )
    +        );
    +
    +        return true;
    +    }
    +};
    +
    +

    To invoke the member function, bind all its arguments to named +parameters.

    +
    +D const d = D();
    +d.evaluate_m(
    +    _rr0 = rvalue_bitset<3>()
    +  , _lrc0 = lvalue_const_bitset<0>()
    +  , _lr0 = lvalue_bitset<1>()
    +  , _rrc0 = rvalue_const_bitset<2>()
    +);
    +d.evaluate_m(
    +    _lr0 = lvalue_bitset<1>()
    +  , _lrc0 = lvalue_const_bitset<0>()
    +);
    +
    +

    The test/preprocessor_eval_cat_no_spec.cpp test program demonstrates proper +usage of this macro.

    +
    Macro parameters:
      +
      +
    • result is the parenthesized return type +of the function.
    • +
    • name is the base name of the function; +it determines the name of the generated implementation function.
    • +
    +
    Argument specifiers syntax:
     None.
    +
    +
    Approximate expansion:
    +
    +
    +template <typename TaggedArg0, typename ...TaggedArgs>
    +struct boost_param_no_spec_result_const_ ## __LINE__ ## name
    +{
    +    typedef result type;
    +};
    +
    +template <typename TaggedArg0, typename ...TaggedArgs>
    +inline typename boost::lazy_enable_if<
    +    are_tagged_arguments<TaggedArg0,TaggedArgs...>
    +  , boost_param_no_spec_result_const_ ## __LINE__ ## name<
    +        TaggedArg0
    +      , TaggedArgs...
    +    >
    +>::type
    +    name(TaggedArg0 const& arg0, TaggedArgs const&... args) const
    +{
    +    return this->boost_param_no_spec_impl_const ## __LINE__ ## name(
    +        static_cast<
    +            typename
    +            boost_param_no_spec_result_const_ ## __LINE__ ## name<
    +                TaggedArg0
    +              , TaggedArgs...
    +            >::type(*)()
    +        >(std::nullptr)
    +      , compose(arg0, args...)
    +    );
    +}
    +
    +template <typename ResultType, typename Args>
    +ResultType
    +    boost_param_no_spec_impl_const ## __LINE__ ## name(
    +        (ResultType(*)())
    +      , Args const& args
    +    ) const
    +
    +

    Only the ArgumentPack type Args and its object instance args are +available for use within the function body.

    +
    +
    +
    +
    +

    7.15   BOOST_PARAMETER_NO_SPEC_FUNCTION_CALL_OPERATOR(result)

    + +++ + + + + + +
    Defined in:boost/parameter/preprocessor_no_spec.hpp
    +

    Generates a function call operator that can take in named arguments.

    + +++ + + + + + + + + + + + + + + + + + + + + + + +
    Example usage:
      +

    When designing a front-end class template whose back-end is configurable +via parameterized inheritance, it can be useful to omit argument specifiers +from a named-parameter function call operator so that the delegate member +functions of the back-end classes can enforce their own specifications.

    +
    +template <typename B>
    +struct frontend : B
    +{
    +    frontend() : B()
    +    {
    +    }
    +
    +    BOOST_PARAMETER_NO_SPEC_FUNCTION_CALL_OPERATOR((void))
    +    {
    +        this->initialize_impl(args);
    +    }
    +};
    +
    +

    Named parameters are required when invoking the function call operator; +however, none of their tags need to be in the same namespace.

    +
    +BOOST_PARAMETER_NAME(a0)
    +BOOST_PARAMETER_NAME(a1)
    +BOOST_PARAMETER_NAME(a2)
    +
    +

    For this example, each of the back-end class templates requires its own +parameter to be present in the argument pack. In practice, such parameters +should be optional, with default values.

    +
    +template <typename T>
    +class backend0
    +{
    +    T a0;
    +
    + public:
    +    backend0() : a0()
    +    {
    +    }
    +
    +    T const& get_a0() const
    +    {
    +        return this->a0;
    +    }
    +
    + protected:
    +    template <typename ArgPack>
    +    void initialize_impl(ArgPack const& args)
    +    {
    +        this->a0 = args[_a0];
    +    }
    +};
    +
    +template <typename B, typename T>
    +class backend1 : public B
    +{
    +    T a1;
    +
    + public:
    +    backend1() : B(), a1()
    +    {
    +    }
    +
    +    T const& get_a1() const
    +    {
    +        return this->a1;
    +    }
    +
    + protected:
    +    template <typename ArgPack>
    +    void initialize_impl(ArgPack const& args)
    +    {
    +        B::initialize_impl(args);
    +        this->a1 = args[_a1];
    +    }
    +};
    +
    +template <typename B, typename T>
    +class backend2 : public B
    +{
    +    T a2;
    +
    + public:
    +    backend2() : B(), a2()
    +    {
    +    }
    +
    +    T const& get_a2() const
    +    {
    +        return this->a2;
    +    }
    +
    + protected:
    +    template <typename ArgPack>
    +    void initialize_impl(ArgPack const& args)
    +    {
    +        B::initialize_impl(args);
    +        this->a2 = args[_a2];
    +    }
    +};
    +
    +

    This example shows that while backend0 +must always be the root base class template and that frontend must always be the most derived class +template, the other back-ends can be chained together in different orders.

    +
    +char const* p = "foo";
    +frontend<
    +    backend2<backend1<backend0<char const*>, char>, int>
    +> composed_obj0;
    +frontend<
    +    backend1<backend2<backend0<char const*>, int>, char>
    +> composed_obj1;
    +composed_obj0(_a2 = 4, _a1 = ' ', _a0 = p);
    +composed_obj1(_a0 = p, _a1 = ' ', _a2 = 4);
    +BOOST_TEST_EQ(composed_obj0.get_a0(), composed_obj1.get_a0());
    +BOOST_TEST_EQ(composed_obj0.get_a1(), composed_obj1.get_a1());
    +BOOST_TEST_EQ(composed_obj0.get_a2(), composed_obj1.get_a2());
    +
    +

    The test/parameterized_inheritance.cpp and test/preprocessor_eval_cat_no_spec.cpp test programs demonstrate proper +usage of this macro.

    +
    Macro parameters:
      +
      +
    • result is the parenthesized return type +of the function call operator.
    • +
    +
    Argument specifiers syntax:
     None.
    +
    +
    Approximate expansion:
    +
    +
    +template <typename TaggedArg0, typename ...TaggedArgs>
    +struct boost_param_no_spec_result_ ## __LINE__ ## operator
    +{
    +    typedef result type;
    +};
    +
    +template <typename TaggedArg0, typename ...TaggedArgs>
    +inline typename boost::lazy_enable_if<
    +    are_tagged_arguments<TaggedArg0,TaggedArgs...>
    +  , boost_param_no_spec_result_ ## __LINE__ ## operator<
    +        TaggedArg0
    +      , TaggedArgs...
    +    >
    +>::type
    +    operator()(TaggedArg0 const& arg0, TaggedArgs const&... args)
    +{
    +    return this->boost_param_no_spec_impl ## __LINE__ ## operator(
    +        static_cast<
    +            typename
    +            boost_param_no_spec_result_ ## __LINE__ ## operator<
    +                TaggedArg0
    +              , TaggedArgs...
    +            >::type(*)()
    +        >(std::nullptr)
    +      , compose(arg0, args...)
    +    );
    +}
    +
    +template <typename ResultType, typename Args>
    +ResultType
    +    boost_param_no_spec_impl ## __LINE__ ## operator(
    +        (ResultType(*)())
    +      , Args const& args
    +    )
    +
    +

    Only the ArgumentPack type Args and its object instance args are +available for use within the function body.

    +
    +
    +
    +
    +

    7.16   BOOST_PARAMETER_NO_SPEC_CONST_FUNCTION_CALL_OPERATOR(result)

    + +++ + + + + + +
    Defined in:boost/parameter/preprocessor_no_spec.hpp
    +

    Generates a function call operator that can take in named arguments.

    + +++ + + + + + + + + + + + + + + + + + + + + + + +
    Example usage:
      +

    The return type of each of the following function templates falls under a +different value category.

    +
    +template <std::size_t N>
    +std::bitset<N + 1> rvalue_bitset()
    +{
    +    return std::bitset<N + 1>();
    +}
    +
    +template <std::size_t N>
    +std::bitset<N + 1> const rvalue_const_bitset()
    +{
    +    return std::bitset<N + 1>();
    +}
    +
    +template <std::size_t N>
    +std::bitset<N + 1>& lvalue_bitset()
    +{
    +    static std::bitset<N + 1> lset = std::bitset<N + 1>();
    +    return lset;
    +}
    +
    +template <std::size_t N>
    +std::bitset<N + 1> const& lvalue_const_bitset()
    +{
    +    static std::bitset<N + 1> const clset = std::bitset<N + 1>();
    +    return clset;
    +}
    +
    +

    The U::evaluate_category static member +function template has a simple job: to return the correct value category when +passed in an object returned by one of the functions defined above. Assume +that BOOST_PARAMETER_HAS_PERFECT_FORWARDING is defined.

    +
    +enum invoked
    +{
    +    passed_by_lvalue_reference_to_const
    +  , passed_by_lvalue_reference
    +  , passed_by_rvalue_reference_to_const
    +  , passed_by_rvalue_reference
    +};
    +
    +struct U
    +{
    +    template <std::size_t N>
    +    static invoked evaluate_category(std::bitset<N + 1> const&)
    +    {
    +        return passed_by_lvalue_reference_to_const;
    +    }
    +
    +    template <std::size_t N>
    +    static invoked evaluate_category(std::bitset<N + 1>&)
    +    {
    +        return passed_by_lvalue_reference;
    +    }
    +
    +    template <std::size_t N>
    +    static invoked evaluate_category(std::bitset<N + 1> const&&)
    +    {
    +        return passed_by_rvalue_reference_to_const;
    +    }
    +
    +    template <std::size_t N>
    +    static invoked evaluate_category(std::bitset<N + 1>&&)
    +    {
    +        return passed_by_rvalue_reference;
    +    }
    +};
    +
    +

    Named parameters are required when invoking the function call operator; +however, none of their tags need to be in the same namespace.

    +
    +BOOST_PARAMETER_NAME((_lrc, kw0) in(lrc))
    +BOOST_PARAMETER_NAME((_lr, kw1) in_out(lr))
    +BOOST_PARAMETER_NAME((_rrc, kw2) in(rrc))
    +BOOST_PARAMETER_NAME((_rr, kw3) consume(rr))
    +
    +

    Use the macro as a substitute for a variadic function call operator +header. Enclose the return type bool in +parentheses. The macro will qualify the function with the const keyword.

    +
    +struct D
    +{
    +    D()
    +    {
    +    }
    +
    +    BOOST_PARAMETER_NO_SPEC_CONST_FUNCTION_CALL_OPERATOR((bool))
    +    {
    +        BOOST_TEST_EQ(
    +            passed_by_lvalue_reference_to_const
    +          , U::evaluate_category<0>(args[_lrc])
    +        );
    +        BOOST_TEST_EQ(
    +            passed_by_lvalue_reference
    +          , U::evaluate_category<1>(args[_lr])
    +        );
    +        BOOST_TEST_EQ(
    +            passed_by_rvalue_reference_to_const
    +          , U::evaluate_category<2>(
    +                args[_rrc0 | rvalue_const_bitset<2>()]
    +            )
    +        );
    +        BOOST_TEST_EQ(
    +            passed_by_rvalue_reference
    +          , U::evaluate_category<3>(
    +                args[_rr0 | rvalue_bitset<3>()]
    +            )
    +        );
    +
    +        return true;
    +    }
    +};
    +
    +

    To invoke the function call operator, bind all its arguments to named +parameters.

    +
    +D const d = D();
    +d(
    +    _rr0 = rvalue_bitset<3>()
    +  , _lrc0 = lvalue_const_bitset<0>()
    +  , _lr0 = lvalue_bitset<1>()
    +  , _rrc0 = rvalue_const_bitset<2>()
    +);
    +d(
    +    _lr0 = lvalue_bitset<1>()
    +  , _lrc0 = lvalue_const_bitset<0>()
    +);
    +
    +

    The test/preprocessor_eval_cat_no_spec.cpp test program demonstrates proper +usage of this macro.

    +
    Macro parameters:
      +
      +
    • result is the parenthesized return type +of the function call operator.
    • +
    +
    Argument specifiers syntax:
     None.
    +
    +
    Approximate expansion:
    +
    +
    +template <typename TaggedArg0, typename ...TaggedArgs>
    +struct boost_param_no_spec_result_const_ ## __LINE__ ## operator
    +{
    +    typedef result type;
    +};
    +
    +template <typename TaggedArg0, typename ...TaggedArgs>
    +inline typename boost::lazy_enable_if<
    +    are_tagged_arguments<TaggedArg0,TaggedArgs...>
    +  , boost_param_no_spec_result_const_ ## __LINE__ ## operator<
    +        TaggedArg0
    +      , TaggedArgs...
    +    >
    +>::type
    +    operator()(
    +        TaggedArg0 const& arg0
    +      , TaggedArgs const&... args
    +    ) const
    +{
    +    return this->boost_param_no_spec_impl_const ## __LINE__ ## operator(
    +        static_cast<
    +            typename
    +            boost_param_no_spec_result_const_ ## __LINE__ ## operator<
    +                TaggedArg0
    +              , TaggedArgs...
    +            >::type(*)()
    +        >(std::nullptr)
    +      , compose(arg0, args...)
    +    );
    +}
    +
    +template <typename ResultType, typename Args>
    +ResultType
    +    boost_param_no_spec_impl_const ## __LINE__ ## operator(
    +        (ResultType(*)())
    +      , Args const& args
    +    ) const
    +
    +

    Only the ArgumentPack type Args and its object instance args are +available for use within the function body.

    +
    +
    +
    +
    +

    7.17   BOOST_PARAMETER_NO_SPEC_CONSTRUCTOR(cls, +impl)

    + +++ + + + + + +
    Defined in:boost/parameter/preprocessor_no_spec.hpp
    +

    Generates a constructor that can take in named arguments.

    + +++ + + + + + + + + + + + + + + + + + + + + + + +
    Example usage:
      +

    When designing a front-end class template whose back-end is configurable +via parameterized inheritance, it can be useful to omit argument specifiers +from a named-parameter constructor so that the delegate constructors of the +back-end classes can enforce their own specifications.

    +
    +template <typename B>
    +struct frontend : B
    +{
    +    BOOST_PARAMETER_NO_SPEC_CONSTRUCTOR(frontend, (B))
    +};
    +
    +

    Named parameters are required when invoking the constructor; however, none +of their tags need to be in the same namespace.

    +
    +BOOST_PARAMETER_NAME(a0)
    +BOOST_PARAMETER_NAME(a1)
    +BOOST_PARAMETER_NAME(a2)
    +
    +

    For this example, each of the back-end class templates requires its own +parameter to be present in the argument pack. In practice, such parameters +should be optional, with default values.

    +
    +struct _enabler
    +{
    +};
    +
    +template <typename T>
    +class backend0
    +{
    +    T a0;
    +
    + public:
    +    template <typename ArgPack>
    +    explicit backend0(
    +        ArgPack const& args
    +      , typename boost::enable_if<
    +            is_argument_pack<ArgPack>
    +          , _enabler
    +        >::type = _enabler()
    +    ) : a0(args[_a0])
    +    {
    +    }
    +
    +    T const& get_a0() const
    +    {
    +        return this->a0;
    +    }
    +};
    +
    +template <typename B, typename T>
    +class backend1 : public B
    +{
    +    T a1;
    +
    + public:
    +    template <typename ArgPack>
    +    explicit backend1(
    +        ArgPack const& args
    +      , typename boost::enable_if<
    +            is_argument_pack<ArgPack>
    +          , _enabler
    +        >::type = _enabler()
    +    ) : B(args), a1(args[_a1])
    +    {
    +    }
    +
    +    T const& get_a1() const
    +    {
    +        return this->a1;
    +    }
    +};
    +
    +template <typename B, typename T>
    +class backend2 : public B
    +{
    +    T a2;
    +
    + public:
    +    template <typename ArgPack>
    +    explicit backend2(
    +        ArgPack const& args
    +      , typename boost::enable_if<
    +            is_argument_pack<ArgPack>
    +          , _enabler
    +        >::type = _enabler()
    +    ) : B(args), a2(args[_a2])
    +    {
    +    }
    +
    +    T const& get_a2() const
    +    {
    +        return this->a2;
    +    }
    +};
    +
    +

    This example shows that while backend0 +must always be the root base class template and that frontend must always be the most derived class +template, the other back-ends can be chained together in different orders.

    +
    +char const* p = "foo";
    +frontend<
    +    backend2<backend1<backend0<char const*>, char>, int>
    +> composed_obj0(_a2 = 4, _a1 = ' ', _a0 = p);
    +frontend<
    +    backend1<backend2<backend0<char const*>, int>, char>
    +> composed_obj1(_a0 = p, _a1 = ' ', _a2 = 4);
    +BOOST_TEST_EQ(composed_obj0.get_a0(), composed_obj1.get_a0());
    +BOOST_TEST_EQ(composed_obj0.get_a1(), composed_obj1.get_a1());
    +BOOST_TEST_EQ(composed_obj0.get_a2(), composed_obj1.get_a2());
    +
    +

    The test/parameterized_inheritance.cpp and test/preprocessor_eval_cat_no_spec.cpp test programs demonstrate proper +usage of this macro.

    +
    Macro parameters:
      +
      +
    • cls is the name of the enclosing +class.
    • +
    • impl is the parenthesized implementation +base class for cls.
    • +
    +
    Argument specifiers syntax:
     None.
    +
    +
    Approximate expansion:
    +
    +
    +template <
    +    template <
    +        typename TaggedArg0
    +      , typename ...TaggedArgs
    +      , typename = typename boost::enable_if<
    +            are_tagged_arguments<TaggedArg0,TaggedArgs...>
    +        >::type
    +>
    +inline explicit cls(
    +    TaggedArg0 const& arg0
    +  , TaggedArgs const&... args
    +) : impl(compose(arg0, args...))
    +{
    +}
    +
    +
    +
    +
    +
    +

    7.18   BOOST_PARAMETER_NO_SPEC_NO_BASE_CONSTRUCTOR(cls, +func)

    + +++ + + + + + +
    Defined in:boost/parameter/preprocessor_no_spec.hpp
    +

    Generates a constructor that can take in named arguments.

    + +++ + + + + + + + + + + + + + + + + + + + + + + +
    Example usage:
      +

    The return type of each of the following functon templates falls under a +different value category.

    +
    +template <std::size_t N>
    +std::bitset<N + 1> rvalue_bitset()
    +{
    +    return std::bitset<N + 1>();
    +}
    +
    +template <std::size_t N>
    +std::bitset<N + 1> const rvalue_const_bitset()
    +{
    +    return std::bitset<N + 1>();
    +}
    +
    +template <std::size_t N>
    +std::bitset<N + 1>& lvalue_bitset()
    +{
    +    static std::bitset<N + 1> lset = std::bitset<N + 1>();
    +    return lset;
    +}
    +
    +template <std::size_t N>
    +std::bitset<N + 1> const& lvalue_const_bitset()
    +{
    +    static std::bitset<N + 1> const clset = std::bitset<N + 1>();
    +    return clset;
    +}
    +
    +

    The U::evaluate_category static member +function template has a simple job: to return the correct value category when +passed in an object returned by one of the functions defined above. Assume +that BOOST_PARAMETER_HAS_PERFECT_FORWARDING is defined.

    +
    +enum invoked
    +{
    +    passed_by_lvalue_reference_to_const
    +  , passed_by_lvalue_reference
    +  , passed_by_rvalue_reference_to_const
    +  , passed_by_rvalue_reference
    +};
    +
    +struct U
    +{
    +    template <std::size_t N>
    +    static invoked evaluate_category(std::bitset<N + 1> const&)
    +    {
    +        return passed_by_lvalue_reference_to_const;
    +    }
    +
    +    template <std::size_t N>
    +    static invoked evaluate_category(std::bitset<N + 1>&)
    +    {
    +        return passed_by_lvalue_reference;
    +    }
    +
    +    template <std::size_t N>
    +    static invoked evaluate_category(std::bitset<N + 1> const&&)
    +    {
    +        return passed_by_rvalue_reference_to_const;
    +    }
    +
    +    template <std::size_t N>
    +    static invoked evaluate_category(std::bitset<N + 1>&&)
    +    {
    +        return passed_by_rvalue_reference;
    +    }
    +};
    +
    +

    Named parameters are required when invoking the constructor; however, none +of their tags need to be in the same namespace.

    +
    +BOOST_PARAMETER_NAME((_lrc, kw0) in(lrc))
    +BOOST_PARAMETER_NAME((_lr, kw1) in_out(lr))
    +BOOST_PARAMETER_NAME((_rrc, kw2) in(rrc))
    +BOOST_PARAMETER_NAME((_rr, kw3) consume(rr))
    +
    +

    Unlike BOOST_PARAMETER_NO_SPEC_CONSTRUCTOR, this +macro doesn't require a base class, only a delegate function to which the +generated constructor can pass its ArgumentPack.

    +
    +struct D
    +{
    +    BOOST_PARAMETER_NO_SPEC_NO_BASE_CONSTRUCTOR(D, D::_evaluate)
    +
    + private:
    +    template <typename Args>
    +    static bool _evaluate(Args const& args)
    +    {
    +        BOOST_TEST_EQ(
    +            passed_by_lvalue_reference_to_const
    +          , U::evaluate_category<0>(args[_lrc])
    +        );
    +        BOOST_TEST_EQ(
    +            passed_by_lvalue_reference
    +          , U::evaluate_category<1>(args[_lr])
    +        );
    +        BOOST_TEST_EQ(
    +            passed_by_rvalue_reference_to_const
    +          , U::evaluate_category<2>(
    +                args[_rrc0 | rvalue_const_bitset<2>()]
    +            )
    +        );
    +        BOOST_TEST_EQ(
    +            passed_by_rvalue_reference
    +          , U::evaluate_category<3>(
    +                args[_rr0 | rvalue_bitset<3>()]
    +            )
    +        );
    +
    +        return true;
    +    }
    +};
    +
    +

    To invoke the constructor, bind all its arguments to named parameters.

    +
    +D dp0(
    +    _rr0 = rvalue_bitset<3>()
    +  , _lrc0 = lvalue_const_bitset<0>()
    +  , _lr0 = lvalue_bitset<1>()
    +  , _rrc0 = rvalue_const_bitset<2>()
    +);
    +D dp1(
    +    _lr0 = lvalue_bitset<1>()
    +  , _lrc0 = lvalue_const_bitset<0>()
    +);
    +
    +

    The test/preprocessor_eval_cat_no_spec.cpp test program demonstrates proper +usage of this macro.

    +
    Macro parameters:
      +
      +
    • cls is the name of the enclosing +class.
    • +
    • func is a function that takes in the +ArgumentPack that the generated constructor passes on.
    • +
    +
    Argument specifiers syntax:
     None.
    +
    +
    Approximate expansion:
    +
    +
    +template <
    +    template <
    +        typename TaggedArg0
    +      , typename ...TaggedArgs
    +      , typename = typename boost::enable_if<
    +            are_tagged_arguments<TaggedArg0,TaggedArgs...>
    +        >::type
    +>
    +inline explicit cls(
    +    TaggedArg0 const& arg0
    +  , TaggedArgs const&... args
    +)
    +{
    +    func(compose(arg0, args...));
    +}
    +
    +
    +
    -

    6.10   7.19   BOOST_PARAMETER_NAME(name)

    @@ -3198,7 +8689,7 @@ namespace namespace-name { struct tag-name { - static char const* keyword_name() + static constexpr char const* keyword_name() { return ##tag-name; } @@ -3209,11 +8700,10 @@ namespace namespace-name { }; } -::boost::parameter::keyword<tag-namespace::tag-name> const& - object-name = ::boost::parameter::keyword< - tag-namespace::tag-name - >::instance; +keyword<tag-namespace::tag-name> const& object-name + = keyword<tag-namespace::tag-name>::instance;

    Else If name is of the form:

    @@ -3251,7 +8741,7 @@ namespace tag {
     
         struct tag-name
         {
    -        static char const* keyword_name()
    +        static constexpr char const* keyword_name()
             {
                 return ##tag-name;
             }
    @@ -3262,9 +8752,10 @@ namespace tag {
         };
     }
     
    -::boost::parameter::keyword<tag::tag-name> const& _ ## tag-name
    -    = ::boost::parameter::keyword<tag::tag-name>::instance;
    +keyword<tag::tag-name> const& _ ## tag-name
    +    = keyword<tag::tag-name>::instance;
     

    Else

    Treats name as if it were of the form:

    @@ -3273,7 +8764,7 @@ forward(tag-name)
    @@ -3317,7 +8808,7 @@ namespace tag { struct tag-name { - static char const* keyword_name() + static constexpr char const* keyword_name() { return ##tag-name; } @@ -3325,18 +8816,20 @@ namespace tag { typedef unspecified _; typedef unspecified _1; typedef boost::parameter::qualifier ## _reference qualifier; - static ::boost::parameter::keyword<tag-name> const& alias; + static keyword<tag-name> const& alias; }; - ::boost::parameter::keyword<tag-name> const& tag-name::alias - = ::boost::parameter::keyword<tag-name>::instance; + keyword<tag-name> const& tag-name::alias + = keyword<tag-name>::instance; } -::boost::parameter::keyword<tag::tag-name> const& _ ## tag-name - = ::boost::parameter::keyword<tag::tag-name>::instance; +keyword<tag::tag-name> const& name + = keyword<tag::tag-name>::instance;

    Else

    Treats name as if it were of the form:

    @@ -3345,7 +8838,7 @@ forward(tag-name)
    @@ -3372,8 +8865,8 @@ namespace tag { } template <typename T> -struct name - : ::boost::parameter::template_keyword<tag::name, T> +struct name : template_keyword<tag::name, T> { }; @@ -3383,7 +8876,7 @@ href="../../test/function_type_tpl_param.cpp" of this macro.

    -

    6.13   7.22   BOOST_PARAMETER_FUN(r, n, l, h, p)

    Deprecated

    @@ -3423,10 +8916,6 @@ class="docutils literal">l
    < h
    -

    If BOOST_PARAMETER_HAS_PERFECT_FORWARDING is -#defined, then:

    Expands to:
    @@ -3443,16 +8932,15 @@ r return name_with_named_params( pk( std::forward<A1>(a1) +href="http://en.cppreference.com/w/cpp/utility/forward" +>forward<A1>(a1) , std::forward<A2>(a2) +href="http://en.cppreference.com/w/cpp/utility/forward" +>forward<A2>(a2) , … , std::forward<A ## l>(a ## l) +href="http://en.cppreference.com/w/cpp/utility/forward" +>forward<A ## l>(a ## l) ) ); } @@ -3483,21 +8971,20 @@ href="../../../preprocessor/doc/ref/inc.html">BOOST_PP_INC(name_with_named_params( pk( std::forward<A1>(a1) +href="http://en.cppreference.com/w/cpp/utility/forward" +>forward<A1>(a1) , std::forward<A2>(a2) +href="http://en.cppreference.com/w/cpp/utility/forward" +>forward<A2>(a2) , … , std::forward<A ## l>(a ## l) +href="http://en.cppreference.com/w/cpp/utility/forward" +>forward<A ## l>(a ## l) , std::forward<A ## BOOST_PP_INC(l)>(a ## forward<A ## BOOST_PP_INC(l)>(a ## BOOST_PP_INC(l)) ) @@ -3518,164 +9005,28 @@ r return name_with_named_params( pk( std::forward<A1>(a1) +href="http://en.cppreference.com/w/cpp/utility/forward" +>forward<A1>(a1) , std::forward<A2>(a2) +href="http://en.cppreference.com/w/cpp/utility/forward" +>forward<A2>(a2) , … , std::forward<A ## h>(a ## h) +href="http://en.cppreference.com/w/cpp/utility/forward" +>forward<A ## h>(a ## h) ) ); }
    -

    If BOOST_PARAMETER_HAS_PERFECT_FORWARDING is not -#defined, then:

    -
    -
    Expands to:
    -
    -
    -template <typename A1, typename A2, …, typename A ## l>
    -r
    -    name(
    -        A1 const& a1, A2 const& a2, …, A ## l const& a ## l
    -      , typename p::match<A1, A2, …, A ## l>::type pk = p()
    -    )
    -{
    -    return name_with_named_params(pk(a1, a2, …, a ## l));
    -}
    -
    -… exponential number of overloads …
    -
    -
    -template <typename A1, typename A2, …, typename A ## l>
    -r
    -    name(
    -        A1& a1, A2& a2, …, A ## l & a ## l
    -      , typename p::match<A1, A2, …, A ## l>::type pk = p()
    -    )
    -{
    -    return name_with_named_params(pk(a1, a2, …, a ## l));
    -}
    -
    -template <
    -    typename A1
    -  , typename A2
    -  , …
    -  , typename A ## l
    -  , typename A ## BOOST_PP_INC(l)
    ->
    -r
    -    name(
    -        A1 const& a1, A2 const& a2, …, A ## l const& a ## l
    -      , A ## BOOST_PP_INC(l) const& a ## BOOST_PP_INC(l)
    -      , typename p::match<A1, A2, …, Al, A ## BOOST_PP_INC(l)>::type pk = p()
    -    )
    -{
    -    return name_with_named_params(
    -        pk(a1, a2, …, a ## l, a ## BOOST_PP_INC(l))
    -    );
    -}
    -
    -… exponential number of overloads …
    -
    -
    -template <
    -    typename A1
    -  , typename A2
    -  , …
    -  , typename A ## l
    -  , typename A ## BOOST_PP_INC(l)
    ->
    -r
    -    name(
    -        A1& a1, A2& a2, …, A ## l & a ## l
    -      , A ## BOOST_PP_INC(l) & a ## BOOST_PP_INC(l)
    -      , typename p::match<A1, A2, …, Al, A ## BOOST_PP_INC(l)>::type pk = p()
    -    )
    -{
    -    return name_with_named_params(
    -        pk(a1, a2, …, a ## l, a ## BOOST_PP_INC(l))
    -    );
    -}
    -
    -
    -
    -template <typename A1, typename A2, …, typename A ## h>
    -r
    -    name(
    -        A1 const& a1, A2 const& a2, …, A ## h const& a ## h
    -      , typename p::match<A1, A2, …, A ## h>::type pk = p()
    -    )
    -{
    -    return name_with_named_params(pk(a1, a2, …, a ## h));
    -}
    -
    -… exponential number of overloads …
    -
    -
    -template <typename A1, typename A2, …, typename A ## h>
    -r
    -    name(
    -        A1& a1, A2& a2, …, A ## h& a ## h
    -      , typename p::match<A1, A2, …, A ## h>::type pk = p()
    -    )
    -{
    -    return name_with_named_params(pk(a1, a2, …, a ## h));
    -}
    -
    -
    -

    The test/macros.cpp and test/macros_eval_category.cpp test programs demonstrate proper usage of this macro.

    -

    6.14   7.23   BOOST_PARAMETER_KEYWORD(n, k)

    Deprecated

    @@ -3708,23 +9059,30 @@ namespace n { struct k { + static constexpr char const* keyword_name() + { + return ##k; + } + + typedef unspecified _; + typedef unspecified _1; typedef boost::parameter::forward_reference qualifier; }; } namespace { - boost::parameter::keyword<tag-namespace::k>& k - = boost::parameter::keyword<tag-namespace::k>::instance; + keyword<n::k> const& k + = keyword<n::k>::instance; }
    -

    6.15   7.24   BOOST_PARAMETER_MATCH(p, a, x)

    Generates a defaulted parameter declaration for a

    -

    7   Configuration +

    8   Configuration Macros

    -

    7.1   8.1   BOOST_PARAMETER_HAS_PERFECT_FORWARDING

    Determines whether or not the library supports perfect forwarding, or the preservation of parameter value categories. Users can manually disable this @@ -3782,8 +9140,8 @@ macro by #defining the BOOST_PARAMETER_DISABLE_PERFECT_FORWARDING macro. Otherwise, the library will #define this macro if and only if it and the configuration macros -#define this macro if and only if it is not already defined, and if the +configuration macros BOOST_NO_FUNCTION_TEMPLATE_ORDERING,

    -

    7.2   8.2   BOOST_PARAMETER_DISABLE_PERFECT_FORWARDING

    It may be necessary to test user code in case perfect forwarding support is unavailable. Users can #define this macro either in their project settings or before including any library header -files. Doing so will leave BOOST_PARAMETER_HAS_PERFECT_FORWARDING undefined.

    +>BOOST_PARAMETER_HAS_PERFECT_FORWARDING
    and BOOST_PARAMETER_CAN_USE_MP11 undefined.

    +
    +
    +

    8.3   BOOST_PARAMETER_CAN_USE_MP11

    +

    Determines whether or not the library can use Boost.MP11, a C++11 +metaprogramming library. Users can manually disable +this macro by #defining the BOOST_PARAMETER_DISABLE_MP11_USAGE macro or +the BOOST_PARAMETER_DISABLE_PERFECT_FORWARDING +macro. Otherwise, the library will #define +this macro if and only if it is not already defined, if BOOST_PARAMETER_HAS_PERFECT_FORWARDING is +defined, and if the configuration macros BOOST_NO_CXX11_CONSTEXPR, +BOOST_NO_CXX11_DECLTYPE_N3276, +BOOST_NO_CXX11_AUTO_DECLARATIONS, +BOOST_NO_CXX11_TEMPLATE_ALIASES, +BOOST_NO_CXX11_STATIC_ASSERT, +BOOST_NO_CXX11_HDR_TYPE_TRAITS, +BOOST_NO_CXX11_HDR_INITIALIZER_LIST, +and BOOST_NO_CXX11_HDR_TUPLE are not +already defined by Boost.Config.

    + +++ + + + + + +
    Defined in:boost/parameter/config.hpp
    +
    +
    +

    8.4   BOOST_PARAMETER_DISABLE_MP11_USAGE

    +

    It may be necessary to disable usage of Boost.MP11 for compilers that +cannot support it. Users can #define this +macro either in their project settings or before including any library header +files. Doing so will leave BOOST_PARAMETER_CAN_USE_MP11 undefined.

    -

    7.3   8.5   BOOST_PARAMETER_VARIADIC_MPL_SEQUENCE

    If underlying the nested parameters. If the user does not manually #define this macro, then the library will #define it as +boost::mp11::mp_list if +BOOST_PARAMETER_CAN_USE_MP11 is defined, ::boost::fusion::list if +>boost::fusion::list if BOOST_FUSION_HAS_VARIADIC_LIST is @@ -3845,21 +9275,21 @@ defined (by Boost.Fusion), ::boost::fusion::deque if +>boost::fusion::deque if BOOST_FUSION_HAS_VARIADIC_DEQUE is defined (by Boost.Fusion), or ::boost::mpl::vector otherwise.

    +>boost::mpl::vector otherwise.

    Example:
     #define BOOST_PARAMETER_VARIADIC_MPL_SEQUENCE ::boost::fusion::vector
    +>boost::fusion::vector
     
    @@ -3877,9 +9307,8 @@ href="../../../../boost/parameter/parameters.hpp"

    -

    7.4   8.6   BOOST_PARAMETER_MAX_ARITY

    -

    Determines the maximum number of arguments supported by the library.

    If BOOST_PARAMETER_HAS_PERFECT_FORWARDING is @@ -3891,14 +9320,16 @@ Sequence underlying the nested parameter_spec type of parameters does not have a size limit--which is the case with boost::mp11::mp_list, ::boost::fusion::list and +>boost::fusion::list, and ::boost::fusion::deque but not +>boost::fusion::deque, but not ::boost::mpl::vector--then this macro +>boost::mpl::vector--then this macro can be safely ignored. User code that manually defines BOOST_PARAMETER_VARIADIC_MPL_SEQUENCE @@ -3955,7 +9386,7 @@ href="../../../mpl/doc/refmanual/limit-vector-size.html"

    7.5   

    8.7   BOOST_PARAMETER_EXPONENTIAL_OVERLOAD_THRESHOLD_ARITY

    If this library does not support perfect forwarding, @@ -3997,47 +9428,132 @@ href="../../../../boost/parameter/config.hpp"

    7.6   ...Outside Of +>

    8.8   ...Outside Of This Library

    1. If Boost.Config defines the macro BOOST_NO_FUNCTION_TEMPLATE_ORDERING, -then the macro BOOST_NO_FUNCTION_TEMPLATE_ORDERING, then +the macros BOOST_PARAMETER_HAS_PERFECT_FORWARDING will be left undefined; -otherwise, the code generation macros would not work correctly.
    2. +>BOOST_PARAMETER_HAS_PERFECT_FORWARDING
      and BOOST_PARAMETER_CAN_USE_MP11 will be left +undefined; otherwise, the code generation macros would not work +correctly. +
    3. If Boost.Config defines the macro +BOOST_NO_SFINAE, then the macros BOOST_PARAMETER_HAS_PERFECT_FORWARDING and +BOOST_PARAMETER_CAN_USE_MP11 will be left +undefined; otherwise, keyword types generated by BOOST_PARAMETER_NAME and BOOST_PARAMETER_NESTED_KEYWORD would not work correctly.
    4. +
    5. If Boost.Config defines the macro +BOOST_NO_CXX11_RVALUE_REFERENCES, then the +macros BOOST_PARAMETER_HAS_PERFECT_FORWARDING and BOOST_PARAMETER_CAN_USE_MP11 will be left +undefined.
    6. +
    7. If Boost.Config defines the macro +BOOST_NO_CXX11_VARIADIC_TEMPLATES, then the +macros BOOST_PARAMETER_HAS_PERFECT_FORWARDING and BOOST_PARAMETER_CAN_USE_MP11 will be left +undefined.
    8. +
    9. If Boost.Config defines the macro +BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS, then the macros BOOST_PARAMETER_HAS_PERFECT_FORWARDING and BOOST_PARAMETER_CAN_USE_MP11 will be left +undefined.
    10. +
    11. If Boost.Config defines the macro +BOOST_NO_CXX11_CONSTEXPR, then the macro BOOST_PARAMETER_CAN_USE_MP11 will be left +undefined.
    12. If Boost.Config defines the macro BOOST_NO_SFINAE, then the macro -BOOST_PARAMETER_HAS_PERFECT_FORWARDING -will be left undefined; otherwise, keyword types generated by -BOOST_PARAMETER_NAME and -BOOST_PARAMETER_NESTED_KEYWORD would -not work correctly.
    13. +>BOOST_NO_CXX11_DECLTYPE_N3276, then the +macro BOOST_PARAMETER_CAN_USE_MP11 will be left +undefined.
    14. If Boost.Config defines the macro BOOST_NO_CXX11_RVALUE_REFERENCES, then -the macro BOOST_PARAMETER_HAS_PERFECT_FORWARDING will be left undefined.
    15. +>BOOST_NO_CXX11_AUTO_DECLARATIONS, then +the macro BOOST_PARAMETER_CAN_USE_MP11 will be +left undefined.
    16. If Boost.Config defines the macro BOOST_NO_CXX11_VARIADIC_TEMPLATES, then -the macro BOOST_PARAMETER_HAS_PERFECT_FORWARDING will be left undefined.
    17. +href="../../../config/doc/html/boost_config/boost_macro_reference.html">BOOST_NO_CXX11_TEMPLATE_ALIASES, then the +macro BOOST_PARAMETER_CAN_USE_MP11 will be left +undefined. +
    18. If Boost.Config defines the macro +BOOST_NO_CXX11_STATIC_ASSERT, then the +macro BOOST_PARAMETER_CAN_USE_MP11 will be left +undefined.
    19. +
    20. If Boost.Config defines the macro +BOOST_NO_CXX11_HDR_TYPE_TRAITS, then the +macro BOOST_PARAMETER_CAN_USE_MP11 will be left +undefined.
    21. +
    22. If Boost.Config defines the macro +BOOST_NO_CXX11_HDR_INITIALIZER_LIST, then +the macro BOOST_PARAMETER_CAN_USE_MP11 will be +left undefined.
    23. +
    24. If Boost.Config defines the macro +BOOST_NO_CXX11_HDR_TUPLE, then the macro BOOST_PARAMETER_CAN_USE_MP11 will be left +undefined.
    25. If Boost.Fusion defines the macro underlying the nested parameters will be ::boost::fusion::list.
    26. +>boost::fusion::list.
    27. If Boost.Fusion defines the macro underlying the nested parameters will be ::boost::fusion::deque.
    28. +>boost::fusion::deque.
    29. The value that Boost.MPL defines the macro

    -

    8   Tutorial

    +

    9   Tutorial

    Follow this link to the Boost.Parameter tutorial documentation.


    @@ -4117,9 +9633,8 @@ class="docutils literal">BOOST_NO_RESULT_OF
    is #defined, boost::result_of<F()>::type is replaced by F::result_type. +>result_of
    <F()>::type is +replaced by F::result_type.
    diff --git a/doc/index.rst b/doc/index.rst index 22e9cee..9c00b30 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -765,7 +765,7 @@ that prints the arguments: #include // for dfs_visitor BOOST_PARAMETER_FUNCTION( - (void), depth_first_search, tag + (bool), depth_first_search, tag *…signature goes here…* ) { @@ -779,16 +779,20 @@ that prints the arguments: std::cout << std::endl; std::cout << "color_map=" << color_map; std::cout << std::endl; + return true; } + #include + int main() { + char const\* g = "1"; depth_first_search(1, 2, 3, 4, 5); - depth_first_search( - "1", '2', _color_map = '5', + g, '2', _color_map = '5', _index_map = "4", _root_vertex = "3" ); + return boost::report_errors(); } Despite the fact that default expressions such as ``vertices(graph).first`` @@ -815,7 +819,7 @@ and each one will print exactly the same thing. (color_map, \*) ) ''') -.. @test('compile') +.. @test('run') Signature Matching and Overloading ---------------------------------- @@ -893,14 +897,18 @@ __ `parameter table`_ { template struct apply - : boost::is_convertible< - T - , typename boost::graph_traits< - typename boost::parameter::value_type< - Args - , graphs::graph - >::type - >::vertex_descriptor + : boost::mpl::if_< + boost::is_convertible< + T + , typename boost::graph_traits< + typename boost::parameter::value_type< + Args + , graphs::graph + >::type + >::vertex_descriptor + > + , boost::mpl::true_ + , boost::mpl::false_ > { }; @@ -949,14 +957,18 @@ classes provide the necessary checks. { template struct apply - : boost::mpl::and_< + : boost::mpl::eval_if< boost::is_convertible< typename boost::graph_traits::traversal_category , boost::incidence_graph_tag > - , boost::is_convertible< - typename boost::graph_traits::traversal_category - , boost::vertex_list_graph_tag + , boost::mpl::if_< + boost::is_convertible< + typename boost::graph_traits::traversal_category + , boost::vertex_list_graph_tag + > + , boost::mpl::true_ + , boost::mpl::false_ > > { @@ -967,18 +979,22 @@ classes provide the necessary checks. { template struct apply - : boost::mpl::and_< + : boost::mpl::eval_if< boost::is_integral< typename boost::property_traits::value_type > - , boost::is_same< - typename boost::property_traits::key_type - , typename boost::graph_traits< - typename boost::parameter::value_type< - Args - , graphs::graph - >::type - >::vertex_descriptor + , boost::mpl::if_< + boost::is_same< + typename boost::property_traits::key_type + , typename boost::graph_traits< + typename boost::parameter::value_type< + Args + , graphs::graph + >::type + >::vertex_descriptor + > + , boost::mpl::true_ + , boost::mpl::false_ > > { @@ -989,14 +1005,18 @@ classes provide the necessary checks. { template struct apply - : boost::is_same< - typename boost::property_traits::key_type - , typename boost::graph_traits< - typename boost::parameter::value_type< - Args - , graphs::graph - >::type - >::vertex_descriptor + : boost::mpl::if_< + boost::is_same< + typename boost::property_traits::key_type + , typename boost::graph_traits< + typename boost::parameter::value_type< + Args + , graphs::graph + >::type + >::vertex_descriptor + > + , boost::mpl::true_ + , boost::mpl::false_ > { }; @@ -1080,6 +1100,10 @@ by an asterix*, as follows: { } + #include + #include + #include + int main() { typedef boost::adjacency_list< @@ -1095,11 +1119,11 @@ by an asterix*, as follows: depth_first_search(g); depth_first_search(g, _root_vertex = static_cast(x)); - return 0; + return boost::report_errors(); } ''') -.. @test('compile') +.. @test('run') It usually isn't necessary to so completely encode the type requirements on arguments to generic functions. However, doing so is worth the effort: your @@ -1203,10 +1227,14 @@ follows: .. parsed-literal:: - namespace mpl = boost::mpl; + char const*& blank_char_ptr() + { + static char const* larr = ""; + return larr; + } BOOST_PARAMETER_FUNCTION( - (void), def, tag, + (bool), def, tag, (required (name, (char const\*)) (func,\*) ) // nondeduced @@ -1216,18 +1244,23 @@ follows: (keywords // see [#is_keyword_expression]_ - , \*(is_keyword_expression) + , \*(is_keyword_expression) , no_keywords() ) (policies - , \*(mpl::not_< - mpl::or_< - boost::is_convertible - // see [#is_keyword_expression]_ - , is_keyword_expression + , \*( + boost::mpl::eval_if< + boost::is_convertible + , boost::mpl::false_ + , boost::mpl::if_< + // see [#is_keyword_expression]_ + is_keyword_expression + , boost::mpl::false_ + , boost::mpl::true_ + > > - >) + ) , default_call_policies() ) ) @@ -1237,7 +1270,7 @@ follows: *…* } -.. @example.replace_emphasis('') +.. @example.replace_emphasis('return true;') .. @example.prepend(''' #include @@ -1278,6 +1311,11 @@ follows: { } + #include + #include + #include + #include + ''') .. Admonition:: Syntax Note @@ -1290,8 +1328,19 @@ With the declaration above, the following two calls are equivalent: .. parsed-literal:: - def("f", &f, **some_policies**, **"Documentation for f"**); - def("f", &f, **"Documentation for f"**, **some_policies**); + char const\* f_name = "f"; + def( + f_name + , &f + , **some_policies** + , **"Documentation for f"** + ); + def( + f_name + , &f + , **"Documentation for f"** + , **some_policies** + ); .. @example.prepend(''' int main() @@ -1305,8 +1354,10 @@ name explicitly, as follows: .. parsed-literal:: def( - "f", &f - , **_policies = some_policies**, "Documentation for f" + f_name + , &f + , **_policies = some_policies** + , "Documentation for f" ); .. @example.append('}') @@ -1346,13 +1397,23 @@ the body of a class:: } }; + #include + + int main() + { + callable2 c2; + callable2 const& c2_const = c2; + c2_const.call(1, 2); + return boost::report_errors(); + } + .. @example.prepend(''' #include #include using namespace boost::parameter; ''') -.. @test('compile') +.. @test('run') These macros don't directly allow a function's interface to be separated from its implementation, but you can always forward arguments on to a separate @@ -1364,7 +1425,7 @@ implementation function:: (void), call, tag, (required (arg1,(int))(arg2,(int))) ) { - call_impl(arg1,arg2); + call_impl(arg1, arg2); } private: @@ -1401,13 +1462,22 @@ before the function name: } }; + #include + + int main() + { + somebody::f(); + somebody::f(4); + return boost::report_errors(); + } + .. @example.prepend(''' #include #include using namespace boost::parameter; ''') -.. @test('compile') +.. @test('run') ----------------------------------------- Parameter-Enabled Function Call Operators @@ -1434,13 +1504,23 @@ function objects:: } }; + #include + + int main() + { + callable2 c2; + callable2 const& c2_const = c2; + c2_const(1, 2); + return boost::report_errors(); + } + .. @example.prepend(''' #include #include using namespace boost::parameter; ''') -.. @test('compile') +.. @test('run') ------------------------------ Parameter-Enabled Constructors @@ -1451,7 +1531,7 @@ The lack of a “delegating constructor” feature in C++ limits somewhat the quality of interface this library can provide for defining parameter-enabled constructors. The usual workaround for a lack of constructor delegation applies: one must factor the -common logic into a base class. +common logic into one or more base classes. Let's build a parameter-enabled constructor that simply prints its arguments. The first step is to write a base class whose @@ -1501,7 +1581,11 @@ only ``name`` is required. We can exercise our new interface as follows:: myclass y(_index = 12, _name = "sally"); // named myclass z("june"); // positional/defaulted -.. @example.wrap('int main() {', ' return 0; }') +.. @example.wrap(''' + #include + + int main() { +''', ' return boost::report_errors(); }') .. @test('run', howmany='all') For more on |ArgumentPack| manipulation, see the `Advanced Topics`_ section. @@ -2014,7 +2098,8 @@ The simplest |ArgumentPack| is the result of assigning into a keyword object:: template int print_index(ArgumentPack const& args) { - std::cout << "index = " << args[_index] << std::endl; + std::cout << "index = " << args[_index]; + std::cout << std::endl; return 0; } @@ -2034,7 +2119,8 @@ arguments to ``print_name_and_index``:: template int print_name_and_index(ArgumentPack const& args) { - std::cout << "name = " << args[_name] << "; "; + std::cout << "name = " << args[_name]; + std::cout << "; "; return print_index(args); } @@ -2501,7 +2587,7 @@ the Parameter library to see how it fares on your favorite compiler. Additionally, you may need to be aware of the following issues and workarounds for particular compilers. -.. _`regression test results`: http://www.boost.org/regression/release/user/parameter.html +.. _`regression test results`: http\://www.boost.org/regression/release/user/parameter.html -------------------------- Perfect Forwarding Support @@ -2511,13 +2597,13 @@ If your compiler supports `perfect forwarding`_, then the Parameter library will ``#define`` the macro ``BOOST_PARAMETER_HAS_PERFECT_FORWARDING`` unless you disable it manually. If your compiler does not provide this support, then ``parameter::parameters::operator()`` will treat rvalue references as lvalue -const references to work around the `forwarding problem`_, so in certain cases -you must wrap |boost_ref|_ or |std_ref|_ around any arguments that will be -bound to out parameters. The |evaluate_category|_ and +``const`` references to work around the `forwarding problem`_, so in certain +cases you must wrap |boost_ref|_ or |std_ref|_ around any arguments that will +be bound to out parameters. The |evaluate_category|_ and |preprocessor_eval_category|_ test programs demonstrate this support. -.. _`perfect forwarding`: http://www.justsoftwaresolutions.co.uk/cplusplus/rvalue_references_and_perfect_forwarding.html -.. _`forwarding problem`: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2002/n1385.htm +.. _`perfect forwarding`: http\://www.justsoftwaresolutions.co.uk/cplusplus/rvalue_references_and_perfect_forwarding.html +.. _`forwarding problem`: http\://www.open-std.org/jtc1/sc22/wg21/docs/papers/2002/n1385.htm .. |boost_ref| replace:: ``boost\:\:ref`` .. _boost_ref: ../../../core/doc/html/core/ref.html .. |std_ref| replace:: ``std\:\:ref`` diff --git a/doc/reference.rst b/doc/reference.rst index a100982..1783f32 100644 --- a/doc/reference.rst +++ b/doc/reference.rst @@ -175,10 +175,17 @@ library. An |ArgumentPack| is a collection of |tagged reference|\ s to the actual arguments passed to a function. Every |ArgumentPack| is also a valid `MPL Forward Sequence`_ and `MPL Associative Sequence`_ consisting of the |keyword -tag type|\ s in its |tagged reference|\ s. +tag type|\ s in its |tagged reference|\ s. The |singular_cpp|_, +|compose_cpp|_, and |mpl_cpp|_ test programs demonstrate this functionality. .. _`MPL Forward Sequence`: ../../../mpl/doc/refmanual/forward-sequence.html .. _`MPL Associative Sequence`: ../../../mpl/doc/refmanual/associative-sequence.html +.. |singular_cpp| replace:: singular.cpp +.. _singular_cpp: ../../test/singular.cpp +.. |compose_cpp| replace:: compose.cpp +.. _compose_cpp: ../../test/compose.cpp +.. |mpl_cpp| replace:: mpl.cpp +.. _mpl_cpp: ../../test/mpl.cpp Requirements ............ @@ -291,8 +298,6 @@ The type of every |keyword object| is a specialization of |keyword|. __ ../../../../boost/parameter/keyword.hpp -**If** |BOOST_PARAMETER_HAS_PERFECT_FORWARDING| is ``#defined``, **then** - .. parsed-literal:: template @@ -301,7 +306,7 @@ __ ../../../../boost/parameter/keyword.hpp typedef Tag tag; template - typename boost::`enable_if`_< + constexpr typename boost::`enable_if`_< typename boost::mpl::`eval_if_`_< boost::`is_scalar`_ , boost::mpl::`true_`_ @@ -322,11 +327,11 @@ __ ../../../../boost/parameter/keyword.hpp > >::type , |ArgumentPack|_ - >::type constexpr + >::type `operator=`_\(T const& value) const; template - typename boost::`enable_if`_< + constexpr typename boost::`enable_if`_< typename boost::mpl::`eval_if_`_< typename boost::mpl::`eval_if_`_< boost::`is_same`_< @@ -351,11 +356,11 @@ __ ../../../../boost/parameter/keyword.hpp , boost::mpl::`false_`_ >::type , |ArgumentPack|_ - >::type constexpr + >::type `operator=`_\(T& value) const; template - typename boost::`enable_if`_< + constexpr typename boost::`enable_if`_< typename boost::mpl::`eval_if_`_< boost::`is_scalar`_ , boost::mpl::`false_`_ @@ -376,11 +381,11 @@ __ ../../../../boost/parameter/keyword.hpp > >::type , |ArgumentPack|_ - >::type constexpr + >::type `operator=`_\(T const&& value) const; template - typename boost::`enable_if`_< + constexpr typename boost::`enable_if`_< typename boost::mpl::`eval_if_`_< boost::`is_scalar`_ , boost::mpl::`false_`_ @@ -401,11 +406,11 @@ __ ../../../../boost/parameter/keyword.hpp > >::type , |ArgumentPack|_ - >::type constexpr + >::type `operator=`_\(T&& value) const; template - typename boost::`enable_if`_< + constexpr typename boost::`enable_if`_< typename boost::mpl::`eval_if_`_< boost::`is_scalar`_ , boost::mpl::`true_`_ @@ -430,7 +435,7 @@ __ ../../../../boost/parameter/keyword.hpp `operator|`_\(T const& x) const; template - typename boost::`enable_if`_< + constexpr typename boost::`enable_if`_< typename boost::mpl::`eval_if_`_< typename boost::mpl::`eval_if_`_< boost::`is_same`_< @@ -459,7 +464,7 @@ __ ../../../../boost/parameter/keyword.hpp `operator|`_\(T& x) const; template - typename boost::`enable_if`_< + constexpr typename boost::`enable_if`_< typename boost::mpl::`eval_if_`_< boost::`is_scalar`_ , boost::mpl::`true_`_ @@ -484,7 +489,7 @@ __ ../../../../boost/parameter/keyword.hpp `operator|`_\(T const&& x) const; template - typename boost::`enable_if`_< + constexpr typename boost::`enable_if`_< typename boost::mpl::`eval_if_`_< boost::`is_scalar`_ , boost::mpl::`false_`_ @@ -509,153 +514,24 @@ __ ../../../../boost/parameter/keyword.hpp `operator|`_\(T&& value) const; template - *tagged lazy default* `operator||`_\(F const&) const; + constexpr *tagged lazy default* `operator||`_\(F const&) const; template - *tagged lazy default* `operator||`_\(F&) const; + constexpr *tagged lazy default* `operator||`_\(F&) const; static keyword const& instance; static keyword& get_\(); }; -**If** |BOOST_PARAMETER_HAS_PERFECT_FORWARDING| is **not** ``#defined``, -**then** - -.. parsed-literal:: - - template - struct keyword - { - typedef Tag tag; - - template - typename boost::`enable_if`_< - typename boost::mpl::`eval_if_`_< - boost::`is_scalar`_ - , boost::mpl::`true_`_ - , boost::mpl::`eval_if_`_< - boost::`is_same`_< - typename Tag::qualifier - , boost::parameter::in_reference - > - , boost::mpl::`true_`_ - , boost::mpl::`if_`_< - boost::`is_same`_< - typename Tag::qualifier - , boost::parameter::forward_reference - > - , boost::mpl::`true_`_ - , boost::mpl::`false_`_ - > - > - >::type - , |ArgumentPack|_ - >::type constexpr - `operator=`_\(T const& value) const; - - template - typename boost::`enable_if`_< - typename boost::mpl::`eval_if_`_< - typename boost::mpl::`eval_if_`_< - boost::`is_same`_< - typename Tag::qualifier - , boost::parameter::out_reference - > - , boost::mpl::`true_`_ - , boost::mpl::`if_`_< - boost::`is_same`_< - typename Tag::qualifier - , boost::parameter::forward_reference - > - , boost::mpl::`true_`_ - , boost::mpl::`false_`_ - > - >::type - , boost::mpl::`if_`_< - boost::`is_const`_ - , boost::mpl::`false_`_ - , boost::mpl::`true_`_ - > - , boost::mpl::`false_`_ - >::type - , |ArgumentPack|_ - >::type constexpr - `operator=`_\(T& value) const; - - template - typename boost::`enable_if`_< - typename boost::mpl::`eval_if_`_< - boost::`is_scalar`_ - , boost::mpl::`true_`_ - , boost::mpl::`eval_if_`_< - boost::`is_same`_< - typename Tag::qualifier - , boost::parameter::in_reference - > - , boost::mpl::`true_`_ - , boost::mpl::`if_`_< - boost::`is_same`_< - typename Tag::qualifier - , boost::parameter::forward_reference - > - , boost::mpl::`true_`_ - , boost::mpl::`false_`_ - > - > - >::type - , *tagged default* - >::type - `operator|`_\(T const& x) const; - - template - typename boost::`enable_if`_< - typename boost::mpl::`eval_if_`_< - typename boost::mpl::`eval_if_`_< - boost::`is_same`_< - typename Tag::qualifier - , boost::parameter::out_reference - > - , boost::mpl::`true_`_ - , boost::mpl::`if_`_< - boost::`is_same`_< - typename Tag::qualifier - , boost::parameter::forward_reference - > - , boost::mpl::`true_`_ - , boost::mpl::`false_`_ - > - >::type - , boost::mpl::`if_`_< - boost::`is_const`_ - , boost::mpl::`false_`_ - , boost::mpl::`true_`_ - > - , boost::mpl::`false_`_ - >::type - , *tagged default* - >::type - `operator|`_\(T& x) const; - - template - *tagged lazy default* `operator||`_\(F const&) const; - - template - *tagged lazy default* `operator||`_\(F&) const; - - static keyword const& instance; - - static keyword& get_\(); - }; - -.. _enable_if: ../../../core/doc/html/core/enable_if.html -.. _eval_if_: ../../../mpl/doc/refmanual/eval-if.html -.. _false_: ../../../mpl/doc/refmanual/bool.html -.. _if_: ../../../mpl/doc/refmanual/if.html -.. _is_const: ../../../type_traits/doc/html/boost_typetraits/is_const.html -.. _is_same: ../../../type_traits/doc/html/boost_typetraits/is_same.html -.. _is_scalar: ../../../type_traits/doc/html/boost_typetraits/is_scalar.html -.. _true_: ../../../mpl/doc/refmanual/bool.html +.. _`enable_if`: ../../../core/doc/html/core/enable_if.html +.. _`eval_if`: ../../../mpl/doc/refmanual/eval-if.html +.. _`false_`: ../../../mpl/doc/refmanual/bool.html +.. _`if_`: ../../../mpl/doc/refmanual/if.html +.. _`is_const`: ../../../type_traits/doc/html/boost_typetraits/is_const.html +.. _`is_same`: ../../../type_traits/doc/html/boost_typetraits/is_same.html +.. _`is_scalar`: ../../../type_traits/doc/html/boost_typetraits/is_scalar.html +.. _`true_`: ../../../mpl/doc/refmanual/bool.html .. |operator=| replace:: ``operator=`` .. _operator=: @@ -663,14 +539,17 @@ __ ../../../../boost/parameter/keyword.hpp ``operator=`` .. parsed-literal:: - template |ArgumentPack|_ operator=(T const& value) const; - template |ArgumentPack|_ operator=(T& value) const; + template + constexpr |ArgumentPack|_ operator=(T const& value) const; -**If** |BOOST_PARAMETER_HAS_PERFECT_FORWARDING| is ``#defined``, **then** -.. parsed-literal:: + template + constexpr |ArgumentPack|_ operator=(T& value) const; - template |ArgumentPack|_ operator=(T const&& value) const; - template |ArgumentPack|_ operator=(T&& value) const; + template + constexpr |ArgumentPack|_ operator=(T const&& value) const; + + template + constexpr |ArgumentPack|_ operator=(T&& value) const; :Requires: one of the following: @@ -698,14 +577,17 @@ nested ``qualifier`` type of ``Tag`` must be ``consume_reference`` or ``operator|`` .. parsed-literal:: - template *tagged default* operator|(T const& x) const; - template *tagged default* operator|(T& x) const; + template + constexpr *tagged default* operator|(T const& x) const; -**If** |BOOST_PARAMETER_HAS_PERFECT_FORWARDING| is ``#defined``, **then** -.. parsed-literal:: + template + constexpr *tagged default* operator|(T& x) const; - template *tagged default* operator|(T const&& x) const; - template *tagged default* operator|(T&& x) const; + template + constexpr *tagged default* operator|(T const&& x) const; + + template + constexpr *tagged default* operator|(T&& x) const; :Requires: one of the following: @@ -732,8 +614,11 @@ nested ``qualifier`` type of ``Tag`` must be ``consume_reference`` or ``operator||`` .. parsed-literal:: - template *tagged lazy default* operator||(F const& g) const; - template *tagged lazy default* operator||(F& g) const; + template + constexpr *tagged lazy default* operator||(F const& g) const; + + template + constexpr *tagged lazy default* operator||(F& g) const; :Requires: ``g()`` must be valid, with type ``boost::``\ |result_of|_\ ``::type``. [#no_result_of]_ @@ -795,16 +680,15 @@ __ ../../../../boost/parameter/template_keyword.hpp The |ntp_cpp|_ test program demonstrates proper usage of this class template. -.. |ntp_cpp| replace:: ntp.cpp +.. |ntp_cpp| replace:: test/ntp.cpp .. _ntp_cpp: ../../test/ntp.cpp ``parameters`` -------------- -Provides an interface for assembling the actual arguments to a -`forwarding function` into an |ArgumentPack|, in which any -|positional| arguments will be tagged according to the -corresponding template argument to ``parameters``. +Provides an interface for assembling the actual arguments to a `forwarding +function` into an |ArgumentPack|, in which any |positional| arguments will be +tagged according to the corresponding template argument to ``parameters``. .. _forwarding function: `forwarding functions`_ @@ -812,8 +696,6 @@ corresponding template argument to ``parameters``. __ ../../../../boost/parameter/parameters.hpp -**If** |BOOST_PARAMETER_HAS_PERFECT_FORWARDING| is ``#defined``, **then** - .. parsed-literal:: template @@ -857,78 +739,12 @@ __ ../../../../boost/parameter/parameters.hpp | else | ``K`` ## *i* is the |keyword tag type| of ``P`` ## *i*. -**If** |BOOST_PARAMETER_HAS_PERFECT_FORWARDING| is **not** ``#defined``, -**then** - -.. parsed-literal:: - - template < - typename P0 = *unspecified* - , typename P1 = *unspecified* - , … - , typename P ## β = *unspecified* - > - struct parameters - { - template < - typename A0 - , typename A1 = *unspecified* - , … - , typename A ## β = *unspecified* - > - struct `match`_ - { - typedef … type; - }; - - template - |ArgumentPack|_ `operator()`_\(A0& a0) const; - - template - |ArgumentPack|_ `operator()`_\(A0& a0, A1& a1) const; - - :vellipsis:`⋮` - - template - |ArgumentPack|_ - `operator()`_\(A0& a0, A1& a1, …, A ## β & a ## β) const; - }; - -:Requires: ``P0``, ``P1``, …, ``P`` ## β must be models of |ParameterSpec|_. - -.. Note:: - - In this section, ``R`` ## *i* and ``K`` ## *i* are defined as follows: for - any argument type ``A`` ## *i*: - - | let ``D0`` the set [ d0, …, d ## *j*] of all **deduced** - | *parameter specs* in [ ``P0``, …, ``P`` ## β] - | ``R`` ## *i* is the |intended argument type| of ``A`` ## *i* - | - | if ``A`` ## *i* is a result type of ``keyword::`` |operator=|_ - | then - | ``K`` ## *i* is ``T`` - | else - | if some ``A`` ## *j* where *j* ≤ *i* is a result type of - | ``keyword::`` |operator=|_ - | *or* some ``P`` ## *j* in *j* ≤ *i* is **deduced** - | then - | if some *parameter spec* ``d`` ## *j* in ``D`` ## *i* - | matches ``A`` ## *i* - | then - | ``K`` ## *i* is the |keyword tag type| of ``d`` ## *j*. - | ``D``:sub:`i+1` is ``D`` ## *i* - [ ``d`` ## *j*] - | else - | ``K`` ## *i* is the |keyword tag type| of ``P`` ## *i*. - .. _match: ``match`` A |Metafunction|_ used to remove a `forwarding function`_ from overload resolution. -**If** |BOOST_PARAMETER_HAS_PERFECT_FORWARDING| is ``#defined``, **then** - :Returns: if all elements in ``Params...`` are *satisfied* (see below), then ``parameters``. Otherwise, ``match::type`` is not defined. @@ -945,49 +761,15 @@ Each element ``P`` in ``Params...`` is **satisfied** if either: - ``X`` is some ``K`` ## *i*, **and** - ``mpl::apply::type::value`` is ``true`` -**If** |BOOST_PARAMETER_HAS_PERFECT_FORWARDING| is **not** ``#defined``, -**then** - -:Returns: if ``P0``, ``P1``, …, ``Pβ`` are *satisfied* (see below), then -``parameters``. Otherwise, ``match::type`` is not -defined. - -``P0``, ``P1``, …, ``Pβ`` are **satisfied** if, for every *j* in 0…β, -either: - -* ``P`` ## *j* is the *unspecified* default -* **or**, ``P`` ## *j* is a *keyword tag type* -* **or**, ``P`` ## *j* is |optional|_ ```` and either - - ``X`` is not ``K`` ## *i* for any *i*, - - **or** ``X`` is some ``K`` ## *i* and ``mpl::apply::type::value`` is ``true`` -* **or**, ``P`` ## *j* is |required|_ ````, and - - ``X`` is some ``K`` ## *i*, **and** - - ``mpl::apply::type::value`` is ``true`` - .. _operator(): ``operator()`` -**If** |BOOST_PARAMETER_HAS_PERFECT_FORWARDING| is ``#defined``, **then** - .. parsed-literal:: template |ArgumentPack|_ operator()(Args&&... args) const; -**Else** - -.. parsed-literal:: - - template |ArgumentPack|_ operator()(A0 const& a0) const; - - :vellipsis:`⋮` - - template - |ArgumentPack|_ - `operator()`_\(A0 const& a0, …, A ## β const& a ## β) const; - :Returns: An |ArgumentPack|_ containing, for each ``a`` ## *i*, - if ``a`` ## *i* is a single-element |ArgumentPack|, its element @@ -1029,9 +811,13 @@ Both headers are included by: |preprocessor_header|_ struct required; The default value of ``Predicate`` is an unspecified `MPL Binary Metafunction -Class`_ that returns ``mpl::true_`` for any argument. +Class`_ that returns ``mpl::true_`` for any argument. If +|BOOST_PARAMETER_CAN_USE_MP11| is defined, then the default value of +``Predicate`` is also a `Boost.MP11`-style quoted metafunction that returns +``mp11::mp_true`` for any argument. .. _`MPL Binary Metafunction Class`: ../../../mpl/doc/refmanual/metafunction-class.html +.. _`Boost.MP11`: ../../../mp11/doc/html/mp11.html ``deduced`` ----------- @@ -1132,14 +918,69 @@ __ ../../../../boost/parameter/value_type.hpp :Returns: the (possibly const-qualified) type of the |tagged reference| in ``A`` having |keyword tag type| ``K``, if any. If no such |tagged reference| -exists, returns ``D``. Equivalent to:: +exists, returns ``D``. Equivalent to:: - typename remove_reference< - typename binding::type + typename boost::`remove_reference`_< + typename |binding|_::type >::type … when ``D`` is not a reference type. +.. _remove_reference: ../../../type_traits/doc/html/boost_typetraits/remove_reference.html + +``are_tagged_arguments`` +------------------------ + +:Defined in: `boost/parameter/are_tagged_arguments.hpp`__ + +__ ../../../../boost/parameter/are_tagged_arguments.hpp + +.. parsed-literal:: + + template + struct are_tagged_arguments // : mpl::true_ or mpl::false_ + { + }; + +:Returns: +``mpl::true_`` if ``T0`` and all elements in parameter pack ``Pack`` are +|tagged reference| types, ``mpl::false_`` otherwise. + +:Example usage: +When implementing a Boost.Parameter-enabled constructor for a container that +conforms to the C++ standard, one needs to remember that the standard requires +the presence of other constructors that are typically defined as templates, +such as range constructors. To avoid overload ambiguities between the two +constructors, use this metafunction in conjunction with ``disable_if`` to +define the range constructor. + +.. parsed-literal:: + + template + class frontend : public B + { + struct _enabler + { + }; + + public: + |BOOST_PARAMETER_NO_SPEC_CONSTRUCTOR|_(frontend, (B)) + + template + frontend( + Iterator itr + , Iterator itr_end + , typename boost::`disable_if`_< + are_tagged_arguments + , _enabler + >::type = _enabler() + ) : B(itr, itr_end) + { + } + }; + +.. _`disable_if`: ../../../core/doc/html/core/enable_if.html + ``is_argument_pack`` -------------------- @@ -1154,8 +995,127 @@ __ ../../../../boost/parameter/is_argument_pack.hpp { }; -:Returns: ``mpl::true_`` if ``T`` is a model of |ArgumentPack|_, -``mpl::false_`` otherwise. +:Returns: +``mpl::true_`` if ``T`` is a model of |ArgumentPack|_, ``mpl::false_`` +otherwise. + +:Example usage: +To avoid overload ambiguities between a constructor that takes in an +|ArgumentPack|_ and a templated conversion constructor, use this metafunction +in conjunction with ``enable_if``. + +.. parsed-literal:: + + |BOOST_PARAMETER_NAME|_(a0) + + template + class backend0 + { + struct _enabler + { + }; + + T a0; + + public: + template + explicit backend0( + ArgPack const& args + , typename boost::`enable_if`_< + is_argument_pack + , _enabler + >::type = _enabler() + ) : a0(args[_a0]) + { + } + + template + backend0( + backend0 const& copy + , typename boost::`enable_if`_< + boost::`is_convertible`_ + , _enabler + >::type = _enabler() + ) : a0(copy.get_a0()) + { + } + + T const& get_a0() const + { + return this->a0; + } + }; + +.. _`is_convertible`: ../../../type_traits/doc/html/boost_typetraits/is_convertible.html + +////////////////////////////////////////////////////////////////////////////// + +Function Templates +================== + +``compose`` +----------- + +:Defined in: `boost/parameter/compose.hpp`__ + +__ ../../../../boost/parameter/compose.hpp + +.. parsed-literal:: + + constexpr *empty* |ArgumentPack|_ compose(); + + template + constexpr typename boost::`enable_if`_< + |are_tagged_arguments|_ + , |ArgumentPack|_ + >::type + compose(T0 const& t0, Pack const&... args); + +This function facilitates easier variadic argument composition. It is used by +the |BOOST_PARAMETER_NO_SPEC_FUNCTION|, +|BOOST_PARAMETER_NO_SPEC_MEMBER_FUNCTION|, +|BOOST_PARAMETER_NO_SPEC_CONST_MEMBER_FUNCTION|, +|BOOST_PARAMETER_NO_SPEC_FUNCTION_CALL_OPERATOR|, +|BOOST_PARAMETER_NO_SPEC_CONST_FUNCTION_CALL_OPERATOR|, +|BOOST_PARAMETER_NO_SPEC_CONSTRUCTOR|, and +|BOOST_PARAMETER_NO_SPEC_NO_BASE_CONSTRUCTOR| code generation macros. You can +use it to write your own code generation macros if the ones provided by this +library do not suffice. + +Unlike the |tagged reference| comma operator, the ``compose()`` function is +variadic, as mentioned before. However, the |tagged reference| comma operator +can be invoked indefinitely and therefore does not limit the size of the +resulting |ArgumentPack|, while the ``compose()`` function cannot take in more +than |BOOST_PARAMETER_MAX_ARITY| arguments for compilers that do not +support perfect forwarding. + +:Requires: ``t0`` and all elements in ``args`` must be |tagged reference| +objects, if specified. + +:Returns: an |ArgumentPack|_ containing ``t0`` and all elements in ``args``, +if specified; an empty |ArgumentPack|_ otherwise. + +:Example usage: +.. parsed-literal:: + + BOOST_PARAMETER_NAME(index) + BOOST_PARAMETER_NAME(name) + + template + int print_name_and_index(ArgumentPack const& args) + { + std::cout << "index = " << args[_index]; + std::cout << "name = " << args[_name]; + std::cout << "; " << std::endl; + return 0; + } + + int y = print_name_and_index(compose(_index = 3, _name = "jones")); + +The |compose_cpp|_ test program shows more examples using this function. + +.. |compose_cpp| replace:: compose.cpp +.. _compose_cpp: ../../test/compose.cpp ////////////////////////////////////////////////////////////////////////////// @@ -1172,11 +1132,210 @@ using the Parameter library by eliminating repetitive boilerplate. __ ../../../../boost/parameter/preprocessor.hpp -:Requires: ``result`` is the parenthesized return type of the -function. ``name`` is the base name of the function; it determines the name -of the generated forwarding functions. ``tag_namespace`` is the namespace in -which the keywords used by the function resides. ``arguments`` is a -`Boost.Preprocessor`_ `sequence`_ of *argument-specifiers*, as defined below. +Generates a function that can take in positional arguments, composed +arguments, named arguments, and deduced arguments. + +:Example usage: +The return type of each of the following function templates falls under a +different value category. + +.. parsed-literal:: + + template + std::`bitset`_ rvalue_bitset() + { + return std::`bitset`_(); + } + + template + std::`bitset`_ const rvalue_const_bitset() + { + return std::`bitset`_(); + } + + template + std::`bitset`_& lvalue_bitset() + { + static std::`bitset`_ lset = std::`bitset`_(); + return lset; + } + + template + std::`bitset`_ const& lvalue_const_bitset() + { + static std::`bitset`_ const clset = std::`bitset`_(); + return clset; + } + +The ``U::evaluate_category`` static member function template has a simple job: +to return the correct value category when passed in an object returned by one +of the functions defined above. Assume that +|BOOST_PARAMETER_HAS_PERFECT_FORWARDING| is defined. + +.. parsed-literal:: + + enum invoked + { + passed_by_lvalue_reference_to_const + , passed_by_lvalue_reference + , passed_by_rvalue_reference_to_const + , passed_by_rvalue_reference + }; + + struct U + { + template + static invoked evaluate_category(std::`bitset`_ const&) + { + return passed_by_lvalue_reference_to_const; + } + + template + static invoked evaluate_category(std::`bitset`_&) + { + return passed_by_lvalue_reference; + } + + template + static invoked evaluate_category(std::`bitset`_ const&&) + { + return passed_by_rvalue_reference_to_const; + } + + template + static invoked evaluate_category(std::`bitset`_&&) + { + return passed_by_rvalue_reference; + } + }; + +Define the named parameters that will comprise the argument specification that +this macro will use. Ensure that all their tag types are in the same +namespace, which is ``kw`` in this case. The identifiers with leading +underscores can be passed to the bracket operator of ``args`` to extract the +same argument to which the corresponding named parameter (without underscores) +is bound, as will be shown later. + +.. parsed-literal:: + + |BOOST_PARAMETER_NAME|_((_lrc, kw) in(lrc)) + |BOOST_PARAMETER_NAME|_((_lr, kw) in_out(lr)) + |BOOST_PARAMETER_NAME|_((_rrc, kw) in(rrc)) + |BOOST_PARAMETER_NAME|_((_rr, kw) consume(rr)) + +Use the macro as a substitute for a normal function header. Enclose the +return type ``bool`` in parentheses. For each parameter, also enclose the +expected value type in parentheses. Since the value types are mutually +exclusive, you can wrap the parameters in a ``(deduced …)`` +clause. Otherwise, just as with a normal function, the order in which you +specify the parameters determines their position. Also, just as with a normal +function, optional parameters have default values, whereas required parameters +do not. Within the function body, either simply use the parameter name or +pass the matching identifier with the leading underscore to the bracket +operator of ``args`` to extract the corresponding argument. Note that the +second method doesn't require ``std::forward`` to preserve value categories. + +.. parsed-literal:: + + BOOST_PARAMETER_FUNCTION((bool), evaluate, kw, + (deduced + (required + (lrc, (std::`bitset`_<1>)) + (lr, (std::`bitset`_<2>)) + ) + (optional + (rrc, (std::`bitset`_<3>), rvalue_const_bitset<2>()) + (rr, (std::`bitset`_<4>), rvalue_bitset<3>()) + ) + ) + ) + { + BOOST_TEST_EQ( + passed_by_lvalue_reference_to_const + , U::evaluate_category<0>(lrc) + ); + BOOST_TEST_EQ( + passed_by_lvalue_reference + , U::evaluate_category<1>(lr) + ); + BOOST_TEST_EQ( + passed_by_rvalue_reference_to_const + , U::evaluate_category<2>(std::`forward`_(rrc0)) + ); + BOOST_TEST_EQ( + passed_by_rvalue_reference + , U::evaluate_category<3>(args[_rr0]) + ); + + return true; + } + +The following function calls are legal. + +.. parsed-literal:: + + evaluate( // positional arguments + lvalue_const_bitset<0>() + , lvalue_bitset<1>() + , rvalue_const_bitset<2>() + , rvalue_bitset<3>() + ); + evaluate( // positional arguments + lvalue_const_bitset<0>() + , lvalue_bitset<1>() + ); + evaluate(( // composed arguments + _rr0 = rvalue_bitset<3>() + , _lrc0 = lvalue_const_bitset<0>() + , _lr0 = lvalue_bitset<1>() + , _rrc0 = rvalue_const_bitset<2>() + )); + evaluate( // named arguments + _rr0 = rvalue_bitset<3>() + , _lrc0 = lvalue_const_bitset<0>() + , _lr0 = lvalue_bitset<1>() + , _rrc0 = rvalue_const_bitset<2>() + ); + evaluate( // named arguments + _lr0 = lvalue_bitset<1>() + , _lrc0 = lvalue_const_bitset<0>() + ); + +Because the parameters were wrapped in a ``(deduced …)`` clause, the following +function calls are also legal. + +.. parsed-literal:: + + evaluate( // deduced arguments + rvalue_bitset<3>() + , lvalue_const_bitset<0>() + , lvalue_bitset<1>() + , rvalue_const_bitset<2>() + ); + evaluate( // deduced arguments + lvalue_bitset<1>() + , lvalue_const_bitset<0>() + ); + +The |preprocessor|_, |preprocessor_deduced|_, and |preprocessor_eval_cat|_ +test programs demonstrate proper usage of this macro. + +.. _`bitset`: http\://en.cppreference.com/w/cpp/utility/bitset +.. |preprocessor| replace:: preprocessor.cpp +.. _preprocessor: ../../test/preprocessor.cpp +.. |preprocessor_deduced| replace:: preprocessor_deduced.cpp +.. _preprocessor_deduced: ../../test/preprocessor_deduced.cpp +.. |preprocessor_eval_cat| replace:: preprocessor_eval_category.cpp +.. _preprocessor_eval_cat: ../../test/preprocessor_eval_category.cpp + +:Macro parameters: +\*. ``result`` is the parenthesized return type of the function. +\*. ``name`` is the base name of the function; it determines the name of the +generated forwarding functions. +\*. ``tag_namespace`` is the namespace in which the keywords used by the +function resides. +\*. ``arguments`` is a `Boost.Preprocessor`_ `sequence`_ of +*argument-specifiers*, as defined below. :Argument specifiers syntax: .. parsed-literal:: @@ -1214,17 +1373,17 @@ which the keywords used by the function resides. ``arguments`` is a ( '**(**' *type-name* '**)**' ) | '**\***' -* ``argument-name`` is any valid C++ identifier. -* ``default-value`` is any valid C++ expression; if necessary, user code can +\*. ``argument-name`` is any valid C++ identifier. +\*. ``default-value`` is any valid C++ expression; if necessary, user code can compute it in terms of ``previous-name ## _type``, where ``previous-name`` is the ``argument-name`` in a previous ``specifier-group0`` or ``specifier-group1``. *This expression will be invoked exactly once.* -* ``mfc`` is an `MPL Binary Metafunction Class`_ whose first argument will be -the type of the corresponding ``argument-name``, whose second argument will be -the entire |ArgumentPack|_, and whose return type is a `Boolean Integral +\*. ``mfc`` is an `MPL Binary Metafunction Class`_ whose first argument will +be the type of the corresponding ``argument-name``, whose second argument will +be the entire |ArgumentPack|_, and whose return type is a `Boolean Integral Constant`_; however, user code *cannot* compute ``mfc`` in terms of ``previous-name ## _type``. -* ``type-name`` is either the name of a **target type** or an `MPL Binary +\*. ``type-name`` is either the name of a **target type** or an `MPL Binary Metafunction Class`_ whose first argument will be the type of the corresponding ``argument-name``, whose second argument will be the entire |ArgumentPack|_, and whose return type is the **target type**. If @@ -1238,22 +1397,12 @@ in ``args``) will be cast to that type. .. _`MPL Binary Metafunction Class`: ../../../mpl/doc/refmanual/metafunction-class.html .. _`Boolean Integral Constant`: ../../../mpl/doc/refmanual/integral-constant.html -:Generated names in enclosing scope: -* ``boost_param_result_ ## __LINE__ ## name`` -* ``boost_param_params_ ## __LINE__ ## name`` -* ``boost_param_parameters_ ## __LINE__ ## name`` -* ``boost_param_impl ## name`` -* ``boost_param_dispatch_0boost_ ## __LINE__ ## name`` -* ``boost_param_dispatch_1boost_ ## __LINE__ ## name`` - Approximate expansion: **Where**: * ``n`` denotes the *minimum* arity, as determined from ``arguments``. * ``m`` denotes the *maximum* arity, as determined from ``arguments``. -**If** |BOOST_PARAMETER_HAS_PERFECT_FORWARDING| is ``#defined``, **then** - .. parsed-literal:: template @@ -1263,28 +1412,28 @@ Approximate expansion: }; struct boost_param_params\_ ## __LINE__ ## **name** - : boost::parameter::parameters< + : |parameters|_< *list of parameter specifications, based on arguments* > { }; - typedef boost_param_params\_ ## __LINE__ ## **name** + typedef boost_param_params\_ ## __LINE__ ## **name** boost_param_parameters\_ ## __LINE__ ## **name**; template typename boost_param_result\_ ## __LINE__ ## **name**\ ::type - boost_param_impl ## **name**\ (Args const&); + boost_param_impl ## __LINE__ ## **name**\ (Args const&); template **result** **name**\ ( A0&& a0, …, A ## **n**\ && a ## **n** - , typename boost_param_parameters\_ ## __LINE__ ## **name**::match< - A0, …, A ## **n** - >::type = boost_param_parameters\_ ## __LINE__ ## **name**\ () + , typename boost_param_parameters\_ ## __LINE__ ## **name** + ::match::type + = boost_param_parameters\_ ## __LINE__ ## **name**\ () ) { - return boost_param_impl ## **name**\ ( + return boost_param_impl ## __LINE__ ## **name**\ ( boost_param_parameters\_ ## __LINE__ ## **name**\ ()( std::`forward`_(a0) , … @@ -1298,12 +1447,12 @@ Approximate expansion: template **result** **name**\ ( A0&& a0, …, A ## **m**\ && a ## **m** - , typename boost_param_parameters\_ ## __LINE__ ## **name**::match< - A0, …, A ## **m** - >::type = boost_param_parameters\_ ## __LINE__ ## **name**\ () + , typename boost_param_parameters\_ ## __LINE__ ## **name** + ::match::type + = boost_param_parameters\_ ## __LINE__ ## **name**\ () ) { - return boost_param_impl ## **name**\ ( + return boost_param_impl ## __LINE__ ## **name**\ ( boost_param_parameters\_ ## __LINE__ ## **name**\ ()( std::`forward`_(a0) , … @@ -1321,7 +1470,7 @@ Approximate expansion: > ResultType boost_param_dispatch_0boost\_ ## __LINE__ ## **name**\ ( - (ResultType(\ *)()) + (ResultType(\*)()) , Args const& args , *argument name* ## **0** ## _type&& *argument name* ## **0** , … @@ -1339,7 +1488,7 @@ Approximate expansion: > ResultType boost_param_dispatch_0boost\_ ## __LINE__ ## **name**\ ( - (ResultType(\ *)()) + (ResultType(\*)()) , Args const& args , *argument name* ## **0** ## _type&& *argument name* ## **0** , … @@ -1348,20 +1497,24 @@ Approximate expansion: template typename boost_param_result\_ ## __LINE__ ## **name**\ ::type - boost_param_impl ## **name**\ (Args const& args) + boost_param_impl ## __LINE__ ## **name**\ (Args const& args) { return boost_param_dispatch_0boost\_ ## __LINE__ ## **name**\ ( - static_cast(std::nullptr) + static_cast< + typename boost_param_result\_ ## __LINE__ ## **name**\ < + Args + >::type(\*)() + >(std::`nullptr`_) , args , std::`forward`_< - typename boost::parameter::value_type< + typename |value_type|_< Args , *keyword tag type of required parameter* ## **0** >::type >(args[ *keyword object of required parameter* ## **0**]) , … , std::`forward`_< - typename boost::parameter::value_type< + typename |value_type|_< Args , *keyword tag type of required parameter* ## **n** >::type @@ -1378,7 +1531,7 @@ Approximate expansion: > ResultType boost_param_dispatch_0boost\_ ## __LINE__ ## **name**\ ( - (ResultType(\ *)()) + (ResultType(\*)()) , Args const& args , *argument name* ## **0** ## _type&& *argument name* ## **0** , … @@ -1386,7 +1539,7 @@ Approximate expansion: ) { return boost_param_dispatch_0boost\_ ## __LINE__ ## **name**\ ( - static_cast(std::nullptr) + static_cast(std::`nullptr`_) , (args, *keyword object of optional parameter* ## **n + 1** = *default value of optional parameter* ## **n + 1** ) @@ -1398,7 +1551,7 @@ Approximate expansion: *argument name* ## **n** ) , std::`forward`_< - typename boost::parameter::value_type< + typename |value_type|_< Args , *keyword tag type of optional parameter* ## **n + 1** >::type @@ -1417,15 +1570,296 @@ Approximate expansion: > ResultType boost_param_dispatch_0boost\_ ## __LINE__ ## **name**\ ( - (ResultType(\ *)()) + (ResultType(\*)()) , Args const& args , *argument name* ## **0** ## _type&& *argument name* ## **0** , … , *argument name* ## **m** ## _type&& *argument name* ## **m** ) -**If** |BOOST_PARAMETER_HAS_PERFECT_FORWARDING| is **not** ``#defined``, -**then** +.. _`forward`: http\://en.cppreference.com/w/cpp/utility/forward +.. _`nullptr`: http\://en.cppreference.com/w/cpp/language/nullptr + +``BOOST_PARAMETER_MEMBER_FUNCTION(result, name, tag_namespace, arguments)`` +--------------------------------------------------------------------------- + +:Defined in: `boost/parameter/preprocessor.hpp`__ + +__ ../../../../boost/parameter/preprocessor.hpp + +Generates a member function that can take in positional arguments, composed +arguments, named arguments, and deduced arguments. + +:Example usage: +The return type of each of the following function templates falls under a +different value category. + +.. parsed-literal:: + + template + std::`bitset`_ rvalue_bitset() + { + return std::`bitset`_(); + } + + template + std::`bitset`_ const rvalue_const_bitset() + { + return std::`bitset`_(); + } + + template + std::`bitset`_& lvalue_bitset() + { + static std::`bitset`_ lset = std::`bitset`_(); + return lset; + } + + template + std::`bitset`_ const& lvalue_const_bitset() + { + static std::`bitset`_ const clset = std::`bitset`_(); + return clset; + } + +The ``U::evaluate_category`` static member function template has a simple job: +to return the correct value category when passed in an object returned by one +of the functions defined above. Assume that +|BOOST_PARAMETER_HAS_PERFECT_FORWARDING| is defined. + +.. parsed-literal:: + + enum invoked + { + passed_by_lvalue_reference_to_const + , passed_by_lvalue_reference + , passed_by_rvalue_reference_to_const + , passed_by_rvalue_reference + }; + + struct U + { + template + static invoked evaluate_category(std::`bitset`_ const&) + { + return passed_by_lvalue_reference_to_const; + } + + template + static invoked evaluate_category(std::`bitset`_&) + { + return passed_by_lvalue_reference; + } + + template + static invoked evaluate_category(std::`bitset`_ const&&) + { + return passed_by_rvalue_reference_to_const; + } + + template + static invoked evaluate_category(std::`bitset`_&&) + { + return passed_by_rvalue_reference; + } + }; + +Define the named parameters that will comprise the argument specification that +this macro will use. Ensure that all their tag types are in the same +namespace, which is ``kw`` in this case. The identifiers with leading +underscores can be passed to the bracket operator of ``args`` to extract the +same argument to which the corresponding named parameter (without underscores) +is bound, as will be shown later. + +.. parsed-literal:: + + |BOOST_PARAMETER_NAME|_((_lrc, kw) in(lrc)) + |BOOST_PARAMETER_NAME|_((_lr, kw) in_out(lr)) + |BOOST_PARAMETER_NAME|_((_rrc, kw) in(rrc)) + |BOOST_PARAMETER_NAME|_((_rr, kw) consume(rr)) + +Use the macro as a substitute for a normal ``static`` member function +header. Enclose the return type ``bool`` in parentheses. For each parameter, +also enclose the expected value type in parentheses. Since the value types +are mutually exclusive, you can wrap the parameters in a ``(deduced …)`` +clause. Otherwise, just as with a normal function, the order in which you +specify the parameters determines their position. Also, just as with a normal +function, optional parameters have default values, whereas required parameters +do not. Within the function body, either simply use the parameter name or +pass the matching identifier with the leading underscore to the bracket +operator of ``args`` to extract the corresponding argument. Note that the +second method doesn't require ``std::forward`` to preserve value categories. + +.. parsed-literal:: + + struct B + { + BOOST_PARAMETER_MEMBER_FUNCTION((bool), static evaluate, kw, + (deduced + (required + (lrc, (std::`bitset`_<1>)) + (lr, (std::`bitset`_<2>)) + ) + (optional + (rrc, (std::`bitset`_<3>), rvalue_const_bitset<2>()) + (rr, (std::`bitset`_<4>), rvalue_bitset<3>()) + ) + ) + ) + { + BOOST_TEST_EQ( + passed_by_lvalue_reference_to_const + , U::evaluate_category<0>(lrc) + ); + BOOST_TEST_EQ( + passed_by_lvalue_reference + , U::evaluate_category<1>(lr) + ); + BOOST_TEST_EQ( + passed_by_rvalue_reference_to_const + , U::evaluate_category<2>(std::`forward`_(rrc0)) + ); + BOOST_TEST_EQ( + passed_by_rvalue_reference + , U::evaluate_category<3>(args[_rr0]) + ); + + return true; + } + }; + +The following function calls are legal. + +.. parsed-literal:: + + B::evaluate( // positional arguments + lvalue_const_bitset<0>() + , lvalue_bitset<1>() + , rvalue_const_bitset<2>() + , rvalue_bitset<3>() + ); + B::evaluate( // positional arguments + lvalue_const_bitset<0>() + , lvalue_bitset<1>() + ); + B::evaluate(( // composed arguments + _rr0 = rvalue_bitset<3>() + , _lrc0 = lvalue_const_bitset<0>() + , _lr0 = lvalue_bitset<1>() + , _rrc0 = rvalue_const_bitset<2>() + )); + B::evaluate( // named arguments + _rr0 = rvalue_bitset<3>() + , _lrc0 = lvalue_const_bitset<0>() + , _lr0 = lvalue_bitset<1>() + , _rrc0 = rvalue_const_bitset<2>() + ); + B::evaluate( // named arguments + _lr0 = lvalue_bitset<1>() + , _lrc0 = lvalue_const_bitset<0>() + ); + +Because the parameters were wrapped in a ``(deduced …)`` clause, the following +function calls are also legal. + +.. parsed-literal:: + + B::evaluate( // deduced arguments + rvalue_bitset<3>() + , lvalue_const_bitset<0>() + , lvalue_bitset<1>() + , rvalue_const_bitset<2>() + ); + B::evaluate( // deduced arguments + lvalue_bitset<1>() + , lvalue_const_bitset<0>() + ); + +The |preprocessor|_ and |preprocessor_eval_cat|_ test programs demonstrate +proper usage of this macro. + +.. _`bitset`: http\://en.cppreference.com/w/cpp/utility/bitset +.. |preprocessor| replace:: preprocessor.cpp +.. _preprocessor: ../../test/preprocessor.cpp +.. |preprocessor_eval_cat| replace:: preprocessor_eval_category.cpp +.. _preprocessor_eval_cat: ../../test/preprocessor_eval_category.cpp + +:Macro parameters: +\*. ``result`` is the parenthesized return type of the function. +\*. ``name`` is the base name of the function; it determines the name of the +generated forwarding functions. ``name`` may be qualified by the ``static`` +keyword to declare the member function and its helpers as not associated with +any object of the enclosing type. +\*. ``tag_namespace`` is the namespace in which the keywords used by the +function resides. +\*. ``arguments`` is a `Boost.Preprocessor`_ `sequence`_ of +*argument-specifiers*, as defined below. + +:Argument specifiers syntax: +.. parsed-literal:: + + argument-specifiers ::= *specifier-group0* {*specifier-group0*\ } + + specifier-group0 ::= *specifier-group1* | + ( + '**(**' '**deduced**' + *specifier-group1* {*specifier-group1*\ } + '**)**' + ) + + specifier-group1 ::= + ( + '**(**' '**optional**' + *optional-specifier* {*optional-specifier*\ } + '**)**' + ) | ( + '**(**' '**required**' + *required-specifier* {*required-specifier*\ } + '**)**' + ) + + optional-specifier ::= + '**(**' + *argument-name* '**,**' *restriction* '**,**' *default-value* + ')' + + required-specifier ::= + '**(**' *argument-name* '**,**' *restriction* ')' + + restriction ::= + ( '**\***' '**(**' *mfc* '**)**' ) | + ( '**(**' *type-name* '**)**' ) | + '**\***' + +\*. ``argument-name`` is any valid C++ identifier. +\*. ``default-value`` is any valid C++ expression; if necessary, user code can +compute it in terms of ``previous-name ## _type``, where ``previous-name`` is +the ``argument-name`` in a previous ``specifier-group0`` or +``specifier-group1``. *This expression will be invoked exactly once.* +\*. ``mfc`` is an `MPL Binary Metafunction Class`_ whose first argument will +be the type of the corresponding ``argument-name``, whose second argument will +be the entire |ArgumentPack|_, and whose return type is a `Boolean Integral +Constant`_; however, user code *cannot* compute ``mfc`` in terms of +``previous-name ## _type``. +\*. ``type-name`` is either the name of a **target type** or an `MPL Binary +Metafunction Class`_ whose first argument will be the type of the +corresponding ``argument-name``, whose second argument will be the entire +|ArgumentPack|_, and whose return type is the **target type**. If +``restriction`` uses this form, then the type of the generated name +``argument-name ## _type`` will be computed in terms of the **target type**, +and the generated reference ``argument-name`` (but not its corresponding entry +in ``args``) will be cast to that type. + +.. _`Boost.Preprocessor`: ../../../preprocessor/doc/index.html +.. _`sequence`: ../../../preprocessor/doc/data/sequences.html +.. _`MPL Binary Metafunction Class`: ../../../mpl/doc/refmanual/metafunction-class.html +.. _`Boolean Integral Constant`: ../../../mpl/doc/refmanual/integral-constant.html + +Approximate expansion: +**Where**: + +* ``n`` denotes the *minimum* arity, as determined from ``arguments``. +* ``m`` denotes the *maximum* arity, as determined from ``arguments``. .. parsed-literal:: @@ -1436,50 +1870,28 @@ Approximate expansion: }; struct boost_param_params\_ ## __LINE__ ## **name** - : boost::parameter::parameters< + : |parameters|_< *list of parameter specifications, based on arguments* > { }; - typedef boost_param_params\_ ## __LINE__ ## **name** + typedef boost_param_params\_ ## __LINE__ ## **name** boost_param_parameters\_ ## __LINE__ ## **name**; - template - typename boost_param_result\_ ## __LINE__ ## **name**\ ::type - boost_param_impl ## **name**\ (Args const&); - template - **result** - **name**\ ( - A0 const& a0, …, A ## **n** const& a ## **n** - , typename boost_param_parameters\_ ## __LINE__ ## **name**::match< - A0 const, …, A ## **n** const - >::type = boost_param_parameters\_ ## __LINE__ ## **name**\ () - ) + **result** **name**\ ( + A0&& a0, …, A ## **n**\ && a ## **n** + , typename boost_param_parameters\_ ## __LINE__ ## **name** + ::match::type + = boost_param_parameters\_ ## __LINE__ ## **name**\ () + ) { - return boost_param_impl ## **name**\ ( + return this->boost_param_impl ## __LINE__ ## **name**\ ( boost_param_parameters\_ ## __LINE__ ## **name**\ ()( - a0, …, a ## **n** - ) - ); - } - - *… exponential number of overloads …* - :vellipsis:`⋮` - - template - **result** - **name**\ ( - A0& a0, …, A ## **n** & a ## **n** - , typename boost_param_parameters\_ ## __LINE__ ## **name**::match< - A0, …, A ## **n** - >::type = boost_param_parameters\_ ## __LINE__ ## **name**\ () - ) - { - return boost_param_impl ## **name**\ ( - boost_param_parameters\_ ## __LINE__ ## **name**\ ()( - a0, …, a ## **n** + std::`forward`_(a0) + , … + , std::`forward`_(a ## **n**) ) ); } @@ -1487,84 +1899,46 @@ Approximate expansion: :vellipsis:`⋮` template - **result** - **name**\ ( - A0 const& a0, …, A ## **m** const& a ## **m** - , typename boost_param_parameters\_ ## __LINE__ ## **name**::match< - A0 const, …, A ## **m** const - >::type = boost_param_parameters\_ ## __LINE__ ## **name**\ () - ) + **result** **name**\ ( + A0&& a0, …, A ## **m**\ && a ## **m** + , typename boost_param_parameters\_ ## __LINE__ ## **name** + ::match::type + = boost_param_parameters\_ ## __LINE__ ## **name**\ () + ) { - return boost_param_impl ## **name**\ ( + return this->boost_param_impl ## __LINE__ ## **name**\ ( boost_param_parameters\_ ## __LINE__ ## **name**\ ()( - a0, …, a ## **m** + std::`forward`_(a0) + , … + , std::`forward`_(a ## **m**) ) ); } - *… exponential number of overloads …* - :vellipsis:`⋮` - - template - **result** - **name**\ ( - A0& a0, …, A ## **m** & a ## **m** - , typename boost_param_parameters\_ ## __LINE__ ## **name**::match< - A0, …, A ## **m** - >::type = boost_param_parameters\_ ## __LINE__ ## **name**\ () - ) - { - return boost_param_impl ## **name**\ ( - boost_param_parameters\_ ## __LINE__ ## **name**\ ()( - a0, …, a ## **m** - ) - ); - } - - template < - typename ResultType - , typename Args - , typename *argument name* ## **0** ## _type - , … - , typename *argument name* ## **n** ## _type - > - ResultType - boost_param_dispatch_0boost\_ ## __LINE__ ## **name**\ ( - (ResultType(\ *)()) - , Args const& args - , *argument name* ## **0** ## _type& *argument name* ## **0** - , … - , *argument name* ## **n** ## _type& *argument name* ## **m** - ); - - :vellipsis:`⋮` - - template < - typename ResultType - , typename Args - , typename *argument name* ## **0** ## _type - , … - , typename *argument name* ## **m** ## _type - > - ResultType - boost_param_dispatch_0boost\_ ## __LINE__ ## **name**\ ( - (ResultType(\ *)()) - , Args const& args - , *argument name* ## **0** ## _type& *argument name* ## **0** - , … - , *argument name* ## **m** ## _type& *argument name* ## **m** - ); - template typename boost_param_result\_ ## __LINE__ ## **name**\ ::type - boost_param_impl ## **name**\ (Args const& args) + boost_param_impl ## __LINE__ ## **name**\ (Args const& args) { - return boost_param_dispatch_0boost\_ ## __LINE__ ## **name**\ ( - static_cast(std::nullptr) + return this->boost_param_dispatch_0boost\_ ## __LINE__ ## **name**\ ( + static_cast< + typename boost_param_result\_ ## __LINE__ ## **name**\ < + Args + >::type(\*)() + >(std::`nullptr`_) , args - , args[ *keyword object of required parameter* ## **0**] + , std::`forward`_< + typename |value_type|_< + Args + , *keyword tag type of required parameter* ## **0** + >::type + >(args[ *keyword object of required parameter* ## **0**]) , … - , args[ *keyword object of required parameter* ## **n**] + , std::`forward`_< + typename |value_type|_< + Args + , *keyword tag type of required parameter* ## **n** + >::type + >(args[ *keyword object of required parameter* ## **n**]) ); } @@ -1577,22 +1951,31 @@ Approximate expansion: > ResultType boost_param_dispatch_0boost\_ ## __LINE__ ## **name**\ ( - (ResultType(\ *)()) + (ResultType(\*)()) , Args const& args - , *argument name* ## **0** ## _type& *argument name* ## **0** + , *argument name* ## **0** ## _type&& *argument name* ## **0** , … - , *argument name* ## **n** ## _type& *argument name* ## **m** + , *argument name* ## **n** ## _type&& *argument name* ## **n** ) { - return boost_param_dispatch_0boost\_ ## __LINE__ ## **name**\ ( - static_cast(std::nullptr) + return this->boost_param_dispatch_0boost\_ ## __LINE__ ## **name**\ ( + static_cast(std::`nullptr`_) , (args, *keyword object of optional parameter* ## **n + 1** = *default value of optional parameter* ## **n + 1** ) - , *argument name* ## **0** + , std::`forward`_<*argument name* ## **0** ## _type>( + *argument name* ## **0** + ) , … - , *argument name* ## **n** - , *default value of optional parameter* ## **n + 1** + , std::`forward`_<*argument name* ## **n** ## _type>( + *argument name* ## **n** + ) + , std::`forward`_< + typename |value_type|_< + Args + , *keyword tag type of optional parameter* ## **n + 1** + >::type + >(*default value of optional parameter* ## **n + 1**) ); } @@ -1607,47 +1990,15 @@ Approximate expansion: > ResultType boost_param_dispatch_0boost\_ ## __LINE__ ## **name**\ ( - (ResultType(\ *)()) + (ResultType(\*)()) , Args const& args - , *argument name* ## **0** ## _type& *argument name* ## **0** - :vellipsis:`⋮` - , *argument name* ## **m** ## _type& *argument name* ## **m** + , *argument name* ## **0** ## _type&& *argument name* ## **0** + , … + , *argument name* ## **m** ## _type&& *argument name* ## **m** ) -The |preprocessor|_, |preprocessor_deduced|_, and |preprocessor_eval_cat|_ -test programs demonstrate proper usage of this macro. - .. _`forward`: http\://en.cppreference.com/w/cpp/utility/forward -.. |preprocessor| replace:: preprocessor.cpp -.. _preprocessor: ../../test/preprocessor.cpp -.. |preprocessor_deduced| replace:: preprocessor_deduced.cpp -.. _preprocessor_deduced: ../../test/preprocessor_deduced.cpp -.. |preprocessor_eval_cat| replace:: preprocessor_eval_category.cpp -.. _preprocessor_eval_cat: ../../test/preprocessor_eval_category.cpp - -``BOOST_PARAMETER_MEMBER_FUNCTION(result, name, tag_namespace, arguments)`` ---------------------------------------------------------------------------- - -:Defined in: `boost/parameter/preprocessor.hpp`__ - -__ ../../../../boost/parameter/preprocessor.hpp - -Same as ``BOOST_PARAMETER_FUNCTION``, except: - -\*. ``name`` may be qualified by the ``static`` keyword to declare the member -function and its helpers as not associated with any object of the enclosing -type. - -\*. Expansion of this macro omits all forward declarations of the front-end -implementation and dispatch functions. - -The |preprocessor|_ and |preprocessor_eval_cat|_ test programs demonstrate -proper usage of this macro. - -.. |preprocessor| replace:: preprocessor.cpp -.. _preprocessor: ../../test/preprocessor.cpp -.. |preprocessor_eval_cat| replace:: preprocessor_eval_category.cpp -.. _preprocessor_eval_cat: ../../test/preprocessor_eval_category.cpp +.. _`nullptr`: http\://en.cppreference.com/w/cpp/language/nullptr ``BOOST_PARAMETER_CONST_MEMBER_FUNCTION(result, name, tag_ns, arguments)`` -------------------------------------------------------------------------- @@ -1656,15 +2007,421 @@ proper usage of this macro. __ ../../../../boost/parameter/preprocessor.hpp -Same as ``BOOST_PARAMETER_MEMBER_FUNCTION``, except that the overloaded -forwarding member functions and their helper methods are -``const``-qualified. +Generates a member function that can take in positional arguments, composed +arguments, named arguments, and deduced arguments. + +:Example usage: +The return type of each of the following function templates falls under a +different value category. + +.. parsed-literal:: + + template + std::`bitset`_ rvalue_bitset() + { + return std::`bitset`_(); + } + + template + std::`bitset`_ const rvalue_const_bitset() + { + return std::`bitset`_(); + } + + template + std::`bitset`_& lvalue_bitset() + { + static std::`bitset`_ lset = std::`bitset`_(); + return lset; + } + + template + std::`bitset`_ const& lvalue_const_bitset() + { + static std::`bitset`_ const clset = std::`bitset`_(); + return clset; + } + +The ``U::evaluate_category`` static member function template has a simple job: +to return the correct value category when passed in an object returned by one +of the functions defined above. Assume that +|BOOST_PARAMETER_HAS_PERFECT_FORWARDING| is defined. + +.. parsed-literal:: + + enum invoked + { + passed_by_lvalue_reference_to_const + , passed_by_lvalue_reference + , passed_by_rvalue_reference_to_const + , passed_by_rvalue_reference + }; + + struct U + { + template + static invoked evaluate_category(std::`bitset`_ const&) + { + return passed_by_lvalue_reference_to_const; + } + + template + static invoked evaluate_category(std::`bitset`_&) + { + return passed_by_lvalue_reference; + } + + template + static invoked evaluate_category(std::`bitset`_ const&&) + { + return passed_by_rvalue_reference_to_const; + } + + template + static invoked evaluate_category(std::`bitset`_&&) + { + return passed_by_rvalue_reference; + } + }; + +Define the named parameters that will comprise the argument specification that +this macro will use. Ensure that all their tag types are in the same +namespace, which is ``kw`` in this case. The identifiers with leading +underscores can be passed to the bracket operator of ``args`` to extract the +same argument to which the corresponding named parameter (without underscores) +is bound, as will be shown later. + +.. parsed-literal:: + + |BOOST_PARAMETER_NAME|_((_lrc, kw) in(lrc)) + |BOOST_PARAMETER_NAME|_((_lr, kw) in_out(lr)) + |BOOST_PARAMETER_NAME|_((_rrc, kw) in(rrc)) + |BOOST_PARAMETER_NAME|_((_rr, kw) consume(rr)) + +Use the macro as a substitute for a normal ``const`` member function +header. Enclose the return type ``bool`` in parentheses. For each parameter, +also enclose the expected value type in parentheses. Since the value types +are mutually exclusive, you can wrap the parameters in a ``(deduced …)`` +clause. Otherwise, just as with a normal function, the order in which you +specify the parameters determines their position. Also, just as with a normal +function, optional parameters have default values, whereas required parameters +do not. Within the function body, either simply use the parameter name or +pass the matching identifier with the leading underscore to the bracket +operator of ``args`` to extract the corresponding argument. Note that the +second method doesn't require ``std::forward`` to preserve value categories. + +.. parsed-literal:: + + struct B + { + B() + { + } + + BOOST_PARAMETER_CONST_MEMBER_FUNCTION((bool), evaluate, kw, + (deduced + (required + (lrc, (std::`bitset`_<1>)) + (lr, (std::`bitset`_<2>)) + ) + (optional + (rrc, (std::`bitset`_<3>), rvalue_const_bitset<2>()) + (rr, (std::`bitset`_<4>), rvalue_bitset<3>()) + ) + ) + ) + { + BOOST_TEST_EQ( + passed_by_lvalue_reference_to_const + , U::evaluate_category<0>(lrc) + ); + BOOST_TEST_EQ( + passed_by_lvalue_reference + , U::evaluate_category<1>(lr) + ); + BOOST_TEST_EQ( + passed_by_rvalue_reference_to_const + , U::evaluate_category<2>(std::`forward`_(rrc0)) + ); + BOOST_TEST_EQ( + passed_by_rvalue_reference + , U::evaluate_category<3>(args[_rr0]) + ); + + return true; + } + }; + +The following function calls are legal. + +.. parsed-literal:: + + B const b = B(); + b.evaluate( // positional arguments + lvalue_const_bitset<0>() + , lvalue_bitset<1>() + , rvalue_const_bitset<2>() + , rvalue_bitset<3>() + ); + b.evaluate( // positional arguments + lvalue_const_bitset<0>() + , lvalue_bitset<1>() + ); + b.evaluate(( // composed arguments + _rr0 = rvalue_bitset<3>() + , _lrc0 = lvalue_const_bitset<0>() + , _lr0 = lvalue_bitset<1>() + , _rrc0 = rvalue_const_bitset<2>() + )); + b.evaluate( // named arguments + _rr0 = rvalue_bitset<3>() + , _lrc0 = lvalue_const_bitset<0>() + , _lr0 = lvalue_bitset<1>() + , _rrc0 = rvalue_const_bitset<2>() + ); + b.evaluate( // named arguments + _lr0 = lvalue_bitset<1>() + , _lrc0 = lvalue_const_bitset<0>() + ); + +Because the parameters were wrapped in a ``(deduced …)`` clause, the following +function calls are also legal. + +.. parsed-literal:: + + b.evaluate( // deduced arguments + rvalue_bitset<3>() + , lvalue_const_bitset<0>() + , lvalue_bitset<1>() + , rvalue_const_bitset<2>() + ); + b.evaluate( // deduced arguments + lvalue_bitset<1>() + , lvalue_const_bitset<0>() + ); The |preprocessor|_ test program demonstrates proper usage of this macro. +.. _`bitset`: http\://en.cppreference.com/w/cpp/utility/bitset .. |preprocessor| replace:: preprocessor.cpp .. _preprocessor: ../../test/preprocessor.cpp +:Macro parameters: +\*. ``result`` is the parenthesized return type of the function. +\*. ``name`` is the base name of the function; it determines the name of the +generated forwarding functions. +\*. ``tag_namespace`` is the namespace in which the keywords used by the +function resides. +\*. ``arguments`` is a `Boost.Preprocessor`_ `sequence`_ of +*argument-specifiers*, as defined below. + +:Argument specifiers syntax: +.. parsed-literal:: + + argument-specifiers ::= *specifier-group0* {*specifier-group0*\ } + + specifier-group0 ::= *specifier-group1* | + ( + '**(**' '**deduced**' + *specifier-group1* {*specifier-group1*\ } + '**)**' + ) + + specifier-group1 ::= + ( + '**(**' '**optional**' + *optional-specifier* {*optional-specifier*\ } + '**)**' + ) | ( + '**(**' '**required**' + *required-specifier* {*required-specifier*\ } + '**)**' + ) + + optional-specifier ::= + '**(**' + *argument-name* '**,**' *restriction* '**,**' *default-value* + ')' + + required-specifier ::= + '**(**' *argument-name* '**,**' *restriction* ')' + + restriction ::= + ( '**\***' '**(**' *mfc* '**)**' ) | + ( '**(**' *type-name* '**)**' ) | + '**\***' + +\*. ``argument-name`` is any valid C++ identifier. +\*. ``default-value`` is any valid C++ expression; if necessary, user code can +compute it in terms of ``previous-name ## _type``, where ``previous-name`` is +the ``argument-name`` in a previous ``specifier-group0`` or +``specifier-group1``. *This expression will be invoked exactly once.* +\*. ``mfc`` is an `MPL Binary Metafunction Class`_ whose first argument will +be the type of the corresponding ``argument-name``, whose second argument will +be the entire |ArgumentPack|_, and whose return type is a `Boolean Integral +Constant`_; however, user code *cannot* compute ``mfc`` in terms of +``previous-name ## _type``. +\*. ``type-name`` is either the name of a **target type** or an `MPL Binary +Metafunction Class`_ whose first argument will be the type of the +corresponding ``argument-name``, whose second argument will be the entire +|ArgumentPack|_, and whose return type is the **target type**. If +``restriction`` uses this form, then the type of the generated name +``argument-name ## _type`` will be computed in terms of the **target type**, +and the generated reference ``argument-name`` (but not its corresponding entry +in ``args``) will be cast to that type. + +.. _`Boost.Preprocessor`: ../../../preprocessor/doc/index.html +.. _`sequence`: ../../../preprocessor/doc/data/sequences.html +.. _`MPL Binary Metafunction Class`: ../../../mpl/doc/refmanual/metafunction-class.html +.. _`Boolean Integral Constant`: ../../../mpl/doc/refmanual/integral-constant.html + +Approximate expansion: +**Where**: + +* ``n`` denotes the *minimum* arity, as determined from ``arguments``. +* ``m`` denotes the *maximum* arity, as determined from ``arguments``. + +.. parsed-literal:: + + template + struct boost_param_result_const\_ ## __LINE__ ## **name** + { + typedef **result** type; + }; + + struct boost_param_params_const\_ ## __LINE__ ## **name** + : |parameters|_< + *list of parameter specifications, based on arguments* + > + { + }; + + typedef boost_param_params_const\_ ## __LINE__ ## **name** + boost_param_parameters_const\_ ## __LINE__ ## **name**; + + template + **result** **name**\ ( + A0&& a0, …, A ## **n**\ && a ## **n** + , typename boost_param_parameters_const\_ ## __LINE__ ## **name** + ::match::type + = boost_param_parameters_const\_ ## __LINE__ ## **name**\ () + ) const + { + return this->boost_param_impl_const ## __LINE__ ## **name**\ ( + boost_param_parameters_const\_ ## __LINE__ ## **name**\ ( + std::`forward`_(a0) + , … + , std::`forward`_(a ## **n**) + ) + ); + } + + :vellipsis:`⋮` + + template + **result** **name**\ ( + A0&& a0, …, A ## **m**\ && a ## **m** + , typename boost_param_parameters_const\_ ## __LINE__ ## **name** + ::match::type + = boost_param_parameters_const\_ ## __LINE__ ## **name**\ () + ) const + { + return this->boost_param_impl_const ## __LINE__ ## **name**\ ( + boost_param_parameters_const\_ ## __LINE__ ## **name**\ ()( + std::`forward`_(a0) + , … + , std::`forward`_(a ## **m**) + ) + ); + } + + template + typename boost_param_result_const\_ ## __LINE__ ## **name**\ ::type + boost_param_impl_const ## __LINE__ ## **name**\ (Args const& args) const + { + return this-> + boost_param_dispatch_const_0boost\_ ## __LINE__ ## **name**\ ( + static_cast< + typename boost_param_result_const\_ ## __LINE__ ## **name**\ < + Args + >::type(\*)() + >(std::`nullptr`_) + , args + , std::`forward`_< + typename |value_type|_< + Args + , *keyword tag type of required parameter* ## **0** + >::type + >(args[ *keyword object of required parameter* ## **0**]) + , … + , std::`forward`_< + typename |value_type|_< + Args + , *keyword tag type of required parameter* ## **n** + >::type + >(args[ *keyword object of required parameter* ## **n**]) + ); + } + + template < + typename ResultType + , typename Args + , typename *argument name* ## **0** ## _type + , … + , typename *argument name* ## **n** ## _type + > + ResultType + boost_param_dispatch_const_0boost\_ ## __LINE__ ## **name**\ ( + (ResultType(\*)()) + , Args const& args + , *argument name* ## **0** ## _type&& *argument name* ## **0** + , … + , *argument name* ## **n** ## _type&& *argument name* ## **n** + ) const + { + return this-> + boost_param_dispatch_const_0boost\_ ## __LINE__ ## **name**\ ( + static_cast(std::`nullptr`_) + , (args, *keyword object of optional parameter* ## **n + 1** = + *default value of optional parameter* ## **n + 1** + ) + , std::`forward`_<*argument name* ## **0** ## _type>( + *argument name* ## **0** + ) + , … + , std::`forward`_<*argument name* ## **n** ## _type>( + *argument name* ## **n** + ) + , std::`forward`_< + typename |value_type|_< + Args + , *keyword tag type of optional parameter* ## **n + 1** + >::type + >(*default value of optional parameter* ## **n + 1**) + ); + } + + :vellipsis:`⋮` + + template < + typename ResultType + , typename Args + , typename *argument name* ## **0** ## _type + , … + , typename *argument name* ## **m** ## _type + > + ResultType + boost_param_dispatch_const_0boost\_ ## __LINE__ ## **name**\ ( + (ResultType(\*)()) + , Args const& args + , *argument name* ## **0** ## _type&& *argument name* ## **0** + , … + , *argument name* ## **m** ## _type&& *argument name* ## **m** + ) const + +.. _`forward`: http\://en.cppreference.com/w/cpp/utility/forward +.. _`nullptr`: http\://en.cppreference.com/w/cpp/language/nullptr + ``BOOST_PARAMETER_FUNCTION_CALL_OPERATOR(result, tag_namespace, arguments)`` ---------------------------------------------------------------------------- @@ -1672,21 +2429,313 @@ The |preprocessor|_ test program demonstrates proper usage of this macro. __ ../../../../boost/parameter/preprocessor.hpp -Same as ``BOOST_PARAMETER_MEMBER_FUNCTION``, except that the name of the -forwarding member function overloads is ``operator()``. +Generates a function call operator that can take in positional arguments, +composed arguments, named arguments, and deduced arguments. -:Generated names in enclosing scope: -* ``boost_param_result_ ## __LINE__ ## operator`` -* ``boost_param_params_ ## __LINE__ ## operator`` -* ``boost_param_parameters_ ## __LINE__ ## operator`` -* ``boost_param_impl ## operator`` -* ``boost_param_dispatch_0boost_ ## __LINE__ ## operator`` -* ``boost_param_dispatch_1boost_ ## __LINE__ ## operator`` +:Example usage: +Define the named parameters that will comprise the argument specification that +this macro will use. Ensure that all their tag types are in the same +namespace, which is ``tag`` by default. -The |preprocessor|_ test program demonstrates proper usage of this macro. +.. parsed-literal:: + |BOOST_PARAMETER_NAME|_(y) + |BOOST_PARAMETER_NAME|_(z) + +Use the macro as a substitute for a normal function call operator +header. Enclose the return type in parentheses. For each parameter, also +enclose the expected value type in parentheses. Since the value types are +mutually exclusive, you can wrap the parameters in a ``(deduced …)`` +clause. This is especially useful when implementing multiple +Boost.Parameter-enabled function call operator overloads. + +.. parsed-literal:: + + class char_reader + { + int index; + char const\* key; + + public: + explicit char_reader(char const\* k) : index(0), key(k) + { + } + + BOOST_PARAMETER_FUNCTION_CALL_OPERATOR((void), tag, + (deduced + (required + (y, (int)) + (z, (char const\*)) + ) + ) + ) + { + this->index = y; + this->key = z; + } + + |BOOST_PARAMETER_CONST_FUNCTION_CALL_OPERATOR|_((char), tag, + (deduced + (required + (y, (bool)) + (z, (std::`map`_)) + ) + ) + ) + { + return y ? ( + (z.find(this->key)->second)[this->index] + ) : this->key[this->index]; + } + }; + +As with regular argument-dependent lookup, the value types of the arguments +passed in determine which function call operator overload gets invoked. + +.. parsed-literal:: + + char const\* keys[] = {"foo", "bar", "baz"}; + std::`map`_ k2s; + k2s[keys[0]] = std::`string`_("qux"); + k2s[keys[1]] = std::`string`_("wmb"); + k2s[keys[2]] = std::`string`_("zxc"); + char_reader r(keys[0]); + + // positional arguments + BOOST_TEST_EQ('q', (r(true, k2s))); + BOOST_TEST_EQ('f', (r(false, k2s))); + + // named arguments + r(_z = keys[1], _y = 1); + BOOST_TEST_EQ('m', (r(_z = k2s, _y = true))); + BOOST_TEST_EQ('a', (r(_z = k2s, _y = false))); + + // deduced arguments + r(keys[2], 2); + BOOST_TEST_EQ('c', (r(k2s, true))); + BOOST_TEST_EQ('z', (r(k2s, false))); + +The |preprocessor|_ and |preprocessor_deduced|_ test programs demonstrate +proper usage of this macro. + +.. _`map`: http\://en.cppreference.com/w/cpp/container/map +.. _`string`: http\://en.cppreference.com/w/cpp/string/basic_string .. |preprocessor| replace:: preprocessor.cpp .. _preprocessor: ../../test/preprocessor.cpp +.. |preprocessor_deduced| replace:: preprocessor_deduced.cpp +.. _preprocessor_deduced: ../../test/preprocessor_deduced.cpp + +:Macro parameters: +\*. ``result`` is the parenthesized return type of the function call operator. +\*. ``tag_namespace`` is the namespace in which the keywords used by the +function call operator resides. +\*. ``arguments`` is a `Boost.Preprocessor`_ `sequence`_ of +*argument-specifiers*, as defined below. + +:Argument specifiers syntax: +.. parsed-literal:: + + argument-specifiers ::= *specifier-group0* {*specifier-group0*\ } + + specifier-group0 ::= *specifier-group1* | + ( + '**(**' '**deduced**' + *specifier-group1* {*specifier-group1*\ } + '**)**' + ) + + specifier-group1 ::= + ( + '**(**' '**optional**' + *optional-specifier* {*optional-specifier*\ } + '**)**' + ) | ( + '**(**' '**required**' + *required-specifier* {*required-specifier*\ } + '**)**' + ) + + optional-specifier ::= + '**(**' + *argument-name* '**,**' *restriction* '**,**' *default-value* + ')' + + required-specifier ::= + '**(**' *argument-name* '**,**' *restriction* ')' + + restriction ::= + ( '**\***' '**(**' *mfc* '**)**' ) | + ( '**(**' *type-name* '**)**' ) | + '**\***' + +\*. ``argument-name`` is any valid C++ identifier. +\*. ``default-value`` is any valid C++ expression; if necessary, user code can +compute it in terms of ``previous-name ## _type``, where ``previous-name`` is +the ``argument-name`` in a previous ``specifier-group0`` or +``specifier-group1``. *This expression will be invoked exactly once.* +\*. ``mfc`` is an `MPL Binary Metafunction Class`_ whose first argument will +be the type of the corresponding ``argument-name``, whose second argument will +be the entire |ArgumentPack|_, and whose return type is a `Boolean Integral +Constant`_; however, user code *cannot* compute ``mfc`` in terms of +``previous-name ## _type``. +\*. ``type-name`` is either the name of a **target type** or an `MPL Binary +Metafunction Class`_ whose first argument will be the type of the +corresponding ``argument-name``, whose second argument will be the entire +|ArgumentPack|_, and whose return type is the **target type**. If +``restriction`` uses this form, then the type of the generated name +``argument-name ## _type`` will be computed in terms of the **target type**, +and the generated reference ``argument-name`` (but not its corresponding entry +in ``args``) will be cast to that type. + +.. _`Boost.Preprocessor`: ../../../preprocessor/doc/index.html +.. _`sequence`: ../../../preprocessor/doc/data/sequences.html +.. _`MPL Binary Metafunction Class`: ../../../mpl/doc/refmanual/metafunction-class.html +.. _`Boolean Integral Constant`: ../../../mpl/doc/refmanual/integral-constant.html + +Approximate expansion: +**Where**: + +* ``n`` denotes the *minimum* arity, as determined from ``arguments``. +* ``m`` denotes the *maximum* arity, as determined from ``arguments``. + +.. parsed-literal:: + + template + struct boost_param_result\_ ## __LINE__ ## operator + { + typedef **result** type; + }; + + struct boost_param_params\_ ## __LINE__ ## operator + : |parameters|_< + *list of parameter specifications, based on arguments* + > + { + }; + + typedef boost_param_params\_ ## __LINE__ ## operator + boost_param_parameters\_ ## __LINE__ ## operator; + + template + **result** operator()( + A0&& a0, …, A ## **n**\ && a ## **n** + , typename boost_param_parameters\_ ## __LINE__ ## operator::match< + A0, …, A ## **n** + >::type = boost_param_parameters\_ ## __LINE__ ## operator() + ) + { + return this->boost_param_impl ## __LINE__ ## operator( + boost_param_parameters\_ ## __LINE__ ## operator()( + std::`forward`_(a0) + , … + , std::`forward`_(a ## **n**) + ) + ); + } + + :vellipsis:`⋮` + + template + **result** operator()( + A0&& a0, …, A ## **m**\ && a ## **m** + , typename boost_param_parameters\_ ## __LINE__ ## operator::match< + A0, …, A ## **m** + >::type = boost_param_parameters\_ ## __LINE__ ## operator() + ) + { + return this->boost_param_impl ## __LINE__ ## operator( + boost_param_parameters\_ ## __LINE__ ## operator()( + std::`forward`_(a0) + , … + , std::`forward`_(a ## **m**) + ) + ); + } + + template + typename boost_param_result\_ ## __LINE__ ## operator::type + boost_param_impl ## __LINE__ ## operator(Args const& args) + { + return this->boost_param_dispatch_0boost\_ ## __LINE__ ## operator( + static_cast< + typename boost_param_result\_ ## __LINE__ ## operator< + Args + >::type(\*)() + >(std::`nullptr`_) + , args + , std::`forward`_< + typename |value_type|_< + Args + , *keyword tag type of required parameter* ## **0** + >::type + >(args[ *keyword object of required parameter* ## **0**]) + , … + , std::`forward`_< + typename |value_type|_< + Args + , *keyword tag type of required parameter* ## **n** + >::type + >(args[ *keyword object of required parameter* ## **n**]) + ); + } + + template < + typename ResultType + , typename Args + , typename *argument name* ## **0** ## _type + , … + , typename *argument name* ## **n** ## _type + > + ResultType + boost_param_dispatch_0boost\_ ## __LINE__ ## operator( + (ResultType(\*)()) + , Args const& args + , *argument name* ## **0** ## _type&& *argument name* ## **0** + , … + , *argument name* ## **n** ## _type&& *argument name* ## **n** + ) + { + return this->boost_param_dispatch_0boost\_ ## __LINE__ ## operator( + static_cast(std::`nullptr`_) + , (args, *keyword object of optional parameter* ## **n + 1** = + *default value of optional parameter* ## **n + 1** + ) + , std::`forward`_<*argument name* ## **0** ## _type>( + *argument name* ## **0** + ) + , … + , std::`forward`_<*argument name* ## **n** ## _type>( + *argument name* ## **n** + ) + , std::`forward`_< + typename |value_type|_< + Args + , *keyword tag type of optional parameter* ## **n + 1** + >::type + >(*default value of optional parameter* ## **n + 1**) + ); + } + + :vellipsis:`⋮` + + template < + typename ResultType + , typename Args + , typename *argument name* ## **0** ## _type + , … + , typename *argument name* ## **m** ## _type + > + ResultType + boost_param_dispatch_0boost\_ ## __LINE__ ## operator( + (ResultType(\*)()) + , Args const& args + , *argument name* ## **0** ## _type&& *argument name* ## **0** + , … + , *argument name* ## **m** ## _type&& *argument name* ## **m** + ) + +.. _`forward`: http\://en.cppreference.com/w/cpp/utility/forward +.. _`nullptr`: http\://en.cppreference.com/w/cpp/language/nullptr ``BOOST_PARAMETER_CONST_FUNCTION_CALL_OPERATOR(result, tag_ns, arguments)`` --------------------------------------------------------------------------- @@ -1695,17 +2744,425 @@ The |preprocessor|_ test program demonstrates proper usage of this macro. __ ../../../../boost/parameter/preprocessor.hpp -Same as ``BOOST_PARAMETER_FUNCTION_CALL_OPERATOR``, except that the overloaded -function call operators and their helper methods are ``const``-qualified. +Generates a function call operator that can take in positional arguments, +composed arguments, named arguments, and deduced arguments. -The |preprocessor|_ and |preprocessor_eval_cat_8|_ test programs demonstrate -proper usage of this macro. +:Example usage: +The return type of each of the following function templates falls under a +different value category. +.. parsed-literal:: + + template + std::`bitset`_ rvalue_bitset() + { + return std::`bitset`_(); + } + + template + std::`bitset`_ const rvalue_const_bitset() + { + return std::`bitset`_(); + } + + template + std::`bitset`_& lvalue_bitset() + { + static std::`bitset`_ lset = std::`bitset`_(); + return lset; + } + + template + std::`bitset`_ const& lvalue_const_bitset() + { + static std::`bitset`_ const clset = std::`bitset`_(); + return clset; + } + +The ``U::evaluate_category`` static member function template has a simple job: +to return the correct value category when passed in an object returned by one +of the functions defined above. Assume that +|BOOST_PARAMETER_HAS_PERFECT_FORWARDING| is defined. + +.. parsed-literal:: + + enum invoked + { + passed_by_lvalue_reference_to_const + , passed_by_lvalue_reference + , passed_by_rvalue_reference_to_const + , passed_by_rvalue_reference + }; + + struct U + { + template + static invoked evaluate_category(std::`bitset`_ const&) + { + return passed_by_lvalue_reference_to_const; + } + + template + static invoked evaluate_category(std::`bitset`_&) + { + return passed_by_lvalue_reference; + } + + template + static invoked evaluate_category(std::`bitset`_ const&&) + { + return passed_by_rvalue_reference_to_const; + } + + template + static invoked evaluate_category(std::`bitset`_&&) + { + return passed_by_rvalue_reference; + } + }; + +Define the named parameters that will comprise the argument specification that +this macro will use. Ensure that all their tag types are in the same +namespace, which is ``kw`` in this case. The identifiers with leading +underscores can be passed to the bracket operator of ``args`` to extract the +same argument to which the corresponding named parameter (without underscores) +is bound, as will be shown later. + +.. parsed-literal:: + + |BOOST_PARAMETER_NAME|_((_lrc, kw) in(lrc)) + |BOOST_PARAMETER_NAME|_((_lr, kw) in_out(lr)) + |BOOST_PARAMETER_NAME|_((_rrc, kw) in(rrc)) + |BOOST_PARAMETER_NAME|_((_rr, kw) consume(rr)) + +Use the macro as a substitute for a normal ``const`` function call operator +header. Enclose the return type ``bool`` in parentheses. For each parameter, +also enclose the expected value type in parentheses. Since the value types +are mutually exclusive, you can wrap the parameters in a ``(deduced …)`` +clause. Otherwise, just as with a normal function, the order in which you +specify the parameters determines their position. Also, just as with a normal +function, optional parameters have default values, whereas required parameters +do not. Within the function body, either simply use the parameter name or +pass the matching identifier with the leading underscore to the bracket +operator of ``args`` to extract the corresponding argument. Note that the +second method doesn't require ``std::forward`` to preserve value categories. + +.. parsed-literal:: + + struct B + { + B() + { + } + + BOOST_PARAMETER_CONST_FUNCTION_CALL_OPERATOR((bool), kw, + (deduced + (required + (lrc, (std::`bitset`_<1>)) + (lr, (std::`bitset`_<2>)) + ) + (optional + (rrc, (std::`bitset`_<3>), rvalue_const_bitset<2>()) + (rr, (std::`bitset`_<4>), rvalue_bitset<3>()) + ) + ) + ) + { + BOOST_TEST_EQ( + passed_by_lvalue_reference_to_const + , U::evaluate_category<0>(lrc) + ); + BOOST_TEST_EQ( + passed_by_lvalue_reference + , U::evaluate_category<1>(lr) + ); + BOOST_TEST_EQ( + passed_by_rvalue_reference_to_const + , U::evaluate_category<2>(std::`forward`_(rrc0)) + ); + BOOST_TEST_EQ( + passed_by_rvalue_reference + , U::evaluate_category<3>(args[_rr0]) + ); + + return true; + } + }; + +The following function calls are legal. + +.. parsed-literal:: + + B const b = B(); + b( // positional arguments + lvalue_const_bitset<0>() + , lvalue_bitset<1>() + , rvalue_const_bitset<2>() + , rvalue_bitset<3>() + ); + b( // positional arguments + lvalue_const_bitset<0>() + , lvalue_bitset<1>() + ); + b(( // composed arguments + _rr0 = rvalue_bitset<3>() + , _lrc0 = lvalue_const_bitset<0>() + , _lr0 = lvalue_bitset<1>() + , _rrc0 = rvalue_const_bitset<2>() + )); + b( // named arguments + _rr0 = rvalue_bitset<3>() + , _lrc0 = lvalue_const_bitset<0>() + , _lr0 = lvalue_bitset<1>() + , _rrc0 = rvalue_const_bitset<2>() + ); + b( // named arguments + _lr0 = lvalue_bitset<1>() + , _lrc0 = lvalue_const_bitset<0>() + ); + +Because the parameters were wrapped in a ``(deduced …)`` clause, the following +function calls are also legal. + +.. parsed-literal:: + + b( // deduced arguments + rvalue_bitset<3>() + , lvalue_const_bitset<0>() + , lvalue_bitset<1>() + , rvalue_const_bitset<2>() + ); + b( // deduced arguments + lvalue_bitset<1>() + , lvalue_const_bitset<0>() + ); + +The |preprocessor|_, |preprocessor_deduced|_, and |preprocessor_eval_cat_8|_ +test programs demonstrate proper usage of this macro. + +.. _`bitset`: http\://en.cppreference.com/w/cpp/utility/bitset +.. _`forward`: http\://en.cppreference.com/w/cpp/utility/forward .. |preprocessor| replace:: preprocessor.cpp .. _preprocessor: ../../test/preprocessor.cpp +.. |preprocessor_deduced| replace:: preprocessor_deduced.cpp +.. _preprocessor_deduced: ../../test/preprocessor_deduced.cpp .. |preprocessor_eval_cat_8| replace:: preprocessor_eval_cat_8.cpp .. _preprocessor_eval_cat_8: ../../test/preprocessor_eval_cat_8.cpp +:Macro parameters: +\*. ``result`` is the parenthesized return type of the function call operator. +\*. ``tag_namespace`` is the namespace in which the keywords used by the +function call operator resides. +\*. ``arguments`` is a `Boost.Preprocessor`_ `sequence`_ of +*argument-specifiers*, as defined below. + +:Argument specifiers syntax: +.. parsed-literal:: + + argument-specifiers ::= *specifier-group0* {*specifier-group0*\ } + + specifier-group0 ::= *specifier-group1* | + ( + '**(**' '**deduced**' + *specifier-group1* {*specifier-group1*\ } + '**)**' + ) + + specifier-group1 ::= + ( + '**(**' '**optional**' + *optional-specifier* {*optional-specifier*\ } + '**)**' + ) | ( + '**(**' '**required**' + *required-specifier* {*required-specifier*\ } + '**)**' + ) + + optional-specifier ::= + '**(**' + *argument-name* '**,**' *restriction* '**,**' *default-value* + ')' + + required-specifier ::= + '**(**' *argument-name* '**,**' *restriction* ')' + + restriction ::= + ( '**\***' '**(**' *mfc* '**)**' ) | + ( '**(**' *type-name* '**)**' ) | + '**\***' + +\*. ``argument-name`` is any valid C++ identifier. +\*. ``default-value`` is any valid C++ expression; if necessary, user code can +compute it in terms of ``previous-name ## _type``, where ``previous-name`` is +the ``argument-name`` in a previous ``specifier-group0`` or +``specifier-group1``. *This expression will be invoked exactly once.* +\*. ``mfc`` is an `MPL Binary Metafunction Class`_ whose first argument will +be the type of the corresponding ``argument-name``, whose second argument will +be the entire |ArgumentPack|_, and whose return type is a `Boolean Integral +Constant`_; however, user code *cannot* compute ``mfc`` in terms of +``previous-name ## _type``. +\*. ``type-name`` is either the name of a **target type** or an `MPL Binary +Metafunction Class`_ whose first argument will be the type of the +corresponding ``argument-name``, whose second argument will be the entire +|ArgumentPack|_, and whose return type is the **target type**. If +``restriction`` uses this form, then the type of the generated name +``argument-name ## _type`` will be computed in terms of the **target type**, +and the generated reference ``argument-name`` (but not its corresponding entry +in ``args``) will be cast to that type. + +.. _`Boost.Preprocessor`: ../../../preprocessor/doc/index.html +.. _`sequence`: ../../../preprocessor/doc/data/sequences.html +.. _`MPL Binary Metafunction Class`: ../../../mpl/doc/refmanual/metafunction-class.html +.. _`Boolean Integral Constant`: ../../../mpl/doc/refmanual/integral-constant.html + +Approximate expansion: +**Where**: + +* ``n`` denotes the *minimum* arity, as determined from ``arguments``. +* ``m`` denotes the *maximum* arity, as determined from ``arguments``. + +.. parsed-literal:: + + template + struct boost_param_result_const\_ ## __LINE__ ## operator + { + typedef **result** type; + }; + + struct boost_param_params_const\_ ## __LINE__ ## operator + : |parameters|_< + *list of parameter specifications, based on arguments* + > + { + }; + + typedef boost_param_params_const\_ ## __LINE__ ## operator + boost_param_parameters_const\_ ## __LINE__ ## operator; + + template + **result** operator()( + A0&& a0, …, A ## **n**\ && a ## **n** + , typename boost_param_parameters_const\_ ## __LINE__ ## operator + ::match::type + = boost_param_parameters_const\_ ## __LINE__ ## operator() + ) const + { + return this->boost_param_impl_const ## __LINE__ ## operator( + boost_param_parameters_const\_ ## __LINE__ ## operator()( + std::`forward`_(a0) + , … + , std::`forward`_(a ## **n**) + ) + ); + } + + :vellipsis:`⋮` + + template + **result** operator()( + A0&& a0, …, A ## **m**\ && a ## **m** + , typename boost_param_parameters_const\_ ## __LINE__ ## operator + ::match::type + = boost_param_parameters_const\_ ## __LINE__ ## operator() + ) const + { + return this->boost_param_impl_const ## __LINE__ ## operator( + boost_param_parameters_const\_ ## __LINE__ ## operator()( + std::`forward`_(a0) + , … + , std::`forward`_(a ## **m**) + ) + ); + } + + template + typename boost_param_result_const\_ ## __LINE__ ## operator::type + boost_param_impl_const ## __LINE__ ## operator(Args const& args) const + { + return this-> + boost_param_dispatch_const_0boost\_ ## __LINE__ ## operator( + static_cast< + typename boost_param_result_const\_ ## __LINE__ ## operator< + Args + >::type(\*)() + >(std::`nullptr`_) + , args + , std::`forward`_< + typename |value_type|_< + Args + , *keyword tag type of required parameter* ## **0** + >::type + >(args[ *keyword object of required parameter* ## **0**]) + , … + , std::`forward`_< + typename |value_type|_< + Args + , *keyword tag type of required parameter* ## **n** + >::type + >(args[ *keyword object of required parameter* ## **n**]) + ); + } + + template < + typename ResultType + , typename Args + , typename *argument name* ## **0** ## _type + , … + , typename *argument name* ## **n** ## _type + > + ResultType + boost_param_dispatch_const_0boost\_ ## __LINE__ ## operator( + (ResultType(\*)()) + , Args const& args + , *argument name* ## **0** ## _type&& *argument name* ## **0** + , … + , *argument name* ## **n** ## _type&& *argument name* ## **n** + ) const + { + return this-> + boost_param_dispatch_const_0boost\_ ## __LINE__ ## operator( + static_cast(std::`nullptr`_) + , (args, *keyword object of optional parameter* ## **n + 1** = + *default value of optional parameter* ## **n + 1** + ) + , std::`forward`_<*argument name* ## **0** ## _type>( + *argument name* ## **0** + ) + , … + , std::`forward`_<*argument name* ## **n** ## _type>( + *argument name* ## **n** + ) + , std::`forward`_< + typename |value_type|_< + Args + , *keyword tag type of optional parameter* ## **n + 1** + >::type + >(*default value of optional parameter* ## **n + 1**) + ); + } + + :vellipsis:`⋮` + + template < + typename ResultType + , typename Args + , typename *argument name* ## **0** ## _type + , … + , typename *argument name* ## **m** ## _type + > + ResultType + boost_param_dispatch_const_0boost\_ ## __LINE__ ## operator( + (ResultType(\*)()) + , Args const& args + , *argument name* ## **0** ## _type&& *argument name* ## **0** + , … + , *argument name* ## **m** ## _type&& *argument name* ## **m** + ) const + +.. _`forward`: http\://en.cppreference.com/w/cpp/utility/forward +.. _`nullptr`: http\://en.cppreference.com/w/cpp/language/nullptr + ``BOOST_PARAMETER_CONSTRUCTOR(cls, impl, tag_namespace, arguments)`` -------------------------------------------------------------------- @@ -1713,17 +3170,166 @@ proper usage of this macro. __ ../../../../boost/parameter/preprocessor.hpp -:Requires: ``cls`` is the name of the enclosing class. ``impl`` is the -parenthesized implementation base class for ``cls``. ``tag_namespace`` is the -namespace in which the keywords used by the function resides. ``arguments`` -is a list of *argument-specifiers*, as defined in ``BOOST_PARAMETER_FUNCTION`` -except that *optional-specifier* no longer includes *default-value*. It is up -to the delegate constructor in ``impl`` to determine the default value of all +Generates a constructor that can take in positional arguments, composed +arguments, named arguments, and deduced arguments. + +:Example usage: +Define the named parameters that will comprise the argument specification that +this macro will use. Ensure that all their tag types are in the same +namespace, which is ``tag`` by default. + +.. parsed-literal:: + + |BOOST_PARAMETER_NAME|_(y) + |BOOST_PARAMETER_NAME|_(z) + +In the base class, implement a delegate constructor template that takes in an +|ArgumentPack|_. You must pass the identifiers with leading underscores to +``args`` in order to extract the corresponding arguments. + +.. parsed-literal:: + + class char_read_base + { + int index; + char const\* key; + + public: + template + explicit char_read_base(Args const& args) + : index(args[_y]), key(args[_z]) + { + } + + |BOOST_PARAMETER_CONST_FUNCTION_CALL_OPERATOR|_((char), tag, + (deduced + (required + (y, (bool)) + (z, (std::`map`_)) + ) + ) + ) + { + return y ? ( + (z.find(this->key)->second)[this->index] + ) : this->key[this->index]; + } + }; + +Use the macro as a substitute for a normal constructor definition. Note the +lack of an explicit body. Enclose the base type in parentheses. For each +parameter, also enclose the expected value type in parentheses. Since the +value types are mutually exclusive, you can wrap the parameters in a +``(deduced …)`` clause. + +.. parsed-literal:: + + struct char_reader : public char_read_base + { + BOOST_PARAMETER_CONSTRUCTOR(char_reader, (char_read_base), tag, + (deduced + (required + (y, (int)) + (z, (char const\*)) + ) + ) + ) + }; + +The following ``char_reader`` constructor calls are legal. + +.. parsed-literal:: + + char const\* keys[] = {"foo", "bar", "baz"}; + std::`map`_ k2s; + k2s[keys[0]] = std::`string`_("qux"); + k2s[keys[1]] = std::`string`_("wmb"); + k2s[keys[2]] = std::`string`_("zxc"); + + // positional arguments + char_reader r0(0, keys[0]); + BOOST_TEST_EQ('q', (r0(true, k2s))); + BOOST_TEST_EQ('f', (r0(false, k2s))); + + // named arguments + char_reader r1(_z = keys[1], _y = 1); + BOOST_TEST_EQ('m', (r1(_z = k2s, _y = true))); + BOOST_TEST_EQ('a', (r1(_z = k2s, _y = false))); + + // deduced arguments + char_reader r2(keys[2], 2); + BOOST_TEST_EQ('c', (r2(k2s, true))); + BOOST_TEST_EQ('z', (r2(k2s, false))); + +The |preprocessor|_ and |preprocessor_deduced|_ test programs demonstrate +proper usage of this macro. + +.. _`map`: http\://en.cppreference.com/w/cpp/container/map +.. _`string`: http\://en.cppreference.com/w/cpp/string/basic_string +.. |preprocessor| replace:: preprocessor.cpp +.. _preprocessor: ../../test/preprocessor.cpp +.. |preprocessor_deduced| replace:: preprocessor_deduced.cpp +.. _preprocessor_deduced: ../../test/preprocessor_deduced.cpp +.. |preprocessor_eval_cat| replace:: preprocessor_eval_category.cpp +.. _preprocessor_eval_cat: ../../test/preprocessor_eval_category.cpp + +:Macro parameters: +\*. ``cls`` is the name of the enclosing class. +\*. ``impl`` is the parenthesized implementation base class for ``cls``. +\*. ``tag_namespace`` is the namespace in which the keywords used by the +constructor resides. +\*. ``arguments`` is a list of *argument-specifiers*, as defined below. + +:Argument specifiers syntax: +.. parsed-literal:: + + argument-specifiers ::= *specifier-group0* {*specifier-group0*\ } + + specifier-group0 ::= *specifier-group1* | + ( + '**(**' '**deduced**' + *specifier-group1* {*specifier-group1*\ } + '**)**' + ) + + specifier-group1 ::= + ( + '**(**' '**optional**' + *specifier* {*specifier*\ } + '**)**' + ) | ( + '**(**' '**required**' + *specifier* {*specifier*\ } + '**)**' + ) + + specifier ::= + '**(**' *argument-name* '**,**' *restriction* ')' + + restriction ::= + ( '**\***' '**(**' *mfc* '**)**' ) | + ( '**(**' *type-name* '**)**' ) | + '**\***' + +\*. ``argument-name`` is any valid C++ identifier. +\*. ``mfc`` is an `MPL Binary Metafunction Class`_ whose first argument will +be the type of the corresponding ``argument-name``, whose second argument will +be the entire |ArgumentPack|_, and whose return type is a `Boolean Integral +Constant`_; however, user code *cannot* compute ``mfc`` in terms of +``previous-name ## _type``. +\*. ``type-name`` is either the name of a **target type** or an `MPL Binary +Metafunction Class`_ whose first argument will be the type of the +corresponding ``argument-name``, whose second argument will be the entire +|ArgumentPack|_, and whose return type is the **target type**. + +Note that *specifier* does not include *default-value*. It is up to the +delegate constructor in ``impl`` to determine the default value of all optional arguments. -:Generated names in enclosing scope: -* ``boost_param_params_ ## __LINE__ ## ctor`` -* ``constructor_parameters ## __LINE__`` +.. _`Boost.Preprocessor`: ../../../preprocessor/doc/index.html +.. _`sequence`: ../../../preprocessor/doc/data/sequences.html +.. _`MPL Binary Metafunction Class`: ../../../mpl/doc/refmanual/metafunction-class.html +.. _`Boolean Integral Constant`: ../../../mpl/doc/refmanual/integral-constant.html Approximate expansion: **Where**: @@ -1731,23 +3337,21 @@ Approximate expansion: * ``n`` denotes the *minimum* arity, as determined from ``arguments``. * ``m`` denotes the *maximum* arity, as determined from ``arguments``. -**If** |BOOST_PARAMETER_HAS_PERFECT_FORWARDING| is ``#defined``, **then** - .. parsed-literal:: struct boost_param_params\_ ## __LINE__ ## ctor - : boost::parameter::parameters< + : |parameters|_< *list of parameter specifications, based on arguments* > { }; - typedef boost_param_params\_ ## __LINE__ ## **name** + typedef boost_param_params\_ ## __LINE__ ## ctor constructor_parameters ## __LINE__; template - *cls*\ (A0&& a0, …, A ## **n** && a ## **n**) - : *impl*\ ( + **cls**\ (A0&& a0, …, A ## **n** && a ## **n**) + : **impl**\ ( constructor_parameters ## __LINE__( std::`forward`_(a0) , … @@ -1760,8 +3364,8 @@ Approximate expansion: :vellipsis:`⋮` template - *cls*\ (A0&& a0, …, A ## **m** && a ## **m**) - : *impl*\ ( + **cls**\ (A0&& a0, …, A ## **m** && a ## **m**) + : **impl**\ ( constructor_parameters ## __LINE__( std::`forward`_(a0) , … @@ -1771,61 +3375,7 @@ Approximate expansion: { } -**If** |BOOST_PARAMETER_HAS_PERFECT_FORWARDING| is **not** ``#defined``, -**then** - -.. parsed-literal:: - - struct boost_param_params\_ ## __LINE__ ## ctor - : boost::parameter::parameters< - *list of parameter specifications, based on arguments* - > - { - }; - - typedef boost_param_params\_ ## __LINE__ ## **name** - constructor_parameters ## __LINE__; - - template - *cls*\ (A0 const& a0, …, A ## **n** const& a ## **n**) - : *impl*\ (constructor_parameters ## __LINE__(a0, …, a ## **n**)) - { - } - - *… exponential number of overloads …* - :vellipsis:`⋮` - - template - *cls*\ (A0& a0, …, A ## **n** & a ## **n**) - : *impl*\ (constructor_parameters ## __LINE__(a0, …, a ## **n**)) - { - } - - :vellipsis:`⋮` - - template - *cls*\ (A0 const& a0, …, A ## **m** const& a ## **m**) - : *impl*\ (constructor_parameters ## __LINE__(a0, …, a ## **m**)) - { - } - - *… exponential number of overloads …* - :vellipsis:`⋮` - - template - *cls*\ (A0& a0, …, A ## **m** & a ## **m**) - : *impl*\ (constructor_parameters ## __LINE__(a0, …, a ## **m**)) - { - } - -The |preprocessor|_ and |preprocessor_eval_cat|_ test programs demonstrate -proper usage of this macro. - .. _`forward`: http\://en.cppreference.com/w/cpp/utility/forward -.. |preprocessor| replace:: preprocessor.cpp -.. _preprocessor: ../../test/preprocessor.cpp -.. |preprocessor_eval_cat| replace:: preprocessor_eval_category.cpp -.. _preprocessor_eval_cat: ../../test/preprocessor_eval_category.cpp ``BOOST_PARAMETER_BASIC_FUNCTION(result, name, tag_namespace, arguments)`` -------------------------------------------------------------------------- @@ -1834,28 +3384,331 @@ proper usage of this macro. __ ../../../../boost/parameter/preprocessor.hpp -Same as ``BOOST_PARAMETER_FUNCTION``, except: +Generates a function that can take in positional arguments, composed +arguments, named arguments, and deduced arguments. -\*. For the argument specifiers syntax, *optional-specifier* no longer -includes *default-value*. It is up to the function body to determine the -default value of all optional arguments. +:Example usage: +The return type of each of the following function templates falls under a +different value category. -\*. Generated names in the enclosing scope no longer include -``boost_param_dispatch_0boost_ ## __LINE__ ## name`` or -``boost_param_dispatch_1boost_ ## __LINE__ ## name``. +.. parsed-literal:: -\*. Expansion of this macro omits all overloads of -``boost_param_dispatch_0boost_ ## __LINE__ ## name`` and -``boost_param_dispatch_1boost_ ## __LINE__ ## name`` and stops at the header -of ``boost_param_impl ## name``. Therefore, only the |ArgumentPack|_ type -``Args`` and its object instance ``args`` are available for use within the -function body. + template + std::`bitset`_ rvalue_bitset() + { + return std::`bitset`_(); + } + + template + std::`bitset`_ const rvalue_const_bitset() + { + return std::`bitset`_(); + } + + template + std::`bitset`_& lvalue_bitset() + { + static std::`bitset`_ lset = std::`bitset`_(); + return lset; + } + + template + std::`bitset`_ const& lvalue_const_bitset() + { + static std::`bitset`_ const clset = std::`bitset`_(); + return clset; + } + +The ``U::evaluate_category`` static member function template has a simple job: +to return the correct value category when passed in an object returned by one +of the functions defined above. Assume that +|BOOST_PARAMETER_HAS_PERFECT_FORWARDING| is defined. + +.. parsed-literal:: + + enum invoked + { + passed_by_lvalue_reference_to_const + , passed_by_lvalue_reference + , passed_by_rvalue_reference_to_const + , passed_by_rvalue_reference + }; + + struct U + { + template + static invoked evaluate_category(std::`bitset`_ const&) + { + return passed_by_lvalue_reference_to_const; + } + + template + static invoked evaluate_category(std::`bitset`_&) + { + return passed_by_lvalue_reference; + } + + template + static invoked evaluate_category(std::`bitset`_ const&&) + { + return passed_by_rvalue_reference_to_const; + } + + template + static invoked evaluate_category(std::`bitset`_&&) + { + return passed_by_rvalue_reference; + } + }; + +Define the named parameters that will comprise the argument specification that +this macro will use. Ensure that all their tag types are in the same +namespace, which is ``kw`` in this case. The identifiers with leading +underscores can be passed to the bracket operator of ``args`` to extract the +same argument to which the corresponding named parameter (without underscores) +is bound, as will be shown later. + +.. parsed-literal:: + + |BOOST_PARAMETER_NAME|_((_lrc, kw) in(lrc)) + |BOOST_PARAMETER_NAME|_((_lr, kw) in_out(lr)) + |BOOST_PARAMETER_NAME|_((_rrc, kw) in(rrc)) + |BOOST_PARAMETER_NAME|_((_rr, kw) consume(rr)) + +Use the macro as a substitute for a normal function header. Enclose the +return type ``bool`` in parentheses. For each parameter, also enclose the +expected value type in parentheses. Since the value types are mutually +exclusive, you can wrap the parameters in a ``(deduced …)`` +clause. Otherwise, just as with a normal function, the order in which you +specify the parameters determines their position. However, unlike a normal +function, default values must be specified within the function body. Also +within the function body, you must pass the matching identifier with the +leading underscore to the bracket operator of ``args`` to extract the +corresponding argument, but at least this doesn't require ``std::forward`` to +preserve value categories. + +.. parsed-literal:: + + BOOST_PARAMETER_BASIC_FUNCTION((bool), evaluate, kw, + (deduced + (required + (lrc, (std::`bitset`_<1>)) + (lr, (std::`bitset`_<2>)) + ) + (optional + (rrc, (std::`bitset`_<3>)) + (rr, (std::`bitset`_<4>)) + ) + ) + ) + { + BOOST_TEST_EQ( + passed_by_lvalue_reference_to_const + , U::evaluate_category<0>(args[_lrc]) + ); + BOOST_TEST_EQ( + passed_by_lvalue_reference + , U::evaluate_category<1>(args[_lr]) + ); + BOOST_TEST_EQ( + passed_by_rvalue_reference_to_const + , U::evaluate_category<2>( + args[_rrc0 | rvalue_const_bitset<2>()] + ) + ); + BOOST_TEST_EQ( + passed_by_rvalue_reference + , U::evaluate_category<3>(args[_rr0 | rvalue_bitset<3>()]) + ); + + return true; + } + +The following function calls are legal. + +.. parsed-literal:: + + evaluate( // positional arguments + lvalue_const_bitset<0>() + , lvalue_bitset<1>() + , rvalue_const_bitset<2>() + , rvalue_bitset<3>() + ); + evaluate( // positional arguments + lvalue_const_bitset<0>() + , lvalue_bitset<1>() + ); + evaluate(( // composed arguments + _rr0 = rvalue_bitset<3>() + , _lrc0 = lvalue_const_bitset<0>() + , _lr0 = lvalue_bitset<1>() + , _rrc0 = rvalue_const_bitset<2>() + )); + evaluate( // named arguments + _rr0 = rvalue_bitset<3>() + , _lrc0 = lvalue_const_bitset<0>() + , _lr0 = lvalue_bitset<1>() + , _rrc0 = rvalue_const_bitset<2>() + ); + evaluate( // named arguments + _lr0 = lvalue_bitset<1>() + , _lrc0 = lvalue_const_bitset<0>() + ); + +Because the parameters were wrapped in a ``(deduced …)`` clause, the following +function calls are also legal. + +.. parsed-literal:: + + evaluate( // deduced arguments + rvalue_bitset<3>() + , lvalue_const_bitset<0>() + , lvalue_bitset<1>() + , rvalue_const_bitset<2>() + ); + evaluate( // deduced arguments + lvalue_bitset<1>() + , lvalue_const_bitset<0>() + ); The |preprocessor|_ test program demonstrates proper usage of this macro. +.. _`bitset`: http\://en.cppreference.com/w/cpp/utility/bitset .. |preprocessor| replace:: preprocessor.cpp .. _preprocessor: ../../test/preprocessor.cpp +:Macro parameters: +\*. ``result`` is the parenthesized return type of the function. +\*. ``name`` is the base name of the function; it determines the name of the +generated forwarding functions. +\*. ``tag_namespace`` is the namespace in which the keywords used by the +function resides. +\*. ``arguments`` is a `Boost.Preprocessor`_ `sequence`_ of +*argument-specifiers*, as defined below. + +:Argument specifiers syntax: +.. parsed-literal:: + + argument-specifiers ::= *specifier-group0* {*specifier-group0*\ } + + specifier-group0 ::= *specifier-group1* | + ( + '**(**' '**deduced**' + *specifier-group1* {*specifier-group1*\ } + '**)**' + ) + + specifier-group1 ::= + ( + '**(**' '**optional**' + *specifier* {*specifier*\ } + '**)**' + ) | ( + '**(**' '**required**' + *specifier* {*specifier*\ } + '**)**' + ) + + specifier ::= + '**(**' *argument-name* '**,**' *restriction* ')' + + restriction ::= + ( '**\***' '**(**' *mfc* '**)**' ) | + ( '**(**' *type-name* '**)**' ) | + '**\***' + +\*. ``argument-name`` is any valid C++ identifier. +\*. ``mfc`` is an `MPL Binary Metafunction Class`_ whose first argument will +be the type of the corresponding ``argument-name``, whose second argument will +be the entire |ArgumentPack|_, and whose return type is a `Boolean Integral +Constant`_; however, user code *cannot* compute ``mfc`` in terms of +``previous-name ## _type``. +\*. ``type-name`` is either the name of a **target type** or an `MPL Binary +Metafunction Class`_ whose first argument will be the type of the +corresponding ``argument-name``, whose second argument will be the entire +|ArgumentPack|_, and whose return type is the **target type**. + +Note that *specifier* does not include *default-value*. It is up to the +function body to determine the default value of all optional arguments. + +.. _`Boost.Preprocessor`: ../../../preprocessor/doc/index.html +.. _`sequence`: ../../../preprocessor/doc/data/sequences.html +.. _`MPL Binary Metafunction Class`: ../../../mpl/doc/refmanual/metafunction-class.html +.. _`Boolean Integral Constant`: ../../../mpl/doc/refmanual/integral-constant.html + +Approximate expansion: +**Where**: + +* ``n`` denotes the *minimum* arity, as determined from ``arguments``. +* ``m`` denotes the *maximum* arity, as determined from ``arguments``. + +.. parsed-literal:: + + template + struct boost_param_result\_ ## __LINE__ ## **name** + { + typedef **result** type; + }; + + struct boost_param_params\_ ## __LINE__ ## **name** + : |parameters|_< + *list of parameter specifications, based on arguments* + > + { + }; + + typedef boost_param_params\_ ## __LINE__ ## **name** + boost_param_parameters\_ ## __LINE__ ## **name**; + + template + typename boost_param_result\_ ## __LINE__ ## **name**\ ::type + boost_param_impl ## **name**\ (Args const&); + + template + **result** **name**\ ( + A0&& a0, …, A ## **n**\ && a ## **n** + , typename boost_param_parameters\_ ## __LINE__ ## **name** + ::match::type + = boost_param_parameters\_ ## __LINE__ ## **name**\ () + ) + { + return boost_param_impl ## __LINE__ ## **name**\ ( + boost_param_parameters\_ ## __LINE__ ## **name**\ ()( + std::`forward`_(a0) + , … + , std::`forward`_(a ## **n**) + ) + ); + } + + :vellipsis:`⋮` + + template + **result** **name**\ ( + A0&& a0, …, A ## **m**\ && a ## **m** + , typename boost_param_parameters\_ ## __LINE__ ## **name** + ::match::type + = boost_param_parameters\_ ## __LINE__ ## **name**\ () + ) + { + return boost_param_impl ## __LINE__ ## **name**\ ( + boost_param_parameters\_ ## __LINE__ ## **name**\ ()( + std::`forward`_(a0) + , … + , std::`forward`_(a ## **m**) + ) + ); + } + + template + typename boost_param_result\_ ## __LINE__ ## **name**\ ::type + boost_param_impl ## __LINE__ ## **name**\ (Args const& args) + +Only the |ArgumentPack|_ type ``Args`` and its object instance ``args`` are +available for use within the function body. + +.. _`forward`: http\://en.cppreference.com/w/cpp/utility/forward + ``BOOST_PARAMETER_BASIC_MEMBER_FUNCTION(result, name, tag_ns, arguments)`` -------------------------------------------------------------------------- @@ -1863,20 +3716,335 @@ The |preprocessor|_ test program demonstrates proper usage of this macro. __ ../../../../boost/parameter/preprocessor.hpp -Same as ``BOOST_PARAMETER_BASIC_FUNCTION``, except that: +Generates a member function that can take in positional arguments, composed +arguments, named arguments, and deduced arguments. -\*. ``name`` may be qualified by the ``static`` keyword to declare the member -function and its helpers as not associated with any object of the enclosing -type. +:Example usage: +The return type of each of the following function templates falls under a +different value category. -\*. Expansion of this macro omits the forward declaration of the -implementation function. +.. parsed-literal:: + + template + std::`bitset`_ rvalue_bitset() + { + return std::`bitset`_(); + } + + template + std::`bitset`_ const rvalue_const_bitset() + { + return std::`bitset`_(); + } + + template + std::`bitset`_& lvalue_bitset() + { + static std::`bitset`_ lset = std::`bitset`_(); + return lset; + } + + template + std::`bitset`_ const& lvalue_const_bitset() + { + static std::`bitset`_ const clset = std::`bitset`_(); + return clset; + } + +The ``U::evaluate_category`` static member function template has a simple job: +to return the correct value category when passed in an object returned by one +of the functions defined above. Assume that +|BOOST_PARAMETER_HAS_PERFECT_FORWARDING| is defined. + +.. parsed-literal:: + + enum invoked + { + passed_by_lvalue_reference_to_const + , passed_by_lvalue_reference + , passed_by_rvalue_reference_to_const + , passed_by_rvalue_reference + }; + + struct U + { + template + static invoked evaluate_category(std::`bitset`_ const&) + { + return passed_by_lvalue_reference_to_const; + } + + template + static invoked evaluate_category(std::`bitset`_&) + { + return passed_by_lvalue_reference; + } + + template + static invoked evaluate_category(std::`bitset`_ const&&) + { + return passed_by_rvalue_reference_to_const; + } + + template + static invoked evaluate_category(std::`bitset`_&&) + { + return passed_by_rvalue_reference; + } + }; + +Define the named parameters that will comprise the argument specification that +this macro will use. Ensure that all their tag types are in the same +namespace, which is ``kw`` in this case. The identifiers with leading +underscores can be passed to the bracket operator of ``args`` to extract the +same argument to which the corresponding named parameter (without underscores) +is bound, as will be shown later. + +.. parsed-literal:: + + |BOOST_PARAMETER_NAME|_((_lrc, kw) in(lrc)) + |BOOST_PARAMETER_NAME|_((_lr, kw) in_out(lr)) + |BOOST_PARAMETER_NAME|_((_rrc, kw) in(rrc)) + |BOOST_PARAMETER_NAME|_((_rr, kw) consume(rr)) + +Use the macro as a substitute for a normal ``static`` member function +header. Enclose the return type ``bool`` in parentheses. For each parameter, +also enclose the expected value type in parentheses. Since the value types +are mutually exclusive, you can wrap the parameters in a ``(deduced …)`` +clause. Otherwise, just as with a normal function, the order in which you +specify the parameters determines their position. However, unlike a normal +function, default values must be specified within the function body. Also +within the function body, you must pass the matching identifier with the +leading underscore to the bracket operator of ``args`` to extract the +corresponding argument, but at least this doesn't require ``std::forward`` to +preserve value categories. + +.. parsed-literal:: + + struct B + { + BOOST_PARAMETER_BASIC_MEMBER_FUNCTION((bool), static evaluate, kw, + (deduced + (required + (lrc, (std::`bitset`_<1>)) + (lr, (std::`bitset`_<2>)) + ) + (optional + (rrc, (std::`bitset`_<3>)) + (rr, (std::`bitset`_<4>)) + ) + ) + ) + { + BOOST_TEST_EQ( + passed_by_lvalue_reference_to_const + , U::evaluate_category<0>(args[_lrc]) + ); + BOOST_TEST_EQ( + passed_by_lvalue_reference + , U::evaluate_category<1>(args[_lr]) + ); + BOOST_TEST_EQ( + passed_by_rvalue_reference_to_const + , U::evaluate_category<2>( + args[_rrc0 | rvalue_const_bitset<2>()] + ) + ); + BOOST_TEST_EQ( + passed_by_rvalue_reference + , U::evaluate_category<3>( + args[_rr0 | rvalue_bitset<3>()] + ) + ); + + return true; + } + }; + +The following function calls are legal. + +.. parsed-literal:: + + B::evaluate( // positional arguments + lvalue_const_bitset<0>() + , lvalue_bitset<1>() + , rvalue_const_bitset<2>() + , rvalue_bitset<3>() + ); + B::evaluate( // positional arguments + lvalue_const_bitset<0>() + , lvalue_bitset<1>() + ); + B::evaluate(( // composed arguments + _rr0 = rvalue_bitset<3>() + , _lrc0 = lvalue_const_bitset<0>() + , _lr0 = lvalue_bitset<1>() + , _rrc0 = rvalue_const_bitset<2>() + )); + B::evaluate( // named arguments + _rr0 = rvalue_bitset<3>() + , _lrc0 = lvalue_const_bitset<0>() + , _lr0 = lvalue_bitset<1>() + , _rrc0 = rvalue_const_bitset<2>() + ); + B::evaluate( // named arguments + _lr0 = lvalue_bitset<1>() + , _lrc0 = lvalue_const_bitset<0>() + ); + +Because the parameters were wrapped in a ``(deduced …)`` clause, the following +function calls are also legal. + +.. parsed-literal:: + + B::evaluate( // deduced arguments + rvalue_bitset<3>() + , lvalue_const_bitset<0>() + , lvalue_bitset<1>() + , rvalue_const_bitset<2>() + ); + B::evaluate( // deduced arguments + lvalue_bitset<1>() + , lvalue_const_bitset<0>() + ); The |preprocessor|_ test program demonstrates proper usage of this macro. +.. _`bitset`: http\://en.cppreference.com/w/cpp/utility/bitset +.. _`forward`: http\://en.cppreference.com/w/cpp/utility/forward .. |preprocessor| replace:: preprocessor.cpp .. _preprocessor: ../../test/preprocessor.cpp +:Macro parameters: +\*. ``result`` is the parenthesized return type of the function. +\*. ``name`` is the base name of the function; it determines the name of the +generated forwarding functions. ``name`` may be qualified by the ``static`` +keyword to declare the member function and its helpers as not associated with +any object of the enclosing type. +\*. ``tag_namespace`` is the namespace in which the keywords used by the +function resides. +\*. ``arguments`` is a `Boost.Preprocessor`_ `sequence`_ of +*argument-specifiers*, as defined below. + +:Argument specifiers syntax: +.. parsed-literal:: + + argument-specifiers ::= *specifier-group0* {*specifier-group0*\ } + + specifier-group0 ::= *specifier-group1* | + ( + '**(**' '**deduced**' + *specifier-group1* {*specifier-group1*\ } + '**)**' + ) + + specifier-group1 ::= + ( + '**(**' '**optional**' + *specifier* {*specifier*\ } + '**)**' + ) | ( + '**(**' '**required**' + *specifier* {*specifier*\ } + '**)**' + ) + + specifier ::= + '**(**' *argument-name* '**,**' *restriction* ')' + + restriction ::= + ( '**\***' '**(**' *mfc* '**)**' ) | + ( '**(**' *type-name* '**)**' ) | + '**\***' + +\*. ``argument-name`` is any valid C++ identifier. +\*. ``mfc`` is an `MPL Binary Metafunction Class`_ whose first argument will +be the type of the corresponding ``argument-name``, whose second argument will +be the entire |ArgumentPack|_, and whose return type is a `Boolean Integral +Constant`_; however, user code *cannot* compute ``mfc`` in terms of +``previous-name ## _type``. +\*. ``type-name`` is either the name of a **target type** or an `MPL Binary +Metafunction Class`_ whose first argument will be the type of the +corresponding ``argument-name``, whose second argument will be the entire +|ArgumentPack|_, and whose return type is the **target type**. + +Note that *specifier* does not include *default-value*. It is up to the +function body to determine the default value of all optional arguments. + +.. _`Boost.Preprocessor`: ../../../preprocessor/doc/index.html +.. _`sequence`: ../../../preprocessor/doc/data/sequences.html +.. _`MPL Binary Metafunction Class`: ../../../mpl/doc/refmanual/metafunction-class.html +.. _`Boolean Integral Constant`: ../../../mpl/doc/refmanual/integral-constant.html + +Approximate expansion: +**Where**: + +* ``n`` denotes the *minimum* arity, as determined from ``arguments``. +* ``m`` denotes the *maximum* arity, as determined from ``arguments``. + +.. parsed-literal:: + + template + struct boost_param_result\_ ## __LINE__ ## **name** + { + typedef **result** type; + }; + + struct boost_param_params\_ ## __LINE__ ## **name** + : |parameters|_< + *list of parameter specifications, based on arguments* + > + { + }; + + typedef boost_param_params\_ ## __LINE__ ## **name** + boost_param_parameters\_ ## __LINE__ ## **name**; + + template + **result** **name**\ ( + A0&& a0, …, A ## **n**\ && a ## **n** + , typename boost_param_parameters\_ ## __LINE__ ## **name** + ::match::type + = boost_param_parameters\_ ## __LINE__ ## **name**\ () + ) + { + return this->boost_param_impl ## **name**\ ( + boost_param_parameters\_ ## __LINE__ ## **name**\ ()( + std::`forward`_(a0) + , … + , std::`forward`_(a ## **n**) + ) + ); + } + + :vellipsis:`⋮` + + template + **result** **name**\ ( + A0&& a0, …, A ## **m**\ && a ## **m** + , typename boost_param_parameters\_ ## __LINE__ ## **name** + ::match::type + = boost_param_parameters\_ ## __LINE__ ## **name**\ () + ) + { + return this->boost_param_impl ## **name**\ ( + boost_param_parameters\_ ## __LINE__ ## **name**\ ()( + std::`forward`_(a0) + , … + , std::`forward`_(a ## **m**) + ) + ); + } + + template + typename boost_param_result\_ ## __LINE__ ## **name**\ ::type + boost_param_impl ## **name**\ (Args const& args) + +Only the |ArgumentPack|_ type ``Args`` and its object instance ``args`` are +available for use within the function body. + +.. _`forward`: http\://en.cppreference.com/w/cpp/utility/forward + ``BOOST_PARAMETER_BASIC_CONST_MEMBER_FUNCTION(result, name, tag_ns, args)`` --------------------------------------------------------------------------- @@ -1884,14 +4052,2249 @@ The |preprocessor|_ test program demonstrates proper usage of this macro. __ ../../../../boost/parameter/preprocessor.hpp -Same as ``BOOST_PARAMETER_BASIC_MEMBER_FUNCTION``, except that the overloaded -forwarding member functions and their helper methods are ``const``-qualified. +Generates a member function that can take in positional arguments, composed +arguments, named arguments, and deduced arguments. + +:Example usage: +The return type of each of the following function templates falls under a +different value category. + +.. parsed-literal:: + + template + std::`bitset`_ rvalue_bitset() + { + return std::`bitset`_(); + } + + template + std::`bitset`_ const rvalue_const_bitset() + { + return std::`bitset`_(); + } + + template + std::`bitset`_& lvalue_bitset() + { + static std::`bitset`_ lset = std::`bitset`_(); + return lset; + } + + template + std::`bitset`_ const& lvalue_const_bitset() + { + static std::`bitset`_ const clset = std::`bitset`_(); + return clset; + } + +The ``U::evaluate_category`` static member function template has a simple job: +to return the correct value category when passed in an object returned by one +of the functions defined above. Assume that +|BOOST_PARAMETER_HAS_PERFECT_FORWARDING| is defined. + +.. parsed-literal:: + + enum invoked + { + passed_by_lvalue_reference_to_const + , passed_by_lvalue_reference + , passed_by_rvalue_reference_to_const + , passed_by_rvalue_reference + }; + + struct U + { + template + static invoked evaluate_category(std::`bitset`_ const&) + { + return passed_by_lvalue_reference_to_const; + } + + template + static invoked evaluate_category(std::`bitset`_&) + { + return passed_by_lvalue_reference; + } + + template + static invoked evaluate_category(std::`bitset`_ const&&) + { + return passed_by_rvalue_reference_to_const; + } + + template + static invoked evaluate_category(std::`bitset`_&&) + { + return passed_by_rvalue_reference; + } + }; + +Define the named parameters that will comprise the argument specification that +this macro will use. Ensure that all their tag types are in the same +namespace, which is ``kw`` in this case. The identifiers with leading +underscores can be passed to the bracket operator of ``args`` to extract the +same argument to which the corresponding named parameter (without underscores) +is bound, as will be shown later. + +.. parsed-literal:: + + |BOOST_PARAMETER_NAME|_((_lrc, kw) in(lrc)) + |BOOST_PARAMETER_NAME|_((_lr, kw) in_out(lr)) + |BOOST_PARAMETER_NAME|_((_rrc, kw) in(rrc)) + |BOOST_PARAMETER_NAME|_((_rr, kw) consume(rr)) + +Use the macro as a substitute for a normal ``const`` member function +header. Enclose the return type ``bool`` in parentheses. For each parameter, +also enclose the expected value type in parentheses. Since the value types +are mutually exclusive, you can wrap the parameters in a ``(deduced …)`` +clause. Otherwise, just as with a normal function, the order in which you +specify the parameters determines their position. However, unlike a normal +function, default values must be specified within the function body. Also +within the function body, you must pass the matching identifier with the +leading underscore to the bracket operator of ``args`` to extract the +corresponding argument, but at least this doesn't require ``std::forward`` to +preserve value categories. + +.. parsed-literal:: + + struct B + { + B() + { + } + + BOOST_PARAMETER_BASIC_CONST_MEMBER_FUNCTION((bool), evaluate, kw, + (deduced + (required + (lrc, (std::`bitset`_<1>)) + (lr, (std::`bitset`_<2>)) + ) + (optional + (rrc, (std::`bitset`_<3>)) + (rr, (std::`bitset`_<4>)) + ) + ) + ) + { + BOOST_TEST_EQ( + passed_by_lvalue_reference_to_const + , U::evaluate_category<0>(args[_lrc]) + ); + BOOST_TEST_EQ( + passed_by_lvalue_reference + , U::evaluate_category<1>(args[_lr]) + ); + BOOST_TEST_EQ( + passed_by_rvalue_reference_to_const + , U::evaluate_category<2>( + args[_rrc0 | rvalue_const_bitset<2>()] + ) + ); + BOOST_TEST_EQ( + passed_by_rvalue_reference + , U::evaluate_category<3>( + args[_rr0 | rvalue_bitset<3>()] + ) + ); + + return true; + } + }; + +The following function calls are legal. + +.. parsed-literal:: + + B const b = B(); + b.evaluate( // positional arguments + lvalue_const_bitset<0>() + , lvalue_bitset<1>() + , rvalue_const_bitset<2>() + , rvalue_bitset<3>() + ); + b.evaluate( // positional arguments + lvalue_const_bitset<0>() + , lvalue_bitset<1>() + ); + b.evaluate(( // composed arguments + _rr0 = rvalue_bitset<3>() + , _lrc0 = lvalue_const_bitset<0>() + , _lr0 = lvalue_bitset<1>() + , _rrc0 = rvalue_const_bitset<2>() + )); + b.evaluate( // named arguments + _rr0 = rvalue_bitset<3>() + , _lrc0 = lvalue_const_bitset<0>() + , _lr0 = lvalue_bitset<1>() + , _rrc0 = rvalue_const_bitset<2>() + ); + b.evaluate( // named arguments + _lr0 = lvalue_bitset<1>() + , _lrc0 = lvalue_const_bitset<0>() + ); + +Because the parameters were wrapped in a ``(deduced …)`` clause, the following +function calls are also legal. + +.. parsed-literal:: + + b.evaluate( // deduced arguments + rvalue_bitset<3>() + , lvalue_const_bitset<0>() + , lvalue_bitset<1>() + , rvalue_const_bitset<2>() + ); + b.evaluate( // deduced arguments + lvalue_bitset<1>() + , lvalue_const_bitset<0>() + ); The |preprocessor|_ test program demonstrates proper usage of this macro. +.. _`bitset`: http\://en.cppreference.com/w/cpp/utility/bitset +.. _`forward`: http\://en.cppreference.com/w/cpp/utility/forward .. |preprocessor| replace:: preprocessor.cpp .. _preprocessor: ../../test/preprocessor.cpp +:Macro parameters: +\*. ``result`` is the parenthesized return type of the function. +\*. ``name`` is the base name of the function; it determines the name of the +generated forwarding functions. +\*. ``tag_namespace`` is the namespace in which the keywords used by the +function resides. +\*. ``arguments`` is a `Boost.Preprocessor`_ `sequence`_ of +*argument-specifiers*, as defined below. + +:Argument specifiers syntax: +.. parsed-literal:: + + argument-specifiers ::= *specifier-group0* {*specifier-group0*\ } + + specifier-group0 ::= *specifier-group1* | + ( + '**(**' '**deduced**' + *specifier-group1* {*specifier-group1*\ } + '**)**' + ) + + specifier-group1 ::= + ( + '**(**' '**optional**' + *specifier* {*specifier*\ } + '**)**' + ) | ( + '**(**' '**required**' + *specifier* {*specifier*\ } + '**)**' + ) + + specifier ::= + '**(**' *argument-name* '**,**' *restriction* ')' + + restriction ::= + ( '**\***' '**(**' *mfc* '**)**' ) | + ( '**(**' *type-name* '**)**' ) | + '**\***' + +\*. ``argument-name`` is any valid C++ identifier. +\*. ``mfc`` is an `MPL Binary Metafunction Class`_ whose first argument will +be the type of the corresponding ``argument-name``, whose second argument will +be the entire |ArgumentPack|_, and whose return type is a `Boolean Integral +Constant`_; however, user code *cannot* compute ``mfc`` in terms of +``previous-name ## _type``. +\*. ``type-name`` is either the name of a **target type** or an `MPL Binary +Metafunction Class`_ whose first argument will be the type of the +corresponding ``argument-name``, whose second argument will be the entire +|ArgumentPack|_, and whose return type is the **target type**. + +Note that *specifier* does not include *default-value*. It is up to the +function body to determine the default value of all optional arguments. + +.. _`Boost.Preprocessor`: ../../../preprocessor/doc/index.html +.. _`sequence`: ../../../preprocessor/doc/data/sequences.html +.. _`MPL Binary Metafunction Class`: ../../../mpl/doc/refmanual/metafunction-class.html +.. _`Boolean Integral Constant`: ../../../mpl/doc/refmanual/integral-constant.html + +Approximate expansion: +**Where**: + +* ``n`` denotes the *minimum* arity, as determined from ``arguments``. +* ``m`` denotes the *maximum* arity, as determined from ``arguments``. + +.. parsed-literal:: + + template + struct boost_param_result_const\_ ## __LINE__ ## **name** + { + typedef **result** type; + }; + + struct boost_param_params_const\_ ## __LINE__ ## **name** + : |parameters|_< + *list of parameter specifications, based on arguments* + > + { + }; + + typedef boost_param_params_const\_ ## __LINE__ ## **name** + boost_param_parameters_const\_ ## __LINE__ ## **name**; + + template + **result** **name**\ ( + A0&& a0, …, A ## **n**\ && a ## **n** + , typename boost_param_parameters_const\_ ## __LINE__ ## **name** + ::match::type + = boost_param_parameters_const\_ ## __LINE__ ## **name**\ () + ) const + { + return this->boost_param_impl_const ## __LINE__ ## **name**\ ( + boost_param_parameters_const\_ ## __LINE__ ## **name**\ ()( + std::`forward`_(a0) + , … + , std::`forward`_(a ## **n**) + ) + ); + } + + :vellipsis:`⋮` + + template + **result** **name**\ ( + A0&& a0, …, A ## **m**\ && a ## **m** + , typename boost_param_parameters_const\_ ## __LINE__ ## **name** + ::match::type + = boost_param_parameters_const\_ ## __LINE__ ## **name**\ () + ) const + { + return this->boost_param_impl_const ## __LINE__ ## **name**\ ( + boost_param_parameters_const\_ ## __LINE__ ## **name**\ ()( + std::`forward`_(a0) + , … + , std::`forward`_(a ## **m**) + ) + ); + } + + template + typename boost_param_result_const\_ ## __LINE__ ## **name**\ ::type + boost_param_impl_const ## __LINE__ ## **name**\ (Args const& args) const + +Only the |ArgumentPack|_ type ``Args`` and its object instance ``args`` are +available for use within the function body. + +.. _`forward`: http\://en.cppreference.com/w/cpp/utility/forward + +``BOOST_PARAMETER_BASIC_FUNCTION_CALL_OPERATOR(result, tag_ns, arguments)`` +--------------------------------------------------------------------------- + +:Defined in: `boost/parameter/preprocessor.hpp`__ + +__ ../../../../boost/parameter/preprocessor.hpp + +Generates a function call operator that can take in positional arguments, +composed arguments, named arguments, and deduced arguments. + +:Example usage: +Define the named parameters that will comprise the argument specification that +this macro will use. Ensure that all their tag types are in the same +namespace, which is ``tag`` by default. + +.. parsed-literal:: + + |BOOST_PARAMETER_NAME|_(y) + |BOOST_PARAMETER_NAME|_(z) + +Use the macro as a substitute for a normal function call operator +header. Enclose the return type in parentheses. For each parameter, also +enclose the expected value type in parentheses. Since the value types are +mutually exclusive, you can wrap the parameters in a ``(deduced …)`` +clause. This is especially useful when implementing multiple +Boost.Parameter-enabled function call operator overloads. + +.. parsed-literal:: + + class char_reader + { + int index; + char const\* key; + + public: + explicit char_reader(char const\* k) : index(0), key(k) + { + } + + BOOST_PARAMETER_BASIC_FUNCTION_CALL_OPERATOR((void), tag, + (deduced + (required + (y, (int)) + (z, (char const\*)) + ) + ) + ) + { + this->index = args[_y]; + this->key = args[_z]; + } + + |BOOST_PARAMETER_BASIC_CONST_FUNCTION_CALL_OPERATOR|_((char), tag, + (deduced + (required + (y, (bool)) + (z, (std::`map`_)) + ) + ) + ) + { + return args[_y] ? ( + (args[_z].find(this->key)->second)[this->index] + ) : this->key[this->index]; + } + }; + +As with regular argument-dependent lookup, the value types of the arguments +passed in determine which function call operator overload gets invoked. + +.. parsed-literal:: + + char const* keys[] = {"foo", "bar", "baz"}; + std::`map`_ k2s; + k2s[keys[0]] = std::`string`_("qux"); + k2s[keys[1]] = std::`string`_("wmb"); + k2s[keys[2]] = std::`string`_("zxc"); + char_reader r(keys[0]); + + // positional arguments + BOOST_TEST_EQ('q', (r(true, k2s))); + BOOST_TEST_EQ('f', (r(false, k2s))); + + // named arguments + r(_z = keys[1], _y = 1); + BOOST_TEST_EQ('m', (r(_z = k2s, _y = true))); + BOOST_TEST_EQ('a', (r(_z = k2s, _y = false))); + + // deduced arguments + r(keys[2], 2); + BOOST_TEST_EQ('c', (r(k2s, true))); + BOOST_TEST_EQ('z', (r(k2s, false))); + +The |preprocessor|_ test program demonstrates proper usage of this macro. + +.. _`map`: http\://en.cppreference.com/w/cpp/container/map +.. _`string`: http\://en.cppreference.com/w/cpp/string/basic_string +.. |preprocessor| replace:: preprocessor.cpp +.. _preprocessor: ../../test/preprocessor.cpp + +:Macro parameters: +\*. ``result`` is the parenthesized return type of the function call operator. +\*. ``tag_namespace`` is the namespace in which the keywords used by the +function call operator resides. +\*. ``arguments`` is a `Boost.Preprocessor`_ `sequence`_ of +*argument-specifiers*, as defined below. + +:Argument specifiers syntax: +.. parsed-literal:: + + argument-specifiers ::= *specifier-group0* {*specifier-group0*\ } + + specifier-group0 ::= *specifier-group1* | + ( + '**(**' '**deduced**' + *specifier-group1* {*specifier-group1*\ } + '**)**' + ) + + specifier-group1 ::= + ( + '**(**' '**optional**' + *specifier* {*specifier*\ } + '**)**' + ) | ( + '**(**' '**required**' + *specifier* {*specifier*\ } + '**)**' + ) + + specifier ::= + '**(**' *argument-name* '**,**' *restriction* ')' + + restriction ::= + ( '**\***' '**(**' *mfc* '**)**' ) | + ( '**(**' *type-name* '**)**' ) | + '**\***' + +\*. ``argument-name`` is any valid C++ identifier. +\*. ``mfc`` is an `MPL Binary Metafunction Class`_ whose first argument will +be the type of the corresponding ``argument-name``, whose second argument will +be the entire |ArgumentPack|_, and whose return type is a `Boolean Integral +Constant`_; however, user code *cannot* compute ``mfc`` in terms of +``previous-name ## _type``. +\*. ``type-name`` is either the name of a **target type** or an `MPL Binary +Metafunction Class`_ whose first argument will be the type of the +corresponding ``argument-name``, whose second argument will be the entire +|ArgumentPack|_, and whose return type is the **target type**. + +Note that *specifier* does not include *default-value*. It is up to the +function body to determine the default value of all optional arguments. + +.. _`Boost.Preprocessor`: ../../../preprocessor/doc/index.html +.. _`sequence`: ../../../preprocessor/doc/data/sequences.html +.. _`MPL Binary Metafunction Class`: ../../../mpl/doc/refmanual/metafunction-class.html +.. _`Boolean Integral Constant`: ../../../mpl/doc/refmanual/integral-constant.html + +Approximate expansion: +**Where**: + +* ``n`` denotes the *minimum* arity, as determined from ``arguments``. +* ``m`` denotes the *maximum* arity, as determined from ``arguments``. + +.. parsed-literal:: + + template + struct boost_param_result\_ ## __LINE__ ## operator + { + typedef **result** type; + }; + + struct boost_param_params\_ ## __LINE__ ## operator + : |parameters|_< + *list of parameter specifications, based on arguments* + > + { + }; + + typedef boost_param_params\_ ## __LINE__ ## operator + boost_param_parameters\_ ## __LINE__ ## operator; + + template + **result** operator()( + A0&& a0, …, A ## **n**\ && a ## **n** + , typename boost_param_parameters\_ ## __LINE__ ## operator::match< + A0, …, A ## **n** + >::type = boost_param_parameters\_ ## __LINE__ ## operator() + ) + { + return this->boost_param_impl ## __LINE__ ## operator( + boost_param_parameters\_ ## __LINE__ ## operator()( + std::`forward`_(a0) + , … + , std::`forward`_(a ## **n**) + ) + ); + } + + :vellipsis:`⋮` + + template + **result** operator()( + A0&& a0, …, A ## **m**\ && a ## **m** + , typename boost_param_parameters\_ ## __LINE__ ## operator::match< + A0, …, A ## **m** + >::type = boost_param_parameters\_ ## __LINE__ ## operator() + ) + { + return this->boost_param_impl ## __LINE__ ## operator( + boost_param_parameters\_ ## __LINE__ ## operator()( + std::`forward`_(a0) + , … + , std::`forward`_(a ## **m**) + ) + ); + } + + template + typename boost_param_result\_ ## __LINE__ ## operator::type + boost_param_impl ## __LINE__ ## operator(Args const& args) + +Only the |ArgumentPack|_ type ``Args`` and its object instance ``args`` are +available for use within the function call operator body. + +.. _`forward`: http\://en.cppreference.com/w/cpp/utility/forward + +``BOOST_PARAMETER_BASIC_CONST_FUNCTION_CALL_OPERATOR(result, tag_ns, args)`` +---------------------------------------------------------------------------- + +:Defined in: `boost/parameter/preprocessor.hpp`__ + +__ ../../../../boost/parameter/preprocessor.hpp + +Generates a function call operator that can take in positional arguments, +composed arguments, named arguments, and deduced arguments. + +:Example usage: +The return type of each of the following function templates falls under a +different value category. + +.. parsed-literal:: + + template + std::`bitset`_ rvalue_bitset() + { + return std::`bitset`_(); + } + + template + std::`bitset`_ const rvalue_const_bitset() + { + return std::`bitset`_(); + } + + template + std::`bitset`_& lvalue_bitset() + { + static std::`bitset`_ lset = std::`bitset`_(); + return lset; + } + + template + std::`bitset`_ const& lvalue_const_bitset() + { + static std::`bitset`_ const clset = std::`bitset`_(); + return clset; + } + +The ``U::evaluate_category`` static member function template has a simple job: +to return the correct value category when passed in an object returned by one +of the functions defined above. Assume that +|BOOST_PARAMETER_HAS_PERFECT_FORWARDING| is defined. + +.. parsed-literal:: + + enum invoked + { + passed_by_lvalue_reference_to_const + , passed_by_lvalue_reference + , passed_by_rvalue_reference_to_const + , passed_by_rvalue_reference + }; + + struct U + { + template + static invoked evaluate_category(std::`bitset`_ const&) + { + return passed_by_lvalue_reference_to_const; + } + + template + static invoked evaluate_category(std::`bitset`_&) + { + return passed_by_lvalue_reference; + } + + template + static invoked evaluate_category(std::`bitset`_ const&&) + { + return passed_by_rvalue_reference_to_const; + } + + template + static invoked evaluate_category(std::`bitset`_&&) + { + return passed_by_rvalue_reference; + } + }; + +Define the named parameters that will comprise the argument specification that +this macro will use. Ensure that all their tag types are in the same +namespace, which is ``kw`` in this case. The identifiers with leading +underscores can be passed to the bracket operator of ``args`` to extract the +same argument to which the corresponding named parameter (without underscores) +is bound, as will be shown later. + +.. parsed-literal:: + + |BOOST_PARAMETER_NAME|_((_lrc, kw) in(lrc)) + |BOOST_PARAMETER_NAME|_((_lr, kw) in_out(lr)) + |BOOST_PARAMETER_NAME|_((_rrc, kw) in(rrc)) + |BOOST_PARAMETER_NAME|_((_rr, kw) consume(rr)) + +Use the macro as a substitute for a normal ``const`` function call operator +header. Enclose the return type ``bool`` in parentheses. For each parameter, +also enclose the expected value type in parentheses. Since the value types +are mutually exclusive, you can wrap the parameters in a ``(deduced …)`` +clause. Otherwise, just as with a normal function, the order in which you +specify the parameters determines their position. However, unlike a normal +function, default values must be specified within the function body. Also +within the function body, you must pass the matching identifier with the +leading underscore to the bracket operator of ``args`` to extract the +corresponding argument, but at least this doesn't require ``std::forward`` to +preserve value categories. + +.. parsed-literal:: + + struct B + { + B() + { + } + + BOOST_PARAMETER_BASIC_CONST_FUNCTION_CALL_OPERATOR((bool), kw, + (deduced + (required + (lrc, (std::`bitset`_<1>)) + (lr, (std::`bitset`_<2>)) + ) + (optional + (rrc, (std::`bitset`_<3>)) + (rr, (std::`bitset`_<4>)) + ) + ) + ) + { + BOOST_TEST_EQ( + passed_by_lvalue_reference_to_const + , U::evaluate_category<0>(args[_lrc]) + ); + BOOST_TEST_EQ( + passed_by_lvalue_reference + , U::evaluate_category<1>(args[_lr]) + ); + BOOST_TEST_EQ( + passed_by_rvalue_reference_to_const + , U::evaluate_category<2>( + args[_rrc0 | rvalue_const_bitset<2>()] + ) + ); + BOOST_TEST_EQ( + passed_by_rvalue_reference + , U::evaluate_category<3>( + args[_rr0 | rvalue_bitset<3>()] + ) + ); + + return true; + } + }; + +The following function calls are legal. + +.. parsed-literal:: + + B const b = B(); + b( // positional arguments + lvalue_const_bitset<0>() + , lvalue_bitset<1>() + , rvalue_const_bitset<2>() + , rvalue_bitset<3>() + ); + b( // positional arguments + lvalue_const_bitset<0>() + , lvalue_bitset<1>() + ); + b(( // composed arguments + _rr0 = rvalue_bitset<3>() + , _lrc0 = lvalue_const_bitset<0>() + , _lr0 = lvalue_bitset<1>() + , _rrc0 = rvalue_const_bitset<2>() + )); + b( // named arguments + _rr0 = rvalue_bitset<3>() + , _lrc0 = lvalue_const_bitset<0>() + , _lr0 = lvalue_bitset<1>() + , _rrc0 = rvalue_const_bitset<2>() + ); + b( // named arguments + _lr0 = lvalue_bitset<1>() + , _lrc0 = lvalue_const_bitset<0>() + ); + +Because the parameters were wrapped in a ``(deduced …)`` clause, the following +function calls are also legal. + +.. parsed-literal:: + + b( // deduced arguments + rvalue_bitset<3>() + , lvalue_const_bitset<0>() + , lvalue_bitset<1>() + , rvalue_const_bitset<2>() + ); + b( // deduced arguments + lvalue_bitset<1>() + , lvalue_const_bitset<0>() + ); + +The |preprocessor|_ test program demonstrates proper usage of this macro. + +.. _`bitset`: http\://en.cppreference.com/w/cpp/utility/bitset +.. |preprocessor| replace:: preprocessor.cpp +.. _preprocessor: ../../test/preprocessor.cpp + +:Macro parameters: +\*. ``result`` is the parenthesized return type of the function call operator. +\*. ``tag_namespace`` is the namespace in which the keywords used by the +function call operator resides. +\*. ``arguments`` is a `Boost.Preprocessor`_ `sequence`_ of +*argument-specifiers*, as defined below. + +:Argument specifiers syntax: +.. parsed-literal:: + + argument-specifiers ::= *specifier-group0* {*specifier-group0*\ } + + specifier-group0 ::= *specifier-group1* | + ( + '**(**' '**deduced**' + *specifier-group1* {*specifier-group1*\ } + '**)**' + ) + + specifier-group1 ::= + ( + '**(**' '**optional**' + *specifier* {*specifier*\ } + '**)**' + ) | ( + '**(**' '**required**' + *specifier* {*specifier*\ } + '**)**' + ) + + specifier ::= + '**(**' *argument-name* '**,**' *restriction* ')' + + restriction ::= + ( '**\***' '**(**' *mfc* '**)**' ) | + ( '**(**' *type-name* '**)**' ) | + '**\***' + +\*. ``argument-name`` is any valid C++ identifier. +\*. ``mfc`` is an `MPL Binary Metafunction Class`_ whose first argument will +be the type of the corresponding ``argument-name``, whose second argument will +be the entire |ArgumentPack|_, and whose return type is a `Boolean Integral +Constant`_; however, user code *cannot* compute ``mfc`` in terms of +``previous-name ## _type``. +\*. ``type-name`` is either the name of a **target type** or an `MPL Binary +Metafunction Class`_ whose first argument will be the type of the +corresponding ``argument-name``, whose second argument will be the entire +|ArgumentPack|_, and whose return type is the **target type**. + +Note that *specifier* does not include *default-value*. It is up to the +function body to determine the default value of all optional arguments. + +.. _`Boost.Preprocessor`: ../../../preprocessor/doc/index.html +.. _`sequence`: ../../../preprocessor/doc/data/sequences.html +.. _`MPL Binary Metafunction Class`: ../../../mpl/doc/refmanual/metafunction-class.html +.. _`Boolean Integral Constant`: ../../../mpl/doc/refmanual/integral-constant.html + +Approximate expansion: +**Where**: + +* ``n`` denotes the *minimum* arity, as determined from ``arguments``. +* ``m`` denotes the *maximum* arity, as determined from ``arguments``. + +.. parsed-literal:: + + template + struct boost_param_result_const\_ ## __LINE__ ## operator + { + typedef **result** type; + }; + + struct boost_param_params_const\_ ## __LINE__ ## operator + : |parameters|_< + *list of parameter specifications, based on arguments* + > + { + }; + + typedef boost_param_params_const\_ ## __LINE__ ## operator + boost_param_parameters_const\_ ## __LINE__ ## operator; + + template + **result** operator()( + A0&& a0, …, A ## **n**\ && a ## **n** + , typename boost_param_parameters_const\_ ## __LINE__ ## operator + ::match::type + = boost_param_parameters_const\_ ## __LINE__ ## operator() + ) const + { + return this->boost_param_impl_const ## __LINE__ ## operator( + boost_param_parameters_const\_ ## __LINE__ ## operator()( + std::`forward`_(a0) + , … + , std::`forward`_(a ## **n**) + ) + ); + } + + :vellipsis:`⋮` + + template + **result** operator()( + A0&& a0, …, A ## **m**\ && a ## **m** + , typename boost_param_parameters_const\_ ## __LINE__ ## operator + ::match::type + = boost_param_parameters_const\_ ## __LINE__ ## operator() + ) const + { + return this->boost_param_impl_const ## __LINE__ ## operator( + boost_param_parameters_const\_ ## __LINE__ ## operator()( + std::`forward`_(a0) + , … + , std::`forward`_(a ## **m**) + ) + ); + } + + template + typename boost_param_result_const\_ ## __LINE__ ## operator::type + boost_param_impl_const ## __LINE__ ## operator(Args const& args) const + +Only the |ArgumentPack|_ type ``Args`` and its object instance ``args`` are +available for use within the function call operator body. + +.. _`forward`: http\://en.cppreference.com/w/cpp/utility/forward + +``BOOST_PARAMETER_NO_SPEC_FUNCTION(result, name)`` +-------------------------------------------------- + +:Defined in: `boost/parameter/preprocessor_no_spec.hpp`__ + +__ ../../../../boost/parameter/preprocessor_no_spec.hpp + +Generates a function that can take in named arguments. + +:Example usage: +The return type of each of the following function templates falls under a +different value category. + +.. parsed-literal:: + + template + std::`bitset`_ rvalue_bitset() + { + return std::`bitset`_(); + } + + template + std::`bitset`_ const rvalue_const_bitset() + { + return std::`bitset`_(); + } + + template + std::`bitset`_& lvalue_bitset() + { + static std::`bitset`_ lset = std::`bitset`_(); + return lset; + } + + template + std::`bitset`_ const& lvalue_const_bitset() + { + static std::`bitset`_ const clset = std::`bitset`_(); + return clset; + } + +The ``U::evaluate_category`` static member function template has a simple job: +to return the correct value category when passed in an object returned by one +of the functions defined above. Assume that +|BOOST_PARAMETER_HAS_PERFECT_FORWARDING| is defined. + +.. parsed-literal:: + + enum invoked + { + passed_by_lvalue_reference_to_const + , passed_by_lvalue_reference + , passed_by_rvalue_reference_to_const + , passed_by_rvalue_reference + }; + + struct U + { + template + static invoked evaluate_category(std::`bitset`_ const&) + { + return passed_by_lvalue_reference_to_const; + } + + template + static invoked evaluate_category(std::`bitset`_&) + { + return passed_by_lvalue_reference; + } + + template + static invoked evaluate_category(std::`bitset`_ const&&) + { + return passed_by_rvalue_reference_to_const; + } + + template + static invoked evaluate_category(std::`bitset`_&&) + { + return passed_by_rvalue_reference; + } + }; + +Named parameters are required when invoking the function; however, none of +their tags need to be in the same namespace. + +.. parsed-literal:: + + |BOOST_PARAMETER_NAME|_((_lrc, kw0) in(lrc)) + |BOOST_PARAMETER_NAME|_((_lr, kw1) in_out(lr)) + |BOOST_PARAMETER_NAME|_((_rrc, kw2) in(rrc)) + |BOOST_PARAMETER_NAME|_((_rr, kw3) consume(rr)) + +Use the macro as a substitute for a variadic function header. Enclose the +return type ``bool`` in parentheses. + +.. parsed-literal:: + + BOOST_PARAMETER_NO_SPEC_FUNCTION((bool), evaluate) + { + BOOST_TEST_EQ( + passed_by_lvalue_reference_to_const + , U::evaluate_category<0>(args[_lrc]) + ); + BOOST_TEST_EQ( + passed_by_lvalue_reference + , U::evaluate_category<1>(args[_lr]) + ); + BOOST_TEST_EQ( + passed_by_rvalue_reference_to_const + , U::evaluate_category<2>( + args[_rrc | rvalue_const_bitset<2>()] + ) + ); + BOOST_TEST_EQ( + passed_by_rvalue_reference + , U::evaluate_category<3>(args[_rr | rvalue_bitset<3>()]) + ); + + return true; + } + +To invoke the function, bind all its arguments to named parameters. + +.. parsed-literal:: + + evaluate( + _rr0 = rvalue_bitset<3>() + , _lrc0 = lvalue_const_bitset<0>() + , _lr0 = lvalue_bitset<1>() + , _rrc0 = rvalue_const_bitset<2>() + ); + evaluate( + _lr0 = lvalue_bitset<1>() + , _lrc0 = lvalue_const_bitset<0>() + ); + +The |preproc_eval_cat_no_spec|_ test program demonstrates proper usage of +this macro. + +.. _`bitset`: http\://en.cppreference.com/w/cpp/utility/bitset +.. |preproc_eval_cat_no_spec| replace:: preprocessor_eval_cat_no_spec.cpp +.. _preproc_eval_cat_no_spec: ../../test/preprocessor_eval_cat_no_spec.cpp + +:Macro parameters: +\*. ``result`` is the parenthesized return type of the function. +\*. ``name`` is the base name of the function; it determines the name of the +generated implementation function. + +:Argument specifiers syntax: +None. + +Approximate expansion: +.. parsed-literal:: + + template + struct boost_param_no_spec_result\_ ## __LINE__ ## **name** + { + typedef **result** type; + }; + + template + ResultType + boost_param_no_spec_impl ## __LINE__ ## **name**\ ( + (ResultType(\*)()) + , Args const& args + ); + + template + inline typename boost::`lazy_enable_if`_< + |are_tagged_arguments|_ + , boost_param_no_spec_result\_ ## __LINE__ ## **name**\ < + TaggedArg0 + , TaggedArgs... + > + >::type + **name**\ (TaggedArg0 const& arg0, TaggedArgs const&... args) + { + return boost_param_no_spec_impl ## __LINE__ ## **name**\ ( + static_cast< + typename + boost_param_no_spec_result\_ ## __LINE__ ## **name**\ < + TaggedArg0 + , TaggedArgs... + >::type(\*)() + >(std::`nullptr`_) + , |compose|_(arg0, args...) + ); + } + + template + ResultType + boost_param_no_spec_impl ## __LINE__ ## **name**\ ( + (ResultType(\*)()) + , Args const& args + ) + +Only the |ArgumentPack|_ type ``Args`` and its object instance ``args`` are +available for use within the function body. + +.. _`nullptr`: http\://en.cppreference.com/w/cpp/language/nullptr +.. _`lazy_enable_if`: ../../../core/doc/html/core/enable_if.html + +``BOOST_PARAMETER_NO_SPEC_MEMBER_FUNCTION(result, name)`` +--------------------------------------------------------- + +:Defined in: `boost/parameter/preprocessor_no_spec.hpp`__ + +__ ../../../../boost/parameter/preprocessor_no_spec.hpp + +Generates a member function that can take in named arguments. + +:Example usage: +When designing a front-end class template whose back-end is configurable via +parameterized inheritance, it can be useful to omit argument specifiers from +a named-parameter member function so that the delegate member functions of the +back-end classes can enforce their own specifications. + +.. parsed-literal:: + + template + struct frontend : B + { + frontend() : B() + { + } + + BOOST_PARAMETER_NO_SPEC_MEMBER_FUNCTION((void), initialize) + { + this->initialize_impl(args); + } + }; + +Named parameters are required when invoking the member function; however, none +of their tags need to be in the same namespace. + +.. parsed-literal:: + + |BOOST_PARAMETER_NAME|_(a0) + |BOOST_PARAMETER_NAME|_(a1) + |BOOST_PARAMETER_NAME|_(a2) + +For this example, each of the back-end class templates requires its own +parameter to be present in the argument pack. In practice, such parameters +should be optional, with default values. + +.. parsed-literal:: + + template + class backend0 + { + T a0; + + public: + backend0() : a0() + { + } + + T const& get_a0() const + { + return this->a0; + } + + protected: + template + void initialize_impl(ArgPack const& args) + { + this->a0 = args[_a0]; + } + }; + + template + class backend1 : public B + { + T a1; + + public: + backend1() : B(), a1() + { + } + + T const& get_a1() const + { + return this->a1; + } + + protected: + template + void initialize_impl(ArgPack const& args) + { + B::initialize_impl(args); + this->a1 = args[_a1]; + } + }; + + template + class backend2 : public B + { + T a2; + + public: + backend2() : B(), a2() + { + } + + T const& get_a2() const + { + return this->a2; + } + + protected: + template + void initialize_impl(ArgPack const& args) + { + B::initialize_impl(args); + this->a2 = args[_a2]; + } + }; + +This example shows that while ``backend0`` must always be the root base class +template and that ``frontend`` must always be the most derived class template, +the other back-ends can be chained together in different orders. + +.. parsed-literal:: + + char const\* p = "foo"; + frontend< + backend2, char>, int> + > composed_obj0; + frontend< + backend1, int>, char> + > composed_obj1; + composed_obj0.initialize(_a2 = 4, _a1 = ' ', _a0 = p); + composed_obj1.initialize(_a0 = p, _a1 = ' ', _a2 = 4); + BOOST_TEST_EQ(composed_obj0.get_a0(), composed_obj1.get_a0()); + BOOST_TEST_EQ(composed_obj0.get_a1(), composed_obj1.get_a1()); + BOOST_TEST_EQ(composed_obj0.get_a2(), composed_obj1.get_a2()); + +The |parameterized_inheritance|_ and |preproc_eval_cat_no_spec|_ test programs +demonstrate proper usage of this macro. + +.. |parameterized_inheritance| replace:: parameterized_inheritance.cpp +.. _parameterized_inheritance: ../../test/parameterized_inheritance.cpp +.. |preproc_eval_cat_no_spec| replace:: preprocessor_eval_cat_no_spec.cpp +.. _preproc_eval_cat_no_spec: ../../test/preprocessor_eval_cat_no_spec.cpp + +:Macro parameters: +\*. ``result`` is the parenthesized return type of the function. +\*. ``name`` is the base name of the function; it determines the name of the +generated implementation function. ``name`` may be qualified by the +``static`` keyword to declare the member function and its helpers as not +associated with any object of the enclosing type. + +:Argument specifiers syntax: +None. + +Approximate expansion: +.. parsed-literal:: + + template + struct boost_param_no_spec_result\_ ## __LINE__ ## **name** + { + typedef **result** type; + }; + + template + inline typename boost::`lazy_enable_if`_< + |are_tagged_arguments|_ + , boost_param_no_spec_result\_ ## __LINE__ ## **name**\ < + TaggedArg0 + , TaggedArgs... + > + >::type + **name**\ (TaggedArg0 const& arg0, TaggedArgs const&... args) + { + return this->boost_param_no_spec_impl ## __LINE__ ## **name**\ ( + static_cast< + typename + boost_param_no_spec_result\_ ## __LINE__ ## **name**\ < + TaggedArg0 + , TaggedArgs... + >::type(\*)() + >(std::`nullptr`_) + , |compose|_(arg0, args...) + ); + } + + template + ResultType + boost_param_no_spec_impl ## __LINE__ ## **name**\ ( + (ResultType(\*)()) + , Args const& args + ) + +Only the |ArgumentPack|_ type ``Args`` and its object instance ``args`` are +available for use within the function body. + +.. _`nullptr`: http\://en.cppreference.com/w/cpp/language/nullptr +.. _`lazy_enable_if`: ../../../core/doc/html/core/enable_if.html + +``BOOST_PARAMETER_NO_SPEC_CONST_MEMBER_FUNCTION(result, name)`` +--------------------------------------------------------------- + +:Defined in: `boost/parameter/preprocessor_no_spec.hpp`__ + +__ ../../../../boost/parameter/preprocessor_no_spec.hpp + +Generates a member function that can take in named arguments. + +:Example usage: +The return type of each of the following function templates falls under a +different value category. + +.. parsed-literal:: + + template + std::`bitset`_ rvalue_bitset() + { + return std::`bitset`_(); + } + + template + std::`bitset`_ const rvalue_const_bitset() + { + return std::`bitset`_(); + } + + template + std::`bitset`_& lvalue_bitset() + { + static std::`bitset`_ lset = std::`bitset`_(); + return lset; + } + + template + std::`bitset`_ const& lvalue_const_bitset() + { + static std::`bitset`_ const clset = std::`bitset`_(); + return clset; + } + +The ``U::evaluate_category`` static member function template has a simple job: +to return the correct value category when passed in an object returned by one +of the functions defined above. Assume that +|BOOST_PARAMETER_HAS_PERFECT_FORWARDING| is defined. + +.. parsed-literal:: + + enum invoked + { + passed_by_lvalue_reference_to_const + , passed_by_lvalue_reference + , passed_by_rvalue_reference_to_const + , passed_by_rvalue_reference + }; + + struct U + { + template + static invoked evaluate_category(std::`bitset`_ const&) + { + return passed_by_lvalue_reference_to_const; + } + + template + static invoked evaluate_category(std::`bitset`_&) + { + return passed_by_lvalue_reference; + } + + template + static invoked evaluate_category(std::`bitset`_ const&&) + { + return passed_by_rvalue_reference_to_const; + } + + template + static invoked evaluate_category(std::`bitset`_&&) + { + return passed_by_rvalue_reference; + } + }; + +Named parameters are required when invoking the member function; however, none +of their tags need to be in the same namespace. + +.. parsed-literal:: + + |BOOST_PARAMETER_NAME|_((_lrc, kw0) in(lrc)) + |BOOST_PARAMETER_NAME|_((_lr, kw1) in_out(lr)) + |BOOST_PARAMETER_NAME|_((_rrc, kw2) in(rrc)) + |BOOST_PARAMETER_NAME|_((_rr, kw3) consume(rr)) + +Use the macro as a substitute for a variadic function header. Enclose the +return type ``bool`` in parentheses. The macro will qualify the function with +the ``const`` keyword. + +.. parsed-literal:: + + struct D + { + D() + { + } + + BOOST_PARAMETER_NO_SPEC_CONST_MEMBER_FUNCTION((bool), evaluate_m) + { + BOOST_TEST_EQ( + passed_by_lvalue_reference_to_const + , U::evaluate_category<0>(args[_lrc]) + ); + BOOST_TEST_EQ( + passed_by_lvalue_reference + , U::evaluate_category<1>(args[_lr]) + ); + BOOST_TEST_EQ( + passed_by_rvalue_reference_to_const + , U::evaluate_category<2>( + args[_rrc | rvalue_const_bitset<2>()] + ) + ); + BOOST_TEST_EQ( + passed_by_rvalue_reference + , U::evaluate_category<3>( + args[_rr | rvalue_bitset<3>()] + ) + ); + + return true; + } + }; + +To invoke the member function, bind all its arguments to named parameters. + +.. parsed-literal:: + + D const d = D(); + d.evaluate_m( + _rr0 = rvalue_bitset<3>() + , _lrc0 = lvalue_const_bitset<0>() + , _lr0 = lvalue_bitset<1>() + , _rrc0 = rvalue_const_bitset<2>() + ); + d.evaluate_m( + _lr0 = lvalue_bitset<1>() + , _lrc0 = lvalue_const_bitset<0>() + ); + +The |preproc_eval_cat_no_spec|_ test program demonstrates proper usage of this +macro. + +.. _`bitset`: http\://en.cppreference.com/w/cpp/utility/bitset +.. |preproc_eval_cat_no_spec| replace:: preprocessor_eval_cat_no_spec.cpp +.. _preproc_eval_cat_no_spec: ../../test/preprocessor_eval_cat_no_spec.cpp + +:Macro parameters: +\*. ``result`` is the parenthesized return type of the function. +\*. ``name`` is the base name of the function; it determines the name of the +generated implementation function. + +:Argument specifiers syntax: +None. + +Approximate expansion: +.. parsed-literal:: + + template + struct boost_param_no_spec_result_const\_ ## __LINE__ ## **name** + { + typedef **result** type; + }; + + template + inline typename boost::`lazy_enable_if`_< + |are_tagged_arguments|_ + , boost_param_no_spec_result_const\_ ## __LINE__ ## **name**\ < + TaggedArg0 + , TaggedArgs... + > + >::type + **name**\ (TaggedArg0 const& arg0, TaggedArgs const&... args) const + { + return this->boost_param_no_spec_impl_const ## __LINE__ ## **name**\ ( + static_cast< + typename + boost_param_no_spec_result_const\_ ## __LINE__ ## **name**\ < + TaggedArg0 + , TaggedArgs... + >::type(\*)() + >(std::`nullptr`_) + , |compose|_(arg0, args...) + ); + } + + template + ResultType + boost_param_no_spec_impl_const ## __LINE__ ## **name**\ ( + (ResultType(\*)()) + , Args const& args + ) const + +Only the |ArgumentPack|_ type ``Args`` and its object instance ``args`` are +available for use within the function body. + +.. _`nullptr`: http\://en.cppreference.com/w/cpp/language/nullptr +.. _`lazy_enable_if`: ../../../core/doc/html/core/enable_if.html + +``BOOST_PARAMETER_NO_SPEC_FUNCTION_CALL_OPERATOR(result)`` +---------------------------------------------------------- + +:Defined in: `boost/parameter/preprocessor_no_spec.hpp`__ + +__ ../../../../boost/parameter/preprocessor_no_spec.hpp + +Generates a function call operator that can take in named arguments. + +:Example usage: +When designing a front-end class template whose back-end is configurable via +parameterized inheritance, it can be useful to omit argument specifiers from +a named-parameter function call operator so that the delegate member functions +of the back-end classes can enforce their own specifications. + +.. parsed-literal:: + + template + struct frontend : B + { + frontend() : B() + { + } + + BOOST_PARAMETER_NO_SPEC_FUNCTION_CALL_OPERATOR((void)) + { + this->initialize_impl(args); + } + }; + +Named parameters are required when invoking the function call operator; +however, none of their tags need to be in the same namespace. + +.. parsed-literal:: + + |BOOST_PARAMETER_NAME|_(a0) + |BOOST_PARAMETER_NAME|_(a1) + |BOOST_PARAMETER_NAME|_(a2) + +For this example, each of the back-end class templates requires its own +parameter to be present in the argument pack. In practice, such parameters +should be optional, with default values. + +.. parsed-literal:: + + template + class backend0 + { + T a0; + + public: + backend0() : a0() + { + } + + T const& get_a0() const + { + return this->a0; + } + + protected: + template + void initialize_impl(ArgPack const& args) + { + this->a0 = args[_a0]; + } + }; + + template + class backend1 : public B + { + T a1; + + public: + backend1() : B(), a1() + { + } + + T const& get_a1() const + { + return this->a1; + } + + protected: + template + void initialize_impl(ArgPack const& args) + { + B::initialize_impl(args); + this->a1 = args[_a1]; + } + }; + + template + class backend2 : public B + { + T a2; + + public: + backend2() : B(), a2() + { + } + + T const& get_a2() const + { + return this->a2; + } + + protected: + template + void initialize_impl(ArgPack const& args) + { + B::initialize_impl(args); + this->a2 = args[_a2]; + } + }; + +This example shows that while ``backend0`` must always be the root base class +template and that ``frontend`` must always be the most derived class template, +the other back-ends can be chained together in different orders. + +.. parsed-literal:: + + char const\* p = "foo"; + frontend< + backend2, char>, int> + > composed_obj0; + frontend< + backend1, int>, char> + > composed_obj1; + composed_obj0(_a2 = 4, _a1 = ' ', _a0 = p); + composed_obj1(_a0 = p, _a1 = ' ', _a2 = 4); + BOOST_TEST_EQ(composed_obj0.get_a0(), composed_obj1.get_a0()); + BOOST_TEST_EQ(composed_obj0.get_a1(), composed_obj1.get_a1()); + BOOST_TEST_EQ(composed_obj0.get_a2(), composed_obj1.get_a2()); + +The |parameterized_inheritance|_ and |preproc_eval_cat_no_spec|_ test programs +demonstrate proper usage of this macro. + +.. |parameterized_inheritance| replace:: parameterized_inheritance.cpp +.. _parameterized_inheritance: ../../test/parameterized_inheritance.cpp +.. |preproc_eval_cat_no_spec| replace:: preprocessor_eval_cat_no_spec.cpp +.. _preproc_eval_cat_no_spec: ../../test/preprocessor_eval_cat_no_spec.cpp + +:Macro parameters: +\*. ``result`` is the parenthesized return type of the function call operator. + +:Argument specifiers syntax: +None. + +Approximate expansion: +.. parsed-literal:: + + template + struct boost_param_no_spec_result\_ ## __LINE__ ## operator + { + typedef **result** type; + }; + + template + inline typename boost::`lazy_enable_if`_< + |are_tagged_arguments|_ + , boost_param_no_spec_result\_ ## __LINE__ ## operator< + TaggedArg0 + , TaggedArgs... + > + >::type + operator()(TaggedArg0 const& arg0, TaggedArgs const&... args) + { + return this->boost_param_no_spec_impl ## __LINE__ ## operator( + static_cast< + typename + boost_param_no_spec_result\_ ## __LINE__ ## operator< + TaggedArg0 + , TaggedArgs... + >::type(\*)() + >(std::`nullptr`_) + , |compose|_(arg0, args...) + ); + } + + template + ResultType + boost_param_no_spec_impl ## __LINE__ ## operator( + (ResultType(\*)()) + , Args const& args + ) + +Only the |ArgumentPack|_ type ``Args`` and its object instance ``args`` are +available for use within the function body. + +.. _`nullptr`: http\://en.cppreference.com/w/cpp/language/nullptr +.. _`lazy_enable_if`: ../../../core/doc/html/core/enable_if.html + +``BOOST_PARAMETER_NO_SPEC_CONST_FUNCTION_CALL_OPERATOR(result)`` +---------------------------------------------------------------- + +:Defined in: `boost/parameter/preprocessor_no_spec.hpp`__ + +__ ../../../../boost/parameter/preprocessor_no_spec.hpp + +Generates a function call operator that can take in named arguments. + +:Example usage: +The return type of each of the following function templates falls under a +different value category. + +.. parsed-literal:: + + template + std::`bitset`_ rvalue_bitset() + { + return std::`bitset`_(); + } + + template + std::`bitset`_ const rvalue_const_bitset() + { + return std::`bitset`_(); + } + + template + std::`bitset`_& lvalue_bitset() + { + static std::`bitset`_ lset = std::`bitset`_(); + return lset; + } + + template + std::`bitset`_ const& lvalue_const_bitset() + { + static std::`bitset`_ const clset = std::`bitset`_(); + return clset; + } + +The ``U::evaluate_category`` static member function template has a simple job: +to return the correct value category when passed in an object returned by one +of the functions defined above. Assume that +|BOOST_PARAMETER_HAS_PERFECT_FORWARDING| is defined. + +.. parsed-literal:: + + enum invoked + { + passed_by_lvalue_reference_to_const + , passed_by_lvalue_reference + , passed_by_rvalue_reference_to_const + , passed_by_rvalue_reference + }; + + struct U + { + template + static invoked evaluate_category(std::`bitset`_ const&) + { + return passed_by_lvalue_reference_to_const; + } + + template + static invoked evaluate_category(std::`bitset`_&) + { + return passed_by_lvalue_reference; + } + + template + static invoked evaluate_category(std::`bitset`_ const&&) + { + return passed_by_rvalue_reference_to_const; + } + + template + static invoked evaluate_category(std::`bitset`_&&) + { + return passed_by_rvalue_reference; + } + }; + +Named parameters are required when invoking the function call operator; +however, none of their tags need to be in the same namespace. + +.. parsed-literal:: + + |BOOST_PARAMETER_NAME|_((_lrc, kw0) in(lrc)) + |BOOST_PARAMETER_NAME|_((_lr, kw1) in_out(lr)) + |BOOST_PARAMETER_NAME|_((_rrc, kw2) in(rrc)) + |BOOST_PARAMETER_NAME|_((_rr, kw3) consume(rr)) + +Use the macro as a substitute for a variadic function call operator +header. Enclose the return type ``bool`` in parentheses. The macro will +qualify the function with the ``const`` keyword. + +.. parsed-literal:: + + struct D + { + D() + { + } + + BOOST_PARAMETER_NO_SPEC_CONST_FUNCTION_CALL_OPERATOR((bool)) + { + BOOST_TEST_EQ( + passed_by_lvalue_reference_to_const + , U::evaluate_category<0>(args[_lrc]) + ); + BOOST_TEST_EQ( + passed_by_lvalue_reference + , U::evaluate_category<1>(args[_lr]) + ); + BOOST_TEST_EQ( + passed_by_rvalue_reference_to_const + , U::evaluate_category<2>( + args[_rrc | rvalue_const_bitset<2>()] + ) + ); + BOOST_TEST_EQ( + passed_by_rvalue_reference + , U::evaluate_category<3>( + args[_rr | rvalue_bitset<3>()] + ) + ); + + return true; + } + }; + +To invoke the function call operator, bind all its arguments to named +parameters. + +.. parsed-literal:: + + D const d = D(); + d( + _rr0 = rvalue_bitset<3>() + , _lrc0 = lvalue_const_bitset<0>() + , _lr0 = lvalue_bitset<1>() + , _rrc0 = rvalue_const_bitset<2>() + ); + d( + _lr0 = lvalue_bitset<1>() + , _lrc0 = lvalue_const_bitset<0>() + ); + +The |preproc_eval_cat_no_spec|_ test program demonstrates proper usage of this +macro. + +.. _`bitset`: http\://en.cppreference.com/w/cpp/utility/bitset +.. |preproc_eval_cat_no_spec| replace:: preprocessor_eval_cat_no_spec.cpp +.. _preproc_eval_cat_no_spec: ../../test/preprocessor_eval_cat_no_spec.cpp + +:Macro parameters: +\*. ``result`` is the parenthesized return type of the function call operator. + +:Argument specifiers syntax: +None. + +Approximate expansion: +.. parsed-literal:: + + template + struct boost_param_no_spec_result_const\_ ## __LINE__ ## operator + { + typedef **result** type; + }; + + template + inline typename boost::`lazy_enable_if`_< + |are_tagged_arguments|_ + , boost_param_no_spec_result_const\_ ## __LINE__ ## operator< + TaggedArg0 + , TaggedArgs... + > + >::type + operator()( + TaggedArg0 const& arg0 + , TaggedArgs const&... args + ) const + { + return this->boost_param_no_spec_impl_const ## __LINE__ ## operator( + static_cast< + typename + boost_param_no_spec_result_const\_ ## __LINE__ ## operator< + TaggedArg0 + , TaggedArgs... + >::type(\*)() + >(std::`nullptr`_) + , |compose|_(arg0, args...) + ); + } + + template + ResultType + boost_param_no_spec_impl_const ## __LINE__ ## operator( + (ResultType(\*)()) + , Args const& args + ) const + +Only the |ArgumentPack|_ type ``Args`` and its object instance ``args`` are +available for use within the function body. + +.. _`nullptr`: http\://en.cppreference.com/w/cpp/language/nullptr +.. _`lazy_enable_if`: ../../../core/doc/html/core/enable_if.html + +``BOOST_PARAMETER_NO_SPEC_CONSTRUCTOR(cls, impl)`` +-------------------------------------------------- + +:Defined in: `boost/parameter/preprocessor_no_spec.hpp`__ + +__ ../../../../boost/parameter/preprocessor_no_spec.hpp + +Generates a constructor that can take in named arguments. + +:Example usage: +When designing a front-end class template whose back-end is configurable via +parameterized inheritance, it can be useful to omit argument specifiers from +a named-parameter constructor so that the delegate constructors of the +back-end classes can enforce their own specifications. + +.. parsed-literal:: + + template + struct frontend : B + { + BOOST_PARAMETER_NO_SPEC_CONSTRUCTOR(frontend, (B)) + }; + +Named parameters are required when invoking the constructor; however, none of +their tags need to be in the same namespace. + +.. parsed-literal:: + + |BOOST_PARAMETER_NAME|_(a0) + |BOOST_PARAMETER_NAME|_(a1) + |BOOST_PARAMETER_NAME|_(a2) + +For this example, each of the back-end class templates requires its own +parameter to be present in the argument pack. In practice, such parameters +should be optional, with default values. + +.. parsed-literal:: + + struct _enabler + { + }; + + template + class backend0 + { + T a0; + + public: + template + explicit backend0( + ArgPack const& args + , typename boost::`enable_if`_< + |is_argument_pack|_ + , _enabler + >::type = _enabler() + ) : a0(args[_a0]) + { + } + + T const& get_a0() const + { + return this->a0; + } + }; + + template + class backend1 : public B + { + T a1; + + public: + template + explicit backend1( + ArgPack const& args + , typename boost::`enable_if`_< + |is_argument_pack|_ + , _enabler + >::type = _enabler() + ) : B(args), a1(args[_a1]) + { + } + + T const& get_a1() const + { + return this->a1; + } + }; + + template + class backend2 : public B + { + T a2; + + public: + template + explicit backend2( + ArgPack const& args + , typename boost::`enable_if`_< + |is_argument_pack|_ + , _enabler + >::type = _enabler() + ) : B(args), a2(args[_a2]) + { + } + + T const& get_a2() const + { + return this->a2; + } + }; + +This example shows that while ``backend0`` must always be the root base class +template and that ``frontend`` must always be the most derived class template, +the other back-ends can be chained together in different orders. + +.. parsed-literal:: + + char const\* p = "foo"; + frontend< + backend2, char>, int> + > composed_obj0(_a2 = 4, _a1 = ' ', _a0 = p); + frontend< + backend1, int>, char> + > composed_obj1(_a0 = p, _a1 = ' ', _a2 = 4); + BOOST_TEST_EQ(composed_obj0.get_a0(), composed_obj1.get_a0()); + BOOST_TEST_EQ(composed_obj0.get_a1(), composed_obj1.get_a1()); + BOOST_TEST_EQ(composed_obj0.get_a2(), composed_obj1.get_a2()); + +The |parameterized_inheritance|_ and |preproc_eval_cat_no_spec|_ test programs +demonstrate proper usage of this macro. + +.. |parameterized_inheritance| replace:: parameterized_inheritance.cpp +.. _parameterized_inheritance: ../../test/parameterized_inheritance.cpp +.. |preproc_eval_cat_no_spec| replace:: preprocessor_eval_cat_no_spec.cpp +.. _preproc_eval_cat_no_spec: ../../test/preprocessor_eval_cat_no_spec.cpp + +:Macro parameters: +\*. ``cls`` is the name of the enclosing class. +\*. ``impl`` is the parenthesized implementation base class for ``cls``. + +:Argument specifiers syntax: +None. + +Approximate expansion: +.. parsed-literal:: + + template < + typename TaggedArg0 + , typename ...TaggedArgs + , typename = typename boost::`enable_if`_< + |are_tagged_arguments|_ + >::type + > + inline explicit **cls**\ ( + TaggedArg0 const& arg0 + , TaggedArgs const&... args + ) : **impl**\ (|compose|_(arg0, args...)) + { + } + +``BOOST_PARAMETER_NO_SPEC_NO_BASE_CONSTRUCTOR(cls, impl)`` +---------------------------------------------------------- + +:Defined in: `boost/parameter/preprocessor_no_spec.hpp`__ + +__ ../../../../boost/parameter/preprocessor_no_spec.hpp + +Generates a constructor that can take in named arguments. + +:Example usage: +The return type of each of the following function templates falls under a +different value category. + +.. parsed-literal:: + + template + std::`bitset`_ rvalue_bitset() + { + return std::`bitset`_(); + } + + template + std::`bitset`_ const rvalue_const_bitset() + { + return std::`bitset`_(); + } + + template + std::`bitset`_& lvalue_bitset() + { + static std::`bitset`_ lset = std::`bitset`_(); + return lset; + } + + template + std::`bitset`_ const& lvalue_const_bitset() + { + static std::`bitset`_ const clset = std::`bitset`_(); + return clset; + } + +The ``U::evaluate_category`` static member function template has a simple job: +to return the correct value category when passed in an object returned by one +of the functions defined above. Assume that +|BOOST_PARAMETER_HAS_PERFECT_FORWARDING| is defined. + +.. parsed-literal:: + + enum invoked + { + passed_by_lvalue_reference_to_const + , passed_by_lvalue_reference + , passed_by_rvalue_reference_to_const + , passed_by_rvalue_reference + }; + + struct U + { + template + static invoked evaluate_category(std::`bitset`_ const&) + { + return passed_by_lvalue_reference_to_const; + } + + template + static invoked evaluate_category(std::`bitset`_&) + { + return passed_by_lvalue_reference; + } + + template + static invoked evaluate_category(std::`bitset`_ const&&) + { + return passed_by_rvalue_reference_to_const; + } + + template + static invoked evaluate_category(std::`bitset`_&&) + { + return passed_by_rvalue_reference; + } + }; + +Named parameters are required when invoking the constructor; however, none of +their tags need to be in the same namespace. + +.. parsed-literal:: + + |BOOST_PARAMETER_NAME|_((_lrc, kw0) in(lrc)) + |BOOST_PARAMETER_NAME|_((_lr, kw1) in_out(lr)) + |BOOST_PARAMETER_NAME|_((_rrc, kw2) in(rrc)) + |BOOST_PARAMETER_NAME|_((_rr, kw3) consume(rr)) + +Unlike |BOOST_PARAMETER_NO_SPEC_CONSTRUCTOR|, this macro doesn't require a +base class, only a delegate function to which the generated constructor can +pass its |ArgumentPack|_. + +.. parsed-literal:: + + struct D + { + BOOST_PARAMETER_NO_SPEC_NO_BASE_CONSTRUCTOR(D, D::_evaluate) + + private: + template + static bool _evaluate(Args const& args) + { + BOOST_TEST_EQ( + passed_by_lvalue_reference_to_const + , U::evaluate_category<0>(args[_lrc]) + ); + BOOST_TEST_EQ( + passed_by_lvalue_reference + , U::evaluate_category<1>(args[_lr]) + ); + BOOST_TEST_EQ( + passed_by_rvalue_reference_to_const + , U::evaluate_category<2>( + args[_rrc | rvalue_const_bitset<2>()] + ) + ); + BOOST_TEST_EQ( + passed_by_rvalue_reference + , U::evaluate_category<3>( + args[_rr | rvalue_bitset<3>()] + ) + ); + + return true; + } + }; + +To invoke the constructor, bind all its arguments to named parameters. + +.. parsed-literal:: + + D dp0( + _rr0 = rvalue_bitset<3>() + , _lrc0 = lvalue_const_bitset<0>() + , _lr0 = lvalue_bitset<1>() + , _rrc0 = rvalue_const_bitset<2>() + ); + D dp1( + _lr0 = lvalue_bitset<1>() + , _lrc0 = lvalue_const_bitset<0>() + ); + +The |preproc_eval_cat_no_spec|_ test program demonstrates proper usage of this +macro. + +.. _`bitset`: http\://en.cppreference.com/w/cpp/utility/bitset +.. |preproc_eval_cat_no_spec| replace:: preprocessor_eval_cat_no_spec.cpp +.. _preproc_eval_cat_no_spec: ../../test/preprocessor_eval_cat_no_spec.cpp + +:Macro parameters: +\*. ``cls`` is the name of the enclosing class. +\*. ``func`` is a function that takes in the |ArgumentPack|_ that the +generated constructor passes on. + +:Argument specifiers syntax: +None. + +Approximate expansion: +.. parsed-literal:: + + template < + typename TaggedArg0 + , typename ...TaggedArgs + , typename = typename boost::`enable_if`_< + |are_tagged_arguments|_ + >::type + > + inline explicit **cls**\ ( + TaggedArg0 const& arg0 + , TaggedArgs const&... args + ) + { + **func**\ (|compose|_(arg0, args...)); + } + ``BOOST_PARAMETER_NAME(name)`` ------------------------------ @@ -1920,7 +6323,7 @@ Expands to: struct *tag-name* { - static char const* keyword_name() + static constexpr char const\* keyword_name() { return ## *tag-name*; } @@ -1931,10 +6334,8 @@ Expands to: }; } - ::boost::parameter::keyword<*tag-namespace* :: *tag-name* > const& - *object-name* = ::boost::parameter::keyword< - *tag-namespace* :: *tag-name* - >::instance; + |keyword|_<*tag-namespace*::*tag-name*> const& *object-name* + = |keyword|_<*tag-namespace*::*tag-name*>::instance; **Else If** *name* is of the form: @@ -1969,7 +6370,7 @@ Expands to: struct *tag-name* { - static char const* keyword_name() + static constexpr char const\* keyword_name() { return ## *tag-name*; } @@ -1980,8 +6381,8 @@ Expands to: }; } - ::boost::parameter::keyword const& _ ## *tag-name* - = ::boost::parameter::keyword::instance; + |keyword|_ const& _ ## *tag-name* + = |keyword|_::instance; **Else** @@ -2020,7 +6421,7 @@ Expands to: struct *tag-name* { - static char const* keyword_name() + static constexpr char const\* keyword_name() { return ## *tag-name* ## _; } @@ -2028,12 +6429,15 @@ Expands to: typedef *unspecified* _; typedef *unspecified* _1; typedef boost::parameter::*qualifier* ## _reference qualifier; - static ::boost::parameter::keyword<*tag-name*> const& *alias*; + static |keyword|_<*tag-name*> const& *alias*; }; + + |keyword|_<*tag-name*> const& tag::*tag-name*::*alias* + = |keyword|_<*tag-name*>::instance; } - ::boost::parameter::keyword<*tag-name*> const& *tag-name*::*alias* - = ::boost::parameter::keyword<*tag-name*>::instance; + |keyword|_ const& tag::*tag-name*::*name* + = |keyword|_::instance; **Else** @@ -2064,8 +6468,7 @@ Expands to: } template - struct *name* - : ::boost::parameter::template_keyword + struct *name* : |template_keyword|_ { }; @@ -2095,8 +6498,6 @@ __ ../../../../boost/parameter/macros.hpp :Requires: ``l`` and ``h`` are nonnegative integer tokens such that ``l`` < ``h`` -**If** |BOOST_PARAMETER_HAS_PERFECT_FORWARDING| is ``#defined``, **then** - Expands to: .. parsed-literal:: @@ -2166,109 +6567,6 @@ Expands to: ); } -**If** |BOOST_PARAMETER_HAS_PERFECT_FORWARDING| is **not** ``#defined``, -**then** - -Expands to: - -.. parsed-literal:: - - template - r - name( - A1 const& a1, A2 const& a2, …, A ## **l** const& a ## **l** - , typename **p**::match::type pk = **p**\ () - ) - { - return **name**\ _with_named_params(pk(a1, a2, …, a ## **l**)); - } - - *… exponential number of overloads …* - :vellipsis:`⋮` - - template - r - name( - A1& a1, A2& a2, …, A ## **l** & a ## **l** - , typename **p**::match::type pk = **p**\ () - ) - { - return **name**\ _with_named_params(pk(a1, a2, …, a ## **l**)); - } - - template < - typename A1 - , typename A2 - , … - , typename A ## **l** - , typename A ## `BOOST_PP_INC`_\ (**l**) - > - r - name( - A1 const& a1, A2 const& a2, …, A ## **l** const& a ## **l** - , A ## `BOOST_PP_INC`_\ (**l**) const& a ## `BOOST_PP_INC`_\ (**l**) - , typename **p**::match< - A1 const, A2 const, …, A ## **l** const - , A ## `BOOST_PP_INC`_\ (**l**) const - >::type pk = **p**\ () - ) - { - return **name**\ _with_named_params( - pk(a1, a2, …, a ## **l**, a ## `BOOST_PP_INC`_\ (**l**)) - ); - } - - *… exponential number of overloads …* - :vellipsis:`⋮` - - template < - typename A1 - , typename A2 - , … - , typename A ## **l** - , typename A ## `BOOST_PP_INC`_\ (**l**) - > - r - name( - A1& a1, A2& a2, …, A ## **l** & a ## **l** - , A ## `BOOST_PP_INC`_\ (**l**) & a ## `BOOST_PP_INC`_\ (**l**) - , typename **p**::match< - A1, A2, …, A ## **l**, A ## `BOOST_PP_INC`_\ (**l**) - >::type pk = **p**\ () - ) - { - return **name**\ _with_named_params( - pk(a1, a2, …, a ## **l**, a ## `BOOST_PP_INC`_\ (**l**)) - ); - } - - :vellipsis:`⋮` - - template - r - name( - A1 const& a1, A2 const& a2, …, A ## **h** const& x ## **h** - , typename **p**::match< - A1 const, A2 const, …, A ## **h** const - >::type pk = **p**\ () - ) - { - return **name**\ _with_named_params(pk(a1, a2, …, a ## **h**)); - } - - *… exponential number of overloads …* - :vellipsis:`⋮` - - template - r - name( - A1& a1, A2& a2, …, A ## **h** & x ## **h** - , typename **p**::match::type pk = **p**\ () - ) - { - return **name**\ _with_named_params(pk(a1, a2, …, a ## **h**)); - } - The |macros_cpp|_ and |macros_eval_cat_cpp|_ test programs demonstrate proper usage of this macro. @@ -2303,14 +6601,21 @@ Expands to: struct **k** { + static constexpr char const\* keyword_name() + { + return ## *k*; + } + + typedef *unspecified* _; + typedef *unspecified* _1; typedef boost::parameter::forward_reference qualifier; }; } namespace { - boost::parameter::keyword<*tag-namespace*::**k**>& **k** - = boost::parameter::keyword<*tag-namespace*::**k**>::instance; + |keyword|_<*n*::**k**> const& **k** + = |keyword|_<*n*::**k**>::instance; } ``BOOST_PARAMETER_MATCH(p, a, x)`` @@ -2347,9 +6652,10 @@ Determines whether or not the library supports perfect forwarding, or the preservation of parameter value categories. Users can manually disable this macro by ``#defining`` the |BOOST_PARAMETER_DISABLE_PERFECT_FORWARDING| macro. Otherwise, the library will ``#define`` this macro if and only if it -and the configuration macros |BOOST_NO_FUNCTION_TEMPLATE_ORDERING|_, -|BOOST_NO_SFINAE|_, |BOOST_NO_CXX11_RVALUE_REFERENCES|_, and -|BOOST_NO_CXX11_VARIADIC_TEMPLATES|_ are not already defined by +is not already defined, and if the configuration macros +|BOOST_NO_FUNCTION_TEMPLATE_ORDERING|_, |BOOST_NO_SFINAE|_, +|BOOST_NO_CXX11_RVALUE_REFERENCES|_, |BOOST_NO_CXX11_VARIADIC_TEMPLATES|_, and +|BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS|_ are not already defined by `Boost.Config`_. .. |BOOST_PARAMETER_HAS_PERFECT_FORWARDING| replace:: ``BOOST_PARAMETER_HAS_PERFECT_FORWARDING`` @@ -2362,6 +6668,8 @@ and the configuration macros |BOOST_NO_FUNCTION_TEMPLATE_ORDERING|_, .. _BOOST_NO_CXX11_RVALUE_REFERENCES: ../../../config/doc/html/boost_config/boost_macro_reference.html .. |BOOST_NO_CXX11_VARIADIC_TEMPLATES| replace:: ``BOOST_NO_CXX11_VARIADIC_TEMPLATES`` .. _BOOST_NO_CXX11_VARIADIC_TEMPLATES: ../../../config/doc/html/boost_config/boost_macro_reference.html +.. |BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS| replace:: ``BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS`` +.. _BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS: ../../../config/doc/html/boost_config/boost_macro_reference.html .. _`Boost.Config`: ../../../config/doc/html/index.html :Defined in: `boost/parameter/config.hpp`__ @@ -2374,7 +6682,64 @@ __ ../../../../boost/parameter/config.hpp It may be necessary to test user code in case perfect forwarding support is unavailable. Users can ``#define`` this macro either in their project settings or before including any library header files. Doing so will leave -|BOOST_PARAMETER_HAS_PERFECT_FORWARDING| undefined. +both |BOOST_PARAMETER_HAS_PERFECT_FORWARDING| and +|BOOST_PARAMETER_CAN_USE_MP11| undefined. + +.. |BOOST_PARAMETER_HAS_PERFECT_FORWARDING| replace:: ``BOOST_PARAMETER_HAS_PERFECT_FORWARDING`` +.. |BOOST_PARAMETER_CAN_USE_MP11| replace:: ``BOOST_PARAMETER_CAN_USE_MP11`` + +``BOOST_PARAMETER_CAN_USE_MP11`` +-------------------------------- + +Determines whether or not the library can use `Boost.MP11`_, a C++11 +metaprogramming library. Users can manually disable this macro by +``#defining`` the |BOOST_PARAMETER_DISABLE_MP11_USAGE| macro or the +|BOOST_PARAMETER_DISABLE_PERFECT_FORWARDING| macro. Otherwise, the library +will ``#define`` this macro if and only if it is not already defined, if +|BOOST_PARAMETER_HAS_PERFECT_FORWARDING| is defined, and if the configuration +macros |BOOST_NO_CXX11_CONSTEXPR|_, |BOOST_NO_CXX11_DECLTYPE_N3276|_, +|BOOST_NO_CXX11_AUTO_DECLARATIONS|_, |BOOST_NO_CXX11_TEMPLATE_ALIASES|_, +|BOOST_NO_CXX11_STATIC_ASSERT|_, |BOOST_NO_CXX11_HDR_TYPE_TRAITS|_, +|BOOST_NO_CXX11_HDR_INITIALIZER_LIST|_, and |BOOST_NO_CXX11_HDR_TUPLE|_ +are not already defined by `Boost.Config`_. + +.. |BOOST_PARAMETER_CAN_USE_MP11| replace:: ``BOOST_PARAMETER_CAN_USE_MP11`` +.. |BOOST_PARAMETER_DISABLE_MP11_USAGE| replace:: ``BOOST_PARAMETER_DISABLE_MP11_USAGE`` +.. |BOOST_PARAMETER_HAS_PERFECT_FORWARDING| replace:: ``BOOST_PARAMETER_HAS_PERFECT_FORWARDING`` +.. |BOOST_PARAMETER_DISABLE_PERFECT_FORWARDING| replace:: ``BOOST_PARAMETER_DISABLE_PERFECT_FORWARDING`` +.. |BOOST_NO_CXX11_CONSTEXPR| replace:: ``BOOST_NO_CXX11_CONSTEXPR`` +.. _BOOST_NO_CXX11_CONSTEXPR: ../../../config/doc/html/boost_config/boost_macro_reference.html +.. |BOOST_NO_CXX11_DECLTYPE_N3276| replace:: ``BOOST_NO_CXX11_DECLTYPE_N3276`` +.. _BOOST_NO_CXX11_DECLTYPE_N3276: ../../../config/doc/html/boost_config/boost_macro_reference.html +.. |BOOST_NO_CXX11_AUTO_DECLARATIONS| replace:: ``BOOST_NO_CXX11_AUTO_DECLARATIONS`` +.. _BOOST_NO_CXX11_AUTO_DECLARATIONS: ../../../config/doc/html/boost_config/boost_macro_reference.html +.. |BOOST_NO_CXX11_AUTO_DECLARATIONS| replace:: ``BOOST_NO_CXX11_AUTO_DECLARATIONS`` +.. _BOOST_NO_CXX11_AUTO_DECLARATIONS: ../../../config/doc/html/boost_config/boost_macro_reference.html +.. |BOOST_NO_CXX11_STATIC_ASSERT| replace:: ``BOOST_NO_CXX11_STATIC_ASSERT`` +.. _BOOST_NO_CXX11_STATIC_ASSERT: ../../../config/doc/html/boost_config/boost_macro_reference.html +.. |BOOST_NO_CXX11_HDR_TYPE_TRAITS| replace:: ``BOOST_NO_CXX11_HDR_TYPE_TRAITS`` +.. _BOOST_NO_CXX11_HDR_TYPE_TRAITS: ../../../config/doc/html/boost_config/boost_macro_reference.html +.. |BOOST_NO_CXX11_HDR_INITIALIZER_LIST| replace:: ``BOOST_NO_CXX11_HDR_INITIALIZER_LIST`` +.. _BOOST_NO_CXX11_HDR_INITIALIZER_LIST: ../../../config/doc/html/boost_config/boost_macro_reference.html +.. |BOOST_NO_CXX11_HDR_TUPLE| replace:: ``BOOST_NO_CXX11_HDR_TUPLE`` +.. _BOOST_NO_CXX11_HDR_TUPLE: ../../../config/doc/html/boost_config/boost_macro_reference.html +.. _`Boost.MP11`: ../../../mp11/doc/html/mp11.html +.. _`Boost.Config`: ../../../config/doc/html/index.html + +:Defined in: `boost/parameter/config.hpp`__ + +__ ../../../../boost/parameter/config.hpp + +``BOOST_PARAMETER_DISABLE_MP11_USAGE`` +-------------------------------------- + +It may be necessary to disable usage of `Boost.MP11`_ for compilers that +cannot support it. Users can ``#define`` this macro either in their project +settings or before including any library header files. Doing so will leave +|BOOST_PARAMETER_CAN_USE_MP11| undefined. + +.. |BOOST_PARAMETER_CAN_USE_MP11| replace:: ``BOOST_PARAMETER_CAN_USE_MP11`` +.. _`Boost.MP11`: ../../../mp11/doc/html/mp11.html ``BOOST_PARAMETER_VARIADIC_MPL_SEQUENCE`` ----------------------------------------- @@ -2382,7 +6747,8 @@ settings or before including any library header files. Doing so will leave If |BOOST_PARAMETER_HAS_PERFECT_FORWARDING| is ``#defined``, then determines the `MPL Variadic Sequence`_ underlying the nested ``parameter_spec`` type of |parameters|. If the user does not manually ``#define`` this macro, then the -library will ``#define`` it as |boost_fusion_list|_ if +library will ``#define`` it as |boost_mp11_list|_ if +|BOOST_PARAMETER_CAN_USE_MP11| is defined, |boost_fusion_list|_ if |BOOST_FUSION_HAS_VARIADIC_LIST|_ is defined (by `Boost.Fusion`_), |boost_fusion_deque|_ if |BOOST_FUSION_HAS_VARIADIC_DEQUE|_ is defined (by `Boost.Fusion`_), or |boost_mpl_vector|_ otherwise. @@ -2394,9 +6760,12 @@ library will ``#define`` it as |boost_fusion_list|_ if #define BOOST_PARAMETER_VARIADIC_MPL_SEQUENCE |boost_fusion_vector|_ .. |BOOST_PARAMETER_HAS_PERFECT_FORWARDING| replace:: ``BOOST_PARAMETER_HAS_PERFECT_FORWARDING`` +.. |BOOST_PARAMETER_CAN_USE_MP11| replace:: ``BOOST_PARAMETER_CAN_USE_MP11`` .. |BOOST_PARAMETER_VARIADIC_MPL_SEQUENCE| replace:: ``BOOST_PARAMETER_VARIADIC_MPL_SEQUENCE`` .. _`MPL Variadic Sequence`: ../../../mpl/doc/refmanual/variadic-sequence.html .. _`Boost.Fusion`: ../../../fusion/doc/html/index.html +.. |boost_mp11_list| replace:: ``boost\:\:mp11\:\:mp_list`` +.. _boost_mp11_list: ../../../mp11/doc/html/mp11.html .. |BOOST_FUSION_HAS_VARIADIC_LIST| replace:: ``BOOST_FUSION_HAS_VARIADIC_LIST`` .. _BOOST_FUSION_HAS_VARIADIC_LIST: ../../../../boost/fusion/container/list/list_fwd.hpp .. |boost_fusion_list| replace:: ``boost\:\:fusion\:\:list`` @@ -2417,13 +6786,11 @@ __ ../../../../boost/parameter/parameters.hpp ``BOOST_PARAMETER_MAX_ARITY`` ----------------------------- -Determines the maximum number of arguments supported by the library. - If |BOOST_PARAMETER_HAS_PERFECT_FORWARDING| is ``#defined``, then: \*. If the `MPL Variadic Sequence`_ underlying the nested ``parameter_spec`` type of |parameters| does not have a size limit--which is the case with -|boost_fusion_list|_ and |boost_fusion_deque|_, but not +|boost_mp11_list|_, |boost_fusion_list|_, and |boost_fusion_deque|_, but not |boost_mpl_vector|_--then this macro can be safely ignored. User code that manually defines |BOOST_PARAMETER_VARIADIC_MPL_SEQUENCE| should also manually define this macro to the size limit of the sequence if it has one. @@ -2438,6 +6805,8 @@ equal to ``BOOST_PARAMETER_EXPONENTIAL_OVERLOAD_THRESHOLD_ARITY``. .. |BOOST_PARAMETER_VARIADIC_MPL_SEQUENCE| replace:: ``BOOST_PARAMETER_VARIADIC_MPL_SEQUENCE`` .. |BOOST_PARAMETER_MAX_ARITY| replace:: ``BOOST_PARAMETER_MAX_ARITY`` .. _`MPL Variadic Sequence`: ../../../mpl/doc/refmanual/variadic-sequence.html +.. |boost_mp11_list| replace:: ``boost\:\:mp11\:\:mp_list`` +.. _boost_mp11_list: ../../../mp11/doc/html/mp11.html .. |boost_fusion_list| replace:: ``boost\:\:fusion\:\:list`` .. _boost_fusion_list: ../../../fusion/doc/html/fusion/container/list.html .. |boost_fusion_deque| replace:: ``boost\:\:fusion\:\:deque`` @@ -2453,7 +6822,8 @@ equal to ``BOOST_PARAMETER_EXPONENTIAL_OVERLOAD_THRESHOLD_ARITY``. __ ../../../../boost/parameter/config.hpp -:Default Value: |BOOST_MPL_LIMIT_VECTOR_SIZE|_ (defined by `Boost.MPL`_) if perfect forwarding is supported, ``8`` otherwise. +:Default Value: |BOOST_MPL_LIMIT_VECTOR_SIZE|_ (defined by `Boost.MPL`_) if +perfect forwarding is supported, ``8`` otherwise. :Minimum Value: ``2`` .. |BOOST_MPL_LIMIT_VECTOR_SIZE| replace:: ``BOOST_MPL_LIMIT_VECTOR_SIZE`` @@ -2483,22 +6853,54 @@ __ ../../../../boost/parameter/config.hpp -------------------------- #. If `Boost.Config`_ defines the macro -|BOOST_NO_FUNCTION_TEMPLATE_ORDERING|_, then the macro -|BOOST_PARAMETER_HAS_PERFECT_FORWARDING| will be left undefined; -otherwise, the code generation macros would not work correctly. +|BOOST_NO_FUNCTION_TEMPLATE_ORDERING|_, then the macros +|BOOST_PARAMETER_HAS_PERFECT_FORWARDING| and |BOOST_PARAMETER_CAN_USE_MP11| +will be left undefined; otherwise, the code generation macros would not work +correctly. -#. If `Boost.Config`_ defines the macro |BOOST_NO_SFINAE|_, then the macro -|BOOST_PARAMETER_HAS_PERFECT_FORWARDING| will be left undefined; otherwise, -keyword types generated by |BOOST_PARAMETER_NAME| and -|BOOST_PARAMETER_NESTED_KEYWORD| would not work correctly. +#. If `Boost.Config`_ defines the macro |BOOST_NO_SFINAE|_, then the macros +|BOOST_PARAMETER_HAS_PERFECT_FORWARDING| and |BOOST_PARAMETER_CAN_USE_MP11| +will be left undefined; otherwise, keyword types generated by +|BOOST_PARAMETER_NAME| and |BOOST_PARAMETER_NESTED_KEYWORD| would not work +correctly. #. If `Boost.Config`_ defines the macro |BOOST_NO_CXX11_RVALUE_REFERENCES|_, -then the macro |BOOST_PARAMETER_HAS_PERFECT_FORWARDING| will be left -undefined. +then the macros |BOOST_PARAMETER_HAS_PERFECT_FORWARDING| and +|BOOST_PARAMETER_CAN_USE_MP11| will be left undefined. #. If `Boost.Config`_ defines the macro |BOOST_NO_CXX11_VARIADIC_TEMPLATES|_, -then the macro |BOOST_PARAMETER_HAS_PERFECT_FORWARDING| will be left -undefined. +then the macros |BOOST_PARAMETER_HAS_PERFECT_FORWARDING| and +|BOOST_PARAMETER_CAN_USE_MP11| will be left undefined. + +#. If `Boost.Config`_ defines the macro +|BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS|_, then the macros +|BOOST_PARAMETER_HAS_PERFECT_FORWARDING| and |BOOST_PARAMETER_CAN_USE_MP11| +will be left undefined. + +#. If `Boost.Config`_ defines the macro |BOOST_NO_CXX11_CONSTEXPR|_, then the +macro |BOOST_PARAMETER_CAN_USE_MP11| will be left undefined. + +#. If `Boost.Config`_ defines the macro |BOOST_NO_CXX11_DECLTYPE_N3276|_, then +the macro |BOOST_PARAMETER_CAN_USE_MP11| will be left undefined. + +#. If `Boost.Config`_ defines the macro |BOOST_NO_CXX11_AUTO_DECLARATIONS|_, +then the macro |BOOST_PARAMETER_CAN_USE_MP11| will be left undefined. + +#. If `Boost.Config`_ defines the macro |BOOST_NO_CXX11_TEMPLATE_ALIASES|_, +then the macro |BOOST_PARAMETER_CAN_USE_MP11| will be left undefined. + +#. If `Boost.Config`_ defines the macro |BOOST_NO_CXX11_STATIC_ASSERT|_, then +the macro |BOOST_PARAMETER_CAN_USE_MP11| will be left undefined. + +#. If `Boost.Config`_ defines the macro |BOOST_NO_CXX11_HDR_TYPE_TRAITS|_, +then the macro |BOOST_PARAMETER_CAN_USE_MP11| will be left undefined. + +#. If `Boost.Config`_ defines the macro +|BOOST_NO_CXX11_HDR_INITIALIZER_LIST|_, then the macro +|BOOST_PARAMETER_CAN_USE_MP11| will be left undefined. + +#. If `Boost.Config`_ defines the macro |BOOST_NO_CXX11_HDR_TUPLE|_, then the +macro |BOOST_PARAMETER_CAN_USE_MP11| will be left undefined. #. If `Boost.Fusion`_ defines the macro |BOOST_FUSION_HAS_VARIADIC_LIST|_, if this library defines the macro |BOOST_PARAMETER_HAS_PERFECT_FORWARDING|, @@ -2530,6 +6932,8 @@ the macro |BOOST_PARAMETER_MAX_ARITY| as if this library defines the macro .. _BOOST_NO_CXX11_RVALUE_REFERENCES: ../../../config/doc/html/boost_config/boost_macro_reference.html .. |BOOST_NO_CXX11_VARIADIC_TEMPLATES| replace:: ``BOOST_NO_CXX11_VARIADIC_TEMPLATES`` .. _BOOST_NO_CXX11_VARIADIC_TEMPLATES: ../../../config/doc/html/boost_config/boost_macro_reference.html +.. |BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS| replace:: ``BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS`` +.. _BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS: ../../../config/doc/html/boost_config/boost_macro_reference.html .. |BOOST_FUSION_HAS_VARIADIC_LIST| replace:: ``BOOST_FUSION_HAS_VARIADIC_LIST`` .. _BOOST_FUSION_HAS_VARIADIC_LIST: ../../../../boost/fusion/container/list/list_fwd.hpp .. |BOOST_FUSION_HAS_VARIADIC_DEQUE| replace:: ``BOOST_FUSION_HAS_VARIADIC_DEQUE`` diff --git a/include/boost/parameter.hpp b/include/boost/parameter.hpp index aa5e107..b6e666c 100644 --- a/include/boost/parameter.hpp +++ b/include/boost/parameter.hpp @@ -9,6 +9,7 @@ #define BOOST_PARAMETER_050401_HPP #include +#include #include #include #include @@ -21,7 +22,9 @@ #include #include #include +#include #include +#include #endif // include guard diff --git a/include/boost/parameter/are_tagged_arguments.hpp b/include/boost/parameter/are_tagged_arguments.hpp new file mode 100644 index 0000000..9a74444 --- /dev/null +++ b/include/boost/parameter/are_tagged_arguments.hpp @@ -0,0 +1,125 @@ +// Copyright Cromwell D. Enage 2018. +// 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_ARE_TAGGED_ARGUMENTS_HPP +#define BOOST_PARAMETER_ARE_TAGGED_ARGUMENTS_HPP + +#include + +#if defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING) + +namespace boost { namespace parameter { + + template + struct are_tagged_arguments; +}} // namespace boost::parameter + +#include + +namespace boost { namespace parameter { + + template + struct are_tagged_arguments + : ::boost::parameter::aux::is_tagged_argument + { + }; +}} // namespace boost::parameter + +#include +#include + +namespace boost { namespace parameter { + + template + struct are_tagged_arguments + : ::boost::mpl::if_< + ::boost::parameter::aux::is_tagged_argument + , ::boost::parameter::are_tagged_arguments + , ::boost::mpl::false_ + >::type + { + }; +}} // namespace boost::parameter + +#else // !defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING) + +#define BOOST_PARAMETER_ARE_TAGGED_ARGUMENTS_END_Z(z, n, false_t) , false_t> +/**/ + +#include +#include +#include + +#define BOOST_PARAMETER_ARE_TAGGED_ARGUMENTS_BEGIN_Z(z, n, prefix) \ + ::boost::mpl::eval_if< \ + ::boost::parameter::aux::is_tagged_argument, +/**/ + +#include +#include +#include +#include +#include +#include +#include + +#define BOOST_PARAMETER_ARE_TAGGED_ARGUMENTS_OVERLOADS_Z(z, n, prefix) \ + template \ + struct are_tagged_arguments< \ + BOOST_PP_ENUM_PARAMS_Z(z, n, prefix) \ + BOOST_PP_ENUM_TRAILING_PARAMS_Z( \ + z \ + , BOOST_PP_SUB(BOOST_PARAMETER_MAX_ARITY, n) \ + , ::boost::parameter::void_ BOOST_PP_INTERCEPT \ + ) \ + > : BOOST_PP_CAT(BOOST_PP_REPEAT_, z)( \ + n \ + , BOOST_PARAMETER_ARE_TAGGED_ARGUMENTS_BEGIN_Z \ + , prefix \ + ) \ + ::boost::mpl::true_ \ + BOOST_PP_CAT(BOOST_PP_REPEAT_, z)( \ + n \ + , BOOST_PARAMETER_ARE_TAGGED_ARGUMENTS_END_Z \ + , ::boost::mpl::false_ \ + )::type \ + { \ + }; +/**/ + +#include +#include + +namespace boost { namespace parameter { + + template < + BOOST_PP_ENUM_BINARY_PARAMS( + BOOST_PP_INC(BOOST_PARAMETER_MAX_ARITY) + , typename TaggedArg + , = ::boost::parameter::void_ BOOST_PP_INTERCEPT + ) + > + struct are_tagged_arguments; +}} // namespace boost::parameter + +#include + +namespace boost { namespace parameter { + + BOOST_PP_REPEAT_FROM_TO( + 1 + , BOOST_PP_INC(BOOST_PARAMETER_MAX_ARITY) + , BOOST_PARAMETER_ARE_TAGGED_ARGUMENTS_OVERLOADS_Z + , TaggedArg + ) +}} // namespace boost::parameter + +#undef BOOST_PARAMETER_ARE_TAGGED_ARGUMENTS_OVERLOADS_Z +#undef BOOST_PARAMETER_ARE_TAGGED_ARGUMENTS_BEGIN_Z +#undef BOOST_PARAMETER_ARE_TAGGED_ARGUMENTS_END_Z + +#endif // BOOST_PARAMETER_HAS_PERFECT_FORWARDING +#endif // include guard + diff --git a/include/boost/parameter/aux_/arg_list.hpp b/include/boost/parameter/aux_/arg_list.hpp index e49bf77..6c78bf5 100644 --- a/include/boost/parameter/aux_/arg_list.hpp +++ b/include/boost/parameter/aux_/arg_list.hpp @@ -144,6 +144,7 @@ namespace boost { namespace parameter { namespace aux { #include #include #include +#include namespace boost { namespace parameter { namespace aux { @@ -153,9 +154,13 @@ namespace boost { namespace parameter { namespace aux { template < typename TaggedArg , typename Next = ::boost::parameter::aux::empty_arg_list + , typename EmitsErrors = ::boost::mpl::true_ > - struct arg_list : Next + class arg_list : public Next { + TaggedArg arg; // Stores the argument + + public: typedef TaggedArg tagged_arg; typedef ::boost::parameter::aux::arg_list self; typedef typename TaggedArg::key_type key_type; @@ -176,8 +181,6 @@ namespace boost { namespace parameter { namespace aux { , typename TaggedArg::value_type >::type value_type; - TaggedArg arg; // Stores the argument - // Create a new list by prepending arg to a copy of tail. Used when // incrementally building this structure with the comma operator. inline arg_list(TaggedArg const& head, Next const& tail) @@ -276,16 +279,22 @@ namespace boost { namespace parameter { namespace aux { static ::boost::parameter::aux::yes_tag has_key(key_type*); using Next::has_key; - BOOST_MPL_ASSERT_MSG( + private: + typedef ::boost::mpl::bool_< sizeof( Next::has_key( static_cast(BOOST_TTI_DETAIL_NULLPTR) ) ) == sizeof(::boost::parameter::aux::no_tag) + > _has_unique_key; + + BOOST_MPL_ASSERT_MSG( + !(EmitsErrors::value) || (_has_unique_key::value) , duplicate_keyword , (key_type) ); + public: // // Begin implementation of indexing operators // for looking up specific arguments by name. @@ -356,11 +365,18 @@ namespace boost { namespace parameter { namespace aux { // satisfied by TaggedArg. Used only for compile-time computation // and never really called, so a declaration is enough. template - static typename ::boost::mpl::apply_wrap2< - ::boost::parameter::aux - ::augment_predicate - , value_type - , ArgPack + static typename ::boost::lazy_enable_if< + typename ::boost::mpl::if_< + EmitsErrors + , ::boost::mpl::true_ + , _has_unique_key + >::type + , ::boost::mpl::apply_wrap2< + ::boost::parameter::aux + ::augment_predicate + , value_type + , ArgPack + > >::type satisfies( ::boost::parameter::aux::parameter_requirements< @@ -524,6 +540,10 @@ namespace boost { namespace parameter { namespace aux { #include #include +#if !defined(BOOST_NO_SFINAE) && !BOOST_WORKAROUND(BOOST_MSVC, < 1800) +#include +#endif + #if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) #include #endif @@ -535,9 +555,13 @@ namespace boost { namespace parameter { namespace aux { template < typename TaggedArg , typename Next = ::boost::parameter::aux::empty_arg_list + , typename EmitsErrors = ::boost::mpl::true_ > - struct arg_list : Next + class arg_list : public Next { + TaggedArg arg; // Stores the argument + + public: typedef TaggedArg tagged_arg; typedef ::boost::parameter::aux::arg_list self; typedef typename TaggedArg::key_type key_type; @@ -558,8 +582,6 @@ namespace boost { namespace parameter { namespace aux { , typename TaggedArg::value_type >::type value_type; - TaggedArg arg; // Stores the argument - // Create a new list by prepending arg to a copy of tail. Used when // incrementally building this structure with the comma operator. inline arg_list(TaggedArg const& head, Next const& tail) @@ -613,6 +635,7 @@ namespace boost { namespace parameter { namespace aux { static ::boost::parameter::aux::yes_tag has_key(key_type*); using Next::has_key; +#if defined(BOOST_NO_SFINAE) || BOOST_WORKAROUND(BOOST_MSVC, < 1800) BOOST_MPL_ASSERT_MSG( sizeof( Next::has_key( @@ -622,8 +645,25 @@ namespace boost { namespace parameter { namespace aux { , duplicate_keyword , (key_type) ); -#endif +#else + private: + typedef ::boost::mpl::bool_< + sizeof( + Next::has_key( + static_cast(BOOST_TTI_DETAIL_NULLPTR) + ) + ) == sizeof(::boost::parameter::aux::no_tag) + > _has_unique_key; + BOOST_MPL_ASSERT_MSG( + !(EmitsErrors::value) || (_has_unique_key::value) + , duplicate_keyword + , (key_type) + ); +#endif +#endif // Borland workarounds not needed. + + public: // // Begin implementation of indexing operators // for looking up specific arguments by name. @@ -786,11 +826,23 @@ namespace boost { namespace parameter { namespace aux { // satisfied by TaggedArg. Used only for compile-time computation // and never really called, so a declaration is enough. template - static typename ::boost::mpl::apply_wrap2< - ::boost::parameter::aux - ::augment_predicate - , value_type - , ArgPack + static typename +#if !defined(BOOST_NO_SFINAE) && !BOOST_WORKAROUND(BOOST_MSVC, < 1800) + ::boost::lazy_enable_if< + typename ::boost::mpl::if_< + EmitsErrors + , ::boost::mpl::true_ + , _has_unique_key + >::type, +#endif + ::boost::mpl::apply_wrap2< + ::boost::parameter::aux + ::augment_predicate + , value_type + , ArgPack +#if !defined(BOOST_NO_SFINAE) && !BOOST_WORKAROUND(BOOST_MSVC, < 1800) + > +#endif >::type satisfies( ::boost::parameter::aux::parameter_requirements< diff --git a/include/boost/parameter/aux_/pack/deduce_tag.hpp b/include/boost/parameter/aux_/pack/deduce_tag.hpp index d95b94b..07295ad 100644 --- a/include/boost/parameter/aux_/pack/deduce_tag.hpp +++ b/include/boost/parameter/aux_/pack/deduce_tag.hpp @@ -14,6 +14,7 @@ namespace boost { namespace parameter { namespace aux { , typename DeducedArgs , typename UsedArgs , typename TagFn + , typename EmitsErrors > struct deduce_tag; }}} // namespace boost::parameter::aux @@ -38,45 +39,53 @@ namespace boost { namespace parameter { namespace aux { , typename DeducedArgs , typename UsedArgs , typename TagFn + , typename EmitsErrors > - struct deduce_tag0 + class deduce_tag0 { - typedef typename DeducedArgs::spec spec; + typedef typename DeducedArgs::spec _spec; typedef typename ::boost::mpl::apply_wrap2< typename ::boost::mpl::lambda< - typename spec::predicate + typename _spec::predicate , ::boost::parameter::aux::lambda_tag >::type , Argument , ArgumentPack - >::type condition; + >::type _condition; // Deduced parameter matches several arguments. BOOST_MPL_ASSERT(( typename ::boost::mpl::eval_if< typename ::boost::parameter::aux::has_key_< UsedArgs - , typename ::boost::parameter::aux::tag_type::type + , typename ::boost::parameter::aux::tag_type<_spec>::type >::type - , ::boost::mpl::if_< - condition - , ::boost::mpl::false_ + , ::boost::mpl::eval_if< + _condition + , ::boost::mpl::if_< + EmitsErrors + , ::boost::mpl::false_ + , ::boost::mpl::true_ + > , ::boost::mpl::true_ > , ::boost::mpl::true_ >::type )); + public: typedef typename ::boost::mpl::eval_if< - condition - , ::boost::parameter::aux::tag_deduced + _condition + , ::boost::parameter::aux + ::tag_deduced , ::boost::parameter::aux::deduce_tag< Argument , ArgumentPack , typename DeducedArgs::tail , UsedArgs , TagFn + , EmitsErrors > >::type type; }; @@ -108,6 +117,7 @@ namespace boost { namespace parameter { namespace aux { , typename DeducedArgs , typename UsedArgs , typename TagFn + , typename EmitsErrors > struct deduce_tag : ::boost::mpl::eval_if< @@ -119,6 +129,7 @@ namespace boost { namespace parameter { namespace aux { , DeducedArgs , UsedArgs , TagFn + , EmitsErrors > > { diff --git a/include/boost/parameter/aux_/pack/make_arg_list.hpp b/include/boost/parameter/aux_/pack/make_arg_list.hpp index d80e3f4..bf0b1d0 100644 --- a/include/boost/parameter/aux_/pack/make_arg_list.hpp +++ b/include/boost/parameter/aux_/pack/make_arg_list.hpp @@ -12,10 +12,11 @@ namespace boost { namespace parameter { namespace aux { typename List , typename DeducedArgs , typename TagFn - , typename Positional + , typename IsPositional , typename UsedArgs , typename ArgumentPack , typename Error + , typename EmitsErrors > struct make_arg_list_aux; }}} // namespace boost::parameter::aux @@ -47,117 +48,126 @@ namespace boost { namespace parameter { namespace aux { typename List , typename DeducedArgs , typename TagFn - , typename Positional + , typename IsPositional , typename UsedArgs , typename ArgumentPack #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) - , typename argument + , typename _argument #endif , typename Error + , typename EmitsErrors > #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) - struct make_arg_list00 + class make_arg_list00 #else - struct make_arg_list0 + class make_arg_list0 #endif { #if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) - typedef typename List::arg argument; + typedef typename List::arg _argument; #endif typedef typename ::boost::remove_const< - typename ::boost::remove_reference::type - >::type arg_type; - typedef typename List::spec parameter_spec; + typename ::boost::remove_reference<_argument>::type + >::type _arg_type; + typedef typename List::spec _parameter_spec; typedef typename ::boost::parameter::aux - ::tag_type::type tag_; + ::tag_type<_parameter_spec>::type _tag; typedef ::boost::parameter::aux - ::is_named_argument is_tagged; + ::is_named_argument<_argument> _is_tagged; // If this argument is either explicitly tagged or a deduced // parameter, then turn off positional matching. typedef typename ::boost::mpl::eval_if< - Positional + IsPositional , ::boost::mpl::eval_if< - ::boost::parameter::aux::is_deduced + ::boost::parameter::aux::is_deduced<_parameter_spec> , ::boost::mpl::false_ , ::boost::mpl::if_< - is_tagged + _is_tagged , ::boost::mpl::false_ , ::boost::mpl::true_ > > , ::boost::mpl::false_ - >::type positional; + >::type _is_positional; // If this parameter is explicitly tagged, then add it to the // used-parmeters set. We only really need to add parameters // that are deduced, but we would need a way to check if // a given tag corresponds to a deduced parameter spec. typedef typename ::boost::mpl::eval_if< - is_tagged - , ::boost::parameter::aux::insert_tagged + _is_tagged + , ::boost::parameter::aux::insert_tagged , ::boost::mpl::identity - >::type used_args; + >::type _used_args; // If this parameter is neither explicitly tagged nor positionally // matched, then deduce the tag from the deduced parameter specs. typedef typename ::boost::mpl::eval_if< typename ::boost::mpl::if_< - is_tagged + _is_tagged , ::boost::mpl::true_ - , positional + , _is_positional >::type - , ::boost::mpl::pair< ::boost::parameter::void_,used_args> + , ::boost::mpl::pair< ::boost::parameter::void_,_used_args> , ::boost::parameter::aux::deduce_tag< - argument + _argument , ArgumentPack , DeducedArgs - , used_args + , _used_args , TagFn + , EmitsErrors > - >::type deduced_data; + >::type _deduced_data; // If this parameter is explicitly tagged ... typedef typename ::boost::mpl::eval_if< - is_tagged + _is_tagged // ... just use it - , ::boost::mpl::identity + , ::boost::mpl::identity<_arg_type> // ... else ... , ::boost::mpl::eval_if< // if positional matching is turned on ... - positional + _is_positional // ... tag it positionally - , ::boost::mpl::apply_wrap2 + , ::boost::mpl::apply_wrap2 // ... else, use the deduced tag - , ::boost::mpl::first + , ::boost::mpl::first<_deduced_data> > - >::type tagged; + >::type _tagged; // Build the arg_list incrementally, prepending new nodes. typedef typename ::boost::mpl::if_< typename ::boost::mpl::if_< ::boost::is_same - , ::boost::is_same + , ::boost::is_same<_tagged,::boost::parameter::void_> , ::boost::mpl::false_ >::type - , ::boost::parameter::aux::unmatched_argument + , ::boost::parameter::aux::unmatched_argument<_argument> , ::boost::parameter::void_ >::type error; typedef typename ::boost::mpl::if_< - ::boost::is_same + ::boost::is_same<_tagged,::boost::parameter::void_> , ArgumentPack - , ::boost::parameter::aux::arg_list - >::type argument_pack; +#if defined(BOOST_NO_SFINAE) || BOOST_WORKAROUND(BOOST_MSVC, < 1800) + , ::boost::parameter::aux::arg_list<_tagged,ArgumentPack> +#else + , ::boost::parameter::aux + ::arg_list<_tagged,ArgumentPack,EmitsErrors> +#endif + >::type _argument_pack; + public: typedef typename ::boost::parameter::aux::make_arg_list_aux< typename List::tail , DeducedArgs , TagFn - , positional - , typename deduced_data::second - , argument_pack + , _is_positional + , typename _deduced_data::second + , _argument_pack , error + , EmitsErrors >::type type; }; @@ -166,10 +176,11 @@ namespace boost { namespace parameter { namespace aux { typename List , typename DeducedArgs , typename TagFn - , typename Positional + , typename IsPositional , typename UsedArgs , typename ArgumentPack , typename Error + , typename EmitsErrors > struct make_arg_list0 { @@ -179,21 +190,23 @@ namespace boost { namespace parameter { namespace aux { List , DeducedArgs , TagFn - , Positional + , IsPositional , UsedArgs , ArgumentPack , typename List::arg const , Error + , EmitsErrors > , ::boost::parameter::aux::make_arg_list00< List , DeducedArgs , TagFn - , Positional + , IsPositional , UsedArgs , ArgumentPack , typename List::arg , Error + , EmitsErrors > >::type type; }; @@ -211,7 +224,7 @@ namespace boost { namespace parameter { namespace aux { // TagFn: A metafunction class used to tag positional or deduced // arguments with a keyword tag. // - // Positional: An mpl::bool_<> specialization indicating if positional + // IsPositional: An mpl::bool_<> specialization indicating if positional // matching is to be performed. // // DeducedSet: An mpl::set<> containing the keyword tags used so far. @@ -222,10 +235,11 @@ namespace boost { namespace parameter { namespace aux { typename List , typename DeducedArgs , typename TagFn - , typename Positional + , typename IsPositional , typename DeducedSet , typename ArgumentPack , typename Error + , typename EmitsErrors > struct make_arg_list_aux : ::boost::mpl::eval_if< @@ -235,10 +249,11 @@ namespace boost { namespace parameter { namespace aux { List , DeducedArgs , TagFn - , Positional + , IsPositional , DeducedSet , ArgumentPack , Error + , EmitsErrors > > { @@ -255,7 +270,7 @@ namespace boost { namespace parameter { namespace aux { typename List , typename DeducedArgs , typename TagFn - , typename EmitErrors = ::boost::mpl::true_ + , typename EmitsErrors = ::boost::mpl::true_ > struct make_arg_list : ::boost::parameter::aux::make_arg_list_aux< @@ -266,6 +281,7 @@ namespace boost { namespace parameter { namespace aux { , ::boost::parameter::aux::set0 , ::boost::parameter::aux::empty_arg_list , ::boost::parameter::void_ + , EmitsErrors > { }; diff --git a/include/boost/parameter/aux_/pack/satisfies.hpp b/include/boost/parameter/aux_/pack/satisfies.hpp index f201a1e..10b7d26 100644 --- a/include/boost/parameter/aux_/pack/satisfies.hpp +++ b/include/boost/parameter/aux_/pack/satisfies.hpp @@ -11,6 +11,7 @@ #include #if BOOST_WORKAROUND(BOOST_MSVC, == 1310) +#include #include #include #include @@ -23,6 +24,22 @@ namespace boost { namespace parameter { namespace aux { +#if BOOST_WORKAROUND(BOOST_MSVC, == 1310) + template + struct satisfies_impl + : ::boost::mpl::apply_wrap2< + ::boost::parameter::aux::augment_predicate< + typename ParameterRequirements::predicate + , typename ArgList::reference + , typename ArgList::key_type + > + , Bound + , ArgList + > + { + }; +#endif + // Returns mpl::true_ iff the given ParameterRequirements are satisfied by // ArgList. template @@ -41,14 +58,17 @@ namespace boost { namespace parameter { namespace aux { typedef typename ::boost::mpl::eval_if< ::boost::is_same , typename ParameterRequirements::has_default - , ::boost::mpl::apply_wrap2< - ::boost::parameter::aux::augment_predicate< - typename ParameterRequirements::predicate - , typename ArgList::reference - , typename ArgList::key_type + , ::boost::mpl::eval_if< + ::boost::is_same< + ArgList + , ::boost::parameter::aux::empty_arg_list + > + , ::boost::mpl::false_ + , ::boost::parameter::aux::satisfies_impl< + ArgList + , ParameterRequirements + , bound > - , bound - , ArgList > >::type type; #else // !BOOST_WORKAROUND(BOOST_MSVC, == 1310) @@ -83,7 +103,7 @@ namespace boost { namespace parameter { namespace aux { ArgList , typename ::boost::parameter::aux ::as_parameter_requirements::type - > + >::type { }; }}} // namespace boost::parameter::aux diff --git a/include/boost/parameter/aux_/preprocessor/impl/forwarding_overloads.hpp b/include/boost/parameter/aux_/preprocessor/impl/forwarding_overloads.hpp index 24402f1..f5eb7ab 100644 --- a/include/boost/parameter/aux_/preprocessor/impl/forwarding_overloads.hpp +++ b/include/boost/parameter/aux_/preprocessor/impl/forwarding_overloads.hpp @@ -47,23 +47,29 @@ // Expands to a 0-arity forwarding function, whose job is to pass an empty // pack to the front-end implementation function. #define BOOST_PARAMETER_FUNCTION_FORWARD_OVERLOAD_0_Z(z, n, data) \ - BOOST_PARAMETER_MEMBER_FUNCTION_STATIC(BOOST_PP_TUPLE_ELEM(3, 1, data)) \ - inline \ - BOOST_PARAMETER_FUNCTION_RESULT_NAME(BOOST_PP_TUPLE_ELEM(3, 1, data))< \ + BOOST_PARAMETER_MEMBER_FUNCTION_STATIC(BOOST_PP_TUPLE_ELEM(4, 1, data)) \ + inline BOOST_PARAMETER_FUNCTION_RESULT_NAME( \ + BOOST_PP_TUPLE_ELEM(4, 1, data) \ + , BOOST_PP_TUPLE_ELEM(4, 3, data) \ + )< \ ::boost::parameter::aux::argument_pack< \ BOOST_PARAMETER_FUNCTION_SPECIFICATION_NAME( \ - BOOST_PP_TUPLE_ELEM(3, 1, data) \ + BOOST_PP_TUPLE_ELEM(4, 1, data) \ + , BOOST_PP_TUPLE_ELEM(4, 3, data) \ ) \ >::type \ >::type \ BOOST_PARAMETER_MEMBER_FUNCTION_NAME(BOOST_PP_TUPLE_ELEM(3, 0, data))() \ - BOOST_PP_EXPR_IF(BOOST_PP_TUPLE_ELEM(3, 2, data), const) \ + BOOST_PP_EXPR_IF(BOOST_PP_TUPLE_ELEM(4, 3, data), const) \ { \ - return BOOST_PARAMETER_FUNCTION_IMPL_NAME( \ - BOOST_PP_TUPLE_ELEM(3, 1, data) \ + return BOOST_PP_EXPR_IF(BOOST_PP_TUPLE_ELEM(4, 2, data), this->) \ + BOOST_PARAMETER_FUNCTION_IMPL_NAME( \ + BOOST_PP_TUPLE_ELEM(4, 1, data) \ + , BOOST_PP_TUPLE_ELEM(4, 3, data) \ )( \ BOOST_PARAMETER_FUNCTION_SPECIFICATION_NAME( \ - BOOST_PP_TUPLE_ELEM(3, 1, data) \ + BOOST_PP_TUPLE_ELEM(4, 1, data) \ + , BOOST_PP_TUPLE_ELEM(4, 3, data) \ )()() \ ); \ } @@ -78,12 +84,15 @@ // into a pack for the front-end implementation function to take in. #define BOOST_PARAMETER_FUNCTION_FORWARD_OVERLOAD_1_Z(z, n, data) \ template \ - BOOST_PARAMETER_MEMBER_FUNCTION_STATIC(BOOST_PP_TUPLE_ELEM(3, 1, data)) \ - inline typename \ - BOOST_PARAMETER_FUNCTION_RESULT_NAME(BOOST_PP_TUPLE_ELEM(3, 1, data))< \ + BOOST_PARAMETER_MEMBER_FUNCTION_STATIC(BOOST_PP_TUPLE_ELEM(4, 1, data)) \ + inline typename BOOST_PARAMETER_FUNCTION_RESULT_NAME( \ + BOOST_PP_TUPLE_ELEM(4, 1, data) \ + , BOOST_PP_TUPLE_ELEM(4, 3, data) \ + )< \ typename ::boost::parameter::aux::argument_pack< \ BOOST_PARAMETER_FUNCTION_SPECIFICATION_NAME( \ - BOOST_PP_TUPLE_ELEM(3, 1, data) \ + BOOST_PP_TUPLE_ELEM(4, 1, data) \ + , BOOST_PP_TUPLE_ELEM(4, 3, data) \ ) \ , BOOST_PP_CAT(BOOST_PP_ENUM_, z)( \ n \ @@ -92,23 +101,27 @@ ) \ >::type \ >::type \ - BOOST_PARAMETER_MEMBER_FUNCTION_NAME(BOOST_PP_TUPLE_ELEM(3, 0, data))( \ + BOOST_PARAMETER_MEMBER_FUNCTION_NAME(BOOST_PP_TUPLE_ELEM(4, 0, data))( \ BOOST_PP_ENUM_BINARY_PARAMS_Z(z, n, ParameterArgumentType, && a) \ BOOST_PARAMETER_FUNCTION_FORWARD_MATCH_Z( \ z \ , BOOST_PARAMETER_FUNCTION_SPECIFICATION_NAME( \ - BOOST_PP_TUPLE_ELEM(3, 1, data) \ + BOOST_PP_TUPLE_ELEM(4, 1, data) \ + , BOOST_PP_TUPLE_ELEM(4, 3, data) \ ) \ , n \ , ParameterArgumentType \ ) \ - ) BOOST_PP_EXPR_IF(BOOST_PP_TUPLE_ELEM(3, 2, data), const) \ + ) BOOST_PP_EXPR_IF(BOOST_PP_TUPLE_ELEM(4, 3, data), const) \ { \ - return BOOST_PARAMETER_FUNCTION_IMPL_NAME( \ - BOOST_PP_TUPLE_ELEM(3, 1, data) \ + return BOOST_PP_EXPR_IF(BOOST_PP_TUPLE_ELEM(4, 2, data), this->) \ + BOOST_PARAMETER_FUNCTION_IMPL_NAME( \ + BOOST_PP_TUPLE_ELEM(4, 1, data) \ + , BOOST_PP_TUPLE_ELEM(4, 3, data) \ )( \ BOOST_PARAMETER_FUNCTION_SPECIFICATION_NAME( \ - BOOST_PP_TUPLE_ELEM(3, 1, data) \ + BOOST_PP_TUPLE_ELEM(4, 1, data) \ + , BOOST_PP_TUPLE_ELEM(4, 3, data) \ )()( \ BOOST_PP_CAT(BOOST_PP_ENUM_, z)( \ n \ @@ -169,12 +182,21 @@ #include // Helper macro for BOOST_PARAMETER_FUNCTION_FORWARD_OVERLOADS. -#define BOOST_PARAMETER_FUNCTION_FORWARD_OVERLOADS_AUX(name, impl, range, c) \ +#define BOOST_PARAMETER_FUNCTION_FORWARD_OVERLOADS_AUX(nm, impl, r, is_m, c) \ BOOST_PP_REPEAT_FROM_TO( \ - BOOST_PP_TUPLE_ELEM(2, 0, range) \ - , BOOST_PP_TUPLE_ELEM(2, 1, range) \ + BOOST_PP_TUPLE_ELEM(2, 0, r) \ + , BOOST_PP_TUPLE_ELEM(2, 1, r) \ , BOOST_PARAMETER_FUNCTION_FORWARD_OVERLOAD_Z \ - , (name, impl, c) \ + , ( \ + nm \ + , impl \ + , BOOST_PP_IF( \ + BOOST_PARAMETER_MEMBER_FUNCTION_IS_STATIC(nm) \ + , 0 \ + , is_m \ + ) \ + , c \ + ) \ ) /**/ @@ -192,9 +214,9 @@ // Expands to the layer of forwarding functions for the function with the // specified name, whose arguments determine the range of arities. -#define BOOST_PARAMETER_FUNCTION_FORWARD_OVERLOADS(name, impl, args, const_) \ +#define BOOST_PARAMETER_FUNCTION_FORWARD_OVERLOADS(name, impl, a, is_m, c) \ BOOST_PARAMETER_FUNCTION_FORWARD_OVERLOADS_AUX( \ - name, impl, BOOST_PARAMETER_ARITY_RANGE(args), const_ \ + name, impl, BOOST_PARAMETER_ARITY_RANGE(a), is_m, c \ ) /**/ @@ -236,41 +258,58 @@ #define BOOST_PARAMETER_FUNCTION_FORWARD_OVERLOAD_0_ARITY(z, n, seq) \ BOOST_PARAMETER_MEMBER_FUNCTION_STATIC( \ BOOST_PP_TUPLE_ELEM( \ - 3, 1, BOOST_PP_SEQ_HEAD(BOOST_PP_SEQ_TAIL(seq)) \ + 4, 1, BOOST_PP_SEQ_HEAD(BOOST_PP_SEQ_TAIL(seq)) \ ) \ ) \ inline BOOST_PARAMETER_FUNCTION_RESULT_NAME( \ BOOST_PP_TUPLE_ELEM( \ - 3, 1, BOOST_PP_SEQ_HEAD(BOOST_PP_SEQ_TAIL(seq)) \ + 4, 1, BOOST_PP_SEQ_HEAD(BOOST_PP_SEQ_TAIL(seq)) \ + ) \ + , BOOST_PP_TUPLE_ELEM( \ + 4, 3, BOOST_PP_SEQ_HEAD(BOOST_PP_SEQ_TAIL(seq)) \ ) \ )< \ ::boost::parameter::aux::argument_pack< \ BOOST_PARAMETER_FUNCTION_SPECIFICATION_NAME( \ BOOST_PP_TUPLE_ELEM( \ - 3, 1, BOOST_PP_SEQ_HEAD(BOOST_PP_SEQ_TAIL(seq)) \ + 4, 1, BOOST_PP_SEQ_HEAD(BOOST_PP_SEQ_TAIL(seq)) \ + ) \ + , BOOST_PP_TUPLE_ELEM( \ + 4, 3, BOOST_PP_SEQ_HEAD(BOOST_PP_SEQ_TAIL(seq)) \ ) \ ) \ >::type \ >::type \ BOOST_PARAMETER_MEMBER_FUNCTION_NAME( \ BOOST_PP_TUPLE_ELEM( \ - 3, 0, BOOST_PP_SEQ_HEAD(BOOST_PP_SEQ_TAIL(seq)) \ + 4, 0, BOOST_PP_SEQ_HEAD(BOOST_PP_SEQ_TAIL(seq)) \ ) \ )() BOOST_PP_EXPR_IF( \ BOOST_PP_TUPLE_ELEM( \ - 3, 2, BOOST_PP_SEQ_HEAD(BOOST_PP_SEQ_TAIL(seq)) \ + 4, 3, BOOST_PP_SEQ_HEAD(BOOST_PP_SEQ_TAIL(seq)) \ ) \ , const \ ) \ { \ - return BOOST_PARAMETER_FUNCTION_IMPL_NAME( \ + return BOOST_PP_EXPR_IF( \ BOOST_PP_TUPLE_ELEM( \ - 3, 1, BOOST_PP_SEQ_HEAD(BOOST_PP_SEQ_TAIL(seq)) \ + 4, 2, BOOST_PP_SEQ_HEAD(BOOST_PP_SEQ_TAIL(seq)) \ + ) \ + , this-> \ + ) BOOST_PARAMETER_FUNCTION_IMPL_NAME( \ + BOOST_PP_TUPLE_ELEM( \ + 4, 1, BOOST_PP_SEQ_HEAD(BOOST_PP_SEQ_TAIL(seq)) \ + ) \ + , BOOST_PP_TUPLE_ELEM( \ + 4, 3, BOOST_PP_SEQ_HEAD(BOOST_PP_SEQ_TAIL(seq)) \ ) \ )( \ BOOST_PARAMETER_FUNCTION_SPECIFICATION_NAME( \ BOOST_PP_TUPLE_ELEM( \ - 3, 1, BOOST_PP_SEQ_HEAD(BOOST_PP_SEQ_TAIL(seq)) \ + 4, 1, BOOST_PP_SEQ_HEAD(BOOST_PP_SEQ_TAIL(seq)) \ + ) \ + , BOOST_PP_TUPLE_ELEM( \ + 4, 3, BOOST_PP_SEQ_HEAD(BOOST_PP_SEQ_TAIL(seq)) \ ) \ )()() \ ); \ @@ -332,14 +371,16 @@ ) \ > \ BOOST_PARAMETER_MEMBER_FUNCTION_STATIC( \ - BOOST_PP_TUPLE_ELEM(3, 1, BOOST_PP_SEQ_HEAD(seq)) \ + BOOST_PP_TUPLE_ELEM(4, 1, BOOST_PP_SEQ_HEAD(seq)) \ ) \ inline typename BOOST_PARAMETER_FUNCTION_RESULT_NAME( \ - BOOST_PP_TUPLE_ELEM(3, 1, BOOST_PP_SEQ_HEAD(seq)) \ + BOOST_PP_TUPLE_ELEM(4, 1, BOOST_PP_SEQ_HEAD(seq)) \ + , BOOST_PP_TUPLE_ELEM(4, 3, BOOST_PP_SEQ_HEAD(seq)) \ )< \ typename ::boost::parameter::aux::argument_pack< \ BOOST_PARAMETER_FUNCTION_SPECIFICATION_NAME( \ - BOOST_PP_TUPLE_ELEM(3, 1, BOOST_PP_SEQ_HEAD(seq)) \ + BOOST_PP_TUPLE_ELEM(4, 1, BOOST_PP_SEQ_HEAD(seq)) \ + , BOOST_PP_TUPLE_ELEM(4, 3, BOOST_PP_SEQ_HEAD(seq)) \ ) \ , BOOST_PARAMETER_AUX_PP_BINARY_SEQ_TO_ARGS( \ BOOST_PP_SEQ_TAIL(seq), (ParameterArgumentType) \ @@ -347,27 +388,33 @@ >::type \ >::type \ BOOST_PARAMETER_MEMBER_FUNCTION_NAME( \ - BOOST_PP_TUPLE_ELEM(3, 0, BOOST_PP_SEQ_HEAD(seq)) \ + BOOST_PP_TUPLE_ELEM(4, 0, BOOST_PP_SEQ_HEAD(seq)) \ )( \ BOOST_PARAMETER_AUX_PP_BINARY_SEQ_TO_ARGS( \ BOOST_PP_SEQ_TAIL(seq), (ParameterArgumentType)(a) \ ) \ BOOST_PARAMETER_FUNCTION_FORWARD_MATCH( \ BOOST_PARAMETER_FUNCTION_SPECIFICATION_NAME( \ - BOOST_PP_TUPLE_ELEM(3, 1, BOOST_PP_SEQ_HEAD(seq)) \ + BOOST_PP_TUPLE_ELEM(4, 1, BOOST_PP_SEQ_HEAD(seq)) \ + , BOOST_PP_TUPLE_ELEM(4, 3, BOOST_PP_SEQ_HEAD(seq)) \ ) \ , BOOST_PP_SEQ_SIZE(BOOST_PP_SEQ_TAIL(seq)) \ , ParameterArgumentType \ ) \ ) BOOST_PP_EXPR_IF( \ - BOOST_PP_TUPLE_ELEM(3, 2, BOOST_PP_SEQ_HEAD(seq)), const \ + BOOST_PP_TUPLE_ELEM(4, 3, BOOST_PP_SEQ_HEAD(seq)), const \ ) \ { \ - return BOOST_PARAMETER_FUNCTION_IMPL_NAME( \ - BOOST_PP_TUPLE_ELEM(3, 1, BOOST_PP_SEQ_HEAD(seq)) \ + return BOOST_PP_EXPR_IF( \ + BOOST_PP_TUPLE_ELEM(4, 2, BOOST_PP_SEQ_HEAD(seq)) \ + , this-> \ + ) BOOST_PARAMETER_FUNCTION_IMPL_NAME( \ + BOOST_PP_TUPLE_ELEM(4, 1, BOOST_PP_SEQ_HEAD(seq)) \ + , BOOST_PP_TUPLE_ELEM(4, 3, BOOST_PP_SEQ_HEAD(seq)) \ )( \ BOOST_PARAMETER_FUNCTION_SPECIFICATION_NAME( \ - BOOST_PP_TUPLE_ELEM(3, 1, BOOST_PP_SEQ_HEAD(seq)) \ + BOOST_PP_TUPLE_ELEM(4, 1, BOOST_PP_SEQ_HEAD(seq)) \ + , BOOST_PP_TUPLE_ELEM(4, 3, BOOST_PP_SEQ_HEAD(seq)) \ )()( \ BOOST_PP_ENUM_PARAMS( \ BOOST_PP_SEQ_SIZE(BOOST_PP_SEQ_TAIL(seq)), a \ @@ -415,12 +462,21 @@ /**/ // Helper macro for BOOST_PARAMETER_FUNCTION_FORWARD_OVERLOADS. -#define BOOST_PARAMETER_FUNCTION_FORWARD_OVERLOADS_AUX(name, impl, range, c) \ +#define BOOST_PARAMETER_FUNCTION_FORWARD_OVERLOADS_AUX(nm, impl, r, is_m, c) \ BOOST_PP_REPEAT_FROM_TO( \ - BOOST_PP_TUPLE_ELEM(2, 0, range) \ - , BOOST_PP_TUPLE_ELEM(2, 1, range) \ + BOOST_PP_TUPLE_ELEM(2, 0, r) \ + , BOOST_PP_TUPLE_ELEM(2, 1, r) \ , BOOST_PARAMETER_FUNCTION_FORWARD_OVERLOAD_Z \ - , (name, impl, c) \ + , ( \ + nm \ + , impl \ + , BOOST_PP_IF( \ + BOOST_PARAMETER_MEMBER_FUNCTION_IS_STATIC(impl) \ + , 0 \ + , is_m \ + ) \ + , c \ + ) \ ) /**/ @@ -438,12 +494,13 @@ // Expands to the layer of forwarding functions for the function with the // specified name, whose arguments determine the range of arities. -#define BOOST_PARAMETER_FUNCTION_FORWARD_OVERLOADS(name, impl, args, const_) \ +#define BOOST_PARAMETER_FUNCTION_FORWARD_OVERLOADS(name, impl, a, is_m, c) \ BOOST_PARAMETER_FUNCTION_FORWARD_OVERLOADS_AUX( \ name \ , impl \ - , BOOST_PARAMETER_ARITY_RANGE(args) \ - , const_ \ + , BOOST_PARAMETER_ARITY_RANGE(a) \ + , is_m \ + , c \ ) /**/ diff --git a/include/boost/parameter/aux_/preprocessor/impl/function_dispatch_layer.hpp b/include/boost/parameter/aux_/preprocessor/impl/function_dispatch_layer.hpp index 5f98c0a..6ad837b 100644 --- a/include/boost/parameter/aux_/preprocessor/impl/function_dispatch_layer.hpp +++ b/include/boost/parameter/aux_/preprocessor/impl/function_dispatch_layer.hpp @@ -79,6 +79,24 @@ #include #include +#include + +// Produces a name for the dispatch functions. +#define BOOST_PARAMETER_FUNCTION_DISPATCH_NAME(x, n) \ + BOOST_PP_CAT( \ + BOOST_PP_CAT( \ + BOOST_PP_IF( \ + BOOST_PARAMETER_FUNCTION_DISPATCH_IS_CONST(x) \ + , boost_param_dispatch_const_ \ + , boost_param_dispatch_ \ + ) \ + , BOOST_PP_CAT(BOOST_PP_CAT(n, boost_), __LINE__) \ + ) \ + , BOOST_PARAMETER_MEMBER_FUNCTION_NAME( \ + BOOST_PARAMETER_FUNCTION_DISPATCH_BASE_NAME(x) \ + ) \ + ) +/**/ // Expands to the template parameter list of the dispatch function with all // required and first n optional parameters; also extracts the static keyword @@ -281,7 +299,10 @@ BOOST_PARAMETER_FUNCTION_DISPATCH_HEAD_TPL(n, x) \ inline BOOST_PARAMETER_FUNCTION_DISPATCH_HEAD_PRN(n, x, 0, 0) \ { \ - return BOOST_PARAMETER_FUNCTION_DISPATCH_NAME(x, 0)( \ + return BOOST_PP_EXPR_IF( \ + BOOST_PARAMETER_FUNCTION_DISPATCH_IS_MEMBER(x) \ + , this-> \ + ) BOOST_PARAMETER_FUNCTION_DISPATCH_NAME(x, 0)( \ static_cast(BOOST_TTI_DETAIL_NULLPTR) \ , args \ , 0L \ @@ -304,7 +325,10 @@ BOOST_PARAMETER_FUNCTION_DISPATCH_HEAD_TPL(n, x) \ inline BOOST_PARAMETER_FUNCTION_DISPATCH_HEAD_PRN(n, x, 1, 0) \ { \ - return BOOST_PARAMETER_FUNCTION_DISPATCH_NAME(x, 0)( \ + return BOOST_PP_EXPR_IF( \ + BOOST_PARAMETER_FUNCTION_DISPATCH_IS_MEMBER(x) \ + , this-> \ + ) BOOST_PARAMETER_FUNCTION_DISPATCH_NAME(x, 0)( \ static_cast(BOOST_TTI_DETAIL_NULLPTR) \ , args \ , 0L \ @@ -331,7 +355,10 @@ BOOST_PARAMETER_FUNCTION_DISPATCH_HEAD_TPL(n, x) \ inline BOOST_PARAMETER_FUNCTION_DISPATCH_HEAD_PRN(n, x, 0, 1) \ { \ - return BOOST_PARAMETER_FUNCTION_DISPATCH_NAME(x, 1)( \ + return BOOST_PP_EXPR_IF( \ + BOOST_PARAMETER_FUNCTION_DISPATCH_IS_MEMBER(x) \ + , this-> \ + ) BOOST_PARAMETER_FUNCTION_DISPATCH_NAME(x, 1)( \ static_cast(BOOST_TTI_DETAIL_NULLPTR) \ , (args \ , BOOST_PARAMETER_FUNCTION_DISPATCH_DEFAULT( \ @@ -357,7 +384,7 @@ // x is a tuple: // -// (base_name, split_args, is_const, tag_namespace) +// (base_name, split_args, is_member, is_const, tag_namespace) // // Generates all dispatch functions for the function named base_name. Each // dispatch function that takes in n optional parameters passes the default @@ -391,15 +418,21 @@ BOOST_PARAMETER_FUNCTION_DISPATCH_BASE_NAME(x) \ ) inline typename BOOST_PARAMETER_FUNCTION_RESULT_NAME( \ BOOST_PARAMETER_FUNCTION_DISPATCH_BASE_NAME(x) \ + , BOOST_PARAMETER_FUNCTION_DISPATCH_IS_CONST(x) \ )::type BOOST_PARAMETER_FUNCTION_IMPL_NAME( \ BOOST_PARAMETER_FUNCTION_DISPATCH_BASE_NAME(x) \ + , BOOST_PARAMETER_FUNCTION_DISPATCH_IS_CONST(x) \ )(Args const& args) \ BOOST_PP_EXPR_IF(BOOST_PARAMETER_FUNCTION_DISPATCH_IS_CONST(x), const) \ { \ - return BOOST_PARAMETER_FUNCTION_DISPATCH_NAME(x, 0)( \ + return BOOST_PP_EXPR_IF( \ + BOOST_PARAMETER_FUNCTION_DISPATCH_IS_MEMBER(x) \ + , this-> \ + ) BOOST_PARAMETER_FUNCTION_DISPATCH_NAME(x, 0)( \ static_cast< \ typename BOOST_PARAMETER_FUNCTION_RESULT_NAME( \ BOOST_PARAMETER_FUNCTION_DISPATCH_BASE_NAME(x) \ + , BOOST_PARAMETER_FUNCTION_DISPATCH_IS_CONST(x) \ )::type(*)() \ >(BOOST_TTI_DETAIL_NULLPTR) \ , args \ diff --git a/include/boost/parameter/aux_/preprocessor/impl/function_dispatch_tuple.hpp b/include/boost/parameter/aux_/preprocessor/impl/function_dispatch_tuple.hpp index 63e6acd..b24c898 100644 --- a/include/boost/parameter/aux_/preprocessor/impl/function_dispatch_tuple.hpp +++ b/include/boost/parameter/aux_/preprocessor/impl/function_dispatch_tuple.hpp @@ -10,19 +10,23 @@ // Accessor macros for the input tuple to the dispatch macros. #define BOOST_PARAMETER_FUNCTION_DISPATCH_BASE_NAME(x) \ - BOOST_PP_TUPLE_ELEM(4, 0, x) + BOOST_PP_TUPLE_ELEM(5, 0, x) /**/ #define BOOST_PARAMETER_FUNCTION_DISPATCH_SPLIT_ARGS(x) \ - BOOST_PP_TUPLE_ELEM(4, 1, x) + BOOST_PP_TUPLE_ELEM(5, 1, x) +/**/ + +#define BOOST_PARAMETER_FUNCTION_DISPATCH_IS_MEMBER(x) \ + BOOST_PP_TUPLE_ELEM(5, 2, x) /**/ #define BOOST_PARAMETER_FUNCTION_DISPATCH_IS_CONST(x) \ - BOOST_PP_TUPLE_ELEM(4, 2, x) + BOOST_PP_TUPLE_ELEM(5, 3, x) /**/ #define BOOST_PARAMETER_FUNCTION_DISPATCH_TAG_NAMESPACE(x) \ - BOOST_PP_TUPLE_ELEM(4, 3, x) + BOOST_PP_TUPLE_ELEM(5, 4, x) /**/ #endif // include guard diff --git a/include/boost/parameter/aux_/preprocessor/impl/function_name.hpp b/include/boost/parameter/aux_/preprocessor/impl/function_name.hpp index aed9f15..af5d194 100644 --- a/include/boost/parameter/aux_/preprocessor/impl/function_name.hpp +++ b/include/boost/parameter/aux_/preprocessor/impl/function_name.hpp @@ -72,18 +72,64 @@ /**/ // Produces a name for a parameter specification for the function named base. -#define BOOST_PARAMETER_FUNCTION_SPECIFICATION_NAME(base) \ +#define BOOST_PARAMETER_FUNCTION_SPECIFICATION_NAME(base, is_const) \ BOOST_PP_CAT( \ - BOOST_PP_CAT(boost_param_parameters_, __LINE__) \ - , BOOST_PARAMETER_MEMBER_FUNCTION_NAME(name) \ + BOOST_PP_CAT( \ + BOOST_PP_IF( \ + is_const \ + , boost_param_parameters_const_ \ + , boost_param_parameters_ \ + ) \ + , __LINE__ \ + ) \ + , BOOST_PARAMETER_MEMBER_FUNCTION_NAME(base) \ + ) +/**/ + +// Produces a name for a result type metafunction for the no-spec function +// named base. +#define BOOST_PARAMETER_NO_SPEC_FUNCTION_RESULT_NAME(base, is_const) \ + BOOST_PP_CAT( \ + BOOST_PP_CAT( \ + BOOST_PP_IF( \ + is_const \ + , boost_param_no_spec_result_const_ \ + , boost_param_no_spec_result_ \ + ) \ + , __LINE__ \ + ) \ + , BOOST_PARAMETER_MEMBER_FUNCTION_NAME(base) \ ) /**/ // Produces a name for a result type metafunction for the function named base. -#define BOOST_PARAMETER_FUNCTION_RESULT_NAME(base) \ +#define BOOST_PARAMETER_FUNCTION_RESULT_NAME(base, is_const) \ BOOST_PP_CAT( \ - BOOST_PP_CAT(boost_param_result_, __LINE__) \ - , BOOST_PARAMETER_MEMBER_FUNCTION_NAME(name) \ + BOOST_PP_CAT( \ + BOOST_PP_IF( \ + is_const \ + , boost_param_result_const_ \ + , boost_param_result_ \ + ) \ + , __LINE__ \ + ) \ + , BOOST_PARAMETER_MEMBER_FUNCTION_NAME(base) \ + ) +/**/ + +// Produces a name for the implementation function to which the no-spec +// function named base forwards its result type and argument pack. +#define BOOST_PARAMETER_NO_SPEC_FUNCTION_IMPL_NAME(base, is_const) \ + BOOST_PP_CAT( \ + BOOST_PP_CAT( \ + BOOST_PP_IF( \ + is_const \ + , boost_param_no_spec_impl_const \ + , boost_param_no_spec_impl \ + ) \ + , __LINE__ \ + ) \ + , BOOST_PARAMETER_MEMBER_FUNCTION_NAME(base) \ ) /**/ @@ -92,22 +138,13 @@ // daniel: what? how is that relevant? the reason for using CAT() // is to make sure base is expanded. i'm not sure we need to here, // but it's more stable to do it. -#define BOOST_PARAMETER_FUNCTION_IMPL_NAME(base) \ - BOOST_PP_CAT(boost_param_impl, BOOST_PARAMETER_MEMBER_FUNCTION_NAME(base)) -/**/ - -#include - -// Produces a name for the dispatch functions. -#define BOOST_PARAMETER_FUNCTION_DISPATCH_NAME(x, n) \ +#define BOOST_PARAMETER_FUNCTION_IMPL_NAME(base, is_const) \ BOOST_PP_CAT( \ BOOST_PP_CAT( \ - BOOST_PP_CAT(boost_param_dispatch_, n) \ - , BOOST_PP_CAT(boost_, __LINE__) \ - ) \ - , BOOST_PARAMETER_MEMBER_FUNCTION_NAME( \ - BOOST_PARAMETER_FUNCTION_DISPATCH_BASE_NAME(x) \ + BOOST_PP_IF(is_const, boost_param_impl_const, boost_param_impl) \ + , __LINE__ \ ) \ + , BOOST_PARAMETER_MEMBER_FUNCTION_NAME(base) \ ) /**/ diff --git a/include/boost/parameter/aux_/preprocessor/impl/no_spec_overloads.hpp b/include/boost/parameter/aux_/preprocessor/impl/no_spec_overloads.hpp new file mode 100644 index 0000000..00df170 --- /dev/null +++ b/include/boost/parameter/aux_/preprocessor/impl/no_spec_overloads.hpp @@ -0,0 +1,321 @@ +// Copyright Cromwell D. Enage 2019. +// 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_AUX_PREPROCESSOR_IMPL_NO_SPEC_OVERLOADS_HPP +#define BOOST_PARAMETER_AUX_PREPROCESSOR_IMPL_NO_SPEC_OVERLOADS_HPP + +#include + +// Defines the no-spec implementation function header. +#define BOOST_PARAMETER_NO_SPEC_FUNCTION_IMPL_HEAD(name, is_const) \ + template \ + BOOST_PARAMETER_MEMBER_FUNCTION_STATIC(name) ResultType \ + BOOST_PARAMETER_NO_SPEC_FUNCTION_IMPL_NAME( \ + name, is_const \ + )(ResultType(*)(), Args const& args) +/**/ + +#include + +#if defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING) + +#include + +// Expands to the result metafunction for the specified no-spec function. +#define BOOST_PARAMETER_NO_SPEC_FUNCTION_HEAD(result, name, is_const) \ + template \ + struct BOOST_PARAMETER_NO_SPEC_FUNCTION_RESULT_NAME(name, is_const) \ + { \ + typedef typename BOOST_PARAMETER_PARENTHESIZED_TYPE(result) type; \ + }; +/**/ + +#include +#include +#include + +// Exapnds to a variadic constructor that is enabled if and only if all its +// arguments are tagged arguments. The enclosing class must inherit from the +// specified base class, which in turn must implement a constructor that takes +// in the argument pack that this one passes on. +#define BOOST_PARAMETER_NO_SPEC_CONSTRUCTOR(class_, base) \ + template < \ + typename TaggedArg0 \ + , typename ...TaggedArgs \ + , typename = typename ::boost::enable_if< \ + ::boost::parameter \ + ::are_tagged_arguments \ + >::type \ + > inline explicit \ + class_(TaggedArg0 const& arg0, TaggedArgs const&... args) \ + : BOOST_PARAMETER_PARENTHESIZED_TYPE(base)( \ + ::boost::parameter::compose(arg0, args...) \ + ) \ + { \ + } +/**/ + +// Exapnds to a variadic constructor that is enabled if and only if all its +// arguments are tagged arguments. The specified function must be able to +// take in the argument pack that this constructor passes on. +#define BOOST_PARAMETER_NO_SPEC_NO_BASE_CONSTRUCTOR(class_, func) \ + template < \ + typename TaggedArg0 \ + , typename ...TaggedArgs \ + , typename = typename ::boost::enable_if< \ + ::boost::parameter \ + ::are_tagged_arguments \ + >::type \ + > inline explicit \ + class_(TaggedArg0 const& arg0, TaggedArgs const&... args) \ + { \ + func(::boost::parameter::compose(arg0, args...)); \ + } +/**/ + +#include +#include + +// Exapnds to a variadic function that is enabled if and only if +// all its arguments are tagged arguments. +#define BOOST_PARAMETER_NO_SPEC_FUNCTION_OVERLOAD(name, impl, is_m, c) \ + template \ + BOOST_PARAMETER_MEMBER_FUNCTION_STATIC(impl) \ + inline typename ::boost::lazy_enable_if< \ + ::boost::parameter \ + ::are_tagged_arguments \ + , BOOST_PARAMETER_NO_SPEC_FUNCTION_RESULT_NAME( \ + impl, c \ + ) \ + >::type BOOST_PARAMETER_MEMBER_FUNCTION_NAME(name) \ + (TaggedArg0 const& arg0, TaggedArgs const&... args) \ + BOOST_PP_EXPR_IF(c, const) \ + { \ + return BOOST_PP_EXPR_IF(is_m, this->) \ + BOOST_PARAMETER_NO_SPEC_FUNCTION_IMPL_NAME(impl, c)( \ + static_cast< \ + typename BOOST_PARAMETER_NO_SPEC_FUNCTION_RESULT_NAME( \ + impl, c \ + )::type(*)() \ + >(BOOST_TTI_DETAIL_NULLPTR) \ + , ::boost::parameter::compose(arg0, args...) \ + ); \ + } +/**/ + +#else // !defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING) + +#include +#include +#include +#include + +// Expands to the result metafunction for the specified no-spec function. +#define BOOST_PARAMETER_NO_SPEC_FUNCTION_HEAD(result, name, is_const) \ + template < \ + BOOST_PP_ENUM_BINARY_PARAMS( \ + BOOST_PARAMETER_MAX_ARITY \ + , typename TaggedArg \ + , = ::boost::parameter::void_ BOOST_PP_INTERCEPT \ + ) \ + > \ + struct BOOST_PARAMETER_NO_SPEC_FUNCTION_RESULT_NAME(name, is_const) \ + { \ + typedef typename BOOST_PARAMETER_PARENTHESIZED_TYPE(result) type; \ + }; +/**/ + +#include +#include +#include +#include +#include + +#if defined(BOOST_NO_SFINAE) + +// Exapnds to a tagged-argument constructor overload that passes the argument +// pack to the base class delegate constructor. +#define BOOST_PARAMETER_NO_SPEC_CONSTRUCTOR_OVERLOAD_Z(z, n, data) \ + template \ + BOOST_PP_EXPR_IF(BOOST_PP_EQUAL(n, 1), explicit) inline \ + BOOST_PP_TUPLE_ELEM(2, 0, data)( \ + BOOST_PP_ENUM_BINARY_PARAMS_Z(z, n, TaggedArg, const& arg) \ + ) : BOOST_PARAMETER_PARENTHESIZED_TYPE(BOOST_PP_TUPLE_ELEM(2, 1, data))( \ + ::boost::parameter::compose(BOOST_PP_ENUM_PARAMS_Z(z, n, arg)) \ + ) \ + { \ + } +/**/ + +// Exapnds to a tagged-argument constructor overload that passes the argument +// pack to the delegate function. +#define BOOST_PARAMETER_NO_SPEC_NO_BASE_CONSTRUCTOR_OVERLOAD_Z(z, n, data) \ + template \ + BOOST_PP_EXPR_IF(BOOST_PP_EQUAL(n, 1), explicit) inline \ + BOOST_PP_TUPLE_ELEM(2, 0, data)( \ + BOOST_PP_ENUM_BINARY_PARAMS_Z(z, n, TaggedArg, const& a) \ + ) \ + { \ + BOOST_PP_TUPLE_ELEM(2, 1, data)( \ + ::boost::parameter::compose(BOOST_PP_ENUM_PARAMS_Z(z, n, a)) \ + ); \ + } +/**/ + +#include + +// Exapnds to a tagged-argument function overload. +#define BOOST_PARAMETER_NO_SPEC_FUNCTION_OVERLOAD_Z(z, n, data) \ + template \ + BOOST_PARAMETER_MEMBER_FUNCTION_STATIC(BOOST_PP_TUPLE_ELEM(4, 1, data)) \ + inline typename BOOST_PARAMETER_NO_SPEC_FUNCTION_RESULT_NAME( \ + BOOST_PP_TUPLE_ELEM(4, 1, data) \ + , BOOST_PP_TUPLE_ELEM(4, 3, data) \ + )::type \ + BOOST_PARAMETER_MEMBER_FUNCTION_NAME( \ + BOOST_PP_TUPLE_ELEM(4, 0, data) \ + )(BOOST_PP_ENUM_BINARY_PARAMS_Z(z, n, TaggedArg, const& arg)) \ + BOOST_PP_EXPR_IF(BOOST_PP_TUPLE_ELEM(4, 3, data), const) \ + { \ + return BOOST_PP_EXPR_IF(BOOST_PP_TUPLE_ELEM(4, 2, data), this->) \ + BOOST_PARAMETER_NO_SPEC_FUNCTION_IMPL_NAME( \ + BOOST_PP_TUPLE_ELEM(4, 1, data) \ + , BOOST_PP_TUPLE_ELEM(4, 3, data) \ + )( \ + static_cast< \ + typename BOOST_PARAMETER_NO_SPEC_FUNCTION_RESULT_NAME( \ + BOOST_PP_TUPLE_ELEM(4, 1, data) \ + , BOOST_PP_TUPLE_ELEM(4, 3, data) \ + )::type(*)() \ + >(BOOST_TTI_DETAIL_NULLPTR) \ + , ::boost::parameter::compose(BOOST_PP_ENUM_PARAMS_Z(z, n, arg)) \ + ); \ + } +/**/ + +#else // !defined(BOOST_NO_SFINAE) + +#include +#include +#include + +// Exapnds to a tagged-argument constructor overload that passes the argument +// pack to the base class delegate constructor. This constructor is enabled +// if and only if all its arguments are tagged arguments. +#define BOOST_PARAMETER_NO_SPEC_CONSTRUCTOR_OVERLOAD_Z(z, n, data) \ + template \ + BOOST_PP_EXPR_IF(BOOST_PP_EQUAL(n, 1), explicit) inline \ + BOOST_PP_TUPLE_ELEM(2, 0, data)( \ + BOOST_PP_ENUM_BINARY_PARAMS_Z(z, n, TaggedArg, const& arg) \ + , typename ::boost::enable_if< \ + ::boost::parameter::are_tagged_arguments< \ + BOOST_PP_ENUM_PARAMS_Z(z, n, TaggedArg) \ + > \ + >::type* = BOOST_TTI_DETAIL_NULLPTR \ + ) : BOOST_PARAMETER_PARENTHESIZED_TYPE(BOOST_PP_TUPLE_ELEM(2, 1, data))( \ + ::boost::parameter::compose(BOOST_PP_ENUM_PARAMS_Z(z, n, arg)) \ + ) \ + { \ + } +/**/ + +// Exapnds to a tagged-argument constructor overload that passes the argument +// pack to the delegate function. This constructor is enabled if and only if +// all its arguments are tagged arguments. +#define BOOST_PARAMETER_NO_SPEC_NO_BASE_CONSTRUCTOR_OVERLOAD_Z(z, n, data) \ + template \ + BOOST_PP_EXPR_IF(BOOST_PP_EQUAL(n, 1), explicit) inline \ + BOOST_PP_TUPLE_ELEM(2, 0, data)( \ + BOOST_PP_ENUM_BINARY_PARAMS_Z(z, n, TaggedArg, const& a) \ + , typename ::boost::enable_if< \ + ::boost::parameter::are_tagged_arguments< \ + BOOST_PP_ENUM_PARAMS_Z(z, n, TaggedArg) \ + > \ + >::type* = BOOST_TTI_DETAIL_NULLPTR \ + ) \ + { \ + BOOST_PP_TUPLE_ELEM(2, 1, data)( \ + ::boost::parameter::compose(BOOST_PP_ENUM_PARAMS_Z(z, n, a)) \ + ); \ + } +/**/ + +// Exapnds to a function overload that is enabled if and only if +// all its arguments are tagged arguments. +#define BOOST_PARAMETER_NO_SPEC_FUNCTION_OVERLOAD_Z(z, n, data) \ + template \ + BOOST_PARAMETER_MEMBER_FUNCTION_STATIC(BOOST_PP_TUPLE_ELEM(4, 1, data)) \ + inline typename ::boost::lazy_enable_if< \ + ::boost::parameter \ + ::are_tagged_arguments \ + , BOOST_PARAMETER_NO_SPEC_FUNCTION_RESULT_NAME( \ + BOOST_PP_TUPLE_ELEM(4, 1, data) \ + , BOOST_PP_TUPLE_ELEM(4, 3, data) \ + ) \ + >::type BOOST_PARAMETER_MEMBER_FUNCTION_NAME( \ + BOOST_PP_TUPLE_ELEM(4, 0, data) \ + )(BOOST_PP_ENUM_BINARY_PARAMS_Z(z, n, TaggedArg, const& arg)) \ + BOOST_PP_EXPR_IF(BOOST_PP_TUPLE_ELEM(4, 3, data), const) \ + { \ + return BOOST_PP_EXPR_IF(BOOST_PP_TUPLE_ELEM(4, 2, data), this->) \ + BOOST_PARAMETER_NO_SPEC_FUNCTION_IMPL_NAME( \ + BOOST_PP_TUPLE_ELEM(4, 1, data) \ + , BOOST_PP_TUPLE_ELEM(4, 3, data) \ + )( \ + static_cast< \ + typename BOOST_PARAMETER_NO_SPEC_FUNCTION_RESULT_NAME( \ + BOOST_PP_TUPLE_ELEM(4, 1, data) \ + , BOOST_PP_TUPLE_ELEM(4, 3, data) \ + )::type(*)() \ + >(BOOST_TTI_DETAIL_NULLPTR) \ + , ::boost::parameter::compose(BOOST_PP_ENUM_PARAMS_Z(z, n, arg)) \ + ); \ + } +/**/ + +#endif // BOOST_NO_SFINAE + +#include +#include + +// Emulates a variadic constructor that is enabled if and only if all its +// arguments are tagged arguments. The enclosing class must inherit from the +// specified base class, which in turn must implement a constructor that takes +// in the argument pack that this one passes on. +#define BOOST_PARAMETER_NO_SPEC_CONSTRUCTOR(class_, base) \ + BOOST_PP_REPEAT_FROM_TO( \ + 1 \ + , BOOST_PP_INC(BOOST_PARAMETER_MAX_ARITY) \ + , BOOST_PARAMETER_NO_SPEC_CONSTRUCTOR_OVERLOAD_Z \ + , (class_, base) \ + ) +/**/ + +// Emulates a variadic constructor that is enabled if and only if all its +// arguments are tagged arguments. The specified function must be able to +// take in the argument pack that this constructor passes on. +#define BOOST_PARAMETER_NO_SPEC_NO_BASE_CONSTRUCTOR(class_, func) \ + BOOST_PP_REPEAT_FROM_TO( \ + 1 \ + , BOOST_PP_INC(BOOST_PARAMETER_MAX_ARITY) \ + , BOOST_PARAMETER_NO_SPEC_NO_BASE_CONSTRUCTOR_OVERLOAD_Z \ + , (class_, func) \ + ) +/**/ + +// Emulates a variadic function that is enabled if and only if +// all its arguments are tagged arguments. +#define BOOST_PARAMETER_NO_SPEC_FUNCTION_OVERLOAD(name, impl, is_m, c) \ + BOOST_PP_REPEAT_FROM_TO( \ + 1 \ + , BOOST_PP_INC(BOOST_PARAMETER_MAX_ARITY) \ + , BOOST_PARAMETER_NO_SPEC_FUNCTION_OVERLOAD_Z \ + , (name, impl, is_m, c) \ + ) +/**/ + +#endif // BOOST_PARAMETER_HAS_PERFECT_FORWARDING +#endif // include guard + diff --git a/include/boost/parameter/aux_/preprocessor/impl/specification.hpp b/include/boost/parameter/aux_/preprocessor/impl/specification.hpp index 302930a..d2a4638 100644 --- a/include/boost/parameter/aux_/preprocessor/impl/specification.hpp +++ b/include/boost/parameter/aux_/preprocessor/impl/specification.hpp @@ -67,15 +67,23 @@ #include #include +#include #include // Expands to a boost::parameter::parameters<> specialization for the // function named base. Used by BOOST_PARAMETER_CONSTRUCTOR_AUX and // BOOST_PARAMETER_FUNCTION_HEAD for their respective ParameterSpec models. -#define BOOST_PARAMETER_SPECIFICATION(tag_ns, base, split_args) \ +#define BOOST_PARAMETER_SPECIFICATION(tag_ns, base, split_args, is_const) \ template \ struct BOOST_PP_CAT( \ - BOOST_PP_CAT(boost_param_params_, __LINE__) \ + BOOST_PP_CAT( \ + BOOST_PP_IF( \ + is_const \ + , boost_param_params_const_ \ + , boost_param_params_ \ + ) \ + , __LINE__ \ + ) \ , BOOST_PARAMETER_MEMBER_FUNCTION_NAME(base) \ ) : ::boost::parameter::parameters< \ BOOST_PP_SEQ_FOR_EACH_I( \ @@ -85,7 +93,14 @@ { \ }; \ typedef BOOST_PP_CAT( \ - BOOST_PP_CAT(boost_param_params_, __LINE__) \ + BOOST_PP_CAT( \ + BOOST_PP_IF( \ + is_const \ + , boost_param_params_const_ \ + , boost_param_params_ \ + ) \ + , __LINE__ \ + ) \ , BOOST_PARAMETER_MEMBER_FUNCTION_NAME(base) \ ) /**/ diff --git a/include/boost/parameter/aux_/unwrap_cv_reference.hpp b/include/boost/parameter/aux_/unwrap_cv_reference.hpp index b2ffe2a..43c4c37 100644 --- a/include/boost/parameter/aux_/unwrap_cv_reference.hpp +++ b/include/boost/parameter/aux_/unwrap_cv_reference.hpp @@ -51,7 +51,8 @@ namespace boost { namespace parameter { namespace aux { #include #include -#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) +#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) && \ + !BOOST_WORKAROUND(BOOST_GCC, < 40000) #include #endif @@ -83,7 +84,8 @@ namespace boost { namespace parameter { namespace aux { value> type; }; -#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) +#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) || \ + BOOST_WORKAROUND(BOOST_GCC, < 40000) template < typename T , typename = typename ::boost::parameter::aux @@ -103,7 +105,7 @@ namespace boost { namespace parameter { namespace aux { struct unwrap_cv_reference : T { }; -#else // !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) +#else // no Borland or GCC 3- workarounds needed // Needed for unwrap_cv_reference below. T might be const, so // eval_if<> might fail because of deriving from T const on EDG. template @@ -123,7 +125,7 @@ namespace boost { namespace parameter { namespace aux { > { }; -#endif // Borland workarounds needed. +#endif // Borland or GCC 3- workarounds needed }}} // namespace boost::parameter::aux #endif // include guard diff --git a/include/boost/parameter/compose.hpp b/include/boost/parameter/compose.hpp new file mode 100644 index 0000000..fc874f2 --- /dev/null +++ b/include/boost/parameter/compose.hpp @@ -0,0 +1,157 @@ +// Copyright Cromwell D. Enage 2018. +// 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_COMPOSE_HPP +#define BOOST_PARAMETER_COMPOSE_HPP + +#include + +namespace boost { namespace parameter { + + inline ::boost::parameter::aux::empty_arg_list compose() + { + return ::boost::parameter::aux::empty_arg_list(); + } +}} // namespace boost::parameter + +#include + +#if defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING) + +namespace boost { namespace parameter { namespace aux { + + template + struct compose_arg_list; + + template + struct compose_arg_list + { + typedef ::boost::parameter::aux::arg_list type; + }; + + template + struct compose_arg_list + { + typedef ::boost::parameter::aux::arg_list< + TaggedArg0 + , typename ::boost::parameter::aux + ::compose_arg_list::type + > type; + }; +}}} // namespace boost::parameter::aux + +#include +#include + +namespace boost { namespace parameter { + + template + inline typename ::boost::lazy_enable_if< + ::boost::parameter::are_tagged_arguments + , ::boost::parameter::aux + ::compose_arg_list + >::type + compose(TaggedArg0 const& arg0, TaggedArgs const&... args) + { + return typename ::boost::parameter::aux + ::compose_arg_list::type( + ::boost::parameter::aux::value_type_is_not_void() + , arg0 + , args... + ); + } +}} // namespace boost::parameter + +#else // !defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING) + +#define BOOST_PARAMETER_compose_arg_list_type_suffix(z, n, suffix) suffix + +#include + +#define BOOST_PARAMETER_compose_arg_list_type_prefix(z, n, prefix) \ + ::boost::parameter::aux::arg_list +#include +#include + +#define BOOST_PARAMETER_compose_arg_list_type(z, n, prefix) \ + BOOST_PP_CAT(BOOST_PP_ENUM_, z)( \ + n, BOOST_PARAMETER_compose_arg_list_type_prefix, prefix \ + ) BOOST_PP_CAT(BOOST_PP_REPEAT_, z)( \ + n, BOOST_PARAMETER_compose_arg_list_type_suffix, > \ + ) +/**/ + +#include +#include +#include +#include +#include + +#if defined(BOOST_NO_SFINAE) +#define BOOST_PARAMETER_compose_arg_list_function_overload(z, n, prefix) \ + template \ + inline \ + BOOST_PARAMETER_compose_arg_list_type(z, n, prefix) \ + compose(BOOST_PP_ENUM_BINARY_PARAMS_Z(z, n, prefix, const& a)) \ + { \ + return BOOST_PARAMETER_compose_arg_list_type(z, n, prefix)( \ + BOOST_PP_ENUM_PARAMS_Z(z, n, a) \ + BOOST_PP_ENUM_TRAILING_PARAMS_Z( \ + z \ + , BOOST_PP_SUB(BOOST_PARAMETER_MAX_ARITY, n) \ + , ::boost::parameter::aux::void_reference() BOOST_PP_INTERCEPT \ + ) \ + ); \ + } +/**/ +#else // !defined(BOOST_NO_SFINAE) +#include +#include + +#define BOOST_PARAMETER_compose_arg_list_function_overload(z, n, prefix) \ + template \ + inline typename ::boost::enable_if< \ + ::boost::parameter \ + ::are_tagged_arguments \ + , BOOST_PARAMETER_compose_arg_list_type(z, n, prefix) \ + >::type \ + compose(BOOST_PP_ENUM_BINARY_PARAMS_Z(z, n, prefix, const& a)) \ + { \ + return BOOST_PARAMETER_compose_arg_list_type(z, n, prefix)( \ + BOOST_PP_ENUM_PARAMS_Z(z, n, a) \ + BOOST_PP_ENUM_TRAILING_PARAMS_Z( \ + z \ + , BOOST_PP_SUB(BOOST_PARAMETER_MAX_ARITY, n) \ + , ::boost::parameter::aux::void_reference() BOOST_PP_INTERCEPT \ + ) \ + ); \ + } +/**/ +#endif // BOOST_NO_SFINAE + +#include +#include + +namespace boost { namespace parameter { + + BOOST_PP_REPEAT_FROM_TO( + 1 + , BOOST_PP_INC(BOOST_PARAMETER_MAX_ARITY) + , BOOST_PARAMETER_compose_arg_list_function_overload + , TaggedArg + ) +}} // namespace boost::parameter + +#undef BOOST_PARAMETER_compose_arg_list_function_overload +#undef BOOST_PARAMETER_compose_arg_list_type +#undef BOOST_PARAMETER_compose_arg_list_type_prefix +#undef BOOST_PARAMETER_compose_arg_list_type_suffix + +#endif // BOOST_PARAMETER_HAS_PERFECT_FORWARDING +#endif // include guard + diff --git a/include/boost/parameter/config.hpp b/include/boost/parameter/config.hpp index 91ce66e..d9e8198 100644 --- a/include/boost/parameter/config.hpp +++ b/include/boost/parameter/config.hpp @@ -15,9 +15,13 @@ // SFINAE support, needed explicitly by tagged_argument & keyword & cast; // correct function template ordering, needed by the code generation macros; // rvalue references, needed throughout; variadic templates, needed by -// parameters; and the ability to handle multiple parameter packs, needed by -// parameters. Older versions of GCC either don't have the latter ability or -// cannot disambiguate between keyword's overloaded operators. +// parameters; function template default arguments, needed by the code +// generation macros; and the ability to handle multiple parameter packs, +// needed by parameters. Older versions of GCC either don't have the latter +// ability or cannot disambiguate between keyword's overloaded +// operators. Older versions of Clang either fail to compile due to +// differences in length between parameter packs 'Args' and 'args' or fail at +// runtime due to segmentation faults. // -- Cromwell D. Enage #if !defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING) && \ !defined(BOOST_PARAMETER_DISABLE_PERFECT_FORWARDING) && \ @@ -25,12 +29,31 @@ !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) && \ !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \ !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && \ - !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) && \ - !BOOST_WORKAROUND(BOOST_GCC, < 40900) + !defined(BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS) && \ + !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) && !( \ + defined(BOOST_CLANG) && (1 == BOOST_CLANG) && ( \ + (__clang_major__ < 3) || ( \ + (3 == __clang_major__) && (__clang_minor__ < 2) \ + ) \ + ) \ + ) && !BOOST_WORKAROUND(BOOST_GCC, < 40900) #define BOOST_PARAMETER_HAS_PERFECT_FORWARDING #endif #if defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING) +#if !defined(BOOST_PARAMETER_CAN_USE_MP11) && \ + !defined(BOOST_PARAMETER_DISABLE_MP11_USAGE) && \ + !defined(BOOST_NO_CXX11_CONSTEXPR) && \ + !defined(BOOST_NO_CXX11_DECLTYPE_N3276) && \ + !defined(BOOST_NO_CXX11_AUTO_DECLARATIONS) && \ + !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) && \ + !defined(BOOST_NO_CXX11_STATIC_ASSERT) && \ + !defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS) && \ + !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) && \ + !defined(BOOST_NO_CXX11_HDR_TUPLE) +// Boost.MP11 requires C++11. -- Cromwell D. Enage +#define BOOST_PARAMETER_CAN_USE_MP11 +#endif #if !defined(BOOST_PARAMETER_MAX_ARITY) // Unlike the variadic MPL sequences provided by Boost.Fusion, // boost::mpl::vector has a size limit. -- Cromwell D. Enage diff --git a/include/boost/parameter/parameters.hpp b/include/boost/parameter/parameters.hpp index 73db121..f9ae612 100644 --- a/include/boost/parameter/parameters.hpp +++ b/include/boost/parameter/parameters.hpp @@ -74,6 +74,11 @@ namespace boost { namespace parameter { namespace aux { #include #if !defined(BOOST_PARAMETER_VARIADIC_MPL_SEQUENCE) +#if defined(BOOST_PARAMETER_CAN_USE_MP11) +#include +#include +#define BOOST_PARAMETER_VARIADIC_MPL_SEQUENCE ::boost::mp11::mp_list +#else #include // Newer versions of MSVC fail on the evaluate_category and @@ -98,6 +103,7 @@ namespace boost { namespace parameter { namespace aux { #define BOOST_PARAMETER_VARIADIC_MPL_SEQUENCE ::boost::mpl::vector #endif // BOOST_FUSION_HAS_VARIADIC_DEQUE #endif // BOOST_FUSION_HAS_VARIADIC_LIST +#endif // BOOST_PARAMETER_CAN_USE_MP11 #endif // BOOST_PARAMETER_VARIADIC_MPL_SEQUENCE namespace boost { namespace parameter { diff --git a/include/boost/parameter/preprocessor.hpp b/include/boost/parameter/preprocessor.hpp index 911ff7f..25f0a25 100644 --- a/include/boost/parameter/preprocessor.hpp +++ b/include/boost/parameter/preprocessor.hpp @@ -13,7 +13,7 @@ // Helper macro for BOOST_PARAMETER_CONSTRUCTOR. #define BOOST_PARAMETER_CONSTRUCTOR_AUX(class_, base, tag_namespace, args) \ - BOOST_PARAMETER_SPECIFICATION(tag_namespace, ctor, args) \ + BOOST_PARAMETER_SPECIFICATION(tag_namespace, ctor, args, 0) \ BOOST_PP_CAT(constructor_parameters, __LINE__); \ BOOST_PARAMETER_CONSTRUCTOR_OVERLOADS(class_, base, args) /**/ @@ -21,42 +21,46 @@ #include // Defines the implementation function header. -#define BOOST_PARAMETER_FUNCTION_IMPL_HEAD(name) \ +#define BOOST_PARAMETER_FUNCTION_IMPL_HEAD(name, is_const) \ template \ - typename BOOST_PARAMETER_FUNCTION_RESULT_NAME(name)< \ + typename BOOST_PARAMETER_FUNCTION_RESULT_NAME(name, is_const)< \ Args \ - >::type BOOST_PARAMETER_FUNCTION_IMPL_NAME(name)(Args const& args) + >::type BOOST_PARAMETER_FUNCTION_IMPL_NAME(name, is_const)( \ + Args const& args \ + ) /**/ #include // Expands to the result metafunction and the parameters specialization. -#define BOOST_PARAMETER_FUNCTION_HEAD(result, name, tag_namespace, args) \ +#define BOOST_PARAMETER_FUNCTION_HEAD(result, name, tag_ns, args, is_const) \ template \ - struct BOOST_PARAMETER_FUNCTION_RESULT_NAME(name) \ + struct BOOST_PARAMETER_FUNCTION_RESULT_NAME(name, is_const) \ { \ typedef typename BOOST_PARAMETER_PARENTHESIZED_TYPE(result) type; \ }; \ - BOOST_PARAMETER_SPECIFICATION(tag_namespace, name, args) \ - BOOST_PARAMETER_FUNCTION_SPECIFICATION_NAME(name); + BOOST_PARAMETER_SPECIFICATION(tag_ns, name, args, is_const) \ + BOOST_PARAMETER_FUNCTION_SPECIFICATION_NAME(name, is_const); /**/ // Helper macro for BOOST_PARAMETER_BASIC_FUNCTION. #define BOOST_PARAMETER_BASIC_FUNCTION_AUX(result, name, tag_ns, args) \ - BOOST_PARAMETER_FUNCTION_HEAD(result, name, tag_ns, args) \ - BOOST_PARAMETER_FUNCTION_IMPL_HEAD(name); \ - BOOST_PARAMETER_FUNCTION_FORWARD_OVERLOADS(name, name, args, 0) \ - BOOST_PARAMETER_FUNCTION_IMPL_HEAD(name) + BOOST_PARAMETER_FUNCTION_HEAD(result, name, tag_ns, args, 0) \ + BOOST_PARAMETER_FUNCTION_IMPL_HEAD(name, 0); \ + BOOST_PARAMETER_FUNCTION_FORWARD_OVERLOADS(name, name, args, 0, 0) \ + BOOST_PARAMETER_FUNCTION_IMPL_HEAD(name, 0) /**/ #include -// Helper macro for BOOST_PARAMETER_BASIC_MEMBER_FUNCTION -// and BOOST_PARAMETER_BASIC_CONST_MEMBER_FUNCTION. -#define BOOST_PARAMETER_BASIC_MEMBER_FUNCTION_AUX(r, name, tag_ns, args, c) \ - BOOST_PARAMETER_FUNCTION_HEAD(r, name, tag_ns, args) \ - BOOST_PARAMETER_FUNCTION_FORWARD_OVERLOADS(name, name, args, c) \ - BOOST_PARAMETER_FUNCTION_IMPL_HEAD(name) BOOST_PP_EXPR_IF(c, const) +// Helper macro for BOOST_PARAMETER_BASIC_MEMBER_FUNCTION, +// BOOST_PARAMETER_BASIC_CONST_MEMBER_FUNCTION, +// BOOST_PARAMETER_BASIC_FUNCTION_CALL_OPERATOR, and +// BOOST_PARAMETER_BASIC_CONST_FUNCTION_CALL_OPERATOR. +#define BOOST_PARAMETER_BASIC_MEMBER_FUNCTION_AUX(r, n, i, tag_ns, args, c) \ + BOOST_PARAMETER_FUNCTION_HEAD(r, i, tag_ns, args, c) \ + BOOST_PARAMETER_FUNCTION_FORWARD_OVERLOADS(n, i, args, 1, c) \ + BOOST_PARAMETER_FUNCTION_IMPL_HEAD(i, c) BOOST_PP_EXPR_IF(c, const) /**/ #include @@ -83,7 +87,7 @@ // are accessible via args and keywords only. #define BOOST_PARAMETER_BASIC_MEMBER_FUNCTION(result, name, tag_ns, args) \ BOOST_PARAMETER_BASIC_MEMBER_FUNCTION_AUX( \ - result, name, tag_ns \ + result, name, name, tag_ns \ , BOOST_PARAMETER_AUX_PP_FLATTEN(2, 2, 3, args), 0 \ ) /**/ @@ -92,7 +96,25 @@ // header. All arguments are accessible via args and keywords only. #define BOOST_PARAMETER_BASIC_CONST_MEMBER_FUNCTION(r, name, tag_ns, args) \ BOOST_PARAMETER_BASIC_MEMBER_FUNCTION_AUX( \ - r, name, tag_ns \ + r, name, name, tag_ns \ + , BOOST_PARAMETER_AUX_PP_FLATTEN(2, 2, 3, args), 1 \ + ) +/**/ + +// Expands to a Boost.Parameter-enabled function call operator header. All +// arguments are accessible via args and keywords only. +#define BOOST_PARAMETER_BASIC_FUNCTION_CALL_OPERATOR(result, tag_ns, args) \ + BOOST_PARAMETER_BASIC_MEMBER_FUNCTION_AUX( \ + result, operator(), operator, tag_ns \ + , BOOST_PARAMETER_AUX_PP_FLATTEN(2, 2, 3, args), 0 \ + ) +/**/ + +// Expands to a Boost.Parameter-enabled const-qualified function call +// operator header. All arguments are accessible via args and keywords only. +#define BOOST_PARAMETER_BASIC_CONST_FUNCTION_CALL_OPERATOR(r, tag_ns, args) \ + BOOST_PARAMETER_BASIC_MEMBER_FUNCTION_AUX( \ + r, operator(), operator, tag_ns \ , BOOST_PARAMETER_AUX_PP_FLATTEN(2, 2, 3, args), 1 \ ) /**/ @@ -101,11 +123,11 @@ // Helper macro for BOOST_PARAMETER_FUNCTION. #define BOOST_PARAMETER_FUNCTION_AUX(result, name, tag_ns, args) \ - BOOST_PARAMETER_FUNCTION_HEAD(result, name, tag_ns, args) \ - BOOST_PARAMETER_FUNCTION_IMPL_HEAD(name); \ - BOOST_PARAMETER_FUNCTION_FORWARD_OVERLOADS(name, name, args, 0) \ + BOOST_PARAMETER_FUNCTION_HEAD(result, name, tag_ns, args, 0) \ + BOOST_PARAMETER_FUNCTION_IMPL_HEAD(name, 0); \ + BOOST_PARAMETER_FUNCTION_FORWARD_OVERLOADS(name, name, args, 0, 0) \ BOOST_PARAMETER_FUNCTION_DISPATCH_LAYER( \ - 1, (name, BOOST_PARAMETER_FUNCTION_SPLIT_ARGS(args), 0, tag_ns) \ + 1, (name, BOOST_PARAMETER_FUNCTION_SPLIT_ARGS(args), 0, 0, tag_ns) \ ) /**/ @@ -118,15 +140,27 @@ ) /**/ +#include + // Helper macro for BOOST_PARAMETER_MEMBER_FUNCTION // BOOST_PARAMETER_CONST_MEMBER_FUNCTION, // BOOST_PARAMETER_FUNCTION_CALL_OPERATOR, and // BOOST_PARAMETER_CONST_FUNCTION_CALL_OPERATOR. #define BOOST_PARAMETER_MEMBER_FUNCTION_AUX(r, name, impl, tag_ns, c, args) \ - BOOST_PARAMETER_FUNCTION_HEAD(r, impl, tag_ns, args) \ - BOOST_PARAMETER_FUNCTION_FORWARD_OVERLOADS(name, impl, args, c) \ + BOOST_PARAMETER_FUNCTION_HEAD(r, impl, tag_ns, args, c) \ + BOOST_PARAMETER_FUNCTION_FORWARD_OVERLOADS(name, impl, args, 1, c) \ BOOST_PARAMETER_FUNCTION_DISPATCH_LAYER( \ - 0, (impl, BOOST_PARAMETER_FUNCTION_SPLIT_ARGS(args), c, tag_ns) \ + 0, ( \ + impl \ + , BOOST_PARAMETER_FUNCTION_SPLIT_ARGS(args) \ + , BOOST_PP_IF( \ + BOOST_PARAMETER_MEMBER_FUNCTION_IS_STATIC(impl) \ + , 0 \ + , 1 \ + ) \ + , c \ + , tag_ns \ + ) \ ) /**/ diff --git a/include/boost/parameter/preprocessor_no_spec.hpp b/include/boost/parameter/preprocessor_no_spec.hpp new file mode 100644 index 0000000..a40b89c --- /dev/null +++ b/include/boost/parameter/preprocessor_no_spec.hpp @@ -0,0 +1,74 @@ +// Copyright Cromwell D. Enage 2019. +// 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_PREPROCESSOR_NO_SPEC_HPP +#define BOOST_PARAMETER_PREPROCESSOR_NO_SPEC_HPP + +#include +#include + +// Exapnds to a variadic function header that is enabled if and only if all +// its arguments are tagged arguments. All arguments are accessible via args +// and keywords only. +#define BOOST_PARAMETER_NO_SPEC_FUNCTION(result, name) \ + BOOST_PARAMETER_NO_SPEC_FUNCTION_HEAD(result, name, 0) \ + BOOST_PARAMETER_NO_SPEC_FUNCTION_IMPL_HEAD(name, 0); \ + BOOST_PARAMETER_NO_SPEC_FUNCTION_OVERLOAD(name, name, 0, 0) \ + BOOST_PARAMETER_NO_SPEC_FUNCTION_IMPL_HEAD(name, 0) +/**/ + +#include +#include + +// Helper macro for BOOST_PARAMETER_NO_SPEC_MEMBER_FUNCTION, +// BOOST_PARAMETER_NO_SPEC_CONST_MEMBER_FUNCTION, +// BOOST_PARAMETER_NO_SPEC_FUNCTION_CALL_OPERATOR, and +// and BOOST_PARAMETER_NO_SPEC_CONST_FUNCTION_CALL_OPERATOR. +#define BOOST_PARAMETER_NO_SPEC_MEMBER_FUNCTION_AUX(result, name, impl, c) \ + BOOST_PARAMETER_NO_SPEC_FUNCTION_HEAD(result, impl, c) \ + BOOST_PARAMETER_NO_SPEC_FUNCTION_OVERLOAD( \ + name \ + , impl \ + , BOOST_PP_IF(BOOST_PARAMETER_MEMBER_FUNCTION_IS_STATIC(impl), 0, 1) \ + , c \ + ) \ + BOOST_PARAMETER_NO_SPEC_FUNCTION_IMPL_HEAD(impl, c) \ + BOOST_PP_EXPR_IF(c, const) +/**/ + +// Exapnds to a variadic member function header that is enabled if and only if +// all its arguments are tagged arguments. All arguments are accessible via +// args and keywords only. +#define BOOST_PARAMETER_NO_SPEC_MEMBER_FUNCTION(result, name) \ + BOOST_PARAMETER_NO_SPEC_MEMBER_FUNCTION_AUX(result, name, name, 0) +/**/ + +// Exapnds to a const-qualified variadic member function header that is +// enabled if and only if all its arguments are tagged arguments. All +// arguments are accessible via args and keywords only. +#define BOOST_PARAMETER_NO_SPEC_CONST_MEMBER_FUNCTION(result, name) \ + BOOST_PARAMETER_NO_SPEC_MEMBER_FUNCTION_AUX(result, name, name, 1) +/**/ + +// Exapnds to a variadic function call operator header that is enabled if and +// only if all its arguments are tagged arguments. All arguments are +// accessible via args and keywords only. +#define BOOST_PARAMETER_NO_SPEC_FUNCTION_CALL_OPERATOR(result) \ + BOOST_PARAMETER_NO_SPEC_MEMBER_FUNCTION_AUX( \ + result, operator(), operator, 0 \ + ) +/**/ + +// Exapnds to a const-qualified variadic function call operator header that is +// enabled if and only if all its arguments are tagged arguments. All +// arguments are accessible via args and keywords only. +#define BOOST_PARAMETER_NO_SPEC_CONST_FUNCTION_CALL_OPERATOR(result) \ + BOOST_PARAMETER_NO_SPEC_MEMBER_FUNCTION_AUX( \ + result, operator(), operator, 1 \ + ) +/**/ + +#endif // include guard + diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 23bd7cf..2716db1 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -32,16 +32,6 @@ alias parameter_standard_tests : off ] - [ run optional_deduced_sfinae.cpp - : - : - : - BOOST_PARAMETER_MAX_ARITY=2 - BOOST_PARAMETER_EXPONENTIAL_OVERLOAD_THRESHOLD_ARITY=2 - : - : - off - ] [ run efficiency.cpp : : @@ -71,6 +61,34 @@ alias parameter_standard_tests : off ] + [ run parameterized_inheritance.cpp + : + : + : + BOOST_PARAMETER_MAX_ARITY=3 + : + : + off + ] + [ run preprocessor_eval_cat_no_spec.cpp + : + : + : + BOOST_PARAMETER_MAX_ARITY=8 + : + : + off + ] + [ run optional_deduced_sfinae.cpp + : + : + : + BOOST_PARAMETER_MAX_ARITY=2 + BOOST_PARAMETER_EXPONENTIAL_OVERLOAD_THRESHOLD_ARITY=2 + : + : + off + ] [ run preprocessor_eval_category.cpp : : @@ -111,26 +129,6 @@ alias parameter_standard_tests : off ] - [ run earwicker.cpp - : - : - : - BOOST_PARAMETER_MAX_ARITY=4 - BOOST_PARAMETER_EXPONENTIAL_OVERLOAD_THRESHOLD_ARITY=5 - : - : - off - ] - [ run macros.cpp - : - : - : - BOOST_PARAMETER_MAX_ARITY=4 - BOOST_PARAMETER_EXPONENTIAL_OVERLOAD_THRESHOLD_ARITY=5 - : - : - off - ] [ run preprocessor.cpp : : @@ -171,19 +169,44 @@ alias parameter_standard_tests : off ] + [ run earwicker.cpp + : + : + : + BOOST_PARAMETER_MAX_ARITY=4 + BOOST_PARAMETER_EXPONENTIAL_OVERLOAD_THRESHOLD_ARITY=5 + : + : + off + ] + [ run macros.cpp + : + : + : + BOOST_PARAMETER_MAX_ARITY=4 + BOOST_PARAMETER_EXPONENTIAL_OVERLOAD_THRESHOLD_ARITY=5 + : + : + off + ] [ compile unwrap_cv_reference.cpp ] [ compile ntp.cpp : BOOST_PARAMETER_MAX_ARITY=4 + BOOST_PARAMETER_EXPONENTIAL_OVERLOAD_THRESHOLD_ARITY=0 ] [ compile function_type_tpl_param.cpp ] [ compile-fail duplicates.cpp : + BOOST_PARAMETER_MAX_ARITY=4 + BOOST_PARAMETER_EXPONENTIAL_OVERLOAD_THRESHOLD_ARITY=5 : duplicates_fail ] [ compile-fail deduced_unmatched_arg.cpp : + BOOST_PARAMETER_MAX_ARITY=4 + BOOST_PARAMETER_EXPONENTIAL_OVERLOAD_THRESHOLD_ARITY=5 : deduced_unmatched_arg_fail ] @@ -217,6 +240,8 @@ alias parameter_standard_tests ] [ compile-fail deduced.cpp : + BOOST_PARAMETER_MAX_ARITY=4 + BOOST_PARAMETER_EXPONENTIAL_OVERLOAD_THRESHOLD_ARITY=5 LIBS_PARAMETER_TEST_COMPILE_FAILURE : deduced_fail @@ -567,6 +592,16 @@ alias parameter_macros_eval_category alias parameter_evaluate_category_10 : + [ run evaluate_category_10.cpp + : + : + : + BOOST_PARAMETER_EXPONENTIAL_OVERLOAD_THRESHOLD_ARITY=0 + : + evaluate_category_10_gcc_4_8_linux + : + off + ] : linux gcc @@ -575,16 +610,16 @@ alias parameter_evaluate_category_10 alias parameter_evaluate_category_10 : - : - # This test fails for xcode 7.3.0 on osx - # so we turn off this test for this compiler for now - darwin - 03 - # TODO: Differentiate by xcode version or by clang version - ; - -alias parameter_evaluate_category_10 - : + [ run evaluate_category_10.cpp + : + : + : + BOOST_PARAMETER_EXPONENTIAL_OVERLOAD_THRESHOLD_ARITY=0 + : + evaluate_category_10_mingw + : + off + ] : windows gcc @@ -596,8 +631,6 @@ alias parameter_evaluate_category_10 : : : - BOOST_PARAMETER_MAX_ARITY=10 - BOOST_PARAMETER_EXPONENTIAL_OVERLOAD_THRESHOLD_ARITY=0 : evaluate_category_10_cxx98 : @@ -613,7 +646,6 @@ alias parameter_evaluate_category_10 : : : - BOOST_PARAMETER_MAX_ARITY=10 BOOST_PARAMETER_EXPONENTIAL_OVERLOAD_THRESHOLD_ARITY=0 : evaluate_category_10_cxx03 @@ -640,40 +672,17 @@ alias parameter_evaluate_category_10 alias parameter_preprocessor_eval_cat_8 : - : - linux - gcc - 4.8 - ; - -alias parameter_preprocessor_eval_cat_8 - : - : - linux - gcc - 4.9 - ; - -alias parameter_preprocessor_eval_cat_8 - : - : - linux - gcc - 03 - ; - -alias parameter_preprocessor_eval_cat_8 - : - : - # This test fails for xcode 7.3.0 and xcode 8.3.0 on osx - # so we turn off this test for this compiler for now - darwin - 03 - # TODO: Differentiate by xcode version or by clang version - ; - -alias parameter_preprocessor_eval_cat_8 - : + [ run preprocessor_eval_cat_8.cpp + : + : + : + BOOST_PARAMETER_MAX_ARITY=8 + BOOST_PARAMETER_EXPONENTIAL_OVERLOAD_THRESHOLD_ARITY=0 + : + preproc_eval_cat_8_mingw + : + off + ] : windows gcc @@ -722,22 +731,22 @@ alias parameter_preprocessor_eval_cat_fail ] ; -alias parameter_msvc_fail_tests ; +alias parameter_vendor_specific_fail_tests ; -alias parameter_msvc_fail_tests +alias parameter_vendor_specific_fail_tests : [ compile-fail compose.cpp : LIBS_PARAMETER_TEST_COMPILE_FAILURE_MSVC : - compose_msvc11_fail_11 + compose_fail_msvc11 ] : msvc 11.0 ; -alias parameter_msvc_fail_tests +alias parameter_vendor_specific_fail_tests : [ compile-fail evaluate_category.cpp : @@ -745,7 +754,7 @@ alias parameter_msvc_fail_tests BOOST_PARAMETER_EXPONENTIAL_OVERLOAD_THRESHOLD_ARITY=5 LIBS_PARAMETER_TEST_COMPILE_FAILURE_MSVC : - evaluate_category_msvc12_fail + evaluate_category_fail_msvc12 ] [ compile-fail preprocessor_eval_category.cpp : @@ -753,14 +762,21 @@ alias parameter_msvc_fail_tests BOOST_PARAMETER_EXPONENTIAL_OVERLOAD_THRESHOLD_ARITY=9 LIBS_PARAMETER_TEST_COMPILE_FAILURE_MSVC : - preproc_eval_cat_msvc12_fail + preproc_eval_cat_fail_msvc12 + ] + [ compile-fail preprocessor_eval_cat_no_spec.cpp + : + BOOST_PARAMETER_MAX_ARITY=8 + LIBS_PARAMETER_TEST_COMPILE_FAILURE_MSVC + : + preproc_eval_cat_no_spec_fail_msvc12 ] : msvc 12.0 ; -alias parameter_msvc_fail_tests +alias parameter_vendor_specific_fail_tests : [ compile-fail evaluate_category.cpp : @@ -768,7 +784,7 @@ alias parameter_msvc_fail_tests BOOST_PARAMETER_EXPONENTIAL_OVERLOAD_THRESHOLD_ARITY=5 LIBS_PARAMETER_TEST_COMPILE_FAILURE_MSVC : - evaluate_category_msvc14_0_fail + evaluate_category_fail_msvc14_0 ] [ compile-fail preprocessor_eval_category.cpp : @@ -776,14 +792,21 @@ alias parameter_msvc_fail_tests BOOST_PARAMETER_EXPONENTIAL_OVERLOAD_THRESHOLD_ARITY=9 LIBS_PARAMETER_TEST_COMPILE_FAILURE_MSVC : - preproc_eval_cat_msvc14_0_fail + preproc_eval_cat_fail_msvc14_0 + ] + [ compile-fail preprocessor_eval_cat_no_spec.cpp + : + BOOST_PARAMETER_MAX_ARITY=8 + LIBS_PARAMETER_TEST_COMPILE_FAILURE_MSVC + : + preproc_eval_cat_no_spec_fail_msvc14_0 ] : msvc 14.0 ; -alias parameter_msvc_fail_tests +alias parameter_vendor_specific_fail_tests : [ compile-fail evaluate_category.cpp : @@ -791,7 +814,7 @@ alias parameter_msvc_fail_tests BOOST_PARAMETER_EXPONENTIAL_OVERLOAD_THRESHOLD_ARITY=5 LIBS_PARAMETER_TEST_COMPILE_FAILURE_MSVC : - evaluate_category_msvc14_1_fail + evaluate_category_fail_msvc14_1 ] [ compile-fail preprocessor_eval_category.cpp : @@ -799,7 +822,14 @@ alias parameter_msvc_fail_tests BOOST_PARAMETER_EXPONENTIAL_OVERLOAD_THRESHOLD_ARITY=9 LIBS_PARAMETER_TEST_COMPILE_FAILURE_MSVC : - preproc_eval_cat_msvc14_1_fail + preproc_eval_cat_fail_msvc14_1 + ] + [ compile-fail preprocessor_eval_cat_no_spec.cpp + : + BOOST_PARAMETER_MAX_ARITY=8 + LIBS_PARAMETER_TEST_COMPILE_FAILURE_MSVC + : + preproc_eval_cat_no_spec_fail_msvc14_1 ] : msvc @@ -816,5 +846,5 @@ test-suite "parameter" parameter_standard_tests parameter_literate_tests parameter_python_test - parameter_msvc_fail_tests + parameter_vendor_specific_fail_tests ; diff --git a/test/basics.hpp b/test/basics.hpp index 4bed83b..41b94f5 100644 --- a/test/basics.hpp +++ b/test/basics.hpp @@ -9,15 +9,14 @@ #include -#if !defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING) #if (BOOST_PARAMETER_MAX_ARITY < 4) #error Define BOOST_PARAMETER_MAX_ARITY as 4 or greater. #endif -#if (BOOST_PARAMETER_EXPONENTIAL_OVERLOAD_THRESHOLD_ARITY < 5) +#if !defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING) && \ + (BOOST_PARAMETER_EXPONENTIAL_OVERLOAD_THRESHOLD_ARITY < 5) #error Define BOOST_PARAMETER_EXPONENTIAL_OVERLOAD_THRESHOLD_ARITY \ as 5 or greater. #endif -#endif #include #include diff --git a/test/earwicker.cpp b/test/earwicker.cpp index 46260d2..f71a965 100644 --- a/test/earwicker.cpp +++ b/test/earwicker.cpp @@ -5,15 +5,14 @@ #include -#if !defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING) #if (BOOST_PARAMETER_MAX_ARITY < 4) #error Define BOOST_PARAMETER_MAX_ARITY as 4 or greater. #endif -#if (BOOST_PARAMETER_EXPONENTIAL_OVERLOAD_THRESHOLD_ARITY < 5) +#if !defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING) && \ + (BOOST_PARAMETER_EXPONENTIAL_OVERLOAD_THRESHOLD_ARITY < 5) #error Define BOOST_PARAMETER_EXPONENTIAL_OVERLOAD_THRESHOLD_ARITY \ as 5 or greater. #endif -#endif #include diff --git a/test/efficiency.cpp b/test/efficiency.cpp index 52a2c27..ddfb62a 100644 --- a/test/efficiency.cpp +++ b/test/efficiency.cpp @@ -3,7 +3,7 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include +#include #include #include #include diff --git a/test/evaluate_category_10.cpp b/test/evaluate_category_10.cpp index 217b8ad..efc8258 100644 --- a/test/evaluate_category_10.cpp +++ b/test/evaluate_category_10.cpp @@ -5,12 +5,19 @@ #include -#if !defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING) && \ - (BOOST_PARAMETER_MAX_ARITY < 10) +#if ( \ + defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING) && \ + !defined(__MINGW32__) \ + ) || ( \ + !defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING) && \ + (10 < BOOST_PARAMETER_EXPONENTIAL_OVERLOAD_THRESHOLD_ARITY) \ + ) +#if (BOOST_PARAMETER_MAX_ARITY < 10) #error Define BOOST_PARAMETER_MAX_ARITY as 10 or greater. #endif +#endif -#include +#include namespace test { @@ -28,6 +35,20 @@ namespace test { BOOST_PARAMETER_NAME((_lrc2, keywords) in(lrc2)) BOOST_PARAMETER_NAME((_lr2, keywords) out(lr2)) BOOST_PARAMETER_NAME((_rr2, keywords) rr2) +} // namespace test + +#if ( \ + defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING) && \ + !defined(__MINGW32__) \ + ) || ( \ + !defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING) && \ + (10 < BOOST_PARAMETER_EXPONENTIAL_OVERLOAD_THRESHOLD_ARITY) \ + ) +#include +#include +#include + +namespace test { struct g_parameters : boost::parameter::parameters< @@ -46,6 +67,8 @@ namespace test { }; } // namespace test +#endif + #include #include "evaluate_category.hpp" @@ -58,67 +81,67 @@ namespace test { { BOOST_TEST_EQ( test::passed_by_lvalue_reference_to_const - , U::evaluate_category<0>(args[test::_lrc0]) + , test::U::evaluate_category<0>(args[test::_lrc0]) ); BOOST_TEST_EQ( test::passed_by_lvalue_reference - , U::evaluate_category<0>(args[test::_lr0]) + , test::U::evaluate_category<0>(args[test::_lr0]) ); BOOST_TEST_EQ( test::passed_by_lvalue_reference_to_const - , U::evaluate_category<1>(args[test::_lrc1]) + , test::U::evaluate_category<1>(args[test::_lrc1]) ); BOOST_TEST_EQ( test::passed_by_lvalue_reference - , U::evaluate_category<1>(args[test::_lr1]) + , test::U::evaluate_category<1>(args[test::_lr1]) ); BOOST_TEST_EQ( test::passed_by_lvalue_reference_to_const - , U::evaluate_category<2>( + , test::U::evaluate_category<2>( args[test::_lrc2 | test::lvalue_const_bitset<2>()] ) ); BOOST_TEST_EQ( test::passed_by_lvalue_reference - , U::evaluate_category<2>( + , test::U::evaluate_category<2>( args[test::_lr2 || test::lvalue_bitset_function<2>()] ) ); #if defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING) BOOST_TEST_EQ( test::passed_by_rvalue_reference_to_const - , U::evaluate_category<0>(args[test::_rrc0]) + , test::U::evaluate_category<0>(args[test::_rrc0]) ); BOOST_TEST_EQ( test::passed_by_rvalue_reference - , U::evaluate_category<0>(args[test::_rr0]) + , test::U::evaluate_category<0>(args[test::_rr0]) ); BOOST_TEST_EQ( test::passed_by_rvalue_reference_to_const - , U::evaluate_category<1>(args[test::_rrc1]) + , test::U::evaluate_category<1>(args[test::_rrc1]) ); BOOST_TEST_EQ( test::passed_by_rvalue_reference - , U::evaluate_category<2>( + , test::U::evaluate_category<2>( args[test::_rr2 || test::rvalue_bitset_function<2>()] ) ); #else // !defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING) BOOST_TEST_EQ( test::passed_by_lvalue_reference_to_const - , U::evaluate_category<0>(args[test::_rrc0]) + , test::U::evaluate_category<0>(args[test::_rrc0]) ); BOOST_TEST_EQ( test::passed_by_lvalue_reference_to_const - , U::evaluate_category<0>(args[test::_rr0]) + , test::U::evaluate_category<0>(args[test::_rr0]) ); BOOST_TEST_EQ( test::passed_by_lvalue_reference_to_const - , U::evaluate_category<1>(args[test::_rrc1]) + , test::U::evaluate_category<1>(args[test::_rrc1]) ); BOOST_TEST_EQ( test::passed_by_lvalue_reference_to_const - , U::evaluate_category<2>( + , test::U::evaluate_category<2>( args[test::_rr2 || test::rvalue_bitset_function<2>()] ) ); @@ -129,13 +152,34 @@ namespace test { #if !defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING) #include -#include #endif int main() { -#if defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING) || \ - (10 < BOOST_PARAMETER_EXPONENTIAL_OVERLOAD_THRESHOLD_ARITY) +#if defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING) +#if defined(__MINGW32__) + test::C::evaluate(( + test::_rrc1 = test::rvalue_const_bitset<1>() + , test::_lrc0 = test::lvalue_const_bitset<0>() + , test::_lr0 = test::lvalue_bitset<0>() + , test::_rrc0 = test::rvalue_const_bitset<0>() + , test::_rr0 = test::rvalue_bitset<0>() + , test::_lrc1 = test::lvalue_const_bitset<1>() + , test::_lr1 = test::lvalue_bitset<1>() + )); + test::C::evaluate(( + test::_lr0 = test::lvalue_bitset<0>() + , test::_rrc0 = test::rvalue_const_bitset<0>() + , test::_rr0 = test::rvalue_bitset<0>() + , test::_lrc1 = test::lvalue_const_bitset<1>() + , test::_lr1 = test::lvalue_bitset<1>() + , test::_rrc1 = test::rvalue_const_bitset<1>() + , test::_lrc2 = test::lvalue_const_bitset<2>() + , test::_lr2 = test::lvalue_bitset<2>() + , test::_rr2 = test::rvalue_bitset<2>() + , test::_lrc0 = test::lvalue_const_bitset<0>() + )); +#else // !defined(__MINGW32__) test::C::evaluate( test::g_parameters()( test::lvalue_const_bitset<0>() @@ -161,33 +205,64 @@ int main() , test::rvalue_bitset<2>() ) ); -#else // no perfect forwarding support and no exponential overloads +#endif // __MINGW32__ +#else // !defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING) +#if (10 < BOOST_PARAMETER_EXPONENTIAL_OVERLOAD_THRESHOLD_ARITY) test::C::evaluate( test::g_parameters()( test::lvalue_const_bitset<0>() - , boost::ref(test::lvalue_bitset<0>()) + , test::lvalue_bitset<0>() , test::rvalue_const_bitset<0>() , boost::parameter::aux::as_lvalue(test::rvalue_bitset<0>()) , test::lvalue_const_bitset<1>() - , boost::ref(test::lvalue_bitset<1>()) + , test::lvalue_bitset<1>() , test::rvalue_const_bitset<1>() ) ); test::C::evaluate( test::g_parameters()( test::lvalue_const_bitset<0>() - , boost::ref(test::lvalue_bitset<0>()) + , test::lvalue_bitset<0>() , test::rvalue_const_bitset<0>() , boost::parameter::aux::as_lvalue(test::rvalue_bitset<0>()) , test::lvalue_const_bitset<1>() - , boost::ref(test::lvalue_bitset<1>()) + , test::lvalue_bitset<1>() , test::rvalue_const_bitset<1>() , test::lvalue_const_bitset<2>() - , boost::ref(test::lvalue_bitset<2>()) + , test::lvalue_bitset<2>() , boost::parameter::aux::as_lvalue(test::rvalue_bitset<2>()) ) ); -#endif // perfect forwarding support, or exponential overloads +#else // !(10 < BOOST_PARAMETER_EXPONENTIAL_OVERLOAD_THRESHOLD_ARITY) + test::C::evaluate(( + test::_lrc0 = test::lvalue_const_bitset<0>() + , test::_lr0 = test::lvalue_bitset<0>() + , test::_rrc0 = test::rvalue_const_bitset<0>() + , test::_rr0 = boost::parameter::aux::as_lvalue( + test::rvalue_bitset<0>() + ) + , test::_lrc1 = test::lvalue_const_bitset<1>() + , test::_lr1 = test::lvalue_bitset<1>() + , test::_rrc1 = test::rvalue_const_bitset<1>() + )); + test::C::evaluate(( + test::_lrc0 = test::lvalue_const_bitset<0>() + , test::_lr0 = test::lvalue_bitset<0>() + , test::_rrc0 = test::rvalue_const_bitset<0>() + , test::_rr0 = boost::parameter::aux::as_lvalue( + test::rvalue_bitset<0>() + ) + , test::_lrc1 = test::lvalue_const_bitset<1>() + , test::_lr1 = test::lvalue_bitset<1>() + , test::_rrc1 = test::rvalue_const_bitset<1>() + , test::_lrc2 = test::lvalue_const_bitset<2>() + , test::_lr2 = test::lvalue_bitset<2>() + , test::_rr2 = boost::parameter::aux::as_lvalue( + test::rvalue_bitset<2>() + ) + )); +#endif // (10 < BOOST_PARAMETER_EXPONENTIAL_OVERLOAD_THRESHOLD_ARITY) +#endif // BOOST_PARAMETER_HAS_PERFECT_FORWARDING return boost::report_errors(); } diff --git a/test/literate/deduced-parameters0.cpp b/test/literate/deduced-parameters0.cpp index 801e1e1..f2e1d4c 100644 --- a/test/literate/deduced-parameters0.cpp +++ b/test/literate/deduced-parameters0.cpp @@ -44,14 +44,21 @@ void f() #include #include +char const*& blank_char_ptr() +{ + static char const* larr = ""; + return larr; +} + BOOST_PARAMETER_FUNCTION( - (void), def, tag, + (bool), def, tag, (required (name,(char const*)) (func,*) ) // nondeduced (deduced (optional - (docstring, (char const*), "") + (docstring, (char const*), blank_char_ptr()) (keywords - , *(is_keyword_expression) // see 5 + // see 5 + , *(is_keyword_expression) , no_keywords() ) (policies @@ -60,7 +67,8 @@ BOOST_PARAMETER_FUNCTION( boost::is_convertible , boost::mpl::false_ , boost::mpl::if_< - is_keyword_expression // see 5 + // see 5 + is_keyword_expression , boost::mpl::false_ , boost::mpl::true_ > @@ -72,16 +80,18 @@ BOOST_PARAMETER_FUNCTION( ) ) { + return true; } #include int main() { - def("f", &f, some_policies, "Documentation for f"); - def("f", &f, "Documentation for f", some_policies); + char const* f_name = "f"; + def(f_name, &f, some_policies, "Documentation for f"); + def(f_name, &f, "Documentation for f", some_policies); def( - "f" + f_name , &f , _policies = some_policies , "Documentation for f" diff --git a/test/literate/default-expression-evaluation0.cpp b/test/literate/default-expression-evaluation0.cpp index 9acf2d1..87c99d3 100644 --- a/test/literate/default-expression-evaluation0.cpp +++ b/test/literate/default-expression-evaluation0.cpp @@ -10,7 +10,7 @@ BOOST_PARAMETER_NAME(color_map) #include // for dfs_visitor -BOOST_PARAMETER_FUNCTION((void), depth_first_search, tag, +BOOST_PARAMETER_FUNCTION((bool), depth_first_search, tag, (required (graph, *) (visitor, *) @@ -20,20 +20,27 @@ BOOST_PARAMETER_FUNCTION((void), depth_first_search, tag, ) ) { - std::cout << "graph=" << graph << std::endl; - std::cout << "visitor=" << visitor << std::endl; - std::cout << "root_vertex=" << root_vertex << std::endl; - std::cout << "index_map=" << index_map << std::endl; - std::cout << "color_map=" << color_map << std::endl; + std::cout << "graph=" << graph; + std::cout << std::endl; + std::cout << "visitor=" << visitor; + std::cout << std::endl; + std::cout << "root_vertex=" << root_vertex; + std::cout << std::endl; + std::cout << "index_map=" << index_map; + std::cout << std::endl; + std::cout << "color_map=" << color_map; + std::cout << std::endl; + return true; } #include int main() { + char const* g = "1"; depth_first_search(1, 2, 3, 4, 5); depth_first_search( - "1", '2', _color_map = '5' + g, '2', _color_map = '5' , _index_map = "4", _root_vertex = "3" ); return boost::report_errors(); diff --git a/test/literate/parameter-enabled-member-functions0.cpp b/test/literate/parameter-enabled-member-functions0.cpp index 625e147..04eecbf 100644 --- a/test/literate/parameter-enabled-member-functions0.cpp +++ b/test/literate/parameter-enabled-member-functions0.cpp @@ -17,3 +17,13 @@ struct callable2 } }; +#include + +int main() +{ + callable2 c2; + callable2 const& c2_const = c2; + c2_const.call(1, 2); + return boost::report_errors(); +} + diff --git a/test/literate/static-member-functions0.cpp b/test/literate/static-member-functions0.cpp index 5bcd6b7..ce56828 100644 --- a/test/literate/static-member-functions0.cpp +++ b/test/literate/static-member-functions0.cpp @@ -16,3 +16,12 @@ struct somebody } }; +#include + +int main() +{ + somebody::f(); + somebody::f(4); + return boost::report_errors(); +} + diff --git a/test/literate/top-level0.cpp b/test/literate/top-level0.cpp index 25b88d4..8a8e39f 100644 --- a/test/literate/top-level0.cpp +++ b/test/literate/top-level0.cpp @@ -43,7 +43,8 @@ namespace test { int main() { - int x = test::new_window("alert", test::_width=10, test::_titlebar=false); + char const* alert_s = "alert"; + int x = test::new_window(alert_s, test::_width=10, test::_titlebar=false); test::Foo* foo = new test::Foo(); test::smart_ptr< test::Foo diff --git a/test/normalized_argument_types.cpp b/test/normalized_argument_types.cpp index 36aaf9d..1017473 100644 --- a/test/normalized_argument_types.cpp +++ b/test/normalized_argument_types.cpp @@ -5,17 +5,14 @@ #include -#if !defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING) #if (BOOST_PARAMETER_MAX_ARITY < 2) #error Define BOOST_PARAMETER_MAX_ARITY as 2 or greater. #endif -#if (BOOST_PARAMETER_EXPONENTIAL_OVERLOAD_THRESHOLD_ARITY < 3) +#if !defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING) && \ + (BOOST_PARAMETER_EXPONENTIAL_OVERLOAD_THRESHOLD_ARITY < 3) #error Define BOOST_PARAMETER_EXPONENTIAL_OVERLOAD_THRESHOLD_ARITY \ as 3 or greater. #endif -#endif - -#include namespace test { @@ -50,11 +47,17 @@ namespace test { }; std::size_t count_instances::count = 0; +} // namespace test + +#include + +namespace test { BOOST_PARAMETER_NAME(x) BOOST_PARAMETER_NAME(y) } // namespace test +#include #include #include #include @@ -107,7 +110,9 @@ namespace test { >::type )); x.noop(); +#if !BOOST_WORKAROUND(BOOST_GCC, < 40000) BOOST_TEST_LT(0, test::count_instances::count); +#endif return 0; } @@ -125,7 +130,9 @@ namespace test { >::type )); x.noop(); +#if !BOOST_WORKAROUND(BOOST_GCC, < 40000) BOOST_TEST_EQ(1, test::count_instances::count); +#endif return 0; } } // namespace test diff --git a/test/ntp.cpp b/test/ntp.cpp index f574296..798f182 100644 --- a/test/ntp.cpp +++ b/test/ntp.cpp @@ -5,8 +5,7 @@ #include -#if !defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING) && \ - (BOOST_PARAMETER_MAX_ARITY < 4) +#if (BOOST_PARAMETER_MAX_ARITY < 4) #error Define BOOST_PARAMETER_MAX_ARITY as 4 or greater. #endif diff --git a/test/optional_deduced_sfinae.cpp b/test/optional_deduced_sfinae.cpp index 56b7245..b77cc05 100644 --- a/test/optional_deduced_sfinae.cpp +++ b/test/optional_deduced_sfinae.cpp @@ -5,15 +5,14 @@ #include -#if !defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING) #if (BOOST_PARAMETER_MAX_ARITY < 2) #error Define BOOST_PARAMETER_MAX_ARITY as 2 or greater. #endif -#if (BOOST_PARAMETER_EXPONENTIAL_OVERLOAD_THRESHOLD_ARITY < 2) +#if !defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING) && \ + (BOOST_PARAMETER_EXPONENTIAL_OVERLOAD_THRESHOLD_ARITY < 2) #error Define BOOST_PARAMETER_EXPONENTIAL_OVERLOAD_THRESHOLD_ARITY \ as 2 or greater. #endif -#endif #include #include diff --git a/test/parameterized_inheritance.cpp b/test/parameterized_inheritance.cpp new file mode 100644 index 0000000..5ee09dc --- /dev/null +++ b/test/parameterized_inheritance.cpp @@ -0,0 +1,263 @@ +// Copyright Cromwell D. Enage 2018. +// 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) + +#include + +#if (BOOST_PARAMETER_MAX_ARITY < 3) +#error Define BOOST_PARAMETER_MAX_ARITY as 3 or greater. +#endif + +#include + +namespace test { + + BOOST_PARAMETER_NAME(a0) + BOOST_PARAMETER_NAME(a1) + BOOST_PARAMETER_NAME(a2) +} + +#if !defined(BOOST_NO_SFINAE) +#include +#include +#include +#endif + +namespace test { + +#if !defined(BOOST_NO_SFINAE) + struct _enabler + { + }; +#endif + + template + class backend0 + { + T _a0; + + public: + template + explicit backend0( + ArgPack const& args +#if !defined(BOOST_NO_SFINAE) + , typename boost::enable_if< + boost::parameter::is_argument_pack + , test::_enabler + >::type = test::_enabler() +#endif + ) : _a0(args[test::_a0]) + { + } + +#if !defined(BOOST_NO_SFINAE) + template + backend0( + backend0 const& copy + , typename boost::enable_if< + boost::is_convertible + , test::_enabler + >::type = test::_enabler() + ) : _a0(copy.get_a0()) + { + } +#endif + + template + backend0(Iterator itr, Iterator itr_end) : _a0(itr, itr_end) + { + } + + T const& get_a0() const + { + return this->_a0; + } + + protected: + template + void initialize_impl(ArgPack const& args) + { + this->_a0 = args[test::_a0]; + } + }; + + template + class backend1 : public B + { + T _a1; + + public: + template + explicit backend1( + ArgPack const& args +#if !defined(BOOST_NO_SFINAE) + , typename boost::enable_if< + boost::parameter::is_argument_pack + , test::_enabler + >::type = test::_enabler() +#endif + ) : B(args), _a1(args[test::_a1]) + { + } + +#if !defined(BOOST_NO_SFINAE) + template + backend1( + Derived const& copy + , typename boost::disable_if< + boost::parameter::is_argument_pack + , test::_enabler + >::type = test::_enabler() + ) : B(copy), _a1(copy.get_a1()) + { + } +#endif + + T const& get_a1() const + { + return this->_a1; + } + + protected: + template + void initialize_impl(ArgPack const& args) + { + B::initialize_impl(args); + this->_a1 = args[test::_a1]; + } + }; + + template + class backend2 : public B + { + T _a2; + + public: + template + explicit backend2( + ArgPack const& args +#if !defined(BOOST_NO_SFINAE) + , typename boost::enable_if< + boost::parameter::is_argument_pack + , test::_enabler + >::type = test::_enabler() +#endif + ) : B(args), _a2(args[test::_a2]) + { + } + +#if !defined(BOOST_NO_SFINAE) + template + backend2( + Derived const& copy + , typename boost::disable_if< + boost::parameter::is_argument_pack + , test::_enabler + >::type = test::_enabler() + ) : B(copy), _a2(copy.get_a2()) + { + } +#endif + + T const& get_a2() const + { + return this->_a2; + } + + protected: + template + void initialize_impl(ArgPack const& args) + { + B::initialize_impl(args); + this->_a2 = args[test::_a2]; + } + }; +} + +#include + +#if !defined(BOOST_NO_SFINAE) +#include +#endif + +namespace test { + + template + struct frontend : public B + { + BOOST_PARAMETER_NO_SPEC_CONSTRUCTOR(frontend, (B)) + +#if !defined(BOOST_NO_SFINAE) + template + frontend( + Iterator itr + , Iterator itr_end + , typename boost::disable_if< + boost::parameter::are_tagged_arguments + , test::_enabler + >::type = test::_enabler() + ) : B(itr, itr_end) + { + } + + template + frontend(frontend const& copy) : B(copy) + { + } +#endif + + BOOST_PARAMETER_NO_SPEC_MEMBER_FUNCTION((void), initialize) + { + this->initialize_impl(args); + } + + BOOST_PARAMETER_NO_SPEC_FUNCTION_CALL_OPERATOR((void)) + { + this->initialize_impl(args); + } + }; +} // namespace test + +#include + +#if !defined(BOOST_NO_SFINAE) +#include +#endif + +int main() +{ + char const* p = "foo"; + char const* q = "bar"; + test::frontend< + test::backend2, char>, int> + > composed_obj0(test::_a2 = 4, test::_a1 = ' ', test::_a0 = p); +#if defined(BOOST_NO_SFINAE) + test::frontend< + test::backend1, int>, char> + > composed_obj1(test::_a0 = p, test::_a1 = ' ', test::_a2 = 4); +#else + test::frontend< + test::backend1, int>, char> + > composed_obj1(composed_obj0); +#endif + BOOST_TEST_EQ(composed_obj0.get_a0(), composed_obj1.get_a0()); + BOOST_TEST_EQ(composed_obj0.get_a1(), composed_obj1.get_a1()); + BOOST_TEST_EQ(composed_obj0.get_a2(), composed_obj1.get_a2()); + composed_obj0.initialize(test::_a0 = q, test::_a1 = '!', test::_a2 = 8); + composed_obj1.initialize(test::_a2 = 8, test::_a1 = '!', test::_a0 = q); + BOOST_TEST_EQ(composed_obj0.get_a0(), composed_obj1.get_a0()); + BOOST_TEST_EQ(composed_obj0.get_a1(), composed_obj1.get_a1()); + BOOST_TEST_EQ(composed_obj0.get_a2(), composed_obj1.get_a2()); + composed_obj0(test::_a2 = 8, test::_a1 = '!', test::_a0 = q); + composed_obj1(test::_a0 = q, test::_a1 = '!', test::_a2 = 8); + BOOST_TEST_EQ(composed_obj0.get_a0(), composed_obj1.get_a0()); + BOOST_TEST_EQ(composed_obj0.get_a1(), composed_obj1.get_a1()); + BOOST_TEST_EQ(composed_obj0.get_a2(), composed_obj1.get_a2()); +#if !defined(BOOST_NO_SFINAE) + test::frontend > string_wrap(p, p + 3); + BOOST_TEST_EQ(string_wrap.get_a0(), std::string(p)); +#endif + return boost::report_errors(); +} + diff --git a/test/preprocessor.cpp b/test/preprocessor.cpp index c71853b..a9bbdac 100644 --- a/test/preprocessor.cpp +++ b/test/preprocessor.cpp @@ -5,7 +5,7 @@ #include #include -#include +#include #include #include #include @@ -46,6 +46,7 @@ namespace test { } } // namespace test +#include #include namespace test { @@ -195,6 +196,18 @@ namespace test { (index, *) ) ) + + BOOST_PARAMETER_BASIC_FUNCTION_CALL_OPERATOR((int), test::tag, + (optional + (value, *) + (index, *) + ) + ) + { + this->f = args[test::_value | 2.f]; + this->i = args[test::_index | 1]; + return 1; + } }; struct base_1 @@ -391,6 +404,16 @@ namespace test { > { }; + + BOOST_PARAMETER_BASIC_CONST_FUNCTION_CALL_OPERATOR((bool), test::tag, + (required + (value, *) + (index, *) + ) + ) + { + return args[test::_value] < args[test::_index]; + } }; BOOST_PARAMETER_FUNCTION((int), sfinae1, test::tag, @@ -423,12 +446,6 @@ namespace test { } #endif // BOOST_NO_SFINAE - template - T const& as_lvalue(T const& x) - { - return x; - } - struct udt { udt(int foo_, int bar_) : foo(foo_), bar(bar_) @@ -453,6 +470,10 @@ namespace test { } } // namespace test +#if BOOST_WORKAROUND(BOOST_MSVC, == 1300) +#include +#endif + #include int main() @@ -487,7 +508,7 @@ int main() , std::string("foo") , 1.f #if BOOST_WORKAROUND(BOOST_MSVC, == 1300) - , test::as_lvalue(2) + , boost::parameter::aux::as_lvalue(2) #else , 2 #endif @@ -498,7 +519,7 @@ int main() , std::string("foo") , 1.f #if BOOST_WORKAROUND(BOOST_MSVC, == 1300) - , test::as_lvalue(2) + , boost::parameter::aux::as_lvalue(2) #else , 2 #endif @@ -515,6 +536,11 @@ int main() BOOST_TEST(2 == u.i); BOOST_TEST(1.f == u.f); + u(); + + BOOST_TEST(1 == u.i); + BOOST_TEST(2.f == u.f); + test::class_1 x( test::values(std::string("foo"), 1.f, 2) , std::string("foo") @@ -563,22 +589,33 @@ int main() , test::_name = std::string("foo") ); + test::predicate p; + test::predicate const& p_const = p; + + BOOST_TEST(p_const(3, 4)); + BOOST_TEST(!p_const(4, 3)); + BOOST_TEST(!p_const(test::_index = 3, test::_value = 4)); + #if !defined(BOOST_NO_SFINAE) && \ !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x592)) - BOOST_TEST(test::sfinae("foo") == 1); + // GCC 3- tries to bind string literals + // to non-const references to char const*. + // BOOST_TEST(test::sfinae("foo") == 1); + char const* foo_str = "foo"; + BOOST_TEST(test::sfinae(foo_str) == 1); BOOST_TEST(test::sfinae(1) == 0); #if !BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x580)) // Sun actually eliminates the desired overload for some reason. // Disabling this part of the test because SFINAE abilities are // not the point of this test. - BOOST_TEST(test::sfinae1("foo") == 1); + BOOST_TEST(test::sfinae1(foo_str) == 1); #endif - + BOOST_TEST(test::sfinae1(1) == 0); #endif - test::lazy_defaults(test::_name = test::udt(0,1)); + test::lazy_defaults(test::_name = test::udt(0, 1)); test::lazy_defaults(test::_name = 0, test::_value = 1, test::_index = 2); return boost::report_errors(); diff --git a/test/preprocessor_deduced.cpp b/test/preprocessor_deduced.cpp index c912c46..8954f46 100644 --- a/test/preprocessor_deduced.cpp +++ b/test/preprocessor_deduced.cpp @@ -10,11 +10,13 @@ #include #include #include +#include #include #include "basics.hpp" #if !defined(BOOST_NO_SFINAE) #include +#include #endif namespace test { @@ -30,7 +32,7 @@ namespace test { // template1< r* ( template2 ) > // // Workaround: factor template2 into separate typedefs - struct predicate1 + struct predicate_int { template struct apply @@ -43,7 +45,7 @@ namespace test { }; }; - struct predicate2 + struct predicate_string { template struct apply @@ -116,7 +118,7 @@ namespace test { #if BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x580)) // SunPro workaround; see above - struct predicate3 + struct predicate_X { template struct apply @@ -135,11 +137,11 @@ namespace test { ) (deduced (required - (x, *(test::predicate1)) - (y, *(test::predicate2)) + (x, *(test::predicate_int)) + (y, *(test::predicate_string)) ) (optional - (z, *(test::predicate3), test::X()) + (z, *(test::predicate_X), test::X()) ) ) ) @@ -170,7 +172,7 @@ namespace test { BOOST_PARAMETER_FUNCTION((int), sfinae, test::tag, (deduced (required - (x, *(test::predicate2)) + (x, *(test::predicate_string)) ) ) ) @@ -206,6 +208,63 @@ namespace test { { return 0; } + +#if defined(LIBS_PARAMETER_TEST_COMPILE_FAILURE_MSVC) || \ + !BOOST_WORKAROUND(BOOST_MSVC, < 1800) + // Test support for two different Boost.Parameter-enabled + // function call operator overloads. + class char_read_base + { + int index; + char const* key; + + public: + template + explicit char_read_base(Args const& args) + : index(args[test::_y]), key(args[test::_z]) + { + } + + BOOST_PARAMETER_FUNCTION_CALL_OPERATOR((void), test::tag, + (deduced + (required + (y, (int)) + (z, (char const*)) + ) + ) + ) + { + this->index = y; + this->key = z; + } + + BOOST_PARAMETER_CONST_FUNCTION_CALL_OPERATOR((char), test::tag, + (deduced + (required + (y, (bool)) + (z, (std::map)) + ) + ) + ) + { + return y ? ( + (z.find(this->key)->second)[this->index] + ) : this->key[this->index]; + } + }; + + struct char_reader : public char_read_base + { + BOOST_PARAMETER_CONSTRUCTOR(char_reader, (char_read_base), test::tag, + (deduced + (required + (y, (int)) + (z, (char const*)) + ) + ) + ) + }; +#endif // MSVC-11.0- #endif // BOOST_NO_SFINAE } // namespace test @@ -287,9 +346,26 @@ int main() ); #if !defined(BOOST_NO_SFINAE) - BOOST_TEST(test::sfinae("foo") == 1); - BOOST_TEST(test::sfinae(0) == 0); -#endif + char const* keys[] = {"foo", "bar", "baz"}; + BOOST_TEST_EQ(1, test::sfinae(keys[0])); + BOOST_TEST_EQ(0, test::sfinae(0)); +#if defined(LIBS_PARAMETER_TEST_COMPILE_FAILURE_MSVC) || \ + !BOOST_WORKAROUND(BOOST_MSVC, < 1800) + std::map k2s; + k2s[keys[0]] = std::string("qux"); + k2s[keys[1]] = std::string("wmb"); + k2s[keys[2]] = std::string("zxc"); + test::char_reader r(keys[0], 0); + BOOST_TEST_EQ('q', (r(k2s, true))); + BOOST_TEST_EQ('f', (r(k2s, false))); + r(keys[1], 1); + BOOST_TEST_EQ('m', (r(k2s, true))); + BOOST_TEST_EQ('a', (r(k2s, false))); + r(keys[2], 2); + BOOST_TEST_EQ('c', (r(k2s, true))); + BOOST_TEST_EQ('z', (r(k2s, false))); +#endif // MSVC-11.0- +#endif // BOOST_NO_SFINAE return boost::report_errors(); } diff --git a/test/preprocessor_eval_cat_8.cpp b/test/preprocessor_eval_cat_8.cpp index 50f4a24..01a5c7c 100644 --- a/test/preprocessor_eval_cat_8.cpp +++ b/test/preprocessor_eval_cat_8.cpp @@ -5,12 +5,11 @@ #include -#if !defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING) && \ - (BOOST_PARAMETER_MAX_ARITY < 8) +#if (BOOST_PARAMETER_MAX_ARITY < 8) #error Define BOOST_PARAMETER_MAX_ARITY as 8 or greater. #endif -#include +#include namespace test { @@ -35,14 +34,23 @@ namespace test { #include #include "evaluate_category.hpp" -#if defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING) +#if !defined(__MINGW32__) && defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING) +#include #include +#elif defined(BOOST_MSVC) +#include +#else +#include #endif namespace test { struct C { +#if ( \ + !defined(__MINGW32__) && \ + defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING) \ + ) || defined(BOOST_MSVC) typedef boost::mpl::if_< boost::is_convertible > , boost::mpl::true_ @@ -100,57 +108,130 @@ namespace test { ) ) ) +#else + BOOST_PARAMETER_NO_SPEC_CONST_FUNCTION_CALL_OPERATOR((bool)) +#endif // msvc, or perfect forwarding support and not mingw { +#if ( \ + !defined(__MINGW32__) && \ + defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING) \ + ) || defined(BOOST_MSVC) BOOST_TEST_EQ( - passed_by_lvalue_reference_to_const - , U::evaluate_category<0>(lrc0) + test::passed_by_lvalue_reference_to_const + , test::U::evaluate_category<0>(lrc0) ); BOOST_TEST_EQ( - passed_by_lvalue_reference - , U::evaluate_category<1>(lr0) + test::passed_by_lvalue_reference + , test::U::evaluate_category<1>(lr0) ); BOOST_TEST_EQ( - passed_by_lvalue_reference_to_const - , U::evaluate_category<4>(lrc1) + test::passed_by_lvalue_reference_to_const + , test::U::evaluate_category<4>(lrc1) ); BOOST_TEST_EQ( - passed_by_lvalue_reference - , U::evaluate_category<5>(lr1) + test::passed_by_lvalue_reference + , test::U::evaluate_category<5>(lr1) ); +#else // mingw, or no perfect forwarding support and not msvc + BOOST_TEST_EQ( + test::passed_by_lvalue_reference_to_const + , test::U::evaluate_category<0>(args[test::_lrc0]) + ); + BOOST_TEST_EQ( + test::passed_by_lvalue_reference + , test::U::evaluate_category<1>(args[test::_lr0]) + ); + BOOST_TEST_EQ( + test::passed_by_lvalue_reference_to_const + , test::U::evaluate_category<4>(args[test::_lrc1]) + ); + BOOST_TEST_EQ( + test::passed_by_lvalue_reference + , test::U::evaluate_category<5>( + args[test::_lr1 | test::lvalue_bitset<5>()] + ) + ); +#endif // msvc, or perfect forwarding support and not mingw #if defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING) +#if defined(__MINGW32__) BOOST_TEST_EQ( - passed_by_rvalue_reference_to_const - , U::evaluate_category<2>(std::forward(rrc0)) + test::passed_by_rvalue_reference_to_const + , test::U::evaluate_category<2>(args[test::_rrc0]) ); BOOST_TEST_EQ( - passed_by_rvalue_reference - , U::evaluate_category<3>(std::forward(rr0)) + test::passed_by_rvalue_reference + , test::U::evaluate_category<3>(args[test::_rr0]) ); BOOST_TEST_EQ( - passed_by_rvalue_reference_to_const - , U::evaluate_category<6>(std::forward(rrc1)) + test::passed_by_rvalue_reference_to_const + , test::U::evaluate_category<6>( + args[test::_rrc1 | test::rvalue_const_bitset<6>()] + ) ); BOOST_TEST_EQ( - passed_by_rvalue_reference - , U::evaluate_category<7>(std::forward(rr1)) + test::passed_by_rvalue_reference + , test::U::evaluate_category<7>( + args[test::_rr1 | test::rvalue_bitset<7>()] + ) ); +#else // !defined(__MINGW32__) + BOOST_TEST_EQ( + test::passed_by_rvalue_reference_to_const + , test::U::evaluate_category<2>(std::forward(rrc0)) + ); + BOOST_TEST_EQ( + test::passed_by_rvalue_reference + , test::U::evaluate_category<3>(std::forward(rr0)) + ); + BOOST_TEST_EQ( + test::passed_by_rvalue_reference_to_const + , test::U::evaluate_category<6>(std::forward(rrc1)) + ); + BOOST_TEST_EQ( + test::passed_by_rvalue_reference + , test::U::evaluate_category<7>(std::forward(rr1)) + ); +#endif // __MINGW32__ #else // !defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING) +#if defined(BOOST_MSVC) BOOST_TEST_EQ( - passed_by_lvalue_reference_to_const - , U::evaluate_category<2>(rrc0) + test::passed_by_lvalue_reference_to_const + , test::U::evaluate_category<2>(rrc0) ); BOOST_TEST_EQ( - passed_by_lvalue_reference_to_const - , U::evaluate_category<3>(rr0) + test::passed_by_lvalue_reference_to_const + , test::U::evaluate_category<3>(rr0) ); BOOST_TEST_EQ( - passed_by_lvalue_reference_to_const - , U::evaluate_category<6>(rrc1) + test::passed_by_lvalue_reference_to_const + , test::U::evaluate_category<6>(rrc1) ); BOOST_TEST_EQ( - passed_by_lvalue_reference_to_const - , U::evaluate_category<7>(rr1) + test::passed_by_lvalue_reference_to_const + , test::U::evaluate_category<7>(rr1) ); +#else // !defined(BOOST_MSVC) + BOOST_TEST_EQ( + test::passed_by_lvalue_reference_to_const + , test::U::evaluate_category<2>(args[test::_rrc0]) + ); + BOOST_TEST_EQ( + test::passed_by_lvalue_reference_to_const + , test::U::evaluate_category<3>(args[test::_rr0]) + ); + BOOST_TEST_EQ( + test::passed_by_lvalue_reference_to_const + , test::U::evaluate_category<6>( + args[test::_rrc1 | test::rvalue_const_bitset<6>()] + ) + ); + BOOST_TEST_EQ( + test::passed_by_lvalue_reference_to_const + , test::U::evaluate_category<7>( + args[test::_rr1 | test::rvalue_bitset<7>()] + ) + ); +#endif // BOOST_MSVC #endif // BOOST_PARAMETER_HAS_PERFECT_FORWARDING return true; @@ -163,6 +244,10 @@ int main() test::C cp0; test::C cp1; +#if ( \ + !defined(__MINGW32__) && \ + defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING) \ + ) || defined(BOOST_MSVC) cp0( test::lvalue_const_bitset<4>() , test::lvalue_const_bitset<0>() @@ -188,6 +273,33 @@ int main() , test::rvalue_bitset<7>() , test::lvalue_const_bitset<0>() ); +#else // mingw, or no perfect forwarding support and not msvc + cp0( + test::_lrc1 = test::lvalue_const_bitset<4>() + , test::_lrc0 = test::lvalue_const_bitset<0>() + , test::_lr0 = test::lvalue_bitset<1>() + , test::_rrc0 = test::rvalue_const_bitset<2>() + , test::_rr0 = test::rvalue_bitset<3>() + ); + cp0( + test::_lrc1 = test::lvalue_const_bitset<4>() + , test::_lrc0 = test::lvalue_const_bitset<0>() + , test::_rrc1 = test::rvalue_const_bitset<6>() + , test::_lr0 = test::lvalue_bitset<1>() + , test::_rrc0 = test::rvalue_const_bitset<2>() + , test::_rr0 = test::rvalue_bitset<3>() + ); + cp1( + test::_lr0 = test::lvalue_bitset<1>() + , test::_rrc0 = test::rvalue_const_bitset<2>() + , test::_rr0 = test::rvalue_bitset<3>() + , test::_lrc1 = test::lvalue_const_bitset<4>() + , test::_lr1 = test::lvalue_bitset<5>() + , test::_rrc1 = test::rvalue_const_bitset<6>() + , test::_rr1 = test::rvalue_bitset<7>() + , test::_lrc0 = test::lvalue_const_bitset<0>() + ); +#endif // msvc, or perfect forwarding support and not mingw return boost::report_errors(); } diff --git a/test/preprocessor_eval_cat_no_spec.cpp b/test/preprocessor_eval_cat_no_spec.cpp new file mode 100644 index 0000000..bfec3da --- /dev/null +++ b/test/preprocessor_eval_cat_no_spec.cpp @@ -0,0 +1,524 @@ +// Copyright Cromwell D. Enage 2018. +// 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) + +#include + +#if (BOOST_PARAMETER_MAX_ARITY < 8) +#error Define BOOST_PARAMETER_MAX_ARITY as 8 or greater. +#endif + +#include + +namespace test { + + BOOST_PARAMETER_NAME((_lrc0, kw0) in(lrc0)) + BOOST_PARAMETER_NAME((_lr0, kw1) in_out(lr0)) + BOOST_PARAMETER_NAME((_rrc0, kw2) in(rrc0)) +#if defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING) + BOOST_PARAMETER_NAME((_rr0, kw3) consume(rr0)) +#else + BOOST_PARAMETER_NAME((_rr0, kw3) rr0) +#endif + BOOST_PARAMETER_NAME((_lrc1, kw4) in(lrc1)) + BOOST_PARAMETER_NAME((_lr1, kw5) out(lr1)) + BOOST_PARAMETER_NAME((_rrc1, kw6) in(rrc1)) + BOOST_PARAMETER_NAME((_rr1, kw7) rr1) +} // namespace test + +#include +#include +#include +#include +#include +#include "evaluate_category.hpp" + +namespace test { + + BOOST_PARAMETER_NO_SPEC_FUNCTION((bool), evaluate) + { + BOOST_TEST(( + test::passed_by_lvalue_reference_to_const == test::A< + typename boost::remove_const< + typename boost::parameter::value_type< + Args + , test::kw0::lrc0 + >::type + >::type + >::evaluate_category(args[test::_lrc0]) + )); + BOOST_TEST(( + test::passed_by_lvalue_reference == test::A< + typename boost::remove_const< + typename boost::parameter::value_type< + Args + , test::kw1::lr0 + >::type + >::type + >::evaluate_category(args[test::_lr0]) + )); + +#if defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING) + if ( + boost::is_scalar< + typename boost::remove_const< + typename boost::parameter::value_type< + Args + , test::kw2::rrc0 + >::type + >::type + >::value + ) + { + BOOST_TEST(( + test::passed_by_lvalue_reference_to_const == test::A< + typename boost::remove_const< + typename boost::parameter::value_type< + Args + , test::kw2::rrc0 + >::type + >::type + >::evaluate_category(args[test::_rrc0]) + )); + BOOST_TEST(( + test::passed_by_lvalue_reference_to_const == test::A< + typename boost::remove_const< + typename boost::parameter::value_type< + Args + , test::kw3::rr0 + >::type + >::type + >::evaluate_category(args[test::_rr0]) + )); + } + else // rrc0's value type isn't scalar + { + BOOST_TEST(( + test::passed_by_rvalue_reference_to_const == test::A< + typename boost::remove_const< + typename boost::parameter::value_type< + Args + , test::kw2::rrc0 + >::type + >::type + >::evaluate_category(args[test::_rrc0]) + )); + BOOST_TEST(( + test::passed_by_rvalue_reference == test::A< + typename boost::remove_const< + typename boost::parameter::value_type< + Args + , test::kw3::rr0 + >::type + >::type + >::evaluate_category(args[test::_rr0]) + )); + } +#else // !defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING) + BOOST_TEST(( + test::passed_by_lvalue_reference_to_const == test::A< + typename boost::remove_const< + typename boost::parameter::value_type< + Args + , test::kw2::rrc0 + >::type + >::type + >::evaluate_category(args[test::_rrc0]) + )); + BOOST_TEST(( + test::passed_by_lvalue_reference_to_const == test::A< + typename boost::remove_const< + typename boost::parameter::value_type< + Args + , test::kw3::rr0 + >::type + >::type + >::evaluate_category(args[test::_rr0]) + )); +#endif // BOOST_PARAMETER_HAS_PERFECT_FORWARDING + + return true; + } +} // namespace test + +#include +#include + +#if !defined(BOOST_NO_SFINAE) +#include +#include +#include +#endif + +namespace test { + + char const* baz = "baz"; + + struct B + { +#if !defined(LIBS_PARAMETER_TEST_COMPILE_FAILURE_MSVC) && \ + BOOST_WORKAROUND(BOOST_MSVC, >= 1800) + B() + { + } +#endif + + template + explicit B( + Args const& args +#if !defined(BOOST_NO_SFINAE) + , typename boost::disable_if< + typename boost::mpl::if_< + boost::is_base_of + , boost::mpl::true_ + , boost::mpl::false_ + >::type + >::type* = BOOST_TTI_DETAIL_NULLPTR +#endif // BOOST_NO_SFINAE + ) + { + test::evaluate( + test::_lrc0 = args[test::_lrc0] + , test::_lr0 = args[test::_lr0] + , test::_rrc0 = args[test::_rrc0] + , test::_rr0 = args[test::_rr0] + ); + } + + BOOST_PARAMETER_NO_SPEC_MEMBER_FUNCTION((bool), static evaluate) + { + BOOST_TEST(( + test::passed_by_lvalue_reference_to_const == test::A< + typename boost::remove_const< + typename boost::parameter::value_type< + Args + , test::kw0::lrc0 + >::type + >::type + >::evaluate_category(args[test::_lrc0]) + )); + BOOST_TEST(( + test::passed_by_lvalue_reference == test::A< + typename boost::remove_const< + typename boost::parameter::value_type< + Args + , test::kw1::lr0 + , char const* + >::type + >::type + >::evaluate_category(args[test::_lr0 | test::baz]) + )); + BOOST_TEST(( + test::passed_by_lvalue_reference_to_const == test::A< + typename boost::remove_const< + typename boost::parameter::value_type< + Args + , test::kw2::rrc0 + , float + >::type + >::type + >::evaluate_category(args[test::_rrc0 | 0.0f]) + )); + +#if defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING) + BOOST_TEST(( + test::passed_by_rvalue_reference == test::A< + typename boost::remove_const< + typename boost::parameter::value_type< + Args + , test::kw3::rr0 + , std::string + >::type + >::type + >::evaluate_category( + args[ + test::_rr0 | std::string(args[test::_lr0 | test::baz]) + ] + ) + )); +#else // !defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING) + BOOST_TEST(( + test::passed_by_lvalue_reference_to_const == test::A< + typename boost::remove_const< + typename boost::parameter::value_type< + Args + , test::kw3::rr0 + , std::string + >::type + >::type + >::evaluate_category( + args[ + test::_rr0 | std::string(args[test::_lr0 | test::baz]) + ] + ) + )); +#endif // BOOST_PARAMETER_HAS_PERFECT_FORWARDING + + return true; + } + }; + + struct C : B + { +#if !defined(LIBS_PARAMETER_TEST_COMPILE_FAILURE_MSVC) && \ + BOOST_WORKAROUND(BOOST_MSVC, >= 1800) + C() : B() + { + } +#endif + + BOOST_PARAMETER_NO_SPEC_CONSTRUCTOR(C, (B)) + }; + + struct D + { + BOOST_PARAMETER_NO_SPEC_NO_BASE_CONSTRUCTOR(D, D::_evaluate) + + BOOST_PARAMETER_NO_SPEC_CONST_MEMBER_FUNCTION((bool), evaluate_m) + { + return D::_evaluate(args); + } + + BOOST_PARAMETER_NO_SPEC_CONST_FUNCTION_CALL_OPERATOR((bool)) + { + return D::_evaluate(args); + } + + private: + template + static bool _evaluate(Args const& args) + { + BOOST_TEST_EQ( + test::passed_by_lvalue_reference_to_const + , test::U::evaluate_category<0>(args[test::_lrc0]) + ); + BOOST_TEST_EQ( + test::passed_by_lvalue_reference + , test::U::evaluate_category<1>(args[test::_lr0]) + ); + BOOST_TEST_EQ( + test::passed_by_lvalue_reference_to_const + , test::U::evaluate_category<4>(args[test::_lrc1]) + ); + BOOST_TEST_EQ( + test::passed_by_lvalue_reference + , test::U::evaluate_category<5>( + args[test::_lr1 | test::lvalue_bitset<5>()] + ) + ); +#if defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING) + BOOST_TEST_EQ( + test::passed_by_rvalue_reference_to_const + , test::U::evaluate_category<2>(args[test::_rrc0]) + ); + BOOST_TEST_EQ( + test::passed_by_rvalue_reference + , test::U::evaluate_category<3>(args[test::_rr0]) + ); + BOOST_TEST_EQ( + test::passed_by_rvalue_reference_to_const + , test::U::evaluate_category<6>( + args[test::_rrc1 | test::rvalue_const_bitset<6>()] + ) + ); + BOOST_TEST_EQ( + test::passed_by_rvalue_reference + , test::U::evaluate_category<7>( + args[test::_rr1 | test::rvalue_bitset<7>()] + ) + ); +#else // !defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING) + BOOST_TEST_EQ( + test::passed_by_lvalue_reference_to_const + , test::U::evaluate_category<2>(args[test::_rrc0]) + ); + BOOST_TEST_EQ( + test::passed_by_lvalue_reference_to_const + , test::U::evaluate_category<3>(args[test::_rr0]) + ); + BOOST_TEST_EQ( + test::passed_by_lvalue_reference_to_const + , test::U::evaluate_category<6>( + args[test::_rrc1 | test::rvalue_const_bitset<6>()] + ) + ); + BOOST_TEST_EQ( + test::passed_by_lvalue_reference_to_const + , test::U::evaluate_category<7>( + args[test::_rr1 | test::rvalue_bitset<7>()] + ) + ); +#endif // BOOST_PARAMETER_HAS_PERFECT_FORWARDING + + return true; + } + }; +} // namespace test + +int main() +{ + test::evaluate( + test::_lr0 = test::lvalue_float() + , test::_rrc0 = test::rvalue_const_float() + , test::_rr0 = test::rvalue_float() + , test::_lrc0 = test::lvalue_const_float() + ); + test::evaluate( + test::_lr0 = test::lvalue_char_ptr() + , test::_rrc0 = test::rvalue_const_char_ptr() + , test::_rr0 = test::rvalue_char_ptr() + , test::_lrc0 = test::lvalue_const_char_ptr() + ); + test::evaluate( + test::_lr0 = test::lvalue_str() + , test::_rrc0 = test::rvalue_const_str() + , test::_rr0 = test::rvalue_str() + , test::_lrc0 = test::lvalue_const_str() + ); + + test::C cf1( + test::_lr0 = test::lvalue_float() + , test::_rrc0 = test::rvalue_const_float() + , test::_rr0 = test::rvalue_float() + , test::_lrc0 = test::lvalue_const_float() + ); + test::C cc1( + test::_lr0 = test::lvalue_char_ptr() + , test::_rrc0 = test::rvalue_const_char_ptr() + , test::_rr0 = test::rvalue_char_ptr() + , test::_lrc0 = test::lvalue_const_char_ptr() + ); + test::C cs1( + test::_lr0 = test::lvalue_str() + , test::_rrc0 = test::rvalue_const_str() + , test::_rr0 = test::rvalue_str() + , test::_lrc0 = test::lvalue_const_str() + ); + + char baz_arr[4] = "qux"; + typedef char char_arr[4]; + +#if !defined(LIBS_PARAMETER_TEST_COMPILE_FAILURE_MSVC) && ( \ + BOOST_WORKAROUND(BOOST_GCC, < 40000) || \ + BOOST_WORKAROUND(BOOST_MSVC, >= 1800) \ + ) + // MSVC-12+ treats static_cast(baz_arr) as an lvalue. + // GCC 3- tries to bind string literals + // to non-const references to char const*. +#else + test::evaluate( + test::_lr0 = baz_arr +#if defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING) + , test::_rrc0 = static_cast("def") + , test::_rr0 = static_cast(baz_arr) +#else + , test::_rrc0 = "grl" + , test::_rr0 = "grp" +#endif + , test::_lrc0 = "wld" + ); +#endif // MSVC-12+ + test::B::evaluate(test::_lrc0 = test::lvalue_const_str()[0]); + test::C::evaluate( + test::_rrc0 = test::rvalue_const_float() + , test::_lrc0 = test::lvalue_const_str()[0] + ); + +#if !defined(LIBS_PARAMETER_TEST_COMPILE_FAILURE_MSVC) && \ + BOOST_WORKAROUND(BOOST_MSVC, >= 1800) + // MSVC-12+ treats static_cast(baz_arr) as an lvalue. + test::C cp0; + test::C cp1; +#else + test::C cp0( + test::_lrc0 = "frd" + , test::_lr0 = baz_arr +#if defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING) + , test::_rrc0 = static_cast("dfs") + , test::_rr0 = static_cast(baz_arr) +#else + , test::_rrc0 = "plg" + , test::_rr0 = "thd" +#endif + ); + test::C cp1( + test::_lr0 = baz_arr +#if defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING) + , test::_rrc0 = static_cast("dgx") + , test::_rr0 = static_cast(baz_arr) +#else + , test::_rrc0 = "hnk" + , test::_rr0 = "xzz" +#endif + , test::_lrc0 = "zts" + ); +#endif // MSVC-12+ + + cp0.evaluate( + test::_lrc0 = test::lvalue_const_str()[0] + , test::_lr0 = test::lvalue_char_ptr() + , test::_rr0 = test::rvalue_str() + , test::_rrc0 = test::rvalue_const_float() + ); + cp1.evaluate( + test::_lrc0 = test::lvalue_const_str()[0] + , test::_rr0 = test::rvalue_str() + , test::_rrc0 = test::rvalue_const_float() + , test::_lr0 = test::lvalue_char_ptr() + ); + + test::D dp0( + test::_lrc1 = test::lvalue_const_bitset<4>() + , test::_lrc0 = test::lvalue_const_bitset<0>() + , test::_lr0 = test::lvalue_bitset<1>() + , test::_rrc0 = test::rvalue_const_bitset<2>() + , test::_rr0 = test::rvalue_bitset<3>() + ); + test::D dp1( + test::_lrc1 = test::lvalue_const_bitset<4>() + , test::_lrc0 = test::lvalue_const_bitset<0>() + , test::_rrc1 = test::rvalue_const_bitset<6>() + , test::_lr0 = test::lvalue_bitset<1>() + , test::_rrc0 = test::rvalue_const_bitset<2>() + , test::_rr0 = test::rvalue_bitset<3>() + ); + + dp0.evaluate_m( + test::_lrc1 = test::lvalue_const_bitset<4>() + , test::_lrc0 = test::lvalue_const_bitset<0>() + , test::_rrc1 = test::rvalue_const_bitset<6>() + , test::_lr0 = test::lvalue_bitset<1>() + , test::_rrc0 = test::rvalue_const_bitset<2>() + , test::_rr0 = test::rvalue_bitset<3>() + ); + dp1.evaluate_m( + test::_lr0 = test::lvalue_bitset<1>() + , test::_rrc0 = test::rvalue_const_bitset<2>() + , test::_rr0 = test::rvalue_bitset<3>() + , test::_lrc1 = test::lvalue_const_bitset<4>() + , test::_lr1 = test::lvalue_bitset<5>() + , test::_rrc1 = test::rvalue_const_bitset<6>() + , test::_rr1 = test::rvalue_bitset<7>() + , test::_lrc0 = test::lvalue_const_bitset<0>() + ); + dp0( + test::_lrc1 = test::lvalue_const_bitset<4>() + , test::_lrc0 = test::lvalue_const_bitset<0>() + , test::_lr0 = test::lvalue_bitset<1>() + , test::_rrc0 = test::rvalue_const_bitset<2>() + , test::_rr0 = test::rvalue_bitset<3>() + ); + dp1( + test::_lr0 = test::lvalue_bitset<1>() + , test::_rrc0 = test::rvalue_const_bitset<2>() + , test::_rr0 = test::rvalue_bitset<3>() + , test::_lrc1 = test::lvalue_const_bitset<4>() + , test::_lr1 = test::lvalue_bitset<5>() + , test::_rrc1 = test::rvalue_const_bitset<6>() + , test::_rr1 = test::rvalue_bitset<7>() + , test::_lrc0 = test::lvalue_const_bitset<0>() + ); + return boost::report_errors(); +} + diff --git a/test/sfinae.cpp b/test/sfinae.cpp index 46dbe51..c99b097 100644 --- a/test/sfinae.cpp +++ b/test/sfinae.cpp @@ -5,10 +5,10 @@ #include -#if !defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING) #if (BOOST_PARAMETER_MAX_ARITY < 2) #error Define BOOST_PARAMETER_MAX_ARITY as 2 or greater. #endif +#if !defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING) #if (BOOST_PARAMETER_EXPONENTIAL_OVERLOAD_THRESHOLD_ARITY < 3) #error Define BOOST_PARAMETER_EXPONENTIAL_OVERLOAD_THRESHOLD_ARITY \ as 3 or greater. diff --git a/test/singular.cpp b/test/singular.cpp index 4c1d757..0acb6e9 100644 --- a/test/singular.cpp +++ b/test/singular.cpp @@ -26,6 +26,8 @@ namespace test { } // namespace test #include +#include +#include #include namespace test { @@ -45,12 +47,10 @@ namespace test { #include #include #include -#include #include #include #include #include -#include namespace test {