diff --git a/develop/singles/headers/meta.hpp/meta_all.hpp b/develop/singles/headers/meta.hpp/meta_all.hpp index 43883bf..d87cb6d 100644 --- a/develop/singles/headers/meta.hpp/meta_all.hpp +++ b/develop/singles/headers/meta.hpp/meta_all.hpp @@ -766,14 +766,22 @@ namespace meta_hpp::detail { struct hash_combiner { template < typename T > - [[nodiscard]] std::size_t operator()(const T& x) noexcept { + [[nodiscard]] std::size_t operator()(const T& x) const noexcept { return std::hash{}(x); } template < typename T > - [[nodiscard]] std::size_t operator()(std::size_t seed, const T& x) noexcept { + requires(sizeof(std::size_t) == sizeof(std::uint32_t)) + [[nodiscard]] std::size_t operator()(std::size_t seed, const T& x) const noexcept { // NOLINTNEXTLINE(*-magic-numbers) - return (seed ^= std::hash{}(x) + 0x9e3779b9 + (seed << 6) + (seed >> 2)); + return (seed ^= std::hash{}(x) + 0x9e3779b9U + (seed << 6) + (seed >> 2)); + } + + template < typename T > + requires(sizeof(std::size_t) == sizeof(std::uint64_t)) + [[nodiscard]] std::size_t operator()(std::size_t seed, const T& x) const noexcept { + // NOLINTNEXTLINE(*-magic-numbers) + return (seed ^= std::hash{}(x) + 0x9e3779b97f4a7c15LLU + (seed << 12) + (seed >> 4)); } }; } @@ -1163,13 +1171,58 @@ namespace meta_hpp::detail concept non_function_pointer_kind = std::is_pointer_v && !std::is_function_v>; } +namespace meta_hpp::detail +{ + template < typename T > + struct type_to_kind; + + template < typename T > + inline constexpr type_kind type_to_kind_v = type_to_kind::value; +} + +namespace meta_hpp::detail +{ + template < array_kind T > + struct type_to_kind : std::integral_constant {}; + + template < class_kind T > + struct type_to_kind : std::integral_constant {}; + + template < enum_kind T > + struct type_to_kind : std::integral_constant {}; + + template < function_kind T > + struct type_to_kind : std::integral_constant {}; + + template < member_pointer_kind T > + struct type_to_kind : std::integral_constant {}; + + template < method_pointer_kind T > + struct type_to_kind : std::integral_constant {}; + + template < nullptr_kind T > + struct type_to_kind : std::integral_constant {}; + + template < number_kind T > + struct type_to_kind : std::integral_constant {}; + + template < pointer_kind T > + struct type_to_kind : std::integral_constant {}; + + template < reference_kind T > + struct type_to_kind : std::integral_constant {}; + + template < void_kind T > + struct type_to_kind : std::integral_constant {}; +} + namespace meta_hpp::detail { template < typename... Types > struct type_list { template < typename F > // NOLINTNEXTLINE(*-missing-std-forward) - static void for_each(F&& f) { + static constexpr void for_each(F&& f) { (f.template operator()(), ...); } }; @@ -1241,6 +1294,30 @@ namespace meta_hpp::detail using type_list_first_of_t = typename type_list_first_of::type; } +namespace meta_hpp::detail +{ + template < template < typename > class Pred, typename TypeList > + struct type_list_and; + + template < template < typename > class Pred, typename... Types > + struct type_list_and> : std::bool_constant<(... && Pred::value)> {}; + + template < template < typename > class Pred, typename TypeList > + inline constexpr bool type_list_and_v = type_list_and::value; +} + +namespace meta_hpp::detail +{ + template < template < typename > class Pred, typename TypeList > + struct type_list_or; + + template < template < typename > class Pred, typename... Types > + struct type_list_or> : std::bool_constant<(... || Pred::value)> {}; + + template < template < typename > class Pred, typename TypeList > + inline constexpr bool type_list_or_v = type_list_or::value; +} + namespace meta_hpp { using detail::error_code; @@ -1586,8 +1663,10 @@ namespace meta_hpp namespace meta_hpp::detail { enum class array_flags : std::uint32_t { - is_bounded = 1 << 0, - is_unbounded = 1 << 1, + is_readonly = 1 << 0, + is_volatile = 1 << 1, + is_bounded = 1 << 2, + is_unbounded = 1 << 3, }; using array_bitflags = bitflags; @@ -1600,11 +1679,23 @@ namespace meta_hpp::detail struct array_traits { static constexpr std::size_t extent{std::extent_v}; - using data_type = std::remove_extent_t; + using cv_data_type = std::remove_extent_t; + inline static constexpr bool is_readonly = std::is_const_v; + inline static constexpr bool is_volatile = std::is_volatile_v; + + using data_type = std::remove_cv_t; [[nodiscard]] static constexpr array_bitflags make_flags() noexcept { array_bitflags flags{}; + if constexpr ( is_readonly ) { + flags.set(array_flags::is_readonly); + } + + if constexpr ( is_volatile ) { + flags.set(array_flags::is_volatile); + } + if constexpr ( std::is_bounded_array_v ) { flags.set(array_flags::is_bounded); } @@ -1932,7 +2023,7 @@ namespace meta_hpp::detail static constexpr std::size_t arity{sizeof...(Args)}; using class_type = Class; - using argument_types = type_list; + using argument_types = type_list...>; [[nodiscard]] static constexpr constructor_bitflags make_flags() noexcept { constructor_bitflags flags{}; @@ -2026,8 +2117,8 @@ namespace meta_hpp::detail struct function_traits { static constexpr std::size_t arity{sizeof...(Args)}; - using return_type = R; - using argument_types = type_list; + using return_type = std::remove_cv_t; + using argument_types = type_list...>; [[nodiscard]] static constexpr function_bitflags make_flags() noexcept { return {}; @@ -2046,6 +2137,7 @@ namespace meta_hpp::detail { enum class member_flags : std::uint32_t { is_readonly = 1 << 0, + is_volatile = 1 << 1, }; using member_bitflags = bitflags; @@ -2059,16 +2151,24 @@ namespace meta_hpp::detail template < typename V, typename C > struct member_traits { + using cv_value_type = V; + inline static constexpr bool is_readonly = std::is_const_v; + inline static constexpr bool is_volatile = std::is_volatile_v; + using class_type = C; - using value_type = V; + using value_type = std::remove_cv_t; [[nodiscard]] static constexpr member_bitflags make_flags() noexcept { member_bitflags flags{}; - if constexpr ( std::is_const_v ) { + if constexpr ( is_readonly ) { flags.set(member_flags::is_readonly); } + if constexpr ( is_volatile ) { + flags.set(member_flags::is_volatile); + } + return flags; } }; @@ -2097,9 +2197,9 @@ namespace meta_hpp::detail static constexpr std::size_t arity{sizeof...(Args)}; using class_type = C; - using return_type = R; + using return_type = std::remove_cv_t; using qualified_type = C; - using argument_types = type_list; + using argument_types = type_list...>; [[nodiscard]] static constexpr method_bitflags make_flags() noexcept { return {}; @@ -2254,6 +2354,7 @@ namespace meta_hpp::detail { enum class pointer_flags : std::uint32_t { is_readonly = 1 << 0, + is_volatile = 1 << 1, }; using pointer_bitflags = bitflags; @@ -2264,15 +2365,23 @@ namespace meta_hpp::detail { template < pointer_kind Pointer > struct pointer_traits { - using data_type = std::remove_pointer_t; + using cv_data_type = std::remove_pointer_t; + inline static constexpr bool is_readonly = std::is_const_v; + inline static constexpr bool is_volatile = std::is_volatile_v; + + using data_type = std::remove_cv_t; [[nodiscard]] static constexpr pointer_bitflags make_flags() noexcept { pointer_bitflags flags{}; - if constexpr ( std::is_const_v ) { + if constexpr ( is_readonly ) { flags.set(pointer_flags::is_readonly); } + if constexpr ( is_volatile ) { + flags.set(pointer_flags::is_volatile); + } + return flags; } }; @@ -2282,8 +2391,9 @@ namespace meta_hpp::detail { enum class reference_flags : std::uint32_t { is_readonly = 1 << 0, - is_lvalue = 1 << 1, - is_rvalue = 1 << 2, + is_volatile = 1 << 1, + is_lvalue = 1 << 2, + is_rvalue = 1 << 3, }; using reference_bitflags = bitflags; @@ -2294,15 +2404,23 @@ namespace meta_hpp::detail { template < reference_kind Reference > struct reference_traits { - using data_type = std::remove_reference_t; + using cv_data_type = std::remove_reference_t; + inline static constexpr bool is_readonly = std::is_const_v; + inline static constexpr bool is_volatile = std::is_volatile_v; + + using data_type = std::remove_cv_t; [[nodiscard]] static constexpr reference_bitflags make_flags() noexcept { reference_bitflags flags{}; - if constexpr ( std::is_const_v ) { + if constexpr ( is_readonly ) { flags.set(reference_flags::is_readonly); } + if constexpr ( is_volatile ) { + flags.set(reference_flags::is_volatile); + } + if constexpr ( std::is_lvalue_reference_v ) { flags.set(reference_flags::is_lvalue); } @@ -2454,31 +2572,28 @@ namespace meta_hpp class type_id final { public: type_id() = default; + ~type_id() = default; - [[nodiscard]] bool is_valid() const noexcept { - return data_ != nullptr; - } + type_id(type_id&&) = default; + type_id(const type_id&) = default; - [[nodiscard]] explicit operator bool() const noexcept { - return is_valid(); - } + type_id& operator=(type_id&&) = default; + type_id& operator=(const type_id&) = default; - void swap(type_id& other) noexcept { - std::swap(data_, other.data_); - } + [[nodiscard]] bool is_valid() const noexcept; + [[nodiscard]] explicit operator bool() const noexcept; - [[nodiscard]] std::size_t get_hash() const noexcept { - return data_ != nullptr ? detail::hash_combiner{}(data_) : 0; - } + void swap(type_id& other) noexcept; + [[nodiscard]] std::size_t get_hash() const noexcept; - [[nodiscard]] std::strong_ordering operator<=>(const type_id& other) const = default; + [[nodiscard]] bool operator==(const type_id& other) const noexcept; + [[nodiscard]] std::strong_ordering operator<=>(const type_id& other) const noexcept; private: template < type_family T > friend class type_base; - explicit type_id(const detail::type_data_base* data) - : data_{data} {} + explicit type_id(const detail::type_data_base* data); private: const detail::type_data_base* data_{}; @@ -2507,34 +2622,20 @@ namespace meta_hpp type_base() = default; - explicit type_base(data_ptr data) - : data_{data} {} + explicit type_base(data_ptr data); - type_base(type_base&&) noexcept = default; + type_base(type_base&&) = default; type_base(const type_base&) = default; - type_base& operator=(type_base&&) noexcept = default; + type_base& operator=(type_base&&) = default; type_base& operator=(const type_base&) = default; - [[nodiscard]] bool is_valid() const noexcept { - return data_ != nullptr; - } + [[nodiscard]] bool is_valid() const noexcept; + [[nodiscard]] explicit operator bool() const noexcept; - [[nodiscard]] explicit operator bool() const noexcept { - return is_valid(); - } - - [[nodiscard]] id_type get_id() const noexcept { - return id_type{data_}; - } - - [[nodiscard]] type_kind get_kind() const noexcept { - return data_->kind; - } - - [[nodiscard]] const metadata_map& get_metadata() const noexcept { - return data_->metadata; - } + [[nodiscard]] id_type get_id() const noexcept; + [[nodiscard]] type_kind get_kind() const noexcept; + [[nodiscard]] const metadata_map& get_metadata() const noexcept; protected: ~type_base() = default; @@ -2863,12 +2964,14 @@ namespace meta_hpp::detail struct type_data_base { // NOLINTBEGIN(*-avoid-const-or-ref-data-members) const type_kind kind; + const std::size_t shared; // NOLINTEND(*-avoid-const-or-ref-data-members) metadata_map metadata; - explicit type_data_base(type_kind nkind) - : kind{nkind} {} + explicit type_data_base(type_kind nkind, std::size_t nshared) + : kind{nkind} + , shared{nshared} {} type_data_base(type_data_base&&) = delete; type_data_base(const type_data_base&) = delete; @@ -3034,6 +3137,85 @@ namespace meta_hpp::detail }; } +namespace meta_hpp +{ + inline type_id::type_id(const detail::type_data_base* data) + : data_{data} {} + + inline bool type_id::is_valid() const noexcept { + return data_ != nullptr; + } + + inline type_id::operator bool() const noexcept { + return is_valid(); + } + + inline void type_id::swap(type_id& other) noexcept { + std::swap(data_, other.data_); + } + + inline std::size_t type_id::get_hash() const noexcept { + return data_ != nullptr ? data_->shared : 0; + } + + inline bool type_id::operator==(const type_id& other) const noexcept { + if ( data_ == other.data_ ) { + return true; + } + + if ( is_valid() != other.is_valid() ) { + return false; + } + + return data_->shared == other.data_->shared; + } + + inline std::strong_ordering type_id::operator<=>(const type_id& other) const noexcept { + if ( data_ == other.data_ ) { + return std::strong_ordering::equal; + } + + // NOLINTNEXTLINE(*-bool-conversion) + if ( const std::strong_ordering cmp{is_valid() <=> other.is_valid()}; cmp != std::strong_ordering::equal ) { + return cmp; + } + + return data_->shared <=> other.data_->shared; + } +} + +namespace meta_hpp +{ + template < type_family Type > + type_base::type_base(data_ptr data) + : data_{data} {} + + template < type_family Type > + bool type_base::is_valid() const noexcept { + return data_ != nullptr; + } + + template < type_family Type > + type_base::operator bool() const noexcept { + return is_valid(); + } + + template < type_family Type > + type_base::id_type type_base::get_id() const noexcept { + return id_type{data_}; + } + + template < type_family Type > + type_kind type_base::get_kind() const noexcept { + return data_->kind; + } + + template < type_family Type > + const metadata_map& type_base::get_metadata() const noexcept { + return data_->metadata; + } +} + namespace meta_hpp { class argument_index final { @@ -6171,6 +6353,360 @@ namespace meta_hpp::detail } } +namespace meta_hpp::detail +{ + template < typename T > + struct shared_type_name; + + template < type_kind, typename... > + struct shared_type_hash; +} + +namespace meta_hpp::detail +{ + template < typename Type > + [[nodiscard]] constexpr std::size_t shared_hash() noexcept { + return shared_type_hash, Type>{}(); + } + + template < enum_kind Enum > + [[nodiscard]] constexpr std::size_t shared_hash(Enum value) noexcept { + return static_cast(value); + } + + template < enum_kind Enum > + [[nodiscard]] constexpr std::size_t shared_hash(bitflags value) noexcept { + return static_cast(value.as_raw()); + } + + template < typename Integral > + requires(std::is_integral_v && sizeof(Integral) <= sizeof(std::size_t)) + [[nodiscard]] constexpr std::size_t shared_hash(Integral value) noexcept { + return static_cast(value); + } + + template < typename Value > + requires(sizeof(std::size_t) == sizeof(std::uint32_t)) + [[nodiscard]] constexpr std::size_t shared_hash_append(std::size_t seed, Value value) noexcept { + // NOLINTNEXTLINE(*-magic-numbers) + return (seed ^= shared_hash(value) + 0x9e3779b9U + (seed << 6) + (seed >> 2)); + } + + template < typename Value > + requires(sizeof(std::size_t) == sizeof(std::uint64_t)) + [[nodiscard]] constexpr std::size_t shared_hash_append(std::size_t seed, Value value) noexcept { + // NOLINTNEXTLINE(*-magic-numbers) + return (seed ^= shared_hash(value) + 0x9e3779b97f4a7c15LLU + (seed << 12) + (seed >> 4)); + } +} + +namespace meta_hpp::detail +{ + template < typename T > + struct is_shared_type : std::false_type {}; + + template < typename T > + concept shared_type_kind = is_shared_type>::value; +} + +namespace meta_hpp::detail +{ + template < type_kind, typename... > + struct shared_type_data_hash { + [[nodiscard]] std::size_t operator()(const void* type_data) const noexcept { + return hash_combiner{}(type_data); + } + }; + + template < type_kind Kind, shared_type_kind Type > + struct shared_type_data_hash { + [[nodiscard]] std::size_t operator()(const void*) const noexcept { + return shared_type_hash{}(); + } + }; + + template < shared_type_kind Class, shared_type_kind... Args > + struct shared_type_data_hash { + [[nodiscard]] std::size_t operator()(const void*) const noexcept { + return shared_type_hash{}(); + } + }; + + template < shared_type_kind Class > + struct shared_type_data_hash { + [[nodiscard]] std::size_t operator()(const void*) const noexcept { + return shared_type_hash{}(); + } + }; +} + +namespace meta_hpp::detail +{ + template < typename T > + requires requires { + { shared_type_name{}() }; + } + struct is_shared_type : std::true_type {}; + + template < array_kind Array > + requires shared_type_kind::data_type> + struct is_shared_type : std::true_type {}; + + template < function_kind Function > + requires shared_type_kind::return_type> + && type_list_and_v::argument_types> + struct is_shared_type : std::true_type {}; + + template < member_pointer_kind Member > + requires shared_type_kind::class_type> + && shared_type_kind::value_type> + struct is_shared_type : std::true_type {}; + + template < method_pointer_kind Method > + requires shared_type_kind::class_type> + && shared_type_kind::return_type> + && type_list_and_v::argument_types> + struct is_shared_type : std::true_type {}; + + template < pointer_kind Pointer > + requires shared_type_kind::data_type> + struct is_shared_type : std::true_type {}; + + template < reference_kind Reference > + requires shared_type_kind::data_type> + struct is_shared_type : std::true_type {}; +} + +namespace meta_hpp::detail +{ + template < shared_type_kind Array > + struct shared_type_hash { + [[nodiscard]] constexpr std::size_t operator()() const noexcept { + std::size_t hash = shared_hash(type_kind::array_); + + using traits = array_traits; + hash = shared_hash_append(hash, traits::make_flags()); + + hash = shared_hash_append(hash, shared_hash()); + + hash = shared_hash_append(hash, traits::extent); + + return hash; + } + }; + + template < shared_type_kind Class > + struct shared_type_hash { + [[nodiscard]] constexpr std::size_t operator()() const noexcept { + std::size_t hash = shared_hash(type_kind::class_); + + using traits = class_traits; + hash = shared_hash_append(hash, traits::make_flags()); + + hash = shared_hash_append(hash, shared_type_name{}()); + + return hash; + } + }; + + template < shared_type_kind Class, shared_type_kind... Args > + struct shared_type_hash { + [[nodiscard]] constexpr std::size_t operator()() const noexcept { + std::size_t hash = shared_hash(type_kind::constructor_); + + using traits = constructor_traits; + hash = shared_hash_append(hash, traits::make_flags()); + + hash = shared_hash_append(hash, shared_hash()); + + traits::argument_types::for_each([&hash]() { // + hash = shared_hash_append(hash, shared_hash()); + }); + + return hash; + } + }; + + template < shared_type_kind Class > + struct shared_type_hash { + [[nodiscard]] constexpr std::size_t operator()() const noexcept { + std::size_t hash = shared_hash(type_kind::destructor_); + + using traits = destructor_traits; + hash = shared_hash_append(hash, traits::make_flags()); + + hash = shared_hash_append(hash, shared_hash()); + + return hash; + } + }; + + template < shared_type_kind Enum > + struct shared_type_hash { + [[nodiscard]] constexpr std::size_t operator()() const noexcept { + std::size_t hash = shared_hash(type_kind::enum_); + + using traits = enum_traits; + hash = shared_hash_append(hash, traits::make_flags()); + + hash = shared_hash_append(hash, shared_type_name{}()); + + return hash; + } + }; + + template < shared_type_kind Function > + struct shared_type_hash { + [[nodiscard]] constexpr std::size_t operator()() const noexcept { + std::size_t hash = shared_hash(type_kind::function_); + + using traits = function_traits; + hash = shared_hash_append(hash, traits::make_flags()); + + hash = shared_hash_append(hash, shared_hash()); + + traits::argument_types::for_each([&hash]() { // + hash = shared_hash_append(hash, shared_hash()); + }); + + return hash; + } + }; + + template < shared_type_kind Member > + struct shared_type_hash { + [[nodiscard]] constexpr std::size_t operator()() const noexcept { + std::size_t hash = shared_hash(type_kind::member_); + + using traits = member_traits; + hash = shared_hash_append(hash, traits::make_flags()); + + hash = shared_hash_append(hash, shared_hash()); + hash = shared_hash_append(hash, shared_hash()); + + return hash; + } + }; + + template < shared_type_kind Method > + struct shared_type_hash { + [[nodiscard]] constexpr std::size_t operator()() const noexcept { + std::size_t hash = shared_hash(type_kind::method_); + + using traits = method_traits; + hash = shared_hash_append(hash, traits::make_flags()); + + hash = shared_hash_append(hash, shared_hash()); + hash = shared_hash_append(hash, shared_hash()); + + traits::argument_types::for_each([&hash]() { // + hash = shared_hash_append(hash, shared_hash()); + }); + + return hash; + } + }; + + template < shared_type_kind Nullptr > + struct shared_type_hash { + [[nodiscard]] constexpr std::size_t operator()() const noexcept { + std::size_t hash = shared_hash(type_kind::nullptr_); + + hash = shared_hash_append(hash, shared_type_name{}()); + + return hash; + } + }; + + template < shared_type_kind Number > + struct shared_type_hash { + [[nodiscard]] constexpr std::size_t operator()() const noexcept { + std::size_t hash = shared_hash(type_kind::number_); + + using traits = number_traits; + hash = shared_hash_append(hash, traits::make_flags()); + + hash = shared_hash_append(hash, shared_type_name{}()); + + return hash; + } + }; + + template < shared_type_kind Pointer > + struct shared_type_hash { + [[nodiscard]] constexpr std::size_t operator()() const noexcept { + std::size_t hash = shared_hash(type_kind::pointer_); + + using traits = pointer_traits; + hash = shared_hash_append(hash, traits::make_flags()); + + hash = shared_hash_append(hash, shared_hash()); + + return hash; + } + }; + + template < shared_type_kind Reference > + struct shared_type_hash { + [[nodiscard]] constexpr std::size_t operator()() const noexcept { + std::size_t hash = shared_hash(type_kind::reference_); + + using traits = reference_traits; + hash = shared_hash_append(hash, traits::make_flags()); + + hash = shared_hash_append(hash, shared_hash()); + + return hash; + } + }; + + template < shared_type_kind Void > + struct shared_type_hash { + [[nodiscard]] constexpr std::size_t operator()() const noexcept { + std::size_t hash = shared_hash(type_kind::void_); + + hash = shared_hash_append(hash, shared_type_name{}()); + + return hash; + } + }; +} + +#define META_HPP_DEFINE_SHARED_TYPE(Type, Name) \ + namespace meta_hpp::detail \ + { \ + template <> \ + struct shared_type_name { \ + [[nodiscard]] constexpr std::size_t operator()() const noexcept { \ + return hashed_string{Name}.get_hash(); \ + } \ + }; \ + } + +META_HPP_DEFINE_SHARED_TYPE(void, "void") +META_HPP_DEFINE_SHARED_TYPE(bool, "bool") +META_HPP_DEFINE_SHARED_TYPE(wchar_t, "wchar_t") +META_HPP_DEFINE_SHARED_TYPE(decltype(nullptr), "nullptr_t") + +META_HPP_DEFINE_SHARED_TYPE(char8_t, "char8_t") +META_HPP_DEFINE_SHARED_TYPE(char16_t, "char16_t") +META_HPP_DEFINE_SHARED_TYPE(char32_t, "char32_t") + +META_HPP_DEFINE_SHARED_TYPE(float, "float") +META_HPP_DEFINE_SHARED_TYPE(double, "double") +META_HPP_DEFINE_SHARED_TYPE(long double, "long double") + +META_HPP_DEFINE_SHARED_TYPE(signed char, "schar") +META_HPP_DEFINE_SHARED_TYPE(unsigned char, "uchar") +META_HPP_DEFINE_SHARED_TYPE(signed short, "sshort") +META_HPP_DEFINE_SHARED_TYPE(unsigned short, "ushort") +META_HPP_DEFINE_SHARED_TYPE(signed int, "sint") +META_HPP_DEFINE_SHARED_TYPE(unsigned int, "uint") +META_HPP_DEFINE_SHARED_TYPE(signed long, "slong") +META_HPP_DEFINE_SHARED_TYPE(unsigned long, "ulong") +META_HPP_DEFINE_SHARED_TYPE(signed long long, "sllong") +META_HPP_DEFINE_SHARED_TYPE(unsigned long long, "ullong") + namespace meta_hpp::detail::function_type_data_impl { template < function_kind Function > @@ -6196,7 +6732,7 @@ namespace meta_hpp::detail { template < function_kind Function > function_type_data::function_type_data(type_list) - : type_data_base{type_kind::function_} + : type_data_base{type_kind::function_, shared_type_data_hash{}(this)} , flags{function_traits::make_flags()} , return_type{resolve_type::return_type>()} , argument_types(function_type_data_impl::make_argument_types()) {} @@ -6706,7 +7242,7 @@ namespace meta_hpp::detail { template < member_pointer_kind Member > member_type_data::member_type_data(type_list) - : type_data_base{type_kind::member_} + : type_data_base{type_kind::member_, shared_type_data_hash{}(this)} , flags{member_traits::make_flags()} , owner_type{resolve_type::class_type>()} , value_type{resolve_type::value_type>()} {} @@ -6815,7 +7351,7 @@ namespace meta_hpp::detail using class_type = typename mt::class_type; using value_type = typename mt::value_type; - if constexpr ( std::is_const_v ) { + if constexpr ( mt::is_readonly ) { (void)registry; (void)member_ptr; (void)inst; @@ -6847,7 +7383,7 @@ namespace meta_hpp::detail using class_type = typename mt::class_type; using value_type = typename mt::value_type; - if constexpr ( std::is_const_v ) { + if constexpr ( mt::is_readonly ) { (void)registry; (void)inst; (void)arg; @@ -7079,7 +7615,7 @@ namespace meta_hpp::detail { template < method_pointer_kind Method > method_type_data::method_type_data(type_list) - : type_data_base{type_kind::method_} + : type_data_base{type_kind::method_, shared_type_data_hash{}(this)} , flags{method_traits::make_flags()} , owner_type{resolve_type::class_type>()} , return_type{resolve_type::return_type>()} @@ -7693,7 +8229,7 @@ namespace meta_hpp::detail { template < class_kind Class, typename... Args > constructor_type_data::constructor_type_data(type_list, type_list) - : type_data_base{type_kind::constructor_} + : type_data_base{type_kind::constructor_, shared_type_data_hash{}(this)} , flags{constructor_traits::make_flags()} , owner_type{resolve_type::class_type>()} , argument_types(constructor_type_data_impl::make_argument_types()) {} @@ -8028,7 +8564,7 @@ namespace meta_hpp::detail { template < class_kind Class > destructor_type_data::destructor_type_data(type_list) - : type_data_base{type_kind::destructor_} + : type_data_base{type_kind::destructor_, shared_type_data_hash{}(this)} , flags{destructor_traits::make_flags()} , owner_type{resolve_type::class_type>()} {} } @@ -8197,7 +8733,7 @@ namespace meta_hpp::detail { template < enum_kind Enum > enum_type_data::enum_type_data(type_list) - : type_data_base{type_kind::enum_} + : type_data_base{type_kind::enum_, shared_type_data_hash{}(this)} , flags{enum_traits::make_flags()} , underlying_type{resolve_type::underlying_type>()} {} } @@ -8294,7 +8830,7 @@ namespace meta_hpp::detail { template < pointer_kind Pointer > pointer_type_data::pointer_type_data(type_list) - : type_data_base{type_kind::pointer_} + : type_data_base{type_kind::pointer_, shared_type_data_hash{}(this)} , flags{pointer_traits::make_flags()} , data_type{resolve_type::data_type>()} {} } @@ -8349,7 +8885,7 @@ namespace meta_hpp::detail using pt = pointer_traits; using data_type = typename pt::data_type; - if constexpr ( std::is_const_v ) { + if constexpr ( pt::is_readonly ) { (void)registry; (void)variable_ptr; (void)arg; @@ -8369,7 +8905,7 @@ namespace meta_hpp::detail using pt = pointer_traits; using data_type = typename pt::data_type; - if constexpr ( std::is_const_v ) { + if constexpr ( pt::is_readonly ) { (void)registry; (void)arg; return uerror{error_code::bad_const_access}; @@ -8596,7 +9132,7 @@ namespace meta_hpp::detail { template < class_kind Class > class_type_data::class_type_data(type_list) - : type_data_base{type_kind::class_} + : type_data_base{type_kind::class_, shared_type_data_hash{}(this)} , flags{class_traits::make_flags()} , size{class_traits::size} , align{class_traits::align} @@ -9335,7 +9871,7 @@ namespace meta_hpp::detail { template < array_kind Array > array_type_data::array_type_data(type_list) - : type_data_base{type_kind::array_} + : type_data_base{type_kind::array_, shared_type_data_hash{}(this)} , flags{array_traits::make_flags()} , extent{array_traits::extent} , data_type{resolve_type::data_type>()} {} @@ -9360,14 +9896,14 @@ namespace meta_hpp::detail { template < nullptr_kind Nullptr > nullptr_type_data::nullptr_type_data(type_list) - : type_data_base{type_kind::nullptr_} {} + : type_data_base{type_kind::nullptr_, shared_type_data_hash{}(this)} {} } namespace meta_hpp::detail { template < number_kind Number > number_type_data::number_type_data(type_list) - : type_data_base{type_kind::number_} + : type_data_base{type_kind::number_, shared_type_data_hash{}(this)} , flags{number_traits::make_flags()} , size{number_traits::size} , align{number_traits::align} {} @@ -9392,7 +9928,7 @@ namespace meta_hpp::detail { template < reference_kind Reference > reference_type_data::reference_type_data(type_list) - : type_data_base{type_kind::reference_} + : type_data_base{type_kind::reference_, shared_type_data_hash{}(this)} , flags{reference_traits::make_flags()} , data_type{resolve_type::data_type>()} {} } @@ -9412,7 +9948,7 @@ namespace meta_hpp::detail { template < void_kind Void > void_type_data::void_type_data(type_list) - : type_data_base{type_kind::void_} {} + : type_data_base{type_kind::void_, shared_type_data_hash{}(this)} {} } namespace meta_hpp::detail diff --git a/develop/unshared/meta_shared_exe/meta_shared_tests.cpp b/develop/unshared/meta_shared_exe/meta_shared_tests.cpp new file mode 100644 index 0000000..0ed4009 --- /dev/null +++ b/develop/unshared/meta_shared_exe/meta_shared_tests.cpp @@ -0,0 +1,366 @@ +/******************************************************************************* + * This file is part of the "https://github.com/blackmatov/meta.hpp" + * For conditions of distribution and use, see copyright notice in LICENSE.md + * Copyright (C) 2021-2024, by Matvey Cherevko (blackmatov@gmail.com) + ******************************************************************************/ + +#include + +#include + +namespace +{ + namespace meta = meta_hpp; + namespace shared = meta_shared_lib; + + struct ivec2 { + int x{}, y{}; + + explicit ivec2(int nv) : x{nv}, y{nv} {} + ivec2(int nx, int ny) : x{nx}, y{ny} {} + }; + + struct another_ivec2 { + int x; + int y; + }; + + struct unshared_ivec2 { + int x{}, y{}; + }; + + enum class color {}; + enum class unshared_color {}; +} + +META_HPP_DEFINE_SHARED_TYPE(ivec2, "ivec2") +META_HPP_DEFINE_SHARED_TYPE(another_ivec2, "another_ivec2") +META_HPP_DEFINE_SHARED_TYPE(color, "color") + +TEST_CASE("meta/meta_shared/tests") { + const meta::scope library_scope = shared::get_library_scope(); + REQUIRE(library_scope); + + SUBCASE("0") { + static_assert(meta::detail::shared_type_hash{}()); + static_assert(meta::detail::shared_type_hash{}()); + static_assert(meta::detail::shared_type_hash{}()); + static_assert(meta::detail::shared_type_hash{}()); + static_assert(meta::detail::shared_type_hash{}()); + static_assert(meta::detail::shared_type_hash{}()); + static_assert(meta::detail::shared_type_hash{}()); + static_assert(meta::detail::shared_type_hash{}()); + static_assert(meta::detail::shared_type_hash{}()); + static_assert(meta::detail::shared_type_hash{}()); + static_assert(meta::detail::shared_type_hash{}()); + static_assert(meta::detail::shared_type_hash{}()); + } + + SUBCASE("1") { + const meta::class_type ivec2_type = library_scope.get_typedef("ivec2").as_class(); + const meta::class_type another_ivec2_type = library_scope.get_typedef("another_ivec2").as_class(); + + REQUIRE(ivec2_type); + REQUIRE(another_ivec2_type); + + CHECK(ivec2_type == meta::resolve_type()); + CHECK(another_ivec2_type == meta::resolve_type()); + + const meta::constructor ivec2_ctor0 = ivec2_type.get_constructor_with(); + const meta::constructor ivec2_ctor1 = ivec2_type.get_constructor_with(); + const meta::constructor ivec2_ctor2 = ivec2_type.get_constructor_with(); + const meta::destructor ivec2_dtor = ivec2_type.get_destructor(); + const meta::destructor another_ivec2_dtor = another_ivec2_type.get_destructor(); + + REQUIRE(ivec2_ctor0); + REQUIRE(ivec2_ctor1); + REQUIRE(ivec2_ctor2); + REQUIRE(ivec2_dtor); + REQUIRE(another_ivec2_dtor); + + CHECK(ivec2_ctor0.get_type() == meta::resolve_constructor_type()); + CHECK(ivec2_ctor1.get_type() == meta::resolve_constructor_type()); + CHECK(ivec2_ctor2.get_type() == meta::resolve_constructor_type()); + CHECK(ivec2_dtor.get_type() == meta::resolve_destructor_type()); + CHECK(another_ivec2_dtor.get_type() == meta::resolve_destructor_type()); + + CHECK(ivec2_ctor0 != ivec2_ctor1); + CHECK(ivec2_ctor1 != ivec2_ctor2); + + CHECK(ivec2_dtor.get_type() != another_ivec2_dtor.get_type()); + } + + SUBCASE("2") { + const meta::any_type color_type = library_scope.get_typedef("color"); + const meta::any_type color_const_ptr_type = library_scope.get_typedef("color const*"); + + REQUIRE(color_type); + REQUIRE(color_const_ptr_type); + + CHECK(color_type == meta::resolve_type()); + CHECK(color_const_ptr_type == meta::resolve_type()); + } + + SUBCASE("3") { + const meta::any_type int_ptr_ptr_type = library_scope.get_typedef("int**"); + const meta::any_type int_ptr_const_ptr_type = library_scope.get_typedef("int* const*"); + const meta::any_type int_const_ptr_ptr_type = library_scope.get_typedef("int const**"); + + REQUIRE(int_ptr_ptr_type); + REQUIRE(int_ptr_const_ptr_type); + REQUIRE(int_const_ptr_ptr_type); + + CHECK(int_ptr_ptr_type == meta::resolve_type()); + CHECK(int_ptr_const_ptr_type == meta::resolve_type()); + CHECK(int_const_ptr_ptr_type == meta::resolve_type()); + + CHECK(int_ptr_ptr_type != int_ptr_const_ptr_type); + CHECK(int_ptr_const_ptr_type != int_const_ptr_ptr_type); + } + + SUBCASE("4") { + const meta::any_type void_ptr_ptr_type = library_scope.get_typedef("void**"); + const meta::any_type void_ptr_const_ptr_type = library_scope.get_typedef("void* const*"); + const meta::any_type void_const_ptr_ptr_type = library_scope.get_typedef("void const**"); + + REQUIRE(void_ptr_ptr_type); + REQUIRE(void_ptr_const_ptr_type); + REQUIRE(void_const_ptr_ptr_type); + + CHECK(void_ptr_ptr_type == meta::resolve_type()); + CHECK(void_ptr_const_ptr_type == meta::resolve_type()); + CHECK(void_const_ptr_ptr_type == meta::resolve_type()); + + CHECK(void_ptr_ptr_type != void_ptr_const_ptr_type); + CHECK(void_ptr_const_ptr_type != void_const_ptr_ptr_type); + } + + SUBCASE("5") { + const meta::any_type void_func_type = library_scope.get_typedef("void()"); + const meta::any_type int_ptr_func_type = library_scope.get_typedef("int*()"); + const meta::any_type color_int_ptr_func_type = library_scope.get_typedef("color(int*)"); + const meta::any_type color_float_ptr_func_type = library_scope.get_typedef("color(float*)"); + const meta::any_type color_float_ptr_noexcept_func_type = library_scope.get_typedef("color(float*) noexcept"); + + REQUIRE(void_func_type); + REQUIRE(int_ptr_func_type); + REQUIRE(color_int_ptr_func_type); + REQUIRE(color_float_ptr_func_type); + REQUIRE(color_float_ptr_noexcept_func_type); + + CHECK(void_func_type == meta::resolve_type()); + CHECK(int_ptr_func_type == meta::resolve_type()); + CHECK(color_int_ptr_func_type == meta::resolve_type()); + CHECK(color_float_ptr_func_type == meta::resolve_type()); + CHECK(color_float_ptr_noexcept_func_type == meta::resolve_type()); + + CHECK(void_func_type != int_ptr_func_type); + CHECK(int_ptr_func_type != color_int_ptr_func_type); + CHECK(color_int_ptr_func_type != color_float_ptr_func_type); + CHECK(color_float_ptr_func_type != color_float_ptr_noexcept_func_type); + } + + SUBCASE("6") { + const meta::any_type void_type = library_scope.get_typedef("void"); + const meta::any_type void_ptr_type = library_scope.get_typedef("void*"); + const meta::any_type void_const_ptr_type = library_scope.get_typedef("void const*"); + const meta::any_type nullptr_type = library_scope.get_typedef("nullptr_t"); + const meta::any_type nullptr_ptr_type = library_scope.get_typedef("nullptr_t*"); + const meta::any_type nullptr_const_ptr_type = library_scope.get_typedef("nullptr_t const*"); + + REQUIRE(void_type); + REQUIRE(void_ptr_type); + REQUIRE(void_const_ptr_type); + REQUIRE(nullptr_type); + REQUIRE(nullptr_ptr_type); + REQUIRE(nullptr_const_ptr_type); + + CHECK(void_type == meta::resolve_type()); + CHECK(void_ptr_type == meta::resolve_type()); + CHECK(void_const_ptr_type == meta::resolve_type()); + CHECK(nullptr_type == meta::resolve_type()); + CHECK(nullptr_ptr_type == meta::resolve_type()); + CHECK(nullptr_const_ptr_type == meta::resolve_type()); + + CHECK(void_type != void_ptr_type); + CHECK(void_ptr_type != void_const_ptr_type); + CHECK(void_const_ptr_type != nullptr_type); + CHECK(nullptr_type != nullptr_ptr_type); + CHECK(nullptr_ptr_type != nullptr_const_ptr_type); + } + + SUBCASE("7") { + const meta::any_type int_type = library_scope.get_typedef("int"); + const meta::any_type int_ptr_type = library_scope.get_typedef("int*"); + const meta::any_type int_const_ptr_type = library_scope.get_typedef("int const*"); + const meta::any_type int_volatile_ptr_type = library_scope.get_typedef("int volatile*"); + const meta::any_type int_const_volatile_ptr_type = library_scope.get_typedef("int const volatile*"); + const meta::any_type int_ref_type = library_scope.get_typedef("int&"); + const meta::any_type int_const_ref_type = library_scope.get_typedef("int const&"); + const meta::any_type int_volatile_ref_type = library_scope.get_typedef("int volatile&"); + const meta::any_type int_const_volatile_ref_type = library_scope.get_typedef("int const volatile&"); + + REQUIRE(int_type); + REQUIRE(int_ptr_type); + REQUIRE(int_const_ptr_type); + REQUIRE(int_volatile_ptr_type); + REQUIRE(int_const_volatile_ptr_type); + REQUIRE(int_ref_type); + REQUIRE(int_const_ref_type); + REQUIRE(int_volatile_ref_type); + REQUIRE(int_const_volatile_ref_type); + + CHECK(int_type == meta::resolve_type()); + CHECK(int_ptr_type == meta::resolve_type()); + CHECK(int_const_ptr_type == meta::resolve_type()); + CHECK(int_volatile_ptr_type == meta::resolve_type()); + CHECK(int_const_volatile_ptr_type == meta::resolve_type()); + CHECK(int_ref_type == meta::resolve_type()); + CHECK(int_const_ref_type == meta::resolve_type()); + CHECK(int_volatile_ref_type == meta::resolve_type()); + CHECK(int_const_volatile_ref_type == meta::resolve_type()); + + CHECK(int_type != int_ptr_type); + CHECK(int_type != int_ref_type); + + CHECK(int_ptr_type != int_const_ptr_type); + CHECK(int_ptr_type != int_volatile_ptr_type); + CHECK(int_ptr_type != int_const_volatile_ptr_type); + CHECK(int_ptr_type != int_const_ref_type); + CHECK(int_ptr_type != int_volatile_ref_type); + CHECK(int_ptr_type != int_const_volatile_ref_type); + + CHECK(int_const_ptr_type != int_volatile_ptr_type); + CHECK(int_const_ptr_type != int_const_volatile_ptr_type); + CHECK(int_const_ptr_type != int_volatile_ref_type); + CHECK(int_const_ptr_type != int_const_volatile_ref_type); + + CHECK(int_volatile_ptr_type != int_const_volatile_ptr_type); + CHECK(int_volatile_ptr_type != int_const_volatile_ref_type); + + CHECK(int_ref_type != int_const_ref_type); + CHECK(int_ref_type != int_volatile_ref_type); + CHECK(int_ref_type != int_const_volatile_ref_type); + CHECK(int_const_ref_type != int_volatile_ref_type); + CHECK(int_const_ref_type != int_const_volatile_ref_type); + CHECK(int_volatile_ref_type != int_const_volatile_ref_type); + } + + SUBCASE("8") { + const meta::any_type ivec2_const_lref_type = library_scope.get_typedef("ivec2 const&"); + const meta::any_type ivec2_const_rref_type = library_scope.get_typedef("ivec2 const&&"); + const meta::any_type ivec2_unbounded_array_type = library_scope.get_typedef("ivec2[]"); + const meta::any_type ivec2_unbounded_array_ref_type = library_scope.get_typedef("ivec2(&)[]"); + const meta::any_type ivec2_const_unbounded_array_ref_type = library_scope.get_typedef("ivec2 const(&)[]"); + const meta::any_type ivec2_const_ptr_bounded42_array_type = library_scope.get_typedef("ivec2 const*[42]"); + const meta::any_type ivec2_const_ptr_bounded21_array_type = library_scope.get_typedef("ivec2 const*[21]"); + + REQUIRE(ivec2_const_lref_type); + REQUIRE(ivec2_const_rref_type); + REQUIRE(ivec2_unbounded_array_type); + REQUIRE(ivec2_unbounded_array_ref_type); + REQUIRE(ivec2_const_unbounded_array_ref_type); + REQUIRE(ivec2_const_ptr_bounded42_array_type); + REQUIRE(ivec2_const_ptr_bounded21_array_type); + + CHECK(ivec2_const_lref_type == meta::resolve_type()); + CHECK(ivec2_const_rref_type == meta::resolve_type()); + CHECK(ivec2_unbounded_array_type == meta::resolve_type()); + CHECK(ivec2_unbounded_array_ref_type == meta::resolve_type()); + CHECK(ivec2_const_unbounded_array_ref_type == meta::resolve_type()); + CHECK(ivec2_const_ptr_bounded42_array_type == meta::resolve_type()); + CHECK(ivec2_const_ptr_bounded21_array_type == meta::resolve_type()); + + CHECK(ivec2_const_lref_type != ivec2_const_rref_type); + CHECK(ivec2_const_rref_type != ivec2_unbounded_array_type); + CHECK(ivec2_unbounded_array_type != ivec2_unbounded_array_ref_type); + CHECK(ivec2_unbounded_array_ref_type != ivec2_const_unbounded_array_ref_type); + CHECK(ivec2_const_unbounded_array_ref_type != ivec2_const_ptr_bounded42_array_type); + CHECK(ivec2_const_ptr_bounded42_array_type != ivec2_const_ptr_bounded21_array_type); + } + + SUBCASE("9") { + using meta::detail::type_access; + using meta::detail::hash_combiner; + + CHECK_FALSE(meta::resolve_type().get_id().get_hash() == hash_combiner{}(type_access(meta::resolve_type()))); + CHECK_FALSE(meta::resolve_type().get_id().get_hash() == hash_combiner{}(type_access(meta::resolve_type()))); + CHECK_FALSE(meta::resolve_type().get_id().get_hash() == hash_combiner{}(type_access(meta::resolve_type()))); + CHECK_FALSE(meta::resolve_type().get_id().get_hash() == hash_combiner{}(type_access(meta::resolve_type()))); + CHECK_FALSE(meta::resolve_type().get_id().get_hash() == hash_combiner{}(type_access(meta::resolve_type()))); + CHECK_FALSE(meta::resolve_type().get_id().get_hash() == hash_combiner{}(type_access(meta::resolve_type()))); + CHECK_FALSE(meta::resolve_type().get_id().get_hash() == hash_combiner{}(type_access(meta::resolve_type()))); + CHECK_FALSE(meta::resolve_type().get_id().get_hash() == hash_combiner{}(type_access(meta::resolve_type()))); + CHECK_FALSE(meta::resolve_type().get_id().get_hash() == hash_combiner{}(type_access(meta::resolve_type()))); + CHECK_FALSE(meta::resolve_type().get_id().get_hash() == hash_combiner{}(type_access(meta::resolve_type()))); + CHECK_FALSE(meta::resolve_type().get_id().get_hash() == hash_combiner{}(type_access(meta::resolve_type()))); + + CHECK(meta::resolve_type().get_id().get_hash() == hash_combiner{}(type_access(meta::resolve_type()))); + CHECK(meta::resolve_type().get_id().get_hash() == hash_combiner{}(type_access(meta::resolve_type()))); + CHECK(meta::resolve_type().get_id().get_hash() == hash_combiner{}(type_access(meta::resolve_type()))); + CHECK(meta::resolve_type().get_id().get_hash() == hash_combiner{}(type_access(meta::resolve_type()))); + CHECK(meta::resolve_type().get_id().get_hash() == hash_combiner{}(type_access(meta::resolve_type()))); + CHECK(meta::resolve_type().get_id().get_hash() == hash_combiner{}(type_access(meta::resolve_type()))); + CHECK(meta::resolve_type().get_id().get_hash() == hash_combiner{}(type_access(meta::resolve_type()))); + CHECK(meta::resolve_type().get_id().get_hash() == hash_combiner{}(type_access(meta::resolve_type()))); + CHECK(meta::resolve_type().get_id().get_hash() == hash_combiner{}(type_access(meta::resolve_type()))); + CHECK(meta::resolve_type().get_id().get_hash() == hash_combiner{}(type_access(meta::resolve_type()))); + CHECK(meta::resolve_type().get_id().get_hash() == hash_combiner{}(type_access(meta::resolve_type()))); + CHECK(meta::resolve_type().get_id().get_hash() == hash_combiner{}(type_access(meta::resolve_type()))); + CHECK(meta::resolve_type().get_id().get_hash() == hash_combiner{}(type_access(meta::resolve_type()))); + CHECK(meta::resolve_type().get_id().get_hash() == hash_combiner{}(type_access(meta::resolve_type()))); + } + + SUBCASE("10") { + const meta::any_type int_ivec2_type = library_scope.get_typedef("int ivec2::*"); + const meta::any_type int_const_ivec2_type = library_scope.get_typedef("int const ivec2::*"); + const meta::any_type int_volatile_ivec2_type = library_scope.get_typedef("int volatile ivec2::*"); + const meta::any_type int_const_volatile_ivec2_type = library_scope.get_typedef("int const volatile ivec2::*"); + const meta::any_type int_ivec2_const_ptr = library_scope.get_typedef("int ivec2::*const*"); + + REQUIRE(int_ivec2_type); + REQUIRE(int_const_ivec2_type); + REQUIRE(int_volatile_ivec2_type); + REQUIRE(int_const_volatile_ivec2_type); + REQUIRE(int_ivec2_const_ptr); + + CHECK(int_ivec2_type != int_const_ivec2_type); + CHECK(int_const_ivec2_type != int_volatile_ivec2_type); + CHECK(int_const_ivec2_type != int_const_volatile_ivec2_type); + CHECK(int_volatile_ivec2_type != int_const_volatile_ivec2_type); + } + + SUBCASE("11") { + const meta::any_type int_ivec2_type = library_scope.get_typedef("int (ivec2::*)()"); + const meta::any_type float_ivec2_type = library_scope.get_typedef("float (ivec2::*)()"); + const meta::any_type int_ivec2_float_type = library_scope.get_typedef("int (ivec2::*)(float)"); + const meta::any_type int_ivec2_double_type = library_scope.get_typedef("int (ivec2::*)(double)"); + const meta::any_type int_ivec2_double_noexcept_type = library_scope.get_typedef("int (ivec2::*)(double) noexcept"); + const meta::any_type int_ivec2_const_ptr = library_scope.get_typedef("int (ivec2::*const*)()"); + + REQUIRE(int_ivec2_type); + REQUIRE(float_ivec2_type); + REQUIRE(int_ivec2_float_type); + REQUIRE(int_ivec2_double_type); + REQUIRE(int_ivec2_double_noexcept_type); + REQUIRE(int_ivec2_const_ptr); + + CHECK(int_ivec2_type == meta::resolve_type()); + CHECK(float_ivec2_type == meta::resolve_type()); + CHECK(int_ivec2_float_type == meta::resolve_type()); + CHECK(int_ivec2_double_type == meta::resolve_type()); + CHECK(int_ivec2_double_noexcept_type == meta::resolve_type()); + + CHECK(int_ivec2_type != float_ivec2_type); + CHECK(int_ivec2_type != int_ivec2_float_type); + CHECK(int_ivec2_type != int_ivec2_double_type); + CHECK(int_ivec2_type != int_ivec2_double_noexcept_type); + + CHECK(float_ivec2_type != int_ivec2_float_type); + CHECK(int_ivec2_float_type != int_ivec2_double_type); + CHECK(int_ivec2_double_type != int_ivec2_double_noexcept_type); + + CHECK(int_ivec2_float_type != int_ivec2_double_type); + CHECK(int_ivec2_double_type != int_ivec2_double_noexcept_type); + } +} diff --git a/develop/unshared/meta_shared_exe/meta_shared_exe.cpp b/develop/unshared/meta_shared_exe/meta_shared_usage.cpp similarity index 76% rename from develop/unshared/meta_shared_exe/meta_shared_exe.cpp rename to develop/unshared/meta_shared_exe/meta_shared_usage.cpp index 5d7db62..9dd0702 100644 --- a/develop/unshared/meta_shared_exe/meta_shared_exe.cpp +++ b/develop/unshared/meta_shared_exe/meta_shared_usage.cpp @@ -8,22 +8,22 @@ #include -TEST_CASE("meta/meta_shared/exe") { +namespace +{ namespace meta = meta_hpp; namespace shared = meta_shared_lib; +} +TEST_CASE("meta/meta_shared/usage") { const meta::scope library_scope = shared::get_library_scope(); REQUIRE(library_scope); // - const meta::number_type int_type = library_scope.get_typedef("int").as_number(); - REQUIRE(int_type); - const meta::class_type ivec2_type = library_scope.get_typedef("ivec2").as_class(); REQUIRE(ivec2_type); - const meta::constructor ivec2_ctor2 = ivec2_type.get_constructor_with({int_type, int_type}); + const meta::constructor ivec2_ctor2 = ivec2_type.get_constructor_with(); REQUIRE(ivec2_ctor2); const meta::method ivec2_length2 = ivec2_type.get_method("length2"); @@ -31,11 +31,11 @@ TEST_CASE("meta/meta_shared/exe") { // - const meta::uvalue ivec2_inst = ivec2_ctor2.create(shared::wrap_int(3), shared::wrap_int(4)); + const meta::uvalue ivec2_inst = ivec2_ctor2.create(3, 4); REQUIRE(ivec2_inst); const meta::uvalue ivec2_inst_length2 = ivec2_length2.invoke(ivec2_inst); REQUIRE(ivec2_inst_length2); - CHECK(shared::unwrap_int(ivec2_inst_length2) == 25); + CHECK(ivec2_inst_length2.as() == 25); } diff --git a/develop/unshared/meta_shared_lib/meta_shared_lib.cpp b/develop/unshared/meta_shared_lib/meta_shared_lib.cpp index b7bb2c7..7a34f94 100644 --- a/develop/unshared/meta_shared_lib/meta_shared_lib.cpp +++ b/develop/unshared/meta_shared_lib/meta_shared_lib.cpp @@ -14,6 +14,7 @@ namespace int x; int y; + ivec2() = default; explicit ivec2(int nv) : x{nv}, y{nv} {} ivec2(int nx, int ny) : x{nx}, y{ny} {} @@ -22,35 +23,110 @@ namespace } }; + struct another_ivec2 { + int x; + int y; + }; + + enum class color { + red, green, blue, + }; + void bind_ivec2() { meta::class_() + .constructor_<>() .constructor_() .constructor_() + .constructor_() .member_("x", &ivec2::x) .member_("y", &ivec2::y) .method_("length2", &ivec2::length2); + + meta::class_(); + } + + void bind_color() { + meta::enum_() + .evalue_("red", color::red) + .evalue_("green", color::green) + .evalue_("blue", color::blue); } const auto library_scope = []() -> meta::scope { bind_ivec2(); + bind_color(); return meta::local_scope_("library_scope") .typedef_("int") - .typedef_("ivec2"); + + .typedef_("int*") + .typedef_("int const*") + .typedef_("int volatile*") + .typedef_("int const volatile*") + + .typedef_("int&") + .typedef_("int const&") + .typedef_("int volatile&") + .typedef_("int const volatile&") + + .typedef_("int**") + .typedef_("int* const*") + .typedef_("int const**") + + .typedef_("void**") + .typedef_("void* const*") + .typedef_("void const**") + + .typedef_("void()") + .typedef_("int*()") + .typedef_("color(int*)") + .typedef_("color(float*)") + .typedef_("color(float*) noexcept") + + .typedef_("void") + .typedef_("void*") + .typedef_("void const*") + .typedef_("nullptr_t") + .typedef_("nullptr_t*") + .typedef_("nullptr_t const*") + + .typedef_("ivec2") + .typedef_("another_ivec2") + + .typedef_("ivec2 const&") + .typedef_("ivec2 const&&") + .typedef_("ivec2[]") + .typedef_("ivec2(&)[]") + .typedef_("ivec2 const(&)[]") + .typedef_("ivec2 const*[42]") + .typedef_("ivec2 const*[21]") + + .typedef_("color") + .typedef_("color const*") + + .typedef_("int ivec2::*") + .typedef_("int const ivec2::*") + .typedef_("int volatile ivec2::*") + .typedef_("int const volatile ivec2::*") + .typedef_("int ivec2::*const*") + + .typedef_("int (ivec2::*)()") + .typedef_("float (ivec2::*)()") + .typedef_("int (ivec2::*)(float)") + .typedef_("int (ivec2::*)(double)") + .typedef_("int (ivec2::*)(double) noexcept") + .typedef_("int (ivec2::*const*)()") + ; }(); } +META_HPP_DEFINE_SHARED_TYPE(ivec2, "ivec2") +META_HPP_DEFINE_SHARED_TYPE(another_ivec2, "another_ivec2") +META_HPP_DEFINE_SHARED_TYPE(color, "color") + namespace meta_shared_lib { meta::scope get_library_scope() { return library_scope; } - - meta::uvalue wrap_int(int value) { - return value; - } - - int unwrap_int(const meta::uvalue& value) { - return value.as(); - } } diff --git a/develop/unshared/meta_shared_lib/meta_shared_lib.hpp b/develop/unshared/meta_shared_lib/meta_shared_lib.hpp index b0c0db1..7a0f958 100644 --- a/develop/unshared/meta_shared_lib/meta_shared_lib.hpp +++ b/develop/unshared/meta_shared_lib/meta_shared_lib.hpp @@ -15,7 +15,4 @@ namespace meta_shared_lib namespace meta = meta_hpp; META_HPP_SHARED_LIB_EXPORT meta::scope get_library_scope(); - - META_HPP_SHARED_LIB_EXPORT meta::uvalue wrap_int(int value); - META_HPP_SHARED_LIB_EXPORT int unwrap_int(const meta::uvalue& value); } diff --git a/headers/meta.hpp/meta_detail/type_sharing.hpp b/headers/meta.hpp/meta_detail/type_sharing.hpp new file mode 100644 index 0000000..b5f1630 --- /dev/null +++ b/headers/meta.hpp/meta_detail/type_sharing.hpp @@ -0,0 +1,375 @@ +/******************************************************************************* + * This file is part of the "https://github.com/blackmatov/meta.hpp" + * For conditions of distribution and use, see copyright notice in LICENSE.md + * Copyright (C) 2021-2024, by Matvey Cherevko (blackmatov@gmail.com) + ******************************************************************************/ + +#pragma once + +#include "../meta_base.hpp" + +#include "type_traits/array_traits.hpp" +#include "type_traits/class_traits.hpp" +#include "type_traits/constructor_traits.hpp" +#include "type_traits/destructor_traits.hpp" +#include "type_traits/enum_traits.hpp" +#include "type_traits/function_traits.hpp" +#include "type_traits/member_traits.hpp" +#include "type_traits/method_traits.hpp" +#include "type_traits/number_traits.hpp" +#include "type_traits/pointer_traits.hpp" +#include "type_traits/reference_traits.hpp" + +namespace meta_hpp::detail +{ + template < typename T > + struct shared_type_name; + + template < type_kind, typename... > + struct shared_type_hash; +} + +namespace meta_hpp::detail +{ + template < typename Type > + [[nodiscard]] constexpr std::size_t shared_hash() noexcept { + return shared_type_hash, Type>{}(); + } + + template < enum_kind Enum > + [[nodiscard]] constexpr std::size_t shared_hash(Enum value) noexcept { + return static_cast(value); + } + + template < enum_kind Enum > + [[nodiscard]] constexpr std::size_t shared_hash(bitflags value) noexcept { + return static_cast(value.as_raw()); + } + + template < typename Integral > + requires(std::is_integral_v && sizeof(Integral) <= sizeof(std::size_t)) + [[nodiscard]] constexpr std::size_t shared_hash(Integral value) noexcept { + return static_cast(value); + } + + template < typename Value > + requires(sizeof(std::size_t) == sizeof(std::uint32_t)) + [[nodiscard]] constexpr std::size_t shared_hash_append(std::size_t seed, Value value) noexcept { + // NOLINTNEXTLINE(*-magic-numbers) + return (seed ^= shared_hash(value) + 0x9e3779b9U + (seed << 6) + (seed >> 2)); + } + + template < typename Value > + requires(sizeof(std::size_t) == sizeof(std::uint64_t)) + [[nodiscard]] constexpr std::size_t shared_hash_append(std::size_t seed, Value value) noexcept { + // NOLINTNEXTLINE(*-magic-numbers) + return (seed ^= shared_hash(value) + 0x9e3779b97f4a7c15LLU + (seed << 12) + (seed >> 4)); + } +} + +namespace meta_hpp::detail +{ + template < typename T > + struct is_shared_type : std::false_type {}; + + template < typename T > + concept shared_type_kind = is_shared_type>::value; +} + +namespace meta_hpp::detail +{ + template < type_kind, typename... > + struct shared_type_data_hash { + [[nodiscard]] std::size_t operator()(const void* type_data) const noexcept { + return hash_combiner{}(type_data); + } + }; + + template < type_kind Kind, shared_type_kind Type > + struct shared_type_data_hash { + [[nodiscard]] std::size_t operator()(const void*) const noexcept { + return shared_type_hash{}(); + } + }; + + template < shared_type_kind Class, shared_type_kind... Args > + struct shared_type_data_hash { + [[nodiscard]] std::size_t operator()(const void*) const noexcept { + return shared_type_hash{}(); + } + }; + + template < shared_type_kind Class > + struct shared_type_data_hash { + [[nodiscard]] std::size_t operator()(const void*) const noexcept { + return shared_type_hash{}(); + } + }; +} + +namespace meta_hpp::detail +{ + template < typename T > + requires requires { + { shared_type_name{}() }; + } + struct is_shared_type : std::true_type {}; + + template < array_kind Array > + requires shared_type_kind::data_type> + struct is_shared_type : std::true_type {}; + + template < function_kind Function > + requires shared_type_kind::return_type> + && type_list_and_v::argument_types> + struct is_shared_type : std::true_type {}; + + template < member_pointer_kind Member > + requires shared_type_kind::class_type> + && shared_type_kind::value_type> + struct is_shared_type : std::true_type {}; + + template < method_pointer_kind Method > + requires shared_type_kind::class_type> + && shared_type_kind::return_type> + && type_list_and_v::argument_types> + struct is_shared_type : std::true_type {}; + + template < pointer_kind Pointer > + requires shared_type_kind::data_type> + struct is_shared_type : std::true_type {}; + + template < reference_kind Reference > + requires shared_type_kind::data_type> + struct is_shared_type : std::true_type {}; +} + +namespace meta_hpp::detail +{ + template < shared_type_kind Array > + struct shared_type_hash { + [[nodiscard]] constexpr std::size_t operator()() const noexcept { + std::size_t hash = shared_hash(type_kind::array_); + + using traits = array_traits; + hash = shared_hash_append(hash, traits::make_flags()); + + hash = shared_hash_append(hash, shared_hash()); + + hash = shared_hash_append(hash, traits::extent); + + return hash; + } + }; + + template < shared_type_kind Class > + struct shared_type_hash { + [[nodiscard]] constexpr std::size_t operator()() const noexcept { + std::size_t hash = shared_hash(type_kind::class_); + + using traits = class_traits; + hash = shared_hash_append(hash, traits::make_flags()); + + hash = shared_hash_append(hash, shared_type_name{}()); + + return hash; + } + }; + + template < shared_type_kind Class, shared_type_kind... Args > + struct shared_type_hash { + [[nodiscard]] constexpr std::size_t operator()() const noexcept { + std::size_t hash = shared_hash(type_kind::constructor_); + + using traits = constructor_traits; + hash = shared_hash_append(hash, traits::make_flags()); + + hash = shared_hash_append(hash, shared_hash()); + + traits::argument_types::for_each([&hash]() { // + hash = shared_hash_append(hash, shared_hash()); + }); + + return hash; + } + }; + + template < shared_type_kind Class > + struct shared_type_hash { + [[nodiscard]] constexpr std::size_t operator()() const noexcept { + std::size_t hash = shared_hash(type_kind::destructor_); + + using traits = destructor_traits; + hash = shared_hash_append(hash, traits::make_flags()); + + hash = shared_hash_append(hash, shared_hash()); + + return hash; + } + }; + + template < shared_type_kind Enum > + struct shared_type_hash { + [[nodiscard]] constexpr std::size_t operator()() const noexcept { + std::size_t hash = shared_hash(type_kind::enum_); + + using traits = enum_traits; + hash = shared_hash_append(hash, traits::make_flags()); + + hash = shared_hash_append(hash, shared_type_name{}()); + + return hash; + } + }; + + template < shared_type_kind Function > + struct shared_type_hash { + [[nodiscard]] constexpr std::size_t operator()() const noexcept { + std::size_t hash = shared_hash(type_kind::function_); + + using traits = function_traits; + hash = shared_hash_append(hash, traits::make_flags()); + + hash = shared_hash_append(hash, shared_hash()); + + traits::argument_types::for_each([&hash]() { // + hash = shared_hash_append(hash, shared_hash()); + }); + + return hash; + } + }; + + template < shared_type_kind Member > + struct shared_type_hash { + [[nodiscard]] constexpr std::size_t operator()() const noexcept { + std::size_t hash = shared_hash(type_kind::member_); + + using traits = member_traits; + hash = shared_hash_append(hash, traits::make_flags()); + + hash = shared_hash_append(hash, shared_hash()); + hash = shared_hash_append(hash, shared_hash()); + + return hash; + } + }; + + template < shared_type_kind Method > + struct shared_type_hash { + [[nodiscard]] constexpr std::size_t operator()() const noexcept { + std::size_t hash = shared_hash(type_kind::method_); + + using traits = method_traits; + hash = shared_hash_append(hash, traits::make_flags()); + + hash = shared_hash_append(hash, shared_hash()); + hash = shared_hash_append(hash, shared_hash()); + + traits::argument_types::for_each([&hash]() { // + hash = shared_hash_append(hash, shared_hash()); + }); + + return hash; + } + }; + + template < shared_type_kind Nullptr > + struct shared_type_hash { + [[nodiscard]] constexpr std::size_t operator()() const noexcept { + std::size_t hash = shared_hash(type_kind::nullptr_); + + hash = shared_hash_append(hash, shared_type_name{}()); + + return hash; + } + }; + + template < shared_type_kind Number > + struct shared_type_hash { + [[nodiscard]] constexpr std::size_t operator()() const noexcept { + std::size_t hash = shared_hash(type_kind::number_); + + using traits = number_traits; + hash = shared_hash_append(hash, traits::make_flags()); + + hash = shared_hash_append(hash, shared_type_name{}()); + + return hash; + } + }; + + template < shared_type_kind Pointer > + struct shared_type_hash { + [[nodiscard]] constexpr std::size_t operator()() const noexcept { + std::size_t hash = shared_hash(type_kind::pointer_); + + using traits = pointer_traits; + hash = shared_hash_append(hash, traits::make_flags()); + + hash = shared_hash_append(hash, shared_hash()); + + return hash; + } + }; + + template < shared_type_kind Reference > + struct shared_type_hash { + [[nodiscard]] constexpr std::size_t operator()() const noexcept { + std::size_t hash = shared_hash(type_kind::reference_); + + using traits = reference_traits; + hash = shared_hash_append(hash, traits::make_flags()); + + hash = shared_hash_append(hash, shared_hash()); + + return hash; + } + }; + + template < shared_type_kind Void > + struct shared_type_hash { + [[nodiscard]] constexpr std::size_t operator()() const noexcept { + std::size_t hash = shared_hash(type_kind::void_); + + hash = shared_hash_append(hash, shared_type_name{}()); + + return hash; + } + }; +} + +#define META_HPP_DEFINE_SHARED_TYPE(Type, Name) \ + namespace meta_hpp::detail \ + { \ + template <> \ + struct shared_type_name { \ + [[nodiscard]] constexpr std::size_t operator()() const noexcept { \ + return hashed_string{Name}.get_hash(); \ + } \ + }; \ + } + +META_HPP_DEFINE_SHARED_TYPE(void, "void") +META_HPP_DEFINE_SHARED_TYPE(bool, "bool") +META_HPP_DEFINE_SHARED_TYPE(wchar_t, "wchar_t") +META_HPP_DEFINE_SHARED_TYPE(decltype(nullptr), "nullptr_t") + +META_HPP_DEFINE_SHARED_TYPE(char8_t, "char8_t") +META_HPP_DEFINE_SHARED_TYPE(char16_t, "char16_t") +META_HPP_DEFINE_SHARED_TYPE(char32_t, "char32_t") + +META_HPP_DEFINE_SHARED_TYPE(float, "float") +META_HPP_DEFINE_SHARED_TYPE(double, "double") +META_HPP_DEFINE_SHARED_TYPE(long double, "long double") + +META_HPP_DEFINE_SHARED_TYPE(signed char, "schar") +META_HPP_DEFINE_SHARED_TYPE(unsigned char, "uchar") +META_HPP_DEFINE_SHARED_TYPE(signed short, "sshort") +META_HPP_DEFINE_SHARED_TYPE(unsigned short, "ushort") +META_HPP_DEFINE_SHARED_TYPE(signed int, "sint") +META_HPP_DEFINE_SHARED_TYPE(unsigned int, "uint") +META_HPP_DEFINE_SHARED_TYPE(signed long, "slong") +META_HPP_DEFINE_SHARED_TYPE(unsigned long, "ulong") +META_HPP_DEFINE_SHARED_TYPE(signed long long, "sllong") +META_HPP_DEFINE_SHARED_TYPE(unsigned long long, "ullong") diff --git a/headers/meta.hpp/meta_types.hpp b/headers/meta.hpp/meta_types.hpp index 9e4d1a5..0df00b1 100644 --- a/headers/meta.hpp/meta_types.hpp +++ b/headers/meta.hpp/meta_types.hpp @@ -52,31 +52,28 @@ namespace meta_hpp class type_id final { public: type_id() = default; + ~type_id() = default; - [[nodiscard]] bool is_valid() const noexcept { - return data_ != nullptr; - } + type_id(type_id&&) = default; + type_id(const type_id&) = default; - [[nodiscard]] explicit operator bool() const noexcept { - return is_valid(); - } + type_id& operator=(type_id&&) = default; + type_id& operator=(const type_id&) = default; - void swap(type_id& other) noexcept { - std::swap(data_, other.data_); - } + [[nodiscard]] bool is_valid() const noexcept; + [[nodiscard]] explicit operator bool() const noexcept; - [[nodiscard]] std::size_t get_hash() const noexcept { - return data_ != nullptr ? detail::hash_combiner{}(data_) : 0; - } + void swap(type_id& other) noexcept; + [[nodiscard]] std::size_t get_hash() const noexcept; - [[nodiscard]] std::strong_ordering operator<=>(const type_id& other) const = default; + [[nodiscard]] bool operator==(const type_id& other) const noexcept; + [[nodiscard]] std::strong_ordering operator<=>(const type_id& other) const noexcept; private: template < type_family T > friend class type_base; - explicit type_id(const detail::type_data_base* data) - : data_{data} {} + explicit type_id(const detail::type_data_base* data); private: const detail::type_data_base* data_{}; @@ -105,34 +102,20 @@ namespace meta_hpp type_base() = default; - explicit type_base(data_ptr data) - : data_{data} {} + explicit type_base(data_ptr data); - type_base(type_base&&) noexcept = default; + type_base(type_base&&) = default; type_base(const type_base&) = default; - type_base& operator=(type_base&&) noexcept = default; + type_base& operator=(type_base&&) = default; type_base& operator=(const type_base&) = default; - [[nodiscard]] bool is_valid() const noexcept { - return data_ != nullptr; - } + [[nodiscard]] bool is_valid() const noexcept; + [[nodiscard]] explicit operator bool() const noexcept; - [[nodiscard]] explicit operator bool() const noexcept { - return is_valid(); - } - - [[nodiscard]] id_type get_id() const noexcept { - return id_type{data_}; - } - - [[nodiscard]] type_kind get_kind() const noexcept { - return data_->kind; - } - - [[nodiscard]] const metadata_map& get_metadata() const noexcept { - return data_->metadata; - } + [[nodiscard]] id_type get_id() const noexcept; + [[nodiscard]] type_kind get_kind() const noexcept; + [[nodiscard]] const metadata_map& get_metadata() const noexcept; protected: ~type_base() = default; @@ -461,12 +444,14 @@ namespace meta_hpp::detail struct type_data_base { // NOLINTBEGIN(*-avoid-const-or-ref-data-members) const type_kind kind; + const std::size_t shared; // NOLINTEND(*-avoid-const-or-ref-data-members) metadata_map metadata; - explicit type_data_base(type_kind nkind) - : kind{nkind} {} + explicit type_data_base(type_kind nkind, std::size_t nshared) + : kind{nkind} + , shared{nshared} {} type_data_base(type_data_base&&) = delete; type_data_base(const type_data_base&) = delete; @@ -631,3 +616,82 @@ namespace meta_hpp::detail explicit void_type_data(type_list); }; } + +namespace meta_hpp +{ + inline type_id::type_id(const detail::type_data_base* data) + : data_{data} {} + + inline bool type_id::is_valid() const noexcept { + return data_ != nullptr; + } + + inline type_id::operator bool() const noexcept { + return is_valid(); + } + + inline void type_id::swap(type_id& other) noexcept { + std::swap(data_, other.data_); + } + + inline std::size_t type_id::get_hash() const noexcept { + return data_ != nullptr ? data_->shared : 0; + } + + inline bool type_id::operator==(const type_id& other) const noexcept { + if ( data_ == other.data_ ) { + return true; + } + + if ( is_valid() != other.is_valid() ) { + return false; + } + + return data_->shared == other.data_->shared; + } + + inline std::strong_ordering type_id::operator<=>(const type_id& other) const noexcept { + if ( data_ == other.data_ ) { + return std::strong_ordering::equal; + } + + // NOLINTNEXTLINE(*-bool-conversion) + if ( const std::strong_ordering cmp{is_valid() <=> other.is_valid()}; cmp != std::strong_ordering::equal ) { + return cmp; + } + + return data_->shared <=> other.data_->shared; + } +} + +namespace meta_hpp +{ + template < type_family Type > + type_base::type_base(data_ptr data) + : data_{data} {} + + template < type_family Type > + bool type_base::is_valid() const noexcept { + return data_ != nullptr; + } + + template < type_family Type > + type_base::operator bool() const noexcept { + return is_valid(); + } + + template < type_family Type > + type_base::id_type type_base::get_id() const noexcept { + return id_type{data_}; + } + + template < type_family Type > + type_kind type_base::get_kind() const noexcept { + return data_->kind; + } + + template < type_family Type > + const metadata_map& type_base::get_metadata() const noexcept { + return data_->metadata; + } +} diff --git a/headers/meta.hpp/meta_types/array_type.hpp b/headers/meta.hpp/meta_types/array_type.hpp index 782c6d5..4ae873a 100644 --- a/headers/meta.hpp/meta_types/array_type.hpp +++ b/headers/meta.hpp/meta_types/array_type.hpp @@ -10,13 +10,14 @@ #include "../meta_registry.hpp" #include "../meta_types.hpp" +#include "../meta_detail/type_sharing.hpp" #include "../meta_detail/type_traits/array_traits.hpp" namespace meta_hpp::detail { template < array_kind Array > array_type_data::array_type_data(type_list) - : type_data_base{type_kind::array_} + : type_data_base{type_kind::array_, shared_type_data_hash{}(this)} , flags{array_traits::make_flags()} , extent{array_traits::extent} , data_type{resolve_type::data_type>()} {} diff --git a/headers/meta.hpp/meta_types/class_type.hpp b/headers/meta.hpp/meta_types/class_type.hpp index 5b69ddb..8189354 100644 --- a/headers/meta.hpp/meta_types/class_type.hpp +++ b/headers/meta.hpp/meta_types/class_type.hpp @@ -16,6 +16,7 @@ #include "../meta_states/method.hpp" #include "../meta_states/variable.hpp" +#include "../meta_detail/type_sharing.hpp" #include "../meta_detail/type_traits/class_traits.hpp" namespace meta_hpp::detail::class_type_data_impl @@ -105,7 +106,7 @@ namespace meta_hpp::detail { template < class_kind Class > class_type_data::class_type_data(type_list) - : type_data_base{type_kind::class_} + : type_data_base{type_kind::class_, shared_type_data_hash{}(this)} , flags{class_traits::make_flags()} , size{class_traits::size} , align{class_traits::align} diff --git a/headers/meta.hpp/meta_types/constructor_type.hpp b/headers/meta.hpp/meta_types/constructor_type.hpp index c7a3244..bb66442 100644 --- a/headers/meta.hpp/meta_types/constructor_type.hpp +++ b/headers/meta.hpp/meta_types/constructor_type.hpp @@ -10,6 +10,7 @@ #include "../meta_registry.hpp" #include "../meta_types.hpp" +#include "../meta_detail/type_sharing.hpp" #include "../meta_detail/type_traits/constructor_traits.hpp" namespace meta_hpp::detail::constructor_type_data_impl @@ -37,7 +38,7 @@ namespace meta_hpp::detail { template < class_kind Class, typename... Args > constructor_type_data::constructor_type_data(type_list, type_list) - : type_data_base{type_kind::constructor_} + : type_data_base{type_kind::constructor_, shared_type_data_hash{}(this)} , flags{constructor_traits::make_flags()} , owner_type{resolve_type::class_type>()} , argument_types(constructor_type_data_impl::make_argument_types()) {} diff --git a/headers/meta.hpp/meta_types/destructor_type.hpp b/headers/meta.hpp/meta_types/destructor_type.hpp index b534495..3212c91 100644 --- a/headers/meta.hpp/meta_types/destructor_type.hpp +++ b/headers/meta.hpp/meta_types/destructor_type.hpp @@ -10,13 +10,14 @@ #include "../meta_registry.hpp" #include "../meta_types.hpp" +#include "../meta_detail/type_sharing.hpp" #include "../meta_detail/type_traits/destructor_traits.hpp" namespace meta_hpp::detail { template < class_kind Class > destructor_type_data::destructor_type_data(type_list) - : type_data_base{type_kind::destructor_} + : type_data_base{type_kind::destructor_, shared_type_data_hash{}(this)} , flags{destructor_traits::make_flags()} , owner_type{resolve_type::class_type>()} {} } diff --git a/headers/meta.hpp/meta_types/enum_type.hpp b/headers/meta.hpp/meta_types/enum_type.hpp index 36bd36b..cc0e198 100644 --- a/headers/meta.hpp/meta_types/enum_type.hpp +++ b/headers/meta.hpp/meta_types/enum_type.hpp @@ -12,6 +12,7 @@ #include "../meta_states/evalue.hpp" +#include "../meta_detail/type_sharing.hpp" #include "../meta_detail/type_traits/enum_traits.hpp" #include "../meta_detail/value_utilities/uarg.hpp" @@ -19,7 +20,7 @@ namespace meta_hpp::detail { template < enum_kind Enum > enum_type_data::enum_type_data(type_list) - : type_data_base{type_kind::enum_} + : type_data_base{type_kind::enum_, shared_type_data_hash{}(this)} , flags{enum_traits::make_flags()} , underlying_type{resolve_type::underlying_type>()} {} } diff --git a/headers/meta.hpp/meta_types/function_type.hpp b/headers/meta.hpp/meta_types/function_type.hpp index bb3ca93..ba3032c 100644 --- a/headers/meta.hpp/meta_types/function_type.hpp +++ b/headers/meta.hpp/meta_types/function_type.hpp @@ -10,6 +10,7 @@ #include "../meta_registry.hpp" #include "../meta_types.hpp" +#include "../meta_detail/type_sharing.hpp" #include "../meta_detail/type_traits/function_traits.hpp" namespace meta_hpp::detail::function_type_data_impl @@ -37,7 +38,7 @@ namespace meta_hpp::detail { template < function_kind Function > function_type_data::function_type_data(type_list) - : type_data_base{type_kind::function_} + : type_data_base{type_kind::function_, shared_type_data_hash{}(this)} , flags{function_traits::make_flags()} , return_type{resolve_type::return_type>()} , argument_types(function_type_data_impl::make_argument_types()) {} diff --git a/headers/meta.hpp/meta_types/member_type.hpp b/headers/meta.hpp/meta_types/member_type.hpp index 5558494..c133aa1 100644 --- a/headers/meta.hpp/meta_types/member_type.hpp +++ b/headers/meta.hpp/meta_types/member_type.hpp @@ -10,13 +10,14 @@ #include "../meta_registry.hpp" #include "../meta_types.hpp" +#include "../meta_detail/type_sharing.hpp" #include "../meta_detail/type_traits/member_traits.hpp" namespace meta_hpp::detail { template < member_pointer_kind Member > member_type_data::member_type_data(type_list) - : type_data_base{type_kind::member_} + : type_data_base{type_kind::member_, shared_type_data_hash{}(this)} , flags{member_traits::make_flags()} , owner_type{resolve_type::class_type>()} , value_type{resolve_type::value_type>()} {} diff --git a/headers/meta.hpp/meta_types/method_type.hpp b/headers/meta.hpp/meta_types/method_type.hpp index 4face78..5a8d2aa 100644 --- a/headers/meta.hpp/meta_types/method_type.hpp +++ b/headers/meta.hpp/meta_types/method_type.hpp @@ -10,6 +10,7 @@ #include "../meta_registry.hpp" #include "../meta_types.hpp" +#include "../meta_detail/type_sharing.hpp" #include "../meta_detail/type_traits/method_traits.hpp" namespace meta_hpp::detail::method_type_data_impl @@ -37,7 +38,7 @@ namespace meta_hpp::detail { template < method_pointer_kind Method > method_type_data::method_type_data(type_list) - : type_data_base{type_kind::method_} + : type_data_base{type_kind::method_, shared_type_data_hash{}(this)} , flags{method_traits::make_flags()} , owner_type{resolve_type::class_type>()} , return_type{resolve_type::return_type>()} diff --git a/headers/meta.hpp/meta_types/nullptr_type.hpp b/headers/meta.hpp/meta_types/nullptr_type.hpp index ec2cccc..74c7164 100644 --- a/headers/meta.hpp/meta_types/nullptr_type.hpp +++ b/headers/meta.hpp/meta_types/nullptr_type.hpp @@ -10,9 +10,11 @@ #include "../meta_registry.hpp" #include "../meta_types.hpp" +#include "../meta_detail/type_sharing.hpp" + namespace meta_hpp::detail { template < nullptr_kind Nullptr > nullptr_type_data::nullptr_type_data(type_list) - : type_data_base{type_kind::nullptr_} {} + : type_data_base{type_kind::nullptr_, shared_type_data_hash{}(this)} {} } diff --git a/headers/meta.hpp/meta_types/number_type.hpp b/headers/meta.hpp/meta_types/number_type.hpp index 5db2279..5eb58b3 100644 --- a/headers/meta.hpp/meta_types/number_type.hpp +++ b/headers/meta.hpp/meta_types/number_type.hpp @@ -10,13 +10,14 @@ #include "../meta_registry.hpp" #include "../meta_types.hpp" +#include "../meta_detail/type_sharing.hpp" #include "../meta_detail/type_traits/number_traits.hpp" namespace meta_hpp::detail { template < number_kind Number > number_type_data::number_type_data(type_list) - : type_data_base{type_kind::number_} + : type_data_base{type_kind::number_, shared_type_data_hash{}(this)} , flags{number_traits::make_flags()} , size{number_traits::size} , align{number_traits::align} {} diff --git a/headers/meta.hpp/meta_types/pointer_type.hpp b/headers/meta.hpp/meta_types/pointer_type.hpp index f9dfbfd..30a5b78 100644 --- a/headers/meta.hpp/meta_types/pointer_type.hpp +++ b/headers/meta.hpp/meta_types/pointer_type.hpp @@ -10,13 +10,14 @@ #include "../meta_registry.hpp" #include "../meta_types.hpp" +#include "../meta_detail/type_sharing.hpp" #include "../meta_detail/type_traits/pointer_traits.hpp" namespace meta_hpp::detail { template < pointer_kind Pointer > pointer_type_data::pointer_type_data(type_list) - : type_data_base{type_kind::pointer_} + : type_data_base{type_kind::pointer_, shared_type_data_hash{}(this)} , flags{pointer_traits::make_flags()} , data_type{resolve_type::data_type>()} {} } diff --git a/headers/meta.hpp/meta_types/reference_type.hpp b/headers/meta.hpp/meta_types/reference_type.hpp index 0b07e6e..49ea01b 100644 --- a/headers/meta.hpp/meta_types/reference_type.hpp +++ b/headers/meta.hpp/meta_types/reference_type.hpp @@ -10,13 +10,14 @@ #include "../meta_registry.hpp" #include "../meta_types.hpp" +#include "../meta_detail/type_sharing.hpp" #include "../meta_detail/type_traits/reference_traits.hpp" namespace meta_hpp::detail { template < reference_kind Reference > reference_type_data::reference_type_data(type_list) - : type_data_base{type_kind::reference_} + : type_data_base{type_kind::reference_, shared_type_data_hash{}(this)} , flags{reference_traits::make_flags()} , data_type{resolve_type::data_type>()} {} } diff --git a/headers/meta.hpp/meta_types/void_type.hpp b/headers/meta.hpp/meta_types/void_type.hpp index e325449..cb53989 100644 --- a/headers/meta.hpp/meta_types/void_type.hpp +++ b/headers/meta.hpp/meta_types/void_type.hpp @@ -10,9 +10,11 @@ #include "../meta_registry.hpp" #include "../meta_types.hpp" +#include "../meta_detail/type_sharing.hpp" + namespace meta_hpp::detail { template < void_kind Void > void_type_data::void_type_data(type_list) - : type_data_base{type_kind::void_} {} + : type_data_base{type_kind::void_, shared_type_data_hash{}(this)} {} }