mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-19 02:46:51 +00:00
[libc++] Implement std::experimental::observer_ptr
This patch adds std::experimental::observer_ptr (n4282) and also fixes LWG2516. Co-Authored-By: Louis Dionne <ldionne.2@gmail.com> Differential Revision: https://reviews.llvm.org/D63230
This commit is contained in:
parent
cf7d4f543c
commit
7a62bee611
@ -143,7 +143,7 @@
|
||||
"`2441 <https://wg21.link/LWG2441>`__","Exact-width atomic typedefs should be provided","Oulu","|Complete|",""
|
||||
"`2451 <https://wg21.link/LWG2451>`__","[fund.ts.v2] optional should 'forward' T's implicit conversions","Oulu","|Nothing To Do|",""
|
||||
"`2509 <https://wg21.link/LWG2509>`__","[fund.ts.v2] any_cast doesn't work with rvalue reference targets and cannot move with a value target","Oulu","|Complete|",""
|
||||
"`2516 <https://wg21.link/LWG2516>`__","[fund.ts.v2] Public ""exposition only"" members in observer_ptr","Oulu","",""
|
||||
"`2516 <https://wg21.link/LWG2516>`__","[fund.ts.v2] Public ""exposition only"" members in observer_ptr","Oulu","|Complete|","18.0"
|
||||
"`2542 <https://wg21.link/LWG2542>`__","Missing const requirements for associative containers","Oulu","",""
|
||||
"`2549 <https://wg21.link/LWG2549>`__","Tuple EXPLICIT constructor templates that take tuple parameters end up taking references to temporaries and will create dangling references","Oulu","|Complete|",""
|
||||
"`2550 <https://wg21.link/LWG2550>`__","Wording of unordered container's clear() method complexity","Oulu","|Complete|",""
|
||||
|
|
@ -925,6 +925,7 @@ set(files
|
||||
experimental/iterator
|
||||
experimental/list
|
||||
experimental/map
|
||||
experimental/memory
|
||||
experimental/memory_resource
|
||||
experimental/propagate_const
|
||||
experimental/regex
|
||||
|
@ -91,6 +91,7 @@
|
||||
#include <experimental/iterator>
|
||||
#include <experimental/list>
|
||||
#include <experimental/map>
|
||||
#include <experimental/memory>
|
||||
#include <experimental/memory_resource>
|
||||
#include <experimental/propagate_const>
|
||||
#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
|
||||
|
194
libcxx/include/experimental/memory
Normal file
194
libcxx/include/experimental/memory
Normal file
@ -0,0 +1,194 @@
|
||||
// -*- C++ -*-
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP_EXPERIMENTAL_MEMORY
|
||||
#define _LIBCPP_EXPERIMENTAL_MEMORY
|
||||
|
||||
/*
|
||||
experimental/memory synopsis
|
||||
|
||||
namespace std::experimental::inline fundamentals_v2 {
|
||||
|
||||
template <class W> class observer_ptr {
|
||||
public:
|
||||
using element_type = W;
|
||||
using pointer = add_pointer_t<W>; // exposition-only
|
||||
using reference = add_lvalue_reference_t<W>; // exposition-only
|
||||
|
||||
// default ctor
|
||||
constexpr observer_ptr() noexcept;
|
||||
|
||||
// pointer-accepting ctors
|
||||
constexpr observer_ptr(nullptr_t) noexcept;
|
||||
constexpr explicit observer_ptr(pointer) noexcept;
|
||||
|
||||
// copying ctors (in addition to compiler-generated copy ctor)
|
||||
template <class W2> constexpr observer_ptr(observer_ptr<W2>) noexcept;
|
||||
|
||||
// observers
|
||||
constexpr pointer get() const noexcept;
|
||||
constexpr reference operator*() const;
|
||||
constexpr pointer operator->() const noexcept;
|
||||
constexpr explicit operator bool() const noexcept;
|
||||
|
||||
// conversions
|
||||
constexpr explicit operator pointer() const noexcept;
|
||||
|
||||
// modifiers
|
||||
constexpr pointer release() noexcept;
|
||||
constexpr void reset(pointer = nullptr) noexcept;
|
||||
constexpr void swap(observer_ptr&) noexcept;
|
||||
};
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
#include <__functional/hash.h>
|
||||
#include <__functional/operations.h>
|
||||
#include <__type_traits/add_lvalue_reference.h>
|
||||
#include <__type_traits/add_pointer.h>
|
||||
#include <__type_traits/common_type.h>
|
||||
#include <__type_traits/enable_if.h>
|
||||
#include <__type_traits/is_convertible.h>
|
||||
#include <cstddef>
|
||||
#include <experimental/__config>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
#ifdef _LIBCPP_ENABLE_EXPERIMENTAL
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_LFTS_V2
|
||||
|
||||
# if _LIBCPP_STD_VER >= 17
|
||||
|
||||
template <class _Wp>
|
||||
class observer_ptr {
|
||||
public:
|
||||
using element_type = _Wp;
|
||||
|
||||
// constructors
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr observer_ptr() noexcept : __ptr_(nullptr) {}
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr observer_ptr(nullptr_t) noexcept : __ptr_(nullptr) {}
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr explicit observer_ptr(element_type* __p) noexcept : __ptr_(__p) {}
|
||||
|
||||
template <class _W2, class = __enable_if_t<is_convertible<_W2*, _Wp*>::value>>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr observer_ptr(observer_ptr<_W2> __other) noexcept : __ptr_(__other.get()) {}
|
||||
|
||||
// observers
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr element_type* get() const noexcept { return __ptr_; }
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr add_lvalue_reference_t<_Wp> operator*() const { return *__ptr_; }
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr element_type* operator->() const noexcept { return __ptr_; }
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr explicit operator bool() const noexcept { return __ptr_ != nullptr; }
|
||||
|
||||
// conversions
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr explicit operator element_type*() const noexcept { return __ptr_; }
|
||||
|
||||
// modifiers
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr void reset(element_type* __p = nullptr) noexcept { __ptr_ = __p; }
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr void swap(observer_ptr& __other) noexcept {
|
||||
observer_ptr __tmp = __other;
|
||||
__other = *this;
|
||||
*this = __tmp;
|
||||
}
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr element_type* release() noexcept {
|
||||
observer_ptr __p;
|
||||
__p.swap(*this);
|
||||
return __p.get();
|
||||
}
|
||||
|
||||
private:
|
||||
element_type* __ptr_;
|
||||
};
|
||||
|
||||
// specializations
|
||||
|
||||
template <class _Wp>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr void swap(observer_ptr<_Wp>& __a, observer_ptr<_Wp>& __b) noexcept {
|
||||
__a.swap(__b);
|
||||
}
|
||||
|
||||
template <class _Wp>
|
||||
_LIBCPP_HIDE_FROM_ABI observer_ptr<_Wp> make_observer(_Wp* __ptr) noexcept {
|
||||
return observer_ptr<_Wp>{__ptr};
|
||||
}
|
||||
|
||||
template <class _W1, class _W2>
|
||||
_LIBCPP_HIDE_FROM_ABI bool operator==(observer_ptr<_W1> __a, observer_ptr<_W2> __b) {
|
||||
return __a.get() == __b.get();
|
||||
}
|
||||
|
||||
template <class _W1, class _W2>
|
||||
_LIBCPP_HIDE_FROM_ABI bool operator!=(observer_ptr<_W1> __a, observer_ptr<_W2> __b) {
|
||||
return !(__a == __b);
|
||||
}
|
||||
|
||||
template <class _Wp>
|
||||
_LIBCPP_HIDE_FROM_ABI bool operator==(observer_ptr<_Wp> __p, nullptr_t) {
|
||||
return !__p;
|
||||
}
|
||||
|
||||
template <class _Wp>
|
||||
_LIBCPP_HIDE_FROM_ABI bool operator==(nullptr_t, observer_ptr<_Wp> __p) {
|
||||
return !__p;
|
||||
}
|
||||
|
||||
template <class _Wp>
|
||||
_LIBCPP_HIDE_FROM_ABI bool operator!=(observer_ptr<_Wp> __p, nullptr_t) {
|
||||
return (bool)__p;
|
||||
}
|
||||
|
||||
template <class _Wp>
|
||||
_LIBCPP_HIDE_FROM_ABI bool operator!=(nullptr_t, observer_ptr<_Wp> __p) {
|
||||
return (bool)__p;
|
||||
}
|
||||
|
||||
template <class _W1, class _W2>
|
||||
_LIBCPP_HIDE_FROM_ABI bool operator<(observer_ptr<_W1> __a, observer_ptr<_W2> __b) {
|
||||
return std::less<typename std::common_type<_W1*, _W2*>::type>()(__a.get(), __b.get());
|
||||
}
|
||||
|
||||
template <class _W1, class _W2>
|
||||
_LIBCPP_HIDE_FROM_ABI bool operator>(observer_ptr<_W1> __a, observer_ptr<_W2> __b) {
|
||||
return __b < __a;
|
||||
}
|
||||
|
||||
template <class _W1, class _W2>
|
||||
_LIBCPP_HIDE_FROM_ABI bool operator<=(observer_ptr<_W1> __a, observer_ptr<_W2> __b) {
|
||||
return !(__a > __b);
|
||||
}
|
||||
|
||||
template <class _W1, class _W2>
|
||||
_LIBCPP_HIDE_FROM_ABI bool operator>=(observer_ptr<_W1> __a, observer_ptr<_W2> __b) {
|
||||
return !(__a < __b);
|
||||
}
|
||||
|
||||
# endif // _LIBCPP_STD_VER >= 17
|
||||
|
||||
_LIBCPP_END_NAMESPACE_LFTS_V2
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
// hash
|
||||
|
||||
# if _LIBCPP_STD_VER >= 17
|
||||
template <class _Tp>
|
||||
struct hash<experimental::observer_ptr<_Tp>> {
|
||||
_LIBCPP_HIDE_FROM_ABI size_t operator()(const experimental::observer_ptr<_Tp>& __ptr) const noexcept {
|
||||
return hash<_Tp*>()(__ptr.get());
|
||||
}
|
||||
};
|
||||
# endif // _LIBCPP_STD_VER >= 17
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP_ENABLE_EXPERIMENTAL
|
||||
|
||||
#endif /* _LIBCPP_EXPERIMENTAL_MEMORY */
|
@ -533,6 +533,10 @@ module std_experimental [system] {
|
||||
header "experimental/map"
|
||||
export *
|
||||
}
|
||||
module memory {
|
||||
header "experimental/memory"
|
||||
export *
|
||||
}
|
||||
module memory_resource {
|
||||
header "experimental/memory_resource"
|
||||
export *
|
||||
|
@ -241,6 +241,10 @@ experimental/list experimental/memory_resource
|
||||
experimental/list list
|
||||
experimental/map experimental/memory_resource
|
||||
experimental/map map
|
||||
experimental/memory cstddef
|
||||
experimental/memory cstdint
|
||||
experimental/memory cstring
|
||||
experimental/memory limits
|
||||
experimental/memory_resource atomic
|
||||
experimental/memory_resource climits
|
||||
experimental/memory_resource concepts
|
||||
|
|
@ -242,6 +242,10 @@ experimental/list experimental/memory_resource
|
||||
experimental/list list
|
||||
experimental/map experimental/memory_resource
|
||||
experimental/map map
|
||||
experimental/memory cstddef
|
||||
experimental/memory cstdint
|
||||
experimental/memory cstring
|
||||
experimental/memory limits
|
||||
experimental/memory_resource atomic
|
||||
experimental/memory_resource climits
|
||||
experimental/memory_resource concepts
|
||||
|
|
@ -242,6 +242,10 @@ experimental/list experimental/memory_resource
|
||||
experimental/list list
|
||||
experimental/map experimental/memory_resource
|
||||
experimental/map map
|
||||
experimental/memory cstddef
|
||||
experimental/memory cstdint
|
||||
experimental/memory cstring
|
||||
experimental/memory limits
|
||||
experimental/memory_resource atomic
|
||||
experimental/memory_resource climits
|
||||
experimental/memory_resource concepts
|
||||
|
|
@ -242,6 +242,10 @@ experimental/list experimental/memory_resource
|
||||
experimental/list list
|
||||
experimental/map experimental/memory_resource
|
||||
experimental/map map
|
||||
experimental/memory cstddef
|
||||
experimental/memory cstdint
|
||||
experimental/memory cstring
|
||||
experimental/memory limits
|
||||
experimental/memory_resource atomic
|
||||
experimental/memory_resource climits
|
||||
experimental/memory_resource concepts
|
||||
|
|
@ -248,6 +248,10 @@ experimental/list experimental/memory_resource
|
||||
experimental/list list
|
||||
experimental/map experimental/memory_resource
|
||||
experimental/map map
|
||||
experimental/memory cstddef
|
||||
experimental/memory cstdint
|
||||
experimental/memory cstring
|
||||
experimental/memory limits
|
||||
experimental/memory_resource atomic
|
||||
experimental/memory_resource climits
|
||||
experimental/memory_resource concepts
|
||||
|
|
@ -170,6 +170,10 @@ experimental/list experimental/memory_resource
|
||||
experimental/list list
|
||||
experimental/map experimental/memory_resource
|
||||
experimental/map map
|
||||
experimental/memory cstddef
|
||||
experimental/memory cstdint
|
||||
experimental/memory cstring
|
||||
experimental/memory limits
|
||||
experimental/memory_resource cstddef
|
||||
experimental/memory_resource experimental/utility
|
||||
experimental/memory_resource limits
|
||||
|
|
@ -170,6 +170,10 @@ experimental/list experimental/memory_resource
|
||||
experimental/list list
|
||||
experimental/map experimental/memory_resource
|
||||
experimental/map map
|
||||
experimental/memory cstddef
|
||||
experimental/memory cstdint
|
||||
experimental/memory cstring
|
||||
experimental/memory limits
|
||||
experimental/memory_resource cstddef
|
||||
experimental/memory_resource experimental/utility
|
||||
experimental/memory_resource limits
|
||||
|
|
@ -0,0 +1,179 @@
|
||||
// -*- C++ -*-
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++03, c++11, c++14
|
||||
// REQUIRES: c++experimental
|
||||
|
||||
// <experimental/memory>
|
||||
|
||||
// observer_ptr
|
||||
//
|
||||
// template <class W1, class W2>
|
||||
// bool operator==(const observer_ptr<W1>& p1, const observer_ptr<W2>& p2);
|
||||
//
|
||||
// template <class W1, class W2>
|
||||
// bool operator!=(const observer_ptr<W1>& p1, const observer_ptr<W2>& p2);
|
||||
//
|
||||
// template <class W>
|
||||
// bool operator==(const observer_ptr<W>& p, std::nullptr_t) noexcept;
|
||||
//
|
||||
// template <class W>
|
||||
// bool operator==(std::nullptr_t, const observer_ptr<W>& p) noexcept;
|
||||
//
|
||||
// template <class W>
|
||||
// bool operator!=(const observer_ptr<W>& p, std::nullptr_t) noexcept;
|
||||
//
|
||||
// template <class W>
|
||||
// bool operator!=(std::nullptr_t, const observer_ptr<W>& p) noexcept;
|
||||
//
|
||||
// template <class W1, class W2>
|
||||
// bool operator<(const observer_ptr<W1>& p1, const observer_ptr<W2>& p2);
|
||||
//
|
||||
// template <class W1, class W2>
|
||||
// bool operator>(const observer_ptr<W1>& p1, const observer_ptr<W2>& p2);
|
||||
//
|
||||
// template <class W1, class W2>
|
||||
// bool operator<=(const observer_ptr<W1>& p1, const observer_ptr<W2>& p2);
|
||||
//
|
||||
// template <class W1, class W2>
|
||||
// bool operator>=(const observer_ptr<W1>& p1, const observer_ptr<W2>& p2);
|
||||
|
||||
#include <experimental/memory>
|
||||
#include <cassert>
|
||||
|
||||
void test() {
|
||||
using T = int;
|
||||
using Ptr = std::experimental::observer_ptr<T>;
|
||||
using VoidPtr = std::experimental::observer_ptr<void>;
|
||||
|
||||
// operator==(observer_ptr, observer_ptr)
|
||||
{
|
||||
T obj1, obj2;
|
||||
Ptr ptr1(&obj1), ptr1_x(&obj1);
|
||||
Ptr ptr2(&obj2);
|
||||
VoidPtr ptr3(&obj1);
|
||||
|
||||
assert(!(ptr1 == ptr2));
|
||||
assert(ptr1 == ptr1_x);
|
||||
|
||||
assert(ptr1 == ptr3);
|
||||
}
|
||||
|
||||
// operator!=(observer_ptr, observer_ptr)
|
||||
{
|
||||
T obj1, obj2;
|
||||
Ptr ptr1(&obj1), ptr1_x(&obj1);
|
||||
Ptr ptr2(&obj2);
|
||||
VoidPtr ptr3(&obj1);
|
||||
|
||||
assert(ptr1 != ptr2);
|
||||
assert(!(ptr1 != ptr1_x));
|
||||
|
||||
assert(ptr2 != ptr3);
|
||||
}
|
||||
|
||||
// operator==(observer_ptr, nullptr_t)
|
||||
{
|
||||
T obj1;
|
||||
Ptr ptr1(&obj1);
|
||||
Ptr ptr2(nullptr);
|
||||
|
||||
assert(!(ptr1 == nullptr));
|
||||
assert(ptr2 == nullptr);
|
||||
}
|
||||
|
||||
// operator==(nullptr_t, observer_ptr)
|
||||
{
|
||||
T obj1;
|
||||
Ptr ptr1(&obj1);
|
||||
Ptr ptr2(nullptr);
|
||||
|
||||
assert(!(nullptr == ptr1));
|
||||
assert(nullptr == ptr2);
|
||||
}
|
||||
|
||||
// operator!=(observer_ptr, nullptr_t)
|
||||
{
|
||||
T obj1;
|
||||
Ptr ptr1(&obj1);
|
||||
Ptr ptr2(nullptr);
|
||||
|
||||
assert(ptr1 != nullptr);
|
||||
assert(!(ptr2 != nullptr));
|
||||
}
|
||||
|
||||
// operator!=(nullptr_t, observer_ptr)
|
||||
{
|
||||
T obj1;
|
||||
Ptr ptr1(&obj1);
|
||||
Ptr ptr2(nullptr);
|
||||
|
||||
assert(nullptr != ptr1);
|
||||
assert(!(nullptr != ptr2));
|
||||
}
|
||||
|
||||
// operator<(observer_ptr, observer_ptr)
|
||||
{
|
||||
T obj1, obj2;
|
||||
Ptr ptr1(&obj1);
|
||||
Ptr ptr2(&obj2);
|
||||
VoidPtr ptr3(&obj1);
|
||||
|
||||
assert(!(ptr1 < ptr1));
|
||||
assert((ptr1 < ptr2) == (&obj1 < &obj2));
|
||||
|
||||
assert(!(ptr1 < ptr3));
|
||||
}
|
||||
|
||||
// operator>(observer_ptr, observer_ptr)
|
||||
{
|
||||
T obj1, obj2;
|
||||
Ptr ptr1(&obj1);
|
||||
Ptr ptr2(&obj2);
|
||||
VoidPtr ptr3(&obj1);
|
||||
|
||||
assert(!(ptr1 > ptr1));
|
||||
assert((ptr1 > ptr2) == (&obj1 > &obj2));
|
||||
|
||||
assert(!(ptr1 > ptr3));
|
||||
}
|
||||
|
||||
// operator<=(observer_ptr, observer_ptr)
|
||||
{
|
||||
T obj1, obj2;
|
||||
Ptr ptr1(&obj1);
|
||||
Ptr ptr2(&obj2);
|
||||
VoidPtr ptr3(&obj1);
|
||||
|
||||
assert(ptr1 <= ptr1);
|
||||
assert((ptr1 <= ptr2) == (&obj1 <= &obj2));
|
||||
|
||||
assert(ptr1 <= ptr3);
|
||||
}
|
||||
|
||||
// operator>=(observer_ptr, observer_ptr)
|
||||
{
|
||||
T obj1, obj2;
|
||||
Ptr ptr1(&obj1);
|
||||
Ptr ptr2(&obj2);
|
||||
VoidPtr ptr3(&obj1);
|
||||
|
||||
assert(ptr1 >= ptr1);
|
||||
assert((ptr1 >= ptr2) == (&obj1 >= &obj2));
|
||||
|
||||
assert(ptr1 >= ptr3);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int, char**) {
|
||||
// Note: this is not constexpr in the spec
|
||||
test();
|
||||
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,75 @@
|
||||
// -*- C++ -*-
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++03, c++11, c++14
|
||||
// REQUIRES: c++experimental
|
||||
|
||||
// <experimental/memory>
|
||||
|
||||
// observer_ptr
|
||||
//
|
||||
// template <class W2>
|
||||
// constexpr observer_ptr(observer_ptr<W2> other) noexcept;
|
||||
|
||||
#include <experimental/memory>
|
||||
#include <type_traits>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
|
||||
template <class To, class From>
|
||||
constexpr void test_converting_ctor() {
|
||||
using ToPtr = std::experimental::observer_ptr<To>;
|
||||
using FromPtr = std::experimental::observer_ptr<From>;
|
||||
From obj;
|
||||
FromPtr from(&obj);
|
||||
ToPtr to = from;
|
||||
|
||||
assert(from.get() == &obj);
|
||||
assert(to.get() == &obj);
|
||||
#if TEST_STD_VER >= 20
|
||||
static_assert(std::is_nothrow_convertible<FromPtr, ToPtr>::value);
|
||||
#endif
|
||||
}
|
||||
|
||||
template <class To, class From>
|
||||
constexpr void check_non_constructible() {
|
||||
using ToPtr = std::experimental::observer_ptr<To>;
|
||||
using FromPtr = std::experimental::observer_ptr<From>;
|
||||
static_assert(!std::is_constructible<ToPtr, FromPtr>::value);
|
||||
}
|
||||
|
||||
struct Bar {};
|
||||
struct Base {};
|
||||
struct Derived : Base {};
|
||||
|
||||
constexpr bool test() {
|
||||
test_converting_ctor<void, Bar>();
|
||||
test_converting_ctor<void, int>();
|
||||
test_converting_ctor<Base, Derived>();
|
||||
|
||||
check_non_constructible<Derived, Base>();
|
||||
check_non_constructible<int, void>();
|
||||
check_non_constructible<Bar, void>();
|
||||
check_non_constructible<int, long>();
|
||||
check_non_constructible<long, int>();
|
||||
|
||||
// Check const-ness
|
||||
check_non_constructible<Bar, Bar const>();
|
||||
test_converting_ctor<Bar const, Bar>();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int main(int, char**) {
|
||||
test();
|
||||
static_assert(test());
|
||||
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,60 @@
|
||||
// -*- C++ -*-
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++03, c++11, c++14
|
||||
// REQUIRES: c++experimental
|
||||
|
||||
// <experimental/memory>
|
||||
|
||||
// observer_ptr
|
||||
//
|
||||
// observer_ptr(const observer_ptr& other) = default;
|
||||
// observer_ptr(observer_ptr&& other) = default;
|
||||
|
||||
#include <experimental/memory>
|
||||
#include <cassert>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
template <class T, class Object = T>
|
||||
constexpr void test_copy_move() {
|
||||
using Ptr = std::experimental::observer_ptr<T>;
|
||||
Object obj;
|
||||
{
|
||||
Ptr ptr(&obj);
|
||||
Ptr copy = ptr;
|
||||
assert(ptr.get() == &obj);
|
||||
assert(copy.get() == &obj);
|
||||
static_assert(std::is_nothrow_copy_constructible<Ptr>::value);
|
||||
}
|
||||
{
|
||||
Ptr ptr(&obj);
|
||||
Ptr copy = std::move(ptr);
|
||||
assert(ptr.get() == &obj);
|
||||
assert(copy.get() == &obj);
|
||||
static_assert(std::is_nothrow_move_constructible<Ptr>::value);
|
||||
}
|
||||
}
|
||||
|
||||
struct Bar {};
|
||||
|
||||
constexpr bool test() {
|
||||
test_copy_move<int>();
|
||||
test_copy_move<Bar>();
|
||||
test_copy_move<void, int>();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int main(int, char**) {
|
||||
test();
|
||||
static_assert(test());
|
||||
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
// -*- C++ -*-
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++03, c++11, c++14
|
||||
// REQUIRES: c++experimental
|
||||
|
||||
// <experimental/memory>
|
||||
|
||||
// observer_ptr
|
||||
//
|
||||
// constexpr observer_ptr() noexcept;
|
||||
|
||||
#include <experimental/memory>
|
||||
#include <type_traits>
|
||||
#include <cassert>
|
||||
|
||||
template <class T>
|
||||
constexpr void test_default_ctor() {
|
||||
using Ptr = std::experimental::observer_ptr<T>;
|
||||
Ptr ptr;
|
||||
assert(ptr.get() == nullptr);
|
||||
static_assert(std::is_nothrow_default_constructible<Ptr>::value);
|
||||
}
|
||||
|
||||
struct Foo;
|
||||
struct Bar {
|
||||
Bar(int) {}
|
||||
};
|
||||
|
||||
constexpr bool test() {
|
||||
test_default_ctor<Foo>();
|
||||
test_default_ctor<Bar>();
|
||||
test_default_ctor<int>();
|
||||
test_default_ctor<void>();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int main(int, char**) {
|
||||
test();
|
||||
static_assert(test());
|
||||
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
// -*- C++ -*-
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++03, c++11, c++14
|
||||
// REQUIRES: c++experimental
|
||||
|
||||
// <experimental/memory>
|
||||
|
||||
// observer_ptr
|
||||
//
|
||||
// constexpr explicit observer_ptr(element_type* p) noexcept;
|
||||
|
||||
#include <experimental/memory>
|
||||
#include <type_traits>
|
||||
#include <cassert>
|
||||
|
||||
template <class T, class ObjectT = T>
|
||||
constexpr void test_element_type_ctor() {
|
||||
using Ptr = std::experimental::observer_ptr<T>;
|
||||
ObjectT obj;
|
||||
T* raw = &obj;
|
||||
Ptr ptr(raw);
|
||||
assert(ptr.get() == raw);
|
||||
static_assert(!std::is_convertible<T*, Ptr>::value);
|
||||
static_assert(std::is_nothrow_constructible<Ptr, T*>::value);
|
||||
}
|
||||
|
||||
struct Bar {};
|
||||
|
||||
constexpr bool test() {
|
||||
test_element_type_ctor<Bar>();
|
||||
test_element_type_ctor<int>();
|
||||
test_element_type_ctor<void, int>();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int main(int, char**) {
|
||||
test();
|
||||
static_assert(test());
|
||||
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
// -*- C++ -*-
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++03, c++11, c++14
|
||||
// REQUIRES: c++experimental
|
||||
|
||||
// <experimental/memory>
|
||||
|
||||
// observer_ptr
|
||||
//
|
||||
// constexpr observer_ptr(nullptr_t) noexcept;
|
||||
|
||||
#include <experimental/memory>
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
#include <type_traits>
|
||||
|
||||
template <class T>
|
||||
constexpr void test_nullptr_ctor() {
|
||||
using Ptr = std::experimental::observer_ptr<T>;
|
||||
Ptr ptr = nullptr;
|
||||
assert(ptr.get() == nullptr);
|
||||
static_assert(std::is_nothrow_constructible<Ptr, std::nullptr_t>::value);
|
||||
}
|
||||
|
||||
struct Foo;
|
||||
struct Bar {
|
||||
Bar(int) {}
|
||||
};
|
||||
|
||||
constexpr bool test() {
|
||||
test_nullptr_ctor<Foo>();
|
||||
test_nullptr_ctor<Bar>();
|
||||
test_nullptr_ctor<int>();
|
||||
test_nullptr_ctor<void>();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int main(int, char**) {
|
||||
test();
|
||||
static_assert(test());
|
||||
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,65 @@
|
||||
// -*- C++ -*-
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++03, c++11, c++14
|
||||
// REQUIRES: c++experimental
|
||||
|
||||
// <experimental/memory>
|
||||
|
||||
// observer_ptr
|
||||
//
|
||||
// constexpr std::add_lvalue_reference_t<element_type> operator*() const;
|
||||
// constexpr element_type* operator->() const noexcept;
|
||||
|
||||
#include <experimental/memory>
|
||||
#include <type_traits>
|
||||
#include <cassert>
|
||||
|
||||
template <class T, class Object = T>
|
||||
constexpr void test_deref() {
|
||||
using Ptr = std::experimental::observer_ptr<T>;
|
||||
Object obj;
|
||||
|
||||
{
|
||||
Ptr const ptr(&obj);
|
||||
T& r = *ptr;
|
||||
assert(&r == &obj);
|
||||
}
|
||||
{
|
||||
Ptr const ptr(&obj);
|
||||
T* r = ptr.operator->();
|
||||
assert(r == &obj);
|
||||
static_assert(noexcept(ptr.operator->()));
|
||||
}
|
||||
}
|
||||
|
||||
struct Bar {};
|
||||
struct Foo {
|
||||
int member = 42;
|
||||
};
|
||||
|
||||
constexpr bool test() {
|
||||
test_deref<Bar>();
|
||||
test_deref<int>();
|
||||
|
||||
{
|
||||
Foo foo;
|
||||
std::experimental::observer_ptr<Foo> ptr(&foo);
|
||||
assert(&ptr->member == &foo.member);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int main(int, char**) {
|
||||
test();
|
||||
static_assert(test());
|
||||
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
// -*- C++ -*-
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++03, c++11, c++14
|
||||
// REQUIRES: c++experimental
|
||||
|
||||
// <experimental/memory>
|
||||
|
||||
// observer_ptr
|
||||
//
|
||||
// constexpr element_type* get() const noexcept;
|
||||
|
||||
#include <experimental/memory>
|
||||
#include <type_traits>
|
||||
#include <cassert>
|
||||
|
||||
template <class T, class Object = T>
|
||||
constexpr void test_get() {
|
||||
using Ptr = std::experimental::observer_ptr<T>;
|
||||
Object obj;
|
||||
|
||||
Ptr const ptr(&obj);
|
||||
assert(ptr.get() == &obj);
|
||||
|
||||
static_assert(noexcept(ptr.get()));
|
||||
static_assert(std::is_same<decltype(ptr.get()), T*>::value);
|
||||
}
|
||||
|
||||
struct Bar {};
|
||||
|
||||
constexpr bool test() {
|
||||
test_get<Bar>();
|
||||
test_get<int>();
|
||||
test_get<void, int>();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int main(int, char**) {
|
||||
test();
|
||||
static_assert(test());
|
||||
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++03, c++11, c++14
|
||||
// REQUIRES: c++experimental
|
||||
|
||||
// <experimental/memory>
|
||||
|
||||
// observer_ptr
|
||||
//
|
||||
// template <class T> struct hash<std::experimental::observer_ptr<T>>;
|
||||
|
||||
#include <experimental/memory>
|
||||
#include <cassert>
|
||||
|
||||
#include "poisoned_hash_helper.h"
|
||||
|
||||
template <class T, class Object = T>
|
||||
void test_hash() {
|
||||
{
|
||||
using Ptr = std::experimental::observer_ptr<T>;
|
||||
Object obj;
|
||||
Ptr ptr(&obj);
|
||||
|
||||
std::hash<std::experimental::observer_ptr<T>> f;
|
||||
std::size_t h = f(ptr);
|
||||
|
||||
assert(h == std::hash<T*>()(&obj));
|
||||
}
|
||||
|
||||
test_hash_enabled_for_type<std::experimental::observer_ptr<T>>();
|
||||
}
|
||||
|
||||
struct Bar {};
|
||||
|
||||
void test() {
|
||||
test_hash<void, int>();
|
||||
test_hash<int>();
|
||||
test_hash<Bar>();
|
||||
}
|
||||
|
||||
int main(int, char**) {
|
||||
// Note: This isn't constexpr friendly in the spec!
|
||||
test();
|
||||
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++03, c++11, c++14
|
||||
// REQUIRES: c++experimental
|
||||
|
||||
// <experimental/memory>
|
||||
|
||||
// observer_ptr
|
||||
//
|
||||
// template <class W>
|
||||
// std::experimental::observer_ptr<W> make_observer(W* p) noexcept;
|
||||
|
||||
#include <experimental/memory>
|
||||
#include <cassert>
|
||||
#include <type_traits>
|
||||
|
||||
template <class T, class Object = T>
|
||||
void test_make_observer() {
|
||||
using Ptr = std::experimental::observer_ptr<T>;
|
||||
Object obj;
|
||||
T* raw = &obj;
|
||||
|
||||
Ptr ptr = std::experimental::make_observer(raw);
|
||||
assert(ptr.get() == raw);
|
||||
static_assert(noexcept(std::experimental::make_observer(raw)));
|
||||
static_assert(std::is_same<decltype(std::experimental::make_observer(raw)), Ptr>::value);
|
||||
}
|
||||
|
||||
struct Bar {};
|
||||
|
||||
void test() {
|
||||
test_make_observer<void, int>();
|
||||
test_make_observer<int>();
|
||||
test_make_observer<Bar>();
|
||||
}
|
||||
|
||||
int main(int, char**) {
|
||||
// Note: this is not constexpr in the spec
|
||||
test();
|
||||
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
// -*- C++ -*-
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++03, c++11, c++14
|
||||
// REQUIRES: c++experimental
|
||||
|
||||
// <experimental/memory>
|
||||
|
||||
// observer_ptr
|
||||
//
|
||||
// constexpr explicit operator bool() const noexcept;
|
||||
|
||||
#include <experimental/memory>
|
||||
#include <type_traits>
|
||||
#include <cassert>
|
||||
|
||||
template <class T, class Object = T>
|
||||
constexpr void test_operator_bool() {
|
||||
using Ptr = std::experimental::observer_ptr<T>;
|
||||
Object obj;
|
||||
|
||||
{
|
||||
Ptr const ptr(&obj);
|
||||
bool b = static_cast<bool>(ptr);
|
||||
assert(b);
|
||||
|
||||
static_assert(noexcept(static_cast<bool>(ptr)));
|
||||
}
|
||||
|
||||
{
|
||||
Ptr const ptr(nullptr);
|
||||
bool b = static_cast<bool>(ptr);
|
||||
assert(!b);
|
||||
}
|
||||
|
||||
static_assert(!std::is_convertible<Ptr const, bool>::value);
|
||||
static_assert(std::is_constructible<bool, Ptr const>::value);
|
||||
}
|
||||
|
||||
struct Bar {};
|
||||
|
||||
constexpr bool test() {
|
||||
test_operator_bool<Bar>();
|
||||
test_operator_bool<int>();
|
||||
test_operator_bool<void, int>();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int main(int, char**) {
|
||||
test();
|
||||
static_assert(test());
|
||||
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
// -*- C++ -*-
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++03, c++11, c++14
|
||||
// REQUIRES: c++experimental
|
||||
|
||||
// <experimental/memory>
|
||||
|
||||
// observer_ptr
|
||||
//
|
||||
// constexpr explicit operator element_type*() const noexcept;
|
||||
|
||||
#include <experimental/memory>
|
||||
#include <type_traits>
|
||||
#include <cassert>
|
||||
|
||||
template <class T, class Object = T>
|
||||
constexpr void test_convertibility() {
|
||||
Object obj;
|
||||
std::experimental::observer_ptr<T> ptr(&obj);
|
||||
|
||||
T* raw = static_cast<T*>(ptr);
|
||||
assert(raw == &obj);
|
||||
static_assert(!std::is_convertible<std::experimental::observer_ptr<T>, T*>::value, "");
|
||||
static_assert(std::is_constructible<T*, std::experimental::observer_ptr<T>>::value, "");
|
||||
}
|
||||
|
||||
struct Incomplete;
|
||||
|
||||
struct Bar {};
|
||||
|
||||
constexpr bool test() {
|
||||
test_convertibility<void, int>();
|
||||
test_convertibility<bool>();
|
||||
test_convertibility<int>();
|
||||
test_convertibility<Bar>();
|
||||
|
||||
{
|
||||
std::experimental::observer_ptr<Incomplete> ptr = nullptr;
|
||||
Incomplete* raw = static_cast<Incomplete*>(ptr);
|
||||
assert(raw == nullptr);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int main(int, char**) {
|
||||
test();
|
||||
static_assert(test());
|
||||
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
// -*- C++ -*-
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++03, c++11, c++14
|
||||
// REQUIRES: c++experimental
|
||||
|
||||
// <experimental/memory>
|
||||
|
||||
// observer_ptr
|
||||
//
|
||||
// constexpr element_type* release() noexcept;
|
||||
|
||||
#include <experimental/memory>
|
||||
#include <type_traits>
|
||||
#include <cassert>
|
||||
|
||||
template <class T, class Object = T>
|
||||
constexpr void test_release() {
|
||||
Object obj;
|
||||
using Ptr = std::experimental::observer_ptr<T>;
|
||||
Ptr ptr(&obj);
|
||||
assert(ptr.get() == &obj);
|
||||
|
||||
decltype(auto) r = ptr.release();
|
||||
assert(r == &obj);
|
||||
assert(ptr.get() == nullptr);
|
||||
|
||||
static_assert(std::is_same<decltype(r), typename Ptr::element_type*>::value);
|
||||
static_assert(noexcept(ptr.release()));
|
||||
}
|
||||
|
||||
struct Bar {};
|
||||
|
||||
constexpr bool test() {
|
||||
test_release<Bar>();
|
||||
test_release<int>();
|
||||
test_release<void, int>();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int main(int, char**) {
|
||||
test();
|
||||
static_assert(test());
|
||||
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
// -*- C++ -*-
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++03, c++11, c++14
|
||||
// REQUIRES: c++experimental
|
||||
|
||||
// <experimental/memory>
|
||||
|
||||
// observer_ptr
|
||||
//
|
||||
// constexpr void reset(element_type* p = nullptr) noexcept;
|
||||
|
||||
#include <experimental/memory>
|
||||
#include <type_traits>
|
||||
#include <cassert>
|
||||
|
||||
template <class T, class Object = T>
|
||||
constexpr void test_reset() {
|
||||
using Ptr = std::experimental::observer_ptr<T>;
|
||||
Object obj1, obj2;
|
||||
|
||||
{
|
||||
Ptr ptr(&obj1);
|
||||
assert(ptr.get() == &obj1);
|
||||
ptr.reset(&obj2);
|
||||
assert(ptr.get() == &obj2);
|
||||
static_assert(noexcept(ptr.reset(&obj2)));
|
||||
static_assert(std::is_same<decltype(ptr.reset(&obj2)), void>::value);
|
||||
}
|
||||
{
|
||||
Ptr ptr(&obj1);
|
||||
assert(ptr.get() == &obj1);
|
||||
ptr.reset();
|
||||
assert(ptr.get() == nullptr);
|
||||
static_assert(noexcept(ptr.reset()));
|
||||
static_assert(std::is_same<decltype(ptr.reset()), void>::value);
|
||||
}
|
||||
}
|
||||
|
||||
struct Bar {};
|
||||
|
||||
constexpr bool test() {
|
||||
test_reset<Bar>();
|
||||
test_reset<int>();
|
||||
test_reset<void, int>();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int main(int, char**) {
|
||||
test();
|
||||
static_assert(test());
|
||||
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,79 @@
|
||||
// -*- C++ -*-
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++03, c++11, c++14
|
||||
// REQUIRES: c++experimental
|
||||
|
||||
// <experimental/memory>
|
||||
|
||||
// observer_ptr
|
||||
//
|
||||
// constexpr void swap(observer_ptr& other) noexcept;
|
||||
//
|
||||
// template <class W>
|
||||
// void swap(observer_ptr<W>& lhs, observer_ptr<W>& rhs) noexcept;
|
||||
|
||||
#include <experimental/memory>
|
||||
#include <type_traits>
|
||||
#include <cassert>
|
||||
|
||||
template <class T, class Object = T>
|
||||
constexpr void test_swap() {
|
||||
using Ptr = std::experimental::observer_ptr<T>;
|
||||
Object obj1, obj2;
|
||||
|
||||
{
|
||||
Ptr ptr1(&obj1);
|
||||
Ptr ptr2(&obj2);
|
||||
|
||||
assert(ptr1.get() == &obj1);
|
||||
assert(ptr2.get() == &obj2);
|
||||
|
||||
ptr1.swap(ptr2);
|
||||
|
||||
assert(ptr1.get() == &obj2);
|
||||
assert(ptr2.get() == &obj1);
|
||||
|
||||
static_assert(noexcept(ptr1.swap(ptr2)));
|
||||
static_assert(std::is_same<decltype(ptr1.swap(ptr2)), void>::value);
|
||||
}
|
||||
|
||||
{
|
||||
Ptr ptr1(&obj1);
|
||||
Ptr ptr2(&obj2);
|
||||
|
||||
assert(ptr1.get() == &obj1);
|
||||
assert(ptr2.get() == &obj2);
|
||||
|
||||
std::experimental::swap(ptr1, ptr2);
|
||||
|
||||
assert(ptr1.get() == &obj2);
|
||||
assert(ptr2.get() == &obj1);
|
||||
|
||||
static_assert(noexcept(std::experimental::swap(ptr1, ptr2)));
|
||||
static_assert(std::is_same<decltype(std::experimental::swap(ptr1, ptr2)), void>::value);
|
||||
}
|
||||
}
|
||||
|
||||
struct Bar {};
|
||||
|
||||
constexpr bool test() {
|
||||
test_swap<Bar>();
|
||||
test_swap<int>();
|
||||
test_swap<void, int>();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int main(int, char**) {
|
||||
test();
|
||||
static_assert(test());
|
||||
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
// -*- C++ -*-
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++03, c++11, c++14
|
||||
// REQUIRES: c++experimental
|
||||
|
||||
// <experimental/memory>
|
||||
|
||||
// observer_ptr
|
||||
//
|
||||
// using element_type = W;
|
||||
|
||||
#include <experimental/memory>
|
||||
#include <type_traits>
|
||||
|
||||
using T = std::experimental::observer_ptr<int>::element_type;
|
||||
static_assert(std::is_same<T, int>::value);
|
Loading…
x
Reference in New Issue
Block a user