Implement N3672, optional<T>.

git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@189772 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Howard Hinnant
2013-09-02 20:30:37 +00:00
parent c64c980140
commit 01afa5c6e4
65 changed files with 4535 additions and 4 deletions

View File

@@ -0,0 +1,115 @@
//===----------------------------------------------------------------------===//
//
// 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.
//
//===----------------------------------------------------------------------===//
// <optional>
// constexpr optional(const T& v);
#include <optional>
#include <type_traits>
#include <cassert>
#if _LIBCPP_STD_VER > 11
class X
{
int i_;
public:
X(int i) : i_(i) {}
friend bool operator==(const X& x, const X& y) {return x.i_ == y.i_;}
};
class Y
{
int i_;
public:
constexpr Y(int i) : i_(i) {}
friend constexpr bool operator==(const Y& x, const Y& y) {return x.i_ == y.i_;}
};
class Z
{
int i_;
public:
Z(int i) : i_(i) {}
Z(const Z&) {throw 6;}
};
#endif // _LIBCPP_STD_VER > 11
int main()
{
#if _LIBCPP_STD_VER > 11
{
typedef int T;
constexpr T t(5);
constexpr std::optional<T> opt(t);
static_assert(static_cast<bool>(opt) == true, "");
static_assert(*opt == 5, "");
struct test_constexpr_ctor
: public std::optional<T>
{
constexpr test_constexpr_ctor(const T&) {}
};
}
{
typedef double T;
constexpr T t(3);
constexpr std::optional<T> opt(t);
static_assert(static_cast<bool>(opt) == true, "");
static_assert(*opt == 3, "");
struct test_constexpr_ctor
: public std::optional<T>
{
constexpr test_constexpr_ctor(const T&) {}
};
}
{
typedef X T;
const T t(3);
std::optional<T> opt(t);
assert(static_cast<bool>(opt) == true);
assert(*opt == 3);
}
{
typedef Y T;
constexpr T t(3);
constexpr std::optional<T> opt(t);
static_assert(static_cast<bool>(opt) == true, "");
static_assert(*opt == 3, "");
struct test_constexpr_ctor
: public std::optional<T>
{
constexpr test_constexpr_ctor(const T&) {}
};
}
{
typedef Z T;
try
{
const T t(3);
std::optional<T> opt(t);
assert(false);
}
catch (int i)
{
assert(i == 6);
}
}
#endif // _LIBCPP_STD_VER > 11
}

View File

@@ -0,0 +1,122 @@
//===----------------------------------------------------------------------===//
//
// 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.
//
//===----------------------------------------------------------------------===//
// <optional>
// optional(const optional<T>& rhs);
#include <optional>
#include <type_traits>
#include <cassert>
#if _LIBCPP_STD_VER > 11
template <class T>
void
test(const std::optional<T>& rhs, bool is_going_to_throw = false)
{
bool rhs_engaged = static_cast<bool>(rhs);
try
{
std::optional<T> lhs = rhs;
assert(is_going_to_throw == false);
assert(static_cast<bool>(lhs) == rhs_engaged);
if (rhs_engaged)
assert(*lhs == *rhs);
}
catch (int i)
{
assert(i == 6);
}
}
class X
{
int i_;
public:
X(int i) : i_(i) {}
X(const X& x) : i_(x.i_) {}
~X() {i_ = 0;}
friend bool operator==(const X& x, const X& y) {return x.i_ == y.i_;}
};
class Y
{
int i_;
public:
Y(int i) : i_(i) {}
Y(const Y& x) : i_(x.i_) {}
friend constexpr bool operator==(const Y& x, const Y& y) {return x.i_ == y.i_;}
};
int count = 0;
class Z
{
int i_;
public:
Z(int i) : i_(i) {}
Z(const Z&)
{
if (++count == 2)
throw 6;
}
friend constexpr bool operator==(const Z& x, const Z& y) {return x.i_ == y.i_;}
};
#endif // _LIBCPP_STD_VER > 11
int main()
{
#if _LIBCPP_STD_VER > 11
{
typedef int T;
std::optional<T> rhs;
test(rhs);
}
{
typedef int T;
std::optional<T> rhs(3);
test(rhs);
}
{
typedef X T;
std::optional<T> rhs;
test(rhs);
}
{
typedef X T;
std::optional<T> rhs(X(3));
test(rhs);
}
{
typedef Y T;
std::optional<T> rhs;
test(rhs);
}
{
typedef Y T;
std::optional<T> rhs(Y(3));
test(rhs);
}
{
typedef Z T;
std::optional<T> rhs;
test(rhs);
}
{
typedef Z T;
std::optional<T> rhs(Z(3));
test(rhs, true);
}
#endif // _LIBCPP_STD_VER > 11
}

View File

@@ -0,0 +1,65 @@
//===----------------------------------------------------------------------===//
//
// 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.
//
//===----------------------------------------------------------------------===//
// <optional>
// constexpr optional() noexcept;
#include <optional>
#include <type_traits>
#include <cassert>
#if _LIBCPP_STD_VER > 11
template <class Opt>
void
test_constexpr()
{
static_assert(std::is_nothrow_default_constructible<Opt>::value, "");
constexpr Opt opt;
static_assert(static_cast<bool>(opt) == false, "");
struct test_constexpr_ctor
: public Opt
{
constexpr test_constexpr_ctor() {}
};
}
template <class Opt>
void
test()
{
static_assert(std::is_nothrow_default_constructible<Opt>::value, "");
Opt opt;
assert(static_cast<bool>(opt) == false);
struct test_constexpr_ctor
: public Opt
{
constexpr test_constexpr_ctor() {}
};
}
struct X
{
X();
};
#endif // _LIBCPP_STD_VER > 11
int main()
{
#if _LIBCPP_STD_VER > 11
test_constexpr<std::optional<int>>();
test_constexpr<std::optional<int*>>();
test<std::optional<X>>();
#endif // _LIBCPP_STD_VER > 11
}

View File

@@ -0,0 +1,141 @@
//===----------------------------------------------------------------------===//
//
// 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.
//
//===----------------------------------------------------------------------===//
// <optional>
// template <class... Args>
// constexpr explicit optional(in_place_t, Args&&... args);
#include <optional>
#include <type_traits>
#include <cassert>
#if _LIBCPP_STD_VER > 11
class X
{
int i_;
int j_ = 0;
public:
X() : i_(0) {}
X(int i) : i_(i) {}
X(int i, int j) : i_(i), j_(j) {}
~X() {}
friend bool operator==(const X& x, const X& y)
{return x.i_ == y.i_ && x.j_ == y.j_;}
};
class Y
{
int i_;
int j_ = 0;
public:
constexpr Y() : i_(0) {}
constexpr Y(int i) : i_(i) {}
constexpr Y(int i, int j) : i_(i), j_(j) {}
friend constexpr bool operator==(const Y& x, const Y& y)
{return x.i_ == y.i_ && x.j_ == y.j_;}
};
class Z
{
int i_;
public:
Z(int i) : i_(i) {throw 6;}
};
#endif // _LIBCPP_STD_VER > 11
int main()
{
#if _LIBCPP_STD_VER > 11
{
constexpr std::optional<int> opt(std::in_place, 5);
static_assert(static_cast<bool>(opt) == true, "");
static_assert(*opt == 5, "");
struct test_constexpr_ctor
: public std::optional<int>
{
constexpr test_constexpr_ctor(std::in_place_t, int i)
: std::optional<int>(std::in_place, i) {}
};
}
{
const std::optional<X> opt(std::in_place);
assert(static_cast<bool>(opt) == true);
assert(*opt == X());
}
{
const std::optional<X> opt(std::in_place, 5);
assert(static_cast<bool>(opt) == true);
assert(*opt == X(5));
}
{
const std::optional<X> opt(std::in_place, 5, 4);
assert(static_cast<bool>(opt) == true);
assert(*opt == X(5, 4));
}
{
constexpr std::optional<Y> opt(std::in_place);
static_assert(static_cast<bool>(opt) == true, "");
static_assert(*opt == Y(), "");
struct test_constexpr_ctor
: public std::optional<Y>
{
constexpr test_constexpr_ctor(std::in_place_t)
: std::optional<Y>(std::in_place) {}
};
}
{
constexpr std::optional<Y> opt(std::in_place, 5);
static_assert(static_cast<bool>(opt) == true, "");
static_assert(*opt == Y(5), "");
struct test_constexpr_ctor
: public std::optional<Y>
{
constexpr test_constexpr_ctor(std::in_place_t, int i)
: std::optional<Y>(std::in_place, i) {}
};
}
{
constexpr std::optional<Y> opt(std::in_place, 5, 4);
static_assert(static_cast<bool>(opt) == true, "");
static_assert(*opt == Y(5, 4), "");
struct test_constexpr_ctor
: public std::optional<Y>
{
constexpr test_constexpr_ctor(std::in_place_t, int i, int j)
: std::optional<Y>(std::in_place, i, j) {}
};
}
{
try
{
const std::optional<Z> opt(std::in_place, 1);
assert(false);
}
catch (int i)
{
assert(i == 6);
}
}
#endif // _LIBCPP_STD_VER > 11
}

View File

@@ -0,0 +1,122 @@
//===----------------------------------------------------------------------===//
//
// 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.
//
//===----------------------------------------------------------------------===//
// <optional>
// template <class U, class... Args>
// constexpr
// explicit optional(in_place_t, initializer_list<U> il, Args&&... args);
#include <optional>
#include <type_traits>
#include <vector>
#include <cassert>
#if _LIBCPP_STD_VER > 11
class X
{
int i_;
int j_ = 0;
public:
X() : i_(0) {}
X(int i) : i_(i) {}
X(int i, int j) : i_(i), j_(j) {}
~X() {}
friend bool operator==(const X& x, const X& y)
{return x.i_ == y.i_ && x.j_ == y.j_;}
};
class Y
{
int i_;
int j_ = 0;
public:
constexpr Y() : i_(0) {}
constexpr Y(int i) : i_(i) {}
constexpr Y(std::initializer_list<int> il) : i_(il.begin()[0]), j_(il.begin()[1]) {}
friend constexpr bool operator==(const Y& x, const Y& y)
{return x.i_ == y.i_ && x.j_ == y.j_;}
};
class Z
{
int i_;
int j_ = 0;
public:
constexpr Z() : i_(0) {}
constexpr Z(int i) : i_(i) {}
constexpr Z(std::initializer_list<int> il) : i_(il.begin()[0]), j_(il.begin()[1])
{throw 6;}
friend constexpr bool operator==(const Z& x, const Z& y)
{return x.i_ == y.i_ && x.j_ == y.j_;}
};
#endif // _LIBCPP_STD_VER > 11
int main()
{
#if _LIBCPP_STD_VER > 11
{
static_assert(!std::is_constructible<X, std::initializer_list<int>&>::value, "");
static_assert(!std::is_constructible<std::optional<X>, std::initializer_list<int>&>::value, "");
}
{
std::optional<std::vector<int>> opt(std::in_place, {3, 1});
assert(static_cast<bool>(opt) == true);
assert((*opt == std::vector<int>{3, 1}));
assert(opt->size() == 2);
}
{
std::optional<std::vector<int>> opt(std::in_place, {3, 1}, std::allocator<int>());
assert(static_cast<bool>(opt) == true);
assert((*opt == std::vector<int>{3, 1}));
assert(opt->size() == 2);
}
{
static_assert(std::is_constructible<std::optional<Y>, std::initializer_list<int>&>::value, "");
constexpr std::optional<Y> opt(std::in_place, {3, 1});
static_assert(static_cast<bool>(opt) == true, "");
static_assert(*opt == Y{3, 1}, "");
struct test_constexpr_ctor
: public std::optional<Y>
{
constexpr test_constexpr_ctor(std::in_place_t, std::initializer_list<int> i)
: std::optional<Y>(std::in_place, i) {}
};
}
{
static_assert(std::is_constructible<std::optional<Z>, std::initializer_list<int>&>::value, "");
try
{
std::optional<Z> opt(std::in_place, {3, 1});
assert(false);
}
catch (int i)
{
assert(i == 6);
}
struct test_constexpr_ctor
: public std::optional<Z>
{
constexpr test_constexpr_ctor(std::in_place_t, std::initializer_list<int> i)
: std::optional<Z>(std::in_place, i) {}
};
}
#endif // _LIBCPP_STD_VER > 11
}

View File

@@ -0,0 +1,122 @@
//===----------------------------------------------------------------------===//
//
// 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.
//
//===----------------------------------------------------------------------===//
// <optional>
// optional(optional<T>&& rhs) noexcept(is_nothrow_move_constructible<T>::value);
#include <optional>
#include <type_traits>
#include <cassert>
#if _LIBCPP_STD_VER > 11
template <class T>
void
test(std::optional<T>& rhs, bool is_going_to_throw = false)
{
static_assert(std::is_nothrow_move_constructible<std::optional<T>>::value ==
std::is_nothrow_move_constructible<T>::value, "");
bool rhs_engaged = static_cast<bool>(rhs);
try
{
std::optional<T> lhs = std::move(rhs);
assert(is_going_to_throw == false);
assert(static_cast<bool>(lhs) == rhs_engaged);
}
catch (int i)
{
assert(i == 6);
}
}
class X
{
int i_;
public:
X(int i) : i_(i) {}
X(X&& x) : i_(x.i_) {x.i_ = 0;}
~X() {i_ = 0;}
friend bool operator==(const X& x, const X& y) {return x.i_ == y.i_;}
};
class Y
{
int i_;
public:
Y(int i) : i_(i) {}
Y(Y&& x) noexcept : i_(x.i_) {x.i_ = 0;}
friend constexpr bool operator==(const Y& x, const Y& y) {return x.i_ == y.i_;}
};
int count = 0;
class Z
{
int i_;
public:
Z(int i) : i_(i) {}
Z(Z&&)
{
if (++count == 2)
throw 6;
}
friend constexpr bool operator==(const Z& x, const Z& y) {return x.i_ == y.i_;}
};
#endif // _LIBCPP_STD_VER > 11
int main()
{
#if _LIBCPP_STD_VER > 11
{
typedef int T;
std::optional<T> rhs;
test(rhs);
}
{
typedef int T;
std::optional<T> rhs(3);
test(rhs);
}
{
typedef X T;
std::optional<T> rhs;
test(rhs);
}
{
typedef X T;
std::optional<T> rhs(X(3));
test(rhs);
}
{
typedef Y T;
std::optional<T> rhs;
test(rhs);
}
{
typedef Y T;
std::optional<T> rhs(Y(3));
test(rhs);
}
{
typedef Z T;
std::optional<T> rhs;
test(rhs);
}
{
typedef Z T;
std::optional<T> rhs(Z(3));
test(rhs, true);
}
#endif // _LIBCPP_STD_VER > 11
}

View File

@@ -0,0 +1,64 @@
//===----------------------------------------------------------------------===//
//
// 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.
//
//===----------------------------------------------------------------------===//
// <optional>
// constexpr optional(nullopt_t) noexcept;
#include <optional>
#include <type_traits>
#include <cassert>
#if _LIBCPP_STD_VER > 11
template <class Opt>
void
test_constexpr()
{
static_assert(noexcept(Opt(std::nullopt)), "");
constexpr Opt opt(std::nullopt);
static_assert(static_cast<bool>(opt) == false, "");
struct test_constexpr_ctor
: public Opt
{
constexpr test_constexpr_ctor() {}
};
}
template <class Opt>
void
test()
{
static_assert(noexcept(Opt(std::nullopt)), "");
Opt opt(std::nullopt);
assert(static_cast<bool>(opt) == false);
struct test_constexpr_ctor
: public Opt
{
constexpr test_constexpr_ctor() {}
};
}
struct X
{
X();
};
#endif // _LIBCPP_STD_VER > 11
int main()
{
#if _LIBCPP_STD_VER > 11
test_constexpr<std::optional<int>>();
test_constexpr<std::optional<int*>>();
test<std::optional<X>>();
#endif // _LIBCPP_STD_VER > 11
}

View File

@@ -0,0 +1,108 @@
//===----------------------------------------------------------------------===//
//
// 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.
//
//===----------------------------------------------------------------------===//
// <optional>
// constexpr optional(T&& v);
#include <optional>
#include <type_traits>
#include <cassert>
#if _LIBCPP_STD_VER > 11
class X
{
int i_;
public:
X(int i) : i_(i) {}
X(X&& x) : i_(x.i_) {}
friend bool operator==(const X& x, const X& y) {return x.i_ == y.i_;}
};
class Y
{
int i_;
public:
constexpr Y(int i) : i_(i) {}
constexpr Y(Y&& x) : i_(x.i_) {}
friend constexpr bool operator==(const Y& x, const Y& y) {return x.i_ == y.i_;}
};
class Z
{
int i_;
public:
Z(int i) : i_(i) {}
Z(Z&&) {throw 6;}
};
#endif // _LIBCPP_STD_VER > 11
int main()
{
#if _LIBCPP_STD_VER > 11
{
typedef int T;
constexpr std::optional<T> opt(T(5));
static_assert(static_cast<bool>(opt) == true, "");
static_assert(*opt == 5, "");
struct test_constexpr_ctor
: public std::optional<T>
{
constexpr test_constexpr_ctor(T&&) {}
};
}
{
typedef double T;
constexpr std::optional<T> opt(T(3));
static_assert(static_cast<bool>(opt) == true, "");
static_assert(*opt == 3, "");
struct test_constexpr_ctor
: public std::optional<T>
{
constexpr test_constexpr_ctor(T&&) {}
};
}
{
typedef X T;
std::optional<T> opt(T(3));
assert(static_cast<bool>(opt) == true);
assert(*opt == 3);
}
{
typedef Y T;
constexpr std::optional<T> opt(T(3));
static_assert(static_cast<bool>(opt) == true, "");
static_assert(*opt == 3, "");
struct test_constexpr_ctor
: public std::optional<T>
{
constexpr test_constexpr_ctor(T&&) {}
};
}
{
typedef Z T;
try
{
std::optional<T> opt(T(3));
assert(false);
}
catch (int i)
{
assert(i == 6);
}
}
#endif // _LIBCPP_STD_VER > 11
}