1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
|
// Author(s): Jeroen Keiren, Wieger Wesselink
// Copyright: see the accompanying file COPYING or copy at
// https://svn.win.tue.nl/trac/MCRL2/browser/trunk/COPYING
//
// Distributed under 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)
//
/// \file swap_test.cpp
/// \brief Test for std::swap usage
#include <boost/test/included/unit_test_framework.hpp>
#include <algorithm>
#include <utility>
#include <vector>
namespace nsp
{
class swappable
{
protected:
int val_;
public:
swappable(int x) : val_(x)
{}
void swap(swappable& other)
{
std::cerr << "swap method called" << std::endl;
int tmp = other.val_;
other.val_ = val_;
val_ = tmp;
}
int val() const
{
return val_;
}
};
inline bool operator<(const swappable& x, const swappable& y)
{
return x.val() < y.val();
}
}
// The following approach does not work on recent versions of Clang using C++11,
// whereas according to the standard and existing documentation it should.
/*
namespace std
{
template<>
void swap(nsp::swappable& x, nsp::swappable& y)
{
std::cerr << "std::swap specialisation" << std::endl;
x.swap(y);
}
}
*/
namespace nsp
{
void swap(swappable& x, swappable& y)
{
std::cerr << "nsp::swap overload" << std::endl;
x.swap(y);
}
}
// This test case check whether, if both std::swap and
// nsp::swap are visible, the nsp::swap is called.
BOOST_AUTO_TEST_CASE(swapping_element)
{
using std::swap;
using namespace nsp;
swappable x(1);
swappable y(2);
swap(x,y);
BOOST_CHECK(x.val() == 2);
BOOST_CHECK(y.val() == 1);
}
// This test case checks whether, if a vector is sorted and
// swap is called internally, then nsp::swap is called through
// argument dependent lookup (ADL) instead of std::swap.
// if nsp::swap is called, a message to this effect is printed.
BOOST_AUTO_TEST_CASE(swapping_vector)
{
std::vector<nsp::swappable> v;
nsp::swappable x(1);
nsp::swappable y(2);
nsp::swappable z(3);
v.push_back(y);
v.push_back(x);
std::sort(v.begin(),v.end());
}
namespace nA {
template <typename T>
class A
{
protected:
T val_;
public:
A(T x) : val_(x)
{}
void swap(A<T>& other)
{
std::cerr << "swap method called" << std::endl;
T tmp = other.val_;
other.val_ = val_;
val_ = tmp;
}
T val() const
{
return val_;
}
};
template <typename T>
inline bool operator<(const A<T>& x, const A<T>& y)
{
return x.val() < y.val();
}
template <typename T>
void swap(A<T>& x, A<T>& y)
{
std::cerr << "nA::swap overload" << std::endl;
x.swap(y);
}
} // namespace nA
// This test case checks whether ADL works if std::swap is applied to a template class.
BOOST_AUTO_TEST_CASE(template_class_swap)
{
using std::swap;
using namespace nA;
A<int> x(1);
A<int> y(2);
swap(x, y);
BOOST_CHECK(x.val() == 2);
BOOST_CHECK(y.val() == 1);
}
boost::unit_test::test_suite* init_unit_test_suite(int argc, char* argv[])
{
return 0;
}
|