File: swap_test.cpp

package info (click to toggle)
mcrl2 201409.0-1
  • links: PTS, VCS
  • area: main
  • in suites: buster, jessie, jessie-kfreebsd
  • size: 46,348 kB
  • ctags: 29,960
  • sloc: cpp: 213,160; ansic: 16,219; python: 13,238; yacc: 309; lex: 214; xml: 197; makefile: 83; sh: 82; pascal: 17
file content (153 lines) | stat: -rwxr-xr-x 3,127 bytes parent folder | download
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;
}