1#ifndef BOOST_TYPE_TRAITS_IS_SWAPPABLE_HPP_INCLUDED
2#define BOOST_TYPE_TRAITS_IS_SWAPPABLE_HPP_INCLUDED
3
4// Copyright 2023 Andrey Semashev
5//
6// Distributed under the Boost Software License, Version 1.0.
7// See accompanying file LICENSE_1_0.txt or copy at
8// http://www.boost.org/LICENSE_1_0.txt
9
10#include <boost/config.hpp>
11#include <boost/config/workaround.hpp>
12
13#if !defined(BOOST_NO_SFINAE_EXPR) && !defined(BOOST_NO_CXX11_DECLTYPE) && !defined(BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS) && \
14 !(defined(BOOST_DINKUMWARE_STDLIB) && (BOOST_CXX_VERSION < 201703L))
15
16#include <boost/type_traits/detail/is_swappable_cxx_11.hpp>
17
18namespace boost
19{
20
21template<class T, class U> struct is_swappable_with : boost_type_traits_swappable_detail::is_swappable_with_helper<T, U>::type
22{
23};
24
25template<class T> struct is_swappable : boost_type_traits_swappable_detail::is_swappable_helper<T>::type
26{
27};
28
29} // namespace boost
30
31#elif defined(BOOST_DINKUMWARE_STDLIB) && (BOOST_CXX_VERSION < 201703L) && \
32 !defined(BOOST_NO_SFINAE_EXPR) && !defined(BOOST_NO_CXX11_DECLTYPE) && !defined(BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \
33 !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !BOOST_WORKAROUND(BOOST_MSVC, < 1800) // these are required for is_constructible and is_assignable
34
35// MSVC standard library has SFINAE-unfriendly std::swap in C++ modes prior to C++17,
36// so we have to reproduce the restrictions on std::swap that are in effect in C++17 mode.
37
38#include <cstddef>
39#include <boost/type_traits/negation.hpp>
40#include <boost/type_traits/conjunction.hpp>
41#include <boost/type_traits/integral_constant.hpp>
42#include <boost/type_traits/is_constructible.hpp>
43#include <boost/type_traits/is_assignable.hpp>
44#include <boost/type_traits/is_const.hpp>
45#include <boost/type_traits/detail/is_swappable_cxx_11.hpp>
46
47namespace boost
48{
49
50template<class T> struct is_swappable
51 : boost::conjunction<
52 boost::negation< boost::is_const<T> >,
53 boost::is_constructible<T, T&&>,
54 boost::is_assignable<T&, T&&>
55 >::type {};
56
57template<> struct is_swappable<void> : false_type {};
58template<> struct is_swappable<const void> : false_type {};
59template<> struct is_swappable<volatile void> : false_type {};
60template<> struct is_swappable<const volatile void> : false_type {};
61template<class T> struct is_swappable<T[]> : false_type {};
62template<class T> struct is_swappable<T(&)[]> : false_type {};
63template<class T, std::size_t N> struct is_swappable<T[N]> : is_swappable<T> {};
64template<class T, std::size_t N> struct is_swappable<T(&)[N]> : is_swappable<T> {};
65
66template<class T, class U> struct is_swappable_with : boost_type_traits_swappable_detail::is_swappable_with_helper<T, U>::type
67{
68};
69
70template<class T> struct is_swappable_with<T, T> : is_swappable<T> {};
71
72} // namespace boost
73
74#else
75
76#include <boost/type_traits/is_scalar.hpp>
77#include <boost/type_traits/integral_constant.hpp>
78
79namespace boost
80{
81
82template<class T> struct is_swappable : boost::is_scalar<T> {};
83template<class T> struct is_swappable<const T> : false_type {};
84
85template<class T, class U> struct is_swappable_with : false_type {};
86template<class T> struct is_swappable_with<T, T> : is_swappable<T> {};
87
88} // namespace boost
89
90#endif
91
92#endif // #ifndef BOOST_TYPE_TRAITS_IS_SWAPPABLE_HPP_INCLUDED
93