diff options
Diffstat (limited to 'libcxx/test/std/utilities')
73 files changed, 6347 insertions, 1 deletions
diff --git a/libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_swappable_with.pass.cpp b/libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_swappable_with.pass.cpp index 408231f6057..b23a5e45f28 100644 --- a/libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_swappable_with.pass.cpp +++ b/libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_swappable_with.pass.cpp @@ -59,7 +59,7 @@ int main()                        !std::is_nothrow_swappable_with<A&, A&>::value, "");      }      { -        // test that hetrogenius swap is allowed only if both 'swap(A, B)' and +        // test that heterogeneous swap is allowed only if both 'swap(A, B)' and          // 'swap(B, A)' are valid.          static_assert(std::is_nothrow_swappable_with<A&, B&>::value, "");          static_assert(!std::is_nothrow_swappable_with<A&, C&>::value && diff --git a/libcxx/test/std/utilities/optional/optional.bad_optional_access/default.pass.cpp b/libcxx/test/std/utilities/optional/optional.bad_optional_access/default.pass.cpp new file mode 100644 index 00000000000..e3c7bb5ad27 --- /dev/null +++ b/libcxx/test/std/utilities/optional/optional.bad_optional_access/default.pass.cpp @@ -0,0 +1,23 @@ +//===----------------------------------------------------------------------===// +// +//                     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> + +// class bad_optional_access is default constructible + +#include <optional> +#include <type_traits> + +int main() +{ +    using std::bad_optional_access; +    bad_optional_access ex; +} diff --git a/libcxx/test/std/utilities/optional/optional.bad_optional_access/derive.pass.cpp b/libcxx/test/std/utilities/optional/optional.bad_optional_access/derive.pass.cpp new file mode 100644 index 00000000000..85e36d2c107 --- /dev/null +++ b/libcxx/test/std/utilities/optional/optional.bad_optional_access/derive.pass.cpp @@ -0,0 +1,25 @@ +//===----------------------------------------------------------------------===// +// +//                     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> + +// class bad_optional_access : public logic_error + +#include <optional> +#include <type_traits> + +int main() +{ +    using std::bad_optional_access; + +    static_assert(std::is_base_of<std::logic_error, bad_optional_access>::value, ""); +    static_assert(std::is_convertible<bad_optional_access*, std::logic_error*>::value, ""); +} diff --git a/libcxx/test/std/utilities/optional/optional.comp_with_t/equal.pass.cpp b/libcxx/test/std/utilities/optional/optional.comp_with_t/equal.pass.cpp new file mode 100644 index 00000000000..b54a08f5575 --- /dev/null +++ b/libcxx/test/std/utilities/optional/optional.comp_with_t/equal.pass.cpp @@ -0,0 +1,53 @@ +//===----------------------------------------------------------------------===// +// +//                     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 T> constexpr bool operator==(const optional<T>& x, const T& v); +// template <class T> constexpr bool operator==(const T& v, const optional<T>& x); + +#include <optional> + +using std::optional; + +struct X +{ +    int i_; + +    constexpr X(int i) : i_(i) {} +}; + +constexpr bool operator == ( const X &lhs, const X &rhs ) +    { return lhs.i_ == rhs.i_ ; } + +int main() +{ +    { +    typedef X T; +    typedef optional<T> O; + +    constexpr T val(2); +    constexpr O o1;       // disengaged +    constexpr O o2{1};    // engaged +    constexpr O o3{val};  // engaged + +    static_assert ( !(o1 == T(1)), "" ); +    static_assert (  (o2 == T(1)), "" ); +    static_assert ( !(o3 == T(1)), "" ); +    static_assert (  (o3 == T(2)), "" ); +    static_assert (  (o3 == val),  "" ); + +    static_assert ( !(T(1) == o1), "" ); +    static_assert (  (T(1) == o2), "" ); +    static_assert ( !(T(1) == o3), "" ); +    static_assert (  (T(2) == o3), "" ); +    static_assert (  (val  == o3), "" ); +    } +} diff --git a/libcxx/test/std/utilities/optional/optional.comp_with_t/greater.pass.cpp b/libcxx/test/std/utilities/optional/optional.comp_with_t/greater.pass.cpp new file mode 100644 index 00000000000..064114fb9db --- /dev/null +++ b/libcxx/test/std/utilities/optional/optional.comp_with_t/greater.pass.cpp @@ -0,0 +1,55 @@ +//===----------------------------------------------------------------------===// +// +//                     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 T> constexpr bool operator>(const optional<T>& x, const T& v); +// template <class T> constexpr bool operator>(const T& v, const optional<T>& x); + +#include <optional> + +using std::optional; + +struct X +{ +    int i_; + +    constexpr X(int i) : i_(i) {} +}; + +constexpr bool operator > ( const X &lhs, const X &rhs ) +    { return lhs.i_ > rhs.i_ ; } + +int main() +{ +    { +    typedef X T; +    typedef optional<T> O; + +    constexpr T val(2); +    constexpr O o1;       // disengaged +    constexpr O o2{1};    // engaged +    constexpr O o3{val};  // engaged + +    static_assert ( !(o1 > T(1)), "" ); +    static_assert ( !(o2 > T(1)), "" );  // equal +    static_assert (  (o3 > T(1)), "" ); +    static_assert ( !(o2 >  val), "" ); +    static_assert ( !(o3 >  val), "" );  // equal +    static_assert ( !(o3 > T(3)), "" ); + +    static_assert (   (T(1) > o1), "" ); +    static_assert (  !(T(1) > o2), "" ); // equal +    static_assert (  !(T(1) > o3), "" ); +    static_assert (   (val  > o2), "" ); +    static_assert (  !(val  > o3), "" ); // equal +    static_assert (   (T(3) > o3), "" ); +    } +} diff --git a/libcxx/test/std/utilities/optional/optional.comp_with_t/greater_equal.pass.cpp b/libcxx/test/std/utilities/optional/optional.comp_with_t/greater_equal.pass.cpp new file mode 100644 index 00000000000..663686cdf34 --- /dev/null +++ b/libcxx/test/std/utilities/optional/optional.comp_with_t/greater_equal.pass.cpp @@ -0,0 +1,55 @@ +//===----------------------------------------------------------------------===// +// +//                     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 T> constexpr bool operator>=(const optional<T>& x, const T& v); +// template <class T> constexpr bool operator>=(const T& v, const optional<T>& x); + +#include <optional> + +using std::optional; + +struct X +{ +    int i_; + +    constexpr X(int i) : i_(i) {} +}; + +constexpr bool operator >= ( const X &lhs, const X &rhs ) +    { return lhs.i_ >= rhs.i_ ; } + +int main() +{ +    { +    typedef X T; +    typedef optional<T> O; + +    constexpr T val(2); +    constexpr O o1;       // disengaged +    constexpr O o2{1};    // engaged +    constexpr O o3{val};  // engaged + +    static_assert ( !(o1 >= T(1)), "" ); +    static_assert (  (o2 >= T(1)), "" );  // equal +    static_assert (  (o3 >= T(1)), "" ); +    static_assert ( !(o2 >=  val), "" ); +    static_assert (  (o3 >=  val), "" );  // equal +    static_assert ( !(o3 >= T(3)), "" ); + +    static_assert (   (T(1) >= o1), "" ); +    static_assert (   (T(1) >= o2), "" ); // equal +    static_assert (  !(T(1) >= o3), "" ); +    static_assert (   (val  >= o2), "" ); +    static_assert (   (val  >= o3), "" ); // equal +    static_assert (   (T(3) >= o3), "" ); +    } +} diff --git a/libcxx/test/std/utilities/optional/optional.comp_with_t/less_equal.pass.cpp b/libcxx/test/std/utilities/optional/optional.comp_with_t/less_equal.pass.cpp new file mode 100644 index 00000000000..05ac5eb12b4 --- /dev/null +++ b/libcxx/test/std/utilities/optional/optional.comp_with_t/less_equal.pass.cpp @@ -0,0 +1,55 @@ +//===----------------------------------------------------------------------===// +// +//                     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 T> constexpr bool operator<=(const optional<T>& x, const T& v); +// template <class T> constexpr bool operator<=(const T& v, const optional<T>& x); + +#include <optional> + +using std::optional; + +struct X +{ +    int i_; + +    constexpr X(int i) : i_(i) {} +}; + +constexpr bool operator <= ( const X &lhs, const X &rhs ) +    { return lhs.i_ <= rhs.i_ ; } + +int main() +{ +    { +    typedef X T; +    typedef optional<T> O; + +    constexpr T val(2); +    constexpr O o1;       // disengaged +    constexpr O o2{1};    // engaged +    constexpr O o3{val};  // engaged + +    static_assert (  (o1 <= T(1)), "" ); +    static_assert (  (o2 <= T(1)), "" );  // equal +    static_assert ( !(o3 <= T(1)), "" ); +    static_assert (  (o2 <=  val), "" ); +    static_assert (  (o3 <=  val), "" );  // equal +    static_assert (  (o3 <= T(3)), "" ); + +    static_assert (  !(T(1) <= o1), "" ); +    static_assert (   (T(1) <= o2), "" ); // equal +    static_assert (   (T(1) <= o3), "" ); +    static_assert (  !(val  <= o2), "" ); +    static_assert (   (val  <= o3), "" ); // equal +    static_assert (  !(T(3) <= o3), "" ); +    } +} diff --git a/libcxx/test/std/utilities/optional/optional.comp_with_t/less_than.pass.cpp b/libcxx/test/std/utilities/optional/optional.comp_with_t/less_than.pass.cpp new file mode 100644 index 00000000000..d1891a286d7 --- /dev/null +++ b/libcxx/test/std/utilities/optional/optional.comp_with_t/less_than.pass.cpp @@ -0,0 +1,55 @@ +//===----------------------------------------------------------------------===// +// +//                     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 T> constexpr bool operator<(const optional<T>& x, const T& v); +// template <class T> constexpr bool operator<(const T& v, const optional<T>& x); + +#include <optional> + +using std::optional; + +struct X +{ +    int i_; + +    constexpr X(int i) : i_(i) {} +}; + +constexpr bool operator < ( const X &lhs, const X &rhs ) +    { return lhs.i_ < rhs.i_ ; } + +int main() +{ +    { +    typedef X T; +    typedef optional<T> O; + +    constexpr T val(2); +    constexpr O o1;       // disengaged +    constexpr O o2{1};    // engaged +    constexpr O o3{val};  // engaged + +    static_assert (  (o1 < T(1)), "" ); +    static_assert ( !(o2 < T(1)), "" );  // equal +    static_assert ( !(o3 < T(1)), "" ); +    static_assert (  (o2 <  val), "" ); +    static_assert ( !(o3 <  val), "" );  // equal +    static_assert (  (o3 < T(3)), "" ); + +    static_assert (  !(T(1) < o1), "" ); +    static_assert (  !(T(1) < o2), "" ); // equal +    static_assert (   (T(1) < o3), "" ); +    static_assert (  !(val  < o2), "" ); +    static_assert (  !(val  < o3), "" ); // equal +    static_assert (  !(T(3) < o3), "" ); +    } +} diff --git a/libcxx/test/std/utilities/optional/optional.comp_with_t/not_equal.pass.cpp b/libcxx/test/std/utilities/optional/optional.comp_with_t/not_equal.pass.cpp new file mode 100644 index 00000000000..ae2ff808fb2 --- /dev/null +++ b/libcxx/test/std/utilities/optional/optional.comp_with_t/not_equal.pass.cpp @@ -0,0 +1,53 @@ +//===----------------------------------------------------------------------===// +// +//                     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 T> constexpr bool operator!=(const optional<T>& x, const T& v); +// template <class T> constexpr bool operator!=(const T& v, const optional<T>& x); + +#include <optional> + +using std::optional; + +struct X +{ +    int i_; + +    constexpr X(int i) : i_(i) {} +}; + +constexpr bool operator != ( const X &lhs, const X &rhs ) +    { return lhs.i_ != rhs.i_ ; } + +int main() +{ +    { +    typedef X T; +    typedef optional<T> O; + +    constexpr T val(2); +    constexpr O o1;       // disengaged +    constexpr O o2{1};    // engaged +    constexpr O o3{val};  // engaged + +    static_assert (  (o1 != T(1)), "" ); +    static_assert ( !(o2 != T(1)), "" ); +    static_assert (  (o3 != T(1)), "" ); +    static_assert ( !(o3 != T(2)), "" ); +    static_assert ( !(o3 != val),  "" ); + +    static_assert (  (T(1) != o1), "" ); +    static_assert ( !(T(1) != o2), "" ); +    static_assert (  (T(1) != o3), "" ); +    static_assert ( !(T(2) != o3), "" ); +    static_assert ( !(val  != o3), "" ); +    } +} diff --git a/libcxx/test/std/utilities/optional/optional.hash/hash.pass.cpp b/libcxx/test/std/utilities/optional/optional.hash/hash.pass.cpp new file mode 100644 index 00000000000..dfdd07ddf45 --- /dev/null +++ b/libcxx/test/std/utilities/optional/optional.hash/hash.pass.cpp @@ -0,0 +1,48 @@ +//===----------------------------------------------------------------------===// +// +//                     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 T> struct hash<optional<T>>; + +#include <optional> +#include <string> +#include <memory> +#include <cassert> + + +int main() +{ +    using std::optional; +    const std::size_t nullopt_hash = +        std::hash<optional<double>>{}(optional<double>{}); + +    { +        typedef int T; +        optional<T> opt; +        assert(std::hash<optional<T>>{}(opt) == nullopt_hash); +        opt = 2; +        assert(std::hash<optional<T>>{}(opt) == std::hash<T>{}(*opt)); +    } +    { +        typedef std::string T; +        optional<T> opt; +        assert(std::hash<optional<T>>{}(opt) == nullopt_hash); +        opt = std::string("123"); +        assert(std::hash<optional<T>>{}(opt) == std::hash<T>{}(*opt)); +    } +    { +        typedef std::unique_ptr<int> T; +        optional<T> opt; +        assert(std::hash<optional<T>>{}(opt) == nullopt_hash); +        opt = std::unique_ptr<int>(new int(3)); +        assert(std::hash<optional<T>>{}(opt) == std::hash<T>{}(*opt)); +    } +} diff --git a/libcxx/test/std/utilities/optional/optional.nullops/equal.pass.cpp b/libcxx/test/std/utilities/optional/optional.nullops/equal.pass.cpp new file mode 100644 index 00000000000..a87a87f877f --- /dev/null +++ b/libcxx/test/std/utilities/optional/optional.nullops/equal.pass.cpp @@ -0,0 +1,39 @@ +//===----------------------------------------------------------------------===// +// +//                     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 T> constexpr bool operator==(const optional<T>& x, nullopt_t) noexcept; +// template <class T> constexpr bool operator==(nullopt_t, const optional<T>& x) noexcept; + +#include <optional> + +int main() +{ +    using std::optional; +    using std::nullopt_t; +    using std::nullopt; + +    { +    typedef int T; +    typedef optional<T> O; + +    constexpr O o1;     // disengaged +    constexpr O o2{1};  // engaged + +    static_assert (  (nullopt == o1), "" ); +    static_assert ( !(nullopt == o2), "" ); +    static_assert (  (o1 == nullopt), "" ); +    static_assert ( !(o2 == nullopt), "" ); + +    static_assert (noexcept(nullopt == o1), ""); +    static_assert (noexcept(o1 == nullopt), ""); +    } +} diff --git a/libcxx/test/std/utilities/optional/optional.nullops/greater.pass.cpp b/libcxx/test/std/utilities/optional/optional.nullops/greater.pass.cpp new file mode 100644 index 00000000000..3986a0a9265 --- /dev/null +++ b/libcxx/test/std/utilities/optional/optional.nullops/greater.pass.cpp @@ -0,0 +1,39 @@ +//===----------------------------------------------------------------------===// +// +//                     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 T> constexpr bool operator>(const optional<T>& x, nullopt_t) noexcept; +// template <class T> constexpr bool operator>(nullopt_t, const optional<T>& x) noexcept; + +#include <optional> + +int main() +{ +    using std::optional; +    using std::nullopt_t; +    using std::nullopt; + +    { +    typedef int T; +    typedef optional<T> O; + +    constexpr O o1;     // disengaged +    constexpr O o2{1};  // engaged + +    static_assert ( !(nullopt > o1), "" ); +    static_assert ( !(nullopt > o2), "" ); +    static_assert ( !(o1 > nullopt), "" ); +    static_assert (  (o2 > nullopt), "" ); + +    static_assert (noexcept(nullopt > o1), ""); +    static_assert (noexcept(o1 > nullopt), ""); +    } +} diff --git a/libcxx/test/std/utilities/optional/optional.nullops/greater_equal.pass.cpp b/libcxx/test/std/utilities/optional/optional.nullops/greater_equal.pass.cpp new file mode 100644 index 00000000000..9f242727347 --- /dev/null +++ b/libcxx/test/std/utilities/optional/optional.nullops/greater_equal.pass.cpp @@ -0,0 +1,39 @@ +//===----------------------------------------------------------------------===// +// +//                     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 T> constexpr bool operator>=(const optional<T>& x, nullopt_t) noexcept; +// template <class T> constexpr bool operator>=(nullopt_t, const optional<T>& x) noexcept; + +#include <optional> + +int main() +{ +    using std::optional; +    using std::nullopt_t; +    using std::nullopt; + +    { +    typedef int T; +    typedef optional<T> O; + +    constexpr O o1;     // disengaged +    constexpr O o2{1};  // engaged + +    static_assert (  (nullopt >= o1), "" ); +    static_assert ( !(nullopt >= o2), "" ); +    static_assert (  (o1 >= nullopt), "" ); +    static_assert (  (o2 >= nullopt), "" ); + +    static_assert (noexcept(nullopt >= o1), ""); +    static_assert (noexcept(o1 >= nullopt), ""); +    } +} diff --git a/libcxx/test/std/utilities/optional/optional.nullops/less_equal.pass.cpp b/libcxx/test/std/utilities/optional/optional.nullops/less_equal.pass.cpp new file mode 100644 index 00000000000..8e73247b9d6 --- /dev/null +++ b/libcxx/test/std/utilities/optional/optional.nullops/less_equal.pass.cpp @@ -0,0 +1,40 @@ +//===----------------------------------------------------------------------===// +// +//                     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 T> constexpr bool operator<=(const optional<T>& x, nullopt_t) noexcept; +// template <class T> constexpr bool operator<=(nullopt_t, const optional<T>& x) noexcept; + +#include <optional> + +int main() +{ +    using std::optional; +    using std::nullopt_t; +    using std::nullopt; + +    { +    typedef int T; +    typedef optional<T> O; + +    constexpr O o1;     // disengaged +    constexpr O o2{1};  // engaged + +    static_assert (  (nullopt <= o1), "" ); +    static_assert (  (nullopt <= o2), "" ); +    static_assert (  (o1 <= nullopt), "" ); +    static_assert ( !(o2 <= nullopt), "" ); + +    static_assert (noexcept(nullopt <= o1), ""); +    static_assert (noexcept(o1 <= nullopt), ""); +    } +} diff --git a/libcxx/test/std/utilities/optional/optional.nullops/less_than.pass.cpp b/libcxx/test/std/utilities/optional/optional.nullops/less_than.pass.cpp new file mode 100644 index 00000000000..39a8e4a3936 --- /dev/null +++ b/libcxx/test/std/utilities/optional/optional.nullops/less_than.pass.cpp @@ -0,0 +1,39 @@ +//===----------------------------------------------------------------------===// +// +//                     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 T> constexpr bool operator<(const optional<T>& x, nullopt_t) noexcept; +// template <class T> constexpr bool operator<(nullopt_t, const optional<T>& x) noexcept; + +#include <optional> + +int main() +{ +    using std::optional; +    using std::nullopt_t; +    using std::nullopt; + +    { +    typedef int T; +    typedef optional<T> O; + +    constexpr O o1;     // disengaged +    constexpr O o2{1};  // engaged + +    static_assert ( !(nullopt < o1), "" ); +    static_assert (  (nullopt < o2), "" ); +    static_assert ( !(o1 < nullopt), "" ); +    static_assert ( !(o2 < nullopt), "" ); + +    static_assert (noexcept(nullopt < o1), ""); +    static_assert (noexcept(o1 < nullopt), ""); +    } +} diff --git a/libcxx/test/std/utilities/optional/optional.nullops/not_equal.pass.cpp b/libcxx/test/std/utilities/optional/optional.nullops/not_equal.pass.cpp new file mode 100644 index 00000000000..1c96dd42e80 --- /dev/null +++ b/libcxx/test/std/utilities/optional/optional.nullops/not_equal.pass.cpp @@ -0,0 +1,39 @@ +//===----------------------------------------------------------------------===// +// +//                     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 T> constexpr bool operator!=(const optional<T>& x, nullopt_t) noexcept; +// template <class T> constexpr bool operator!=(nullopt_t, const optional<T>& x) noexcept; + +#include <optional> + +int main() +{ +    using std::optional; +    using std::nullopt_t; +    using std::nullopt; + +    { +    typedef int T; +    typedef optional<T> O; + +    constexpr O o1;     // disengaged +    constexpr O o2{1};  // engaged + +    static_assert ( !(nullopt != o1), "" ); +    static_assert (  (nullopt != o2), "" ); +    static_assert ( !(o1 != nullopt), "" ); +    static_assert (  (o2 != nullopt), "" ); + +    static_assert (noexcept(nullopt != o1), ""); +    static_assert (noexcept(o1 != nullopt), ""); +    } +} diff --git a/libcxx/test/std/utilities/optional/optional.nullopt/not_brace_initializable.fail.cpp b/libcxx/test/std/utilities/optional/optional.nullopt/not_brace_initializable.fail.cpp new file mode 100644 index 00000000000..86da5054a70 --- /dev/null +++ b/libcxx/test/std/utilities/optional/optional.nullopt/not_brace_initializable.fail.cpp @@ -0,0 +1,25 @@ +//===----------------------------------------------------------------------===// +// +//                     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> + +// struct nullopt_t{see below}; + +#include <optional> + +using std::optional; +using std::nullopt_t; + +int main() +{ +    // I roughly interpret LWG2736 as "it shall not be possible to copy-list-initialize nullopt_t with an +    // empty braced-init-list." +    nullopt_t foo = {}; +} diff --git a/libcxx/test/std/utilities/optional/optional.nullopt/nullopt_t.pass.cpp b/libcxx/test/std/utilities/optional/optional.nullopt/nullopt_t.pass.cpp new file mode 100644 index 00000000000..84bb29fabac --- /dev/null +++ b/libcxx/test/std/utilities/optional/optional.nullopt/nullopt_t.pass.cpp @@ -0,0 +1,38 @@ +//===----------------------------------------------------------------------===// +// +//                     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> + +// struct nullopt_t{see below}; +// constexpr nullopt_t nullopt(unspecified); + +#include <optional> +#include <type_traits> + +using std::optional; +using std::nullopt_t; +using std::nullopt; + +constexpr +int +test(const nullopt_t&) +{ +    return 3; +} + +int main() +{ +    static_assert((std::is_class<nullopt_t>::value), ""); +    static_assert((std::is_empty<nullopt_t>::value), ""); +    static_assert((std::is_literal_type<nullopt_t>::value), ""); +    static_assert((!std::is_default_constructible<nullopt_t>::value), ""); + +    static_assert(test(nullopt) == 3, ""); +} diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.assign/assign_value.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.assign/assign_value.pass.cpp new file mode 100644 index 00000000000..6abdd0db63c --- /dev/null +++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.assign/assign_value.pass.cpp @@ -0,0 +1,261 @@ +//===----------------------------------------------------------------------===// +// +//                     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<T>& operator=(U&& v); + +#include <optional> +#include <type_traits> +#include <cassert> +#include <memory> + +#include "test_macros.h" +#include "archetypes.hpp" + +using std::optional; + +struct ThrowAssign { +  static int dtor_called; +  ThrowAssign() = default; +  ThrowAssign(int) { TEST_THROW(42); } +  ThrowAssign& operator=(int) { +      TEST_THROW(42); +  } +  ~ThrowAssign() { ++dtor_called; } +}; +int ThrowAssign::dtor_called = 0; + +template <class T, class Arg = T, bool Expect = true> +void assert_assignable() { +    static_assert(std::is_assignable<optional<T>&, Arg>::value == Expect, ""); +    static_assert(!std::is_assignable<const optional<T>&, Arg>::value, ""); +} + +struct MismatchType { +  explicit MismatchType(int) {} +  explicit MismatchType(char*) {} +  explicit MismatchType(int*) = delete; +  MismatchType& operator=(int) { return *this; } +  MismatchType& operator=(int*) { return *this; } +  MismatchType& operator=(char*) = delete; +}; + +void test_sfinae() { +    using I = TestTypes::TestType; +    using E = ExplicitTestTypes::TestType; +    assert_assignable<int>(); +    assert_assignable<int, int&>(); +    assert_assignable<int, int const&>(); +    // Implicit test type +    assert_assignable<I, I const&>(); +    assert_assignable<I, I&&>(); +    assert_assignable<I, int>(); +    assert_assignable<I, void*, false>(); +    // Explicit test type +    assert_assignable<E, E const&>(); +    assert_assignable<E, E &&>(); +    assert_assignable<E, int>(); +    assert_assignable<E, void*, false>(); +    // Mismatch type +    assert_assignable<MismatchType, int>(); +    assert_assignable<MismatchType, int*, false>(); +    assert_assignable<MismatchType, char*, false>(); +} + +void test_with_test_type() +{ +    using T = TestTypes::TestType; +    T::reset(); +    { // to empty +        optional<T> opt; +        opt = 3; +        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>(opt) == true); +        assert(*opt == T(3)); +    } +    { // to existing +        optional<T> opt(42); +        T::reset_constructors(); +        opt = 3; +        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>(opt) == true); +        assert(*opt == T(3)); +    } +    { // test default argument +        optional<T> opt; +        T::reset_constructors(); +        opt = {1, 2}; +        assert(T::alive == 1); +        assert(T::constructed == 2); +        assert(T::value_constructed == 1); +        assert(T::move_constructed == 1); +        assert(T::assigned == 0); +        assert(T::destroyed == 1); +        assert(static_cast<bool>(opt) == true); +        assert(*opt == T(1, 2)); +    } +    { // test default argument +        optional<T> opt(42); +        T::reset_constructors(); +        opt = {1, 2}; +        assert(T::alive == 1); +        assert(T::constructed == 1); +        assert(T::value_constructed == 1); +        assert(T::assigned == 1); +        assert(T::move_assigned == 1); +        assert(T::destroyed == 1); +        assert(static_cast<bool>(opt) == true); +        assert(*opt == T(1, 2)); +    } +    { // test default argument +        optional<T> opt; +        T::reset_constructors(); +        opt = {1}; +        assert(T::alive == 1); +        assert(T::constructed == 2); +        assert(T::value_constructed == 1); +        assert(T::move_constructed == 1); +        assert(T::assigned == 0); +        assert(T::destroyed == 1); +        assert(static_cast<bool>(opt) == true); +        assert(*opt == T(1)); +    } +    { // test default argument +        optional<T> opt(42); +        T::reset_constructors(); +        opt = {}; +        assert(static_cast<bool>(opt) == false); +        assert(T::alive == 0); +        assert(T::constructed == 0); +        assert(T::assigned == 0); +        assert(T::destroyed == 1); +    } +} + +template <class T, class Value = int> +void test_with_type() { +    { // to empty +        optional<T> opt; +        opt = Value(3); +        assert(static_cast<bool>(opt) == true); +        assert(*opt == T(3)); +    } +    { // to existing +        optional<T> opt(Value(42)); +        opt = Value(3); +        assert(static_cast<bool>(opt) == true); +        assert(*opt == T(3)); +    } +    { // test const +        optional<T> opt(Value(42)); +        const T t(Value(3)); +        opt = t; +        assert(static_cast<bool>(opt) == true); +        assert(*opt == T(3)); +    } +    { // test default argument +        optional<T> opt; +        opt = {Value(1)}; +        assert(static_cast<bool>(opt) == true); +        assert(*opt == T(1)); +    } +    { // test default argument +        optional<T> opt(Value(42)); +        opt = {}; +        assert(static_cast<bool>(opt) == false); +    } +} + +template <class T> +void test_with_type_multi() { +    test_with_type<T>(); +    { // test default argument +        optional<T> opt; +        opt = {1, 2}; +        assert(static_cast<bool>(opt) == true); +        assert(*opt == T(1, 2)); +    } +    { // test default argument +        optional<T> opt(42); +        opt = {1, 2}; +        assert(static_cast<bool>(opt) == true); +        assert(*opt == T(1, 2)); +    } +} + +void test_throws() +{ +#ifndef TEST_HAS_NO_EXCEPTIONS +    using T = ThrowAssign; +    { +        using T = ThrowAssign; +        optional<T> opt; +        try { +            opt = 42; +            assert(false); +        } catch (int) {} +        assert(static_cast<bool>(opt) == false); +    } +    assert(T::dtor_called == 0); +    { +        T::dtor_called = 0; +        optional<T> opt(std::in_place); +        try { +            opt = 42; +            assert(false); +        } catch (int) {} +        assert(static_cast<bool>(opt) == true); +        assert(T::dtor_called == 0); +    } +    assert(T::dtor_called == 1); +#endif +} + +enum MyEnum { Zero, One, Two, Three, FortyTwo = 42 }; + +using Fn = void(*)(); + +int main() +{ +    test_sfinae(); +    // Test with instrumented type +    test_with_test_type(); +    // Test with various scalar types +    test_with_type<int>(); +    test_with_type<MyEnum, MyEnum>(); +    test_with_type<int, MyEnum>(); +    test_with_type<Fn, Fn>(); +    // Test types with multi argument constructors +    test_with_type_multi<ConstexprTestTypes::TestType>(); +    test_with_type_multi<TrivialTestTypes::TestType>(); +    // Test move only types +    { +        optional<std::unique_ptr<int>> opt; +        opt = std::unique_ptr<int>(new int(3)); +        assert(static_cast<bool>(opt) == true); +        assert(**opt == 3); +    } +    { +        optional<std::unique_ptr<int>> opt(std::unique_ptr<int>(new int(2))); +        opt = std::unique_ptr<int>(new int(3)); +        assert(static_cast<bool>(opt) == true); +        assert(**opt == 3); +    } +    test_throws(); +} diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.assign/const_optional_U.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.assign/const_optional_U.pass.cpp new file mode 100644 index 00000000000..d471c053c90 --- /dev/null +++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.assign/const_optional_U.pass.cpp @@ -0,0 +1,254 @@ +//===----------------------------------------------------------------------===// +// +//                     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=(const optional<U>& rhs); + +#include <optional> +#include <type_traits> +#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; } +}; + +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; +        const optional<int> other(42); +        opt = 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); +        const optional<int> other(42); +        T::reset_constructors(); +        opt = 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); +        const optional<int> other; +        T::reset_constructors(); +        opt = 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; +        const optional<int> other; +        T::reset_constructors(); +        opt = 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 const&>; +        const OptInt a(42); +        T::reset(); +        { +            std::optional<T> t; +            t = a; +            assert(T::type_constructed == 1); +            assert(T::type_assigned == 0); +            assert(T::int_constructed == 0); +            assert(T::int_assigned == 0); +        } +        T::reset(); +        { +            std::optional<T> t(42); +            t = a; +            assert(T::type_constructed == 0); +            assert(T::type_assigned == 1); +            assert(T::int_constructed == 1); +            assert(T::int_assigned == 0); +        } +        T::reset(); +        { +            std::optional<T> t(42); +            t = std::move(a); +            assert(T::type_constructed == 0); +            assert(T::type_assigned == 1); +            assert(T::int_constructed == 1); +            assert(T::int_assigned == 0); +        } +    } +    { +        using T = AssignableFrom<OptInt&>; +        OptInt a(42); +        T::reset(); +        { +            std::optional<T> t; +            t = 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_v<Opt&, OptInt const&>, ""); +        } +    } +} + + +int main() +{ +    test_with_test_type(); +    test_ambigious_assign(); +    { +        optional<int> opt; +        constexpr optional<short> opt2; +        opt = opt2; +        static_assert(static_cast<bool>(opt2) == false, ""); +        assert(static_cast<bool>(opt) == static_cast<bool>(opt2)); +    } +    { +        optional<int> opt; +        constexpr optional<short> opt2(short{2}); +        opt = opt2; +        static_assert(static_cast<bool>(opt2) == true, ""); +        static_assert(*opt2 == 2, ""); +        assert(static_cast<bool>(opt) == static_cast<bool>(opt2)); +        assert(*opt == *opt2); +    } +    { +        optional<int> opt(3); +        constexpr optional<short> opt2; +        opt = opt2; +        static_assert(static_cast<bool>(opt2) == false, ""); +        assert(static_cast<bool>(opt) == static_cast<bool>(opt2)); +    } +    { +        optional<int> opt(3); +        constexpr optional<short> opt2(short{2}); +        opt = opt2; +        static_assert(static_cast<bool>(opt2) == true, ""); +        static_assert(*opt2 == 2, ""); +        assert(static_cast<bool>(opt) == static_cast<bool>(opt2)); +        assert(*opt == *opt2); +    } +#ifndef TEST_HAS_NO_EXCEPTIONS +    { +        optional<X> opt; +        optional<int> opt2(42); +        assert(static_cast<bool>(opt2) == true); +        try +        { +            X::throw_now = true; +            opt = opt2; +            assert(false); +        } +        catch (int i) +        { +            assert(i == 6); +            assert(static_cast<bool>(opt) == false); +        } +    } +#endif +} diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.assign/copy.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.assign/copy.pass.cpp new file mode 100644 index 00000000000..98c90aa1d4f --- /dev/null +++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.assign/copy.pass.cpp @@ -0,0 +1,102 @@ +//===----------------------------------------------------------------------===// +// +//                     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<T>& operator=(const optional<T>& rhs); + +#include <optional> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "archetypes.hpp" + +using std::optional; + +struct X +{ +    static bool throw_now; + +    X() = default; +    X(const X&) +    { +        if (throw_now) +            TEST_THROW(6); +    } +}; + +bool X::throw_now = false; + +template <class Tp> +constexpr bool assign_empty(optional<Tp>&& lhs) { +    const optional<Tp> rhs; +    lhs = rhs; +    return !lhs.has_value() && !rhs.has_value(); +} + +template <class Tp> +constexpr bool assign_value(optional<Tp>&& lhs) { +    const optional<Tp> rhs(101); +    lhs = rhs; +    return lhs.has_value() && rhs.has_value() && *lhs == *rhs; +} + +int main() +{ +    { +        using O = optional<int>; +        LIBCPP_STATIC_ASSERT(assign_empty(O{42}), ""); +        LIBCPP_STATIC_ASSERT(assign_value(O{42}), ""); +        assert(assign_empty(O{42})); +        assert(assign_value(O{42})); +    } +    { +        using O = optional<TrivialTestTypes::TestType>; +        LIBCPP_STATIC_ASSERT(assign_empty(O{42}), ""); +        LIBCPP_STATIC_ASSERT(assign_value(O{42}), ""); +        assert(assign_empty(O{42})); +        assert(assign_value(O{42})); +    } +    { +        using O = optional<TestTypes::TestType>; +        assert(assign_empty(O{42})); +        assert(assign_value(O{42})); +    } +    { +        using T = TestTypes::TestType; +        T::reset(); +        optional<T> opt(3); +        const optional<T> opt2; +        assert(T::alive == 1); +        opt = opt2; +        assert(T::alive == 0); +        assert(!opt2.has_value()); +        assert(!opt.has_value()); +    } +#ifndef TEST_HAS_NO_EXCEPTIONS +    { +        optional<X> opt; +        optional<X> opt2(X{}); +        assert(static_cast<bool>(opt2) == true); +        try +        { +            X::throw_now = true; +            opt = opt2; +            assert(false); +        } +        catch (int i) +        { +            assert(i == 6); +            assert(static_cast<bool>(opt) == false); +        } +    } +#endif +} diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.assign/emplace.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.assign/emplace.pass.cpp new file mode 100644 index 00000000000..be17aa6fc51 --- /dev/null +++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.assign/emplace.pass.cpp @@ -0,0 +1,237 @@ +//===----------------------------------------------------------------------===// +// +//                     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> void optional<T>::emplace(Args&&... args); + +#include <optional> +#include <type_traits> +#include <cassert> +#include <memory> + +#include "test_macros.h" +#include "archetypes.hpp" + +using std::optional; + +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) {} + +    friend bool operator==(const X& x, const X& y) +        {return x.i_ == y.i_ && x.j_ == y.j_;} +}; + +class Y +{ +public: +    static bool dtor_called; +    Y() = default; +    Y(int) { TEST_THROW(6);} +    ~Y() {dtor_called = true;} +}; + +bool Y::dtor_called = false; + +template <class T> +void test_one_arg() { +    using Opt = std::optional<T>; +    { +        Opt opt; +        opt.emplace(); +        assert(static_cast<bool>(opt) == true); +        assert(*opt == T(0)); +    } +    { +        Opt opt; +        opt.emplace(1); +        assert(static_cast<bool>(opt) == true); +        assert(*opt == T(1)); +    } +    { +        Opt opt(2); +        opt.emplace(); +        assert(static_cast<bool>(opt) == true); +        assert(*opt == T(0)); +    } +    { +        Opt opt(2); +        opt.emplace(1); +        assert(static_cast<bool>(opt) == true); +        assert(*opt == T(1)); +    } +} + + +template <class T> +void test_multi_arg() +{ +    test_one_arg<T>(); +    using Opt = std::optional<T>; +    Opt opt; +    { +        opt.emplace(101, 41); +        assert(static_cast<bool>(opt) == true); +        assert(*opt == T(101, 41)); +    } +    { +        Opt opt; +        opt.emplace({1, 2, 3, 4}); +        assert(static_cast<bool>(opt) == true); +        assert(*opt == T(4)); // T sets its value to the size of the init list +    } +    { +        Opt opt; +        opt.emplace({1, 2, 3, 4, 5}, 6); +        assert(static_cast<bool>(opt) == true); +        assert(*opt == T(5)); // T sets its value to the size of the init list +    } +} + +template <class T> +void test_on_test_type() { + +    T::reset(); +    optional<T> opt; +    assert(T::alive == 0); +    { +        T::reset_constructors(); +        opt.emplace(); +        assert(T::alive == 1); +        assert(T::constructed == 1); +        assert(T::default_constructed == 1); +        assert(T::destroyed == 0); +        assert(static_cast<bool>(opt) == true); +        assert(*opt == T()); +    } +    { +        T::reset_constructors(); +        opt.emplace(); +        assert(T::alive == 1); +        assert(T::constructed == 1); +        assert(T::default_constructed == 1); +        assert(T::destroyed == 1); +        assert(static_cast<bool>(opt) == true); +        assert(*opt == T()); +    } +    { +        T::reset_constructors(); +        opt.emplace(101); +        assert(T::alive == 1); +        assert(T::constructed == 1); +        assert(T::value_constructed == 1); +        assert(T::destroyed == 1); +        assert(static_cast<bool>(opt) == true); +        assert(*opt == T(101)); +    } +    { +        T::reset_constructors(); +        opt.emplace(-10, 99); +        assert(T::alive == 1); +        assert(T::constructed == 1); +        assert(T::value_constructed == 1); +        assert(T::destroyed == 1); +        assert(static_cast<bool>(opt) == true); +        assert(*opt == T(-10, 99)); +    } +    { +        T::reset_constructors(); +        opt.emplace(-10, 99); +        assert(T::alive == 1); +        assert(T::constructed == 1); +        assert(T::value_constructed == 1); +        assert(T::destroyed == 1); +        assert(static_cast<bool>(opt) == true); +        assert(*opt == T(-10, 99)); +    } +    { +        T::reset_constructors(); +        opt.emplace({-10, 99, 42, 1}); +        assert(T::alive == 1); +        assert(T::constructed == 1); +        assert(T::value_constructed == 1); +        assert(T::destroyed == 1); +        assert(static_cast<bool>(opt) == true); +        assert(*opt == T(4)); // size of the initializer list +    } +    { +        T::reset_constructors(); +        opt.emplace({-10, 99, 42, 1}, 42); +        assert(T::alive == 1); +        assert(T::constructed == 1); +        assert(T::value_constructed == 1); +        assert(T::destroyed == 1); +        assert(static_cast<bool>(opt) == true); +        assert(*opt == T(4)); // size of the initializer list +    } +} + + + +int main() +{ +    { +        test_on_test_type<TestTypes::TestType>(); +        test_on_test_type<ExplicitTestTypes::TestType>(); +    } +    { +        using T = int; +        test_one_arg<T>(); +        test_one_arg<const T>(); +    } +    { +        using T = ConstexprTestTypes::TestType; +        test_multi_arg<T>(); +    } +    { +        using T = ExplicitConstexprTestTypes::TestType; +        test_multi_arg<T>(); +    } +    { +        using T = TrivialTestTypes::TestType; +        test_multi_arg<T>(); +    } +    { +        using T = ExplicitTrivialTestTypes::TestType; +        test_multi_arg<T>(); +    } +    { +        optional<const int> opt; +        opt.emplace(42); +        assert(*opt == 42); +        opt.emplace(); +        assert(*opt == 0); +    } +#ifndef TEST_HAS_NO_EXCEPTIONS +    Y::dtor_called = false; +    { +        Y y; +        optional<Y> opt(y); +        try +        { +            assert(static_cast<bool>(opt) == true); +            assert(Y::dtor_called == false); +            opt.emplace(1); +        } +        catch (int i) +        { +            assert(i == 6); +            assert(static_cast<bool>(opt) == false); +            assert(Y::dtor_called == true); +        } +    } +#endif +} diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.assign/emplace_initializer_list.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.assign/emplace_initializer_list.pass.cpp new file mode 100644 index 00000000000..1c3c69a7030 --- /dev/null +++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.assign/emplace_initializer_list.pass.cpp @@ -0,0 +1,113 @@ +//===----------------------------------------------------------------------===// +// +//                     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> +//   void optional<T>::emplace(initializer_list<U> il, Args&&... args); + +#include <optional> +#include <type_traits> +#include <cassert> +#include <vector> + +#include "test_macros.h" + +using std::optional; + +class X +{ +    int i_; +    int j_ = 0; +public: +    static bool dtor_called; +    constexpr X() : i_(0) {} +    constexpr X(int i) : i_(i) {} +    constexpr X(std::initializer_list<int> il) : i_(il.begin()[0]), j_(il.begin()[1]) {} +    ~X() {dtor_called = true;} + +    friend constexpr bool operator==(const X& x, const X& y) +        {return x.i_ == y.i_ && x.j_ == y.j_;} +}; + +bool X::dtor_called = false; + +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: +    static bool dtor_called; +    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);} +    ~Z() {dtor_called = true;} + +    friend bool operator==(const Z& x, const Z& y) +        {return x.i_ == y.i_ && x.j_ == y.j_;} +}; + +bool Z::dtor_called = false; + +int main() +{ +    { +        X x; +        optional<X> opt(x); +        assert(X::dtor_called == false); +        opt.emplace({1, 2}); +        assert(X::dtor_called == true); +        assert(*opt == X({1, 2})); +    } +    { +        optional<std::vector<int>> opt; +        opt.emplace({1, 2, 3}, std::allocator<int>()); +        assert(static_cast<bool>(opt) == true); +        assert(*opt == std::vector<int>({1, 2, 3})); +    } +    { +        optional<Y> opt; +        opt.emplace({1, 2}); +        assert(static_cast<bool>(opt) == true); +        assert(*opt == Y({1, 2})); +    } +#ifndef TEST_HAS_NO_EXCEPTIONS +    { +        Z z; +        optional<Z> opt(z); +        try +        { +            assert(static_cast<bool>(opt) == true); +            assert(Z::dtor_called == false); +            opt.emplace({1, 2}); +        } +        catch (int i) +        { +            assert(i == 6); +            assert(static_cast<bool>(opt) == false); +            assert(Z::dtor_called == true); +        } +    } +#endif +} diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.assign/move.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.assign/move.pass.cpp new file mode 100644 index 00000000000..3ba261b5246 --- /dev/null +++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.assign/move.pass.cpp @@ -0,0 +1,174 @@ +//===----------------------------------------------------------------------===// +// +//                     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<T>& operator=(optional<T>&& rhs) +//     noexcept(is_nothrow_move_assignable<T>::value && +//              is_nothrow_move_constructible<T>::value); + +#include <optional> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "archetypes.hpp" + +using std::optional; + +struct X +{ +    static bool throw_now; +    static int alive; + +    X() { ++alive; } +    X(X&&) +    { +        if (throw_now) +            TEST_THROW(6); +        ++alive; +    } + +    X& operator=(X&&) +    { +        if (throw_now) +            TEST_THROW(42); +        return *this; +    } + +    ~X() { assert(alive > 0); --alive; } +}; + +struct Y {}; + +bool X::throw_now = false; +int X::alive = 0; + +int main() +{ +    { +        static_assert(std::is_nothrow_move_assignable<optional<int>>::value, ""); +        optional<int> opt; +        constexpr optional<int> opt2; +        opt = std::move(opt2); +        static_assert(static_cast<bool>(opt2) == false, ""); +        assert(static_cast<bool>(opt) == static_cast<bool>(opt2)); +    } +    { +        optional<int> opt; +        constexpr optional<int> opt2(2); +        opt = std::move(opt2); +        static_assert(static_cast<bool>(opt2) == true, ""); +        static_assert(*opt2 == 2, ""); +        assert(static_cast<bool>(opt) == static_cast<bool>(opt2)); +        assert(*opt == *opt2); +    } +    { +        optional<int> opt(3); +        constexpr optional<int> opt2; +        opt = std::move(opt2); +        static_assert(static_cast<bool>(opt2) == false, ""); +        assert(static_cast<bool>(opt) == static_cast<bool>(opt2)); +    } +    { +        using T = TestTypes::TestType; +        T::reset(); +        optional<T> opt(3); +        optional<T> opt2; +        assert(T::alive == 1); +        opt = std::move(opt2); +        assert(T::alive == 0); +        assert(static_cast<bool>(opt2) == false); +        assert(static_cast<bool>(opt) == static_cast<bool>(opt2)); +    } +    { +        optional<int> opt(3); +        constexpr optional<int> opt2(2); +        opt = std::move(opt2); +        static_assert(static_cast<bool>(opt2) == true, ""); +        static_assert(*opt2 == 2, ""); +        assert(static_cast<bool>(opt) == static_cast<bool>(opt2)); +        assert(*opt == *opt2); +    } +#ifndef TEST_HAS_NO_EXCEPTIONS +    { +        static_assert(!std::is_nothrow_move_assignable<optional<X>>::value, ""); +        X::alive = 0; +        X::throw_now = false; +        optional<X> opt; +        optional<X> opt2(X{}); +        assert(X::alive == 1); +        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); +        } +        assert(X::alive == 1); +    } +    assert(X::alive == 0); +    { +        static_assert(!std::is_nothrow_move_assignable<optional<X>>::value, ""); +        X::throw_now = false; +        optional<X> opt(X{}); +        optional<X> opt2(X{}); +        assert(X::alive == 2); +        assert(static_cast<bool>(opt2) == true); +        try +        { +            X::throw_now = true; +            opt = std::move(opt2); +            assert(false); +        } +        catch (int i) +        { +            assert(i == 42); +            assert(static_cast<bool>(opt) == true); +        } +        assert(X::alive == 2); +    } +    assert(X::alive == 0); +#endif // TEST_HAS_NO_EXCEPTIONS +    { +        static_assert(std::is_nothrow_move_assignable<optional<Y>>::value, ""); +    } +    { +        struct ThrowsMove { +          ThrowsMove() noexcept {} +          ThrowsMove(ThrowsMove const&) noexcept {} +          ThrowsMove(ThrowsMove &&) noexcept(false) {} +          ThrowsMove& operator=(ThrowsMove const&) noexcept { return *this; } +          ThrowsMove& operator=(ThrowsMove &&) noexcept { return *this; } +        }; +        static_assert(!std::is_nothrow_move_assignable<optional<ThrowsMove>>::value, ""); +        struct ThrowsMoveAssign { +          ThrowsMoveAssign() noexcept {} +          ThrowsMoveAssign(ThrowsMoveAssign const&) noexcept {} +          ThrowsMoveAssign(ThrowsMoveAssign &&) noexcept {} +          ThrowsMoveAssign& operator=(ThrowsMoveAssign const&) noexcept { return *this; } +          ThrowsMoveAssign& operator=(ThrowsMoveAssign &&) noexcept(false) { return *this; } +        }; +        static_assert(!std::is_nothrow_move_assignable<optional<ThrowsMoveAssign>>::value, ""); +        struct NoThrowMove { +          NoThrowMove() noexcept(false) {} +          NoThrowMove(NoThrowMove const&) noexcept(false) {} +          NoThrowMove(NoThrowMove &&) noexcept {} +          NoThrowMove& operator=(NoThrowMove const&) noexcept { return *this; } +          NoThrowMove& operator=(NoThrowMove&&) noexcept { return *this; } +        }; +        static_assert(std::is_nothrow_move_assignable<optional<NoThrowMove>>::value, ""); +    } +} diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.assign/nullopt_t.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.assign/nullopt_t.pass.cpp new file mode 100644 index 00000000000..991f4334304 --- /dev/null +++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.assign/nullopt_t.pass.cpp @@ -0,0 +1,67 @@ +//===----------------------------------------------------------------------===// +// +//                     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<T>& operator=(nullopt_t) noexcept; + +#include <optional> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "archetypes.hpp" + +using std::optional; +using std::nullopt_t; +using std::nullopt; + +int main() +{ +    { +        optional<int> opt; +        static_assert(noexcept(opt = nullopt) == true, ""); +        opt = nullopt; +        assert(static_cast<bool>(opt) == false); +    } +    { +        optional<int> opt(3); +        opt = nullopt; +        assert(static_cast<bool>(opt) == false); +    } +    using TT = TestTypes::TestType; +    TT::reset(); +    { +        optional<TT> opt; +        static_assert(noexcept(opt = nullopt) == true, ""); +        assert(TT::destroyed == 0); +        opt = nullopt; +        assert(TT::constructed == 0); +        assert(TT::alive == 0); +        assert(TT::destroyed == 0); +        assert(static_cast<bool>(opt) == false); +    } +    assert(TT::alive == 0); +    assert(TT::destroyed == 0); +    TT::reset(); +    { +        optional<TT> opt(42); +        assert(TT::destroyed == 0); +        TT::reset_constructors(); +        opt = nullopt; +        assert(TT::constructed == 0); +        assert(TT::alive == 0); +        assert(TT::destroyed == 1); +        assert(static_cast<bool>(opt) == false); +    } +    assert(TT::alive == 0); +    assert(TT::destroyed == 1); +    TT::reset(); +} diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.assign/optional_U.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.assign/optional_U.pass.cpp new file mode 100644 index 00000000000..db7fc19bfb1 --- /dev/null +++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.assign/optional_U.pass.cpp @@ -0,0 +1,268 @@ +//===----------------------------------------------------------------------===// +// +//                     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 +} 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..4830fe90d67 --- /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(); +}
\ No newline at end of file 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 +} diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.dtor/dtor.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.dtor/dtor.pass.cpp new file mode 100644 index 00000000000..5132c9a73d0 --- /dev/null +++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.dtor/dtor.pass.cpp @@ -0,0 +1,68 @@ +//===----------------------------------------------------------------------===// +// +//                     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(); + +#include <optional> +#include <type_traits> +#include <cassert> + +using std::optional; + +struct PODType { +  int value; +  int value2; +}; + +class X +{ +public: +    static bool dtor_called; +    X() = default; +    ~X() {dtor_called = true;} +}; + +bool X::dtor_called = false; + +int main() +{ +    { +        typedef int T; +        static_assert(std::is_trivially_destructible<T>::value, ""); +        static_assert(std::is_trivially_destructible<optional<T>>::value, ""); +        static_assert(std::is_literal_type<optional<T>>::value, ""); +    } +    { +        typedef double T; +        static_assert(std::is_trivially_destructible<T>::value, ""); +        static_assert(std::is_trivially_destructible<optional<T>>::value, ""); +        static_assert(std::is_literal_type<optional<T>>::value, ""); +    } +    { +        typedef PODType T; +        static_assert(std::is_trivially_destructible<T>::value, ""); +        static_assert(std::is_trivially_destructible<optional<T>>::value, ""); +        static_assert(std::is_literal_type<optional<T>>::value, ""); +    } +    { +        typedef X T; +        static_assert(!std::is_trivially_destructible<T>::value, ""); +        static_assert(!std::is_trivially_destructible<optional<T>>::value, ""); +        static_assert(!std::is_literal_type<optional<T>>::value, ""); +        { +            X x; +            optional<X> opt{x}; +            assert(X::dtor_called == false); +        } +        assert(X::dtor_called == true); +    } +} diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.mod/reset.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.mod/reset.pass.cpp new file mode 100644 index 00000000000..cee73da849b --- /dev/null +++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.mod/reset.pass.cpp @@ -0,0 +1,61 @@ +//===----------------------------------------------------------------------===// +// +//                     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> + +// void reset() noexcept; + +#include <optional> +#include <type_traits> +#include <cassert> + +using std::optional; + +struct X +{ +    static bool dtor_called; +    ~X() {dtor_called = true;} +}; + +bool X::dtor_called = false; + +int main() +{ +    { +        optional<int> opt; +        static_assert(noexcept(opt.reset()) == true, ""); +        opt.reset(); +        assert(static_cast<bool>(opt) == false); +    } +    { +        optional<int> opt(3); +        opt.reset(); +        assert(static_cast<bool>(opt) == false); +    } +    { +        optional<X> opt; +        static_assert(noexcept(opt.reset()) == true, ""); +        assert(X::dtor_called == false); +        opt.reset(); +        assert(X::dtor_called == false); +        assert(static_cast<bool>(opt) == false); +    } +    assert(X::dtor_called == false); // TRANSITION, Clang/C2 VSO#239997 +    { +        optional<X> opt(X{}); +        X::dtor_called = false; +        opt.reset(); +        assert(X::dtor_called == true); +        assert(static_cast<bool>(opt) == false); +        X::dtor_called = false; +    } +    assert(X::dtor_called == false); // TRANSITION, Clang/C2 VSO#239997 +} diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/bool.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/bool.pass.cpp new file mode 100644 index 00000000000..9820d50f632 --- /dev/null +++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/bool.pass.cpp @@ -0,0 +1,37 @@ +//===----------------------------------------------------------------------===// +// +//                     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 explicit optional<T>::operator bool() const noexcept; + +#include <optional> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" + +int main() +{ +    using std::optional; +    { +        const optional<int> opt; ((void)opt); +        ASSERT_NOEXCEPT(bool(opt)); +        static_assert(!std::is_convertible<optional<int>, bool>::value, ""); +    } +    { +        constexpr optional<int> opt; +        static_assert(!opt, ""); +    } +    { +        constexpr optional<int> opt(0); +        static_assert(opt, ""); +    } +} diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/dereference.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/dereference.pass.cpp new file mode 100644 index 00000000000..4087cfdf104 --- /dev/null +++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/dereference.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 T& optional<T>::operator*() &; + +#ifdef _LIBCPP_DEBUG +#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0)) +#endif + +#include <optional> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" + +using std::optional; + +struct X +{ +    constexpr int test() const& {return 3;} +    int test() & {return 4;} +    constexpr int test() const&& {return 5;} +    int test() && {return 6;} +}; + +struct Y +{ +    constexpr int test() {return 7;} +}; + +constexpr int +test() +{ +    optional<Y> opt{Y{}}; +    return (*opt).test(); +} + +int main() +{ +    { +        optional<X> opt; ((void)opt); +        ASSERT_SAME_TYPE(decltype(*opt), X&); +        // ASSERT_NOT_NOEXCEPT(*opt); +        // FIXME: This assertion fails with GCC because it can see that +        // (A) operator*() is constexpr, and +        // (B) there is no path through the function that throws. +        // It's arguable if this is the correct behavior for the noexcept +        // operator. +        // Regardless this function should still be noexcept(false) because +        // it has a narrow contract. +    } +    { +        optional<X> opt(X{}); +        assert((*opt).test() == 4); +    } +    static_assert(test() == 7, ""); +#ifdef _LIBCPP_DEBUG +    { +        optional<X> opt; +        assert((*opt).test() == 3); +        assert(false); +    } +#endif  // _LIBCPP_DEBUG +} diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/dereference_const.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/dereference_const.pass.cpp new file mode 100644 index 00000000000..0779c9047c9 --- /dev/null +++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/dereference_const.pass.cpp @@ -0,0 +1,69 @@ +//===----------------------------------------------------------------------===// +// +//                     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 const T& optional<T>::operator*() const &; + +#ifdef _LIBCPP_DEBUG +#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0)) +#endif + +#include <optional> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" + +using std::optional; + +struct X +{ +    constexpr int test() const& {return 3;} +    int test() & {return 4;} +    constexpr int test() const&& {return 5;} +    int test() && {return 6;} +}; + +struct Y +{ +    int test() const {return 2;} +}; + +int main() +{ +    { +        const optional<X> opt; ((void)opt); +        ASSERT_SAME_TYPE(decltype(*opt), X const&); +        // ASSERT_NOT_NOEXCEPT(*opt); +        // FIXME: This assertion fails with GCC because it can see that +        // (A) operator*() is constexpr, and +        // (B) there is no path through the function that throws. +        // It's arguable if this is the correct behavior for the noexcept +        // operator. +        // Regardless this function should still be noexcept(false) because +        // it has a narrow contract. +    } +    { +        constexpr optional<X> opt(X{}); +        static_assert((*opt).test() == 3, ""); +    } +    { +        constexpr optional<Y> opt(Y{}); +        assert((*opt).test() == 2); +    } +#ifdef _LIBCPP_DEBUG +    { +        const optional<X> opt; +        assert((*opt).test() == 3); +        assert(false); +    } +#endif  // _LIBCPP_DEBUG +} diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/dereference_const_rvalue.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/dereference_const_rvalue.pass.cpp new file mode 100644 index 00000000000..78fd992952c --- /dev/null +++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/dereference_const_rvalue.pass.cpp @@ -0,0 +1,69 @@ +//===----------------------------------------------------------------------===// +// +//                     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 T&& optional<T>::operator*() const &&; + +#ifdef _LIBCPP_DEBUG +#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0)) +#endif + +#include <optional> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" + +using std::optional; + +struct X +{ +    constexpr int test() const& {return 3;} +    int test() & {return 4;} +    constexpr int test() const&& {return 5;} +    int test() && {return 6;} +}; + +struct Y +{ +    int test() const && {return 2;} +}; + +int main() +{ +    { +        const optional<X> opt; ((void)opt); +        ASSERT_SAME_TYPE(decltype(*std::move(opt)), X const &&); +        // ASSERT_NOT_NOEXCEPT(*std::move(opt)); +        // FIXME: This assertion fails with GCC because it can see that +        // (A) operator*() is constexpr, and +        // (B) there is no path through the function that throws. +        // It's arguable if this is the correct behavior for the noexcept +        // operator. +        // Regardless this function should still be noexcept(false) because +        // it has a narrow contract. +    } +    { +        constexpr optional<X> opt(X{}); +        static_assert((*std::move(opt)).test() == 5, ""); +    } +    { +        constexpr optional<Y> opt(Y{}); +        assert((*std::move(opt)).test() == 2); +    } +#ifdef _LIBCPP_DEBUG +    { +        optional<X> opt; +        assert((*std::move(opt)).test() == 5); +        assert(false); +    } +#endif  // _LIBCPP_DEBUG +} diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/dereference_rvalue.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/dereference_rvalue.pass.cpp new file mode 100644 index 00000000000..2924123234a --- /dev/null +++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/dereference_rvalue.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 T&& optional<T>::operator*() &&; + +#ifdef _LIBCPP_DEBUG +#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0)) +#endif + +#include <optional> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" + +using std::optional; + +struct X +{ +    constexpr int test() const& {return 3;} +    int test() & {return 4;} +    constexpr int test() const&& {return 5;} +    int test() && {return 6;} +}; + +struct Y +{ +    constexpr int test() && {return 7;} +}; + +constexpr int +test() +{ +    optional<Y> opt{Y{}}; +    return (*std::move(opt)).test(); +} + +int main() +{ +    { +        optional<X> opt; ((void)opt); +        ASSERT_SAME_TYPE(decltype(*std::move(opt)), X&&); +        // ASSERT_NOT_NOEXCEPT(*std::move(opt)); +        // FIXME: This assertion fails with GCC because it can see that +        // (A) operator*() is constexpr, and +        // (B) there is no path through the function that throws. +        // It's arguable if this is the correct behavior for the noexcept +        // operator. +        // Regardless this function should still be noexcept(false) because +        // it has a narrow contract. +    } +    { +        optional<X> opt(X{}); +        assert((*std::move(opt)).test() == 6); +    } +    static_assert(test() == 7, ""); +#ifdef _LIBCPP_DEBUG +    { +        optional<X> opt; +        assert((*std::move(opt)).test() == 3); +        assert(false); +    } +#endif  // _LIBCPP_DEBUG +} diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/has_value.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/has_value.pass.cpp new file mode 100644 index 00000000000..5df295d01e2 --- /dev/null +++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/has_value.pass.cpp @@ -0,0 +1,37 @@ +//===----------------------------------------------------------------------===// +// +//                     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 bool optional<T>::has_value() const noexcept; + +#include <optional> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" + +int main() +{ +    using std::optional; +    { +        const optional<int> opt; ((void)opt); +        ASSERT_NOEXCEPT(opt.has_value()); +        ASSERT_SAME_TYPE(decltype(opt.has_value()), bool); +    } +    { +        constexpr optional<int> opt; +        static_assert(!opt.has_value(), ""); +    } +    { +        constexpr optional<int> opt(0); +        static_assert(opt.has_value(), ""); +    } +} diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/op_arrow.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/op_arrow.pass.cpp new file mode 100644 index 00000000000..2f1648c48c8 --- /dev/null +++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/op_arrow.pass.cpp @@ -0,0 +1,72 @@ +//===----------------------------------------------------------------------===// +// +//                     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 T* optional<T>::operator->(); + +#ifdef _LIBCPP_DEBUG +#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0)) +#endif + +#include <optional> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" + +using std::optional; + +struct X +{ +    int test() noexcept {return 3;} +}; + +struct Y +{ +    constexpr int test() {return 3;} +}; + +constexpr int +test() +{ +    optional<Y> opt{Y{}}; +    return opt->test(); +} + +int main() +{ +    { +        std::optional<X> opt; ((void)opt); +        ASSERT_SAME_TYPE(decltype(opt.operator->()), X*); +        // ASSERT_NOT_NOEXCEPT(opt.operator->()); +        // FIXME: This assertion fails with GCC because it can see that +        // (A) operator->() is constexpr, and +        // (B) there is no path through the function that throws. +        // It's arguable if this is the correct behavior for the noexcept +        // operator. +        // Regardless this function should still be noexcept(false) because +        // it has a narrow contract. +    } +    { +        optional<X> opt(X{}); +        assert(opt->test() == 3); +    } +    { +        static_assert(test() == 3, ""); +    } +#ifdef _LIBCPP_DEBUG +    { +        optional<X> opt; +        assert(opt->test() == 3); +        assert(false); +    } +#endif  // _LIBCPP_DEBUG +} diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/op_arrow_const.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/op_arrow_const.pass.cpp new file mode 100644 index 00000000000..887edc7114e --- /dev/null +++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/op_arrow_const.pass.cpp @@ -0,0 +1,76 @@ +//===----------------------------------------------------------------------===// +// +//                     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 const T* optional<T>::operator->() const; + +#ifdef _LIBCPP_DEBUG +#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0)) +#endif + +#include <optional> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" + +using std::optional; + +struct X +{ +    constexpr int test() const {return 3;} +}; + +struct Y +{ +    int test() const noexcept {return 2;} +}; + +struct Z +{ +    const Z* operator&() const; +    constexpr int test() const {return 1;} +}; + +int main() +{ +    { +        const std::optional<X> opt; ((void)opt); +        ASSERT_SAME_TYPE(decltype(opt.operator->()), X const*); +        // ASSERT_NOT_NOEXCEPT(opt.operator->()); +        // FIXME: This assertion fails with GCC because it can see that +        // (A) operator->() is constexpr, and +        // (B) there is no path through the function that throws. +        // It's arguable if this is the correct behavior for the noexcept +        // operator. +        // Regardless this function should still be noexcept(false) because +        // it has a narrow contract. +    } +    { +        constexpr optional<X> opt(X{}); +        static_assert(opt->test() == 3, ""); +    } +    { +        constexpr optional<Y> opt(Y{}); +        assert(opt->test() == 2); +    } +    { +        constexpr optional<Z> opt(Z{}); +        static_assert(opt->test() == 1, ""); +    } +#ifdef _LIBCPP_DEBUG +    { +        const optional<X> opt; +        assert(opt->test() == 3); +        assert(false); +    } +#endif  // _LIBCPP_DEBUG +} diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/value.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/value.pass.cpp new file mode 100644 index 00000000000..516a79db5f6 --- /dev/null +++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/value.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 T& optional<T>::value() &; + +#include <optional> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" + +using std::optional; +using std::bad_optional_access; + +struct X +{ +    X() = default; +    X(const X&) = delete; +    constexpr int test() const & {return 3;} +    int test() & {return 4;} +    constexpr int test() const && {return 5;} +    int test() && {return 6;} +}; + +struct Y +{ +    constexpr int test() & {return 7;} +}; + +constexpr int +test() +{ +    optional<Y> opt{Y{}}; +    return opt.value().test(); +} + + +int main() +{ +    { +        optional<X> opt; ((void)opt); +        ASSERT_NOT_NOEXCEPT(opt.value()); +        ASSERT_SAME_TYPE(decltype(opt.value()), X&); +    } +    { +        optional<X> opt; +        opt.emplace(); +        assert(opt.value().test() == 4); +    } +#ifndef TEST_HAS_NO_EXCEPTIONS +    { +        optional<X> opt; +        try +        { +            opt.value(); +            assert(false); +        } +        catch (const bad_optional_access&) +        { +        } +    } +#endif +    static_assert(test() == 7, ""); +} diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/value_const.fail.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/value_const.fail.cpp new file mode 100644 index 00000000000..6076c509fa4 --- /dev/null +++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/value_const.fail.cpp @@ -0,0 +1,33 @@ +//===----------------------------------------------------------------------===// +// +//                     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 const T& optional<T>::value() const &; + +#include <optional> +#include <type_traits> +#include <cassert> + +using std::optional; + +struct X +{ +    constexpr int test() const {return 3;} +    int test() {return 4;} +}; + +int main() +{ +    { +        constexpr optional<X> opt; +        static_assert(opt.value().test() == 3, ""); +    } +} diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/value_const.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/value_const.pass.cpp new file mode 100644 index 00000000000..d4038e4efa6 --- /dev/null +++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/value_const.pass.cpp @@ -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. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11, c++14 +// <optional> + +// constexpr const T& optional<T>::value() const &; + +#include <optional> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" + +using std::optional; +using std::in_place_t; +using std::in_place; +using std::bad_optional_access; + +struct X +{ +    X() = default; +    X(const X&) = delete; +    constexpr int test() const & {return 3;} +    int test() & {return 4;} +    constexpr int test() const && {return 5;} +    int test() && {return 6;} +}; + +int main() +{ +    { +        const optional<X> opt; ((void)opt); +        ASSERT_NOT_NOEXCEPT(opt.value()); +        ASSERT_SAME_TYPE(decltype(opt.value()), X const&); +    } +    { +        constexpr optional<X> opt(in_place); +        static_assert(opt.value().test() == 3, ""); +    } +    { +        const optional<X> opt(in_place); +        assert(opt.value().test() == 3); +    } +#ifndef TEST_HAS_NO_EXCEPTIONS +    { +        const optional<X> opt; +        try +        { +            opt.value(); +            assert(false); +        } +        catch (const bad_optional_access&) +        { +        } +    } +#endif +} diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/value_const_rvalue.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/value_const_rvalue.pass.cpp new file mode 100644 index 00000000000..e189d3af688 --- /dev/null +++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/value_const_rvalue.pass.cpp @@ -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. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11, c++14 +// <optional> + +// constexpr const T& optional<T>::value() const &&; + +#include <optional> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" + +using std::optional; +using std::in_place_t; +using std::in_place; +using std::bad_optional_access; + +struct X +{ +    X() = default; +    X(const X&) = delete; +    constexpr int test() const & {return 3;} +    int test() & {return 4;} +    constexpr int test() const && {return 5;} +    int test() && {return 6;} +}; + +int main() +{ +    { +        const optional<X> opt; ((void)opt); +        ASSERT_NOT_NOEXCEPT(std::move(opt).value()); +        ASSERT_SAME_TYPE(decltype(std::move(opt).value()), X const&&); +    } +    { +        constexpr optional<X> opt(in_place); +        static_assert(std::move(opt).value().test() == 5, ""); +    } +    { +        const optional<X> opt(in_place); +        assert(std::move(opt).value().test() == 5); +    } +#ifndef TEST_HAS_NO_EXCEPTIONS +    { +        const optional<X> opt; +        try +        { +            std::move(opt).value(); +            assert(false); +        } +        catch (const bad_optional_access&) +        { +        } +    } +#endif +} diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/value_or.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/value_or.pass.cpp new file mode 100644 index 00000000000..c219e970471 --- /dev/null +++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/value_or.pass.cpp @@ -0,0 +1,68 @@ +//===----------------------------------------------------------------------===// +// +//                     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> T optional<T>::value_or(U&& v) &&; + +#include <optional> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" + +using std::optional; +using std::in_place_t; +using std::in_place; + +struct Y +{ +    int i_; + +    Y(int i) : i_(i) {} +}; + +struct X +{ +    int i_; + +    X(int i) : i_(i) {} +    X(X&& x) : i_(x.i_) {x.i_ = 0;} +    X(const Y& y) : i_(y.i_) {} +    X(Y&& y) : i_(y.i_+1) {} +    friend constexpr bool operator==(const X& x, const X& y) +        {return x.i_ == y.i_;} +}; + +int main() +{ +    { +        optional<X> opt(in_place, 2); +        Y y(3); +        assert(std::move(opt).value_or(y) == 2); +        assert(*opt == 0); +    } +    { +        optional<X> opt(in_place, 2); +        assert(std::move(opt).value_or(Y(3)) == 2); +        assert(*opt == 0); +    } +    { +        optional<X> opt; +        Y y(3); +        assert(std::move(opt).value_or(y) == 3); +        assert(!opt); +    } +    { +        optional<X> opt; +        assert(std::move(opt).value_or(Y(3)) == 4); +        assert(!opt); +    } +} diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/value_or_const.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/value_or_const.pass.cpp new file mode 100644 index 00000000000..36a85811ba4 --- /dev/null +++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/value_or_const.pass.cpp @@ -0,0 +1,77 @@ +//===----------------------------------------------------------------------===// +// +//                     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 T optional<T>::value_or(U&& v) const&; + +#include <optional> +#include <type_traits> +#include <cassert> + +using std::optional; + +struct Y +{ +    int i_; + +    constexpr Y(int i) : i_(i) {} +}; + +struct X +{ +    int i_; + +    constexpr X(int i) : i_(i) {} +    constexpr X(const Y& y) : i_(y.i_) {} +    constexpr X(Y&& y) : i_(y.i_+1) {} +    friend constexpr bool operator==(const X& x, const X& y) +        {return x.i_ == y.i_;} +}; + +int main() +{ +    { +        constexpr optional<X> opt(2); +        constexpr Y y(3); +        static_assert(opt.value_or(y) == 2, ""); +    } +    { +        constexpr optional<X> opt(2); +        static_assert(opt.value_or(Y(3)) == 2, ""); +    } +    { +        constexpr optional<X> opt; +        constexpr Y y(3); +        static_assert(opt.value_or(y) == 3, ""); +    } +    { +        constexpr optional<X> opt; +        static_assert(opt.value_or(Y(3)) == 4, ""); +    } +    { +        const optional<X> opt(2); +        const Y y(3); +        assert(opt.value_or(y) == 2); +    } +    { +        const optional<X> opt(2); +        assert(opt.value_or(Y(3)) == 2); +    } +    { +        const optional<X> opt; +        const Y y(3); +        assert(opt.value_or(y) == 3); +    } +    { +        const optional<X> opt; +        assert(opt.value_or(Y(3)) == 4); +    } +} diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/value_rvalue.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/value_rvalue.pass.cpp new file mode 100644 index 00000000000..2ef485b7fe5 --- /dev/null +++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.observe/value_rvalue.pass.cpp @@ -0,0 +1,72 @@ +//===----------------------------------------------------------------------===// +// +//                     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 T& optional<T>::value() &&; + +#include <optional> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" + +using std::optional; +using std::bad_optional_access; + +struct X +{ +    X() = default; +    X(const X&) = delete; +    constexpr int test() const & {return 3;} +    int test() & {return 4;} +    constexpr int test() const && {return 5;} +    int test() && {return 6;} +}; + +struct Y +{ +    constexpr int test() && {return 7;} +}; + +constexpr int +test() +{ +    optional<Y> opt{Y{}}; +    return std::move(opt).value().test(); +} + +int main() +{ +    { +        optional<X> opt; ((void)opt); +        ASSERT_NOT_NOEXCEPT(std::move(opt).value()); +        ASSERT_SAME_TYPE(decltype(std::move(opt).value()), X&&); +    } +    { +        optional<X> opt; +        opt.emplace(); +        assert(std::move(opt).value().test() == 6); +    } +#ifndef TEST_HAS_NO_EXCEPTIONS +    { +        optional<X> opt; +        try +        { +            std::move(opt).value(); +            assert(false); +        } +        catch (const bad_optional_access&) +        { +        } +    } +#endif +    static_assert(test() == 7, ""); +} diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.swap/swap.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.swap/swap.pass.cpp new file mode 100644 index 00000000000..6bbb880b6ec --- /dev/null +++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.swap/swap.pass.cpp @@ -0,0 +1,345 @@ +//===----------------------------------------------------------------------===// +// +//                     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> + +// void swap(optional&) +//     noexcept(is_nothrow_move_constructible<T>::value && +//              is_nothrow_swappable<T>::value) + +#include <optional> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "archetypes.hpp" + +using std::optional; + +class X +{ +    int i_; +public: +    static unsigned dtor_called; +    X(int i) : i_(i) {} +    X(X&& x) = default; +    X& operator=(X&&) = default; +    ~X() {++dtor_called;} + +    friend bool operator==(const X& x, const X& y) {return x.i_ == y.i_;} +}; + +unsigned X::dtor_called = 0; + +class Y +{ +    int i_; +public: +    static unsigned dtor_called; +    Y(int i) : i_(i) {} +    Y(Y&&) = default; +    ~Y() {++dtor_called;} + +    friend constexpr bool operator==(const Y& x, const Y& y) {return x.i_ == y.i_;} +    friend void swap(Y& x, Y& y) {std::swap(x.i_, y.i_);} +}; + +unsigned Y::dtor_called = 0; + +class Z +{ +    int i_; +public: +    Z(int i) : i_(i) {} +    Z(Z&&) {TEST_THROW(7);} + +    friend constexpr bool operator==(const Z& x, const Z& y) {return x.i_ == y.i_;} +    friend void swap(Z& x, Z& y) {TEST_THROW(6);} +}; + +template <class T, class = decltype(std::declval<T&>().swap(std::declval<T&>()))> +constexpr bool has_swap(int) { return true; } +template <class T> +constexpr bool has_swap(long) { return false; } +template <class T> +constexpr bool has_swap() {return has_swap<T>(0); } + +struct NonSwappable { +}; +void swap(NonSwappable&, NonSwappable&) = delete; + +void test_swap_sfinae() { +    using std::optional; +    { +        using T = TestTypes::TestType; +        static_assert(has_swap<optional<T>>(), ""); +    } +    { +        using T = TestTypes::MoveOnly; +        static_assert(has_swap<optional<T>>(), ""); +    } +    { +        using T = TestTypes::Copyable; +        static_assert(has_swap<optional<T>>(), ""); +    } +    { +        using T = TestTypes::NoCtors; +        static_assert(!has_swap<optional<T>>(), ""); +    } +    { +        using T = TestTypes::CopyOnly; +        static_assert(!has_swap<optional<T>>(), ""); +    } +    { +        using T = NonSwappable; +        static_assert(!has_swap<optional<T>>(), ""); +    } +} + +int main() +{ +    test_swap_sfinae(); +    { +        optional<int> opt1; +        optional<int> opt2; +        static_assert(noexcept(opt1.swap(opt2)) == true, ""); +        assert(static_cast<bool>(opt1) == false); +        assert(static_cast<bool>(opt2) == false); +        opt1.swap(opt2); +        assert(static_cast<bool>(opt1) == false); +        assert(static_cast<bool>(opt2) == false); +    } +    { +        optional<int> opt1(1); +        optional<int> opt2; +        static_assert(noexcept(opt1.swap(opt2)) == true, ""); +        assert(static_cast<bool>(opt1) == true); +        assert(*opt1 == 1); +        assert(static_cast<bool>(opt2) == false); +        opt1.swap(opt2); +        assert(static_cast<bool>(opt1) == false); +        assert(static_cast<bool>(opt2) == true); +        assert(*opt2 == 1); +    } +    { +        optional<int> opt1; +        optional<int> opt2(2); +        static_assert(noexcept(opt1.swap(opt2)) == true, ""); +        assert(static_cast<bool>(opt1) == false); +        assert(static_cast<bool>(opt2) == true); +        assert(*opt2 == 2); +        opt1.swap(opt2); +        assert(static_cast<bool>(opt1) == true); +        assert(*opt1 == 2); +        assert(static_cast<bool>(opt2) == false); +    } +    { +        optional<int> opt1(1); +        optional<int> opt2(2); +        static_assert(noexcept(opt1.swap(opt2)) == true, ""); +        assert(static_cast<bool>(opt1) == true); +        assert(*opt1 == 1); +        assert(static_cast<bool>(opt2) == true); +        assert(*opt2 == 2); +        opt1.swap(opt2); +        assert(static_cast<bool>(opt1) == true); +        assert(*opt1 == 2); +        assert(static_cast<bool>(opt2) == true); +        assert(*opt2 == 1); +    } +    { +        optional<X> opt1; +        optional<X> opt2; +        static_assert(noexcept(opt1.swap(opt2)) == true, ""); +        assert(static_cast<bool>(opt1) == false); +        assert(static_cast<bool>(opt2) == false); +        opt1.swap(opt2); +        assert(static_cast<bool>(opt1) == false); +        assert(static_cast<bool>(opt2) == false); +        assert(X::dtor_called == 0); +    } +    { +        optional<X> opt1(1); +        optional<X> opt2; +        static_assert(noexcept(opt1.swap(opt2)) == true, ""); +        assert(static_cast<bool>(opt1) == true); +        assert(*opt1 == 1); +        assert(static_cast<bool>(opt2) == false); +        X::dtor_called = 0; +        opt1.swap(opt2); +        assert(X::dtor_called == 1); +        assert(static_cast<bool>(opt1) == false); +        assert(static_cast<bool>(opt2) == true); +        assert(*opt2 == 1); +    } +    { +        optional<X> opt1; +        optional<X> opt2(2); +        static_assert(noexcept(opt1.swap(opt2)) == true, ""); +        assert(static_cast<bool>(opt1) == false); +        assert(static_cast<bool>(opt2) == true); +        assert(*opt2 == 2); +        X::dtor_called = 0; +        opt1.swap(opt2); +        assert(X::dtor_called == 1); +        assert(static_cast<bool>(opt1) == true); +        assert(*opt1 == 2); +        assert(static_cast<bool>(opt2) == false); +    } +    { +        optional<X> opt1(1); +        optional<X> opt2(2); +        static_assert(noexcept(opt1.swap(opt2)) == true, ""); +        assert(static_cast<bool>(opt1) == true); +        assert(*opt1 == 1); +        assert(static_cast<bool>(opt2) == true); +        assert(*opt2 == 2); +        X::dtor_called = 0; +        opt1.swap(opt2); +        assert(X::dtor_called == 1);  // from inside std::swap +        assert(static_cast<bool>(opt1) == true); +        assert(*opt1 == 2); +        assert(static_cast<bool>(opt2) == true); +        assert(*opt2 == 1); +    } +    { +        optional<Y> opt1; +        optional<Y> opt2; +        static_assert(noexcept(opt1.swap(opt2)) == false, ""); +        assert(static_cast<bool>(opt1) == false); +        assert(static_cast<bool>(opt2) == false); +        opt1.swap(opt2); +        assert(static_cast<bool>(opt1) == false); +        assert(static_cast<bool>(opt2) == false); +        assert(Y::dtor_called == 0); +    } +    { +        optional<Y> opt1(1); +        optional<Y> opt2; +        static_assert(noexcept(opt1.swap(opt2)) == false, ""); +        assert(static_cast<bool>(opt1) == true); +        assert(*opt1 == 1); +        assert(static_cast<bool>(opt2) == false); +        Y::dtor_called = 0; +        opt1.swap(opt2); +        assert(Y::dtor_called == 1); +        assert(static_cast<bool>(opt1) == false); +        assert(static_cast<bool>(opt2) == true); +        assert(*opt2 == 1); +    } +    { +        optional<Y> opt1; +        optional<Y> opt2(2); +        static_assert(noexcept(opt1.swap(opt2)) == false, ""); +        assert(static_cast<bool>(opt1) == false); +        assert(static_cast<bool>(opt2) == true); +        assert(*opt2 == 2); +        Y::dtor_called = 0; +        opt1.swap(opt2); +        assert(Y::dtor_called == 1); +        assert(static_cast<bool>(opt1) == true); +        assert(*opt1 == 2); +        assert(static_cast<bool>(opt2) == false); +    } +    { +        optional<Y> opt1(1); +        optional<Y> opt2(2); +        static_assert(noexcept(opt1.swap(opt2)) == false, ""); +        assert(static_cast<bool>(opt1) == true); +        assert(*opt1 == 1); +        assert(static_cast<bool>(opt2) == true); +        assert(*opt2 == 2); +        Y::dtor_called = 0; +        opt1.swap(opt2); +        assert(Y::dtor_called == 0); +        assert(static_cast<bool>(opt1) == true); +        assert(*opt1 == 2); +        assert(static_cast<bool>(opt2) == true); +        assert(*opt2 == 1); +    } +    { +        optional<Z> opt1; +        optional<Z> opt2; +        static_assert(noexcept(opt1.swap(opt2)) == false, ""); +        assert(static_cast<bool>(opt1) == false); +        assert(static_cast<bool>(opt2) == false); +        opt1.swap(opt2); +        assert(static_cast<bool>(opt1) == false); +        assert(static_cast<bool>(opt2) == false); +    } +#ifndef TEST_HAS_NO_EXCEPTIONS +    { +        optional<Z> opt1; +        opt1.emplace(1); +        optional<Z> opt2; +        static_assert(noexcept(opt1.swap(opt2)) == false, ""); +        assert(static_cast<bool>(opt1) == true); +        assert(*opt1 == 1); +        assert(static_cast<bool>(opt2) == false); +        try +        { +            opt1.swap(opt2); +            assert(false); +        } +        catch (int i) +        { +            assert(i == 7); +        } +        assert(static_cast<bool>(opt1) == true); +        assert(*opt1 == 1); +        assert(static_cast<bool>(opt2) == false); +    } +    { +        optional<Z> opt1; +        optional<Z> opt2; +        opt2.emplace(2); +        static_assert(noexcept(opt1.swap(opt2)) == false, ""); +        assert(static_cast<bool>(opt1) == false); +        assert(static_cast<bool>(opt2) == true); +        assert(*opt2 == 2); +        try +        { +            opt1.swap(opt2); +            assert(false); +        } +        catch (int i) +        { +            assert(i == 7); +        } +        assert(static_cast<bool>(opt1) == false); +        assert(static_cast<bool>(opt2) == true); +        assert(*opt2 == 2); +    } +    { +        optional<Z> opt1; +        opt1.emplace(1); +        optional<Z> opt2; +        opt2.emplace(2); +        static_assert(noexcept(opt1.swap(opt2)) == false, ""); +        assert(static_cast<bool>(opt1) == true); +        assert(*opt1 == 1); +        assert(static_cast<bool>(opt2) == true); +        assert(*opt2 == 2); +        try +        { +            opt1.swap(opt2); +            assert(false); +        } +        catch (int i) +        { +            assert(i == 6); +        } +        assert(static_cast<bool>(opt1) == true); +        assert(*opt1 == 1); +        assert(static_cast<bool>(opt2) == true); +        assert(*opt2 == 2); +    } +#endif +} diff --git a/libcxx/test/std/utilities/optional/optional.object/optional_requires_destructible_object.fail.cpp b/libcxx/test/std/utilities/optional/optional.object/optional_requires_destructible_object.fail.cpp new file mode 100644 index 00000000000..8a2c77af0ec --- /dev/null +++ b/libcxx/test/std/utilities/optional/optional.object/optional_requires_destructible_object.fail.cpp @@ -0,0 +1,50 @@ +//===----------------------------------------------------------------------===// +// +//                     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> + +// T shall be an object type and shall satisfy the requirements of Destructible + +#include <optional> + +using std::optional; + +struct X +{ +private: +    ~X() {} +}; + +int main() +{ +    using std::optional; +    { +        // expected-error@optional:* 2 {{static_assert failed "instantiation of optional with a reference type is ill-formed}} +        optional<int&> opt1; +        optional<int&&> opt2; +    } +    { +        // expected-error@optional:* {{static_assert failed "instantiation of optional with a non-destructible type is ill-formed"}} +        optional<X> opt3; +    } +    { +        // expected-error@optional:* {{static_assert failed "instantiation of optional with a non-object type is undefined behavior"}} +        // expected-error@optional:* {{static_assert failed "instantiation of optional with a non-destructible type is ill-formed}} +        optional<void()> opt4; +    } +    { +        // expected-error@optional:* {{static_assert failed "instantiation of optional with a non-object type is undefined behavior"}} +        // expected-error@optional:* {{static_assert failed "instantiation of optional with a non-destructible type is ill-formed}} +        // expected-error@optional:* 1+ {{cannot form a reference to 'void'}} +        optional<const void> opt4; +    } +    // FIXME these are garbage diagnostics that Clang should not produce +    // expected-error@optional:* 0+ {{is not a base class}} +} diff --git a/libcxx/test/std/utilities/optional/optional.object/special_member_gen.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/special_member_gen.pass.cpp new file mode 100644 index 00000000000..fdd0f154f0e --- /dev/null +++ b/libcxx/test/std/utilities/optional/optional.object/special_member_gen.pass.cpp @@ -0,0 +1,74 @@ +//===----------------------------------------------------------------------===// +// +//                     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> + + +#include <optional> +#include <type_traits> +#include <cassert> + +#include "archetypes.hpp" + +template <class T> +struct SpecialMemberTest { +    using O = std::optional<T>; + +    static_assert(std::is_default_constructible_v<O>, +        "optional is always default constructible."); +    static_assert(std::is_copy_constructible_v<O> == std::is_copy_constructible_v<T>, +        "optional<T> is copy constructible if and only if T is copy constructible."); +    static_assert(std::is_move_constructible_v<O> == +        (std::is_copy_constructible_v<T> || std::is_move_constructible_v<T>), +        "optional<T> is move constructible if and only if T is copy or move constructible."); +    static_assert(std::is_copy_assignable_v<O> == +        (std::is_copy_constructible_v<T> && std::is_copy_assignable_v<T>), +        "optional<T> is copy assignable if and only if T is both copy " +        "constructible and copy assignable."); +    static_assert(std::is_move_assignable_v<O> == +        ((std::is_copy_constructible_v<T> && std::is_copy_assignable_v<T>) || +         (std::is_move_constructible_v<T> && std::is_move_assignable_v<T>)), +        "optional<T> is move assignable if and only if T is both move assignable and " +        "move constructible, or both copy constructible and copy assignable."); +}; + +template <class ...Args> static void sink(Args&&...) {} + +template <class ...TestTypes> +struct DoTestsMetafunction { +    DoTestsMetafunction() { sink(SpecialMemberTest<TestTypes>{}...); } +}; + +struct TrivialMoveNonTrivialCopy { +    TrivialMoveNonTrivialCopy() = default; +    TrivialMoveNonTrivialCopy(const TrivialMoveNonTrivialCopy&) {} +    TrivialMoveNonTrivialCopy(TrivialMoveNonTrivialCopy&&) = default; +    TrivialMoveNonTrivialCopy& operator=(const TrivialMoveNonTrivialCopy&) { return *this; } +    TrivialMoveNonTrivialCopy& operator=(TrivialMoveNonTrivialCopy&&) = default; +}; + +struct TrivialCopyNonTrivialMove { +    TrivialCopyNonTrivialMove() = default; +    TrivialCopyNonTrivialMove(const TrivialCopyNonTrivialMove&) = default; +    TrivialCopyNonTrivialMove(TrivialCopyNonTrivialMove&&) {} +    TrivialCopyNonTrivialMove& operator=(const TrivialCopyNonTrivialMove&) = default; +    TrivialCopyNonTrivialMove& operator=(TrivialCopyNonTrivialMove&&) { return *this; } +}; + +int main() +{ +    sink( +        ImplicitTypes::ApplyTypes<DoTestsMetafunction>{}, +        ExplicitTypes::ApplyTypes<DoTestsMetafunction>{}, +        NonLiteralTypes::ApplyTypes<DoTestsMetafunction>{}, +        NonTrivialTypes::ApplyTypes<DoTestsMetafunction>{}, +        DoTestsMetafunction<TrivialMoveNonTrivialCopy, TrivialCopyNonTrivialMove>{} +    ); +} diff --git a/libcxx/test/std/utilities/optional/optional.object/types.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/types.pass.cpp new file mode 100644 index 00000000000..0230a13dded --- /dev/null +++ b/libcxx/test/std/utilities/optional/optional.object/types.pass.cpp @@ -0,0 +1,38 @@ +//===----------------------------------------------------------------------===// +// +//                     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 T> +// class optional +// { +// public: +//     typedef T value_type; +//     ... + +#include <optional> +#include <type_traits> + +using std::optional; + +template <class Opt, class T> +void +test() +{ +    static_assert(std::is_same<typename Opt::value_type, T>::value, ""); +} + +int main() +{ +    test<optional<int>, int>(); +    test<optional<const int>, const int>(); +    test<optional<double>, double>(); +    test<optional<const double>, const double>(); +} diff --git a/libcxx/test/std/utilities/optional/optional.relops/equal.pass.cpp b/libcxx/test/std/utilities/optional/optional.relops/equal.pass.cpp new file mode 100644 index 00000000000..6650b6720a8 --- /dev/null +++ b/libcxx/test/std/utilities/optional/optional.relops/equal.pass.cpp @@ -0,0 +1,74 @@ +//===----------------------------------------------------------------------===// +// +//                     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 T> constexpr bool operator==(const optional<T>& x, const optional<T>& y); + +#include <optional> +#include <type_traits> +#include <cassert> + +using std::optional; + +struct X +{ +    int i_; + +    constexpr X(int i) : i_(i) {} +}; + +constexpr bool operator == ( const X &lhs, const X &rhs ) +    { return lhs.i_ == rhs.i_ ; } + +int main() +{ +    { +    typedef X T; +    typedef optional<T> O; + +    constexpr O o1;     // disengaged +    constexpr O o2;     // disengaged +    constexpr O o3{1};  // engaged +    constexpr O o4{2};  // engaged +    constexpr O o5{1};  // engaged + +    static_assert (   o1 == o1 , "" ); +    static_assert (   o1 == o2 , "" ); +    static_assert ( !(o1 == o3), "" ); +    static_assert ( !(o1 == o4), "" ); +    static_assert ( !(o1 == o5), "" ); + +    static_assert (   o2 == o1 , "" ); +    static_assert (   o2 == o2 , "" ); +    static_assert ( !(o2 == o3), "" ); +    static_assert ( !(o2 == o4), "" ); +    static_assert ( !(o2 == o5), "" ); + +    static_assert ( !(o3 == o1), "" ); +    static_assert ( !(o3 == o2), "" ); +    static_assert (   o3 == o3 , "" ); +    static_assert ( !(o3 == o4), "" ); +    static_assert (   o3 == o5 , "" ); + +    static_assert ( !(o4 == o1), "" ); +    static_assert ( !(o4 == o2), "" ); +    static_assert ( !(o4 == o3), "" ); +    static_assert (   o4 == o4 , "" ); +    static_assert ( !(o4 == o5), "" ); + +    static_assert ( !(o5 == o1), "" ); +    static_assert ( !(o5 == o2), "" ); +    static_assert (   o5 == o3 , "" ); +    static_assert ( !(o5 == o4), "" ); +    static_assert (   o5 == o5 , "" ); + +    } +} diff --git a/libcxx/test/std/utilities/optional/optional.relops/greater_equal.pass.cpp b/libcxx/test/std/utilities/optional/optional.relops/greater_equal.pass.cpp new file mode 100644 index 00000000000..f9b30449638 --- /dev/null +++ b/libcxx/test/std/utilities/optional/optional.relops/greater_equal.pass.cpp @@ -0,0 +1,70 @@ +//===----------------------------------------------------------------------===// +// +//                     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 T> constexpr bool operator>= (const optional<T>& x, const optional<T>& y); + +#include <optional> + +using std::optional; + +struct X +{ +    int i_; + +    constexpr X(int i) : i_(i) {} +}; + +constexpr bool operator >= ( const X &lhs, const X &rhs ) +    { return lhs.i_ >= rhs.i_ ; } + +int main() +{ +    { +    typedef optional<X> O; + +    constexpr O o1;     // disengaged +    constexpr O o2;     // disengaged +    constexpr O o3{1};  // engaged +    constexpr O o4{2};  // engaged +    constexpr O o5{1};  // engaged + +    static_assert (  (o1 >= o1), "" ); +    static_assert (  (o1 >= o2), "" ); +    static_assert ( !(o1 >= o3), "" ); +    static_assert ( !(o1 >= o4), "" ); +    static_assert ( !(o1 >= o5), "" ); + +    static_assert (  (o2 >= o1), "" ); +    static_assert (  (o2 >= o2), "" ); +    static_assert ( !(o2 >= o3), "" ); +    static_assert ( !(o2 >= o4), "" ); +    static_assert ( !(o2 >= o5), "" ); + +    static_assert (  (o3 >= o1), "" ); +    static_assert (  (o3 >= o2), "" ); +    static_assert (  (o3 >= o3), "" ); +    static_assert ( !(o3 >= o4), "" ); +    static_assert (  (o3 >= o5), "" ); + +    static_assert (  (o4 >= o1), "" ); +    static_assert (  (o4 >= o2), "" ); +    static_assert (  (o4 >= o3), "" ); +    static_assert (  (o4 >= o4), "" ); +    static_assert (  (o4 >= o5), "" ); + +    static_assert (  (o5 >= o1), "" ); +    static_assert (  (o5 >= o2), "" ); +    static_assert (  (o5 >= o3), "" ); +    static_assert ( !(o5 >= o4), "" ); +    static_assert (  (o5 >= o5), "" ); +    } +} diff --git a/libcxx/test/std/utilities/optional/optional.relops/greater_than.pass.cpp b/libcxx/test/std/utilities/optional/optional.relops/greater_than.pass.cpp new file mode 100644 index 00000000000..8a27eb471f2 --- /dev/null +++ b/libcxx/test/std/utilities/optional/optional.relops/greater_than.pass.cpp @@ -0,0 +1,70 @@ +//===----------------------------------------------------------------------===// +// +//                     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 T> constexpr bool operator> (const optional<T>& x, const optional<T>& y); + +#include <optional> + +using std::optional; + +struct X +{ +    int i_; + +    constexpr X(int i) : i_(i) {} +}; + +constexpr bool operator > ( const X &lhs, const X &rhs ) +    { return lhs.i_ > rhs.i_ ; } + +int main() +{ +    { +    typedef optional<X> O; + +    constexpr O o1;     // disengaged +    constexpr O o2;     // disengaged +    constexpr O o3{1};  // engaged +    constexpr O o4{2};  // engaged +    constexpr O o5{1};  // engaged + +    static_assert ( !(o1 > o1), "" ); +    static_assert ( !(o1 > o2), "" ); +    static_assert ( !(o1 > o3), "" ); +    static_assert ( !(o1 > o4), "" ); +    static_assert ( !(o1 > o5), "" ); + +    static_assert ( !(o2 > o1), "" ); +    static_assert ( !(o2 > o2), "" ); +    static_assert ( !(o2 > o3), "" ); +    static_assert ( !(o2 > o4), "" ); +    static_assert ( !(o2 > o5), "" ); + +    static_assert (  (o3 > o1), "" ); +    static_assert (  (o3 > o2), "" ); +    static_assert ( !(o3 > o3), "" ); +    static_assert ( !(o3 > o4), "" ); +    static_assert ( !(o3 > o5), "" ); + +    static_assert (  (o4 > o1), "" ); +    static_assert (  (o4 > o2), "" ); +    static_assert (  (o4 > o3), "" ); +    static_assert ( !(o4 > o4), "" ); +    static_assert (  (o4 > o5), "" ); + +    static_assert (  (o5 > o1), "" ); +    static_assert (  (o5 > o2), "" ); +    static_assert ( !(o5 > o3), "" ); +    static_assert ( !(o5 > o4), "" ); +    static_assert ( !(o5 > o5), "" ); +    } +} diff --git a/libcxx/test/std/utilities/optional/optional.relops/less_equal.pass.cpp b/libcxx/test/std/utilities/optional/optional.relops/less_equal.pass.cpp new file mode 100644 index 00000000000..a7d594dd34a --- /dev/null +++ b/libcxx/test/std/utilities/optional/optional.relops/less_equal.pass.cpp @@ -0,0 +1,70 @@ +//===----------------------------------------------------------------------===// +// +//                     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 T> constexpr bool operator<= (const optional<T>& x, const optional<T>& y); + +#include <optional> + +using std::optional; + +struct X +{ +    int i_; + +    constexpr X(int i) : i_(i) {} +}; + +constexpr bool operator <= ( const X &lhs, const X &rhs ) +    { return lhs.i_ <= rhs.i_ ; } + +int main() +{ +    { +    typedef optional<X> O; + +    constexpr O o1;     // disengaged +    constexpr O o2;     // disengaged +    constexpr O o3{1};  // engaged +    constexpr O o4{2};  // engaged +    constexpr O o5{1};  // engaged + +    static_assert (  (o1 <= o1), "" ); +    static_assert (  (o1 <= o2), "" ); +    static_assert (  (o1 <= o3), "" ); +    static_assert (  (o1 <= o4), "" ); +    static_assert (  (o1 <= o5), "" ); + +    static_assert (  (o2 <= o1), "" ); +    static_assert (  (o2 <= o2), "" ); +    static_assert (  (o2 <= o3), "" ); +    static_assert (  (o2 <= o4), "" ); +    static_assert (  (o2 <= o5), "" ); + +    static_assert ( !(o3 <= o1), "" ); +    static_assert ( !(o3 <= o2), "" ); +    static_assert (  (o3 <= o3), "" ); +    static_assert (  (o3 <= o4), "" ); +    static_assert (  (o3 <= o5), "" ); + +    static_assert ( !(o4 <= o1), "" ); +    static_assert ( !(o4 <= o2), "" ); +    static_assert ( !(o4 <= o3), "" ); +    static_assert (  (o4 <= o4), "" ); +    static_assert ( !(o4 <= o5), "" ); + +    static_assert ( !(o5 <= o1), "" ); +    static_assert ( !(o5 <= o2), "" ); +    static_assert (  (o5 <= o3), "" ); +    static_assert (  (o5 <= o4), "" ); +    static_assert (  (o5 <= o5), "" ); +    } +} diff --git a/libcxx/test/std/utilities/optional/optional.relops/less_than.pass.cpp b/libcxx/test/std/utilities/optional/optional.relops/less_than.pass.cpp new file mode 100644 index 00000000000..deffa5e849f --- /dev/null +++ b/libcxx/test/std/utilities/optional/optional.relops/less_than.pass.cpp @@ -0,0 +1,70 @@ +//===----------------------------------------------------------------------===// +// +//                     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 T> constexpr bool operator< (const optional<T>& x, const optional<T>& y); + +#include <optional> + +using std::optional; + +struct X +{ +    int i_; + +    constexpr X(int i) : i_(i) {} +}; + +constexpr bool operator < ( const X &lhs, const X &rhs ) +    { return lhs.i_ < rhs.i_ ; } + +int main() +{ +    { +    typedef optional<X> O; + +    constexpr O o1;     // disengaged +    constexpr O o2;     // disengaged +    constexpr O o3{1};  // engaged +    constexpr O o4{2};  // engaged +    constexpr O o5{1};  // engaged + +    static_assert ( !(o1 < o1), "" ); +    static_assert ( !(o1 < o2), "" ); +    static_assert (  (o1 < o3), "" ); +    static_assert (  (o1 < o4), "" ); +    static_assert (  (o1 < o5), "" ); + +    static_assert ( !(o2 < o1), "" ); +    static_assert ( !(o2 < o2), "" ); +    static_assert (  (o2 < o3), "" ); +    static_assert (  (o2 < o4), "" ); +    static_assert (  (o2 < o5), "" ); + +    static_assert ( !(o3 < o1), "" ); +    static_assert ( !(o3 < o2), "" ); +    static_assert ( !(o3 < o3), "" ); +    static_assert (  (o3 < o4), "" ); +    static_assert ( !(o3 < o5), "" ); + +    static_assert ( !(o4 < o1), "" ); +    static_assert ( !(o4 < o2), "" ); +    static_assert ( !(o4 < o3), "" ); +    static_assert ( !(o4 < o4), "" ); +    static_assert ( !(o4 < o5), "" ); + +    static_assert ( !(o5 < o1), "" ); +    static_assert ( !(o5 < o2), "" ); +    static_assert ( !(o5 < o3), "" ); +    static_assert (  (o5 < o4), "" ); +    static_assert ( !(o5 < o5), "" ); +    } +} diff --git a/libcxx/test/std/utilities/optional/optional.relops/not_equal.pass.cpp b/libcxx/test/std/utilities/optional/optional.relops/not_equal.pass.cpp new file mode 100644 index 00000000000..fd11b2a207c --- /dev/null +++ b/libcxx/test/std/utilities/optional/optional.relops/not_equal.pass.cpp @@ -0,0 +1,74 @@ +//===----------------------------------------------------------------------===// +// +//                     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 T> constexpr bool operator!=(const optional<T>& x, const optional<T>& y); + +#include <optional> +#include <type_traits> +#include <cassert> + +using std::optional; + +struct X +{ +    int i_; + +    constexpr X(int i) : i_(i) {} +}; + +constexpr bool operator != ( const X &lhs, const X &rhs ) +    { return lhs.i_ != rhs.i_ ; } + +int main() +{ +    { +    typedef X T; +    typedef optional<T> O; + +    constexpr O o1;     // disengaged +    constexpr O o2;     // disengaged +    constexpr O o3{1};  // engaged +    constexpr O o4{2};  // engaged +    constexpr O o5{1};  // engaged + +    static_assert ( !(o1 != o1), "" ); +    static_assert ( !(o1 != o2), "" ); +    static_assert (  (o1 != o3), "" ); +    static_assert (  (o1 != o4), "" ); +    static_assert (  (o1 != o5), "" ); + +    static_assert ( !(o2 != o1), "" ); +    static_assert ( !(o2 != o2), "" ); +    static_assert (  (o2 != o3), "" ); +    static_assert (  (o2 != o4), "" ); +    static_assert (  (o2 != o5), "" ); + +    static_assert (  (o3 != o1), "" ); +    static_assert (  (o3 != o2), "" ); +    static_assert ( !(o3 != o3), "" ); +    static_assert (  (o3 != o4), "" ); +    static_assert ( !(o3 != o5), "" ); + +    static_assert (  (o4 != o1), "" ); +    static_assert (  (o4 != o2), "" ); +    static_assert (  (o4 != o3), "" ); +    static_assert ( !(o4 != o4), "" ); +    static_assert (  (o4 != o5), "" ); + +    static_assert (  (o5 != o1), "" ); +    static_assert (  (o5 != o2), "" ); +    static_assert ( !(o5 != o3), "" ); +    static_assert (  (o5 != o4), "" ); +    static_assert ( !(o5 != o5), "" ); + +    } +} diff --git a/libcxx/test/std/utilities/optional/optional.specalg/make_optional.pass.cpp b/libcxx/test/std/utilities/optional/optional.specalg/make_optional.pass.cpp new file mode 100644 index 00000000000..3fbf19f8ee1 --- /dev/null +++ b/libcxx/test/std/utilities/optional/optional.specalg/make_optional.pass.cpp @@ -0,0 +1,51 @@ +//===----------------------------------------------------------------------===// +// +//                     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 T> +//   constexpr optional<decay_t<T>> make_optional(T&& v); + +#include <optional> +#include <string> +#include <memory> +#include <cassert> + +#include "test_macros.h" + +int main() +{ +    using std::optional; +    using std::make_optional; +    { +        int arr[10]; ((void)arr); +        ASSERT_SAME_TYPE(decltype(make_optional(arr)), optional<int*>); +    } +    { +        constexpr auto opt = make_optional(2); +        ASSERT_SAME_TYPE(decltype(opt), const optional<int>); +        static_assert(opt.value() == 2); +    } +    { +        optional<int> opt = make_optional(2); +        assert(*opt == 2); +    } +    { +        std::string s("123"); +        optional<std::string> opt = make_optional(s); +        assert(*opt == s); +    } +    { +        std::unique_ptr<int> s(new int(3)); +        optional<std::unique_ptr<int>> opt = make_optional(std::move(s)); +        assert(**opt == 3); +        assert(s == nullptr); +    } +} diff --git a/libcxx/test/std/utilities/optional/optional.specalg/make_optional_explicit.pass.cpp b/libcxx/test/std/utilities/optional/optional.specalg/make_optional_explicit.pass.cpp new file mode 100644 index 00000000000..bdfeefbcc1d --- /dev/null +++ b/libcxx/test/std/utilities/optional/optional.specalg/make_optional_explicit.pass.cpp @@ -0,0 +1,45 @@ +//===----------------------------------------------------------------------===// +// +//                     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 T, class... Args> +//   constexpr optional<T> make_optional(Args&&... args); + +#include <optional> +#include <string> +#include <memory> +#include <cassert> + +int main() +{ +    using std::optional; +    using std::make_optional; + +    { +        constexpr auto opt = make_optional<int>('a'); +        static_assert(*opt == int('a'), ""); +    } +    { +        std::string s("123"); +        auto opt = make_optional<std::string>(s); +        assert(*opt == s); +    } +    { +        std::unique_ptr<int> s(new int(3)); +        auto opt = make_optional<std::unique_ptr<int>>(std::move(s)); +        assert(**opt == 3); +        assert(s == nullptr); +    } +    { +        auto opt = make_optional<std::string>(4, 'X'); +        assert(*opt == "XXXX"); +    } +} diff --git a/libcxx/test/std/utilities/optional/optional.specalg/make_optional_explicit_initializer_list.pass.cpp b/libcxx/test/std/utilities/optional/optional.specalg/make_optional_explicit_initializer_list.pass.cpp new file mode 100644 index 00000000000..f17f5820d20 --- /dev/null +++ b/libcxx/test/std/utilities/optional/optional.specalg/make_optional_explicit_initializer_list.pass.cpp @@ -0,0 +1,53 @@ +//===----------------------------------------------------------------------===// +// +//                     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 T, class U, class... Args> +//   constexpr optional<T> make_optional(initializer_list<U> il, Args&&... args); + +#include <optional> +#include <string> +#include <memory> +#include <cassert> + +#include "test_macros.h" + +struct TestT { +  int x; +  int size; +  constexpr TestT(std::initializer_list<int> il) : x(*il.begin()), size(il.size()) {} +  constexpr TestT(std::initializer_list<int> il, const int*) +      : x(*il.begin()), size(il.size()) {} +}; + +int main() +{ +    using std::make_optional; +    { +        constexpr auto opt = make_optional<TestT>({42, 2, 3}); +        ASSERT_SAME_TYPE(decltype(opt), const std::optional<TestT>); +        static_assert(opt->x == 42, ""); +        static_assert(opt->size == 3, ""); +    } +    { +        constexpr auto opt = make_optional<TestT>({42, 2, 3}, nullptr); +        static_assert(opt->x == 42, ""); +        static_assert(opt->size == 3, ""); +    } +    { +        auto opt = make_optional<std::string>({'1', '2', '3'}); +        assert(*opt == "123"); +    } +    { +        auto opt = make_optional<std::string>({'a', 'b', 'c'}, std::allocator<char>{}); +        assert(*opt == "abc"); +    } +} diff --git a/libcxx/test/std/utilities/optional/optional.specalg/swap.pass.cpp b/libcxx/test/std/utilities/optional/optional.specalg/swap.pass.cpp new file mode 100644 index 00000000000..f364d7dab79 --- /dev/null +++ b/libcxx/test/std/utilities/optional/optional.specalg/swap.pass.cpp @@ -0,0 +1,303 @@ +//===----------------------------------------------------------------------===// +// +//                     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 T> void swap(optional<T>& x, optional<T>& y) +//     noexcept(noexcept(x.swap(y))); + +#include <optional> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" + +using std::optional; + +class X +{ +    int i_; +public: +    static unsigned dtor_called; +    X(int i) : i_(i) {} +    X(X&& x) = default; +    X& operator=(X&&) = default; +    ~X() {++dtor_called;} + +    friend bool operator==(const X& x, const X& y) {return x.i_ == y.i_;} +}; + +unsigned X::dtor_called = 0; + +class Y +{ +    int i_; +public: +    static unsigned dtor_called; +    Y(int i) : i_(i) {} +    Y(Y&&) = default; +    ~Y() {++dtor_called;} + +    friend constexpr bool operator==(const Y& x, const Y& y) {return x.i_ == y.i_;} +    friend void swap(Y& x, Y& y) {std::swap(x.i_, y.i_);} +}; + +unsigned Y::dtor_called = 0; + +class Z +{ +    int i_; +public: +    Z(int i) : i_(i) {} +    Z(Z&&) { TEST_THROW(7);} + +    friend constexpr bool operator==(const Z& x, const Z& y) {return x.i_ == y.i_;} +    friend void swap(Z& x, Z& y) { TEST_THROW(6);} +}; + +int main() +{ +    { +        optional<int> opt1; +        optional<int> opt2; +        static_assert(noexcept(swap(opt1, opt2)) == true, ""); +        assert(static_cast<bool>(opt1) == false); +        assert(static_cast<bool>(opt2) == false); +        swap(opt1, opt2); +        assert(static_cast<bool>(opt1) == false); +        assert(static_cast<bool>(opt2) == false); +    } +    { +        optional<int> opt1(1); +        optional<int> opt2; +        static_assert(noexcept(swap(opt1, opt2)) == true, ""); +        assert(static_cast<bool>(opt1) == true); +        assert(*opt1 == 1); +        assert(static_cast<bool>(opt2) == false); +        swap(opt1, opt2); +        assert(static_cast<bool>(opt1) == false); +        assert(static_cast<bool>(opt2) == true); +        assert(*opt2 == 1); +    } +    { +        optional<int> opt1; +        optional<int> opt2(2); +        static_assert(noexcept(swap(opt1, opt2)) == true, ""); +        assert(static_cast<bool>(opt1) == false); +        assert(static_cast<bool>(opt2) == true); +        assert(*opt2 == 2); +        swap(opt1, opt2); +        assert(static_cast<bool>(opt1) == true); +        assert(*opt1 == 2); +        assert(static_cast<bool>(opt2) == false); +    } +    { +        optional<int> opt1(1); +        optional<int> opt2(2); +        static_assert(noexcept(swap(opt1, opt2)) == true, ""); +        assert(static_cast<bool>(opt1) == true); +        assert(*opt1 == 1); +        assert(static_cast<bool>(opt2) == true); +        assert(*opt2 == 2); +        swap(opt1, opt2); +        assert(static_cast<bool>(opt1) == true); +        assert(*opt1 == 2); +        assert(static_cast<bool>(opt2) == true); +        assert(*opt2 == 1); +    } +    { +        optional<X> opt1; +        optional<X> opt2; +        static_assert(noexcept(swap(opt1, opt2)) == true, ""); +        assert(static_cast<bool>(opt1) == false); +        assert(static_cast<bool>(opt2) == false); +        swap(opt1, opt2); +        assert(static_cast<bool>(opt1) == false); +        assert(static_cast<bool>(opt2) == false); +        assert(X::dtor_called == 0); +    } +    { +        optional<X> opt1(1); +        optional<X> opt2; +        static_assert(noexcept(swap(opt1, opt2)) == true, ""); +        assert(static_cast<bool>(opt1) == true); +        assert(*opt1 == 1); +        assert(static_cast<bool>(opt2) == false); +        X::dtor_called = 0; +        swap(opt1, opt2); +        assert(X::dtor_called == 1); +        assert(static_cast<bool>(opt1) == false); +        assert(static_cast<bool>(opt2) == true); +        assert(*opt2 == 1); +    } +    { +        optional<X> opt1; +        optional<X> opt2(2); +        static_assert(noexcept(swap(opt1, opt2)) == true, ""); +        assert(static_cast<bool>(opt1) == false); +        assert(static_cast<bool>(opt2) == true); +        assert(*opt2 == 2); +        X::dtor_called = 0; +        swap(opt1, opt2); +        assert(X::dtor_called == 1); +        assert(static_cast<bool>(opt1) == true); +        assert(*opt1 == 2); +        assert(static_cast<bool>(opt2) == false); +    } +    { +        optional<X> opt1(1); +        optional<X> opt2(2); +        static_assert(noexcept(swap(opt1, opt2)) == true, ""); +        assert(static_cast<bool>(opt1) == true); +        assert(*opt1 == 1); +        assert(static_cast<bool>(opt2) == true); +        assert(*opt2 == 2); +        X::dtor_called = 0; +        swap(opt1, opt2); +        assert(X::dtor_called == 1);  // from inside std::swap +        assert(static_cast<bool>(opt1) == true); +        assert(*opt1 == 2); +        assert(static_cast<bool>(opt2) == true); +        assert(*opt2 == 1); +    } +    { +        optional<Y> opt1; +        optional<Y> opt2; +        static_assert(noexcept(swap(opt1, opt2)) == false, ""); +        assert(static_cast<bool>(opt1) == false); +        assert(static_cast<bool>(opt2) == false); +        swap(opt1, opt2); +        assert(static_cast<bool>(opt1) == false); +        assert(static_cast<bool>(opt2) == false); +        assert(Y::dtor_called == 0); +    } +    { +        optional<Y> opt1(1); +        optional<Y> opt2; +        static_assert(noexcept(swap(opt1, opt2)) == false, ""); +        assert(static_cast<bool>(opt1) == true); +        assert(*opt1 == 1); +        assert(static_cast<bool>(opt2) == false); +        Y::dtor_called = 0; +        swap(opt1, opt2); +        assert(Y::dtor_called == 1); +        assert(static_cast<bool>(opt1) == false); +        assert(static_cast<bool>(opt2) == true); +        assert(*opt2 == 1); +    } +    { +        optional<Y> opt1; +        optional<Y> opt2(2); +        static_assert(noexcept(swap(opt1, opt2)) == false, ""); +        assert(static_cast<bool>(opt1) == false); +        assert(static_cast<bool>(opt2) == true); +        assert(*opt2 == 2); +        Y::dtor_called = 0; +        swap(opt1, opt2); +        assert(Y::dtor_called == 1); +        assert(static_cast<bool>(opt1) == true); +        assert(*opt1 == 2); +        assert(static_cast<bool>(opt2) == false); +    } +    { +        optional<Y> opt1(1); +        optional<Y> opt2(2); +        static_assert(noexcept(swap(opt1, opt2)) == false, ""); +        assert(static_cast<bool>(opt1) == true); +        assert(*opt1 == 1); +        assert(static_cast<bool>(opt2) == true); +        assert(*opt2 == 2); +        Y::dtor_called = 0; +        swap(opt1, opt2); +        assert(Y::dtor_called == 0); +        assert(static_cast<bool>(opt1) == true); +        assert(*opt1 == 2); +        assert(static_cast<bool>(opt2) == true); +        assert(*opt2 == 1); +    } +    { +        optional<Z> opt1; +        optional<Z> opt2; +        static_assert(noexcept(swap(opt1, opt2)) == false, ""); +        assert(static_cast<bool>(opt1) == false); +        assert(static_cast<bool>(opt2) == false); +        swap(opt1, opt2); +        assert(static_cast<bool>(opt1) == false); +        assert(static_cast<bool>(opt2) == false); +    } +#ifndef TEST_HAS_NO_EXCEPTIONS +    { +        optional<Z> opt1; +        opt1.emplace(1); +        optional<Z> opt2; +        static_assert(noexcept(swap(opt1, opt2)) == false, ""); +        assert(static_cast<bool>(opt1) == true); +        assert(*opt1 == 1); +        assert(static_cast<bool>(opt2) == false); +        try +        { +            swap(opt1, opt2); +            assert(false); +        } +        catch (int i) +        { +            assert(i == 7); +        } +        assert(static_cast<bool>(opt1) == true); +        assert(*opt1 == 1); +        assert(static_cast<bool>(opt2) == false); +    } +    { +        optional<Z> opt1; +        optional<Z> opt2; +        opt2.emplace(2); +        static_assert(noexcept(swap(opt1, opt2)) == false, ""); +        assert(static_cast<bool>(opt1) == false); +        assert(static_cast<bool>(opt2) == true); +        assert(*opt2 == 2); +        try +        { +            swap(opt1, opt2); +            assert(false); +        } +        catch (int i) +        { +            assert(i == 7); +        } +        assert(static_cast<bool>(opt1) == false); +        assert(static_cast<bool>(opt2) == true); +        assert(*opt2 == 2); +    } +    { +        optional<Z> opt1; +        opt1.emplace(1); +        optional<Z> opt2; +        opt2.emplace(2); +        static_assert(noexcept(swap(opt1, opt2)) == false, ""); +        assert(static_cast<bool>(opt1) == true); +        assert(*opt1 == 1); +        assert(static_cast<bool>(opt2) == true); +        assert(*opt2 == 2); +        try +        { +            swap(opt1, opt2); +            assert(false); +        } +        catch (int i) +        { +            assert(i == 6); +        } +        assert(static_cast<bool>(opt1) == true); +        assert(*opt1 == 1); +        assert(static_cast<bool>(opt2) == true); +        assert(*opt2 == 2); +    } +#endif // TEST_HAS_NO_EXCEPTIONS +} diff --git a/libcxx/test/std/utilities/optional/optional.syn/optional_in_place_t.fail.cpp b/libcxx/test/std/utilities/optional/optional.syn/optional_in_place_t.fail.cpp new file mode 100644 index 00000000000..20c90c7e34f --- /dev/null +++ b/libcxx/test/std/utilities/optional/optional.syn/optional_in_place_t.fail.cpp @@ -0,0 +1,26 @@ +//===----------------------------------------------------------------------===// +// +//                     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> + +// A program that necessitates the instantiation of template optional for +// (possibly cv-qualified) in_place_t is ill-formed. + +#include <optional> + +int main() +{ +    using std::optional; +    using std::in_place_t; +    using std::in_place; + +    optional<in_place_t> opt; // expected-note {{requested here}} +    // expected-error@optional:* {{"instantiation of optional with in_place_t is ill-formed"}} +} diff --git a/libcxx/test/std/utilities/optional/optional.syn/optional_includes_initializer_list.pass.cpp b/libcxx/test/std/utilities/optional/optional.syn/optional_includes_initializer_list.pass.cpp new file mode 100644 index 00000000000..687625e8b67 --- /dev/null +++ b/libcxx/test/std/utilities/optional/optional.syn/optional_includes_initializer_list.pass.cpp @@ -0,0 +1,22 @@ +//===----------------------------------------------------------------------===// +// +//                     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> + +// #include <initializer_list> + +#include <optional> + +int main() +{ +    using std::optional; + +    std::initializer_list<int> list; +} diff --git a/libcxx/test/std/utilities/optional/optional.syn/optional_nullopt_t.fail.cpp b/libcxx/test/std/utilities/optional/optional.syn/optional_nullopt_t.fail.cpp new file mode 100644 index 00000000000..56a30ccb0db --- /dev/null +++ b/libcxx/test/std/utilities/optional/optional.syn/optional_nullopt_t.fail.cpp @@ -0,0 +1,29 @@ +//===----------------------------------------------------------------------===// +// +//                     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> + +// A program that necessitates the instantiation of template optional for +// (possibly cv-qualified) nullopt_t is ill-formed. + +#include <optional> + +int main() +{ +    using std::optional; +    using std::nullopt_t; +    using std::nullopt; + +    optional<nullopt_t> opt; // expected-note 1 {{requested here}} +    optional<const nullopt_t> opt1; // expected-note 1 {{requested here}} +    optional<nullopt_t &> opt2; // expected-note 1 {{requested here}} +    optional<nullopt_t &&> opt3; // expected-note 1 {{requested here}} +    // expected-error@optional:* 4 {{instantiation of optional with nullopt_t is ill-formed}} +}  | 

