namespace std_example {
template<class T> struct A { ~A() = delete; }; template<class T> auto h() -> A<T>;
template<class T> auto i(T) -> T;
template<class T> auto f(T) -> decltype(i(h<T>())); template<class T> auto f(T) -> void; auto g() -> void {
  f(42); }
template<class T> auto q(T) -> decltype((h<T>()));
void r() {
      q(42); }
}
class PD {
  friend struct A;
  ~PD(); public:
  typedef int n;
};
struct DD {
  ~DD() = delete;   typedef int n;
};
PD pd();
DD dd();
struct A {
  decltype(pd()) s;   decltype(pd())::n n;   decltype(dd()) *p = new decltype(dd()); };
A a();
decltype(
    pd(),     pd()) pd1; decltype(dd(),          dd()) dd1;
decltype(a(),
         dd()) dd2; decltype(
    pd(),     0) pd2;
decltype(((13, ((dd())))))::n dd_parens; decltype(((((42)), pd())))::n pd_parens_comma; 
extern decltype(pd()) pd_ref; decltype((pd_ref)) pd_ref3 = pd_ref; decltype(pd_ref) pd_ref2 = pd_ref; 
namespace libcxx_example {
  struct nat {
    nat() = delete;
    nat(const nat&) = delete;
    nat &operator=(const nat&) = delete;
    ~nat() = delete;
  };
  struct any {
    any(...);
  };
  template<typename T, typename U> struct is_same { static const bool value = false; };
  template<typename T> struct is_same<T, T> { static const bool value = true; };
  template<typename T> T declval();
  void swap(int &a, int &b);
  nat swap(any, any);
  template<typename T> struct swappable {
    typedef decltype(swap(declval<T&>(), declval<T&>())) type;
    static const bool value = !is_same<type, nat>::value;
    constexpr operator bool() const { return value; }
  };
  static_assert(swappable<int>(), "");
  static_assert(!swappable<const int>(), "");
}
namespace RequireCompleteType {
  template<int N, bool OK> struct S {
    static_assert(OK, "boom!");   };
  template<typename T> T make();
  template<int N, bool OK> S<N, OK> make();
  void consume(...);
  decltype(make<0, false>()) *p1;   decltype((make<1, false>())) *p2; 
    decltype(123, make<2, false>()) *p3; 
  decltype(consume(make<3, false>())) *p4; 
  decltype(make<decltype(make<4, false>())>()) *p5; }
namespace Overload {
  DD operator+(PD &a, PD &b);
  decltype(pd()) *pd_ptr;
  decltype(*pd_ptr + *pd_ptr) *dd_ptr; 
  decltype(0, *pd_ptr) pd_ref2 = pd_ref;   DD operator,(int a, PD b);
  decltype(0, *pd_ptr) *dd_ptr2; }