diff --git a/doc/notes.qbk b/doc/notes.qbk index 26a938fb..0377023c 100644 --- a/doc/notes.qbk +++ b/doc/notes.qbk @@ -121,7 +121,7 @@ creates a __list__ of type __list__ -[heading boost::ref] +[heading Reference Wrappers] Fusion's generation functions (e.g. __make_list__) by default stores the element types as plain non-reference types. Example: @@ -151,6 +151,8 @@ For example: See __boost_ref__ for details. +Since C++11, the standard reference wrappers (`std::ref` and `std::cref`) work as well. + [heading adt_attribute_proxy] To adapt arbitrary data types that do not allow direct access to their members, diff --git a/doc/support.qbk b/doc/support.qbk index 8c2ef1de..1a473819 100644 --- a/doc/support.qbk +++ b/doc/support.qbk @@ -254,7 +254,8 @@ Metafunction to apply __element_conversion__ to the full argument type. It removes references to `const`, references to array types are kept, even if the array is `const`. Reference wrappers are removed (see -__note_boost_ref__). +__note_boost_ref__)[footnote Since C++11, the standard reference wrappers +are also removed.]. [heading Header] diff --git a/include/boost/fusion/support/deduce.hpp b/include/boost/fusion/support/deduce.hpp index 8d53115f..b75381c5 100644 --- a/include/boost/fusion/support/deduce.hpp +++ b/include/boost/fusion/support/deduce.hpp @@ -12,6 +12,10 @@ #include #include +#ifndef BOOST_NO_CXX11_HDR_FUNCTIONAL +#include +#endif + namespace boost { namespace fusion { namespace traits { template struct deduce; @@ -86,6 +90,21 @@ namespace boost { namespace fusion { namespace traits typedef T& type; }; + // Also unwrap C++11 std::ref if available (referencee cv is deduced) +#ifndef BOOST_NO_CXX11_HDR_FUNCTIONAL + template + struct deduce &> + { + typedef T& type; + }; + + template + struct deduce const &> + { + typedef T& type; + }; +#endif + // Keep references on arrays, even if const template diff --git a/include/boost/fusion/support/detail/as_fusion_element.hpp b/include/boost/fusion/support/detail/as_fusion_element.hpp index 628dca4d..2af960ee 100644 --- a/include/boost/fusion/support/detail/as_fusion_element.hpp +++ b/include/boost/fusion/support/detail/as_fusion_element.hpp @@ -11,6 +11,10 @@ #include #include +#ifndef BOOST_NO_CXX11_HDR_FUNCTIONAL +#include +#endif + namespace boost { namespace fusion { namespace detail { template @@ -25,6 +29,14 @@ namespace boost { namespace fusion { namespace detail typedef T& type; }; +#ifndef BOOST_NO_CXX11_HDR_FUNCTIONAL + template + struct as_fusion_element > + { + typedef T& type; + }; +#endif + template struct as_fusion_element { diff --git a/test/sequence/deduce_sequence.cpp b/test/sequence/deduce_sequence.cpp index ea661662..a1569f46 100644 --- a/test/sequence/deduce_sequence.cpp +++ b/test/sequence/deduce_sequence.cpp @@ -6,6 +6,7 @@ http://www.boost.org/LICENSE_1_0.txt). ==============================================================================*/ +#include #include #include #include @@ -13,6 +14,9 @@ #include #include +#ifndef BOOST_NO_CXX11_HDR_FUNCTIONAL +#include +#endif using boost::is_same; using boost::reference_wrapper; @@ -66,6 +70,13 @@ int main() TEST_SAME_TYPE(deduce< reference_wrapper const & >::type, int &); TEST_SAME_TYPE(deduce< reference_wrapper const & >::type, int const &); +#ifndef BOOST_NO_CXX11_HDR_FUNCTIONAL + TEST_SAME_TYPE(deduce< std::reference_wrapper & >::type, int &); + TEST_SAME_TYPE(deduce< std::reference_wrapper & >::type, int const &); + TEST_SAME_TYPE(deduce< std::reference_wrapper const & >::type, int &); + TEST_SAME_TYPE(deduce< std::reference_wrapper const & >::type, int const &); +#endif + TEST_SAME_TYPE(deduce< int(&)[2] >::type, int(&)[2]); TEST_SAME_TYPE(deduce< int const (&)[2] >::type, int const (&)[2]); TEST_SAME_TYPE(deduce< int volatile (&)[2] >::type, int volatile (&)[2]);