Files
clang-p2996/libcxx/test/std/experimental/reflection/related-reflections.pass.cpp
2025-06-24 11:01:59 -04:00

188 lines
6.1 KiB
C++

//===----------------------------------------------------------------------===//
//
// Copyright 2024 Bloomberg Finance L.P.
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++03 || c++11 || c++14 || c++17 || c++20
// ADDITIONAL_COMPILE_FLAGS: -freflection
// <experimental/reflection>
//
// [reflection]
#include <meta>
constexpr auto ctx = std::meta::access_context::current();
// ============
// find_type_of
// ============
namespace find_type_of {
using int_alias = int;
using int_alias_alias = int_alias;
extern int i;
extern int_alias ia;
extern decltype(int_alias{}) dtia;
static_assert(type_of(^^i) == ^^int);
static_assert(type_of(^^ia) != ^^int_alias);
static_assert(type_of(^^ia) == ^^int);
static_assert(type_of(^^dtia) == ^^int);
static_assert(type_of(^^dtia) != ^^int_alias);
static_assert(^^int_alias != ^^int);
static_assert(^^int_alias != ^^int_alias_alias);
constexpr auto a = data_member_spec(^^int, {});
constexpr auto b = data_member_spec(^^int_alias, {});
static_assert(type_of(a) == ^^int);
static_assert(type_of(b) != ^^int_alias);
} // namespace expression_type
// ================
// find_template_of
// ================
namespace find_template_of {
template <typename> struct TCls {
template <typename T> struct TInnerCls {};
};
template <typename> void TFn() {};
template <typename> int TVar = 0;
template <typename> using TAlias = int;
template <typename U> using DependentAlias = TCls<int>::template TInnerCls<U>;
static_assert(template_of(^^TCls<int>) == ^^TCls);
static_assert(template_of(^^TFn<int>) == ^^TFn);
static_assert(template_of(^^TVar<int>) == ^^TVar);
static_assert(template_of(^^TAlias<int>) == ^^TAlias);
static_assert(template_of(^^DependentAlias<bool>) == ^^DependentAlias);
} // namespace find_template_of
// ==============
// find_parent_of
// ==============
namespace find_parent_of {
struct Base {};
struct Cls : Base {
struct InnerCls {};
int mem;
void memfn();
static void sfn();
using Alias = int;
template <typename> static constexpr int TSMem = 0;
template <typename> void TMemFn();
template <typename> static void TSMemFn();
template <typename> struct TInnerCls { int mem; };
template <typename> using TAlias = int;
};
int var;
void fn();
namespace NestedNS { int var; };
enum Enum { A };
template <typename> constexpr int TVar = 0;
template <typename> void TFn();
template <typename> struct TCls { int var; };
template <typename> using TAlias = int;
template <typename> concept Concept = requires { true; };
static_assert(parent_of(^^find_parent_of) == ^^::);
static_assert(parent_of(^^Cls::InnerCls) == ^^Cls);
static_assert(parent_of(^^Cls::mem) == ^^Cls);
static_assert(parent_of(^^Cls::memfn) == ^^Cls);
static_assert(parent_of(^^Cls::sfn) == ^^Cls);
static_assert(parent_of(^^Cls::Alias) == ^^Cls);
static_assert(parent_of(bases_of(^^Cls, ctx)[0]) == ^^Cls);
static_assert(parent_of(^^Cls::TSMem) == ^^Cls);
static_assert(parent_of(^^Cls::TSMem<int>) == ^^Cls);
static_assert(parent_of(^^Cls::TMemFn) == ^^Cls);
static_assert(parent_of(^^Cls::TMemFn<int>) == ^^Cls);
static_assert(parent_of(^^Cls::TSMemFn) == ^^Cls);
static_assert(parent_of(^^Cls::TSMemFn<int>) == ^^Cls);
static_assert(parent_of(^^Cls::TInnerCls) == ^^Cls);
static_assert(parent_of(^^Cls::TInnerCls<int>) == ^^Cls);
static_assert(parent_of(^^Cls::TInnerCls<int>::mem) == ^^Cls::TInnerCls<int>);
static_assert(parent_of(^^Cls::TAlias) == ^^Cls);
static_assert(parent_of(^^Cls::TAlias<int>) == ^^Cls);
static_assert(parent_of(^^Cls) == ^^find_parent_of);
static_assert(parent_of(^^var) == ^^find_parent_of);
static_assert(parent_of(^^fn) == ^^find_parent_of);
static_assert(parent_of(^^NestedNS) == ^^find_parent_of);
static_assert(parent_of(^^NestedNS::var) == ^^NestedNS);
static_assert(parent_of(^^A) == ^^Enum);
static_assert(parent_of(^^TVar) == ^^find_parent_of);
static_assert(parent_of(^^TVar<int>) == ^^find_parent_of);
static_assert(parent_of(^^TFn) == ^^find_parent_of);
static_assert(parent_of(^^TFn<int>) == ^^find_parent_of);
static_assert(parent_of(^^TCls) == ^^find_parent_of);
static_assert(parent_of(^^TCls<int>) == ^^find_parent_of);
static_assert(parent_of(^^TAlias) == ^^find_parent_of);
static_assert(parent_of(^^TAlias<int>) == ^^find_parent_of);
static_assert(parent_of(^^Concept) == ^^find_parent_of);
} // namespace find_parent_of
// ==========
// dealiasing
// ==========
namespace dealiasing {
using int_alias = int;
using int_alias_alias = int_alias;
template <typename T> using TAlias = T;
namespace NSAlias = dealiasing;
namespace NSAliasAlias = NSAlias;
static_assert(dealias(^^int) == ^^int);
static_assert(dealias(^^int_alias) == ^^int);
static_assert(dealias(^^int_alias_alias) == ^^int);
static_assert(dealias(^^TAlias<int_alias_alias>) == ^^int);
static_assert(dealias(^^::) == ^^::);
static_assert(dealias(^^dealiasing) == ^^dealiasing);
static_assert(dealias(^^NSAlias) == ^^dealiasing);
static_assert(dealias(^^NSAliasAlias) == ^^dealiasing);
static_assert(dealias(std::meta::info{}) == std::meta::info{});
} // namespace dealiasing
// ================
// anonymous_unions
// ================
namespace anonymous_unions {
struct S {
union {
union {
int m;
};
};
};
static constexpr auto rm = ^^S::m;
static_assert(type_of(rm) == ^^int);
static_assert(is_union_type(parent_of(rm)));
static_assert(is_union_type(parent_of(parent_of(rm))));
static_assert(parent_of(rm) != parent_of(parent_of(rm)));
static_assert(parent_of(parent_of(parent_of(rm))) == ^^S);
} // namespace anonymous_unions
int main() { }