diff --git a/doc/reference/key_extraction.html b/doc/reference/key_extraction.html index d8702e4..5704737 100644 --- a/doc/reference/key_extraction.html +++ b/doc/reference/key_extraction.html @@ -56,7 +56,9 @@ Compiler specifics "boost/multi_index/mem_fun.hpp" synopsis @@ -141,17 +143,22 @@ for every k1 of type const KeyFromValue and

-Boost.MultiIndex provides six general-purpose key extractors: +Boost.MultiIndex provides twelve general-purpose key extractors:

plus, in C++17 compliant environments, an alias template key -allowing for a very terse specification of the latter five extractors. +allowing for a very terse specification of the previous extractors +(except identity).

Chained pointers

@@ -429,9 +436,33 @@ to plain member because it provides a slightly more concise syntax. template<class Class,typename Type,Type (Class::*PtrToMemberFunction)()const> struct const_mem_fun; +template< + class Class,typename Type,Type (Class::*PtrToMemberFunction)()const volatile +> +struct cv_mem_fun; + +template<class Class,typename Type,Type (Class::*PtrToMemberFunction)()const&> +struct cref_mem_fun; + +template< + class Class,typename Type,Type (Class::*PtrToMemberFunction)()const volatile& +> +struct cvref_mem_fun; + template<class Class,typename Type,Type (Class::*PtrToMemberFunction)()> struct mem_fun; +template<class Class,typename Type,Type (Class::*PtrToMemberFunction)()volatile> +struct volatile_mem_fun; + +template<class Class,typename Type,Type (Class::*PtrToMemberFunction)()&> +struct ref_mem_fun; + +template< + class Class,typename Type,Type (Class::*PtrToMemberFunction)()volatile& +> +struct vref_mem_fun; + template< class Class,typename Type, typename PtrToMemberFunctionType,PtrToMemberFunctionType PtrToMemberFunction @@ -526,6 +557,20 @@ object chained-pointed to by x. Returns: (x.get().*PtrToMemberFunction)(). +

Class templates cv_mem_fun, cref_mem_fun and cvref_mem_fun

+ +

+These Key Extractors are variants of +const_mem_fun used in the case that the +passed member function is: +

+Other than this, their interface is exactly the same as that of const_mem_fun. +

+

Class template mem_fun

@@ -584,6 +629,20 @@ object chained-pointed to by x. Returns: (x.get().*PtrToMemberFunction)(). +

Class templates volatile_mem_fun, ref_mem_fun and vref_mem_fun

+ +

+These Key Extractors are variants of +mem_fun used in the case that the +passed member function is: +

+Other than this, their interface is exactly the same as that of mem_fun. +

+

Class templates const_mem_fun_explicit and mem_fun_explicit

@@ -2106,13 +2165,40 @@ resolves to: if Key is of type Type Class::*,

  • const_mem_fun<Class,Type,Key> - if Key is of type Type (Class::*)()const, + if Key is of type Type (Class::*)()const + (with ot without noexcept-specification), +
  • +
  • cv_mem_fun<Class,Type,Key> + if Key is of type Type (Class::*)()const volatile + (with ot without noexcept-specification), +
  • +
  • cref_mem_fun<Class,Type,Key> + if Key is of type Type (Class::*)()const& + (with ot without noexcept-specification), +
  • +
  • cvref_mem_fun<Class,Type,Key> + if Key is of type Type (Class::*)()const volatile& + (with ot without noexcept-specification),
  • mem_fun<Class,Type,Key> - if Key is of type Type (Class::*)(), + if Key is of type Type (Class::*)() + (with ot without noexcept-specification), +
  • +
  • volatile_mem_fun<Class,Type,Key> + if Key is of type Type (Class::*)()volatile + (with ot without noexcept-specification), +
  • +
  • ref_mem_fun<Class,Type,Key> + if Key is of type Type (Class::*)()& + (with ot without noexcept-specification), +
  • +
  • vref_mem_fun<Class,Type,Key> + if Key is of type Type (Class::*)()volatile& + (with ot without noexcept-specification),
  • global_fun<Value,Type,Key> - if Key is of type Type (*)(Value), + if Key is of type Type (*)(Value) + (with ot without noexcept-specification),
  • and engenders undefined behavior otherwise. When passed two or more arguments, @@ -2150,9 +2236,9 @@ Compiler specifics
    -

    Revised August 22nd 2018

    +

    Revised June 9th 2019

    -

    © Copyright 2003-2018 Joaquín M López Muñoz. +

    © Copyright 2003-2019 Joaquín M López Muñoz. Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at diff --git a/doc/release_notes.html b/doc/release_notes.html index 069d25a..3079c98 100644 --- a/doc/release_notes.html +++ b/doc/release_notes.html @@ -30,6 +30,7 @@ Acknowledgements

    Contents

    +

    Boost 1.71 release

    + +

    +

    +

    +

    Boost 1.70 release

    @@ -618,9 +635,9 @@ Acknowledgements
    -

    Revised December 30th 2018

    +

    Revised June 9th 2019

    -

    © Copyright 2003-2018 Joaquín M López Muñoz. +

    © Copyright 2003-2019 Joaquín M López Muñoz. Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at diff --git a/doc/tutorial/key_extraction.html b/doc/tutorial/key_extraction.html index b9b228a..76957d1 100644 --- a/doc/tutorial/key_extraction.html +++ b/doc/tutorial/key_extraction.html @@ -39,8 +39,11 @@ Container creation

    @@ -246,10 +249,97 @@ of Boost.MultiIndex key extractors. provides a complete program showing how to use const_mem_fun.

    +

    Variants for other types of member functions

    + +

    +Consider the following, non-compiling code: +

    + +
    +struct employee
    +{
    +  ...
    +  std::size_t salary()const&; // note the &
    +};
    +
    +typedef multi_index_container<
    +  employee,
    +  indexed_by<
    +    ...
    +    ordered_non_unique<
    +      // compiler error: can't convert &employee::salary to
    +      // std::size_t (employee::*)() const
    +      const_mem_fun<employee,std::size_t,&employee::salary>
    +    >
    +  >
    +> employee_set;
    +
    + +

    +The problem here is that the type of &employee::salary, which is +ref-qualified, +does not match exactly what const_mem_fun expects. Fortunatey, Boost.MultiIndex +provides a variant to fit: +

    + +
    +typedef multi_index_container<
    +  employee,
    +  indexed_by<
    +    ...
    +    ordered_non_unique<
    +      cref_mem_fun<employee,std::size_t,&employee::salary>
    +    >
    +  >
    +> employee_set;
    +
    + +

    +This is the list of all available variants of const_mem_fun and +mem_fun: +

    + +

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Variants of const_mem_fun and mem_fun.
     Member function example Suitable extractorBehaves as
    int f()const volatilecv_mem_fun<int,X,&X::f> const_mem_fun 
    int f()const&cref_mem_fun<int,X,&X::f>
    int f()const volatile&cvref_mem_fun<int,X,&X::f>
    int f()volatilevolatile_mem_fun<int,X,&X::f>mem_fun
    int f()&ref_mem_fun<int,X,&X::f>
    int f()volatile&vref_mem_fun<int,X,&X::f>
    +

    +

    global_fun

    -Whereas const_mem_fun and mem_fun are based on a +Whereas const_mem_fun and its variants are based on a given member function of the base type from where the key is extracted, global_fun takes a global function (or static member function) accepting the base @@ -638,8 +728,10 @@ which results in the exact same defined type, as key constructs are mere aliases for the old syntax. key can be used to shorten the specification of member, -const_mem_fun, -mem_fun, +const_mem_fun +(and variants), +mem_fun +(and variants), global_fun and, with additional terseness benefits, composite_key: @@ -1034,9 +1126,9 @@ Container creation
    -

    Revised August 18th 2018

    +

    Revised June 9th 2019

    -

    © Copyright 2003-2018 Joaquín M López Muñoz. +

    © Copyright 2003-2019 Joaquín M López Muñoz. Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at diff --git a/include/boost/multi_index/key.hpp b/include/boost/multi_index/key.hpp index 48a418a..8ae6656 100644 --- a/include/boost/multi_index/key.hpp +++ b/include/boost/multi_index/key.hpp @@ -1,4 +1,4 @@ -/* Copyright 2003-2018 Joaquin M Lopez Munoz. +/* Copyright 2003-2019 Joaquin M Lopez Munoz. * 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) @@ -47,21 +47,26 @@ struct typed_key_impl< using type=member; }; -template< - typename Class,typename Type,Type (Class::*PtrToMemberFunction)()const -> -struct typed_key_impl -{ - using value_type=Class; - using type=const_mem_fun; +#define BOOST_MULTI_INDEX_KEY_TYPED_KEY_IMPL(qualifier,extractor) \ +template< \ + typename Class,typename Type,Type (Class::*PtrToMemberFunction)()qualifier \ +> \ +struct typed_key_impl \ +{ \ + using value_type=Class; \ + using type=extractor; \ }; -template -struct typed_key_impl -{ - using value_type=Class; - using type=mem_fun; -}; +BOOST_MULTI_INDEX_KEY_TYPED_KEY_IMPL( ,mem_fun) +BOOST_MULTI_INDEX_KEY_TYPED_KEY_IMPL(const ,const_mem_fun) +BOOST_MULTI_INDEX_KEY_TYPED_KEY_IMPL(volatile ,volatile_mem_fun) +BOOST_MULTI_INDEX_KEY_TYPED_KEY_IMPL(const volatile ,cv_mem_fun) +BOOST_MULTI_INDEX_KEY_TYPED_KEY_IMPL(& ,ref_mem_fun) +BOOST_MULTI_INDEX_KEY_TYPED_KEY_IMPL(const& ,cref_mem_fun) +BOOST_MULTI_INDEX_KEY_TYPED_KEY_IMPL(volatile& ,vref_mem_fun) +BOOST_MULTI_INDEX_KEY_TYPED_KEY_IMPL(const volatile& ,cvref_mem_fun) + +#undef BOOST_MULTI_INDEX_KEY_TYPED_KEY_IMPL template struct typed_key_impl @@ -70,11 +75,47 @@ struct typed_key_impl using type=global_fun; }; +template +struct remove_noexcept{using type=T;}; + +#define BOOST_MULTI_INDEX_KEY_REMOVE_MEMFUN_NOEXCEPT(qualifier) \ +template \ +struct remove_noexcept \ + {using type=R(C::*)(Args...)qualifier;}; \ + \ +template \ +struct remove_noexcept \ + {using type=R(C::*)(Args...,...)qualifier;}; + +BOOST_MULTI_INDEX_KEY_REMOVE_MEMFUN_NOEXCEPT() +BOOST_MULTI_INDEX_KEY_REMOVE_MEMFUN_NOEXCEPT(const) +BOOST_MULTI_INDEX_KEY_REMOVE_MEMFUN_NOEXCEPT(volatile) +BOOST_MULTI_INDEX_KEY_REMOVE_MEMFUN_NOEXCEPT(const volatile) +BOOST_MULTI_INDEX_KEY_REMOVE_MEMFUN_NOEXCEPT(&) +BOOST_MULTI_INDEX_KEY_REMOVE_MEMFUN_NOEXCEPT(const&) +BOOST_MULTI_INDEX_KEY_REMOVE_MEMFUN_NOEXCEPT(volatile&) +BOOST_MULTI_INDEX_KEY_REMOVE_MEMFUN_NOEXCEPT(const volatile&) +BOOST_MULTI_INDEX_KEY_REMOVE_MEMFUN_NOEXCEPT(&&) +BOOST_MULTI_INDEX_KEY_REMOVE_MEMFUN_NOEXCEPT(const&&) +BOOST_MULTI_INDEX_KEY_REMOVE_MEMFUN_NOEXCEPT(volatile&&) +BOOST_MULTI_INDEX_KEY_REMOVE_MEMFUN_NOEXCEPT(const volatile&&) + +#undef BOOST_MULTI_INDEX_KEY_REMOVE_MEMFUN_NOEXCEPT + +template +struct remove_noexcept{using type=R(*)(Args...);}; +template +struct remove_noexcept + {using type=R(*)(Args...,...);}; + +template +using remove_noexcept_t=typename remove_noexcept::type; + template struct key_impl; template -struct key_impl:typed_key_impl{}; +struct key_impl:typed_key_impl,Key>{}; template struct least_generic; diff --git a/include/boost/multi_index/mem_fun.hpp b/include/boost/multi_index/mem_fun.hpp index 111c386..aa116f0 100644 --- a/include/boost/multi_index/mem_fun.hpp +++ b/include/boost/multi_index/mem_fun.hpp @@ -1,4 +1,4 @@ -/* Copyright 2003-2015 Joaquin M Lopez Munoz. +/* Copyright 2003-2019 Joaquin M Lopez Munoz. * 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) @@ -30,17 +30,30 @@ namespace multi_index{ /* mem_fun implements a read-only key extractor based on a given non-const * member function of a class. - * const_mem_fun does the same for const member functions. - * Additionally, mem_fun and const_mem_fun are overloaded to support - * referece_wrappers of T and "chained pointers" to T's. By chained pointer - * to T we mean a type P such that, given a p of Type P + * Also, the following variations are provided: + * const_mem_fun: const member functions + * volatile_mem_fun: volatile member functions + * cv_mem_fun: const volatile member functions + * ref_mem_fun: ref-qualifed member functions (C++11) + * cref_mem_fun: const ref-qualifed member functions (C++11) + * vref_mem_fun: volatile ref-qualifed member functions (C++11) + * cvref_mem_fun: const volatile ref-qualifed member functions (C++11) + * + * All of these classes are overloaded to support boost::referece_wrappers + * of T and "chained pointers" to T's. By chained pointer to T we mean a type + * P such that, given a p of Type P * *...n...*x is convertible to T&, for some n>=1. * Examples of chained pointers are raw and smart pointers, iterators and * arbitrary combinations of these (vg. T** or unique_ptr.) */ -template -struct const_mem_fun +namespace detail{ + +template< + class Class,typename Type, + typename PtrToMemberFunctionType,PtrToMemberFunctionType PtrToMemberFunction +> +struct const_mem_fun_impl { typedef typename remove_reference::type result_type; @@ -74,8 +87,11 @@ struct const_mem_fun } }; -template -struct mem_fun +template< + class Class,typename Type, + typename PtrToMemberFunctionType,PtrToMemberFunctionType PtrToMemberFunction +> +struct mem_fun_impl { typedef typename remove_reference::type result_type; @@ -104,6 +120,62 @@ struct mem_fun } }; +} /* namespace multi_index::detail */ + +template +struct const_mem_fun:detail::const_mem_fun_impl< + Class,Type,Type (Class::*)()const,PtrToMemberFunction +>{}; + +template< + class Class,typename Type, + Type (Class::*PtrToMemberFunction)()const volatile +> +struct cv_mem_fun:detail::const_mem_fun_impl< + Class,Type,Type (Class::*)()const volatile,PtrToMemberFunction +>{}; + +template +struct mem_fun: + detail::mem_fun_impl{}; + +template< + class Class,typename Type,Type (Class::*PtrToMemberFunction)()volatile +> +struct volatile_mem_fun:detail::mem_fun_impl< + Class,Type,Type (Class::*)()volatile,PtrToMemberFunction +>{}; + +#if !defined(BOOST_NO_CXX11_REF_QUALIFIERS) + +template< + class Class,typename Type,Type (Class::*PtrToMemberFunction)()const& +> +struct cref_mem_fun:detail::const_mem_fun_impl< + Class,Type,Type (Class::*)()const&,PtrToMemberFunction +>{}; + +template< + class Class,typename Type, + Type (Class::*PtrToMemberFunction)()const volatile& +> +struct cvref_mem_fun:detail::const_mem_fun_impl< + Class,Type,Type (Class::*)()const volatile&,PtrToMemberFunction +>{}; + +template +struct ref_mem_fun: + detail::mem_fun_impl{}; + +template< + class Class,typename Type,Type (Class::*PtrToMemberFunction)()volatile& +> +struct vref_mem_fun:detail::mem_fun_impl< + Class,Type,Type (Class::*)()volatile&,PtrToMemberFunction +>{}; + +#endif + /* MSVC++ 6.0 has problems with const member functions as non-type template * parameters, somehow it takes them as non-const. const_mem_fun_explicit * workarounds this deficiency by accepting an extra type parameter that @@ -119,7 +191,8 @@ struct mem_fun template< class Class,typename Type, - typename PtrToMemberFunctionType,PtrToMemberFunctionType PtrToMemberFunction> + typename PtrToMemberFunctionType,PtrToMemberFunctionType PtrToMemberFunction +> struct const_mem_fun_explicit { typedef typename remove_reference::type result_type; @@ -156,7 +229,8 @@ struct const_mem_fun_explicit template< class Class,typename Type, - typename PtrToMemberFunctionType,PtrToMemberFunctionType PtrToMemberFunction> + typename PtrToMemberFunctionType,PtrToMemberFunctionType PtrToMemberFunction +> struct mem_fun_explicit { typedef typename remove_reference::type result_type; diff --git a/test/test_key.cpp b/test/test_key.cpp index 264b957..10ebb37 100644 --- a/test/test_key.cpp +++ b/test/test_key.cpp @@ -1,6 +1,6 @@ /* Boost.MultiIndex test for terse key specification syntax. * - * Copyright 2003-2018 Joaquin M Lopez Munoz. + * Copyright 2003-2019 Joaquin M Lopez Munoz. * 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) @@ -39,9 +39,24 @@ struct base const int cx; int f(){return x;}; int cf()const{return x;}; + int vf()volatile{return x;}; + int cvf()const volatile{return x;}; + int rf()&{return x;}; + int crf()const&{return x;}; + int vrf()volatile&{return x;}; + int cvrf()const volatile&{return x;}; + int nef()noexcept{return x;}; + int cnef()const noexcept{return x;}; + int vnef()volatile noexcept{return x;}; + int cvnef()const volatile noexcept{return x;}; + int rnef()& noexcept{return x;}; + int crnef()const& noexcept{return x;}; + int vrnef()volatile& noexcept{return x;}; + int cvrnef()const volatile& noexcept{return x;}; }; int gf(const base& b){return b.x;} +int negf(const base& b)noexcept{return b.x;} struct derived:base { @@ -67,9 +82,54 @@ void test_key() BOOST_TEST((std::is_same< key<&base::cf>,const_mem_fun >::value)); + BOOST_TEST((std::is_same< + key<&base::vf>,volatile_mem_fun + >::value)); + BOOST_TEST((std::is_same< + key<&base::cvf>,cv_mem_fun + >::value)); + BOOST_TEST((std::is_same< + key<&base::rf>,ref_mem_fun + >::value)); + BOOST_TEST((std::is_same< + key<&base::crf>,cref_mem_fun + >::value)); + BOOST_TEST((std::is_same< + key<&base::vrf>,vref_mem_fun + >::value)); + BOOST_TEST((std::is_same< + key<&base::cvrf>,cvref_mem_fun + >::value)); + BOOST_TEST((std::is_same< + key<&base::nef>,mem_fun + >::value)); + BOOST_TEST((std::is_same< + key<&base::cnef>,const_mem_fun + >::value)); + BOOST_TEST((std::is_same< + key<&base::vnef>,volatile_mem_fun + >::value)); + BOOST_TEST((std::is_same< + key<&base::cvnef>,cv_mem_fun + >::value)); + BOOST_TEST((std::is_same< + key<&base::rnef>,ref_mem_fun + >::value)); + BOOST_TEST((std::is_same< + key<&base::crnef>,cref_mem_fun + >::value)); + BOOST_TEST((std::is_same< + key<&base::vrnef>,vref_mem_fun + >::value)); + BOOST_TEST((std::is_same< + key<&base::cvrnef>,cvref_mem_fun + >::value)); BOOST_TEST((std::is_same< key,global_fun >::value)); + BOOST_TEST((std::is_same< + key,global_fun + >::value)); BOOST_TEST((std::is_same< key<&base::x,&base::cx,&base::f,&base::cf,gf>, composite_key< diff --git a/test/test_key_extractors.cpp b/test/test_key_extractors.cpp index 33111d1..95643df 100644 --- a/test/test_key_extractors.cpp +++ b/test/test_key_extractors.cpp @@ -1,6 +1,6 @@ /* Boost.MultiIndex test for key extractors. * - * Copyright 2003-2015 Joaquin M Lopez Munoz. + * Copyright 2003-2019 Joaquin M Lopez Munoz. * 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) @@ -28,6 +28,17 @@ struct test_class bool bool_mem_fun_const()const{return true;} bool bool_mem_fun(){return false;} + bool bool_mem_fun_volatile()volatile{return false;} + bool bool_mem_fun_cv()const volatile{return true;} + +#if !defined(BOOST_NO_CXX11_REF_QUALIFIERS) + + bool bool_mem_fun_cref()const&{return true;} + bool bool_mem_fun_ref()&{return false;} + bool bool_mem_fun_vref()volatile&{return false;} + bool bool_mem_fun_cvref()const volatile&{return true;} + +#endif static bool bool_global_fun(test_class){return true;} static bool bool_global_fun_const_ref(const test_class&){return false;} @@ -66,9 +77,25 @@ typedef identity cidn; typedef BOOST_MULTI_INDEX_MEMBER(test_class,int,int_member) key_m; typedef BOOST_MULTI_INDEX_MEMBER(test_class,const int,int_member) ckey_m; typedef BOOST_MULTI_INDEX_MEMBER(test_class,const int,int_cmember) key_cm; +typedef BOOST_MULTI_INDEX_MEM_FUN(test_class,bool,bool_mem_fun) key_mf; typedef BOOST_MULTI_INDEX_CONST_MEM_FUN( test_class,bool,bool_mem_fun_const) key_cmf; -typedef BOOST_MULTI_INDEX_MEM_FUN(test_class,bool,bool_mem_fun) key_mf; +typedef volatile_mem_fun< + test_class,bool,&test_class::bool_mem_fun_volatile> key_vmf; +typedef cv_mem_fun key_cvmf; + +#if !defined(BOOST_NO_CXX11_REF_QUALIFIERS) + +typedef cref_mem_fun< + test_class,bool,&test_class::bool_mem_fun_cref> key_crmf; +typedef ref_mem_fun key_rmf; +typedef vref_mem_fun< + test_class,bool,&test_class::bool_mem_fun_vref> key_vrmf; +typedef cvref_mem_fun< + test_class,bool,&test_class::bool_mem_fun_cvref> key_cvrmf; + +#endif + typedef global_fun key_gf; typedef global_fun< const test_class&,bool, @@ -165,6 +192,14 @@ void test_key_extractors() key_cm k_cm; key_cmf k_cmf; key_mf k_mf; + key_vmf k_vmf; + key_cvmf k_cvmf; +#if !defined(BOOST_NO_CXX11_REF_QUALIFIERS) + key_crmf k_crmf; + key_rmf k_rmf; + key_vrmf k_vrmf; + key_cvrmf k_cvrmf; +#endif key_gf k_gf; key_gcrf k_gcrf; key_grf k_grf; @@ -313,43 +348,139 @@ void test_key_extractors() BOOST_TEST(k_cmf(tr)); BOOST_TEST(k_cmf(ctr)); + BOOST_TEST(k_cvmf(tr)); + BOOST_TEST(k_cvmf(ctr)); + +#if !defined(BOOST_NO_CXX11_REF_QUALIFIERS) + BOOST_TEST(k_crmf(tr)); + BOOST_TEST(k_crmf(ctr)); + BOOST_TEST(k_cvrmf(tr)); + BOOST_TEST(k_cvrmf(ctr)); +#endif #if !defined(BOOST_NO_SFINAE) BOOST_TEST(k_cmf(td)); BOOST_TEST(k_cmf(ctdr)); + BOOST_TEST(k_cvmf(td)); + BOOST_TEST(k_cvmf(ctdr)); + +#if !defined(BOOST_NO_CXX11_REF_QUALIFIERS) + BOOST_TEST(k_crmf(td)); + BOOST_TEST(k_crmf(ctdr)); + BOOST_TEST(k_cvrmf(td)); + BOOST_TEST(k_cvrmf(ctdr)); +#endif #endif BOOST_TEST(k_cmf(tp)); BOOST_TEST(k_cmf(ctp)); + BOOST_TEST(k_cvmf(tp)); + BOOST_TEST(k_cvmf(ctp)); + +#if !defined(BOOST_NO_CXX11_REF_QUALIFIERS) + BOOST_TEST(k_crmf(tp)); + BOOST_TEST(k_crmf(ctp)); + BOOST_TEST(k_cvrmf(tp)); + BOOST_TEST(k_cvrmf(ctp)); +#endif #if !defined(BOOST_NO_SFINAE) BOOST_TEST(k_cmf(tdp)); BOOST_TEST(k_cmf(ctdp)); + BOOST_TEST(k_cvmf(tdp)); + BOOST_TEST(k_cvmf(ctdp)); + +#if !defined(BOOST_NO_CXX11_REF_QUALIFIERS) + BOOST_TEST(k_crmf(tdp)); + BOOST_TEST(k_crmf(ctdp)); + BOOST_TEST(k_cvrmf(tdp)); + BOOST_TEST(k_cvrmf(ctdp)); +#endif #endif BOOST_TEST(k_cmf(tpp)); BOOST_TEST(k_cmf(ctpp)); BOOST_TEST(k_cmf(tap)); BOOST_TEST(k_cmf(ctap)); + BOOST_TEST(k_cvmf(tpp)); + BOOST_TEST(k_cvmf(ctpp)); + BOOST_TEST(k_cvmf(tap)); + BOOST_TEST(k_cvmf(ctap)); + +#if !defined(BOOST_NO_CXX11_REF_QUALIFIERS) + BOOST_TEST(k_crmf(tpp)); + BOOST_TEST(k_crmf(ctpp)); + BOOST_TEST(k_crmf(tap)); + BOOST_TEST(k_crmf(ctap)); + BOOST_TEST(k_cvrmf(tpp)); + BOOST_TEST(k_cvrmf(ctpp)); + BOOST_TEST(k_cvrmf(tap)); + BOOST_TEST(k_cvrmf(ctap)); +#endif BOOST_TEST(k_cmf(tw)); BOOST_TEST(k_cmf(ctw)); + BOOST_TEST(k_cvmf(tw)); + BOOST_TEST(k_cvmf(ctw)); + +#if !defined(BOOST_NO_CXX11_REF_QUALIFIERS) + BOOST_TEST(k_crmf(tw)); + BOOST_TEST(k_crmf(ctw)); + BOOST_TEST(k_cvrmf(tw)); + BOOST_TEST(k_cvrmf(ctw)); +#endif BOOST_TEST(!k_mf(tr)); + BOOST_TEST(!k_vmf(tr)); + +#if !defined(BOOST_NO_CXX11_REF_QUALIFIERS) + BOOST_TEST(!k_rmf(tr)); + BOOST_TEST(!k_vrmf(tr)); +#endif #if !defined(BOOST_NO_SFINAE) BOOST_TEST(!k_mf(td)); + BOOST_TEST(!k_vmf(td)); + +#if !defined(BOOST_NO_CXX11_REF_QUALIFIERS) + BOOST_TEST(!k_rmf(td)); + BOOST_TEST(!k_vrmf(td)); +#endif #endif BOOST_TEST(!k_mf(tp)); + BOOST_TEST(!k_vmf(tp)); + +#if !defined(BOOST_NO_CXX11_REF_QUALIFIERS) + BOOST_TEST(!k_rmf(tp)); + BOOST_TEST(!k_vrmf(tp)); +#endif #if !defined(BOOST_NO_SFINAE) BOOST_TEST(!k_mf(tdp)); + BOOST_TEST(!k_vmf(tdp)); + +#if !defined(BOOST_NO_CXX11_REF_QUALIFIERS) + BOOST_TEST(!k_rmf(tdp)); + BOOST_TEST(!k_vrmf(tdp)); +#endif #endif BOOST_TEST(!k_mf(tpp)); BOOST_TEST(!k_mf(tap)); BOOST_TEST(!k_mf(tw)); + BOOST_TEST(!k_vmf(tpp)); + BOOST_TEST(!k_vmf(tap)); + BOOST_TEST(!k_vmf(tw)); + +#if !defined(BOOST_NO_CXX11_REF_QUALIFIERS) + BOOST_TEST(!k_rmf(tpp)); + BOOST_TEST(!k_rmf(tap)); + BOOST_TEST(!k_rmf(tw)); + BOOST_TEST(!k_vrmf(tpp)); + BOOST_TEST(!k_vrmf(tap)); + BOOST_TEST(!k_vrmf(tw)); +#endif BOOST_TEST(k_gf(tr)); BOOST_TEST(k_gf(ctr));