Ticket #10882: boost-1.57.0-fix-boost-variant-ambiguous-call-to-swap-boost-trac-10882.patch

File boost-1.57.0-fix-boost-variant-ambiguous-call-to-swap-boost-trac-10882.patch, 8.3 KB (added by Thomas Riccardi <riccardi@…>, 8 years ago)

fix backported on boost 1.57.0

  • boost/move/adl_move_swap.hpp

     
     1//////////////////////////////////////////////////////////////////////////////
     2//
     3// (C) Copyright 2007, 2008 Steven Watanabe, Joseph Gauterin, Niels Dekker
     4// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost
     5// Software License, Version 1.0. (See accompanying file
     6// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
     7//
     8// See http://www.boost.org/libs/container for documentation.
     9//
     10//////////////////////////////////////////////////////////////////////////////
     11
     12#ifndef BOOST_MOVE_ADL_MOVE_SWAP_HPP
     13#define BOOST_MOVE_ADL_MOVE_SWAP_HPP
     14
     15#if defined(BOOST_HAS_PRAGMA_ONCE)
     16#  pragma once
     17#endif
     18
     19//Based on Boost.Core's swap.
     20//Many thanks to Steven Watanabe, Joseph Gauterin and Niels Dekker.
     21
     22#include <boost/config.hpp>
     23#include <cstddef> //for std::size_t
     24
     25//Try to avoid including <algorithm>, as it's quite big
     26#if defined(_MSC_VER) && defined(BOOST_DINKUMWARE_STDLIB)
     27   #include <utility>   //Dinkum libraries define std::swap in utility which is lighter than algorithm
     28#elif defined(BOOST_GNU_STDLIB)
     29   //For non-GCC compilers, where GNUC version is not very reliable, or old GCC versions
     30   //use the good old stl_algobase header, which is quite lightweight
     31   #if !defined(BOOST_GCC) || ((__GNUC__ < 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ < 3)))
     32      #include <bits/stl_algobase.h>
     33   #elif (__GNUC__ == 4) && (__GNUC_MINOR__ == 3)
     34      //In GCC 4.3 a tiny stl_move.h was created with swap and move utilities
     35      #include <bits/stl_move.h>
     36   #else
     37      //In GCC 4.4 stl_move.h was renamed to move.h
     38      #include <bits/move.h>
     39   #endif
     40#elif defined(_LIBCPP_VERSION)
     41   #include <type_traits>  //The initial import of libc++ defines std::swap and still there
     42#elif __cplusplus >= 201103L
     43   #include <utility>    //Fallback for C++ >= 2011
     44#else
     45   #include <algorithm>  //Fallback for C++98/03
     46#endif
     47
     48#include <boost/move/utility_core.hpp> //for boost::move
     49
     50#if !defined(BOOST_MOVE_DOXYGEN_INVOKED)
     51
     52#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
     53namespace boost_move_member_swap {
     54
     55struct dont_care
     56{
     57   dont_care(...);
     58};
     59
     60struct private_type
     61{
     62   static private_type p;
     63   private_type const &operator,(int) const;
     64};
     65
     66typedef char yes_type;           
     67struct no_type{ char dummy[2]; };
     68
     69template<typename T>
     70no_type is_private_type(T const &);
     71
     72yes_type is_private_type(private_type const &);
     73
     74template <typename Type>
     75class has_member_function_named_swap
     76{
     77   struct BaseMixin
     78   {
     79      void swap();
     80   };
     81
     82   struct Base : public Type, public BaseMixin { Base(); };
     83   template <typename T, T t> class Helper{};
     84
     85   template <typename U>
     86   static no_type deduce(U*, Helper<void (BaseMixin::*)(), &U::swap>* = 0);
     87   static yes_type deduce(...);
     88
     89   public:
     90   static const bool value = sizeof(yes_type) == sizeof(deduce((Base*)(0)));
     91};
     92
     93template<typename Fun, bool HasFunc>
     94struct has_member_swap_impl
     95{
     96   static const bool value = false;
     97};
     98
     99template<typename Fun>
     100struct has_member_swap_impl<Fun, true>
     101{
     102   struct FunWrap : Fun
     103   {
     104      FunWrap();
     105
     106      using Fun::swap;
     107      private_type swap(dont_care) const;
     108   };
     109
     110   static Fun &declval_fun();
     111   static FunWrap declval_wrap();
     112
     113   static bool const value =
     114      sizeof(no_type) == sizeof(is_private_type( (declval_wrap().swap(declval_fun()), 0)) );
     115};
     116
     117template<typename Fun>
     118struct has_member_swap : public has_member_swap_impl
     119      <Fun, has_member_function_named_swap<Fun>::value>
     120{};
     121
     122}  //namespace boost_move_member_swap
     123
     124namespace boost_move_adl_swap{
     125
     126template<class P1, class P2, bool = P1::value>
     127struct and_op_impl
     128{  static const bool value = false; };
     129
     130template<class P1, class P2>
     131struct and_op_impl<P1, P2, true>
     132{  static const bool value = P2::value;   };
     133
     134template<class P1, class P2>
     135struct and_op
     136   : and_op_impl<P1, P2>
     137{};
     138
     139//////
     140
     141template<class P1, class P2, bool = P1::value>
     142struct and_op_not_impl
     143{  static const bool value = false; };
     144
     145template<class P1, class P2>
     146struct and_op_not_impl<P1, P2, true>
     147{  static const bool value = !P2::value;   };
     148
     149template<class P1, class P2>
     150struct and_op_not
     151   : and_op_not_impl<P1, P2>
     152{};
     153
     154template<class T>
     155void swap_proxy(T& x, T& y, typename boost::move_detail::enable_if_c<!boost::move_detail::has_move_emulation_enabled_impl<T>::value>::type* = 0)
     156{
     157   //use std::swap if argument dependent lookup fails
     158   //Use using directive ("using namespace xxx;") instead as some older compilers
     159   //don't do ADL with using declarations ("using ns::func;").
     160   using namespace std;
     161   swap(x, y);
     162}
     163
     164template<class T>
     165void swap_proxy(T& x, T& y
     166               , typename boost::move_detail::enable_if< and_op_not_impl<boost::move_detail::has_move_emulation_enabled_impl<T>
     167                                                                        , boost_move_member_swap::has_member_swap<T> >
     168                                                       >::type* = 0)
     169{  T t(::boost::move(x)); x = ::boost::move(y); y = ::boost::move(t);  }
     170
     171template<class T>
     172void swap_proxy(T& x, T& y
     173               , typename boost::move_detail::enable_if< and_op_impl< boost::move_detail::has_move_emulation_enabled_impl<T>
     174                                                                    , boost_move_member_swap::has_member_swap<T> >
     175                                                       >::type* = 0)
     176{  x.swap(y);  }
     177
     178}  //namespace boost_move_adl_swap{
     179
     180#else
     181
     182namespace boost_move_adl_swap{
     183
     184template<class T>
     185void swap_proxy(T& x, T& y)
     186{
     187   using std::swap;
     188   swap(x, y);
     189}
     190
     191}  //namespace boost_move_adl_swap{
     192
     193#endif   //#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
     194
     195namespace boost_move_adl_swap{
     196
     197template<class T, std::size_t N>
     198void swap_proxy(T (& x)[N], T (& y)[N])
     199{
     200   for (std::size_t i = 0; i < N; ++i){
     201      ::boost_move_adl_swap::swap_proxy(x[i], y[i]);
     202   }
     203}
     204
     205}  //namespace boost_move_adl_swap {
     206
     207#endif   //!defined(BOOST_MOVE_DOXYGEN_INVOKED)
     208
     209namespace boost{
     210
     211//! Exchanges the values of a and b, using Argument Dependent Lookup (ADL) to select a
     212//! specialized swap function if available. If no specialized swap function is available,
     213//! std::swap is used.
     214//!
     215//! <b>Exception</b>: If T uses Boost.Move's move emulation and the compiler has
     216//! no rvalue references then:
     217//!
     218//!   -  If T has a <code>T::swap(T&)</code> member, that member is called.
     219//!   -  Otherwise a move-based swap is called, equivalent to:
     220//!      <code>T t(::boost::move(x)); x = ::boost::move(y); y = ::boost::move(t);</code>.
     221template<class T>
     222void adl_move_swap(T& x, T& y)
     223{
     224   ::boost_move_adl_swap::swap_proxy(x, y);
     225}
     226
     227}  //namespace boost{
     228
     229#endif   //#ifndef BOOST_MOVE_ADL_MOVE_SWAP_HPP
  • boost/variant/detail/move.hpp

     
    55//
    66//  Copyright (c) 2002-2003 Eric Friedman
    77//  Copyright (c) 2002 by Andrei Alexandrescu
    8 //  Copyright (c) 2013 Antony Polukhin
     8//  Copyright (c) 2013-2014 Antony Polukhin
    99//
    1010//  Use, modification and distribution are subject to the
    1111//  Boost Software License, Version 1.0. (See accompanying file
     
    2626#include "boost/config.hpp"
    2727#include "boost/detail/workaround.hpp"
    2828#include "boost/move/move.hpp"
     29#include "boost/move/adl_move_swap.hpp"
    2930
    3031namespace boost { namespace detail { namespace variant {
    3132
     
    3839// types and on non-conforming compilers.
    3940//
    4041
    41 namespace move_swap_fallback {
    42 
    43 template <typename T1, typename T2>
    44 inline void swap(T1& lhs, T2& rhs)
    45 {
    46     T1 tmp( boost::detail::variant::move(lhs) );
    47     lhs = boost::detail::variant::move(rhs);
    48     rhs = boost::detail::variant::move(tmp);
    49 }
    50 
    51 } // namespace move_swap_fallback
    52 
    5342template <typename T>
    5443inline void move_swap(T& lhs, T& rhs)
    5544{
    56 #if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
    57     move_swap_fallback::swap(lhs, rhs);
    58 #else
    59     using move_swap_fallback::swap;
    60     swap(lhs, rhs);
    61 #endif
     45    ::boost::adl_move_swap(lhs, rhs);
    6246}
    6347
    6448}}} // namespace boost::detail::variant