Support removing the C++11 standard reference wrappers.

This commit is contained in:
Kohei Takahashi
2015-01-15 18:58:33 +09:00
parent 54dedc5e98
commit ce8bf1079a
5 changed files with 47 additions and 2 deletions

View File

@ -121,7 +121,7 @@ creates a __list__ of type
__list__<void (*)(int)>
[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,

View File

@ -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]

View File

@ -12,6 +12,10 @@
#include <boost/fusion/support/config.hpp>
#include <boost/ref.hpp>
#ifndef BOOST_NO_CXX11_HDR_FUNCTIONAL
#include <functional>
#endif
namespace boost { namespace fusion { namespace traits
{
template <typename T> 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 <typename T>
struct deduce<std::reference_wrapper<T> &>
{
typedef T& type;
};
template <typename T>
struct deduce<std::reference_wrapper<T> const &>
{
typedef T& type;
};
#endif
// Keep references on arrays, even if const
template <typename T, int N>

View File

@ -11,6 +11,10 @@
#include <boost/fusion/support/config.hpp>
#include <boost/ref.hpp>
#ifndef BOOST_NO_CXX11_HDR_FUNCTIONAL
#include <functional>
#endif
namespace boost { namespace fusion { namespace detail
{
template <typename T>
@ -25,6 +29,14 @@ namespace boost { namespace fusion { namespace detail
typedef T& type;
};
#ifndef BOOST_NO_CXX11_HDR_FUNCTIONAL
template <typename T>
struct as_fusion_element<std::reference_wrapper<T> >
{
typedef T& type;
};
#endif
template <typename T, int N>
struct as_fusion_element<T[N]>
{

View File

@ -6,6 +6,7 @@
http://www.boost.org/LICENSE_1_0.txt).
==============================================================================*/
#include <boost/config.hpp>
#include <boost/fusion/support/deduce_sequence.hpp>
#include <boost/fusion/mpl.hpp>
#include <boost/detail/lightweight_test.hpp>
@ -13,6 +14,9 @@
#include <boost/mpl/equal.hpp>
#include <boost/ref.hpp>
#ifndef BOOST_NO_CXX11_HDR_FUNCTIONAL
#include <functional>
#endif
using boost::is_same;
using boost::reference_wrapper;
@ -66,6 +70,13 @@ int main()
TEST_SAME_TYPE(deduce< reference_wrapper<int> const & >::type, int &);
TEST_SAME_TYPE(deduce< reference_wrapper<int const> const & >::type, int const &);
#ifndef BOOST_NO_CXX11_HDR_FUNCTIONAL
TEST_SAME_TYPE(deduce< std::reference_wrapper<int> & >::type, int &);
TEST_SAME_TYPE(deduce< std::reference_wrapper<int const> & >::type, int const &);
TEST_SAME_TYPE(deduce< std::reference_wrapper<int> const & >::type, int &);
TEST_SAME_TYPE(deduce< std::reference_wrapper<int const> 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]);