diff options
Diffstat (limited to 'libcxx/test/std/utilities/optional/optional.object/optional.object.ctor')
13 files changed, 1600 insertions, 0 deletions
diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/U.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/U.pass.cpp new file mode 100644 index 00000000000..18efd10a30b --- /dev/null +++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/U.pass.cpp @@ -0,0 +1,137 @@ +//===----------------------------------------------------------------------===// +// +// 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> + +// template <class U> +// constexpr EXPLICIT optional(U&& u); + +#include <optional> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "archetypes.hpp" +#include "test_convertible.hpp" + + +using std::optional; + +struct ImplicitThrow +{ + constexpr ImplicitThrow(int x) { if (x != -1) TEST_THROW(6);} +}; + +struct ExplicitThrow +{ + constexpr explicit ExplicitThrow(int x) { if (x != -1) TEST_THROW(6);} +}; + + +template <class To, class From> +constexpr bool implicit_conversion(optional<To>&& opt, const From& v) +{ + using O = optional<To>; + static_assert(test_convertible<O, From>(), ""); + static_assert(!test_convertible<O, void*>(), ""); + static_assert(!test_convertible<O, From, int>(), ""); + return opt && *opt == static_cast<To>(v); +} + +template <class To, class Input, class Expect> +constexpr bool explicit_conversion(Input&& in, const Expect& v) +{ + using O = optional<To>; + static_assert(std::is_constructible<O, Input>::value, ""); + static_assert(!std::is_convertible<Input, O>::value, ""); + static_assert(!std::is_constructible<O, void*>::value, ""); + static_assert(!std::is_constructible<O, Input, int>::value, ""); + optional<To> opt(std::forward<Input>(in)); + return opt && *opt == static_cast<To>(v); +} + +void test_implicit() +{ + { + using T = long long; + static_assert(implicit_conversion<long long>(42, 42), ""); + } + { + using T = long double; + static_assert(implicit_conversion<long double>(3.14, 3.14), ""); + } + { + using T = TrivialTestTypes::TestType; + static_assert(implicit_conversion<T>(42, 42), ""); + } + { + using T = TestTypes::TestType; + assert(implicit_conversion<T>(3, T(3))); + } +#ifndef TEST_HAS_NO_EXCEPTIONS + { + try { + using T = ImplicitThrow; + optional<T> t = 42; + assert(false); + } catch (int) { + } + } +#endif +} + +void test_explicit() { + { + using T = ExplicitTrivialTestTypes::TestType; + using O = optional<T>; + static_assert(explicit_conversion<T>(42, 42), ""); + } + { + using T = ExplicitConstexprTestTypes::TestType; + using O = optional<T>; + static_assert(explicit_conversion<T>(42, 42), ""); + static_assert(!std::is_convertible<int, T>::value, ""); + } + { + using T = ExplicitTestTypes::TestType; + using O = optional<T>; + T::reset(); + { + assert(explicit_conversion<T>(42, 42)); + assert(T::alive == 0); + } + T::reset(); + { + optional<T> t(42); + assert(T::alive == 1); + assert(T::value_constructed == 1); + assert(T::move_constructed == 0); + assert(T::copy_constructed == 0); + assert(t.value().value == 42); + } + assert(T::alive == 0); + } +#ifndef TEST_HAS_NO_EXCEPTIONS + { + try { + using T = ExplicitThrow; + optional<T> t(42); + assert(false); + } catch (int) { + } + } +#endif +} + +int main() { + test_implicit(); + test_explicit(); +} diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/const_T.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/const_T.pass.cpp new file mode 100644 index 00000000000..3f98d907890 --- /dev/null +++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/const_T.pass.cpp @@ -0,0 +1,123 @@ +//===----------------------------------------------------------------------===// +// +// 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> + +// constexpr optional(const T& v); + +#include <optional> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "archetypes.hpp" + +using std::optional; + +int main() +{ + { + typedef int T; + constexpr T t(5); + constexpr optional<T> opt(t); + static_assert(static_cast<bool>(opt) == true, ""); + static_assert(*opt == 5, ""); + + struct test_constexpr_ctor + : public optional<T> + { + constexpr test_constexpr_ctor(const T&) {} + }; + + } + { + typedef double T; + constexpr T t(3); + constexpr optional<T> opt(t); + static_assert(static_cast<bool>(opt) == true, ""); + static_assert(*opt == 3, ""); + + struct test_constexpr_ctor + : public optional<T> + { + constexpr test_constexpr_ctor(const T&) {} + }; + + } + { + typedef TestTypes::TestType T; + T::reset(); + const T t(3); + optional<T> opt = t; + assert(T::alive == 2); + assert(T::copy_constructed == 1); + assert(static_cast<bool>(opt) == true); + assert(opt.value().value == 3); + } + { + typedef ExplicitTestTypes::TestType T; + static_assert(!std::is_convertible<T const&, optional<T>>::value, ""); + T::reset(); + const T t(3); + optional<T> opt(t); + assert(T::alive == 2); + assert(T::copy_constructed == 1); + assert(static_cast<bool>(opt) == true); + assert(opt.value().value == 3); + } + { + typedef ConstexprTestTypes::TestType T; + constexpr T t(3); + constexpr optional<T> opt = {t}; + static_assert(static_cast<bool>(opt) == true, ""); + static_assert(opt.value().value == 3, ""); + + struct test_constexpr_ctor + : public optional<T> + { + constexpr test_constexpr_ctor(const T&) {} + }; + } + { + typedef ExplicitConstexprTestTypes::TestType T; + static_assert(!std::is_convertible<const T&, optional<T>>::value, ""); + constexpr T t(3); + constexpr optional<T> opt(t); + static_assert(static_cast<bool>(opt) == true, ""); + static_assert(opt.value().value == 3, ""); + + struct test_constexpr_ctor + : public optional<T> + { + constexpr test_constexpr_ctor(const T&) {} + }; + + } +#ifndef TEST_HAS_NO_EXCEPTIONS + { + struct Z { + Z(int) {} + Z(const Z&) {throw 6;} + }; + typedef Z T; + try + { + const T t(3); + optional<T> opt(t); + assert(false); + } + catch (int i) + { + assert(i == 6); + } + } +#endif +} diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/const_optional_U.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/const_optional_U.pass.cpp new file mode 100644 index 00000000000..e12f6cb28f5 --- /dev/null +++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/const_optional_U.pass.cpp @@ -0,0 +1,134 @@ +//===----------------------------------------------------------------------===// +// +// 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> + +// template <class U> +// optional(const optional<U>& rhs); + +#include <optional> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" + +using std::optional; + +template <class T, class U> +void +test(const optional<U>& rhs, bool is_going_to_throw = false) +{ + bool rhs_engaged = static_cast<bool>(rhs); +#ifndef TEST_HAS_NO_EXCEPTIONS + try + { + 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); + } +#else + if (is_going_to_throw) return; + optional<T> lhs = rhs; + assert(static_cast<bool>(lhs) == rhs_engaged); + if (rhs_engaged) + assert(*lhs == *rhs); +#endif +} + +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) {} + + 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) {TEST_THROW(6);} + + friend constexpr bool operator==(const Z& x, const Z& y) {return x.i_ == y.i_;} +}; + + +int main() +{ + { + typedef short U; + typedef int T; + optional<U> rhs; + test<T>(rhs); + } + { + typedef short U; + typedef int T; + optional<U> rhs(U{3}); + test<T>(rhs); + } + { + typedef X T; + typedef int U; + optional<U> rhs; + test<T>(rhs); + } + { + typedef X T; + typedef int U; + optional<U> rhs(U{3}); + test<T>(rhs); + } + { + typedef Y T; + typedef int U; + optional<U> rhs; + test<T>(rhs); + } + { + typedef Y T; + typedef int U; + optional<U> rhs(U{3}); + test<T>(rhs); + } + { + typedef Z T; + typedef int U; + optional<U> rhs; + test<T>(rhs); + } + { + typedef Z T; + typedef int U; + optional<U> rhs(U{3}); + test<T>(rhs, true); + } + + static_assert(!(std::is_constructible<optional<X>, const optional<Y>&>::value), ""); +} diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/copy.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/copy.pass.cpp new file mode 100644 index 00000000000..d2b704c95f2 --- /dev/null +++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/copy.pass.cpp @@ -0,0 +1,150 @@ +//===----------------------------------------------------------------------===// +// +// 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> + +// optional(const optional<T>& rhs); + +#include <optional> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "archetypes.hpp" + +using std::optional; + +template <class T, class ...InitArgs> +void test(InitArgs&&... args) +{ + const optional<T> rhs(std::forward<InitArgs>(args)...); + bool rhs_engaged = static_cast<bool>(rhs); + optional<T> lhs = rhs; + assert(static_cast<bool>(lhs) == rhs_engaged); + if (rhs_engaged) + assert(*lhs == *rhs); +} + +void test_throwing_ctor() { +#ifndef TEST_HAS_NO_EXCEPTIONS + struct Z { + Z() : count(0) {} + Z(Z const& o) : count(o.count + 1) + { if (count == 2) throw 6; } + int count; + }; + const Z z; + const optional<Z> rhs(z); + try + { + optional<Z> lhs(rhs); + assert(false); + } + catch (int i) + { + assert(i == 6); + } +#endif +} + +template <class T, class ...InitArgs> +void test_ref(InitArgs&&... args) +{ + const optional<T> rhs(std::forward<InitArgs>(args)...); + bool rhs_engaged = static_cast<bool>(rhs); + optional<T> lhs = rhs; + assert(static_cast<bool>(lhs) == rhs_engaged); + if (rhs_engaged) + assert(&(*lhs) == &(*rhs)); +} + + +void test_reference_extension() +{ +#if defined(_LIBCPP_VERSION) && 0 // FIXME these extensions are currently disabled. + using T = TestTypes::TestType; + T::reset(); + { + T t; + T::reset_constructors(); + test_ref<T&>(); + test_ref<T&>(t); + assert(T::alive == 1); + assert(T::constructed == 0); + assert(T::assigned == 0); + assert(T::destroyed == 0); + } + assert(T::destroyed == 1); + assert(T::alive == 0); + { + T t; + const T& ct = t; + T::reset_constructors(); + test_ref<T const&>(); + test_ref<T const&>(t); + test_ref<T const&>(ct); + assert(T::alive == 1); + assert(T::constructed == 0); + assert(T::assigned == 0); + assert(T::destroyed == 0); + } + assert(T::alive == 0); + assert(T::destroyed == 1); + { + static_assert(!std::is_copy_constructible<std::optional<T&&>>::value, ""); + static_assert(!std::is_copy_constructible<std::optional<T const&&>>::value, ""); + } +#endif +} + +int main() +{ + test<int>(); + test<int>(3); + { + using T = TestTypes::TestType; + T::reset(); + const optional<T> rhs; + assert(T::alive == 0); + const optional<T> lhs(rhs); + assert(lhs.has_value() == false); + assert(T::alive == 0); + } + TestTypes::TestType::reset(); + { + using T = TestTypes::TestType; + T::reset(); + const optional<T> rhs(42); + assert(T::alive == 1); + assert(T::value_constructed == 1); + assert(T::copy_constructed == 0); + const optional<T> lhs(rhs); + assert(lhs.has_value()); + assert(T::copy_constructed == 1); + assert(T::alive == 2); + } + TestTypes::TestType::reset(); + { + using namespace ConstexprTestTypes; + test<TestType>(); + test<TestType>(42); + } + { + using namespace TrivialTestTypes; + test<TestType>(); + test<TestType>(42); + } + { + test_throwing_ctor(); + } + { + test_reference_extension(); + } +} diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/default.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/default.pass.cpp new file mode 100644 index 00000000000..62795b91f9f --- /dev/null +++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/default.pass.cpp @@ -0,0 +1,81 @@ +//===----------------------------------------------------------------------===// +// +// 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> + +// constexpr optional() noexcept; + +#include <optional> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "archetypes.hpp" + +using std::optional; + +template <class Opt> +void +test_constexpr() +{ + static_assert(std::is_nothrow_default_constructible<Opt>::value, ""); + static_assert(std::is_trivially_destructible<Opt>::value, ""); + static_assert(std::is_trivially_destructible<typename Opt::value_type>::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, ""); + static_assert(!std::is_trivially_destructible<Opt>::value, ""); + static_assert(!std::is_trivially_destructible<typename Opt::value_type>::value, ""); + { + Opt opt; + assert(static_cast<bool>(opt) == false); + } + { + const Opt opt; + assert(static_cast<bool>(opt) == false); + } + + struct test_constexpr_ctor + : public Opt + { + constexpr test_constexpr_ctor() {} + }; +} + +int main() +{ + test_constexpr<optional<int>>(); + test_constexpr<optional<int*>>(); + test_constexpr<optional<ImplicitTypes::NoCtors>>(); + test_constexpr<optional<NonTrivialTypes::NoCtors>>(); + test_constexpr<optional<NonConstexprTypes::NoCtors>>(); + test<optional<NonLiteralTypes::NoCtors>>(); + // EXTENSIONS +#if defined(_LIBCPP_VERSION) && 0 // FIXME these extensions are currently disabled. + test_constexpr<optional<int&>>(); + test_constexpr<optional<const int&>>(); + test_constexpr<optional<int&>>(); + test_constexpr<optional<NonLiteralTypes::NoCtors&>>(); + test_constexpr<optional<NonLiteralTypes::NoCtors&&>>(); +#endif +} diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/explicit_const_optional_U.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/explicit_const_optional_U.pass.cpp new file mode 100644 index 00000000000..64ac05316c2 --- /dev/null +++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/explicit_const_optional_U.pass.cpp @@ -0,0 +1,121 @@ +//===----------------------------------------------------------------------===// +// +// 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> + +// template <class U> +// explicit optional(const optional<U>& rhs); + +#include <optional> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" + +using std::optional; + +template <class T, class U> +void +test(const optional<U>& rhs, bool is_going_to_throw = false) +{ + static_assert(!(std::is_convertible<const optional<U>&, optional<T>>::value), ""); + bool rhs_engaged = static_cast<bool>(rhs); +#ifndef TEST_HAS_NO_EXCEPTIONS + try + { + optional<T> lhs(rhs); + assert(is_going_to_throw == false); + assert(static_cast<bool>(lhs) == rhs_engaged); + if (rhs_engaged) + assert(*lhs == T(*rhs)); + } + catch (int i) + { + assert(i == 6); + } +#else + if (is_going_to_throw) return; + optional<T> lhs(rhs); + assert(static_cast<bool>(lhs) == rhs_engaged); + if (rhs_engaged) + assert(*lhs == T(*rhs)); +#endif +} + +class X +{ + int i_; +public: + explicit 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: + explicit Y(int i) : i_(i) {} + + friend constexpr bool operator==(const Y& x, const Y& y) {return x.i_ == y.i_;} +}; + +int count = 0; + +class Z +{ + int i_; +public: + explicit Z(int i) : i_(i) { TEST_THROW(6);} + + friend constexpr bool operator==(const Z& x, const Z& y) {return x.i_ == y.i_;} +}; + + +int main() +{ + { + typedef X T; + typedef int U; + optional<U> rhs; + test<T>(rhs); + } + { + typedef X T; + typedef int U; + optional<U> rhs(3); + test<T>(rhs); + } + { + typedef Y T; + typedef int U; + optional<U> rhs; + test<T>(rhs); + } + { + typedef Y T; + typedef int U; + optional<U> rhs(3); + test<T>(rhs); + } + { + typedef Z T; + typedef int U; + optional<U> rhs; + test<T>(rhs); + } + { + typedef Z T; + typedef int U; + optional<U> rhs(3); + test<T>(rhs, true); + } +} diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/explicit_optional_U.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/explicit_optional_U.pass.cpp new file mode 100644 index 00000000000..2c6757a9582 --- /dev/null +++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/explicit_optional_U.pass.cpp @@ -0,0 +1,84 @@ +//===----------------------------------------------------------------------===// +// +// 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> + +// template <class U> +// explicit optional(optional<U>&& rhs); + +#include <optional> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" + +using std::optional; + +template <class T, class U> +void +test(optional<U>&& rhs, bool is_going_to_throw = false) +{ + static_assert(!(std::is_convertible<optional<U>&&, optional<T>>::value), ""); + bool rhs_engaged = static_cast<bool>(rhs); +#ifndef TEST_HAS_NO_EXCEPTIONS + try + { + 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); + } +#else + if (is_going_to_throw) return; + optional<T> lhs(std::move(rhs)); + assert(static_cast<bool>(lhs) == rhs_engaged); +#endif +} + +class X +{ + int i_; +public: + explicit X(int i) : i_(i) {} + X(X&& x) : i_(std::exchange(x.i_, 0)) {} + ~X() {i_ = 0;} + friend bool operator==(const X& x, const X& y) {return x.i_ == y.i_;} +}; + +int count = 0; + +class Z +{ +public: + explicit Z(int) { TEST_THROW(6); } +}; + +int main() +{ + { + optional<int> rhs; + test<X>(std::move(rhs)); + } + { + optional<int> rhs(3); + test<X>(std::move(rhs)); + } + { + optional<int> rhs; + test<Z>(std::move(rhs)); + } + { + optional<int> rhs(3); + test<Z>(std::move(rhs), true); + } +} diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/in_place_t.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/in_place_t.pass.cpp new file mode 100644 index 00000000000..9b59b02593b --- /dev/null +++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/in_place_t.pass.cpp @@ -0,0 +1,144 @@ +//===----------------------------------------------------------------------===// +// +// 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> + +// template <class... Args> +// constexpr explicit optional(in_place_t, Args&&... args); + +#include <optional> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" + +using std::optional; +using std::in_place_t; +using std::in_place; + +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 +{ +public: + Z(int i) {TEST_THROW(6);} +}; + + +int main() +{ + { + constexpr optional<int> opt(in_place, 5); + static_assert(static_cast<bool>(opt) == true, ""); + static_assert(*opt == 5, ""); + + struct test_constexpr_ctor + : public optional<int> + { + constexpr test_constexpr_ctor(in_place_t, int i) + : optional<int>(in_place, i) {} + }; + + } + { + const optional<X> opt(in_place); + assert(static_cast<bool>(opt) == true); + assert(*opt == X()); + } + { + const optional<X> opt(in_place, 5); + assert(static_cast<bool>(opt) == true); + assert(*opt == X(5)); + } + { + const optional<X> opt(in_place, 5, 4); + assert(static_cast<bool>(opt) == true); + assert(*opt == X(5, 4)); + } + { + constexpr optional<Y> opt(in_place); + static_assert(static_cast<bool>(opt) == true, ""); + static_assert(*opt == Y(), ""); + + struct test_constexpr_ctor + : public optional<Y> + { + constexpr test_constexpr_ctor(in_place_t) + : optional<Y>(in_place) {} + }; + + } + { + constexpr optional<Y> opt(in_place, 5); + static_assert(static_cast<bool>(opt) == true, ""); + static_assert(*opt == Y(5), ""); + + struct test_constexpr_ctor + : public optional<Y> + { + constexpr test_constexpr_ctor(in_place_t, int i) + : optional<Y>(in_place, i) {} + }; + + } + { + constexpr optional<Y> opt(in_place, 5, 4); + static_assert(static_cast<bool>(opt) == true, ""); + static_assert(*opt == Y(5, 4), ""); + + struct test_constexpr_ctor + : public optional<Y> + { + constexpr test_constexpr_ctor(in_place_t, int i, int j) + : optional<Y>(in_place, i, j) {} + }; + + } +#ifndef TEST_HAS_NO_EXCEPTIONS + { + try + { + const optional<Z> opt(in_place, 1); + assert(false); + } + catch (int i) + { + assert(i == 6); + } + } +#endif +} diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/initializer_list.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/initializer_list.pass.cpp new file mode 100644 index 00000000000..6d9f45a97d4 --- /dev/null +++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/initializer_list.pass.cpp @@ -0,0 +1,116 @@ +//===----------------------------------------------------------------------===// +// +// 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> + +// 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> + +#include "test_macros.h" + +using std::optional; +using std::in_place_t; +using std::in_place; + +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: + Z() : i_(0) {} + Z(int i) : i_(i) {} + Z(std::initializer_list<int> il) : i_(il.begin()[0]), j_(il.begin()[1]) + {TEST_THROW(6);} + + friend bool operator==(const Z& x, const Z& y) + {return x.i_ == y.i_ && x.j_ == y.j_;} +}; + +int main() +{ + { + static_assert(!std::is_constructible<X, std::initializer_list<int>&>::value, ""); + static_assert(!std::is_constructible<optional<X>, std::initializer_list<int>&>::value, ""); + } + { + optional<std::vector<int>> opt(in_place, {3, 1}); + assert(static_cast<bool>(opt) == true); + assert((*opt == std::vector<int>{3, 1})); + assert(opt->size() == 2); + } + { + optional<std::vector<int>> opt(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<optional<Y>, std::initializer_list<int>&>::value, ""); + constexpr optional<Y> opt(in_place, {3, 1}); + static_assert(static_cast<bool>(opt) == true, ""); + static_assert(*opt == Y{3, 1}, ""); + + struct test_constexpr_ctor + : public optional<Y> + { + constexpr test_constexpr_ctor(in_place_t, std::initializer_list<int> i) + : optional<Y>(in_place, i) {} + }; + + } +#ifndef TEST_HAS_NO_EXCEPTIONS + { + static_assert(std::is_constructible<optional<Z>, std::initializer_list<int>&>::value, ""); + try + { + optional<Z> opt(in_place, {3, 1}); + assert(false); + } + catch (int i) + { + assert(i == 6); + } + } +#endif +} diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/move.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/move.pass.cpp new file mode 100644 index 00000000000..5a4929c5373 --- /dev/null +++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/move.pass.cpp @@ -0,0 +1,196 @@ +//===----------------------------------------------------------------------===// +// +// 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> + +// optional(optional<T>&& rhs); + +#include <optional> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "archetypes.hpp" + +using std::optional; + +template <class T, class ...InitArgs> +void test(InitArgs&&... args) +{ + const optional<T> orig(std::forward<InitArgs>(args)...); + optional<T> rhs(orig); + bool rhs_engaged = static_cast<bool>(rhs); + optional<T> lhs = std::move(rhs); + assert(static_cast<bool>(lhs) == rhs_engaged); + if (rhs_engaged) + assert(*lhs == *orig); +} + +void test_throwing_ctor() { +#ifndef TEST_HAS_NO_EXCEPTIONS + struct Z { + Z() : count(0) {} + Z(Z&& o) : count(o.count + 1) + { if (count == 2) throw 6; } + int count; + }; + Z z; + optional<Z> rhs(std::move(z)); + try + { + optional<Z> lhs(std::move(rhs)); + assert(false); + } + catch (int i) + { + assert(i == 6); + } +#endif +} + + +template <class T, class ...InitArgs> +void test_ref(InitArgs&&... args) +{ + optional<T> rhs(std::forward<InitArgs>(args)...); + bool rhs_engaged = static_cast<bool>(rhs); + optional<T> lhs = std::move(rhs); + assert(static_cast<bool>(lhs) == rhs_engaged); + if (rhs_engaged) + assert(&(*lhs) == &(*rhs)); +} + +void test_reference_extension() +{ +#if defined(_LIBCPP_VERSION) && 0 // FIXME these extensions are currently disabled. + using T = TestTypes::TestType; + T::reset(); + { + T t; + T::reset_constructors(); + test_ref<T&>(); + test_ref<T&>(t); + assert(T::alive == 1); + assert(T::constructed == 0); + assert(T::assigned == 0); + assert(T::destroyed == 0); + } + assert(T::destroyed == 1); + assert(T::alive == 0); + { + T t; + const T& ct = t; + T::reset_constructors(); + test_ref<T const&>(); + test_ref<T const&>(t); + test_ref<T const&>(ct); + assert(T::alive == 1); + assert(T::constructed == 0); + assert(T::assigned == 0); + assert(T::destroyed == 0); + } + assert(T::alive == 0); + assert(T::destroyed == 1); + { + T t; + T::reset_constructors(); + test_ref<T&&>(); + test_ref<T&&>(std::move(t)); + assert(T::alive == 1); + assert(T::constructed == 0); + assert(T::assigned == 0); + assert(T::destroyed == 0); + } + assert(T::alive == 0); + assert(T::destroyed == 1); + { + T t; + const T& ct = t; + T::reset_constructors(); + test_ref<T const&&>(); + test_ref<T const&&>(std::move(t)); + test_ref<T const&&>(std::move(ct)); + assert(T::alive == 1); + assert(T::constructed == 0); + assert(T::assigned == 0); + assert(T::destroyed == 0); + } + assert(T::alive == 0); + assert(T::destroyed == 1); + { + static_assert(!std::is_copy_constructible<std::optional<T&&>>::value, ""); + static_assert(!std::is_copy_constructible<std::optional<T const&&>>::value, ""); + } +#endif +} + + +int main() +{ + test<int>(); + test<int>(3); + { + using T = TestTypes::TestType; + T::reset(); + optional<T> rhs; + assert(T::alive == 0); + const optional<T> lhs(std::move(rhs)); + assert(lhs.has_value() == false); + assert(rhs.has_value() == false); + assert(T::alive == 0); + } + TestTypes::TestType::reset(); + { + using T = TestTypes::TestType; + T::reset(); + optional<T> rhs(42); + assert(T::alive == 1); + assert(T::value_constructed == 1); + assert(T::move_constructed == 0); + const optional<T> lhs(std::move(rhs)); + assert(lhs.has_value()); + assert(rhs.has_value()); + assert(lhs.value().value == 42); + assert(rhs.value().value == -1); + assert(T::move_constructed == 1); + assert(T::alive == 2); + } + TestTypes::TestType::reset(); + { + using namespace ConstexprTestTypes; + test<TestType>(); + test<TestType>(42); + } + { + using namespace TrivialTestTypes; + test<TestType>(); + test<TestType>(42); + } + { + test_throwing_ctor(); + } + { + struct ThrowsMove { + ThrowsMove() noexcept(false) {} + ThrowsMove(ThrowsMove const&) noexcept(false) {} + ThrowsMove(ThrowsMove &&) noexcept(false) {} + }; + static_assert(!std::is_nothrow_move_constructible<optional<ThrowsMove>>::value, ""); + struct NoThrowMove { + NoThrowMove() noexcept(false) {} + NoThrowMove(NoThrowMove const&) noexcept(false) {} + NoThrowMove(NoThrowMove &&) noexcept(true) {} + }; + static_assert(std::is_nothrow_move_constructible<optional<NoThrowMove>>::value, ""); + } + { + test_reference_extension(); + } +} diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/nullopt_t.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/nullopt_t.pass.cpp new file mode 100644 index 00000000000..468a00346fc --- /dev/null +++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/nullopt_t.pass.cpp @@ -0,0 +1,73 @@ +//===----------------------------------------------------------------------===// +// +// 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> + +// constexpr optional(nullopt_t) noexcept; + +#include <optional> +#include <type_traits> +#include <cassert> + +#include "archetypes.hpp" + +using std::optional; +using std::nullopt_t; +using std::nullopt; + +template <class Opt> +void +test_constexpr() +{ + static_assert(std::is_nothrow_constructible<Opt, nullopt_t&>::value, ""); + static_assert(std::is_trivially_destructible<Opt>::value, ""); + static_assert(std::is_trivially_destructible<typename Opt::value_type>::value, ""); + + constexpr Opt opt(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(std::is_nothrow_constructible<Opt, nullopt_t&>::value, ""); + static_assert(!std::is_trivially_destructible<Opt>::value, ""); + static_assert(!std::is_trivially_destructible<typename Opt::value_type>::value, ""); + { + Opt opt(nullopt); + assert(static_cast<bool>(opt) == false); + } + { + const Opt opt(nullopt); + assert(static_cast<bool>(opt) == false); + } + struct test_constexpr_ctor + : public Opt + { + constexpr test_constexpr_ctor() {} + }; +} + +int main() +{ + test_constexpr<optional<int>>(); + test_constexpr<optional<int*>>(); + test_constexpr<optional<ImplicitTypes::NoCtors>>(); + test_constexpr<optional<NonTrivialTypes::NoCtors>>(); + test_constexpr<optional<NonConstexprTypes::NoCtors>>(); + test<optional<NonLiteralTypes::NoCtors>>(); +} diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/optional_U.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/optional_U.pass.cpp new file mode 100644 index 00000000000..0e180c14ec6 --- /dev/null +++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/optional_U.pass.cpp @@ -0,0 +1,93 @@ +//===----------------------------------------------------------------------===// +// +// 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> + +// template <class U> +// optional(optional<U>&& rhs); + +#include <optional> +#include <type_traits> +#include <memory> +#include <cassert> + +#include "test_macros.h" + +using std::optional; + +template <class T, class U> +void +test(optional<U>&& rhs, bool is_going_to_throw = false) +{ + bool rhs_engaged = static_cast<bool>(rhs); +#ifndef TEST_HAS_NO_EXCEPTIONS + try + { + 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); + } +#else + if (is_going_to_throw) return; + optional<T> lhs = std::move(rhs); + assert(static_cast<bool>(lhs) == rhs_engaged); +#endif +} + +class X +{ + int i_; +public: + X(int i) : i_(i) {} + X(X&& x) : i_(std::exchange(x.i_, 0)) {} + ~X() {i_ = 0;} + friend bool operator==(const X& x, const X& y) {return x.i_ == y.i_;} +}; + +int count = 0; + +struct Z +{ + Z(int) { TEST_THROW(6); } +}; + +int main() +{ + { + optional<short> rhs; + test<int>(std::move(rhs)); + } + { + optional<short> rhs(short{3}); + test<int>(std::move(rhs)); + } + { + optional<int> rhs; + test<X>(std::move(rhs)); + } + { + optional<int> rhs(3); + test<X>(std::move(rhs)); + } + { + optional<int> rhs; + test<Z>(std::move(rhs)); + } + { + optional<int> rhs(3); + test<Z>(std::move(rhs), true); + } + + static_assert(!(std::is_constructible<optional<X>, optional<Z>>::value), ""); +} diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/rvalue_T.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/rvalue_T.pass.cpp new file mode 100644 index 00000000000..496661d922a --- /dev/null +++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/rvalue_T.pass.cpp @@ -0,0 +1,148 @@ +//===----------------------------------------------------------------------===// +// +// 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> + +// constexpr optional(T&& v); + +#include <optional> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "archetypes.hpp" + + +using std::optional; + + +class Z +{ +public: + Z(int) {} + Z(Z&&) {TEST_THROW(6);} +}; + + +int main() +{ + { + typedef int T; + constexpr optional<T> opt(T(5)); + static_assert(static_cast<bool>(opt) == true, ""); + static_assert(*opt == 5, ""); + + struct test_constexpr_ctor + : public optional<T> + { + constexpr test_constexpr_ctor(T&&) {} + }; + } + { + typedef double T; + constexpr optional<T> opt(T(3)); + static_assert(static_cast<bool>(opt) == true, ""); + static_assert(*opt == 3, ""); + + struct test_constexpr_ctor + : public optional<T> + { + constexpr test_constexpr_ctor(T&&) {} + }; + } + { + typedef TestTypes::TestType T; + T::reset(); + optional<T> opt = T{3}; + assert(T::alive == 1); + assert(T::move_constructed == 1); + assert(static_cast<bool>(opt) == true); + assert(opt.value().value == 3); + } + { + typedef ExplicitTestTypes::TestType T; + static_assert(!std::is_convertible<T&&, optional<T>>::value, ""); + T::reset(); + optional<T> opt(T{3}); + assert(T::alive == 1); + assert(T::move_constructed == 1); + assert(static_cast<bool>(opt) == true); + assert(opt.value().value == 3); + } + { + typedef TestTypes::TestType T; + T::reset(); + optional<T> opt = {3}; + assert(T::alive == 1); + assert(T::value_constructed == 1); + assert(T::copy_constructed == 0); + assert(T::move_constructed == 0); + assert(static_cast<bool>(opt) == true); + assert(opt.value().value == 3); + } + { + typedef ConstexprTestTypes::TestType T; + constexpr optional<T> opt = {T(3)}; + static_assert(static_cast<bool>(opt) == true, ""); + static_assert(opt.value().value == 3, ""); + + struct test_constexpr_ctor + : public optional<T> + { + constexpr test_constexpr_ctor(const T&) {} + }; + } + { + typedef ConstexprTestTypes::TestType T; + constexpr optional<T> opt = {3}; + static_assert(static_cast<bool>(opt) == true, ""); + static_assert(opt.value().value == 3, ""); + + struct test_constexpr_ctor + : public optional<T> + { + constexpr test_constexpr_ctor(const T&) {} + }; + } + { + typedef ExplicitConstexprTestTypes::TestType T; + static_assert(!std::is_convertible<T&&, optional<T>>::value, ""); + constexpr optional<T> opt(T{3}); + static_assert(static_cast<bool>(opt) == true, ""); + static_assert(opt.value().value == 3, ""); + + struct test_constexpr_ctor + : public optional<T> + { + constexpr test_constexpr_ctor(T&&) {} + }; + + } +#ifndef TEST_HAS_NO_EXCEPTIONS + { + struct Z { + Z(int) {} + Z(Z&&) {throw 6;} + }; + typedef Z T; + try + { + T t(3); + optional<T> opt(std::move(t)); + assert(false); + } + catch (int i) + { + assert(i == 6); + } + } +#endif +} |