// Copyright (C) 2003, 2008 Fernando Luis Cacciola Carballal. // Copyright (C) 2015 Andrzej Krzemienski. // // Use, modification, and distribution is subject to 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) // // See http://www.boost.org/libs/optional for documentation. // // You are welcome to contact the author at: // akrzemi1@gmail.com #ifndef BOOST_OPTIONAL_DETAIL_OPTIONAL_SWAP_AJK_28JAN2015_HPP #define BOOST_OPTIONAL_DETAIL_OPTIONAL_SWAP_AJK_28JAN2015_HPP #include #include namespace boost { namespace optional_detail { template struct swap_selector; template <> struct swap_selector { template static void optional_swap ( optional& x, optional& y ) { const bool hasX = !!x; const bool hasY = !!y; if ( !hasX && !hasY ) return; if( !hasX ) x.emplace(); else if ( !hasY ) y.emplace(); // Boost.Utility.Swap will take care of ADL and workarounds for broken compilers boost::swap(x.get(), y.get()); if( !hasX ) y = boost::none ; else if( !hasY ) x = boost::none ; } }; #ifdef BOOST_OPTIONAL_DETAIL_MOVE # undef BOOST_OPTIONAL_DETAIL_MOVE #endif #ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES # define BOOST_OPTIONAL_DETAIL_MOVE(EXPR_) boost::move(EXPR_) #else # define BOOST_OPTIONAL_DETAIL_MOVE(EXPR_) EXPR_ #endif template <> struct swap_selector { template static void optional_swap ( optional& x, optional& y ) //BOOST_NOEXCEPT_IF(::boost::is_nothrow_move_constructible::value && BOOST_NOEXCEPT_EXPR(boost::swap(*x, *y))) { if (x) { if (y) { boost::swap(*x, *y); } else { y = BOOST_OPTIONAL_DETAIL_MOVE(*x); x = boost::none; } } else { if (y) { x = BOOST_OPTIONAL_DETAIL_MOVE(*y); y = boost::none; } } } }; } // namespace optional_detail #if (!defined BOOST_NO_CXX11_RVALUE_REFERENCES) && (!defined BOOST_CONFIG_RESTORE_OBSOLETE_SWAP_IMPLEMENTATION) template struct optional_swap_should_use_default_constructor : boost::false_type {} ; #else template struct optional_swap_should_use_default_constructor : has_nothrow_default_constructor {} ; #endif template inline void swap ( optional& x, optional& y ) //BOOST_NOEXCEPT_IF(::boost::is_nothrow_move_constructible::value && BOOST_NOEXCEPT_EXPR(boost::swap(*x, *y))) { optional_detail::swap_selector::value>::optional_swap(x, y); } } // namespace boost #undef BOOST_OPTIONAL_DETAIL_MOVE #endif // header guard