a2e70335e2
PR c++/50500 DR 1082 * class.c (type_has_user_declared_move_constructor): New. (type_has_user_declared_move_assign): New. (add_implicitly_declared_members): Add lazy copy ops even if there's a move. * method.c (lazily_declare_fn): Delete implicit copies if there's a move. (maybe_explain_implicit_delete): Explain this. Use inform rather than error. * cp-tree.h: Declare new fns. From-SVN: r180159
281 lines
6.4 KiB
C++
281 lines
6.4 KiB
C++
// -*- C++ -*-
|
|
// Testing utilities for the rvalue reference.
|
|
//
|
|
// Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011
|
|
// Free Software Foundation, Inc.
|
|
//
|
|
// This file is part of the GNU ISO C++ Library. This library is free
|
|
// software; you can redistribute it and/or modify it under the
|
|
// terms of the GNU General Public License as published by the
|
|
// Free Software Foundation; either version 3, or (at your option)
|
|
// any later version.
|
|
//
|
|
// This library is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License along
|
|
// with this library; see the file COPYING3. If not see
|
|
// <http://www.gnu.org/licenses/>.
|
|
//
|
|
|
|
#ifndef _GLIBCXX_TESTSUITE_RVALREF_H
|
|
#define _GLIBCXX_TESTSUITE_RVALREF_H 1
|
|
|
|
#include <testsuite_hooks.h>
|
|
#include <bits/functional_hash.h>
|
|
|
|
namespace __gnu_test
|
|
{
|
|
// This class is designed to test libstdc++'s template-based rvalue
|
|
// reference support. It should fail at compile-time if there is an
|
|
// attempt to copy it.
|
|
struct rvalstruct
|
|
{
|
|
int val;
|
|
bool valid;
|
|
|
|
rvalstruct() : val(0), valid(true)
|
|
{ }
|
|
|
|
rvalstruct(int inval) : val(inval), valid(true)
|
|
{ }
|
|
|
|
rvalstruct&
|
|
operator=(int newval)
|
|
{
|
|
val = newval;
|
|
valid = true;
|
|
return *this;
|
|
}
|
|
|
|
rvalstruct(const rvalstruct&) = delete;
|
|
|
|
rvalstruct(rvalstruct&& in)
|
|
{
|
|
bool test __attribute__((unused)) = true;
|
|
VERIFY( in.valid == true );
|
|
val = in.val;
|
|
in.valid = false;
|
|
valid = true;
|
|
}
|
|
|
|
rvalstruct&
|
|
operator=(const rvalstruct&) = delete;
|
|
|
|
rvalstruct&
|
|
operator=(rvalstruct&& in)
|
|
{
|
|
bool test __attribute__((unused)) = true;
|
|
VERIFY( this != &in );
|
|
VERIFY( in.valid == true );
|
|
val = in.val;
|
|
in.valid = false;
|
|
valid = true;
|
|
return *this;
|
|
}
|
|
};
|
|
|
|
inline bool
|
|
operator==(const rvalstruct& lhs, const rvalstruct& rhs)
|
|
{ return lhs.val == rhs.val; }
|
|
|
|
inline bool
|
|
operator<(const rvalstruct& lhs, const rvalstruct& rhs)
|
|
{ return lhs.val < rhs.val; }
|
|
|
|
void
|
|
swap(rvalstruct& lhs, rvalstruct& rhs)
|
|
{
|
|
bool test __attribute__((unused)) = true;
|
|
VERIFY( lhs.valid && rhs.valid );
|
|
int temp = lhs.val;
|
|
lhs.val = rhs.val;
|
|
rhs.val = temp;
|
|
}
|
|
|
|
// This is a moveable class which copies how many times it is copied.
|
|
// This is mainly of use in the containers, where the an element inserted
|
|
// into a container has to be copied once to get there, but we want to check
|
|
// nothing else is copied.
|
|
struct copycounter
|
|
{
|
|
static int copycount;
|
|
int val;
|
|
bool valid;
|
|
|
|
copycounter() : val(0), valid(true)
|
|
{ }
|
|
|
|
copycounter(int inval) : val(inval), valid(true)
|
|
{ }
|
|
|
|
copycounter(const copycounter& in) : val(in.val), valid(true)
|
|
{
|
|
bool test __attribute__((unused)) = true;
|
|
VERIFY( in.valid == true );
|
|
++copycount;
|
|
}
|
|
|
|
copycounter(copycounter&& in) noexcept
|
|
{
|
|
bool test __attribute__((unused)) = true;
|
|
VERIFY( in.valid == true );
|
|
val = in.val;
|
|
in.valid = false;
|
|
valid = true;
|
|
}
|
|
|
|
copycounter&
|
|
operator=(int newval)
|
|
{
|
|
val = newval;
|
|
valid = true;
|
|
return *this;
|
|
}
|
|
|
|
bool
|
|
operator=(const copycounter& in)
|
|
{
|
|
bool test __attribute__((unused)) = true;
|
|
VERIFY( in.valid == true );
|
|
++copycount;
|
|
val = in.val;
|
|
valid = true;
|
|
return true;
|
|
}
|
|
|
|
copycounter&
|
|
operator=(copycounter&& in)
|
|
{
|
|
bool test __attribute__((unused)) = true;
|
|
VERIFY(in.valid == true);
|
|
val = in.val;
|
|
in.valid = false;
|
|
valid = true;
|
|
return *this;
|
|
}
|
|
|
|
~copycounter() noexcept
|
|
{ valid = false; }
|
|
};
|
|
|
|
int copycounter::copycount = 0;
|
|
|
|
inline bool
|
|
operator==(const copycounter& lhs, const copycounter& rhs)
|
|
{ return lhs.val == rhs.val; }
|
|
|
|
inline bool
|
|
operator<(const copycounter& lhs, const copycounter& rhs)
|
|
{ return lhs.val < rhs.val; }
|
|
|
|
inline void
|
|
swap(copycounter& lhs, copycounter& rhs)
|
|
{
|
|
bool test __attribute__((unused)) = true;
|
|
VERIFY( lhs.valid && rhs.valid );
|
|
int temp = lhs.val;
|
|
lhs.val = rhs.val;
|
|
rhs.val = temp;
|
|
}
|
|
|
|
// In the occasion of libstdc++/48038.
|
|
struct rvalstruct_compare_by_value
|
|
{
|
|
int val;
|
|
bool ok;
|
|
|
|
rvalstruct_compare_by_value(int v)
|
|
: val(v), ok(true) { }
|
|
|
|
rvalstruct_compare_by_value(const rvalstruct_compare_by_value& rh)
|
|
: val(rh.val), ok(rh.ok)
|
|
{
|
|
bool test __attribute__((unused)) = true;
|
|
VERIFY(rh.ok);
|
|
}
|
|
|
|
rvalstruct_compare_by_value&
|
|
operator=(const rvalstruct_compare_by_value& rh)
|
|
{
|
|
bool test __attribute__((unused)) = true;
|
|
VERIFY( rh.ok );
|
|
val = rh.val;
|
|
ok = rh.ok;
|
|
return *this;
|
|
}
|
|
|
|
rvalstruct_compare_by_value(rvalstruct_compare_by_value&& rh)
|
|
: val(rh.val), ok(rh.ok)
|
|
{
|
|
bool test __attribute__((unused)) = true;
|
|
VERIFY( rh.ok );
|
|
rh.ok = false;
|
|
}
|
|
|
|
rvalstruct_compare_by_value&
|
|
operator=(rvalstruct_compare_by_value&& rh)
|
|
{
|
|
bool test __attribute__((unused)) = true;
|
|
VERIFY( rh.ok );
|
|
val = rh.val;
|
|
ok = rh.ok;
|
|
rh.ok = false;
|
|
return *this;
|
|
}
|
|
};
|
|
|
|
inline bool
|
|
operator<(rvalstruct_compare_by_value lh,
|
|
rvalstruct_compare_by_value rh)
|
|
{
|
|
bool test __attribute__((unused)) = true;
|
|
VERIFY( rh.ok );
|
|
VERIFY( lh.ok );
|
|
return lh.val < rh.val;
|
|
}
|
|
|
|
inline bool
|
|
order(rvalstruct_compare_by_value lh,
|
|
rvalstruct_compare_by_value rh)
|
|
{
|
|
bool test __attribute__((unused)) = true;
|
|
VERIFY( rh.ok );
|
|
VERIFY( lh.ok );
|
|
return lh.val < rh.val;
|
|
}
|
|
|
|
struct throwing_move_constructor
|
|
{
|
|
throwing_move_constructor() = default;
|
|
|
|
throwing_move_constructor(throwing_move_constructor&&)
|
|
{ throw 1; }
|
|
|
|
throwing_move_constructor(const throwing_move_constructor&) = default;
|
|
|
|
throwing_move_constructor&
|
|
operator=(const throwing_move_constructor&) = default;
|
|
};
|
|
|
|
} // namespace __gnu_test
|
|
|
|
namespace std
|
|
{
|
|
/// std::hash specialization for __gnu_test::rvalstruct.
|
|
template<>
|
|
struct hash<__gnu_test::rvalstruct>
|
|
{
|
|
typedef size_t result_type;
|
|
typedef __gnu_test::rvalstruct argument_type;
|
|
|
|
size_t
|
|
operator()(const __gnu_test::rvalstruct& __rvs) const
|
|
{ return __rvs.val; }
|
|
};
|
|
}
|
|
|
|
#endif // _GLIBCXX_TESTSUITE_TR1_H
|