C++26'daki yansıma: meta işlevler | merhaba çevrimiçi

Adanali

Active member
C++26'daki yansıma: meta işlevler | merhaba çevrimiçi


  1. C++26'da yansıma: meta işlevler

Duyuru



Bir önceki yazımda C++26'da Reflection'a giriş yaptıktan sonra bu sefer metafonksiyonlardan bahsedeceğim. Bunlara denir consteval ilan etti. consteval sözde acil bir işlev yaratır. Anında bir işleve yapılan her çağrı, bir derleme zamanı sabiti oluşturur. Daha açık ifade etmek gerekirse: bir consteval (hemen) İşlev derleme zamanında çalışır.













Rainer Grimm uzun yıllardır yazılım mimarı, ekip ve eğitim yöneticisi olarak çalışmaktadır. C++, Python ve Haskell programlama dilleri üzerine makaleler yazmaktan hoşlanıyor, aynı zamanda özel konferanslarda sık sık konuşmaktan da hoşlanıyor. Modern C++ adlı blogunda C++ tutkusunu yoğun bir şekilde ele alıyor.







Daha fazlası consteval VE constinit makalemde bulunabilir C++20'de iki yeni anahtar kelime: consteval ve constinit.

Şu ana kadar bildiğimiz gibi:



constexpr auto r = ^int;
typename[:r:] x = 42; // Same as: int x = 42;
typename[:^char:] c = '*'; // Same as: char c = '*';



Yansıma operatörü (^) dilbilgisi öğesinden (C++ öğesi) bir yansıma değeri oluşturur. Yansıma değerinin veri türü std::meta::info. Yansıma değeri, meta işlevlerin veya birleştiricinin bir argümanı olabilir ([: refl :]) Olmak. Birleştiriciler dilbilgisi öğeleri oluşturur.

Yansıma değeri daha sonra aşağıdaki gibi tanımlanabilir:


namespace std {
namespace meta {
using info = decltype(^::);
}
}


Hala eksik olan ne? Açıkçası meta işlevleri eksik. Hepsini iki nedenden dolayı sunacağım:

  • Birçok metafonksiyon vardır.
  • Tüm meta işlevlerin resmi bir listesi (Ekim 2024 itibarıyla) yoktur.
Metafonksiyonlar



namespace std::meta {
using info = decltype(^::);

template <typename R>
concept reflection_range = /* see above */;

// name and location
consteval auto identifier_of(info r) -> string_view;
consteval auto u8identifier_of(info r) -> u8string_view;

consteval auto display_string_of(info r) -> string_view;
consteval auto u8display_string_of(info r) -> u8string_view;

consteval auto source_location_of(info r) -> source_location;

// type queries
consteval auto type_of(info r) -> info;
consteval auto parent_of(info r) -> info;
consteval auto dealias(info r) -> info;

// object and value queries
consteval auto object_of(info r) -> info;
consteval auto value_of(info r) -> info;

// template queries
consteval auto template_of(info r) -> info;
consteval auto template_arguments_of(info r) -> vector<info>;

// member queries
consteval auto members_of(info type_class) -> vector<info>;
consteval auto bases_of(info type_class) -> vector<info>;
consteval auto static_data_members_of(info type_class) -> vector<info>;
consteval auto nonstatic_data_members_of(info type_class) -> vector<info>;
consteval auto subobjects_of(info type_class) -> vector<info>;
consteval auto enumerators_of(info type_enum) -> vector<info>;

// member access
struct access_context {
static consteval access_context current() noexcept;
consteval access_context() noexcept;
};

consteval auto is_accessible(
info r,
acess_context from = access_context::current());

consteval auto accessible_members_of(
info target,
access_context from = access_context::current()) -> vector<info>;
consteval auto accessible_bases_of(info target,
info target,
access_context from = access_context::current()) -> vector<info>;
consteval auto accessible_nonstatic_data_members_of(
info target,
access_context from = access_context::current()) -> vector<info>;
consteval auto accessible_static_data_members_of(
info target,
access_context from = access_context::current()) -> vector<info>;
consteval auto accessible_subobjects_of(
info target,
access_context from = access_context::current()) -> vector<info>;

// substitute
template <reflection_range R = initializer_list<info>>
consteval auto can_substitute(info templ, R&& args) -> bool;
template <reflection_range R = initializer_list<info>>
consteval auto substitute(info templ, R&& args) -> info;

// reflect_invoke
template <reflection_range R = initializer_list<info>>
consteval auto reflect_invoke(info target, R&& args) -> info;
template <reflection_range R1 = initializer_list<info>, reflection_range R2 = initializer_list<info>>
consteval auto reflect_invoke(info target, R1&& tmpl_args, R2&& args) -> info;

// reflect expression results
template <typename T>
consteval auto reflect_value(T value) -> info;
template <typename T>
consteval auto reflect_object(T& value) -> info;
template <typename T>
consteval auto reflect_function(T& value) -> info;

// extract
template <typename T>
consteval auto extract(info) -> T;

// other type predicates (see the wording)
consteval auto is_public(info r) -> bool;
consteval auto is_protected(info r) -> bool;
consteval auto is_private(info r) -> bool;
consteval auto is_virtual(info r) -> bool;
consteval auto is_pure_virtual(info entity) -> bool;
consteval auto is_override(info entity) -> bool;
consteval auto is_final(info r) -> bool;
consteval auto is_deleted(info entity) -> bool;
consteval auto is_defaulted(info entity) -> bool;
consteval auto is_explicit(info entity) -> bool;
consteval auto is_noexcept(info entity) -> bool;
consteval auto is_bit_field(info entity) -> bool;
consteval auto is_enumerator(info entity) -> bool;
consteval auto is_const(info r) -> bool;
consteval auto is_volatile(info r) -> bool;
consteval auto is_lvalue_reference_qualified(info r) -> bool;
consteval auto is_rvalue_reference_qualified(info r) -> bool;
consteval auto has_static_storage_duration(info r) -> bool;
consteval auto has_thread_storage_duration(info r) -> bool;
consteval auto has_automatic_storage_duration(info r) -> bool;
consteval auto has_internal_linkage(info r) -> bool;
consteval auto has_module_linkage(info r) -> bool;
consteval auto has_external_linkage(info r) -> bool;
consteval auto has_linkage(info r) -> bool;
consteval auto is_class_member(info entity) -> bool;
consteval auto is_namespace_member(info entity) -> bool;
consteval auto is_nonstatic_data_member(info entity) -> bool;
consteval auto is_static_member(info entity) -> bool;
consteval auto is_base(info entity) -> bool;
consteval auto is_data_member_spec(info r) -> bool;
consteval auto is_namespace(info entity) -> bool;
consteval auto is_function(info entity) -> bool;
consteval auto is_variable(info entity) -> bool;
consteval auto is_type(info entity) -> bool;
consteval auto is_type_alias(info entity) -> bool;
consteval auto is_namespace_alias(info entity) -> bool;
consteval auto is_complete_type(info entity) -> bool;
consteval auto is_template(info entity) -> bool;
consteval auto is_function_template(info entity) -> bool;
consteval auto is_variable_template(info entity) -> bool;
consteval auto is_class_template(info entity) -> bool;
consteval auto is_alias_template(info entity) -> bool;
consteval auto is_conversion_function_template(info entity) -> bool;
consteval auto is_operator_function_template(info entity) -> bool;
consteval auto is_literal_operator_template(info entity) -> bool;
consteval auto is_constructor_template(info entity) -> bool;
consteval auto is_concept(info entity) -> bool;
consteval auto is_structured_binding(info entity) -> bool;
consteval auto is_value(info entity) -> bool;
consteval auto is_object(info entity) -> bool;
consteval auto has_template_arguments(info r) -> bool;
consteval auto has_default_member_initializer(info r) -> bool;

consteval auto is_special_member(info r) -> bool;
consteval auto is_conversion_function(info r) -> bool;
consteval auto is_operator_function(info r) -> bool;
consteval auto is_literal_operator(info r) -> bool;
consteval auto is_constructor(info r) -> bool;
consteval auto is_default_constructor(info r) -> bool;
consteval auto is_copy_constructor(info r) -> bool;
consteval auto is_move_constructor(info r) -> bool;
consteval auto is_assignment(info r) -> bool;
consteval auto is_copy_assignment(info r) -> bool;
consteval auto is_move_assignment(info r) -> bool;
consteval auto is_destructor(info r) -> bool;
consteval auto is_user_provided(info r) -> bool;

// define_class
struct data_member_options_t;
consteval auto data_member_spec(info type_class,
data_member_options_t options = {}) -> info;
template <reflection_range R = initializer_list<info>>
consteval auto define_class(info type_class, R&&) -> info;

// define_static_string
consteval auto define_static_string(string_view str) -> const char *;
consteval auto define_static_string(u8string_view str) -> const char8_t *;

// data layout
struct member_offsets {
size_t bytes;
size_t bits;
constexpr auto total_bits() const -> . double quote. double quote. double quote. double quote. size_t;
auto operator<=>(member_offsets const&) const = default;
};

consteval auto offset_of(info entity) -> member_offsets;
consteval auto size_of(info entity) -> size_t;
consteval auto alignment_of(info entity) -> size_t;
consteval auto bit_size_of(info entity) -> size_t;

}



Her şeyden önce, meta işlevler size tip özelliklerinin meta işlevlerini hatırlatabilir. Ancak büyük bir fark vardır: türün özellik metafonksiyonları çağrılır. constexpr bildirildi, ancak yansıma meta işlevleri şu şekilde bildirildi: consteval. Bu, tür özelliği meta işlevlerinin derleme zamanında yürütüldüğü anlamına gelir Şekerlerancak yansıma meta işlevleri derleme zamanında yürütülür görev. Dolayısıyla argümanlarının sabit ifadeler olması gerekir.

Yansıma kitaplığı aşağıdaki işlemler için meta işlevlere sahiptir:

  • adı veya konumu döndürür,
  • bir veri türünün, nesnenin ve değerin, modelin ve üyenin yansıma değerini döndürür,
  • üyelere erişimi döndürür,
  • model argümanlarının yansımasını döndürür,
  • bir aramanın sonucunu döndürür,
  • değerlendirilen ifadenin sonucunu döndürür e
  • Splicers'a benzer bir değer çıkarır.
Ayrıca Reflection Library'de 50'den fazla derleme zamanı koşulu bulunur. Bunlar derleme zamanında oluşturulan çağrılabilir öğelerdir bool geri döner

Ayrıca bir sınıfı tanımlamak için meta işlevler vardır.

Bir sonraki adım nedir?


Bir sonraki yazımda meta fonksiyonları uygulayacağım.


(Ben)
 
Üst