Revert Add <optional>. Will recommit with better commit message
llvm-svn: 283978
This commit is contained in:
@@ -1,268 +0,0 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++98, c++03, c++11, c++14
|
||||
// <optional>
|
||||
|
||||
// From LWG2451:
|
||||
// template <class U>
|
||||
// optional<T>& operator=(optional<U>&& rhs);
|
||||
|
||||
#include <optional>
|
||||
#include <type_traits>
|
||||
#include <memory>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
#include "archetypes.hpp"
|
||||
|
||||
using std::optional;
|
||||
|
||||
struct X
|
||||
{
|
||||
static bool throw_now;
|
||||
|
||||
X() = default;
|
||||
X(int &&)
|
||||
{
|
||||
if (throw_now)
|
||||
TEST_THROW(6);
|
||||
}
|
||||
};
|
||||
|
||||
bool X::throw_now = false;
|
||||
|
||||
struct Y1
|
||||
{
|
||||
Y1() = default;
|
||||
Y1(const int&) {}
|
||||
Y1& operator=(const Y1&) = delete;
|
||||
};
|
||||
|
||||
struct Y2
|
||||
{
|
||||
Y2() = default;
|
||||
Y2(const int&) = delete;
|
||||
Y2& operator=(const int&) { return *this; }
|
||||
};
|
||||
|
||||
class B {};
|
||||
class D : public B {};
|
||||
|
||||
|
||||
template <class T>
|
||||
struct AssignableFrom {
|
||||
static int type_constructed;
|
||||
static int type_assigned;
|
||||
static int int_constructed;
|
||||
static int int_assigned;
|
||||
|
||||
static void reset() {
|
||||
type_constructed = int_constructed = 0;
|
||||
type_assigned = int_assigned = 0;
|
||||
}
|
||||
|
||||
AssignableFrom() = default;
|
||||
|
||||
explicit AssignableFrom(T) { ++type_constructed; }
|
||||
AssignableFrom& operator=(T) { ++type_assigned; return *this; }
|
||||
|
||||
AssignableFrom(int) { ++int_constructed; }
|
||||
AssignableFrom& operator=(int) { ++int_assigned; return *this; }
|
||||
private:
|
||||
AssignableFrom(AssignableFrom const&) = delete;
|
||||
AssignableFrom& operator=(AssignableFrom const&) = delete;
|
||||
};
|
||||
|
||||
template <class T> int AssignableFrom<T>::type_constructed = 0;
|
||||
template <class T> int AssignableFrom<T>::type_assigned = 0;
|
||||
template <class T> int AssignableFrom<T>::int_constructed = 0;
|
||||
template <class T> int AssignableFrom<T>::int_assigned = 0;
|
||||
|
||||
void test_with_test_type() {
|
||||
using T = TestTypes::TestType;
|
||||
T::reset();
|
||||
{ // non-empty to empty
|
||||
T::reset_constructors();
|
||||
optional<T> opt;
|
||||
optional<int> other(42);
|
||||
opt = std::move(other);
|
||||
assert(T::alive == 1);
|
||||
assert(T::constructed == 1);
|
||||
assert(T::value_constructed == 1);
|
||||
assert(T::assigned == 0);
|
||||
assert(T::destroyed == 0);
|
||||
assert(static_cast<bool>(other) == true);
|
||||
assert(*other == 42);
|
||||
assert(static_cast<bool>(opt) == true);
|
||||
assert(*opt == T(42));
|
||||
}
|
||||
assert(T::alive == 0);
|
||||
{ // non-empty to non-empty
|
||||
optional<T> opt(101);
|
||||
optional<int> other(42);
|
||||
T::reset_constructors();
|
||||
opt = std::move(other);
|
||||
assert(T::alive == 1);
|
||||
assert(T::constructed == 0);
|
||||
assert(T::assigned == 1);
|
||||
assert(T::value_assigned == 1);
|
||||
assert(T::destroyed == 0);
|
||||
assert(static_cast<bool>(other) == true);
|
||||
assert(*other == 42);
|
||||
assert(static_cast<bool>(opt) == true);
|
||||
assert(*opt == T(42));
|
||||
}
|
||||
assert(T::alive == 0);
|
||||
{ // empty to non-empty
|
||||
optional<T> opt(101);
|
||||
optional<int> other;
|
||||
T::reset_constructors();
|
||||
opt = std::move(other);
|
||||
assert(T::alive == 0);
|
||||
assert(T::constructed == 0);
|
||||
assert(T::assigned == 0);
|
||||
assert(T::destroyed == 1);
|
||||
assert(static_cast<bool>(other) == false);
|
||||
assert(static_cast<bool>(opt) == false);
|
||||
}
|
||||
assert(T::alive == 0);
|
||||
{ // empty to empty
|
||||
optional<T> opt;
|
||||
optional<int> other;
|
||||
T::reset_constructors();
|
||||
opt = std::move(other);
|
||||
assert(T::alive == 0);
|
||||
assert(T::constructed == 0);
|
||||
assert(T::assigned == 0);
|
||||
assert(T::destroyed == 0);
|
||||
assert(static_cast<bool>(other) == false);
|
||||
assert(static_cast<bool>(opt) == false);
|
||||
}
|
||||
assert(T::alive == 0);
|
||||
}
|
||||
|
||||
|
||||
void test_ambigious_assign() {
|
||||
using OptInt = std::optional<int>;
|
||||
{
|
||||
using T = AssignableFrom<OptInt&&>;
|
||||
T::reset();
|
||||
{
|
||||
OptInt a(42);
|
||||
std::optional<T> t;
|
||||
t = std::move(a);
|
||||
assert(T::type_constructed == 1);
|
||||
assert(T::type_assigned == 0);
|
||||
assert(T::int_constructed == 0);
|
||||
assert(T::int_assigned == 0);
|
||||
}
|
||||
{
|
||||
using Opt = std::optional<T>;
|
||||
static_assert(!std::is_assignable<Opt&, const OptInt&&>::value, "");
|
||||
static_assert(!std::is_assignable<Opt&, const OptInt&>::value, "");
|
||||
static_assert(!std::is_assignable<Opt&, OptInt&>::value, "");
|
||||
}
|
||||
}
|
||||
{
|
||||
using T = AssignableFrom<OptInt const&&>;
|
||||
T::reset();
|
||||
{
|
||||
const OptInt a(42);
|
||||
std::optional<T> t;
|
||||
t = std::move(a);
|
||||
assert(T::type_constructed == 1);
|
||||
assert(T::type_assigned == 0);
|
||||
assert(T::int_constructed == 0);
|
||||
assert(T::int_assigned == 0);
|
||||
}
|
||||
T::reset();
|
||||
{
|
||||
OptInt a(42);
|
||||
std::optional<T> t;
|
||||
t = std::move(a);
|
||||
assert(T::type_constructed == 1);
|
||||
assert(T::type_assigned == 0);
|
||||
assert(T::int_constructed == 0);
|
||||
assert(T::int_assigned == 0);
|
||||
}
|
||||
{
|
||||
using Opt = std::optional<T>;
|
||||
static_assert(std::is_assignable<Opt&, OptInt&&>::value, "");
|
||||
static_assert(!std::is_assignable<Opt&, const OptInt&>::value, "");
|
||||
static_assert(!std::is_assignable<Opt&, OptInt&>::value, "");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
test_with_test_type();
|
||||
test_ambigious_assign();
|
||||
{
|
||||
optional<int> opt;
|
||||
optional<short> opt2;
|
||||
opt = std::move(opt2);
|
||||
assert(static_cast<bool>(opt2) == false);
|
||||
assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
|
||||
}
|
||||
{
|
||||
optional<int> opt;
|
||||
optional<short> opt2(short{2});
|
||||
opt = std::move(opt2);
|
||||
assert(static_cast<bool>(opt2) == true);
|
||||
assert(*opt2 == 2);
|
||||
assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
|
||||
assert(*opt == *opt2);
|
||||
}
|
||||
{
|
||||
optional<int> opt(3);
|
||||
optional<short> opt2;
|
||||
opt = std::move(opt2);
|
||||
assert(static_cast<bool>(opt2) == false);
|
||||
assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
|
||||
}
|
||||
{
|
||||
optional<int> opt(3);
|
||||
optional<short> opt2(short{2});
|
||||
opt = std::move(opt2);
|
||||
assert(static_cast<bool>(opt2) == true);
|
||||
assert(*opt2 == 2);
|
||||
assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
|
||||
assert(*opt == *opt2);
|
||||
}
|
||||
{
|
||||
optional<std::unique_ptr<B>> opt;
|
||||
optional<std::unique_ptr<D>> other(new D());
|
||||
opt = std::move(other);
|
||||
assert(static_cast<bool>(opt) == true);
|
||||
assert(static_cast<bool>(other) == true);
|
||||
assert(opt->get() != nullptr);
|
||||
assert(other->get() == nullptr);
|
||||
}
|
||||
#ifndef TEST_HAS_NO_EXCEPTIONS
|
||||
{
|
||||
optional<X> opt;
|
||||
optional<int> opt2(42);
|
||||
assert(static_cast<bool>(opt2) == true);
|
||||
try
|
||||
{
|
||||
X::throw_now = true;
|
||||
opt = std::move(opt2);
|
||||
assert(false);
|
||||
}
|
||||
catch (int i)
|
||||
{
|
||||
assert(i == 6);
|
||||
assert(static_cast<bool>(opt) == false);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
Reference in New Issue
Block a user