[libcxx] r273122 - Implement std::experimental::propagate_const from LFTS v2

Jonathan Coe via cfe-commits cfe-commits at lists.llvm.org
Sun Jun 19 12:34:14 PDT 2016


Author: jbcoe
Date: Sun Jun 19 14:34:13 2016
New Revision: 273122

URL: http://llvm.org/viewvc/llvm-project?rev=273122&view=rev
Log:
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

Added:
    libcxx/trunk/include/experimental/propagate_const
    libcxx/trunk/test/std/experimental/utilities/propagate_const/
    libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/
    libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.assignment/
    libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.assignment/assign.pass.cpp
    libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.assignment/assign_convertible_element_type.pass.cpp
    libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.assignment/assign_convertible_propagate_const.pass.cpp
    libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.assignment/assign_element_type.pass.cpp
    libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.assignment/move_assign.pass.cpp
    libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.assignment/move_assign_convertible.pass.cpp
    libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.assignment/move_assign_convertible_propagate_const.pass.cpp
    libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/
    libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/convertible_element_type.explicit.ctor.pass.cpp
    libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/convertible_element_type.non-explicit.ctor.pass.cpp
    libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/convertible_propagate_const.copy_ctor.pass.cpp
    libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/convertible_propagate_const.explicit.move_ctor.pass.cpp
    libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/convertible_propagate_const.move_ctor.pass.cpp
    libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/copy_ctor.pass.cpp
    libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/element_type.explicit.ctor.pass.cpp
    libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/element_type.non-explicit.ctor.pass.cpp
    libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/move_ctor.pass.cpp
    libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.non-const_observers/
    libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.non-const_observers/dereference.pass.cpp
    libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.non-const_observers/explicit_operator_element_type_ptr.pass.cpp
    libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.non-const_observers/get.pass.cpp
    libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.non-const_observers/op_arrow.pass.cpp
    libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.non-const_observers/operator_element_type_ptr.pass.cpp
    libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.observers/
    libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.observers/dereference.pass.cpp
    libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.observers/explicit_operator_element_type_ptr.pass.cpp
    libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.observers/get.pass.cpp
    libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.observers/op_arrow.pass.cpp
    libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.observers/operator_element_type_ptr.pass.cpp
    libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/swap.pass.cpp
    libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/
    libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/hash.pass.cpp
    libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.comparison_function_objects/
    libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.comparison_function_objects/equal_to.pass.cpp
    libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.comparison_function_objects/greater.pass.cpp
    libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.comparison_function_objects/greater_equal.pass.cpp
    libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.comparison_function_objects/less.pass.cpp
    libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.comparison_function_objects/less_equal.pass.cpp
    libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.comparison_function_objects/not_equal_to.pass.cpp
    libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.relops/
    libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.relops/equal.pass.cpp
    libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.relops/greater_equal.pass.cpp
    libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.relops/greater_than.pass.cpp
    libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.relops/less_equal.pass.cpp
    libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.relops/less_than.pass.cpp
    libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.relops/not_equal.pass.cpp
    libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/swap.pass.cpp
    libcxx/trunk/test/support/propagate_const_helpers.h
Modified:
    libcxx/trunk/include/experimental/__config

Modified: libcxx/trunk/include/experimental/__config
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/experimental/__config?rev=273122&r1=273121&r2=273122&view=diff
==============================================================================
--- libcxx/trunk/include/experimental/__config (original)
+++ libcxx/trunk/include/experimental/__config Sun Jun 19 14:34:13 2016
@@ -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

Added: libcxx/trunk/include/experimental/propagate_const
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/experimental/propagate_const?rev=273122&view=auto
==============================================================================
--- libcxx/trunk/include/experimental/propagate_const (added)
+++ libcxx/trunk/include/experimental/propagate_const Sun Jun 19 14:34:13 2016
@@ -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
+

Added: libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.assignment/assign.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.assignment/assign.pass.cpp?rev=273122&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.assignment/assign.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.assignment/assign.pass.cpp Sun Jun 19 14:34:13 2016
@@ -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, ""); }

Added: libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.assignment/assign_convertible_element_type.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.assignment/assign_convertible_element_type.pass.cpp?rev=273122&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.assignment/assign_convertible_element_type.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.assignment/assign_convertible_element_type.pass.cpp Sun Jun 19 14:34:13 2016
@@ -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);
+}

Added: libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.assignment/assign_convertible_propagate_const.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.assignment/assign_convertible_propagate_const.pass.cpp?rev=273122&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.assignment/assign_convertible_propagate_const.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.assignment/assign_convertible_propagate_const.pass.cpp Sun Jun 19 14:34:13 2016
@@ -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, ""); }

Added: libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.assignment/assign_element_type.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.assignment/assign_element_type.pass.cpp?rev=273122&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.assignment/assign_element_type.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.assignment/assign_element_type.pass.cpp Sun Jun 19 14:34:13 2016
@@ -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);
+}

Added: libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.assignment/move_assign.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.assignment/move_assign.pass.cpp?rev=273122&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.assignment/move_assign.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.assignment/move_assign.pass.cpp Sun Jun 19 14:34:13 2016
@@ -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);
+}

Added: libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.assignment/move_assign_convertible.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.assignment/move_assign_convertible.pass.cpp?rev=273122&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.assignment/move_assign_convertible.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.assignment/move_assign_convertible.pass.cpp Sun Jun 19 14:34:13 2016
@@ -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);
+}

Added: libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.assignment/move_assign_convertible_propagate_const.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.assignment/move_assign_convertible_propagate_const.pass.cpp?rev=273122&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.assignment/move_assign_convertible_propagate_const.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.assignment/move_assign_convertible_propagate_const.pass.cpp Sun Jun 19 14:34:13 2016
@@ -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);
+}

Added: libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/convertible_element_type.explicit.ctor.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/convertible_element_type.explicit.ctor.pass.cpp?rev=273122&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/convertible_element_type.explicit.ctor.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/convertible_element_type.explicit.ctor.pass.cpp Sun Jun 19 14:34:13 2016
@@ -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, "");
+}
+

Added: libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/convertible_element_type.non-explicit.ctor.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/convertible_element_type.non-explicit.ctor.pass.cpp?rev=273122&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/convertible_element_type.non-explicit.ctor.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/convertible_element_type.non-explicit.ctor.pass.cpp Sun Jun 19 14:34:13 2016
@@ -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));
+}
+

Added: libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/convertible_propagate_const.copy_ctor.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/convertible_propagate_const.copy_ctor.pass.cpp?rev=273122&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/convertible_propagate_const.copy_ctor.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/convertible_propagate_const.copy_ctor.pass.cpp Sun Jun 19 14:34:13 2016
@@ -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, ""); }
+

Added: libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/convertible_propagate_const.explicit.move_ctor.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/convertible_propagate_const.explicit.move_ctor.pass.cpp?rev=273122&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/convertible_propagate_const.explicit.move_ctor.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/convertible_propagate_const.explicit.move_ctor.pass.cpp Sun Jun 19 14:34:13 2016
@@ -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, "");
+}

Added: libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/convertible_propagate_const.move_ctor.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/convertible_propagate_const.move_ctor.pass.cpp?rev=273122&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/convertible_propagate_const.move_ctor.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/convertible_propagate_const.move_ctor.pass.cpp Sun Jun 19 14:34:13 2016
@@ -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);
+}
+

Added: libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/copy_ctor.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/copy_ctor.pass.cpp?rev=273122&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/copy_ctor.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/copy_ctor.pass.cpp Sun Jun 19 14:34:13 2016
@@ -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, ""); }

Added: libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/element_type.explicit.ctor.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/element_type.explicit.ctor.pass.cpp?rev=273122&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/element_type.explicit.ctor.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/element_type.explicit.ctor.pass.cpp Sun Jun 19 14:34:13 2016
@@ -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, "");
+}
+

Added: libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/element_type.non-explicit.ctor.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/element_type.non-explicit.ctor.pass.cpp?rev=273122&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/element_type.non-explicit.ctor.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/element_type.non-explicit.ctor.pass.cpp Sun Jun 19 14:34:13 2016
@@ -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); }

Added: libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/move_ctor.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/move_ctor.pass.cpp?rev=273122&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/move_ctor.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.ctors/move_ctor.pass.cpp Sun Jun 19 14:34:13 2016
@@ -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));
+}

Added: libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.non-const_observers/dereference.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.non-const_observers/dereference.pass.cpp?rev=273122&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.non-const_observers/dereference.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.non-const_observers/dereference.pass.cpp Sun Jun 19 14:34:13 2016
@@ -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,"");
+}

Added: libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.non-const_observers/explicit_operator_element_type_ptr.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.non-const_observers/explicit_operator_element_type_ptr.pass.cpp?rev=273122&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.non-const_observers/explicit_operator_element_type_ptr.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.non-const_observers/explicit_operator_element_type_ptr.pass.cpp Sun Jun 19 14:34:13 2016
@@ -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, ""); }

Added: libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.non-const_observers/get.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.non-const_observers/get.pass.cpp?rev=273122&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.non-const_observers/get.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.non-const_observers/get.pass.cpp Sun Jun 19 14:34:13 2016
@@ -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,"");
+}

Added: libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.non-const_observers/op_arrow.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.non-const_observers/op_arrow.pass.cpp?rev=273122&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.non-const_observers/op_arrow.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.non-const_observers/op_arrow.pass.cpp Sun Jun 19 14:34:13 2016
@@ -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,"");
+}

Added: libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.non-const_observers/operator_element_type_ptr.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.non-const_observers/operator_element_type_ptr.pass.cpp?rev=273122&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.non-const_observers/operator_element_type_ptr.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.non-const_observers/operator_element_type_ptr.pass.cpp Sun Jun 19 14:34:13 2016
@@ -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);
+}

Added: libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.observers/dereference.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.observers/dereference.pass.cpp?rev=273122&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.observers/dereference.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.observers/dereference.pass.cpp Sun Jun 19 14:34:13 2016
@@ -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,"");
+}

Added: libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.observers/explicit_operator_element_type_ptr.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.observers/explicit_operator_element_type_ptr.pass.cpp?rev=273122&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.observers/explicit_operator_element_type_ptr.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.observers/explicit_operator_element_type_ptr.pass.cpp Sun Jun 19 14:34:13 2016
@@ -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, "");
+}

Added: libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.observers/get.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.observers/get.pass.cpp?rev=273122&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.observers/get.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.observers/get.pass.cpp Sun Jun 19 14:34:13 2016
@@ -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, "");
+}

Added: libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.observers/op_arrow.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.observers/op_arrow.pass.cpp?rev=273122&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.observers/op_arrow.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.observers/op_arrow.pass.cpp Sun Jun 19 14:34:13 2016
@@ -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,"");
+}

Added: libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.observers/operator_element_type_ptr.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.observers/operator_element_type_ptr.pass.cpp?rev=273122&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.observers/operator_element_type_ptr.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/propagate_const.observers/operator_element_type_ptr.pass.cpp Sun Jun 19 14:34:13 2016
@@ -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); }

Added: libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/swap.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/swap.pass.cpp?rev=273122&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/swap.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.class/swap.pass.cpp Sun Jun 19 14:34:13 2016
@@ -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);
+}
+

Added: libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/hash.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/hash.pass.cpp?rev=273122&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/hash.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/hash.pass.cpp Sun Jun 19 14:34:13 2016
@@ -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);
+}

Added: libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.comparison_function_objects/equal_to.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.comparison_function_objects/equal_to.pass.cpp?rev=273122&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.comparison_function_objects/equal_to.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.comparison_function_objects/equal_to.pass.cpp Sun Jun 19 14:34:13 2016
@@ -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));
+}

Added: libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.comparison_function_objects/greater.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.comparison_function_objects/greater.pass.cpp?rev=273122&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.comparison_function_objects/greater.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.comparison_function_objects/greater.pass.cpp Sun Jun 19 14:34:13 2016
@@ -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));
+}

Added: libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.comparison_function_objects/greater_equal.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.comparison_function_objects/greater_equal.pass.cpp?rev=273122&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.comparison_function_objects/greater_equal.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.comparison_function_objects/greater_equal.pass.cpp Sun Jun 19 14:34:13 2016
@@ -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));
+}

Added: libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.comparison_function_objects/less.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.comparison_function_objects/less.pass.cpp?rev=273122&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.comparison_function_objects/less.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.comparison_function_objects/less.pass.cpp Sun Jun 19 14:34:13 2016
@@ -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));
+}

Added: libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.comparison_function_objects/less_equal.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.comparison_function_objects/less_equal.pass.cpp?rev=273122&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.comparison_function_objects/less_equal.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.comparison_function_objects/less_equal.pass.cpp Sun Jun 19 14:34:13 2016
@@ -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));
+}

Added: libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.comparison_function_objects/not_equal_to.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.comparison_function_objects/not_equal_to.pass.cpp?rev=273122&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.comparison_function_objects/not_equal_to.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.comparison_function_objects/not_equal_to.pass.cpp Sun Jun 19 14:34:13 2016
@@ -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));
+}

Added: libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.relops/equal.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.relops/equal.pass.cpp?rev=273122&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.relops/equal.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.relops/equal.pass.cpp Sun Jun 19 14:34:13 2016
@@ -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),"");
+}

Added: libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.relops/greater_equal.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.relops/greater_equal.pass.cpp?rev=273122&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.relops/greater_equal.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.relops/greater_equal.pass.cpp Sun Jun 19 14:34:13 2016
@@ -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, "");
+}

Added: libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.relops/greater_than.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.relops/greater_than.pass.cpp?rev=273122&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.relops/greater_than.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.relops/greater_than.pass.cpp Sun Jun 19 14:34:13 2016
@@ -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, "");
+}

Added: libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.relops/less_equal.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.relops/less_equal.pass.cpp?rev=273122&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.relops/less_equal.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.relops/less_equal.pass.cpp Sun Jun 19 14:34:13 2016
@@ -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), "");
+
+}

Added: libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.relops/less_than.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.relops/less_than.pass.cpp?rev=273122&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.relops/less_than.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.relops/less_than.pass.cpp Sun Jun 19 14:34:13 2016
@@ -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, "");
+}

Added: libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.relops/not_equal.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.relops/not_equal.pass.cpp?rev=273122&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.relops/not_equal.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/propagate_const.relops/not_equal.pass.cpp Sun Jun 19 14:34:13 2016
@@ -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,"");
+}

Added: libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/swap.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/swap.pass.cpp?rev=273122&view=auto
==============================================================================
--- libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/swap.pass.cpp (added)
+++ libcxx/trunk/test/std/experimental/utilities/propagate_const/propagate_const.nonmembers/swap.pass.cpp Sun Jun 19 14:34:13 2016
@@ -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);
+}

Added: libcxx/trunk/test/support/propagate_const_helpers.h
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/support/propagate_const_helpers.h?rev=273122&view=auto
==============================================================================
--- libcxx/trunk/test/support/propagate_const_helpers.h (added)
+++ libcxx/trunk/test/support/propagate_const_helpers.h Sun Jun 19 14:34:13 2016
@@ -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_) {}
+};
+




More information about the cfe-commits mailing list