]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // Copyright (C) 2003, 2008 Fernando Luis Cacciola Carballal. |
2 | // Copyright (C) 2015 Andrzej Krzemienski. | |
3 | // | |
4 | // Use, modification, and distribution is subject to the Boost Software | |
5 | // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at | |
6 | // http://www.boost.org/LICENSE_1_0.txt) | |
7 | // | |
8 | // See http://www.boost.org/libs/optional for documentation. | |
9 | // | |
10 | // You are welcome to contact the author at: | |
11 | // akrzemi1@gmail.com | |
12 | ||
13 | #ifndef BOOST_OPTIONAL_DETAIL_OPTIONAL_SWAP_AJK_28JAN2015_HPP | |
14 | #define BOOST_OPTIONAL_DETAIL_OPTIONAL_SWAP_AJK_28JAN2015_HPP | |
15 | ||
16 | #include <boost/core/swap.hpp> | |
17 | #include <boost/optional/optional_fwd.hpp> | |
18 | ||
19 | namespace boost { | |
20 | ||
21 | namespace optional_detail { | |
22 | ||
23 | template <bool use_default_constructor> struct swap_selector; | |
24 | ||
25 | template <> | |
26 | struct swap_selector<true> | |
27 | { | |
28 | template <class T> | |
29 | static void optional_swap ( optional<T>& x, optional<T>& y ) | |
30 | { | |
31 | const bool hasX = !!x; | |
32 | const bool hasY = !!y; | |
33 | ||
34 | if ( !hasX && !hasY ) | |
35 | return; | |
36 | ||
37 | if( !hasX ) | |
38 | x.emplace(); | |
39 | else if ( !hasY ) | |
40 | y.emplace(); | |
41 | ||
42 | // Boost.Utility.Swap will take care of ADL and workarounds for broken compilers | |
43 | boost::swap(x.get(), y.get()); | |
44 | ||
45 | if( !hasX ) | |
46 | y = boost::none ; | |
47 | else if( !hasY ) | |
48 | x = boost::none ; | |
49 | } | |
50 | }; | |
51 | ||
52 | #ifdef BOOST_OPTIONAL_DETAIL_MOVE | |
53 | # undef BOOST_OPTIONAL_DETAIL_MOVE | |
54 | #endif | |
55 | ||
56 | #ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES | |
57 | # define BOOST_OPTIONAL_DETAIL_MOVE(EXPR_) boost::move(EXPR_) | |
58 | #else | |
59 | # define BOOST_OPTIONAL_DETAIL_MOVE(EXPR_) EXPR_ | |
60 | #endif | |
61 | ||
62 | template <> | |
63 | struct swap_selector<false> | |
64 | { | |
65 | template <class T> | |
66 | static void optional_swap ( optional<T>& x, optional<T>& y ) | |
67 | //BOOST_NOEXCEPT_IF(::boost::is_nothrow_move_constructible<T>::value && BOOST_NOEXCEPT_EXPR(boost::swap(*x, *y))) | |
68 | { | |
69 | if (x) | |
70 | { | |
71 | if (y) | |
72 | { | |
73 | boost::swap(*x, *y); | |
74 | } | |
75 | else | |
76 | { | |
77 | y = BOOST_OPTIONAL_DETAIL_MOVE(*x); | |
78 | x = boost::none; | |
79 | } | |
80 | } | |
81 | else | |
82 | { | |
83 | if (y) | |
84 | { | |
85 | x = BOOST_OPTIONAL_DETAIL_MOVE(*y); | |
86 | y = boost::none; | |
87 | } | |
88 | } | |
89 | } | |
90 | }; | |
91 | ||
92 | } // namespace optional_detail | |
93 | ||
94 | #if (!defined BOOST_NO_CXX11_RVALUE_REFERENCES) && (!defined BOOST_CONFIG_RESTORE_OBSOLETE_SWAP_IMPLEMENTATION) | |
95 | ||
96 | template<class T> | |
97 | struct optional_swap_should_use_default_constructor : boost::false_type {} ; | |
98 | ||
99 | #else | |
100 | ||
101 | template<class T> | |
102 | struct optional_swap_should_use_default_constructor : has_nothrow_default_constructor<T> {} ; | |
103 | ||
104 | #endif | |
105 | ||
106 | template <class T> | |
107 | inline void swap ( optional<T>& x, optional<T>& y ) | |
108 | //BOOST_NOEXCEPT_IF(::boost::is_nothrow_move_constructible<T>::value && BOOST_NOEXCEPT_EXPR(boost::swap(*x, *y))) | |
109 | { | |
110 | optional_detail::swap_selector<optional_swap_should_use_default_constructor<T>::value>::optional_swap(x, y); | |
111 | } | |
112 | ||
113 | } // namespace boost | |
114 | ||
115 | #undef BOOST_OPTIONAL_DETAIL_MOVE | |
116 | ||
117 | #endif // header guard |