Implement std::experimental::propagate_const from LFTS v2

Summary:
An implementation of std::experimental::propagate_const from Library Fundamentals Technical Specification v2.

No tests are provided for disallowed types like fancy pointers or function pointers as no code was written to handle these.

Reviewers: EricWF, mclow.lists

Differential Revision: http://reviews.llvm.org/D12486


git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@273122 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Jonathan Coe
2016-06-19 19:34:13 +00:00
parent 5270a84ef2
commit ee49613ff4
44 changed files with 2135 additions and 0 deletions

View File

@@ -25,6 +25,10 @@
#define _LIBCPP_END_NAMESPACE_LFTS } } }
#define _VSTD_LFTS _VSTD_EXPERIMENTAL::fundamentals_v1
#define _LIBCPP_BEGIN_NAMESPACE_LFTS_V2 _LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL inline namespace fundamentals_v2 {
#define _LIBCPP_END_NAMESPACE_LFTS_V2 } } }
#define _VSTD_LFTS_V2 _VSTD_EXPERIMENTAL::fundamentals_v2
#define _LIBCPP_BEGIN_NAMESPACE_LFTS_PMR _LIBCPP_BEGIN_NAMESPACE_LFTS namespace pmr {
#define _LIBCPP_END_NAMESPACE_LFTS_PMR _LIBCPP_END_NAMESPACE_LFTS }
#define _VSTD_LFTS_PMR _VSTD_LFTS::pmr

View File

@@ -0,0 +1,576 @@
// -*- C++ -*-
//===------------------------ propagate_const -----------------------------===//
//
// 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.
//
//===----------------------------------------------------------------------===//
#ifndef _LIBCPP_EXPERIMENTAL_PROPAGATE_CONST
#define _LIBCPP_EXPERIMENTAL_PROPAGATE_CONST
/*
propagate_const synopsis
namespace std { namespace experimental { inline namespace fundamentals_v2 {
// [propagate_const]
template <class T> class propagate_const;
// [propagate_const.underlying], underlying pointer access
constexpr const _Tp& _VSTD_LFTS_V2::get_underlying(const propagate_const<T>& pt) noexcept;
constexpr T& _VSTD_LFTS_V2::get_underlying(propagate_const<T>& pt) noexcept;
// [propagate_const.relational], relational operators
template <class T> constexpr bool operator==(const propagate_const<T>& pt, nullptr_t);
template <class T> constexpr bool operator==(nullptr_t, const propagate_const<T>& pu);
template <class T> constexpr bool operator!=(const propagate_const<T>& pt, nullptr_t);
template <class T> constexpr bool operator!=(nullptr_t, const propagate_const<T>& pu);
template <class T, class U> constexpr bool operator==(const propagate_const<T>& pt, const propagate_const<_Up>& pu);
template <class T, class U> constexpr bool operator!=(const propagate_const<T>& pt, const propagate_const<_Up>& pu);
template <class T, class U> constexpr bool operator<(const propagate_const<T>& pt, const propagate_const<_Up>& pu);
template <class T, class U> constexpr bool operator>(const propagate_const<T>& pt, const propagate_const<_Up>& pu);
template <class T, class U> constexpr bool operator<=(const propagate_const<T>& pt, const propagate_const<_Up>& pu);
template <class T, class U> constexpr bool operator>=(const propagate_const<T>& pt, const propagate_const<_Up>& pu);
template <class T, class U> constexpr bool operator==(const propagate_const<T>& pt, const _Up& u);
template <class T, class U> constexpr bool operator!=(const propagate_const<T>& pt, const _Up& u);
template <class T, class U> constexpr bool operator<(const propagate_const<T>& pt, const _Up& u);
template <class T, class U> constexpr bool operator>(const propagate_const<T>& pt, const _Up& u);
template <class T, class U> constexpr bool operator<=(const propagate_const<T>& pt, const _Up& u);
template <class T, class U> constexpr bool operator>=(const propagate_const<T>& pt, const _Up& u);
template <class T, class U> constexpr bool operator==(const _Tp& t, const propagate_const<_Up>& pu);
template <class T, class U> constexpr bool operator!=(const _Tp& t, const propagate_const<_Up>& pu);
template <class T, class U> constexpr bool operator<(const _Tp& t, const propagate_const<_Up>& pu);
template <class T, class U> constexpr bool operator>(const _Tp& t, const propagate_const<_Up>& pu);
template <class T, class U> constexpr bool operator<=(const _Tp& t, const propagate_const<_Up>& pu);
template <class T, class U> constexpr bool operator>=(const _Tp& t, const propagate_const<_Up>& pu);
// [propagate_const.algorithms], specialized algorithms
template <class T> constexpr void swap(propagate_const<T>& pt, propagate_const<T>& pu) noexcept(see below);
template <class T>
class propagate_const
{
public:
typedef remove_reference_t<decltype(*declval<T&>())> element_type;
// [propagate_const.ctor], constructors
constexpr propagate_const() = default;
propagate_const(const propagate_const& p) = delete;
constexpr propagate_const(propagate_const&& p) = default;
template <class U> EXPLICIT constexpr propagate_const(propagate_const<_Up>&& pu); // see below
template <class U> EXPLICIT constexpr propagate_const(U&& u); // see below
// [propagate_const.assignment], assignment
propagate_const& operator=(const propagate_const& p) = delete;
constexpr propagate_const& operator=(propagate_const&& p) = default;
template <class U> constexpr propagate_const& operator=(propagate_const<_Up>&& pu);
template <class U> constexpr propagate_const& operator=(U&& u); // see below
// [propagate_const.const_observers], const observers
explicit constexpr operator bool() const;
constexpr const element_type* operator->() const;
constexpr operator const element_type*() const; // Not always defined
constexpr const element_type& operator*() const;
constexpr const element_type* get() const;
// [propagate_const.non_const_observers], non-const observers
constexpr element_type* operator->();
constexpr operator element_type*(); // Not always defined
constexpr element_type& operator*();
constexpr element_type* get();
// [propagate_const.modifiers], modifiers
constexpr void swap(propagate_const& pt) noexcept(see below)
private:
T t_; // exposition only
};
} // namespace fundamentals_v2
} // namespace experimental
// [propagate_const.hash], hash support
template <class T> struct hash<experimental::fundamentals_v2::propagate_const<T>>;
// [propagate_const.comparison_function_objects], comparison function objects
template <class T> struct equal_to<experimental::fundamentals_v2::propagate_const<T>>;
template <class T> struct not_equal_to<experimental::fundamentals_v2::propagate_const<T>>;
template <class T> struct less<experimental::fundamentals_v2::propagate_const<T>>;
template <class T> struct greater<experimental::fundamentals_v2::propagate_const<T>>;
template <class T> struct less_equal<experimental::fundamentals_v2::propagate_const<T>>;
template <class T> struct greater_equal<experimental::fundamentals_v2::propagate_const<T>>;
} // namespace std
*/
#include <experimental/__config>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
#endif
#if _LIBCPP_STD_VER > 11
#include <type_traits>
#include <utility>
#include <functional>
_LIBCPP_BEGIN_NAMESPACE_LFTS_V2
template <class _Tp>
class propagate_const;
template <class _Up> _LIBCPP_CONSTEXPR const _Up& get_underlying(const propagate_const<_Up>& __pu) _NOEXCEPT;
template <class _Up> _LIBCPP_CONSTEXPR _Up& get_underlying(propagate_const<_Up>& __pu) _NOEXCEPT;
template <class _Tp>
class propagate_const
{
public:
typedef remove_reference_t<decltype(*_VSTD::declval<_Tp&>())> element_type;
static_assert(!is_array<_Tp>::value,
"Instantiation of propagate_const with an array type is ill-formed.");
static_assert(!is_reference<_Tp>::value,
"Instantiation of propagate_const with a reference type is ill-formed.");
static_assert(!(is_pointer<_Tp>::value && is_function<typename remove_pointer<_Tp>::type>::value),
"Instantiation of propagate_const with a function-pointer type is ill-formed.");
static_assert(!(is_pointer<_Tp>::value && is_same<typename remove_cv<typename remove_pointer<_Tp>::type>::type, void>::value),
"Instantiation of propagate_const with a pointer to (possibly cv-qualified) void is ill-formed.");
private:
template <class _Up>
static _LIBCPP_CONSTEXPR element_type* __get_pointer(_Up* __u)
{
return __u;
}
template <class _Up>
static _LIBCPP_CONSTEXPR element_type* __get_pointer(_Up& __u)
{
return __get_pointer(__u.get());
}
template <class _Up>
static _LIBCPP_CONSTEXPR const element_type* __get_pointer(const _Up* __u)
{
return __u;
}
template <class _Up>
static _LIBCPP_CONSTEXPR const element_type* __get_pointer(const _Up& __u)
{
return __get_pointer(__u.get());
}
template <class _Up>
struct __is_propagate_const : false_type
{
};
template <class _Up>
struct __is_propagate_const<propagate_const<_Up>> : true_type
{
};
_Tp __t_;
public:
template <class _Up> friend _LIBCPP_CONSTEXPR const _Up& ::_VSTD_LFTS_V2::get_underlying(const propagate_const<_Up>& __pu) _NOEXCEPT;
template <class _Up> friend _LIBCPP_CONSTEXPR _Up& ::_VSTD_LFTS_V2::get_underlying(propagate_const<_Up>& __pu) _NOEXCEPT;
_LIBCPP_CONSTEXPR propagate_const() = default;
propagate_const(const propagate_const&) = delete;
_LIBCPP_CONSTEXPR propagate_const(propagate_const&&) = default;
template <class _Up, enable_if_t<!is_convertible<_Up, _Tp>::value &&
is_constructible<_Tp, _Up&&>::value,bool> = true>
explicit _LIBCPP_CONSTEXPR propagate_const(propagate_const<_Up>&& __pu)
: __t_(std::move(_VSTD_LFTS_V2::get_underlying(__pu)))
{
}
template <class _Up, enable_if_t<is_convertible<_Up&&, _Tp>::value &&
is_constructible<_Tp, _Up&&>::value,bool> = false>
_LIBCPP_CONSTEXPR propagate_const(propagate_const<_Up>&& __pu)
: __t_(std::move(_VSTD_LFTS_V2::get_underlying(__pu)))
{
}
template <class _Up, enable_if_t<!is_convertible<_Up&&, _Tp>::value &&
is_constructible<_Tp, _Up&&>::value &&
!__is_propagate_const<decay_t<_Up>>::value,bool> = true>
explicit _LIBCPP_CONSTEXPR propagate_const(_Up&& __u)
: __t_(std::forward<_Up>(__u))
{
}
template <class _Up, enable_if_t<is_convertible<_Up&&, _Tp>::value &&
is_constructible<_Tp, _Up&&>::value &&
!__is_propagate_const<decay_t<_Up>>::value,bool> = false>
_LIBCPP_CONSTEXPR propagate_const(_Up&& __u)
: __t_(std::forward<_Up>(__u))
{
}
propagate_const& operator=(const propagate_const&) = delete;
_LIBCPP_CONSTEXPR propagate_const& operator=(propagate_const&&) = default;
template <class _Up>
_LIBCPP_CONSTEXPR propagate_const& operator=(propagate_const<_Up>&& __pu)
{
__t_ = std::move(_VSTD_LFTS_V2::get_underlying(__pu));
return *this;
}
template <class _Up, class _Vp = enable_if_t<!__is_propagate_const<decay_t<_Up>>::value>>
_LIBCPP_CONSTEXPR propagate_const& operator=(_Up&& __u)
{
__t_ = std::forward<_Up>(__u);
return *this;
}
_LIBCPP_CONSTEXPR const element_type* get() const
{
return __get_pointer(__t_);
}
_LIBCPP_CONSTEXPR element_type* get()
{
return __get_pointer(__t_);
}
explicit _LIBCPP_CONSTEXPR operator bool() const
{
return get() != nullptr;
}
_LIBCPP_CONSTEXPR const element_type* operator->() const
{
return get();
}
template <class _Tp_ = _Tp, class _Up = enable_if_t<is_convertible<
const _Tp_, const element_type *>::value>>
_LIBCPP_CONSTEXPR operator const element_type *() const {
return get();
}
_LIBCPP_CONSTEXPR const element_type& operator*() const
{
return *get();
}
_LIBCPP_CONSTEXPR element_type* operator->()
{
return get();
}
template <class _Tp_ = _Tp, class _Up = enable_if_t<
is_convertible<_Tp_, element_type *>::value>>
_LIBCPP_CONSTEXPR operator element_type *() {
return get();
}
_LIBCPP_CONSTEXPR element_type& operator*()
{
return *get();
}
_LIBCPP_CONSTEXPR void swap(propagate_const& __pt) _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value)
{
using _VSTD::swap;
swap(__t_, __pt.__t_);
}
};
template <class _Tp>
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_CONSTEXPR bool operator==(const propagate_const<_Tp>& __pt, nullptr_t)
{
return _VSTD_LFTS_V2::get_underlying(__pt) == nullptr;
}
template <class _Tp>
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_CONSTEXPR bool operator==(nullptr_t, const propagate_const<_Tp>& __pt)
{
return nullptr == _VSTD_LFTS_V2::get_underlying(__pt);
}
template <class _Tp>
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_CONSTEXPR bool operator!=(const propagate_const<_Tp>& __pt, nullptr_t)
{
return _VSTD_LFTS_V2::get_underlying(__pt) != nullptr;
}
template <class _Tp>
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_CONSTEXPR bool operator!=(nullptr_t, const propagate_const<_Tp>& __pt)
{
return nullptr != _VSTD_LFTS_V2::get_underlying(__pt);
}
template <class _Tp, class _Up>
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_CONSTEXPR bool operator==(const propagate_const<_Tp>& __pt,
const propagate_const<_Up>& __pu)
{
return _VSTD_LFTS_V2::get_underlying(__pt) == _VSTD_LFTS_V2::get_underlying(__pu);
}
template <class _Tp, class _Up>
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_CONSTEXPR bool operator!=(const propagate_const<_Tp>& __pt,
const propagate_const<_Up>& __pu)
{
return _VSTD_LFTS_V2::get_underlying(__pt) != _VSTD_LFTS_V2::get_underlying(__pu);
}
template <class _Tp, class _Up>
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_CONSTEXPR bool operator<(const propagate_const<_Tp>& __pt,
const propagate_const<_Up>& __pu)
{
return _VSTD_LFTS_V2::get_underlying(__pt) < _VSTD_LFTS_V2::get_underlying(__pu);
}
template <class _Tp, class _Up>
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_CONSTEXPR bool operator>(const propagate_const<_Tp>& __pt,
const propagate_const<_Up>& __pu)
{
return _VSTD_LFTS_V2::get_underlying(__pt) > _VSTD_LFTS_V2::get_underlying(__pu);
}
template <class _Tp, class _Up>
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_CONSTEXPR bool operator<=(const propagate_const<_Tp>& __pt,
const propagate_const<_Up>& __pu)
{
return _VSTD_LFTS_V2::get_underlying(__pt) <= _VSTD_LFTS_V2::get_underlying(__pu);
}
template <class _Tp, class _Up>
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_CONSTEXPR bool operator>=(const propagate_const<_Tp>& __pt,
const propagate_const<_Up>& __pu)
{
return _VSTD_LFTS_V2::get_underlying(__pt) >= _VSTD_LFTS_V2::get_underlying(__pu);
}
template <class _Tp, class _Up>
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_CONSTEXPR bool operator==(const propagate_const<_Tp>& __pt, const _Up& __u)
{
return _VSTD_LFTS_V2::get_underlying(__pt) == __u;
}
template <class _Tp, class _Up>
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_CONSTEXPR bool operator!=(const propagate_const<_Tp>& __pt, const _Up& __u)
{
return _VSTD_LFTS_V2::get_underlying(__pt) != __u;
}
template <class _Tp, class _Up>
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_CONSTEXPR bool operator<(const propagate_const<_Tp>& __pt, const _Up& __u)
{
return _VSTD_LFTS_V2::get_underlying(__pt) < __u;
}
template <class _Tp, class _Up>
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_CONSTEXPR bool operator>(const propagate_const<_Tp>& __pt, const _Up& __u)
{
return _VSTD_LFTS_V2::get_underlying(__pt) > __u;
}
template <class _Tp, class _Up>
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_CONSTEXPR bool operator<=(const propagate_const<_Tp>& __pt, const _Up& __u)
{
return _VSTD_LFTS_V2::get_underlying(__pt) <= __u;
}
template <class _Tp, class _Up>
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_CONSTEXPR bool operator>=(const propagate_const<_Tp>& __pt, const _Up& __u)
{
return _VSTD_LFTS_V2::get_underlying(__pt) >= __u;
}
template <class _Tp, class _Up>
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_CONSTEXPR bool operator==(const _Tp& __t, const propagate_const<_Up>& __pu)
{
return __t == _VSTD_LFTS_V2::get_underlying(__pu);
}
template <class _Tp, class _Up>
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_CONSTEXPR bool operator!=(const _Tp& __t, const propagate_const<_Up>& __pu)
{
return __t != _VSTD_LFTS_V2::get_underlying(__pu);
}
template <class _Tp, class _Up>
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_CONSTEXPR bool operator<(const _Tp& __t, const propagate_const<_Up>& __pu)
{
return __t < _VSTD_LFTS_V2::get_underlying(__pu);
}
template <class _Tp, class _Up>
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_CONSTEXPR bool operator>(const _Tp& __t, const propagate_const<_Up>& __pu)
{
return __t > _VSTD_LFTS_V2::get_underlying(__pu);
}
template <class _Tp, class _Up>
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_CONSTEXPR bool operator<=(const _Tp& __t, const propagate_const<_Up>& __pu)
{
return __t <= _VSTD_LFTS_V2::get_underlying(__pu);
}
template <class _Tp, class _Up>
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_CONSTEXPR bool operator>=(const _Tp& __t, const propagate_const<_Up>& __pu)
{
return __t >= _VSTD_LFTS_V2::get_underlying(__pu);
}
template <class _Tp>
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_CONSTEXPR void swap(propagate_const<_Tp>& __pc1, propagate_const<_Tp>& __pc2) _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value)
{
using _VSTD::swap;
swap(_VSTD_LFTS_V2::get_underlying(__pc1), _VSTD_LFTS_V2::get_underlying(__pc2));
}
template <class _Tp>
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_CONSTEXPR const _Tp& get_underlying(const propagate_const<_Tp>& __pt) _NOEXCEPT
{
return __pt.__t_;
}
template <class _Tp>
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_CONSTEXPR _Tp& get_underlying(propagate_const<_Tp>& __pt) _NOEXCEPT
{
return __pt.__t_;
}
_LIBCPP_END_NAMESPACE_LFTS_V2
_LIBCPP_BEGIN_NAMESPACE_STD
template <class _Tp>
struct hash<experimental::fundamentals_v2::propagate_const<_Tp>>
{
typedef size_t result_type;
typedef experimental::fundamentals_v2::propagate_const<_Tp> argument_type;
size_t operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1) const
{
return std::hash<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1));
}
};
template <class _Tp>
struct equal_to<experimental::fundamentals_v2::propagate_const<_Tp>>
{
typedef experimental::fundamentals_v2::propagate_const<_Tp> first_argument_type;
typedef experimental::fundamentals_v2::propagate_const<_Tp> second_argument_type;
bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1,
const experimental::fundamentals_v2::propagate_const<_Tp>& __pc2) const
{
return std::equal_to<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1), _VSTD_LFTS_V2::get_underlying(__pc2));
}
};
template <class _Tp>
struct not_equal_to<experimental::fundamentals_v2::propagate_const<_Tp>>
{
typedef experimental::fundamentals_v2::propagate_const<_Tp> first_argument_type;
typedef experimental::fundamentals_v2::propagate_const<_Tp> second_argument_type;
bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1,
const experimental::fundamentals_v2::propagate_const<_Tp>& __pc2) const
{
return std::not_equal_to<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1), _VSTD_LFTS_V2::get_underlying(__pc2));
}
};
template <class _Tp>
struct less<experimental::fundamentals_v2::propagate_const<_Tp>>
{
typedef experimental::fundamentals_v2::propagate_const<_Tp> first_argument_type;
typedef experimental::fundamentals_v2::propagate_const<_Tp> second_argument_type;
bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1,
const experimental::fundamentals_v2::propagate_const<_Tp>& __pc2) const
{
return std::less<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1), _VSTD_LFTS_V2::get_underlying(__pc2));
}
};
template <class _Tp>
struct greater<experimental::fundamentals_v2::propagate_const<_Tp>>
{
typedef experimental::fundamentals_v2::propagate_const<_Tp> first_argument_type;
typedef experimental::fundamentals_v2::propagate_const<_Tp> second_argument_type;
bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1,
const experimental::fundamentals_v2::propagate_const<_Tp>& __pc2) const
{
return std::greater<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1), _VSTD_LFTS_V2::get_underlying(__pc2));
}
};
template <class _Tp>
struct less_equal<experimental::fundamentals_v2::propagate_const<_Tp>>
{
typedef experimental::fundamentals_v2::propagate_const<_Tp> first_argument_type;
typedef experimental::fundamentals_v2::propagate_const<_Tp> second_argument_type;
bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1,
const experimental::fundamentals_v2::propagate_const<_Tp>& __pc2) const
{
return std::less_equal<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1), _VSTD_LFTS_V2::get_underlying(__pc2));
}
};
template <class _Tp>
struct greater_equal<experimental::fundamentals_v2::propagate_const<_Tp>>
{
typedef experimental::fundamentals_v2::propagate_const<_Tp> first_argument_type;
typedef experimental::fundamentals_v2::propagate_const<_Tp> second_argument_type;
bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1,
const experimental::fundamentals_v2::propagate_const<_Tp>& __pc2) const
{
return std::greater_equal<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1), _VSTD_LFTS_V2::get_underlying(__pc2));
}
};
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP_STD_VER > 11
#endif // _LIBCPP_EXPERIMENTAL_PROPAGATE_CONST

View File

@@ -0,0 +1,24 @@
//===----------------------------------------------------------------------===//
//
// 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
// <propagate_const>
// template <class U> propagate_const& propagate_const::operator=(const propagate_const<U>&)=delete;
#include <experimental/propagate_const>
#include "propagate_const_helpers.h"
#include <type_traits>
using std::experimental::propagate_const;
typedef propagate_const<X> P;
int main() { static_assert(!std::is_assignable<P, const P &>::value, ""); }

View File

@@ -0,0 +1,34 @@
//===----------------------------------------------------------------------===//
//
// 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
// <propagate_const>
// template <class U> propagate_const& propagate_const::operator=(U&&);
#include <experimental/propagate_const>
#include "propagate_const_helpers.h"
#include <cassert>
using std::experimental::propagate_const;
int main() {
typedef propagate_const<CopyConstructibleFromX> PY;
X x1(1);
PY p(2);
assert(*p==2);
p = x1;
assert(*p==1);
}

View File

@@ -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
// <propagate_const>
// template <class U> constexpr propagate_const& operator=(U&& u); // won't bind to propagate_const
#include <experimental/propagate_const>
#include "propagate_const_helpers.h"
#include <type_traits>
using std::experimental::propagate_const;
typedef propagate_const<X> PX;
typedef propagate_const<CopyConstructibleFromX> PY;
int main() { static_assert(!std::is_assignable<PY, const PX &>::value, ""); }

View File

@@ -0,0 +1,34 @@
//===----------------------------------------------------------------------===//
//
// 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
// <propagate_const>
// template <class U> propagate_const& propagate_const::operator=(U&&);
#include <experimental/propagate_const>
#include "propagate_const_helpers.h"
#include <cassert>
using std::experimental::propagate_const;
int main() {
typedef propagate_const<X> P;
X x1(1);
P p(2);
assert(*p==2);
p = x1;
assert(*p==1);
}

View File

@@ -0,0 +1,32 @@
//===----------------------------------------------------------------------===//
//
// 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
// <propagate_const>
// template <class U> propagate_const& propagate_const::operator=(propagate_const<U>&&);
#include <experimental/propagate_const>
#include "propagate_const_helpers.h"
#include <cassert>
using std::experimental::propagate_const;
int main() {
typedef propagate_const<X> P;
P p1(1);
P p2(2);
p2=std::move(p1);
assert(*p2==1);
}

View File

@@ -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
// <propagate_const>
// template <class U> propagate_const& propagate_const::operator=(propagate_const<U>&&);
#include <experimental/propagate_const>
#include "propagate_const_helpers.h"
#include <cassert>
using std::experimental::propagate_const;
int main() {
typedef propagate_const<X> PX;
typedef propagate_const<MoveConstructibleFromX> PY;
PX px2(2);
PY py1(1);
py1=std::move(px2);
assert(*py1==2);
}

View File

@@ -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
// <propagate_const>
// template <class U> constexpr propagate_const& operator=(propagate_const<_Up>&& pu);
#include <experimental/propagate_const>
#include "propagate_const_helpers.h"
#include <cassert>
using std::experimental::propagate_const;
int main() {
typedef propagate_const<X> PX;
typedef propagate_const<MoveConstructibleFromX> PY;
PX px2(2);
PY py1(1);
py1=std::move(px2);
assert(*py1==2);
}

View File

@@ -0,0 +1,28 @@
//===----------------------------------------------------------------------===//
//
// 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
// <propagate_const>
// template <class U> constexpr propagate_const& operator=(propagate_const<_Up>&& pu);
#include <experimental/propagate_const>
#include "propagate_const_helpers.h"
#include <type_traits>
using std::experimental::propagate_const;
typedef propagate_const<ExplicitCopyConstructibleFromX> P;
int main() {
static_assert(!std::is_convertible<P, X>::value, "");
static_assert(std::is_constructible<P, X>::value, "");
}

View File

@@ -0,0 +1,32 @@
//===----------------------------------------------------------------------===//
//
// 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
// <propagate_const>
// template <class U> constexpr propagate_const(propagate_const<_Up>&& pu);
#include <experimental/propagate_const>
#include "propagate_const_helpers.h"
#include <cassert>
using std::experimental::propagate_const;
typedef propagate_const<CopyConstructibleFromX> P;
void f(const P& p)
{
assert(*p==2);
}
int main() {
f(X(2));
}

View File

@@ -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
// <propagate_const>
// template <class U> constexpr propagate_const& operator(propagate_const<_Up>&& pu);
#include <experimental/propagate_const>
#include "propagate_const_helpers.h"
#include <type_traits>
using std::experimental::propagate_const;
typedef propagate_const<X> PX;
typedef propagate_const<CopyConstructibleFromX> PY;
int main() { static_assert(!std::is_constructible<PX, PY>::value, ""); }

View File

@@ -0,0 +1,28 @@
//===----------------------------------------------------------------------===//
//
// 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
// <propagate_const>
// template <class U> constexpr propagate_const(propagate_const<_Up>&& pu);
#include <experimental/propagate_const>
#include "propagate_const_helpers.h"
#include <type_traits>
using std::experimental::propagate_const;
typedef propagate_const<X> PX;
typedef propagate_const<ExplicitMoveConstructibleFromX> PY;
int main() {
static_assert(!std::is_convertible<PY, PX &&>::value, "");
static_assert(std::is_constructible<PY, PX &&>::value, "");
}

View File

@@ -0,0 +1,31 @@
//===----------------------------------------------------------------------===//
//
// 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
// <propagate_const>
// template <class U> constexpr propagate_const(propagate_const<_Up>&& pu);
#include <experimental/propagate_const>
#include "propagate_const_helpers.h"
#include <cassert>
using std::experimental::propagate_const;
typedef propagate_const<MoveConstructibleFromX> PY;
typedef propagate_const<X> PX;
int main() {
PX px(1);
PY py(std::move(px));
assert(*py==1);
}

View File

@@ -0,0 +1,24 @@
//===----------------------------------------------------------------------===//
//
// 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
// <propagate_const>
// propagate_const(const propagate_const&)=delete;
#include <experimental/propagate_const>
#include "propagate_const_helpers.h"
#include <type_traits>
using std::experimental::propagate_const;
typedef propagate_const<X> P;
int main() { static_assert(!std::is_constructible<P, const P &>::value, ""); }

View File

@@ -0,0 +1,28 @@
//===----------------------------------------------------------------------===//
//
// 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
// <propagate_const>
// template <class U> propagate_const(U&&);
#include <experimental/propagate_const>
#include "propagate_const_helpers.h"
#include <type_traits>
using std::experimental::propagate_const;
typedef propagate_const<ExplicitX> P;
int main() {
static_assert(!std::is_convertible<P, int>::value, "");
static_assert(std::is_constructible<P, int>::value, "");
}

View File

@@ -0,0 +1,28 @@
//===----------------------------------------------------------------------===//
//
// 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
// <propagate_const>
// template <class U> propagate_const(U&&);
#include <experimental/propagate_const>
#include "propagate_const_helpers.h"
#include <cassert>
using std::experimental::propagate_const;
typedef propagate_const<X> P;
void f(const P&)
{
}
int main() { f(2); }

View File

@@ -0,0 +1,28 @@
//===----------------------------------------------------------------------===//
//
// 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
// <propagate_const>
// propagate_const(propagate_const&&)=default;
#include <experimental/propagate_const>
#include "propagate_const_helpers.h"
#include <cassert>
using std::experimental::propagate_const;
int main() {
typedef propagate_const<X> P;
P p1(2);
P p2(std::move(p1));
}

View File

@@ -0,0 +1,34 @@
//===----------------------------------------------------------------------===//
//
// 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
// <propagate_const>
// element_type& propagate_const::operator*();
#include <experimental/propagate_const>
#include "propagate_const_helpers.h"
#include <cassert>
using std::experimental::propagate_const;
typedef propagate_const<X> P;
constexpr P f()
{
P p(1);
*p = 2;
return p;
}
int main() {
constexpr P p = f();
static_assert(*p==2,"");
}

View File

@@ -0,0 +1,24 @@
//===----------------------------------------------------------------------===//
//
// 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
// <propagate_const>
// propagate_const::operator element_type*();
#include <experimental/propagate_const>
#include "propagate_const_helpers.h"
#include <type_traits>
using std::experimental::propagate_const;
typedef propagate_const<X> P;
int main() { static_assert(!std::is_convertible<P, int *>::value, ""); }

View File

@@ -0,0 +1,34 @@
//===----------------------------------------------------------------------===//
//
// 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
// <propagate_const>
// element_type* propagate_const::get();
#include <experimental/propagate_const>
#include "propagate_const_helpers.h"
#include <cassert>
using std::experimental::propagate_const;
typedef propagate_const<X> P;
constexpr P f()
{
P p(1);
*p.get() = 2;
return p;
}
int main() {
constexpr P p = f();
static_assert(*(p.get())==2,"");
}

View File

@@ -0,0 +1,34 @@
//===----------------------------------------------------------------------===//
//
// 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
// <propagate_const>
// element_type* propagate_const::operator->();
#include <experimental/propagate_const>
#include "propagate_const_helpers.h"
#include <cassert>
using std::experimental::propagate_const;
typedef propagate_const<X> P;
constexpr P f()
{
P p(1);
*(p.operator->()) = 2;
return p;
}
int main() {
constexpr P p = f();
static_assert(*(p.operator->())==2,"");
}

View File

@@ -0,0 +1,35 @@
//===----------------------------------------------------------------------===//
//
// 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
// <propagate_const>
// propagate_const::operator element_type*();
#include <experimental/propagate_const>
#include "propagate_const_helpers.h"
#include <cassert>
using std::experimental::propagate_const;
int main() {
typedef propagate_const<XWithImplicitIntStarConversion> P;
P p(1);
int* ptr_1 = p;
assert(*ptr_1==1);
*ptr_1 = 2;
assert(*ptr_1==2);
}

View File

@@ -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
// <propagate_const>
// const element_type& propagate_const::operator*() const;
#include <experimental/propagate_const>
#include "propagate_const_helpers.h"
#include <cassert>
using std::experimental::propagate_const;
int main() {
typedef propagate_const<X> P;
constexpr P p(1);
static_assert(*p==1,"");
}

View File

@@ -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
// <propagate_const>
// propagate_const::operator const element_type*() const;
#include <experimental/propagate_const>
#include "propagate_const_helpers.h"
#include <type_traits>
using std::experimental::propagate_const;
typedef propagate_const<X> P;
int main() {
static_assert(!std::is_convertible<const P, const int *>::value, "");
}

View File

@@ -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
// <propagate_const>
// const element_type* propagate_const::get() const;
#include <experimental/propagate_const>
#include "propagate_const_helpers.h"
#include <cassert>
using std::experimental::propagate_const;
int main() {
typedef propagate_const<X> P;
constexpr P p(1);
static_assert(*(p.get())==1, "");
}

View File

@@ -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
// <propagate_const>
// const element_type* propagate_const::operator->() const;
#include <experimental/propagate_const>
#include "propagate_const_helpers.h"
#include <cassert>
using std::experimental::propagate_const;
int main() {
typedef propagate_const<X> P;
constexpr P p(1);
static_assert(*(p.operator->())==1,"");
}

View File

@@ -0,0 +1,28 @@
//===----------------------------------------------------------------------===//
//
// 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
// <propagate_const>
// propagate_const::operator const element_type*() const;
#include <experimental/propagate_const>
#include "propagate_const_helpers.h"
#include <cassert>
using std::experimental::propagate_const;
typedef propagate_const<XWithImplicitConstIntStarConversion> P;
constexpr P p(1);
constexpr const int *ptr_1 = p;
int main() { assert(*ptr_1 == 1); }

View File

@@ -0,0 +1,32 @@
//===----------------------------------------------------------------------===//
//
// 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
// <propagate_const>
// template <class T> constexpr void propagate_const::swap(propagate_const<T>& x);
#include <experimental/propagate_const>
#include "propagate_const_helpers.h"
#include <cassert>
using std::experimental::propagate_const;
bool swap_called = false;
void swap(X &, X &) { swap_called = true; }
int main() {
typedef propagate_const<X> P;
P p1(1);
P p2(2);
p1.swap(p2);
assert(swap_called);
}

View File

@@ -0,0 +1,44 @@
//===----------------------------------------------------------------------===//
//
// 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
// <propagate_const>
// template <class T> struct hash<experimental::fundamentals_v2::propagate_const<T>>;
#include <experimental/propagate_const>
#include "propagate_const_helpers.h"
#include <cassert>
using std::experimental::propagate_const;
namespace std {
template <> struct hash<X>
{
typedef X first_argument_type;
size_t operator()(const first_argument_type& x1) const
{
return 99;
}
};
} // namespace std
int main() {
typedef propagate_const<X> P;
P p(1);
auto h = std::hash<P>();
assert(h(p)==99);
}

View File

@@ -0,0 +1,36 @@
//===----------------------------------------------------------------------===//
//
// 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
// <propagate_const>
// template <class T> struct equal_to<experimental::fundamentals_v2::propagate_const<T>>;
#include <experimental/propagate_const>
#include "propagate_const_helpers.h"
#include <cassert>
using std::experimental::propagate_const;
constexpr bool operator==(const X &x1, const X &x2) { return x1.i_ == x2.i_; }
int main() {
typedef propagate_const<X> P;
P p1_1(1);
P p2_1(1);
P p3_2(2);
auto c = std::equal_to<P>();
assert(c(p1_1,p2_1));
assert(!c(p1_1,p3_2));
}

View File

@@ -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
// <propagate_const>
// template <class T> struct greater<experimental::fundamentals_v2::propagate_const<T>>;
#include <experimental/propagate_const>
#include "propagate_const_helpers.h"
#include <cassert>
using std::experimental::propagate_const;
constexpr bool operator>(const X &x1, const X &x2) { return x1.i_ > x2.i_; }
int main() {
typedef propagate_const<X> P;
P p1_1(1);
P p2_1(1);
P p3_2(2);
auto c = std::greater<P>();
assert(!c(p1_1,p2_1));
assert(!c(p2_1,p1_1));
assert(!c(p1_1,p3_2));
assert(c(p3_2,p1_1));
}

View File

@@ -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
// <propagate_const>
// template <class T> struct greater_equal<experimental::fundamentals_v2::propagate_const<T>>;
#include <experimental/propagate_const>
#include "propagate_const_helpers.h"
#include <cassert>
using std::experimental::propagate_const;
constexpr bool operator>=(const X &x1, const X &x2) { return x1.i_ >= x2.i_; }
int main() {
typedef propagate_const<X> P;
P p1_1(1);
P p2_1(1);
P p3_2(2);
auto c = std::greater_equal<P>();
assert(c(p1_1,p2_1));
assert(c(p2_1,p1_1));
assert(!c(p1_1,p3_2));
assert(c(p3_2,p1_1));
}

View File

@@ -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
// <propagate_const>
// template <class T> struct less<experimental::fundamentals_v2::propagate_const<T>>;
#include <experimental/propagate_const>
#include "propagate_const_helpers.h"
#include <cassert>
using std::experimental::propagate_const;
constexpr bool operator<(const X &x1, const X &x2) { return x1.i_ < x2.i_; }
int main() {
typedef propagate_const<X> P;
P p1_1(1);
P p2_1(1);
P p3_2(2);
auto c = std::less<P>();
assert(!c(p1_1,p2_1));
assert(!c(p2_1,p1_1));
assert(c(p1_1,p3_2));
assert(!c(p3_2,p1_1));
}

View File

@@ -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
// <propagate_const>
// template <class T> struct less_equal<experimental::fundamentals_v2::propagate_const<T>>;
#include <experimental/propagate_const>
#include "propagate_const_helpers.h"
#include <cassert>
using std::experimental::propagate_const;
constexpr bool operator<=(const X &x1, const X &x2) { return x1.i_ <= x2.i_; }
int main() {
typedef propagate_const<X> P;
P p1_1(1);
P p2_1(1);
P p3_2(2);
auto c = std::less_equal<P>();
assert(c(p1_1,p2_1));
assert(c(p2_1,p1_1));
assert(c(p1_1,p3_2));
assert(!c(p3_2,p1_1));
}

View File

@@ -0,0 +1,36 @@
//===----------------------------------------------------------------------===//
//
// 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
// <propagate_const>
// template <class T> struct not_equal_to<experimental::fundamentals_v2::propagate_const<T>>;
#include <experimental/propagate_const>
#include "propagate_const_helpers.h"
#include <cassert>
using std::experimental::propagate_const;
constexpr bool operator!=(const X &x1, const X &x2) { return x1.i_ != x2.i_; }
int main() {
typedef propagate_const<X> P;
P p1_1(1);
P p2_1(1);
P p3_2(2);
auto c = std::not_equal_to<P>();
assert(!c(p1_1,p2_1));
assert(c(p1_1,p3_2));
}

View File

@@ -0,0 +1,64 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03, c++11
// <propagate_const>
// template <class T> constexpr bool operator==(const propagate_const<T>& x, const propagate_const<T>& y);
// template <class T> constexpr bool operator==(const T& x, const propagate_const<T>& y);
// template <class T> constexpr bool operator==(const propagate_const<T>& x, const T& y);
#include <experimental/propagate_const>
#include "propagate_const_helpers.h"
#include <cassert>
using std::experimental::propagate_const;
using std::nullptr_t;
constexpr bool operator==(const X &lhs, const X &rhs) {
return lhs.i_ == rhs.i_;
}
constexpr bool operator==(const X &, const nullptr_t &) {
return false;
}
constexpr bool operator==(const nullptr_t &, const X &) {
return false;
}
int main() {
constexpr X x1_1(1);
constexpr X x2_1(1);
constexpr X x3_2(2);
static_assert(x1_1 == x1_1, "");
static_assert(x1_1 == x2_1, "");
static_assert(!(x1_1 == x3_2), "");
typedef propagate_const<X> P;
constexpr P p1_1(1);
constexpr P p2_1(1);
constexpr P p3_2(2);
static_assert(p1_1 == p1_1, "");
static_assert(p1_1 == p2_1, "");
static_assert(!(p1_1 == p3_2), "");
static_assert(x1_1 == p1_1, "");
static_assert(!(x1_1 == p3_2), "");
static_assert(p1_1 == x1_1, "");
static_assert(!(p1_1 == x3_2), "");
static_assert(!(p1_1==nullptr),"");
static_assert(!(nullptr==p1_1),"");
}

View File

@@ -0,0 +1,54 @@
//>==---------------------------------------------------------------------->==//
//
// 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
// <propagate_const>
// template <class T> constexpr bool operator>=(const propagate_const<T>& x, const propagate_const<T>& y);
// template <class T> constexpr bool operator>=(const T& x, const propagate_const<T>& y);
// template <class T> constexpr bool operator>=(const propagate_const<T>& x, const T& y);
#include <experimental/propagate_const>
#include "propagate_const_helpers.h"
#include <cassert>
using std::experimental::propagate_const;
constexpr bool operator>=(const X &lhs, const X &rhs) {
return lhs.i_ >= rhs.i_;
}
int main() {
constexpr X x1_1(1);
constexpr X x2_1(1);
constexpr X x3_2(2);
static_assert(x1_1 >= x2_1, "");
static_assert(!(x1_1 >= x3_2), "");
static_assert(x3_2 >= x1_1, "");
typedef propagate_const<X> P;
constexpr P p1_1(1);
constexpr P p2_1(1);
constexpr P p3_2(2);
static_assert(p1_1 >= p2_1, "");
static_assert(!(p1_1 >= p3_2), "");
static_assert(p3_2 >= p1_1, "");
static_assert(p1_1 >= x2_1, "");
static_assert(!(p1_1 >= x3_2), "");
static_assert(p3_2 >= x1_1, "");
static_assert(x1_1 >= p2_1, "");
static_assert(!(x1_1 >= p3_2), "");
static_assert(x3_2 >= p1_1, "");
}

View File

@@ -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
// <propagate_const>
// template <class T> constexpr bool operator>(const propagate_const<T>& x, const propagate_const<T>& y);
// template <class T> constexpr bool operator>(const T& x, const propagate_const<T>& y);
// template <class T> constexpr bool operator>(const propagate_const<T>& x, const T& y);
#include <experimental/propagate_const>
#include "propagate_const_helpers.h"
#include <cassert>
using std::experimental::propagate_const;
constexpr bool operator>(const X &lhs, const X &rhs) {
return lhs.i_ > rhs.i_;
}
int main() {
constexpr X x1_1(1);
constexpr X x2_1(1);
constexpr X x3_2(2);
static_assert(!(x1_1 > x2_1), "");
static_assert(x3_2 > x1_1, "");
typedef propagate_const<X> P;
constexpr P p1_1(1);
constexpr P p2_1(1);
constexpr P p3_2(2);
static_assert(!(p1_1 > p2_1), "");
static_assert(p3_2 > p1_1, "");
static_assert(!(p1_1 > x2_1), "");
static_assert(p3_2 > x1_1, "");
static_assert(!(x1_1 > p2_1), "");
static_assert(x3_2 > p1_1, "");
}

View File

@@ -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
// <propagate_const>
// template <class T> constexpr bool operator<=(const propagate_const<T>& x, const propagate_const<T>& y);
// template <class T> constexpr bool operator<=(const T& x, const propagate_const<T>& y);
// template <class T> constexpr bool operator<=(const propagate_const<T>& x, const T& y);
#include <experimental/propagate_const>
#include "propagate_const_helpers.h"
#include <cassert>
using std::experimental::propagate_const;
constexpr bool operator<=(const X &lhs, const X &rhs) {
return lhs.i_ <= rhs.i_;
}
int main() {
constexpr X x1_1(1);
constexpr X x2_1(1);
constexpr X x3_2(2);
static_assert(x1_1 <= x2_1, "");
static_assert(x1_1 <= x3_2, "");
static_assert(!(x3_2 <= x1_1), "");
typedef propagate_const<X> P;
constexpr P p1_1(1);
constexpr P p2_1(1);
constexpr P p3_2(2);
static_assert(p1_1 <= p2_1, "");
static_assert(p1_1 <= p3_2, "");
static_assert(!(p3_2 <= p1_1), "");
static_assert(p1_1 <= x2_1, "");
static_assert(p1_1 <= x3_2, "");
static_assert(!(p3_2 <= x1_1), "");
static_assert(x1_1 <= p2_1, "");
static_assert(x1_1 <= p3_2, "");
static_assert(!(x3_2 <= p1_1), "");
}

View File

@@ -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
// <propagate_const>
// template <class T> constexpr bool operator<(const propagate_const<T>& x, const propagate_const<T>& y);
// template <class T> constexpr bool operator<(const T& x, const propagate_const<T>& y);
// template <class T> constexpr bool operator<(const propagate_const<T>& x, const T& y);
#include <experimental/propagate_const>
#include "propagate_const_helpers.h"
#include <cassert>
using std::experimental::propagate_const;
constexpr bool operator<(const X &lhs, const X &rhs) {
return lhs.i_ < rhs.i_;
}
int main() {
constexpr X x1_1(1);
constexpr X x2_1(1);
constexpr X x3_2(2);
static_assert(!(x1_1 < x2_1), "");
static_assert(x1_1 < x3_2, "");
typedef propagate_const<X> P;
constexpr P p1_1(1);
constexpr P p2_1(1);
constexpr P p3_2(2);
static_assert(!(p1_1 < p2_1), "");
static_assert(p1_1 < p3_2, "");
static_assert(!(x1_1 < p1_1), "");
static_assert(x1_1 < p3_2, "");
static_assert(!(p1_1 < x1_1), "");
static_assert(p1_1 < x3_2, "");
}

View File

@@ -0,0 +1,62 @@
//===----------------------------------------------------------------------===//
//
// 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
// <propagate_const>
// template <class T> constexpr bool operator!=(const propagate_const<T>& x, const propagate_const<T>& y);
// template <class T> constexpr bool operator!=(const T& x, const propagate_const<T>& y);
// template <class T> constexpr bool operator!=(const propagate_const<T>& x, const T& y);
#include <experimental/propagate_const>
#include "propagate_const_helpers.h"
#include <cassert>
using std::experimental::propagate_const;
using std::nullptr_t;
constexpr bool operator!=(const X &lhs, const X &rhs) {
return lhs.i_ != rhs.i_;
}
constexpr bool operator!=(const X &, const nullptr_t &) {
return true;
}
constexpr bool operator!=(const nullptr_t &, const X &) {
return true;
}
int main() {
constexpr X x1_1(1);
constexpr X x2_1(1);
constexpr X x3_2(2);
static_assert(!(x1_1 != x2_1), "");
static_assert(x1_1 != x3_2, "");
typedef propagate_const<X> P;
constexpr P p1_1(1);
constexpr P p2_1(1);
constexpr P p3_2(2);
static_assert(!(p1_1 != p2_1), "");
static_assert(p1_1 != p3_2, "");
static_assert(!(x1_1 != p1_1), "");
static_assert(x1_1 != p3_2, "");
static_assert(!(p1_1 != x1_1), "");
static_assert(p1_1 != x3_2, "");
static_assert(p1_1!=nullptr,"");
static_assert(nullptr!=p1_1,"");
}

View File

@@ -0,0 +1,31 @@
//===----------------------------------------------------------------------===//
//
// 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
// <propagate_const>
// template <class T> constexpr void swap(propagate_const<T>& x, propagate_const<T>& y);
#include <experimental/propagate_const>
#include "propagate_const_helpers.h"
#include <cassert>
using std::experimental::propagate_const;
bool swap_called = false;
void swap(X &, X &) { swap_called = true; }
int main() {
typedef propagate_const<X> P;
P p1(1);
P p2(2);
swap(p1, p2);
assert(swap_called);
}

View File

@@ -0,0 +1,119 @@
// A lightweight class, with pointer-like methods, that contains an int
struct X
{
int i_;
constexpr const int &operator*() const { return i_; }
constexpr int &operator*() { return i_; }
constexpr const int *get() const { return &i_; }
constexpr int *get() { return &i_; }
constexpr const int *operator->() const { return &i_; }
constexpr int *operator->() { return &i_; }
constexpr X(int i) : i_(i) {}
};
struct XWithImplicitIntStarConversion
{
int i_;
constexpr const int &operator*() const { return i_; }
constexpr int &operator*() { return i_; }
constexpr const int *get() const { return &i_; }
constexpr int *get() { return &i_; }
constexpr const int *operator->() const { return &i_; }
constexpr int *operator->() { return &i_; }
constexpr operator int* () { return &i_; }
constexpr XWithImplicitIntStarConversion(int i) : i_(i) {}
};
struct XWithImplicitConstIntStarConversion
{
int i_;
constexpr const int &operator*() const { return i_; }
constexpr int &operator*() { return i_; }
constexpr const int *get() const { return &i_; }
constexpr int *get() { return &i_; }
constexpr const int *operator->() const { return &i_; }
constexpr int *operator->() { return &i_; }
constexpr operator const int* () const { return &i_; }
constexpr XWithImplicitConstIntStarConversion(int i) : i_(i) {}
};
struct ExplicitX
{
int i_;
constexpr const int &operator*() const { return i_; }
constexpr int &operator*() { return i_; }
constexpr const int *get() const { return &i_; }
constexpr int *get() { return &i_; }
constexpr const int *operator->() const { return &i_; }
constexpr int *operator->() { return &i_; }
constexpr explicit ExplicitX(int i) : i_(i) {}
};
struct MoveConstructibleFromX
{
int i_;
constexpr const int &operator*() const { return i_; }
constexpr int &operator*() { return i_; }
constexpr const int *get() const { return &i_; }
constexpr int *get() { return &i_; }
constexpr const int *operator->() const { return &i_; }
constexpr int *operator->() { return &i_; }
constexpr MoveConstructibleFromX(int i) : i_(i) {}
constexpr MoveConstructibleFromX(X&& x) : i_(x.i_) {}
};
struct ExplicitMoveConstructibleFromX
{
int i_;
constexpr const int &operator*() const { return i_; }
constexpr int &operator*() { return i_; }
constexpr const int *get() const { return &i_; }
constexpr int *get() { return &i_; }
constexpr const int *operator->() const { return &i_; }
constexpr int *operator->() { return &i_; }
constexpr ExplicitMoveConstructibleFromX(int i) : i_(i) {}
constexpr explicit ExplicitMoveConstructibleFromX(X&& x) : i_(x.i_) {}
};
struct CopyConstructibleFromX
{
int i_;
constexpr const int &operator*() const { return i_; }
constexpr int &operator*() { return i_; }
constexpr const int *get() const { return &i_; }
constexpr int *get() { return &i_; }
constexpr const int *operator->() const { return &i_; }
constexpr int *operator->() { return &i_; }
constexpr CopyConstructibleFromX(int i) : i_(i) {}
constexpr CopyConstructibleFromX(const X& x) : i_(x.i_) {}
};
struct ExplicitCopyConstructibleFromX
{
int i_;
constexpr const int &operator*() const { return i_; }
constexpr int &operator*() { return i_; }
constexpr const int *get() const { return &i_; }
constexpr int *get() { return &i_; }
constexpr const int *operator->() const { return &i_; }
constexpr int *operator->() { return &i_; }
constexpr ExplicitCopyConstructibleFromX(int i) : i_(i) {}
constexpr explicit ExplicitCopyConstructibleFromX(const X& x) : i_(x.i_) {}
};