mirror of
https://github.com/BlackMATov/meta.hpp.git
synced 2025-12-14 11:40:35 +07:00
huge structure refactoring
This commit is contained in:
@@ -9,10 +9,7 @@ endif()
|
||||
|
||||
project(meta.hpp)
|
||||
|
||||
add_subdirectory(vendors/enum.hpp)
|
||||
|
||||
add_library(${PROJECT_NAME} INTERFACE)
|
||||
target_link_libraries(${PROJECT_NAME} INTERFACE enum.hpp)
|
||||
target_compile_features(${PROJECT_NAME} INTERFACE cxx_std_20)
|
||||
target_include_directories(${PROJECT_NAME} INTERFACE headers)
|
||||
|
||||
|
||||
@@ -13,7 +13,15 @@
|
||||
#include "meta_binds/enum_bind.hpp"
|
||||
#include "meta_binds/scope_bind.hpp"
|
||||
|
||||
#include "meta_kinds.hpp"
|
||||
#include "meta_indices.hpp"
|
||||
#include "meta_indices/ctor_index.hpp"
|
||||
#include "meta_indices/dtor_index.hpp"
|
||||
#include "meta_indices/evalue_index.hpp"
|
||||
#include "meta_indices/function_index.hpp"
|
||||
#include "meta_indices/member_index.hpp"
|
||||
#include "meta_indices/method_index.hpp"
|
||||
#include "meta_indices/scope_index.hpp"
|
||||
#include "meta_indices/variable_index.hpp"
|
||||
|
||||
#include "meta_states.hpp"
|
||||
#include "meta_states/ctor.hpp"
|
||||
@@ -25,19 +33,6 @@
|
||||
#include "meta_states/scope.hpp"
|
||||
#include "meta_states/variable.hpp"
|
||||
|
||||
#include "meta_traits.hpp"
|
||||
#include "meta_traits/array_traits.hpp"
|
||||
#include "meta_traits/class_traits.hpp"
|
||||
#include "meta_traits/ctor_traits.hpp"
|
||||
#include "meta_traits/dtor_traits.hpp"
|
||||
#include "meta_traits/enum_traits.hpp"
|
||||
#include "meta_traits/function_traits.hpp"
|
||||
#include "meta_traits/member_traits.hpp"
|
||||
#include "meta_traits/method_traits.hpp"
|
||||
#include "meta_traits/number_traits.hpp"
|
||||
#include "meta_traits/pointer_traits.hpp"
|
||||
#include "meta_traits/reference_traits.hpp"
|
||||
|
||||
#include "meta_types.hpp"
|
||||
#include "meta_types/any_type.hpp"
|
||||
#include "meta_types/array_type.hpp"
|
||||
@@ -54,8 +49,14 @@
|
||||
#include "meta_types/reference_type.hpp"
|
||||
#include "meta_types/void_type.hpp"
|
||||
|
||||
#include "meta_utilities.hpp"
|
||||
#include "meta_utilities/arg.hpp"
|
||||
#include "meta_utilities/inst.hpp"
|
||||
#include "meta_utilities/value.hpp"
|
||||
#include "meta_utilities/vinvoke.hpp"
|
||||
#include "meta_value.hpp"
|
||||
#include "meta_value/value.hpp"
|
||||
#include "meta_value/vinvoke.hpp"
|
||||
|
||||
namespace meta_hpp
|
||||
{
|
||||
using detail::resolve_type;
|
||||
using detail::resolve_polymorphic_type;
|
||||
|
||||
using detail::resolve_scope;
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <iosfwd>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <set>
|
||||
#include <span>
|
||||
#include <stdexcept>
|
||||
@@ -25,47 +26,34 @@
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
#include <type_traits>
|
||||
#include <typeindex>
|
||||
#include <typeinfo>
|
||||
#include <utility>
|
||||
#include <variant>
|
||||
#include <vector>
|
||||
|
||||
#include <enum.hpp/enum.hpp>
|
||||
#include <enum.hpp/enum_bitflags.hpp>
|
||||
#include "meta_base/cvref_traits.hpp"
|
||||
#include "meta_base/enum_bitflags.hpp"
|
||||
#include "meta_base/enum.hpp"
|
||||
#include "meta_base/noncopyable.hpp"
|
||||
#include "meta_base/overloaded.hpp"
|
||||
#include "meta_base/select_overload.hpp"
|
||||
#include "meta_base/stdex.hpp"
|
||||
#include "meta_base/type_id.hpp"
|
||||
#include "meta_base/type_kinds.hpp"
|
||||
#include "meta_base/type_list.hpp"
|
||||
|
||||
namespace meta_hpp
|
||||
{
|
||||
template < typename Enum >
|
||||
using bitflags = enum_hpp::bitflags::bitflags<Enum>;
|
||||
}
|
||||
using detail::select_const;
|
||||
using detail::select_non_const;
|
||||
using detail::select_overload;
|
||||
|
||||
namespace meta_hpp
|
||||
{
|
||||
template < typename Signature >
|
||||
constexpr auto select(Signature* func) noexcept -> Signature* {
|
||||
return func;
|
||||
}
|
||||
using detail::type_id;
|
||||
using detail::type_kind;
|
||||
using detail::type_list;
|
||||
|
||||
template < typename Signature, typename Class >
|
||||
constexpr auto select(Signature Class::*func) noexcept -> Signature Class::* {
|
||||
return func;
|
||||
}
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template < typename... Types >
|
||||
struct type_list {};
|
||||
|
||||
template < std::size_t Index, typename TypeList >
|
||||
struct type_list_at;
|
||||
|
||||
template < std::size_t Index, typename... Types >
|
||||
struct type_list_at<Index, type_list<Types...>> {
|
||||
using type = std::tuple_element_t<Index, std::tuple<Types...>>;
|
||||
};
|
||||
|
||||
template < std::size_t Index, typename TypeList >
|
||||
using type_list_at_t = typename type_list_at<Index, TypeList>::type;
|
||||
}
|
||||
using enum_hpp::bitflags::bitflags;
|
||||
}
|
||||
|
||||
namespace meta_hpp
|
||||
@@ -168,14 +156,14 @@ namespace meta_hpp
|
||||
|
||||
namespace meta_hpp
|
||||
{
|
||||
struct ctor_index;
|
||||
struct dtor_index;
|
||||
struct evalue_index;
|
||||
struct function_index;
|
||||
struct member_index;
|
||||
struct method_index;
|
||||
struct scope_index;
|
||||
struct variable_index;
|
||||
class ctor_index;
|
||||
class dtor_index;
|
||||
class evalue_index;
|
||||
class function_index;
|
||||
class member_index;
|
||||
class method_index;
|
||||
class scope_index;
|
||||
class variable_index;
|
||||
|
||||
using class_set = std::set<class_type, std::less<>>;
|
||||
using class_map = std::map<std::string, class_type, std::less<>>;
|
||||
@@ -192,50 +180,3 @@ namespace meta_hpp
|
||||
using scope_map = std::map<scope_index, scope, std::less<>>;
|
||||
using variable_map = std::map<variable_index, variable, std::less<>>;
|
||||
}
|
||||
|
||||
namespace meta_hpp::detail::stdex
|
||||
{
|
||||
template < typename T >
|
||||
[[nodiscard]] constexpr std::underlying_type_t<T> to_underlying(T v) noexcept {
|
||||
return static_cast<std::underlying_type_t<T>>(v);
|
||||
}
|
||||
}
|
||||
|
||||
namespace meta_hpp::detail::stdex
|
||||
{
|
||||
template < typename T, typename U >
|
||||
concept same_as =
|
||||
std::is_same_v<T, U> &&
|
||||
std::is_same_v<U, T>;
|
||||
|
||||
template < typename Derived, typename Base >
|
||||
concept derived_from =
|
||||
std::is_base_of_v<Base, Derived> &&
|
||||
std::is_convertible_v<const volatile Derived*, const volatile Base*>;
|
||||
|
||||
template < typename From, typename To >
|
||||
concept convertible_to =
|
||||
std::is_convertible_v<From, To> &&
|
||||
requires { static_cast<To>(std::declval<From>()); };
|
||||
|
||||
template < typename T >
|
||||
concept destructible =
|
||||
std::is_nothrow_destructible_v<T>;
|
||||
|
||||
template < typename T, typename... Args >
|
||||
concept constructible_from =
|
||||
destructible<T> &&
|
||||
std::is_constructible_v<T, Args...>;
|
||||
|
||||
template < typename T >
|
||||
concept move_constructible =
|
||||
constructible_from<T, T> &&
|
||||
convertible_to<T, T>;
|
||||
|
||||
template<typename T>
|
||||
concept copy_constructible =
|
||||
move_constructible<T> &&
|
||||
constructible_from<T, T&> && convertible_to<T&, T> &&
|
||||
constructible_from<T, const T&> && convertible_to<const T&, T> &&
|
||||
constructible_from<T, const T> && convertible_to<const T, T>;
|
||||
}
|
||||
|
||||
39
headers/meta.hpp/meta_base/cvref_traits.hpp
Normal file
39
headers/meta.hpp/meta_base/cvref_traits.hpp
Normal file
@@ -0,0 +1,39 @@
|
||||
/*******************************************************************************
|
||||
* 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, by Matvey Cherevko (blackmatov@gmail.com)
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < typename From >
|
||||
struct cvref_traits {
|
||||
static constexpr bool is_lvalue = std::is_lvalue_reference_v<From>;
|
||||
static constexpr bool is_rvalue = std::is_rvalue_reference_v<From>;
|
||||
static constexpr bool is_const = std::is_const_v<std::remove_reference_t<From>>;
|
||||
static constexpr bool is_volatile = std::is_volatile_v<std::remove_reference_t<From>>;
|
||||
|
||||
template < bool yesno, template < typename > typename Q, typename V >
|
||||
using apply_t_if = std::conditional_t<yesno, Q<V>, V>;
|
||||
|
||||
template < typename To >
|
||||
using copy_to =
|
||||
apply_t_if<is_lvalue, std::add_lvalue_reference_t,
|
||||
apply_t_if<is_rvalue, std::add_rvalue_reference_t,
|
||||
apply_t_if<is_const, std::add_const_t,
|
||||
apply_t_if<is_volatile, std::add_volatile_t,
|
||||
std::remove_cvref_t<To>>>>>;
|
||||
};
|
||||
|
||||
template < typename From, typename To >
|
||||
struct copy_cvref {
|
||||
using type = typename cvref_traits<From>::template copy_to<To>;
|
||||
};
|
||||
|
||||
template < typename From, typename To >
|
||||
using copy_cvref_t = typename copy_cvref<From, To>::type;
|
||||
}
|
||||
1436
headers/meta.hpp/meta_base/enum.hpp
Normal file
1436
headers/meta.hpp/meta_base/enum.hpp
Normal file
File diff suppressed because it is too large
Load Diff
332
headers/meta.hpp/meta_base/enum_bitflags.hpp
Normal file
332
headers/meta.hpp/meta_base/enum_bitflags.hpp
Normal file
@@ -0,0 +1,332 @@
|
||||
/*******************************************************************************
|
||||
* This file is part of the "https://github.com/blackmatov/enum.hpp"
|
||||
* For conditions of distribution and use, see copyright notice in LICENSE.md
|
||||
* Copyright (C) 2019-2022, by Matvey Cherevko (blackmatov@gmail.com)
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
namespace enum_hpp::bitflags
|
||||
{
|
||||
template < typename Enum >
|
||||
class bitflags final {
|
||||
static_assert(std::is_enum_v<Enum>);
|
||||
public:
|
||||
using enum_type = Enum;
|
||||
using underlying_type = std::underlying_type_t<Enum>;
|
||||
|
||||
bitflags() = default;
|
||||
bitflags(const bitflags&) = default;
|
||||
bitflags& operator=(const bitflags&) = default;
|
||||
bitflags(bitflags&&) noexcept = default;
|
||||
bitflags& operator=(bitflags&&) noexcept = default;
|
||||
~bitflags() = default;
|
||||
|
||||
constexpr bitflags(enum_type flags)
|
||||
: flags_(static_cast<underlying_type>(flags)) {}
|
||||
|
||||
constexpr explicit bitflags(underlying_type flags)
|
||||
: flags_(flags) {}
|
||||
|
||||
constexpr void swap(bitflags& other) noexcept {
|
||||
using std::swap;
|
||||
swap(flags_, other.flags_);
|
||||
}
|
||||
|
||||
constexpr explicit operator bool() const noexcept {
|
||||
return !!flags_;
|
||||
}
|
||||
|
||||
constexpr underlying_type as_raw() const noexcept {
|
||||
return flags_;
|
||||
}
|
||||
|
||||
constexpr enum_type as_enum() const noexcept {
|
||||
return static_cast<enum_type>(flags_);
|
||||
}
|
||||
|
||||
constexpr bool has(bitflags flags) const noexcept {
|
||||
return flags.flags_ == (flags_ & flags.flags_);
|
||||
}
|
||||
|
||||
constexpr bitflags& set(bitflags flags) noexcept {
|
||||
flags_ |= flags.flags_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
constexpr bitflags& toggle(bitflags flags) noexcept {
|
||||
flags_ ^= flags.flags_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
constexpr bitflags& clear(bitflags flags) noexcept {
|
||||
flags_ &= ~flags.flags_;
|
||||
return *this;
|
||||
}
|
||||
private:
|
||||
underlying_type flags_{};
|
||||
};
|
||||
|
||||
template < typename Enum >
|
||||
constexpr void swap(bitflags<Enum>& l, bitflags<Enum>& r) noexcept {
|
||||
l.swap(r);
|
||||
}
|
||||
}
|
||||
|
||||
namespace std
|
||||
{
|
||||
template < typename Enum >
|
||||
struct hash<enum_hpp::bitflags::bitflags<Enum>> {
|
||||
size_t operator()(enum_hpp::bitflags::bitflags<Enum> bf) const noexcept {
|
||||
return hash<Enum>{}(bf.as_enum());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
namespace enum_hpp::bitflags
|
||||
{
|
||||
#define ENUM_HPP_DEFINE_BINARY_OPERATOR(op)\
|
||||
template < typename Enum >\
|
||||
constexpr bool operator op(Enum l, bitflags<Enum> r) noexcept {\
|
||||
return l op r.as_enum();\
|
||||
}\
|
||||
template < typename Enum >\
|
||||
constexpr bool operator op(bitflags<Enum> l, Enum r) noexcept {\
|
||||
return l.as_enum() op r;\
|
||||
}\
|
||||
template < typename Enum >\
|
||||
constexpr bool operator op(std::underlying_type_t<Enum> l, bitflags<Enum> r) noexcept {\
|
||||
return l op r.as_raw();\
|
||||
}\
|
||||
template < typename Enum >\
|
||||
constexpr bool operator op(bitflags<Enum> l, std::underlying_type_t<Enum> r) noexcept {\
|
||||
return l.as_raw() op r;\
|
||||
}\
|
||||
template < typename Enum >\
|
||||
constexpr bool operator op(bitflags<Enum> l, bitflags<Enum> r) noexcept {\
|
||||
return l.as_raw() op r.as_raw();\
|
||||
}
|
||||
ENUM_HPP_DEFINE_BINARY_OPERATOR(<)
|
||||
ENUM_HPP_DEFINE_BINARY_OPERATOR(>)
|
||||
ENUM_HPP_DEFINE_BINARY_OPERATOR(<=)
|
||||
ENUM_HPP_DEFINE_BINARY_OPERATOR(>=)
|
||||
ENUM_HPP_DEFINE_BINARY_OPERATOR(==)
|
||||
ENUM_HPP_DEFINE_BINARY_OPERATOR(!=)
|
||||
#undef ENUM_HPP_DEFINE_BINARY_OPERATOR
|
||||
}
|
||||
|
||||
namespace enum_hpp::bitflags
|
||||
{
|
||||
template < typename Enum >
|
||||
constexpr bitflags<Enum> operator~(bitflags<Enum> l) noexcept {
|
||||
return static_cast<Enum>(~l.as_raw());
|
||||
}
|
||||
|
||||
#define ENUM_HPP_DEFINE_BINARY_OPERATOR(op)\
|
||||
template < typename Enum >\
|
||||
constexpr bitflags<Enum> operator op (Enum l, bitflags<Enum> r) noexcept {\
|
||||
return bitflags{l} op r;\
|
||||
}\
|
||||
template < typename Enum >\
|
||||
constexpr bitflags<Enum> operator op (bitflags<Enum> l, Enum r) noexcept {\
|
||||
return l op bitflags{r};\
|
||||
}\
|
||||
template < typename Enum >\
|
||||
constexpr bitflags<Enum> operator op (bitflags<Enum> l, bitflags<Enum> r) noexcept {\
|
||||
return static_cast<Enum>(l.as_raw() op r.as_raw());\
|
||||
}\
|
||||
template < typename Enum >\
|
||||
constexpr bitflags<Enum>& operator op##= (bitflags<Enum>& l, Enum r) noexcept {\
|
||||
return l = l op bitflags{r};\
|
||||
}\
|
||||
template < typename Enum >\
|
||||
constexpr bitflags<Enum>& operator op##= (bitflags<Enum>& l, bitflags<Enum> r) noexcept {\
|
||||
return l = l op r;\
|
||||
}
|
||||
ENUM_HPP_DEFINE_BINARY_OPERATOR(|)
|
||||
ENUM_HPP_DEFINE_BINARY_OPERATOR(&)
|
||||
ENUM_HPP_DEFINE_BINARY_OPERATOR(^)
|
||||
#undef ENUM_HPP_DEFINE_BINARY_OPERATOR
|
||||
}
|
||||
|
||||
namespace enum_hpp::bitflags
|
||||
{
|
||||
//
|
||||
// any
|
||||
//
|
||||
|
||||
template < typename Enum
|
||||
, std::enable_if_t<std::is_enum_v<Enum>, int> = 0 >
|
||||
constexpr bool any(Enum flags) noexcept {
|
||||
return any(bitflags{flags});
|
||||
}
|
||||
|
||||
template < typename Enum >
|
||||
constexpr bool any(bitflags<Enum> flags) noexcept {
|
||||
return 0 != flags.as_raw();
|
||||
}
|
||||
|
||||
//
|
||||
// none
|
||||
//
|
||||
|
||||
template < typename Enum
|
||||
, std::enable_if_t<std::is_enum_v<Enum>, int> = 0 >
|
||||
constexpr bool none(Enum flags) noexcept {
|
||||
return none(bitflags{flags});
|
||||
}
|
||||
|
||||
template < typename Enum >
|
||||
constexpr bool none(bitflags<Enum> flags) noexcept {
|
||||
return 0 == flags.as_raw();
|
||||
}
|
||||
|
||||
//
|
||||
// all_of
|
||||
//
|
||||
|
||||
template < typename Enum
|
||||
, std::enable_if_t<std::is_enum_v<Enum>, int> = 0 >
|
||||
constexpr bool all_of(Enum flags, Enum mask) noexcept {
|
||||
return all_of(bitflags{flags}, bitflags{mask});
|
||||
}
|
||||
|
||||
template < typename Enum >
|
||||
constexpr bool all_of(Enum flags, bitflags<Enum> mask) noexcept {
|
||||
return all_of(bitflags{flags}, mask);
|
||||
}
|
||||
|
||||
template < typename Enum >
|
||||
constexpr bool all_of(bitflags<Enum> flags, Enum mask) noexcept {
|
||||
return all_of(flags, bitflags{mask});
|
||||
}
|
||||
|
||||
template < typename Enum >
|
||||
constexpr bool all_of(bitflags<Enum> flags, bitflags<Enum> mask) noexcept {
|
||||
return (flags.as_raw() & mask.as_raw()) == mask.as_raw();
|
||||
}
|
||||
|
||||
//
|
||||
// any_of
|
||||
//
|
||||
|
||||
template < typename Enum
|
||||
, std::enable_if_t<std::is_enum_v<Enum>, int> = 0 >
|
||||
constexpr bool any_of(Enum flags, Enum mask) noexcept {
|
||||
return any_of(bitflags{flags}, bitflags{mask});
|
||||
}
|
||||
|
||||
template < typename Enum >
|
||||
constexpr bool any_of(Enum flags, bitflags<Enum> mask) noexcept {
|
||||
return any_of(bitflags{flags}, mask);
|
||||
}
|
||||
|
||||
template < typename Enum >
|
||||
constexpr bool any_of(bitflags<Enum> flags, Enum mask) noexcept {
|
||||
return any_of(flags, bitflags{mask});
|
||||
}
|
||||
|
||||
template < typename Enum >
|
||||
constexpr bool any_of(bitflags<Enum> flags, bitflags<Enum> mask) noexcept {
|
||||
return mask.as_raw() == 0
|
||||
|| (flags.as_raw() & mask.as_raw()) != 0;
|
||||
}
|
||||
|
||||
//
|
||||
// none_of
|
||||
//
|
||||
|
||||
template < typename Enum
|
||||
, std::enable_if_t<std::is_enum_v<Enum>, int> = 0 >
|
||||
constexpr bool none_of(Enum flags, Enum mask) noexcept {
|
||||
return none_of(bitflags{flags}, bitflags{mask});
|
||||
}
|
||||
|
||||
template < typename Enum >
|
||||
constexpr bool none_of(Enum flags, bitflags<Enum> mask) noexcept {
|
||||
return none_of(bitflags{flags}, mask);
|
||||
}
|
||||
|
||||
template < typename Enum >
|
||||
constexpr bool none_of(bitflags<Enum> flags, Enum mask) noexcept {
|
||||
return none_of(flags, bitflags{mask});
|
||||
}
|
||||
|
||||
template < typename Enum >
|
||||
constexpr bool none_of(bitflags<Enum> flags, bitflags<Enum> mask) noexcept {
|
||||
return mask.as_raw() != 0
|
||||
&& (flags.as_raw() & mask.as_raw()) == 0;
|
||||
}
|
||||
|
||||
//
|
||||
// any_except
|
||||
//
|
||||
|
||||
template < typename Enum
|
||||
, std::enable_if_t<std::is_enum_v<Enum>, int> = 0 >
|
||||
constexpr bool any_except(Enum flags, Enum mask) noexcept {
|
||||
return any_except(bitflags{flags}, bitflags{mask});
|
||||
}
|
||||
|
||||
template < typename Enum >
|
||||
constexpr bool any_except(Enum flags, bitflags<Enum> mask) noexcept {
|
||||
return any_except(bitflags{flags}, mask);
|
||||
}
|
||||
|
||||
template < typename Enum >
|
||||
constexpr bool any_except(bitflags<Enum> flags, Enum mask) noexcept {
|
||||
return any_except(flags, bitflags{mask});
|
||||
}
|
||||
|
||||
template < typename Enum >
|
||||
constexpr bool any_except(bitflags<Enum> flags, bitflags<Enum> mask) noexcept {
|
||||
return any_of(flags, ~mask);
|
||||
}
|
||||
|
||||
//
|
||||
// none_except
|
||||
//
|
||||
|
||||
template < typename Enum
|
||||
, std::enable_if_t<std::is_enum_v<Enum>, int> = 0 >
|
||||
constexpr bool none_except(Enum flags, Enum mask) noexcept {
|
||||
return none_except(bitflags{flags}, bitflags{mask});
|
||||
}
|
||||
|
||||
template < typename Enum >
|
||||
constexpr bool none_except(Enum flags, bitflags<Enum> mask) noexcept {
|
||||
return none_except(bitflags{flags}, mask);
|
||||
}
|
||||
|
||||
template < typename Enum >
|
||||
constexpr bool none_except(bitflags<Enum> flags, Enum mask) noexcept {
|
||||
return none_except(flags, bitflags{mask});
|
||||
}
|
||||
|
||||
template < typename Enum >
|
||||
constexpr bool none_except(bitflags<Enum> flags, bitflags<Enum> mask) noexcept {
|
||||
return none_of(flags, ~mask);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// ENUM_HPP_OPERATORS_DECL
|
||||
//
|
||||
|
||||
#define ENUM_HPP_OPERATORS_DECL(Enum)\
|
||||
constexpr ::enum_hpp::bitflags::bitflags<Enum> operator~ [[maybe_unused]] (Enum l) noexcept {\
|
||||
return ~::enum_hpp::bitflags::bitflags(l);\
|
||||
}\
|
||||
constexpr ::enum_hpp::bitflags::bitflags<Enum> operator| [[maybe_unused]] (Enum l, Enum r) noexcept {\
|
||||
return ::enum_hpp::bitflags::bitflags(l) | ::enum_hpp::bitflags::bitflags(r);\
|
||||
}\
|
||||
constexpr ::enum_hpp::bitflags::bitflags<Enum> operator& [[maybe_unused]] (Enum l, Enum r) noexcept {\
|
||||
return ::enum_hpp::bitflags::bitflags(l) & ::enum_hpp::bitflags::bitflags(r);\
|
||||
}\
|
||||
constexpr ::enum_hpp::bitflags::bitflags<Enum> operator^ [[maybe_unused]] (Enum l, Enum r) noexcept {\
|
||||
return ::enum_hpp::bitflags::bitflags(l) ^ ::enum_hpp::bitflags::bitflags(r);\
|
||||
}
|
||||
21
headers/meta.hpp/meta_base/noncopyable.hpp
Normal file
21
headers/meta.hpp/meta_base/noncopyable.hpp
Normal file
@@ -0,0 +1,21 @@
|
||||
/*******************************************************************************
|
||||
* 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, by Matvey Cherevko (blackmatov@gmail.com)
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
class noncopyable {
|
||||
protected:
|
||||
noncopyable() = default;
|
||||
~noncopyable() = default;
|
||||
public:
|
||||
noncopyable(noncopyable&&) = delete;
|
||||
noncopyable(const noncopyable&) = delete;
|
||||
noncopyable& operator=(noncopyable&&) = delete;
|
||||
noncopyable& operator=(const noncopyable&) = delete;
|
||||
};
|
||||
}
|
||||
18
headers/meta.hpp/meta_base/overloaded.hpp
Normal file
18
headers/meta.hpp/meta_base/overloaded.hpp
Normal file
@@ -0,0 +1,18 @@
|
||||
/*******************************************************************************
|
||||
* 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, by Matvey Cherevko (blackmatov@gmail.com)
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < typename... Ts >
|
||||
struct overloaded : Ts... {
|
||||
using Ts::operator()...;
|
||||
};
|
||||
|
||||
template < typename... Ts >
|
||||
overloaded(Ts...) -> overloaded<Ts...>;
|
||||
}
|
||||
40
headers/meta.hpp/meta_base/select_overload.hpp
Normal file
40
headers/meta.hpp/meta_base/select_overload.hpp
Normal file
@@ -0,0 +1,40 @@
|
||||
/*******************************************************************************
|
||||
* 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, by Matvey Cherevko (blackmatov@gmail.com)
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < typename C, typename R, typename... Args >
|
||||
constexpr auto select_const(R (C::*func)(Args...) const) -> decltype(func) {
|
||||
return func;
|
||||
}
|
||||
|
||||
template < typename C, typename R, typename... Args >
|
||||
constexpr auto select_const(R (C::*func)(Args...) const noexcept) -> decltype(func) {
|
||||
return func;
|
||||
}
|
||||
|
||||
template < typename C, typename R, typename... Args >
|
||||
constexpr auto select_non_const(R (C::*func)(Args...)) -> decltype(func) {
|
||||
return func;
|
||||
}
|
||||
|
||||
template < typename C, typename R, typename... Args >
|
||||
constexpr auto select_non_const(R (C::*func)(Args...) noexcept) -> decltype(func) {
|
||||
return func;
|
||||
}
|
||||
|
||||
template < typename Signature >
|
||||
constexpr auto select_overload(Signature* func) noexcept -> decltype(func) {
|
||||
return func;
|
||||
}
|
||||
|
||||
template < typename Signature, typename C >
|
||||
constexpr auto select_overload(Signature C::*func) noexcept -> decltype(func) {
|
||||
return func;
|
||||
}
|
||||
}
|
||||
56
headers/meta.hpp/meta_base/stdex.hpp
Normal file
56
headers/meta.hpp/meta_base/stdex.hpp
Normal file
@@ -0,0 +1,56 @@
|
||||
/*******************************************************************************
|
||||
* 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, by Matvey Cherevko (blackmatov@gmail.com)
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
namespace meta_hpp::stdex
|
||||
{
|
||||
template < typename T, typename U >
|
||||
concept same_as =
|
||||
std::is_same_v<T, U> &&
|
||||
std::is_same_v<U, T>;
|
||||
|
||||
template < typename Derived, typename Base >
|
||||
concept derived_from =
|
||||
std::is_base_of_v<Base, Derived> &&
|
||||
std::is_convertible_v<const volatile Derived*, const volatile Base*>;
|
||||
|
||||
template < typename From, typename To >
|
||||
concept convertible_to =
|
||||
std::is_convertible_v<From, To> &&
|
||||
requires { static_cast<To>(std::declval<From>()); };
|
||||
|
||||
template < typename T >
|
||||
concept destructible =
|
||||
std::is_nothrow_destructible_v<T>;
|
||||
|
||||
template < typename T, typename... Args >
|
||||
concept constructible_from =
|
||||
destructible<T> &&
|
||||
std::is_constructible_v<T, Args...>;
|
||||
|
||||
template < typename T >
|
||||
concept move_constructible =
|
||||
constructible_from<T, T> &&
|
||||
convertible_to<T, T>;
|
||||
|
||||
template<typename T>
|
||||
concept copy_constructible =
|
||||
move_constructible<T> &&
|
||||
constructible_from<T, T&> && convertible_to<T&, T> &&
|
||||
constructible_from<T, const T&> && convertible_to<const T&, T> &&
|
||||
constructible_from<T, const T> && convertible_to<const T, T>;
|
||||
}
|
||||
|
||||
namespace meta_hpp::stdex
|
||||
{
|
||||
template < typename Enum >
|
||||
[[nodiscard]] constexpr std::underlying_type_t<Enum> to_underlying(Enum e) noexcept {
|
||||
return static_cast<std::underlying_type_t<Enum>>(e);
|
||||
}
|
||||
}
|
||||
62
headers/meta.hpp/meta_base/type_id.hpp
Normal file
62
headers/meta.hpp/meta_base/type_id.hpp
Normal file
@@ -0,0 +1,62 @@
|
||||
/*******************************************************************************
|
||||
* 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, by Matvey Cherevko (blackmatov@gmail.com)
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <atomic>
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
|
||||
#include "type_list.hpp"
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
class type_id final {
|
||||
public:
|
||||
template < typename T >
|
||||
// NOLINTNEXTLINE(readability-named-parameter)
|
||||
explicit type_id(type_list<T>) noexcept
|
||||
: id_{type_to_id<T>()} {}
|
||||
|
||||
type_id(type_id&&) = default;
|
||||
type_id(const type_id&) = default;
|
||||
|
||||
type_id& operator=(type_id&&) = default;
|
||||
type_id& operator=(const type_id&) = default;
|
||||
|
||||
~type_id() = default;
|
||||
|
||||
[[nodiscard]] std::size_t get_hash() const noexcept {
|
||||
return std::hash<underlying_type>{}(id_);
|
||||
}
|
||||
|
||||
[[nodiscard]] friend bool operator<(type_id l, type_id r) noexcept {
|
||||
return l.id_ < r.id_;
|
||||
}
|
||||
|
||||
[[nodiscard]] friend bool operator==(type_id l, type_id r) noexcept {
|
||||
return l.id_ == r.id_;
|
||||
}
|
||||
|
||||
[[nodiscard]] friend bool operator!=(type_id l, type_id r) noexcept {
|
||||
return l.id_ != r.id_;
|
||||
}
|
||||
private:
|
||||
using underlying_type = std::uint32_t;
|
||||
underlying_type id_{};
|
||||
private:
|
||||
[[nodiscard]] static underlying_type next() noexcept {
|
||||
static std::atomic<underlying_type> id{};
|
||||
return ++id;
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
[[nodiscard]] static underlying_type type_to_id() noexcept {
|
||||
static const underlying_type id{next()};
|
||||
return id;
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -6,26 +6,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "meta_base.hpp"
|
||||
|
||||
namespace meta_hpp
|
||||
{
|
||||
enum class type_kind : std::uint32_t {
|
||||
array_,
|
||||
class_,
|
||||
ctor_,
|
||||
dtor_,
|
||||
enum_,
|
||||
function_,
|
||||
member_,
|
||||
method_,
|
||||
nullptr_,
|
||||
number_,
|
||||
pointer_,
|
||||
reference_,
|
||||
void_,
|
||||
};
|
||||
}
|
||||
#include <cstdint>
|
||||
#include <type_traits>
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
@@ -61,6 +43,25 @@ namespace meta_hpp::detail
|
||||
|
||||
template < typename T >
|
||||
concept void_kind = std::is_void_v<T>;
|
||||
}
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
enum class type_kind : std::uint32_t {
|
||||
array_,
|
||||
class_,
|
||||
ctor_,
|
||||
dtor_,
|
||||
enum_,
|
||||
function_,
|
||||
member_,
|
||||
method_,
|
||||
nullptr_,
|
||||
number_,
|
||||
pointer_,
|
||||
reference_,
|
||||
void_,
|
||||
};
|
||||
|
||||
template < typename T >
|
||||
constexpr type_kind make_type_kind() noexcept {
|
||||
@@ -77,96 +78,3 @@ namespace meta_hpp::detail
|
||||
if constexpr ( void_kind<T> ) { return type_kind::void_; }
|
||||
}
|
||||
}
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < type_kind Kind >
|
||||
struct type_kind_traits;
|
||||
|
||||
template <>
|
||||
struct type_kind_traits<type_kind::array_> {
|
||||
using kind_type = array_type;
|
||||
using kind_type_data = array_type_data;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct type_kind_traits<type_kind::class_> {
|
||||
using kind_type = class_type;
|
||||
using kind_type_data = class_type_data;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct type_kind_traits<type_kind::ctor_> {
|
||||
using kind_type = ctor_type;
|
||||
using kind_type_data = ctor_type_data;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct type_kind_traits<type_kind::dtor_> {
|
||||
using kind_type = dtor_type;
|
||||
using kind_type_data = dtor_type_data;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct type_kind_traits<type_kind::enum_> {
|
||||
using kind_type = enum_type;
|
||||
using kind_type_data = enum_type_data;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct type_kind_traits<type_kind::function_> {
|
||||
using kind_type = function_type;
|
||||
using kind_type_data = function_type_data;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct type_kind_traits<type_kind::member_> {
|
||||
using kind_type = member_type;
|
||||
using kind_type_data = member_type_data;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct type_kind_traits<type_kind::method_> {
|
||||
using kind_type = method_type;
|
||||
using kind_type_data = method_type_data;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct type_kind_traits<type_kind::nullptr_> {
|
||||
using kind_type = nullptr_type;
|
||||
using kind_type_data = nullptr_type_data;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct type_kind_traits<type_kind::number_> {
|
||||
using kind_type = number_type;
|
||||
using kind_type_data = number_type_data;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct type_kind_traits<type_kind::pointer_> {
|
||||
using kind_type = pointer_type;
|
||||
using kind_type_data = pointer_type_data;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct type_kind_traits<type_kind::reference_> {
|
||||
using kind_type = reference_type;
|
||||
using kind_type_data = reference_type_data;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct type_kind_traits<type_kind::void_> {
|
||||
using kind_type = void_type;
|
||||
using kind_type_data = void_type_data;
|
||||
};
|
||||
|
||||
template < typename T >
|
||||
using kind_type = typename type_kind_traits<make_type_kind<T>()>::kind_type;
|
||||
|
||||
template < typename T >
|
||||
using kind_type_data = typename type_kind_traits<make_type_kind<T>()>::kind_type_data;
|
||||
|
||||
template < typename T >
|
||||
using kind_type_data_ptr = std::shared_ptr<kind_type_data<T>>;
|
||||
}
|
||||
26
headers/meta.hpp/meta_base/type_list.hpp
Normal file
26
headers/meta.hpp/meta_base/type_list.hpp
Normal file
@@ -0,0 +1,26 @@
|
||||
/*******************************************************************************
|
||||
* 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, by Matvey Cherevko (blackmatov@gmail.com)
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <tuple>
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < typename... Types >
|
||||
struct type_list {};
|
||||
|
||||
template < std::size_t Index, typename TypeList >
|
||||
struct type_list_at;
|
||||
|
||||
template < std::size_t Index, typename... Types >
|
||||
struct type_list_at<Index, type_list<Types...>> {
|
||||
using type = std::tuple_element_t<Index, std::tuple<Types...>>;
|
||||
};
|
||||
|
||||
template < std::size_t Index, typename TypeList >
|
||||
using type_list_at_t = typename type_list_at<Index, TypeList>::type;
|
||||
}
|
||||
@@ -9,11 +9,13 @@
|
||||
#include "../meta_base.hpp"
|
||||
#include "../meta_binds.hpp"
|
||||
|
||||
#include "../meta_detail/type_registry.hpp"
|
||||
|
||||
namespace meta_hpp
|
||||
{
|
||||
template < detail::class_kind Class >
|
||||
class_bind<Class>::class_bind()
|
||||
: data_{detail::class_type_data::get_static<Class>()} {}
|
||||
: data_{detail::type_access(detail::resolve_type<Class>())} {}
|
||||
|
||||
template < detail::class_kind Class >
|
||||
class_bind<Class>::operator class_type() const noexcept {
|
||||
@@ -45,8 +47,8 @@ namespace meta_hpp
|
||||
class_bind<Class>& class_bind<Class>::base_()
|
||||
requires detail::class_bind_base_kind<Class, Base>
|
||||
{
|
||||
data_->bases.emplace(resolve_type<Base>());
|
||||
data_->bases_info.emplace(resolve_type<Base>(), detail::class_type_data::base_info{
|
||||
data_->bases.emplace(detail::resolve_type<Base>());
|
||||
data_->bases_info.emplace(detail::resolve_type<Base>(), detail::class_type_data::base_info{
|
||||
.upcast = +[](void* derived) -> void* {
|
||||
return static_cast<Base*>(static_cast<Class*>(derived));
|
||||
}
|
||||
|
||||
@@ -9,11 +9,13 @@
|
||||
#include "../meta_base.hpp"
|
||||
#include "../meta_binds.hpp"
|
||||
|
||||
#include "../meta_detail/type_registry.hpp"
|
||||
|
||||
namespace meta_hpp
|
||||
{
|
||||
template < detail::enum_kind Enum >
|
||||
enum_bind<Enum>::enum_bind()
|
||||
: data_{detail::enum_type_data::get_static<Enum>()} {}
|
||||
: data_{detail::type_access(detail::resolve_type<Enum>())} {}
|
||||
|
||||
template < detail::enum_kind Enum >
|
||||
enum_bind<Enum>::operator enum_type() const noexcept {
|
||||
|
||||
@@ -9,6 +9,9 @@
|
||||
#include "../meta_base.hpp"
|
||||
#include "../meta_binds.hpp"
|
||||
|
||||
#include "../meta_detail/state_registry.hpp"
|
||||
#include "../meta_detail/type_registry.hpp"
|
||||
|
||||
namespace meta_hpp
|
||||
{
|
||||
// NOLINTNEXTLINE(readability-named-parameter)
|
||||
@@ -17,7 +20,7 @@ namespace meta_hpp
|
||||
|
||||
// NOLINTNEXTLINE(readability-named-parameter)
|
||||
inline scope_bind::scope_bind(std::string_view name, static_tag)
|
||||
: state_{detail::scope_state::get_static(name)} {}
|
||||
: state_{detail::state_access(detail::resolve_scope(name))} {}
|
||||
|
||||
inline scope_bind::operator scope() const noexcept {
|
||||
return scope{state_};
|
||||
@@ -25,13 +28,13 @@ namespace meta_hpp
|
||||
|
||||
template < detail::class_kind Class >
|
||||
scope_bind& scope_bind::class_(std::string name) {
|
||||
state_->classes.emplace(std::move(name), resolve_type<Class>());
|
||||
state_->classes.emplace(std::move(name), detail::resolve_type<Class>());
|
||||
return *this;
|
||||
}
|
||||
|
||||
template < detail::enum_kind Enum >
|
||||
scope_bind& scope_bind::enum_(std::string name) {
|
||||
state_->enums.emplace(std::move(name), resolve_type<Enum>());
|
||||
state_->enums.emplace(std::move(name), detail::resolve_type<Enum>());
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
28
headers/meta.hpp/meta_detail/state_family.hpp
Normal file
28
headers/meta.hpp/meta_detail/state_family.hpp
Normal file
@@ -0,0 +1,28 @@
|
||||
/*******************************************************************************
|
||||
* 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, by Matvey Cherevko (blackmatov@gmail.com)
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../meta_base.hpp"
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < typename T >
|
||||
concept state_family =
|
||||
stdex::same_as<T, ctor> ||
|
||||
stdex::same_as<T, dtor> ||
|
||||
stdex::same_as<T, evalue> ||
|
||||
stdex::same_as<T, function> ||
|
||||
stdex::same_as<T, member> ||
|
||||
stdex::same_as<T, method> ||
|
||||
stdex::same_as<T, scope> ||
|
||||
stdex::same_as<T, variable>;
|
||||
|
||||
template < state_family T >
|
||||
[[nodiscard]] auto state_access(const T& state) {
|
||||
return state.state_;
|
||||
}
|
||||
}
|
||||
54
headers/meta.hpp/meta_detail/state_registry.hpp
Normal file
54
headers/meta.hpp/meta_detail/state_registry.hpp
Normal file
@@ -0,0 +1,54 @@
|
||||
/*******************************************************************************
|
||||
* 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, by Matvey Cherevko (blackmatov@gmail.com)
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../meta_base.hpp"
|
||||
#include "../meta_states.hpp"
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
class state_registry final {
|
||||
public:
|
||||
[[nodiscard]] static state_registry& instance() {
|
||||
static state_registry instance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
[[nodiscard]] scope get_scope_by_name(std::string_view name) const noexcept {
|
||||
if ( auto iter = scopes_.find(name); iter != scopes_.end() ) {
|
||||
return iter->second;
|
||||
}
|
||||
return scope{};
|
||||
}
|
||||
|
||||
[[nodiscard]] scope resolve_scope(std::string_view name) {
|
||||
return ensure_scope(name);
|
||||
}
|
||||
private:
|
||||
state_registry() = default;
|
||||
|
||||
scope ensure_scope(std::string_view name) {
|
||||
if ( auto iter = scopes_.find(name); iter != scopes_.end() ) {
|
||||
return iter->second;
|
||||
}
|
||||
|
||||
return scopes_.emplace(
|
||||
std::string{name},
|
||||
scope_state::make(std::string{name})).first->second;
|
||||
}
|
||||
private:
|
||||
std::map<std::string, scope, std::less<>> scopes_;
|
||||
};
|
||||
}
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
[[nodiscard]] inline scope resolve_scope(std::string_view name) {
|
||||
state_registry& registry = state_registry::instance();
|
||||
return registry.resolve_scope(name);
|
||||
}
|
||||
}
|
||||
34
headers/meta.hpp/meta_detail/type_family.hpp
Normal file
34
headers/meta.hpp/meta_detail/type_family.hpp
Normal file
@@ -0,0 +1,34 @@
|
||||
/*******************************************************************************
|
||||
* 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, by Matvey Cherevko (blackmatov@gmail.com)
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../meta_base.hpp"
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < typename T >
|
||||
concept type_family =
|
||||
stdex::same_as<T, any_type> ||
|
||||
stdex::same_as<T, array_type> ||
|
||||
stdex::same_as<T, class_type> ||
|
||||
stdex::same_as<T, ctor_type> ||
|
||||
stdex::same_as<T, dtor_type> ||
|
||||
stdex::same_as<T, enum_type> ||
|
||||
stdex::same_as<T, function_type> ||
|
||||
stdex::same_as<T, member_type> ||
|
||||
stdex::same_as<T, method_type> ||
|
||||
stdex::same_as<T, nullptr_type> ||
|
||||
stdex::same_as<T, number_type> ||
|
||||
stdex::same_as<T, pointer_type> ||
|
||||
stdex::same_as<T, reference_type> ||
|
||||
stdex::same_as<T, void_type>;
|
||||
|
||||
template < type_family T >
|
||||
[[nodiscard]] auto type_access(const T& type) {
|
||||
return type.data_;
|
||||
}
|
||||
}
|
||||
265
headers/meta.hpp/meta_detail/type_registry.hpp
Normal file
265
headers/meta.hpp/meta_detail/type_registry.hpp
Normal file
@@ -0,0 +1,265 @@
|
||||
/*******************************************************************************
|
||||
* 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, by Matvey Cherevko (blackmatov@gmail.com)
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../meta_base.hpp"
|
||||
#include "../meta_types.hpp"
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
class type_registry final {
|
||||
public:
|
||||
[[nodiscard]] static type_registry& instance() {
|
||||
static type_registry instance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
[[nodiscard]] any_type get_type_by_id(type_id id) const noexcept {
|
||||
if ( auto iter = type_by_id_.find(id); iter != type_by_id_.end() ) {
|
||||
return iter->second;
|
||||
}
|
||||
return any_type{};
|
||||
}
|
||||
|
||||
[[nodiscard]] any_type get_type_by_rtti(const std::type_index& index) const noexcept {
|
||||
if ( auto iter = type_by_rtti_.find(index); iter != type_by_rtti_.end() ) {
|
||||
return iter->second;
|
||||
}
|
||||
return any_type{};
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
template < array_kind Array >
|
||||
[[nodiscard]] array_type resolve_type() { return resolve_array_type<Array>(); }
|
||||
|
||||
template < class_kind Class >
|
||||
[[nodiscard]] class_type resolve_type() { return resolve_class_type<Class>(); }
|
||||
|
||||
template < enum_kind Enum >
|
||||
[[nodiscard]] enum_type resolve_type() { return resolve_enum_type<Enum>(); }
|
||||
|
||||
template < function_kind Function >
|
||||
[[nodiscard]] function_type resolve_type() { return resolve_function_type<Function>(); }
|
||||
|
||||
template < member_kind Member >
|
||||
[[nodiscard]] member_type resolve_type() { return resolve_member_type<Member>(); }
|
||||
|
||||
template < method_kind Method >
|
||||
[[nodiscard]] method_type resolve_type() { return resolve_method_type<Method>(); }
|
||||
|
||||
template < nullptr_kind Nullptr >
|
||||
[[nodiscard]] nullptr_type resolve_type() { return resolve_nullptr_type<Nullptr>(); }
|
||||
|
||||
template < number_kind Number >
|
||||
[[nodiscard]] number_type resolve_type() { return resolve_number_type<Number>(); }
|
||||
|
||||
template < pointer_kind Pointer >
|
||||
[[nodiscard]] pointer_type resolve_type() { return resolve_pointer_type<Pointer>(); }
|
||||
|
||||
template < reference_kind Reference >
|
||||
[[nodiscard]] reference_type resolve_type() { return resolve_reference_type<Reference>(); }
|
||||
|
||||
template < void_kind Void >
|
||||
[[nodiscard]] void_type resolve_type() { return resolve_void_type<Void>(); }
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
template < array_kind Array >
|
||||
[[nodiscard]] array_type resolve_array_type() { return array_type{resolve_array_type_data<Array>()}; }
|
||||
|
||||
template < class_kind Class >
|
||||
[[nodiscard]] class_type resolve_class_type() { return class_type{resolve_class_type_data<Class>()}; }
|
||||
|
||||
template < class_kind Class, typename... Args >
|
||||
[[nodiscard]] ctor_type resolve_ctor_type() { return ctor_type{resolve_ctor_type_data<Class, Args...>()}; }
|
||||
|
||||
template < class_kind Class >
|
||||
[[nodiscard]] dtor_type resolve_dtor_type() { return dtor_type{resolve_dtor_type_data<Class>()}; }
|
||||
|
||||
template < enum_kind Enum >
|
||||
[[nodiscard]] enum_type resolve_enum_type() { return enum_type{resolve_enum_type_data<Enum>()}; }
|
||||
|
||||
template < function_kind Function >
|
||||
[[nodiscard]] function_type resolve_function_type() { return function_type{resolve_function_type_data<Function>()}; }
|
||||
|
||||
template < member_kind Member >
|
||||
[[nodiscard]] member_type resolve_member_type() { return member_type{resolve_member_type_data<Member>()}; }
|
||||
|
||||
template < method_kind Method >
|
||||
[[nodiscard]] method_type resolve_method_type() { return method_type{resolve_method_type_data<Method>()}; }
|
||||
|
||||
template < nullptr_kind Nullptr >
|
||||
[[nodiscard]] nullptr_type resolve_nullptr_type() { return nullptr_type{resolve_nullptr_type_data<Nullptr>()}; }
|
||||
|
||||
template < number_kind Number >
|
||||
[[nodiscard]] number_type resolve_number_type() { return number_type{resolve_number_type_data<Number>()}; }
|
||||
|
||||
template < pointer_kind Pointer >
|
||||
[[nodiscard]] pointer_type resolve_pointer_type() { return pointer_type{resolve_pointer_type_data<Pointer>()}; }
|
||||
|
||||
template < reference_kind Reference >
|
||||
[[nodiscard]] reference_type resolve_reference_type() { return reference_type{resolve_reference_type_data<Reference>()}; }
|
||||
|
||||
template < void_kind Void >
|
||||
[[nodiscard]] void_type resolve_void_type() { return void_type{resolve_void_type_data<Void>()}; }
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
template < array_kind Array >
|
||||
[[nodiscard]] array_type_data_ptr resolve_array_type_data() {
|
||||
static array_type_data_ptr data{std::make_shared<array_type_data>(type_list<Array>{})};
|
||||
return ensure_type<Array>(data);
|
||||
}
|
||||
|
||||
template < class_kind Class >
|
||||
[[nodiscard]] class_type_data_ptr resolve_class_type_data() {
|
||||
static class_type_data_ptr data{std::make_shared<class_type_data>(type_list<Class>{})};
|
||||
return ensure_type<Class>(data);
|
||||
}
|
||||
|
||||
template < class_kind Class, typename... Args >
|
||||
[[nodiscard]] ctor_type_data_ptr resolve_ctor_type_data() {
|
||||
static ctor_type_data_ptr data{std::make_shared<ctor_type_data>(type_list<Class>{}, type_list<Args...>{})};
|
||||
return data;
|
||||
}
|
||||
|
||||
template < class_kind Class >
|
||||
[[nodiscard]] dtor_type_data_ptr resolve_dtor_type_data() {
|
||||
static dtor_type_data_ptr data{std::make_shared<dtor_type_data>(type_list<Class>{})};
|
||||
return data;
|
||||
}
|
||||
|
||||
template < enum_kind Enum >
|
||||
[[nodiscard]] enum_type_data_ptr resolve_enum_type_data() {
|
||||
static enum_type_data_ptr data{std::make_shared<enum_type_data>(type_list<Enum>{})};
|
||||
return ensure_type<Enum>(data);
|
||||
}
|
||||
|
||||
template < function_kind Function >
|
||||
[[nodiscard]] function_type_data_ptr resolve_function_type_data() {
|
||||
static function_type_data_ptr data{std::make_shared<function_type_data>(type_list<Function>{})};
|
||||
return ensure_type<Function>(data);
|
||||
}
|
||||
|
||||
template < member_kind Member >
|
||||
[[nodiscard]] member_type_data_ptr resolve_member_type_data() {
|
||||
static member_type_data_ptr data{std::make_shared<member_type_data>(type_list<Member>{})};
|
||||
return ensure_type<Member>(data);
|
||||
}
|
||||
|
||||
template < method_kind Method >
|
||||
[[nodiscard]] method_type_data_ptr resolve_method_type_data() {
|
||||
static method_type_data_ptr data{std::make_shared<method_type_data>(type_list<Method>{})};
|
||||
return ensure_type<Method>(data);
|
||||
}
|
||||
|
||||
template < nullptr_kind Nullptr >
|
||||
[[nodiscard]] nullptr_type_data_ptr resolve_nullptr_type_data() {
|
||||
static nullptr_type_data_ptr data{std::make_shared<nullptr_type_data>(type_list<Nullptr>{})};
|
||||
return ensure_type<Nullptr>(data);
|
||||
}
|
||||
|
||||
template < number_kind Number >
|
||||
[[nodiscard]] number_type_data_ptr resolve_number_type_data() {
|
||||
static number_type_data_ptr data{std::make_shared<number_type_data>(type_list<Number>{})};
|
||||
return ensure_type<Number>(data);
|
||||
}
|
||||
|
||||
template < pointer_kind Pointer >
|
||||
[[nodiscard]] pointer_type_data_ptr resolve_pointer_type_data() {
|
||||
static pointer_type_data_ptr data{std::make_shared<pointer_type_data>(type_list<Pointer>{})};
|
||||
return ensure_type<Pointer>(data);
|
||||
}
|
||||
|
||||
template < reference_kind Reference >
|
||||
[[nodiscard]] reference_type_data_ptr resolve_reference_type_data() {
|
||||
static reference_type_data_ptr data{std::make_shared<reference_type_data>(type_list<Reference>{})};
|
||||
return ensure_type<Reference>(data);
|
||||
}
|
||||
|
||||
template < void_kind Void >
|
||||
[[nodiscard]] void_type_data_ptr resolve_void_type_data() {
|
||||
static void_type_data_ptr data{std::make_shared<void_type_data>(type_list<Void>{})};
|
||||
return ensure_type<Void>(data);
|
||||
}
|
||||
private:
|
||||
type_registry() = default;
|
||||
|
||||
template < typename Type, typename TypeData >
|
||||
TypeData ensure_type(const TypeData& type_data) {
|
||||
static std::once_flag init_flag{};
|
||||
std::call_once(init_flag, [this, &type_data](){
|
||||
type_by_id_[type_data->id] = any_type{type_data};
|
||||
type_by_rtti_[typeid(Type)] = any_type{type_data};
|
||||
});
|
||||
return type_data;
|
||||
}
|
||||
private:
|
||||
std::map<type_id, any_type, std::less<>> type_by_id_;
|
||||
std::map<std::type_index, any_type, std::less<>> type_by_rtti_;
|
||||
};
|
||||
}
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < typename T >
|
||||
[[nodiscard]] auto resolve_type() {
|
||||
type_registry& registry = type_registry::instance();
|
||||
return registry.resolve_type<std::remove_cv_t<T>>();
|
||||
}
|
||||
|
||||
template < typename... Ts >
|
||||
[[nodiscard]] std::vector<any_type> resolve_types() {
|
||||
return { resolve_type<Ts>()... };
|
||||
}
|
||||
}
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < class_kind Class, typename... Args >
|
||||
ctor_type resolve_ctor_type() {
|
||||
type_registry& registry = type_registry::instance();
|
||||
return registry.resolve_ctor_type<Class, Args...>();
|
||||
}
|
||||
|
||||
template < class_kind Class >
|
||||
dtor_type resolve_dtor_type() {
|
||||
type_registry& registry = type_registry::instance();
|
||||
return registry.resolve_dtor_type<Class>();
|
||||
}
|
||||
}
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < typename T >
|
||||
// NOLINTNEXTLINE(readability-named-parameter)
|
||||
[[nodiscard]] auto resolve_type(T&&) {
|
||||
return resolve_type<std::remove_reference_t<T>>();
|
||||
}
|
||||
|
||||
template < typename... Ts >
|
||||
// NOLINTNEXTLINE(readability-named-parameter)
|
||||
[[nodiscard]] std::vector<any_type> resolve_types(type_list<Ts...>) {
|
||||
return { resolve_type<Ts>()... };
|
||||
}
|
||||
}
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < typename T >
|
||||
[[nodiscard]] any_type resolve_polymorphic_type(T&& v) noexcept {
|
||||
type_registry& registry = type_registry::instance();
|
||||
return registry.get_type_by_rtti(typeid(v));
|
||||
}
|
||||
}
|
||||
@@ -6,8 +6,17 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../meta_base.hpp"
|
||||
#include "../meta_traits.hpp"
|
||||
#include "../../meta_base.hpp"
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
enum class array_flags : std::uint32_t {
|
||||
is_bounded = 1 << 0,
|
||||
is_unbounded = 1 << 1,
|
||||
};
|
||||
|
||||
ENUM_HPP_OPERATORS_DECL(array_flags)
|
||||
}
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
@@ -6,8 +6,20 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../meta_base.hpp"
|
||||
#include "../meta_traits.hpp"
|
||||
#include "../../meta_base.hpp"
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
enum class class_flags : std::uint32_t {
|
||||
is_empty = 1 << 0,
|
||||
is_final = 1 << 1,
|
||||
is_abstract = 1 << 2,
|
||||
is_polymorphic = 1 << 3,
|
||||
is_template_instantiation = 1 << 4,
|
||||
};
|
||||
|
||||
ENUM_HPP_OPERATORS_DECL(class_flags)
|
||||
}
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
@@ -22,10 +34,6 @@ namespace meta_hpp::detail
|
||||
[[nodiscard]] static constexpr bitflags<class_flags> make_flags() noexcept {
|
||||
return {};
|
||||
}
|
||||
|
||||
[[nodiscard]] static std::vector<any_type> make_argument_types() {
|
||||
return {};
|
||||
}
|
||||
};
|
||||
|
||||
template < template < typename... > typename Class, typename... Args >
|
||||
@@ -37,10 +45,6 @@ namespace meta_hpp::detail
|
||||
[[nodiscard]] static constexpr bitflags<class_flags> make_flags() noexcept {
|
||||
return class_flags::is_template_instantiation;
|
||||
}
|
||||
|
||||
[[nodiscard]] static std::vector<any_type> make_argument_types() {
|
||||
return { resolve_type<Args>()... };
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -6,8 +6,16 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../meta_base.hpp"
|
||||
#include "../meta_traits.hpp"
|
||||
#include "../../meta_base.hpp"
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
enum class ctor_flags : std::uint32_t {
|
||||
is_noexcept = 1 << 0,
|
||||
};
|
||||
|
||||
ENUM_HPP_OPERATORS_DECL(ctor_flags)
|
||||
}
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
@@ -27,9 +35,5 @@ namespace meta_hpp::detail
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
[[nodiscard]] static std::vector<any_type> make_argument_types() {
|
||||
return { resolve_type<Args>()... };
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -6,8 +6,16 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../meta_base.hpp"
|
||||
#include "../meta_traits.hpp"
|
||||
#include "../../meta_base.hpp"
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
enum class dtor_flags : std::uint32_t {
|
||||
is_noexcept = 1 << 0,
|
||||
};
|
||||
|
||||
ENUM_HPP_OPERATORS_DECL(dtor_flags)
|
||||
}
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
@@ -6,8 +6,16 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../meta_base.hpp"
|
||||
#include "../meta_traits.hpp"
|
||||
#include "../../meta_base.hpp"
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
enum class enum_flags : std::uint32_t {
|
||||
is_scoped = 1 << 0,
|
||||
};
|
||||
|
||||
ENUM_HPP_OPERATORS_DECL(enum_flags)
|
||||
}
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
@@ -6,8 +6,16 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../meta_base.hpp"
|
||||
#include "../meta_traits.hpp"
|
||||
#include "../../meta_base.hpp"
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
enum class function_flags : std::uint32_t {
|
||||
is_noexcept = 1 << 0,
|
||||
};
|
||||
|
||||
ENUM_HPP_OPERATORS_DECL(function_flags)
|
||||
}
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
@@ -24,10 +32,6 @@ namespace meta_hpp::detail
|
||||
[[nodiscard]] static constexpr bitflags<function_flags> make_flags() noexcept {
|
||||
return {};
|
||||
}
|
||||
|
||||
[[nodiscard]] static std::vector<any_type> make_argument_types() {
|
||||
return { resolve_type<Args>()... };
|
||||
}
|
||||
};
|
||||
|
||||
template < typename R, typename... Args >
|
||||
@@ -6,8 +6,16 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../meta_base.hpp"
|
||||
#include "../meta_traits.hpp"
|
||||
#include "../../meta_base.hpp"
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
enum class member_flags : std::uint32_t {
|
||||
is_readonly = 1 << 0,
|
||||
};
|
||||
|
||||
ENUM_HPP_OPERATORS_DECL(member_flags)
|
||||
}
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
@@ -6,8 +6,19 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../meta_base.hpp"
|
||||
#include "../meta_traits.hpp"
|
||||
#include "../../meta_base.hpp"
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
enum class method_flags : std::uint32_t {
|
||||
is_const = 1 << 0,
|
||||
is_noexcept = 1 << 1,
|
||||
is_lvalue_qualified = 1 << 2,
|
||||
is_rvalue_qualified = 1 << 3,
|
||||
};
|
||||
|
||||
ENUM_HPP_OPERATORS_DECL(method_flags)
|
||||
}
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
@@ -26,10 +37,6 @@ namespace meta_hpp::detail
|
||||
[[nodiscard]] static constexpr bitflags<method_flags> make_flags() noexcept {
|
||||
return {};
|
||||
}
|
||||
|
||||
[[nodiscard]] static std::vector<any_type> make_argument_types() {
|
||||
return { resolve_type<Args>()... };
|
||||
}
|
||||
};
|
||||
|
||||
template < typename R, typename C, typename... Args >
|
||||
@@ -6,8 +6,19 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../meta_base.hpp"
|
||||
#include "../meta_traits.hpp"
|
||||
#include "../../meta_base.hpp"
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
enum class number_flags : std::uint32_t {
|
||||
is_signed = 1 << 0,
|
||||
is_unsigned = 1 << 1,
|
||||
is_integral = 1 << 2,
|
||||
is_floating_point = 1 << 3,
|
||||
};
|
||||
|
||||
ENUM_HPP_OPERATORS_DECL(number_flags)
|
||||
}
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
@@ -6,8 +6,16 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../meta_base.hpp"
|
||||
#include "../meta_traits.hpp"
|
||||
#include "../../meta_base.hpp"
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
enum class pointer_flags : std::uint32_t {
|
||||
is_readonly = 1 << 0,
|
||||
};
|
||||
|
||||
ENUM_HPP_OPERATORS_DECL(pointer_flags)
|
||||
}
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
@@ -6,8 +6,18 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../meta_base.hpp"
|
||||
#include "../meta_traits.hpp"
|
||||
#include "../../meta_base.hpp"
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
enum class reference_flags : std::uint32_t {
|
||||
is_readonly = 1 << 0,
|
||||
is_lvalue = 1 << 1,
|
||||
is_rvalue = 1 << 2,
|
||||
};
|
||||
|
||||
ENUM_HPP_OPERATORS_DECL(reference_flags)
|
||||
}
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
@@ -7,44 +7,44 @@
|
||||
#pragma once
|
||||
|
||||
#include "../../meta_base.hpp"
|
||||
#include "../../meta_utilities.hpp"
|
||||
#include "../../meta_value.hpp"
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < typename T >
|
||||
struct value_deref_traits;
|
||||
struct deref_traits;
|
||||
|
||||
template < typename T >
|
||||
concept has_value_deref_traits = requires(const T& v) {
|
||||
{ value_deref_traits<T>{}(v) } -> stdex::convertible_to<value>;
|
||||
concept has_deref_traits = requires(const T& v) {
|
||||
{ deref_traits<T>{}(v) } -> stdex::convertible_to<value>;
|
||||
};
|
||||
}
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < stdex::copy_constructible T >
|
||||
struct value_deref_traits<T*> {
|
||||
struct deref_traits<T*> {
|
||||
value operator()(T* v) const {
|
||||
return value{*v};
|
||||
}
|
||||
};
|
||||
|
||||
template < stdex::copy_constructible T >
|
||||
struct value_deref_traits<const T*> {
|
||||
struct deref_traits<const T*> {
|
||||
value operator()(const T* v) const {
|
||||
return value{*v};
|
||||
}
|
||||
};
|
||||
|
||||
template < stdex::copy_constructible T >
|
||||
struct value_deref_traits<std::shared_ptr<T>> {
|
||||
struct deref_traits<std::shared_ptr<T>> {
|
||||
value operator()(const std::shared_ptr<T>& v) const {
|
||||
return value{*v};
|
||||
}
|
||||
};
|
||||
|
||||
template < stdex::copy_constructible T >
|
||||
struct value_deref_traits<std::unique_ptr<T>> {
|
||||
struct deref_traits<std::unique_ptr<T>> {
|
||||
value operator()(const std::unique_ptr<T>& v) const {
|
||||
return value{*v};
|
||||
}
|
||||
@@ -7,16 +7,16 @@
|
||||
#pragma once
|
||||
|
||||
#include "../../meta_base.hpp"
|
||||
#include "../../meta_utilities.hpp"
|
||||
#include "../../meta_value.hpp"
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < typename T >
|
||||
struct value_equals_traits;
|
||||
struct equals_traits;
|
||||
|
||||
template < typename T >
|
||||
concept has_value_equals_traits = requires(const T& l, const T& r) {
|
||||
{ value_equals_traits<T>{}(l, r) } -> stdex::convertible_to<bool>;
|
||||
concept has_equals_traits = requires(const T& l, const T& r) {
|
||||
{ equals_traits<T>{}(l, r) } -> stdex::convertible_to<bool>;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace meta_hpp::detail
|
||||
requires requires(const T& l, const T& r) {
|
||||
{ l == r } -> stdex::convertible_to<bool>;
|
||||
}
|
||||
struct value_equals_traits<T> {
|
||||
struct equals_traits<T> {
|
||||
bool operator()(const T& l, const T& r) const {
|
||||
return l == r;
|
||||
}
|
||||
@@ -7,58 +7,58 @@
|
||||
#pragma once
|
||||
|
||||
#include "../../meta_base.hpp"
|
||||
#include "../../meta_utilities.hpp"
|
||||
#include "../../meta_value.hpp"
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < typename T >
|
||||
struct value_index_traits;
|
||||
struct index_traits;
|
||||
|
||||
template < typename T >
|
||||
concept has_value_index_traits = requires(const T& v, std::size_t i) {
|
||||
{ value_index_traits<T>{}(v, i) } -> stdex::convertible_to<value>;
|
||||
concept has_index_traits = requires(const T& v, std::size_t i) {
|
||||
{ index_traits<T>{}(v, i) } -> stdex::convertible_to<value>;
|
||||
};
|
||||
}
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < stdex::copy_constructible T >
|
||||
struct value_index_traits<T*> {
|
||||
struct index_traits<T*> {
|
||||
value operator()(T* v, std::size_t i) const {
|
||||
return value{*(v + i)};
|
||||
}
|
||||
};
|
||||
|
||||
template < stdex::copy_constructible T >
|
||||
struct value_index_traits<const T*> {
|
||||
struct index_traits<const T*> {
|
||||
value operator()(const T* v, std::size_t i) const {
|
||||
return value{*(v + i)};
|
||||
}
|
||||
};
|
||||
|
||||
template < stdex::copy_constructible T, std::size_t Size >
|
||||
struct value_index_traits<std::array<T, Size>> {
|
||||
struct index_traits<std::array<T, Size>> {
|
||||
value operator()(const std::array<T, Size>& v, std::size_t i) const {
|
||||
return value{v[i]};
|
||||
}
|
||||
};
|
||||
|
||||
template < stdex::copy_constructible T, std::size_t Extent >
|
||||
struct value_index_traits<std::span<T, Extent>> {
|
||||
struct index_traits<std::span<T, Extent>> {
|
||||
value operator()(const std::span<T, Extent>& v, std::size_t i) const {
|
||||
return value{v[i]};
|
||||
}
|
||||
};
|
||||
|
||||
template < stdex::copy_constructible T, typename Traits, typename Allocator >
|
||||
struct value_index_traits<std::basic_string<T, Traits, Allocator>> {
|
||||
struct index_traits<std::basic_string<T, Traits, Allocator>> {
|
||||
value operator()(const std::basic_string<T, Traits, Allocator>& v, std::size_t i) const {
|
||||
return value{v[i]};
|
||||
}
|
||||
};
|
||||
|
||||
template < stdex::copy_constructible T, typename Allocator >
|
||||
struct value_index_traits<std::vector<T, Allocator>> {
|
||||
struct index_traits<std::vector<T, Allocator>> {
|
||||
value operator()(const std::vector<T, Allocator>& v, std::size_t i) {
|
||||
return value{v[i]};
|
||||
}
|
||||
@@ -7,16 +7,16 @@
|
||||
#pragma once
|
||||
|
||||
#include "../../meta_base.hpp"
|
||||
#include "../../meta_utilities.hpp"
|
||||
#include "../../meta_value.hpp"
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < typename T >
|
||||
struct value_istream_traits;
|
||||
struct istream_traits;
|
||||
|
||||
template < typename T >
|
||||
concept has_value_istream_traits = requires(std::istream& is, T& v) {
|
||||
{ value_istream_traits<T>{}(is, v) } -> stdex::convertible_to<std::istream&>;
|
||||
concept has_istream_traits = requires(std::istream& is, T& v) {
|
||||
{ istream_traits<T>{}(is, v) } -> stdex::convertible_to<std::istream&>;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace meta_hpp::detail
|
||||
requires requires(std::istream& is, T& v) {
|
||||
{ is >> v } -> stdex::convertible_to<std::istream&>;
|
||||
}
|
||||
struct value_istream_traits<T> {
|
||||
struct istream_traits<T> {
|
||||
std::istream& operator()(std::istream& is, T& v) const {
|
||||
return is >> v;
|
||||
}
|
||||
@@ -7,16 +7,16 @@
|
||||
#pragma once
|
||||
|
||||
#include "../../meta_base.hpp"
|
||||
#include "../../meta_utilities.hpp"
|
||||
#include "../../meta_value.hpp"
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < typename T >
|
||||
struct value_less_traits;
|
||||
struct less_traits;
|
||||
|
||||
template < typename T >
|
||||
concept has_value_less_traits = requires(const T& l, const T& r) {
|
||||
{ value_less_traits<T>{}(l, r) } -> stdex::convertible_to<bool>;
|
||||
concept has_less_traits = requires(const T& l, const T& r) {
|
||||
{ less_traits<T>{}(l, r) } -> stdex::convertible_to<bool>;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace meta_hpp::detail
|
||||
requires requires(const T& l, const T& r) {
|
||||
{ l < r } -> stdex::convertible_to<bool>;
|
||||
}
|
||||
struct value_less_traits<T> {
|
||||
struct less_traits<T> {
|
||||
bool operator()(const T& l, const T& r) const {
|
||||
return l < r;
|
||||
}
|
||||
@@ -7,16 +7,16 @@
|
||||
#pragma once
|
||||
|
||||
#include "../../meta_base.hpp"
|
||||
#include "../../meta_utilities.hpp"
|
||||
#include "../../meta_value.hpp"
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < typename T >
|
||||
struct value_ostream_traits;
|
||||
struct ostream_traits;
|
||||
|
||||
template < typename T >
|
||||
concept has_value_ostream_traits = requires(std::ostream& os, const T& v) {
|
||||
{ value_ostream_traits<T>{}(os, v) } -> stdex::convertible_to<std::ostream&>;
|
||||
concept has_ostream_traits = requires(std::ostream& os, const T& v) {
|
||||
{ ostream_traits<T>{}(os, v) } -> stdex::convertible_to<std::ostream&>;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace meta_hpp::detail
|
||||
requires requires(std::ostream& os, const T& v) {
|
||||
{ os << v } -> stdex::convertible_to<std::ostream&>;
|
||||
}
|
||||
struct value_ostream_traits<T> {
|
||||
struct ostream_traits<T> {
|
||||
std::ostream& operator()(std::ostream& os, const T& v) const {
|
||||
return os << v;
|
||||
}
|
||||
@@ -6,76 +6,140 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../meta_base.hpp"
|
||||
#include "../meta_utilities.hpp"
|
||||
#include "../../meta_base.hpp"
|
||||
#include "../../meta_value.hpp"
|
||||
|
||||
#include "utraits.hpp"
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < decay_value_kind T >
|
||||
// NOLINTNEXTLINE(readability-named-parameter)
|
||||
arg_base::arg_base(T&&)
|
||||
: arg_base{type_list<T&&>{}} {}
|
||||
class arg_base {
|
||||
public:
|
||||
enum class ref_types {
|
||||
lvalue,
|
||||
const_lvalue,
|
||||
rvalue,
|
||||
const_rvalue,
|
||||
};
|
||||
public:
|
||||
arg_base() = delete;
|
||||
|
||||
template < decay_non_uvalue_kind T >
|
||||
// NOLINTNEXTLINE(readability-named-parameter)
|
||||
arg_base::arg_base(T&&)
|
||||
: arg_base{type_list<T&&>{}} {}
|
||||
arg_base(arg_base&&) = default;
|
||||
arg_base(const arg_base&) = default;
|
||||
|
||||
template < arg_lvalue_ref_kind T >
|
||||
// NOLINTNEXTLINE(readability-named-parameter)
|
||||
arg_base::arg_base(type_list<T>)
|
||||
: ref_type_{std::is_const_v<std::remove_reference_t<T>>
|
||||
? ref_types::const_lvalue
|
||||
: ref_types::lvalue}
|
||||
, raw_type_{resolve_type<std::remove_cvref_t<T>>()} {}
|
||||
arg_base& operator=(arg_base&&) = delete;
|
||||
arg_base& operator=(const arg_base&) = delete;
|
||||
|
||||
template < arg_rvalue_ref_kind T >
|
||||
// NOLINTNEXTLINE(readability-named-parameter)
|
||||
arg_base::arg_base(type_list<T>)
|
||||
: ref_type_{std::is_const_v<std::remove_reference_t<T>>
|
||||
? ref_types::const_rvalue
|
||||
: ref_types::rvalue}
|
||||
, raw_type_{resolve_type<std::remove_cvref_t<T>>()} {}
|
||||
virtual ~arg_base() = default;
|
||||
|
||||
inline arg_base::arg_base(value& v)
|
||||
: ref_type_{ref_types::lvalue}
|
||||
, raw_type_{v.get_type()} {}
|
||||
template < decay_value_kind T >
|
||||
// NOLINTNEXTLINE(readability-named-parameter)
|
||||
explicit arg_base(T&&)
|
||||
: arg_base{type_list<T&&>{}} {}
|
||||
|
||||
inline arg_base::arg_base(const value& v)
|
||||
: ref_type_{ref_types::const_lvalue}
|
||||
, raw_type_{v.get_type()} {}
|
||||
template < decay_non_uvalue_kind T >
|
||||
// NOLINTNEXTLINE(readability-named-parameter)
|
||||
explicit arg_base(T&&)
|
||||
: arg_base{type_list<T&&>{}} {}
|
||||
|
||||
inline arg_base::arg_base(value&& v)
|
||||
: ref_type_{ref_types::rvalue}
|
||||
, raw_type_{v.get_type()} {}
|
||||
template < arg_lvalue_ref_kind T >
|
||||
// NOLINTNEXTLINE(readability-named-parameter)
|
||||
explicit arg_base(type_list<T>)
|
||||
: ref_type_{std::is_const_v<std::remove_reference_t<T>>
|
||||
? ref_types::const_lvalue
|
||||
: ref_types::lvalue}
|
||||
, raw_type_{resolve_type<std::remove_cvref_t<T>>()} {}
|
||||
|
||||
inline arg_base::arg_base(const value&& v)
|
||||
: ref_type_{ref_types::const_rvalue}
|
||||
, raw_type_{v.get_type()} {}
|
||||
template < arg_rvalue_ref_kind T >
|
||||
// NOLINTNEXTLINE(readability-named-parameter)
|
||||
explicit arg_base(type_list<T>)
|
||||
: ref_type_{std::is_const_v<std::remove_reference_t<T>>
|
||||
? ref_types::const_rvalue
|
||||
: ref_types::rvalue}
|
||||
, raw_type_{resolve_type<std::remove_cvref_t<T>>()} {}
|
||||
|
||||
inline bool arg_base::is_const() const noexcept {
|
||||
return ref_type_ == ref_types::const_lvalue
|
||||
|| ref_type_ == ref_types::const_rvalue;
|
||||
}
|
||||
explicit arg_base(value& v)
|
||||
: ref_type_{ref_types::lvalue}
|
||||
, raw_type_{v.get_type()} {}
|
||||
|
||||
inline bool arg_base::is_lvalue() const noexcept {
|
||||
return ref_type_ == ref_types::lvalue
|
||||
|| ref_type_ == ref_types::const_lvalue;
|
||||
}
|
||||
explicit arg_base(const value& v)
|
||||
: ref_type_{ref_types::const_lvalue}
|
||||
, raw_type_{v.get_type()} {}
|
||||
|
||||
inline bool arg_base::is_rvalue() const noexcept {
|
||||
return ref_type_ == ref_types::rvalue
|
||||
|| ref_type_ == ref_types::const_rvalue;
|
||||
}
|
||||
explicit arg_base(value&& v)
|
||||
: ref_type_{ref_types::rvalue}
|
||||
, raw_type_{v.get_type()} {}
|
||||
|
||||
inline arg_base::ref_types arg_base::get_ref_type() const noexcept {
|
||||
return ref_type_;
|
||||
}
|
||||
explicit arg_base(const value&& v)
|
||||
: ref_type_{ref_types::const_rvalue}
|
||||
, raw_type_{v.get_type()} {}
|
||||
|
||||
inline const any_type& arg_base::get_raw_type() const noexcept {
|
||||
return raw_type_;
|
||||
}
|
||||
[[nodiscard]] bool is_const() const noexcept {
|
||||
return ref_type_ == ref_types::const_lvalue
|
||||
|| ref_type_ == ref_types::const_rvalue;
|
||||
}
|
||||
|
||||
[[nodiscard]] bool is_lvalue() const noexcept {
|
||||
return ref_type_ == ref_types::lvalue
|
||||
|| ref_type_ == ref_types::const_lvalue;
|
||||
}
|
||||
|
||||
[[nodiscard]] bool is_rvalue() const noexcept {
|
||||
return ref_type_ == ref_types::rvalue
|
||||
|| ref_type_ == ref_types::const_rvalue;
|
||||
}
|
||||
|
||||
[[nodiscard]] ref_types get_ref_type() const noexcept {
|
||||
return ref_type_;
|
||||
}
|
||||
|
||||
[[nodiscard]] const any_type& get_raw_type() const noexcept {
|
||||
return raw_type_;
|
||||
}
|
||||
|
||||
template < typename To >
|
||||
[[nodiscard]] bool can_cast_to() const noexcept;
|
||||
private:
|
||||
ref_types ref_type_{};
|
||||
any_type raw_type_{};
|
||||
};
|
||||
}
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
class arg final : public arg_base {
|
||||
public:
|
||||
arg() = delete;
|
||||
|
||||
arg(arg&&) = default;
|
||||
arg(const arg&) = default;
|
||||
|
||||
arg& operator=(arg&&) = delete;
|
||||
arg& operator=(const arg&) = delete;
|
||||
|
||||
~arg() override = default;
|
||||
|
||||
template < decay_value_kind T >
|
||||
explicit arg(T&& v)
|
||||
: arg_base{std::forward<T>(v)}
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast)
|
||||
, data_{const_cast<void*>(v.data())} {}
|
||||
|
||||
template < decay_non_uvalue_kind T >
|
||||
explicit arg(T&& v)
|
||||
: arg_base{std::forward<T>(v)}
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast)
|
||||
, data_{const_cast<std::remove_cvref_t<T>*>(std::addressof(v))} {}
|
||||
|
||||
template < typename To >
|
||||
[[nodiscard]] To cast() const;
|
||||
private:
|
||||
void* data_{};
|
||||
};
|
||||
}
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < typename To >
|
||||
// NOLINTNEXTLINE(readability-function-cognitive-complexity)
|
||||
bool arg_base::can_cast_to() const noexcept {
|
||||
@@ -182,18 +246,6 @@ namespace meta_hpp::detail
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < decay_value_kind T >
|
||||
arg::arg(T&& v)
|
||||
: arg_base{std::forward<T>(v)}
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast)
|
||||
, data_{const_cast<void*>(v.data())} {}
|
||||
|
||||
template < decay_non_uvalue_kind T >
|
||||
arg::arg(T&& v)
|
||||
: arg_base{std::forward<T>(v)}
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast)
|
||||
, data_{const_cast<std::remove_cvref_t<T>*>(std::addressof(v))} {}
|
||||
|
||||
template < typename To >
|
||||
// NOLINTNEXTLINE(readability-function-cognitive-complexity)
|
||||
To arg::cast() const {
|
||||
@@ -227,7 +279,7 @@ namespace meta_hpp::detail
|
||||
const class_type& to_data_class = to_data_type.as_class();
|
||||
const class_type& from_data_class = from_data_type.as_class();
|
||||
|
||||
void* to_ptr = detail::pointer_upcast(data_, from_data_class, to_data_class);
|
||||
void* to_ptr = pointer_upcast(data_, from_data_class, to_data_class);
|
||||
return static_cast<to_raw_type_cv>(to_ptr);
|
||||
}
|
||||
}
|
||||
@@ -249,7 +301,7 @@ namespace meta_hpp::detail
|
||||
const class_type& to_data_class = to_data_type.as_class();
|
||||
const class_type& from_data_class = from_data_type.as_class();
|
||||
|
||||
void* to_ptr = detail::pointer_upcast(*from_data_ptr, from_data_class, to_data_class);
|
||||
void* to_ptr = pointer_upcast(*from_data_ptr, from_data_class, to_data_class);
|
||||
return static_cast<to_raw_type_cv>(to_ptr);
|
||||
}
|
||||
}
|
||||
@@ -270,7 +322,7 @@ namespace meta_hpp::detail
|
||||
const class_type& to_class = to_type.as_class();
|
||||
const class_type& from_class = from_type.as_class();
|
||||
|
||||
void* to_ptr = detail::pointer_upcast(data_, from_class, to_class);
|
||||
void* to_ptr = pointer_upcast(data_, from_class, to_class);
|
||||
|
||||
if constexpr ( std::is_lvalue_reference_v<To> ) {
|
||||
return *static_cast<to_raw_type_cv*>(to_ptr);
|
||||
210
headers/meta.hpp/meta_detail/value_utilities/inst.hpp
Normal file
210
headers/meta.hpp/meta_detail/value_utilities/inst.hpp
Normal file
@@ -0,0 +1,210 @@
|
||||
/*******************************************************************************
|
||||
* 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, by Matvey Cherevko (blackmatov@gmail.com)
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../../meta_base.hpp"
|
||||
#include "../../meta_value.hpp"
|
||||
|
||||
#include "utraits.hpp"
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
class inst_base {
|
||||
public:
|
||||
enum class ref_types {
|
||||
lvalue,
|
||||
const_lvalue,
|
||||
rvalue,
|
||||
const_rvalue,
|
||||
};
|
||||
public:
|
||||
inst_base() = delete;
|
||||
|
||||
inst_base(inst_base&&) = default;
|
||||
inst_base(const inst_base&) = default;
|
||||
|
||||
inst_base& operator=(inst_base&&) = delete;
|
||||
inst_base& operator=(const inst_base&) = delete;
|
||||
|
||||
virtual ~inst_base() = default;
|
||||
|
||||
template < decay_value_kind T >
|
||||
// NOLINTNEXTLINE(readability-named-parameter)
|
||||
explicit inst_base(T&&)
|
||||
: inst_base{type_list<T&&>{}} {}
|
||||
|
||||
template < decay_non_uvalue_kind T >
|
||||
// NOLINTNEXTLINE(readability-named-parameter)
|
||||
explicit inst_base(T&&)
|
||||
: inst_base{type_list<T&&>{}} {}
|
||||
|
||||
template < inst_class_lvalue_ref_kind T >
|
||||
// NOLINTNEXTLINE(readability-named-parameter)
|
||||
explicit inst_base(type_list<T>)
|
||||
: ref_type_{std::is_const_v<std::remove_reference_t<T>>
|
||||
? ref_types::const_lvalue
|
||||
: ref_types::lvalue}
|
||||
, raw_type_{resolve_type<std::remove_cvref_t<T>>()} {}
|
||||
|
||||
template < inst_class_rvalue_ref_kind T >
|
||||
// NOLINTNEXTLINE(readability-named-parameter)
|
||||
explicit inst_base(type_list<T>)
|
||||
: ref_type_{std::is_const_v<std::remove_reference_t<T>>
|
||||
? ref_types::const_rvalue
|
||||
: ref_types::rvalue}
|
||||
, raw_type_{resolve_type<std::remove_cvref_t<T>>()} {}
|
||||
|
||||
explicit inst_base(value& v)
|
||||
: ref_type_{ref_types::lvalue}
|
||||
, raw_type_{v.get_type()} {}
|
||||
|
||||
explicit inst_base(const value& v)
|
||||
: ref_type_{ref_types::const_lvalue}
|
||||
, raw_type_{v.get_type()} {}
|
||||
|
||||
explicit inst_base(value&& v)
|
||||
: ref_type_{ref_types::rvalue}
|
||||
, raw_type_{v.get_type()} {}
|
||||
|
||||
explicit inst_base(const value&& v)
|
||||
: ref_type_{ref_types::const_rvalue}
|
||||
, raw_type_{v.get_type()} {}
|
||||
|
||||
[[nodiscard]] bool is_const() const noexcept {
|
||||
return ref_type_ == ref_types::const_lvalue
|
||||
|| ref_type_ == ref_types::const_rvalue;
|
||||
}
|
||||
|
||||
[[nodiscard]] bool is_lvalue() const noexcept {
|
||||
return ref_type_ == ref_types::lvalue
|
||||
|| ref_type_ == ref_types::const_lvalue;
|
||||
}
|
||||
|
||||
[[nodiscard]] bool is_rvalue() const noexcept {
|
||||
return ref_type_ == ref_types::rvalue
|
||||
|| ref_type_ == ref_types::const_rvalue;
|
||||
}
|
||||
|
||||
[[nodiscard]] ref_types get_ref_type() const noexcept {
|
||||
return ref_type_;
|
||||
}
|
||||
|
||||
[[nodiscard]] const any_type& get_raw_type() const noexcept {
|
||||
return raw_type_;
|
||||
}
|
||||
|
||||
template < inst_class_ref_kind Q >
|
||||
[[nodiscard]] bool can_cast_to() const noexcept;
|
||||
private:
|
||||
ref_types ref_type_{};
|
||||
any_type raw_type_{};
|
||||
};
|
||||
}
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
class inst final : public inst_base {
|
||||
public:
|
||||
inst() = delete;
|
||||
|
||||
inst(inst&&) = default;
|
||||
inst(const inst&) = default;
|
||||
|
||||
inst& operator=(inst&&) = delete;
|
||||
inst& operator=(const inst&) = delete;
|
||||
|
||||
~inst() override = default;
|
||||
|
||||
template < decay_value_kind T >
|
||||
explicit inst(T&& v)
|
||||
: inst_base{std::forward<T>(v)}
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast)
|
||||
, data_{const_cast<void*>(v.data())} {}
|
||||
|
||||
template < decay_non_uvalue_kind T >
|
||||
explicit inst(T&& v)
|
||||
: inst_base{std::forward<T>(v)}
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast)
|
||||
, data_{const_cast<std::remove_cvref_t<T>*>(std::addressof(v))} {}
|
||||
|
||||
template < inst_class_ref_kind Q >
|
||||
[[nodiscard]] decltype(auto) cast() const;
|
||||
private:
|
||||
void* data_{};
|
||||
};
|
||||
}
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < inst_class_ref_kind Q >
|
||||
bool inst_base::can_cast_to() const noexcept {
|
||||
using inst_class = typename inst_traits<Q>::class_type;
|
||||
using inst_method = typename inst_traits<Q>::method_type;
|
||||
|
||||
const any_type& from_type = get_raw_type();
|
||||
const any_type& to_type = resolve_type<inst_class>();
|
||||
|
||||
const auto is_a = [](const any_type& base, const any_type& derived){
|
||||
return (base == derived)
|
||||
|| (base.is_class() && derived.is_class() && base.as_class().is_base_of(derived.as_class()));
|
||||
};
|
||||
|
||||
const auto is_invocable = [this](){
|
||||
switch ( get_ref_type() ) {
|
||||
case ref_types::lvalue:
|
||||
return std::is_invocable_v<inst_method, inst_class&>;
|
||||
case ref_types::const_lvalue:
|
||||
return std::is_invocable_v<inst_method, const inst_class&>;
|
||||
case ref_types::rvalue:
|
||||
return std::is_invocable_v<inst_method, inst_class&&>;
|
||||
case ref_types::const_rvalue:
|
||||
return std::is_invocable_v<inst_method, const inst_class&&>;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
return is_a(to_type, from_type) && is_invocable();
|
||||
}
|
||||
}
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < inst_class_ref_kind Q >
|
||||
decltype(auto) inst::cast() const {
|
||||
if ( !can_cast_to<Q>() ) {
|
||||
throw std::logic_error("bad instance cast");
|
||||
}
|
||||
|
||||
using inst_class_cv = std::remove_reference_t<Q>;
|
||||
using inst_class = std::remove_cv_t<inst_class_cv>;
|
||||
|
||||
const any_type& from_type = get_raw_type();
|
||||
const any_type& to_type = resolve_type<inst_class>();
|
||||
|
||||
if ( from_type.is_class() && to_type.is_class() ) {
|
||||
const class_type& from_class = from_type.as_class();
|
||||
const class_type& to_class = to_type.as_class();
|
||||
|
||||
void* to_ptr = pointer_upcast(data_, from_class, to_class);
|
||||
|
||||
if constexpr ( !std::is_reference_v<Q> ) {
|
||||
return *static_cast<inst_class_cv*>(to_ptr);
|
||||
}
|
||||
|
||||
if constexpr ( std::is_lvalue_reference_v<Q> ) {
|
||||
return *static_cast<inst_class_cv*>(to_ptr);
|
||||
}
|
||||
|
||||
if constexpr ( std::is_rvalue_reference_v<Q> ) {
|
||||
return std::move(*static_cast<inst_class_cv*>(to_ptr));
|
||||
}
|
||||
}
|
||||
|
||||
throw std::logic_error("bad instance cast");
|
||||
}
|
||||
}
|
||||
145
headers/meta.hpp/meta_detail/value_utilities/utraits.hpp
Normal file
145
headers/meta.hpp/meta_detail/value_utilities/utraits.hpp
Normal file
@@ -0,0 +1,145 @@
|
||||
/*******************************************************************************
|
||||
* 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, by Matvey Cherevko (blackmatov@gmail.com)
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../../meta_base.hpp"
|
||||
#include "../../meta_value.hpp"
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < typename T >
|
||||
concept uvalue_kind =
|
||||
stdex::same_as<T, arg_base> ||
|
||||
stdex::same_as<T, arg> ||
|
||||
stdex::same_as<T, inst_base> ||
|
||||
stdex::same_as<T, inst> ||
|
||||
stdex::same_as<T, value>;
|
||||
|
||||
template < typename T >
|
||||
concept decay_uvalue_kind = uvalue_kind<std::decay_t<T>>;
|
||||
|
||||
template < typename T >
|
||||
concept decay_non_uvalue_kind = !decay_uvalue_kind<T>;
|
||||
}
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < typename T >
|
||||
concept arg_lvalue_ref_kind =
|
||||
(decay_non_uvalue_kind<T>) &&
|
||||
(std::is_lvalue_reference_v<T>);
|
||||
|
||||
template < typename T >
|
||||
concept arg_rvalue_ref_kind =
|
||||
(decay_non_uvalue_kind<T>) &&
|
||||
(!std::is_reference_v<T> || std::is_rvalue_reference_v<T>);
|
||||
}
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < typename T >
|
||||
concept inst_class_ref_kind =
|
||||
(std::is_class_v<T>) ||
|
||||
(std::is_reference_v<T> && std::is_class_v<std::remove_reference_t<T>>);
|
||||
|
||||
template < typename T >
|
||||
concept inst_class_lvalue_ref_kind =
|
||||
(decay_non_uvalue_kind<T>) &&
|
||||
(std::is_lvalue_reference_v<T> && std::is_class_v<std::remove_reference_t<T>>);
|
||||
|
||||
template < typename T >
|
||||
concept inst_class_rvalue_ref_kind =
|
||||
(decay_non_uvalue_kind<T>) &&
|
||||
(std::is_class_v<T> || (std::is_rvalue_reference_v<T> && std::is_class_v<std::remove_reference_t<T>>));
|
||||
}
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
namespace impl
|
||||
{
|
||||
template < inst_class_ref_kind Q, bool is_const, bool is_lvalue, bool is_rvalue >
|
||||
struct inst_traits_impl;
|
||||
|
||||
template < inst_class_ref_kind Q >
|
||||
struct inst_traits_impl<Q, false, false, false> {
|
||||
using class_type = std::remove_cvref_t<Q>;
|
||||
using method_type = void(class_type::*)();
|
||||
};
|
||||
|
||||
template < inst_class_ref_kind Q >
|
||||
struct inst_traits_impl<Q, false, true, false> {
|
||||
using class_type = std::remove_cvref_t<Q>;
|
||||
using method_type = void(class_type::*)() &;
|
||||
};
|
||||
|
||||
template < inst_class_ref_kind Q >
|
||||
struct inst_traits_impl<Q, false, false, true> {
|
||||
using class_type = std::remove_cvref_t<Q>;
|
||||
using method_type = void(class_type::*)() &&;
|
||||
};
|
||||
|
||||
template < inst_class_ref_kind Q >
|
||||
struct inst_traits_impl<Q, true, false, false> {
|
||||
using class_type = std::remove_cvref_t<Q>;
|
||||
using method_type = void(class_type::*)() const;
|
||||
};
|
||||
|
||||
template < inst_class_ref_kind Q >
|
||||
struct inst_traits_impl<Q, true, true, false> {
|
||||
using class_type = std::remove_cvref_t<Q>;
|
||||
using method_type = void(class_type::*)() const &;
|
||||
};
|
||||
|
||||
template < inst_class_ref_kind Q >
|
||||
struct inst_traits_impl<Q, true, false, true> {
|
||||
using class_type = std::remove_cvref_t<Q>;
|
||||
using method_type = void(class_type::*)() const &&;
|
||||
};
|
||||
}
|
||||
|
||||
template < inst_class_ref_kind Q >
|
||||
struct inst_traits final : impl::inst_traits_impl<Q,
|
||||
cvref_traits<Q>::is_const,
|
||||
cvref_traits<Q>::is_lvalue,
|
||||
cvref_traits<Q>::is_rvalue> {};
|
||||
}
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
[[nodiscard]] inline void* pointer_upcast(void* ptr, const class_type& from, const class_type& to) {
|
||||
if ( nullptr == ptr || !from || !to ) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if ( from == to ) {
|
||||
return ptr;
|
||||
}
|
||||
|
||||
for ( auto&& [base, base_info] : type_access(from)->bases_info ) {
|
||||
if ( base == to ) {
|
||||
return base_info.upcast(ptr);
|
||||
}
|
||||
|
||||
if ( base.is_derived_from(to) ) {
|
||||
return pointer_upcast(base_info.upcast(ptr), base, to);
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template < class_kind To, class_kind From >
|
||||
[[nodiscard]] To* pointer_upcast(From* ptr) {
|
||||
return static_cast<To*>(pointer_upcast(ptr, resolve_type<From>(), resolve_type<To>()));
|
||||
}
|
||||
|
||||
template < class_kind To, class_kind From >
|
||||
[[nodiscard]] const To* pointer_upcast(const From* ptr) {
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast)
|
||||
return pointer_upcast<To>(const_cast<From*>(ptr));
|
||||
}
|
||||
}
|
||||
150
headers/meta.hpp/meta_indices.hpp
Normal file
150
headers/meta.hpp/meta_indices.hpp
Normal file
@@ -0,0 +1,150 @@
|
||||
/*******************************************************************************
|
||||
* 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, by Matvey Cherevko (blackmatov@gmail.com)
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "meta_base.hpp"
|
||||
#include "meta_types.hpp"
|
||||
|
||||
namespace meta_hpp
|
||||
{
|
||||
class ctor_index final {
|
||||
public:
|
||||
ctor_index() = delete;
|
||||
|
||||
template < detail::class_kind Class, typename... Args >
|
||||
[[nodiscard]] static ctor_index make();
|
||||
|
||||
[[nodiscard]] const ctor_type& get_type() const noexcept;
|
||||
private:
|
||||
explicit ctor_index(ctor_type type);
|
||||
friend bool operator<(const ctor_index& l, const ctor_index& r) noexcept;
|
||||
friend bool operator==(const ctor_index& l, const ctor_index& r) noexcept;
|
||||
private:
|
||||
ctor_type type_;
|
||||
};
|
||||
|
||||
class dtor_index final {
|
||||
public:
|
||||
dtor_index() = delete;
|
||||
|
||||
template < detail::class_kind Class >
|
||||
[[nodiscard]] static dtor_index make();
|
||||
|
||||
[[nodiscard]] const dtor_type& get_type() const noexcept;
|
||||
private:
|
||||
explicit dtor_index(dtor_type type);
|
||||
friend bool operator<(const dtor_index& l, const dtor_index& r) noexcept;
|
||||
friend bool operator==(const dtor_index& l, const dtor_index& r) noexcept;
|
||||
private:
|
||||
dtor_type type_;
|
||||
};
|
||||
|
||||
class evalue_index final {
|
||||
public:
|
||||
evalue_index() = delete;
|
||||
|
||||
template < detail::enum_kind Enum >
|
||||
[[nodiscard]] static evalue_index make(std::string name);
|
||||
|
||||
[[nodiscard]] const enum_type& get_type() const noexcept;
|
||||
[[nodiscard]] const std::string& get_name() const noexcept;
|
||||
private:
|
||||
explicit evalue_index(enum_type type, std::string name);
|
||||
friend bool operator<(const evalue_index& l, const evalue_index& r) noexcept;
|
||||
friend bool operator==(const evalue_index& l, const evalue_index& r) noexcept;
|
||||
private:
|
||||
enum_type type_;
|
||||
std::string name_;
|
||||
};
|
||||
|
||||
class function_index final {
|
||||
public:
|
||||
function_index() = delete;
|
||||
|
||||
template < detail::function_kind Function >
|
||||
[[nodiscard]] static function_index make(std::string name);
|
||||
|
||||
[[nodiscard]] const function_type& get_type() const noexcept;
|
||||
[[nodiscard]] const std::string& get_name() const noexcept;
|
||||
private:
|
||||
explicit function_index(function_type type, std::string name);
|
||||
friend bool operator<(const function_index& l, const function_index& r) noexcept;
|
||||
friend bool operator==(const function_index& l, const function_index& r) noexcept;
|
||||
private:
|
||||
function_type type_;
|
||||
std::string name_;
|
||||
};
|
||||
|
||||
class member_index final {
|
||||
public:
|
||||
member_index() = delete;
|
||||
|
||||
template < detail::member_kind Member >
|
||||
[[nodiscard]] static member_index make(std::string name);
|
||||
|
||||
[[nodiscard]] const member_type& get_type() const noexcept;
|
||||
[[nodiscard]] const std::string& get_name() const noexcept;
|
||||
private:
|
||||
explicit member_index(member_type type, std::string name);
|
||||
friend bool operator<(const member_index& l, const member_index& r) noexcept;
|
||||
friend bool operator==(const member_index& l, const member_index& r) noexcept;
|
||||
private:
|
||||
member_type type_;
|
||||
std::string name_;
|
||||
};
|
||||
|
||||
class method_index final {
|
||||
public:
|
||||
method_index() = delete;
|
||||
|
||||
template < detail::method_kind Method >
|
||||
[[nodiscard]] static method_index make(std::string name);
|
||||
|
||||
[[nodiscard]] const method_type& get_type() const noexcept;
|
||||
[[nodiscard]] const std::string& get_name() const noexcept;
|
||||
private:
|
||||
explicit method_index(method_type type, std::string name);
|
||||
friend bool operator<(const method_index& l, const method_index& r) noexcept;
|
||||
friend bool operator==(const method_index& l, const method_index& r) noexcept;
|
||||
private:
|
||||
method_type type_;
|
||||
std::string name_;
|
||||
};
|
||||
|
||||
class scope_index final {
|
||||
public:
|
||||
scope_index() = delete;
|
||||
|
||||
[[nodiscard]] static scope_index make(std::string name);
|
||||
|
||||
[[nodiscard]] const std::string& get_name() const noexcept;
|
||||
private:
|
||||
explicit scope_index(std::string name);
|
||||
friend bool operator<(const scope_index& l, const scope_index& r) noexcept;
|
||||
friend bool operator==(const scope_index& l, const scope_index& r) noexcept;
|
||||
private:
|
||||
std::string name_;
|
||||
};
|
||||
|
||||
class variable_index final {
|
||||
public:
|
||||
variable_index() = delete;
|
||||
|
||||
template < detail::pointer_kind Pointer >
|
||||
[[nodiscard]] static variable_index make(std::string name);
|
||||
|
||||
[[nodiscard]] const pointer_type& get_type() const noexcept;
|
||||
[[nodiscard]] const std::string& get_name() const noexcept;
|
||||
private:
|
||||
explicit variable_index(pointer_type type, std::string name);
|
||||
friend bool operator<(const variable_index& l, const variable_index& r) noexcept;
|
||||
friend bool operator==(const variable_index& l, const variable_index& r) noexcept;
|
||||
private:
|
||||
pointer_type type_;
|
||||
std::string name_;
|
||||
};
|
||||
}
|
||||
36
headers/meta.hpp/meta_indices/ctor_index.hpp
Normal file
36
headers/meta.hpp/meta_indices/ctor_index.hpp
Normal file
@@ -0,0 +1,36 @@
|
||||
/*******************************************************************************
|
||||
* 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, by Matvey Cherevko (blackmatov@gmail.com)
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../meta_base.hpp"
|
||||
#include "../meta_indices.hpp"
|
||||
#include "../meta_types.hpp"
|
||||
|
||||
#include "../meta_detail/type_registry.hpp"
|
||||
|
||||
namespace meta_hpp
|
||||
{
|
||||
inline ctor_index::ctor_index(ctor_type type)
|
||||
: type_{std::move(type)} {}
|
||||
|
||||
template < detail::class_kind Class, typename... Args >
|
||||
ctor_index ctor_index::make() {
|
||||
return ctor_index{detail::resolve_ctor_type<Class, Args...>()};
|
||||
}
|
||||
|
||||
inline const ctor_type& ctor_index::get_type() const noexcept {
|
||||
return type_;
|
||||
}
|
||||
|
||||
inline bool operator<(const ctor_index& l, const ctor_index& r) noexcept {
|
||||
return l.type_ < r.type_;
|
||||
}
|
||||
|
||||
inline bool operator==(const ctor_index& l, const ctor_index& r) noexcept {
|
||||
return l.type_ == r.type_;
|
||||
}
|
||||
}
|
||||
36
headers/meta.hpp/meta_indices/dtor_index.hpp
Normal file
36
headers/meta.hpp/meta_indices/dtor_index.hpp
Normal file
@@ -0,0 +1,36 @@
|
||||
/*******************************************************************************
|
||||
* 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, by Matvey Cherevko (blackmatov@gmail.com)
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../meta_base.hpp"
|
||||
#include "../meta_indices.hpp"
|
||||
#include "../meta_types.hpp"
|
||||
|
||||
#include "../meta_detail/type_registry.hpp"
|
||||
|
||||
namespace meta_hpp
|
||||
{
|
||||
inline dtor_index::dtor_index(dtor_type type)
|
||||
: type_{std::move(type)} {}
|
||||
|
||||
template < detail::class_kind Class >
|
||||
dtor_index dtor_index::make() {
|
||||
return dtor_index{detail::resolve_dtor_type<Class>()};
|
||||
}
|
||||
|
||||
inline const dtor_type& dtor_index::get_type() const noexcept {
|
||||
return type_;
|
||||
}
|
||||
|
||||
inline bool operator<(const dtor_index& l, const dtor_index& r) noexcept {
|
||||
return l.type_ < r.type_;
|
||||
}
|
||||
|
||||
inline bool operator==(const dtor_index& l, const dtor_index& r) noexcept {
|
||||
return l.type_ == r.type_;
|
||||
}
|
||||
}
|
||||
41
headers/meta.hpp/meta_indices/evalue_index.hpp
Normal file
41
headers/meta.hpp/meta_indices/evalue_index.hpp
Normal file
@@ -0,0 +1,41 @@
|
||||
/*******************************************************************************
|
||||
* 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, by Matvey Cherevko (blackmatov@gmail.com)
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../meta_base.hpp"
|
||||
#include "../meta_indices.hpp"
|
||||
#include "../meta_types.hpp"
|
||||
|
||||
#include "../meta_detail/type_registry.hpp"
|
||||
|
||||
namespace meta_hpp
|
||||
{
|
||||
inline evalue_index::evalue_index(enum_type type, std::string name)
|
||||
: type_{std::move(type)}
|
||||
, name_{std::move(name)} {}
|
||||
|
||||
template < detail::enum_kind Enum >
|
||||
evalue_index evalue_index::make(std::string name) {
|
||||
return evalue_index{detail::resolve_type<Enum>(), std::move(name)};
|
||||
}
|
||||
|
||||
inline const enum_type& evalue_index::get_type() const noexcept {
|
||||
return type_;
|
||||
}
|
||||
|
||||
inline const std::string& evalue_index::get_name() const noexcept {
|
||||
return name_;
|
||||
}
|
||||
|
||||
inline bool operator<(const evalue_index& l, const evalue_index& r) noexcept {
|
||||
return l.type_ < r.type_ || (l.type_ == r.type_ && l.name_ < r.name_);
|
||||
}
|
||||
|
||||
inline bool operator==(const evalue_index& l, const evalue_index& r) noexcept {
|
||||
return l.type_ == r.type_ && l.name_ == r.name_;
|
||||
}
|
||||
}
|
||||
41
headers/meta.hpp/meta_indices/function_index.hpp
Normal file
41
headers/meta.hpp/meta_indices/function_index.hpp
Normal file
@@ -0,0 +1,41 @@
|
||||
/*******************************************************************************
|
||||
* 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, by Matvey Cherevko (blackmatov@gmail.com)
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../meta_base.hpp"
|
||||
#include "../meta_indices.hpp"
|
||||
#include "../meta_types.hpp"
|
||||
|
||||
#include "../meta_detail/type_registry.hpp"
|
||||
|
||||
namespace meta_hpp
|
||||
{
|
||||
inline function_index::function_index(function_type type, std::string name)
|
||||
: type_{std::move(type)}
|
||||
, name_{std::move(name)} {}
|
||||
|
||||
template < detail::function_kind Function >
|
||||
function_index function_index::make(std::string name) {
|
||||
return function_index{detail::resolve_type<Function>(), std::move(name)};
|
||||
}
|
||||
|
||||
inline const function_type& function_index::get_type() const noexcept {
|
||||
return type_;
|
||||
}
|
||||
|
||||
inline const std::string& function_index::get_name() const noexcept {
|
||||
return name_;
|
||||
}
|
||||
|
||||
inline bool operator<(const function_index& l, const function_index& r) noexcept {
|
||||
return l.type_ < r.type_ || (l.type_ == r.type_ && l.name_ < r.name_);
|
||||
}
|
||||
|
||||
inline bool operator==(const function_index& l, const function_index& r) noexcept {
|
||||
return l.type_ == r.type_ && l.name_ == r.name_;
|
||||
}
|
||||
}
|
||||
41
headers/meta.hpp/meta_indices/member_index.hpp
Normal file
41
headers/meta.hpp/meta_indices/member_index.hpp
Normal file
@@ -0,0 +1,41 @@
|
||||
/*******************************************************************************
|
||||
* 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, by Matvey Cherevko (blackmatov@gmail.com)
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../meta_base.hpp"
|
||||
#include "../meta_indices.hpp"
|
||||
#include "../meta_types.hpp"
|
||||
|
||||
#include "../meta_detail/type_registry.hpp"
|
||||
|
||||
namespace meta_hpp
|
||||
{
|
||||
inline member_index::member_index(member_type type, std::string name)
|
||||
: type_{std::move(type)}
|
||||
, name_{std::move(name)} {}
|
||||
|
||||
template < detail::member_kind Member >
|
||||
member_index member_index::make(std::string name) {
|
||||
return member_index{detail::resolve_type<Member>(), std::move(name)};
|
||||
}
|
||||
|
||||
inline const member_type& member_index::get_type() const noexcept {
|
||||
return type_;
|
||||
}
|
||||
|
||||
inline const std::string& member_index::get_name() const noexcept {
|
||||
return name_;
|
||||
}
|
||||
|
||||
inline bool operator<(const member_index& l, const member_index& r) noexcept {
|
||||
return l.type_ < r.type_ || (l.type_ == r.type_ && l.name_ < r.name_);
|
||||
}
|
||||
|
||||
inline bool operator==(const member_index& l, const member_index& r) noexcept {
|
||||
return l.type_ == r.type_ && l.name_ == r.name_;
|
||||
}
|
||||
}
|
||||
41
headers/meta.hpp/meta_indices/method_index.hpp
Normal file
41
headers/meta.hpp/meta_indices/method_index.hpp
Normal file
@@ -0,0 +1,41 @@
|
||||
/*******************************************************************************
|
||||
* 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, by Matvey Cherevko (blackmatov@gmail.com)
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../meta_base.hpp"
|
||||
#include "../meta_indices.hpp"
|
||||
#include "../meta_types.hpp"
|
||||
|
||||
#include "../meta_detail/type_registry.hpp"
|
||||
|
||||
namespace meta_hpp
|
||||
{
|
||||
inline method_index::method_index(method_type type, std::string name)
|
||||
: type_{std::move(type)}
|
||||
, name_{std::move(name)} {}
|
||||
|
||||
template < detail::method_kind Method >
|
||||
method_index method_index::make(std::string name) {
|
||||
return method_index{detail::resolve_type<Method>(), std::move(name)};
|
||||
}
|
||||
|
||||
inline const method_type& method_index::get_type() const noexcept {
|
||||
return type_;
|
||||
}
|
||||
|
||||
inline const std::string& method_index::get_name() const noexcept {
|
||||
return name_;
|
||||
}
|
||||
|
||||
inline bool operator<(const method_index& l, const method_index& r) noexcept {
|
||||
return l.type_ < r.type_ || (l.type_ == r.type_ && l.name_ < r.name_);
|
||||
}
|
||||
|
||||
inline bool operator==(const method_index& l, const method_index& r) noexcept {
|
||||
return l.type_ == r.type_ && l.name_ == r.name_;
|
||||
}
|
||||
}
|
||||
35
headers/meta.hpp/meta_indices/scope_index.hpp
Normal file
35
headers/meta.hpp/meta_indices/scope_index.hpp
Normal file
@@ -0,0 +1,35 @@
|
||||
/*******************************************************************************
|
||||
* 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, by Matvey Cherevko (blackmatov@gmail.com)
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../meta_base.hpp"
|
||||
#include "../meta_indices.hpp"
|
||||
#include "../meta_states.hpp"
|
||||
|
||||
#include "../meta_detail/type_registry.hpp"
|
||||
|
||||
namespace meta_hpp
|
||||
{
|
||||
inline scope_index::scope_index(std::string name)
|
||||
: name_{std::move(name)} {}
|
||||
|
||||
inline scope_index scope_index::make(std::string name) {
|
||||
return scope_index{std::move(name)};
|
||||
}
|
||||
|
||||
inline const std::string& scope_index::get_name() const noexcept {
|
||||
return name_;
|
||||
}
|
||||
|
||||
inline bool operator<(const scope_index& l, const scope_index& r) noexcept {
|
||||
return l.name_ < r.name_;
|
||||
}
|
||||
|
||||
inline bool operator==(const scope_index& l, const scope_index& r) noexcept {
|
||||
return l.name_ == r.name_;
|
||||
}
|
||||
}
|
||||
41
headers/meta.hpp/meta_indices/variable_index.hpp
Normal file
41
headers/meta.hpp/meta_indices/variable_index.hpp
Normal file
@@ -0,0 +1,41 @@
|
||||
/*******************************************************************************
|
||||
* 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, by Matvey Cherevko (blackmatov@gmail.com)
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../meta_base.hpp"
|
||||
#include "../meta_indices.hpp"
|
||||
#include "../meta_types.hpp"
|
||||
|
||||
#include "../meta_detail/type_registry.hpp"
|
||||
|
||||
namespace meta_hpp
|
||||
{
|
||||
inline variable_index::variable_index(pointer_type type, std::string name)
|
||||
: type_{std::move(type)}
|
||||
, name_{std::move(name)} {}
|
||||
|
||||
template < detail::pointer_kind Pointer >
|
||||
variable_index variable_index::make(std::string name) {
|
||||
return variable_index{detail::resolve_type<Pointer>(), std::move(name)};
|
||||
}
|
||||
|
||||
inline const pointer_type& variable_index::get_type() const noexcept {
|
||||
return type_;
|
||||
}
|
||||
|
||||
inline const std::string& variable_index::get_name() const noexcept {
|
||||
return name_;
|
||||
}
|
||||
|
||||
inline bool operator<(const variable_index& l, const variable_index& r) noexcept {
|
||||
return l.type_ < r.type_ || (l.type_ == r.type_ && l.name_ < r.name_);
|
||||
}
|
||||
|
||||
inline bool operator==(const variable_index& l, const variable_index& r) noexcept {
|
||||
return l.type_ == r.type_ && l.name_ == r.name_;
|
||||
}
|
||||
}
|
||||
@@ -7,56 +7,11 @@
|
||||
#pragma once
|
||||
|
||||
#include "meta_base.hpp"
|
||||
#include "meta_indices.hpp"
|
||||
#include "meta_types.hpp"
|
||||
#include "meta_utilities.hpp"
|
||||
#include "meta_value.hpp"
|
||||
|
||||
namespace meta_hpp
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
template < typename T >
|
||||
concept state_family =
|
||||
std::is_same_v<T, ctor> ||
|
||||
std::is_same_v<T, dtor> ||
|
||||
std::is_same_v<T, evalue> ||
|
||||
std::is_same_v<T, function> ||
|
||||
std::is_same_v<T, member> ||
|
||||
std::is_same_v<T, method> ||
|
||||
std::is_same_v<T, scope> ||
|
||||
std::is_same_v<T, variable>;
|
||||
}
|
||||
|
||||
template < detail::state_family T, detail::state_family U >
|
||||
[[nodiscard]] bool operator<(const T& l, const U& r) noexcept {
|
||||
if ( !static_cast<bool>(r) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( !static_cast<bool>(l) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return l.get_index() < r.get_index();
|
||||
}
|
||||
|
||||
template < detail::state_family T, detail::state_family U >
|
||||
[[nodiscard]] bool operator==(const T& l, const U& r) noexcept {
|
||||
if ( static_cast<bool>(l) != static_cast<bool>(r) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( !static_cast<bool>(l) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return l.get_index() == r.get_index();
|
||||
}
|
||||
|
||||
template < detail::state_family T, detail::state_family U >
|
||||
[[nodiscard]] bool operator!=(const T& l, const U& r) noexcept {
|
||||
return !(l == r);
|
||||
}
|
||||
}
|
||||
#include "meta_detail/state_family.hpp"
|
||||
|
||||
namespace meta_hpp
|
||||
{
|
||||
@@ -97,33 +52,33 @@ namespace meta_hpp
|
||||
|
||||
template < typename Policy >
|
||||
concept ctor_policy_kind =
|
||||
detail::stdex::same_as<Policy, ctor_policy::as_object> ||
|
||||
detail::stdex::same_as<Policy, ctor_policy::as_raw_pointer> ||
|
||||
detail::stdex::same_as<Policy, ctor_policy::as_shared_pointer>;
|
||||
stdex::same_as<Policy, ctor_policy::as_object> ||
|
||||
stdex::same_as<Policy, ctor_policy::as_raw_pointer> ||
|
||||
stdex::same_as<Policy, ctor_policy::as_shared_pointer>;
|
||||
|
||||
template < typename Policy >
|
||||
concept function_policy_kind =
|
||||
detail::stdex::same_as<Policy, function_policy::as_copy> ||
|
||||
detail::stdex::same_as<Policy, function_policy::discard_return> ||
|
||||
detail::stdex::same_as<Policy, function_policy::return_reference_as_pointer>;
|
||||
stdex::same_as<Policy, function_policy::as_copy> ||
|
||||
stdex::same_as<Policy, function_policy::discard_return> ||
|
||||
stdex::same_as<Policy, function_policy::return_reference_as_pointer>;
|
||||
|
||||
template < typename Policy >
|
||||
concept member_policy_kind =
|
||||
detail::stdex::same_as<Policy, member_policy::as_copy> ||
|
||||
detail::stdex::same_as<Policy, member_policy::as_pointer> ||
|
||||
detail::stdex::same_as<Policy, member_policy::as_reference_wrapper>;
|
||||
stdex::same_as<Policy, member_policy::as_copy> ||
|
||||
stdex::same_as<Policy, member_policy::as_pointer> ||
|
||||
stdex::same_as<Policy, member_policy::as_reference_wrapper>;
|
||||
|
||||
template < typename Policy >
|
||||
concept method_policy_kind =
|
||||
detail::stdex::same_as<Policy, method_policy::as_copy> ||
|
||||
detail::stdex::same_as<Policy, method_policy::discard_return> ||
|
||||
detail::stdex::same_as<Policy, method_policy::return_reference_as_pointer>;
|
||||
stdex::same_as<Policy, method_policy::as_copy> ||
|
||||
stdex::same_as<Policy, method_policy::discard_return> ||
|
||||
stdex::same_as<Policy, method_policy::return_reference_as_pointer>;
|
||||
|
||||
template < typename Policy >
|
||||
concept variable_policy_kind =
|
||||
detail::stdex::same_as<Policy, variable_policy::as_copy> ||
|
||||
detail::stdex::same_as<Policy, variable_policy::as_pointer> ||
|
||||
detail::stdex::same_as<Policy, variable_policy::as_reference_wrapper>;
|
||||
stdex::same_as<Policy, variable_policy::as_copy> ||
|
||||
stdex::same_as<Policy, variable_policy::as_pointer> ||
|
||||
stdex::same_as<Policy, variable_policy::as_reference_wrapper>;
|
||||
}
|
||||
|
||||
namespace meta_hpp
|
||||
@@ -152,6 +107,7 @@ namespace meta_hpp
|
||||
[[nodiscard]] bool is_invocable_with(Args&&... args) const noexcept;
|
||||
private:
|
||||
detail::ctor_state_ptr state_;
|
||||
friend auto detail::state_access<ctor>(const ctor&);
|
||||
};
|
||||
|
||||
class dtor final {
|
||||
@@ -178,6 +134,7 @@ namespace meta_hpp
|
||||
[[nodiscard]] bool is_invocable_with(Arg&& ptr) const noexcept;
|
||||
private:
|
||||
detail::dtor_state_ptr state_;
|
||||
friend auto detail::state_access<dtor>(const dtor&);
|
||||
};
|
||||
|
||||
class evalue final {
|
||||
@@ -196,6 +153,7 @@ namespace meta_hpp
|
||||
[[nodiscard]] const value& get_underlying_value() const noexcept;
|
||||
private:
|
||||
detail::evalue_state_ptr state_;
|
||||
friend auto detail::state_access<evalue>(const evalue&);
|
||||
};
|
||||
|
||||
class function final {
|
||||
@@ -223,6 +181,7 @@ namespace meta_hpp
|
||||
[[nodiscard]] bool is_invocable_with(Args&&... args) const noexcept;
|
||||
private:
|
||||
detail::function_state_ptr state_;
|
||||
friend auto detail::state_access<function>(const function&);
|
||||
};
|
||||
|
||||
class member final {
|
||||
@@ -262,6 +221,7 @@ namespace meta_hpp
|
||||
[[nodiscard]] bool is_settable_with(Instance&& instance, Value&& value) const noexcept;
|
||||
private:
|
||||
detail::member_state_ptr state_;
|
||||
friend auto detail::state_access<member>(const member&);
|
||||
};
|
||||
|
||||
class method final {
|
||||
@@ -289,6 +249,7 @@ namespace meta_hpp
|
||||
[[nodiscard]] bool is_invocable_with(Instance&& instance, Args&&... args) const noexcept;
|
||||
private:
|
||||
detail::method_state_ptr state_;
|
||||
friend auto detail::state_access<method>(const method&);
|
||||
};
|
||||
|
||||
class scope final {
|
||||
@@ -318,6 +279,7 @@ namespace meta_hpp
|
||||
[[nodiscard]] function get_function_with(std::string_view name, std::initializer_list<any_type> args) const noexcept;
|
||||
private:
|
||||
detail::scope_state_ptr state_;
|
||||
friend auto detail::state_access<scope>(const scope&);
|
||||
};
|
||||
|
||||
class variable final {
|
||||
@@ -349,9 +311,44 @@ namespace meta_hpp
|
||||
[[nodiscard]] bool is_settable_with(Value&& value) const noexcept;
|
||||
private:
|
||||
detail::variable_state_ptr state_;
|
||||
friend auto detail::state_access<variable>(const variable&);
|
||||
};
|
||||
}
|
||||
|
||||
namespace meta_hpp
|
||||
{
|
||||
template < detail::state_family T, detail::state_family U >
|
||||
[[nodiscard]] bool operator<(const T& l, const U& r) noexcept {
|
||||
if ( !static_cast<bool>(r) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( !static_cast<bool>(l) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return l.get_index() < r.get_index();
|
||||
}
|
||||
|
||||
template < detail::state_family T, detail::state_family U >
|
||||
[[nodiscard]] bool operator==(const T& l, const U& r) noexcept {
|
||||
if ( static_cast<bool>(l) != static_cast<bool>(r) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( !static_cast<bool>(l) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return l.get_index() == r.get_index();
|
||||
}
|
||||
|
||||
template < detail::state_family T, detail::state_family U >
|
||||
[[nodiscard]] bool operator!=(const T& l, const U& r) noexcept {
|
||||
return !(l == r);
|
||||
}
|
||||
}
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
struct ctor_state final {
|
||||
@@ -437,7 +434,6 @@ namespace meta_hpp::detail
|
||||
variable_map variables{};
|
||||
|
||||
[[nodiscard]] static scope_state_ptr make(std::string name);
|
||||
[[nodiscard]] static scope_state_ptr get_static(std::string_view name);
|
||||
};
|
||||
|
||||
struct variable_state final {
|
||||
@@ -454,10 +450,3 @@ namespace meta_hpp::detail
|
||||
[[nodiscard]] static variable_state_ptr make(std::string name, Pointer pointer);
|
||||
};
|
||||
}
|
||||
|
||||
namespace meta_hpp
|
||||
{
|
||||
[[nodiscard]] inline scope resolve_scope(std::string_view name) {
|
||||
return scope{detail::scope_state::get_static(name)};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "../meta_states.hpp"
|
||||
|
||||
#include "../meta_types/ctor_type.hpp"
|
||||
#include "../meta_detail/value_utilities/arg.hpp"
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
@@ -95,9 +96,8 @@ namespace meta_hpp::detail
|
||||
{
|
||||
template < ctor_policy_kind Policy, class_kind Class, typename... Args >
|
||||
ctor_state_ptr ctor_state::make() {
|
||||
ctor_index index{ctor_type_data::get_static<Class, Args...>()};
|
||||
return std::make_shared<ctor_state>(ctor_state{
|
||||
.index{std::move(index)},
|
||||
.index{ctor_index::make<Class, Args...>()},
|
||||
.invoke{make_ctor_invoke<Policy, Class, Args...>()},
|
||||
.is_invocable_with{make_ctor_is_invocable_with<Class, Args...>()},
|
||||
});
|
||||
@@ -122,7 +122,7 @@ namespace meta_hpp
|
||||
}
|
||||
|
||||
inline const ctor_type& ctor::get_type() const noexcept {
|
||||
return state_->index.type;
|
||||
return state_->index.get_type();
|
||||
}
|
||||
|
||||
template < typename... Args >
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "../meta_states.hpp"
|
||||
|
||||
#include "../meta_types/dtor_type.hpp"
|
||||
#include "../meta_detail/value_utilities/arg.hpp"
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
@@ -56,9 +57,8 @@ namespace meta_hpp::detail
|
||||
{
|
||||
template < class_kind Class >
|
||||
dtor_state_ptr dtor_state::make() {
|
||||
dtor_index index{dtor_type_data::get_static<Class>()};
|
||||
return std::make_shared<dtor_state>(dtor_state{
|
||||
.index{std::move(index)},
|
||||
.index{dtor_index::make<Class>()},
|
||||
.invoke{make_dtor_invoke<Class>()},
|
||||
.is_invocable_with{make_dtor_is_invocable_with<Class>()},
|
||||
});
|
||||
@@ -83,7 +83,7 @@ namespace meta_hpp
|
||||
}
|
||||
|
||||
inline const dtor_type& dtor::get_type() const noexcept {
|
||||
return state_->index.type;
|
||||
return state_->index.get_type();
|
||||
}
|
||||
|
||||
template < typename Arg >
|
||||
|
||||
@@ -15,9 +15,8 @@ namespace meta_hpp::detail
|
||||
{
|
||||
template < enum_kind Enum >
|
||||
evalue_state_ptr evalue_state::make(std::string name, Enum evalue) {
|
||||
evalue_index index{enum_type_data::get_static<Enum>(), std::move(name)};
|
||||
return std::make_shared<evalue_state>(evalue_state{
|
||||
.index{std::move(index)},
|
||||
.index{evalue_index::make<Enum>(std::move(name))},
|
||||
.enum_value{value{evalue}},
|
||||
.underlying_value{value{stdex::to_underlying(evalue)}},
|
||||
});
|
||||
@@ -42,11 +41,11 @@ namespace meta_hpp
|
||||
}
|
||||
|
||||
inline const enum_type& evalue::get_type() const noexcept {
|
||||
return state_->index.type;
|
||||
return state_->index.get_type();
|
||||
}
|
||||
|
||||
inline const std::string& evalue::get_name() const noexcept {
|
||||
return state_->index.name;
|
||||
return state_->index.get_name();
|
||||
}
|
||||
|
||||
inline const value& evalue::get_value() const noexcept {
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "../meta_states.hpp"
|
||||
|
||||
#include "../meta_types/function_type.hpp"
|
||||
#include "../meta_detail/value_utilities/arg.hpp"
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
@@ -99,9 +100,8 @@ namespace meta_hpp::detail
|
||||
{
|
||||
template < function_policy_kind Policy, function_kind Function >
|
||||
function_state_ptr function_state::make(std::string name, Function function) {
|
||||
function_index index{function_type_data::get_static<Function>(), std::move(name)};
|
||||
return std::make_shared<function_state>(function_state{
|
||||
.index{std::move(index)},
|
||||
.index{function_index::make<Function>(std::move(name))},
|
||||
.invoke{make_function_invoke<Policy>(std::move(function))},
|
||||
.is_invocable_with{make_function_is_invocable_with<Function>()},
|
||||
});
|
||||
@@ -126,11 +126,11 @@ namespace meta_hpp
|
||||
}
|
||||
|
||||
inline const function_type& function::get_type() const noexcept {
|
||||
return state_->index.type;
|
||||
return state_->index.get_type();
|
||||
}
|
||||
|
||||
inline const std::string& function::get_name() const noexcept {
|
||||
return state_->index.name;
|
||||
return state_->index.get_name();
|
||||
}
|
||||
|
||||
template < typename... Args >
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
#include "../meta_states.hpp"
|
||||
|
||||
#include "../meta_types/member_type.hpp"
|
||||
#include "../meta_detail/value_utilities/arg.hpp"
|
||||
#include "../meta_detail/value_utilities/inst.hpp"
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
@@ -146,9 +148,8 @@ namespace meta_hpp::detail
|
||||
{
|
||||
template < member_policy_kind Policy, member_kind Member >
|
||||
member_state_ptr member_state::make(std::string name, Member member) {
|
||||
member_index index{member_type_data::get_static<Member>(), std::move(name)};
|
||||
return std::make_shared<member_state>(member_state{
|
||||
.index{std::move(index)},
|
||||
.index{member_index::make<Member>(std::move(name))},
|
||||
.getter{make_member_getter<Policy>(std::move(member))},
|
||||
.setter{make_member_setter(std::move(member))},
|
||||
.is_gettable_with{make_member_is_gettable_with<Member>()},
|
||||
@@ -175,11 +176,11 @@ namespace meta_hpp
|
||||
}
|
||||
|
||||
inline const member_type& member::get_type() const noexcept {
|
||||
return state_->index.type;
|
||||
return state_->index.get_type();
|
||||
}
|
||||
|
||||
inline const std::string& member::get_name() const noexcept {
|
||||
return state_->index.name;
|
||||
return state_->index.get_name();
|
||||
}
|
||||
|
||||
template < typename Instance >
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
#include "../meta_states.hpp"
|
||||
|
||||
#include "../meta_types/method_type.hpp"
|
||||
#include "../meta_detail/value_utilities/arg.hpp"
|
||||
#include "../meta_detail/value_utilities/inst.hpp"
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
@@ -112,9 +114,8 @@ namespace meta_hpp::detail
|
||||
{
|
||||
template < method_policy_kind Policy, method_kind Method >
|
||||
method_state_ptr method_state::make(std::string name, Method method) {
|
||||
method_index index{method_type_data::get_static<Method>(), std::move(name)};
|
||||
return std::make_shared<method_state>(method_state{
|
||||
.index{std::move(index)},
|
||||
.index{method_index::make<Method>(std::move(name))},
|
||||
.invoke{make_method_invoke<Policy>(std::move(method))},
|
||||
.is_invocable_with{make_method_is_invocable_with<Method>()},
|
||||
});
|
||||
@@ -139,11 +140,11 @@ namespace meta_hpp
|
||||
}
|
||||
|
||||
inline const method_type& method::get_type() const noexcept {
|
||||
return state_->index.type;
|
||||
return state_->index.get_type();
|
||||
}
|
||||
|
||||
inline const std::string& method::get_name() const noexcept {
|
||||
return state_->index.name;
|
||||
return state_->index.get_name();
|
||||
}
|
||||
|
||||
template < typename Instance, typename... Args >
|
||||
|
||||
@@ -8,25 +8,23 @@
|
||||
|
||||
#include "../meta_base.hpp"
|
||||
#include "../meta_states.hpp"
|
||||
#include "../meta_types.hpp"
|
||||
|
||||
#include "../meta_types/class_type.hpp"
|
||||
#include "../meta_types/enum_type.hpp"
|
||||
|
||||
#include "../meta_states/function.hpp"
|
||||
#include "../meta_states/variable.hpp"
|
||||
|
||||
#include "../meta_detail/type_registry.hpp"
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
inline scope_state_ptr scope_state::make(std::string name) {
|
||||
scope_index index{std::move(name)};
|
||||
return std::make_shared<scope_state>(scope_state{
|
||||
.index{std::move(index)},
|
||||
.index{scope_index::make(std::move(name))},
|
||||
});
|
||||
}
|
||||
|
||||
inline scope_state_ptr scope_state::get_static(std::string_view name) {
|
||||
static std::map<std::string, scope_state_ptr, std::less<>> states;
|
||||
|
||||
if ( auto iter = states.find(name); iter != states.end() ) {
|
||||
return iter->second;
|
||||
}
|
||||
|
||||
return states.emplace(std::string{name}, make(std::string{name})).first->second;
|
||||
}
|
||||
}
|
||||
|
||||
namespace meta_hpp
|
||||
@@ -47,7 +45,7 @@ namespace meta_hpp
|
||||
}
|
||||
|
||||
inline const std::string& scope::get_name() const noexcept {
|
||||
return state_->index.name;
|
||||
return state_->index.get_name();
|
||||
}
|
||||
|
||||
inline const class_map& scope::get_classes() const noexcept {
|
||||
@@ -82,7 +80,7 @@ namespace meta_hpp
|
||||
|
||||
inline function scope::get_function(std::string_view name) const noexcept {
|
||||
for ( auto&& [index, function] : state_->functions ) {
|
||||
if ( index.name == name ) {
|
||||
if ( index.get_name() == name ) {
|
||||
return function;
|
||||
}
|
||||
}
|
||||
@@ -91,7 +89,7 @@ namespace meta_hpp
|
||||
|
||||
inline variable scope::get_variable(std::string_view name) const noexcept {
|
||||
for ( auto&& [index, variable] : state_->variables ) {
|
||||
if ( index.name == name ) {
|
||||
if ( index.get_name() == name ) {
|
||||
return variable;
|
||||
}
|
||||
}
|
||||
@@ -100,12 +98,12 @@ namespace meta_hpp
|
||||
|
||||
template < typename... Args >
|
||||
function scope::get_function_with(std::string_view name) const noexcept {
|
||||
return get_function_with(name, {resolve_type<Args>()...});
|
||||
return get_function_with(name, {detail::resolve_type<Args>()...});
|
||||
}
|
||||
|
||||
inline function scope::get_function_with(std::string_view name, const std::vector<any_type>& args) const noexcept {
|
||||
for ( auto&& [index, function] : state_->functions ) {
|
||||
if ( index.name != name ) {
|
||||
if ( index.get_name() != name ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -123,7 +121,7 @@ namespace meta_hpp
|
||||
|
||||
inline function scope::get_function_with(std::string_view name, std::initializer_list<any_type> args) const noexcept {
|
||||
for ( auto&& [index, function] : state_->functions ) {
|
||||
if ( index.name != name ) {
|
||||
if ( index.get_name() != name ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "../meta_states.hpp"
|
||||
|
||||
#include "../meta_types/pointer_type.hpp"
|
||||
#include "../meta_detail/value_utilities/arg.hpp"
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
@@ -95,9 +96,8 @@ namespace meta_hpp::detail
|
||||
{
|
||||
template < variable_policy_kind Policy, pointer_kind Pointer >
|
||||
variable_state_ptr variable_state::make(std::string name, Pointer pointer) {
|
||||
variable_index index{pointer_type_data::get_static<Pointer>(), std::move(name)};
|
||||
return std::make_shared<variable_state>(variable_state{
|
||||
.index{std::move(index)},
|
||||
.index{variable_index::make<Pointer>(std::move(name))},
|
||||
.getter{make_variable_getter<Policy>(std::move(pointer))},
|
||||
.setter{make_variable_setter(std::move(pointer))},
|
||||
.is_settable_with{make_variable_is_settable_with<Pointer>()},
|
||||
@@ -123,11 +123,11 @@ namespace meta_hpp
|
||||
}
|
||||
|
||||
inline const pointer_type& variable::get_type() const noexcept {
|
||||
return state_->index.type;
|
||||
return state_->index.get_type();
|
||||
}
|
||||
|
||||
inline const std::string& variable::get_name() const noexcept {
|
||||
return state_->index.name;
|
||||
return state_->index.get_name();
|
||||
}
|
||||
|
||||
inline value variable::get() const {
|
||||
|
||||
@@ -1,118 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* 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, by Matvey Cherevko (blackmatov@gmail.com)
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "meta_base.hpp"
|
||||
#include "meta_kinds.hpp"
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < array_kind Array >
|
||||
struct array_traits;
|
||||
|
||||
template < class_kind Class >
|
||||
struct class_traits;
|
||||
|
||||
template < class_kind Class, typename... Args >
|
||||
struct ctor_traits;
|
||||
|
||||
template < class_kind Class >
|
||||
struct dtor_traits;
|
||||
|
||||
template < enum_kind Enum >
|
||||
struct enum_traits;
|
||||
|
||||
template < function_kind Function >
|
||||
struct function_traits;
|
||||
|
||||
template < member_kind Member >
|
||||
struct member_traits;
|
||||
|
||||
template < method_kind Method >
|
||||
struct method_traits;
|
||||
|
||||
template < number_kind Number >
|
||||
struct number_traits;
|
||||
|
||||
template < pointer_kind Pointer >
|
||||
struct pointer_traits;
|
||||
|
||||
template < reference_kind Reference >
|
||||
struct reference_traits;
|
||||
}
|
||||
|
||||
namespace meta_hpp
|
||||
{
|
||||
enum class array_flags : std::uint32_t {
|
||||
is_bounded = 1 << 0,
|
||||
is_unbounded = 1 << 1,
|
||||
};
|
||||
|
||||
enum class class_flags : std::uint32_t {
|
||||
is_empty = 1 << 0,
|
||||
is_final = 1 << 1,
|
||||
is_abstract = 1 << 2,
|
||||
is_polymorphic = 1 << 3,
|
||||
is_template_instantiation = 1 << 4,
|
||||
};
|
||||
|
||||
enum class ctor_flags : std::uint32_t {
|
||||
is_noexcept = 1 << 0,
|
||||
};
|
||||
|
||||
enum class dtor_flags : std::uint32_t {
|
||||
is_noexcept = 1 << 0,
|
||||
};
|
||||
|
||||
enum class enum_flags : std::uint32_t {
|
||||
is_scoped = 1 << 0,
|
||||
};
|
||||
|
||||
enum class function_flags : std::uint32_t {
|
||||
is_noexcept = 1 << 0,
|
||||
};
|
||||
|
||||
enum class member_flags : std::uint32_t {
|
||||
is_readonly = 1 << 0,
|
||||
};
|
||||
|
||||
enum class method_flags : std::uint32_t {
|
||||
is_const = 1 << 0,
|
||||
is_noexcept = 1 << 1,
|
||||
is_lvalue_qualified = 1 << 2,
|
||||
is_rvalue_qualified = 1 << 3,
|
||||
};
|
||||
|
||||
enum class number_flags : std::uint32_t {
|
||||
is_signed = 1 << 0,
|
||||
is_unsigned = 1 << 1,
|
||||
is_integral = 1 << 2,
|
||||
is_floating_point = 1 << 3,
|
||||
};
|
||||
|
||||
enum class pointer_flags : std::uint32_t {
|
||||
is_readonly = 1 << 0,
|
||||
};
|
||||
|
||||
enum class reference_flags : std::uint32_t {
|
||||
is_readonly = 1 << 0,
|
||||
is_lvalue = 1 << 1,
|
||||
is_rvalue = 1 << 2,
|
||||
};
|
||||
|
||||
ENUM_HPP_OPERATORS_DECL(array_flags)
|
||||
ENUM_HPP_OPERATORS_DECL(class_flags)
|
||||
ENUM_HPP_OPERATORS_DECL(ctor_flags)
|
||||
ENUM_HPP_OPERATORS_DECL(dtor_flags)
|
||||
ENUM_HPP_OPERATORS_DECL(enum_flags)
|
||||
ENUM_HPP_OPERATORS_DECL(function_flags)
|
||||
ENUM_HPP_OPERATORS_DECL(member_flags)
|
||||
ENUM_HPP_OPERATORS_DECL(method_flags)
|
||||
ENUM_HPP_OPERATORS_DECL(number_flags)
|
||||
ENUM_HPP_OPERATORS_DECL(pointer_flags)
|
||||
ENUM_HPP_OPERATORS_DECL(reference_flags)
|
||||
}
|
||||
@@ -7,114 +7,34 @@
|
||||
#pragma once
|
||||
|
||||
#include "meta_base.hpp"
|
||||
#include "meta_traits.hpp"
|
||||
|
||||
#include "meta_detail/type_family.hpp"
|
||||
|
||||
#include "meta_detail/type_traits/array_traits.hpp"
|
||||
#include "meta_detail/type_traits/class_traits.hpp"
|
||||
#include "meta_detail/type_traits/ctor_traits.hpp"
|
||||
#include "meta_detail/type_traits/dtor_traits.hpp"
|
||||
#include "meta_detail/type_traits/enum_traits.hpp"
|
||||
#include "meta_detail/type_traits/function_traits.hpp"
|
||||
#include "meta_detail/type_traits/member_traits.hpp"
|
||||
#include "meta_detail/type_traits/method_traits.hpp"
|
||||
#include "meta_detail/type_traits/number_traits.hpp"
|
||||
#include "meta_detail/type_traits/pointer_traits.hpp"
|
||||
#include "meta_detail/type_traits/reference_traits.hpp"
|
||||
|
||||
namespace meta_hpp
|
||||
{
|
||||
class type_id final {
|
||||
public:
|
||||
template < typename T >
|
||||
// NOLINTNEXTLINE(readability-named-parameter)
|
||||
explicit type_id(detail::type_list<T>) noexcept
|
||||
: id_{type_to_id<T>()} {}
|
||||
|
||||
type_id(type_id&&) = default;
|
||||
type_id(const type_id&) = default;
|
||||
|
||||
type_id& operator=(type_id&&) = default;
|
||||
type_id& operator=(const type_id&) = default;
|
||||
|
||||
~type_id() = default;
|
||||
|
||||
[[nodiscard]] std::size_t get_hash() const noexcept {
|
||||
return std::hash<underlying_type>{}(id_);
|
||||
}
|
||||
|
||||
[[nodiscard]] friend bool operator<(type_id l, type_id r) noexcept {
|
||||
return l.id_ < r.id_;
|
||||
}
|
||||
|
||||
[[nodiscard]] friend bool operator==(type_id l, type_id r) noexcept {
|
||||
return l.id_ == r.id_;
|
||||
}
|
||||
|
||||
[[nodiscard]] friend bool operator!=(type_id l, type_id r) noexcept {
|
||||
return l.id_ != r.id_;
|
||||
}
|
||||
private:
|
||||
using underlying_type = std::uint32_t;
|
||||
underlying_type id_{};
|
||||
private:
|
||||
[[nodiscard]] static underlying_type next() noexcept {
|
||||
static std::atomic<underlying_type> id{};
|
||||
return ++id;
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
[[nodiscard]] static underlying_type type_to_id() noexcept {
|
||||
static const underlying_type id{next()};
|
||||
return id;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
namespace meta_hpp
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
template < typename T >
|
||||
concept type_family =
|
||||
std::is_same_v<T, any_type> ||
|
||||
std::is_same_v<T, array_type> ||
|
||||
std::is_same_v<T, class_type> ||
|
||||
std::is_same_v<T, ctor_type> ||
|
||||
std::is_same_v<T, dtor_type> ||
|
||||
std::is_same_v<T, enum_type> ||
|
||||
std::is_same_v<T, function_type> ||
|
||||
std::is_same_v<T, member_type> ||
|
||||
std::is_same_v<T, method_type> ||
|
||||
std::is_same_v<T, nullptr_type> ||
|
||||
std::is_same_v<T, number_type> ||
|
||||
std::is_same_v<T, pointer_type> ||
|
||||
std::is_same_v<T, reference_type> ||
|
||||
std::is_same_v<T, void_type>;
|
||||
|
||||
template < type_family T >
|
||||
[[nodiscard]] auto data_access(const T& type) {
|
||||
return type.data_;
|
||||
}
|
||||
}
|
||||
|
||||
template < detail::type_family T, detail::type_family U >
|
||||
[[nodiscard]] bool operator<(const T& l, const U& r) noexcept {
|
||||
if ( !static_cast<bool>(r) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( !static_cast<bool>(l) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return l.get_id() < r.get_id();
|
||||
}
|
||||
|
||||
template < detail::type_family T, detail::type_family U >
|
||||
[[nodiscard]] bool operator==(const T& l, const U& r) noexcept {
|
||||
if ( static_cast<bool>(l) != static_cast<bool>(r) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( !static_cast<bool>(l) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return l.get_id() == r.get_id();
|
||||
}
|
||||
|
||||
template < detail::type_family T, detail::type_family U >
|
||||
[[nodiscard]] bool operator!=(const T& l, const U& r) noexcept {
|
||||
return !(l == r);
|
||||
}
|
||||
using array_flags = detail::array_flags;
|
||||
using class_flags = detail::class_flags;
|
||||
using ctor_flags = detail::ctor_flags;
|
||||
using dtor_flags = detail::dtor_flags;
|
||||
using enum_flags = detail::enum_flags;
|
||||
using function_flags = detail::function_flags;
|
||||
using member_flags = detail::member_flags;
|
||||
using method_flags = detail::method_flags;
|
||||
using number_flags = detail::number_flags;
|
||||
using pointer_flags = detail::pointer_flags;
|
||||
using reference_flags = detail::reference_flags;
|
||||
}
|
||||
|
||||
namespace meta_hpp
|
||||
@@ -122,7 +42,6 @@ namespace meta_hpp
|
||||
class any_type final {
|
||||
public:
|
||||
explicit any_type() = default;
|
||||
explicit any_type(detail::type_data_base_ptr data);
|
||||
|
||||
[[nodiscard]] bool is_valid() const noexcept;
|
||||
[[nodiscard]] explicit operator bool() const noexcept;
|
||||
@@ -173,7 +92,7 @@ namespace meta_hpp
|
||||
[[nodiscard]] void_type as_void() const noexcept;
|
||||
private:
|
||||
detail::type_data_base_ptr data_;
|
||||
friend auto detail::data_access<any_type>(const any_type&);
|
||||
friend auto detail::type_access<any_type>(const any_type&);
|
||||
};
|
||||
|
||||
class array_type final {
|
||||
@@ -191,7 +110,7 @@ namespace meta_hpp
|
||||
[[nodiscard]] any_type get_data_type() const noexcept;
|
||||
private:
|
||||
detail::array_type_data_ptr data_;
|
||||
friend auto detail::data_access<array_type>(const array_type&);
|
||||
friend auto detail::type_access<array_type>(const array_type&);
|
||||
};
|
||||
|
||||
class class_type final {
|
||||
@@ -257,7 +176,7 @@ namespace meta_hpp
|
||||
[[nodiscard]] method get_method_with(std::string_view name, std::initializer_list<any_type> args) const noexcept;
|
||||
private:
|
||||
detail::class_type_data_ptr data_;
|
||||
friend auto detail::data_access<class_type>(const class_type&);
|
||||
friend auto detail::type_access<class_type>(const class_type&);
|
||||
};
|
||||
|
||||
class ctor_type final {
|
||||
@@ -277,7 +196,7 @@ namespace meta_hpp
|
||||
[[nodiscard]] const std::vector<any_type>& get_argument_types() const noexcept;
|
||||
private:
|
||||
detail::ctor_type_data_ptr data_;
|
||||
friend auto detail::data_access<ctor_type>(const ctor_type&);
|
||||
friend auto detail::type_access<ctor_type>(const ctor_type&);
|
||||
};
|
||||
|
||||
class dtor_type final {
|
||||
@@ -294,7 +213,7 @@ namespace meta_hpp
|
||||
[[nodiscard]] any_type get_class_type() const noexcept;
|
||||
private:
|
||||
detail::dtor_type_data_ptr data_;
|
||||
friend auto detail::data_access<dtor_type>(const dtor_type&);
|
||||
friend auto detail::type_access<dtor_type>(const dtor_type&);
|
||||
};
|
||||
|
||||
class enum_type final {
|
||||
@@ -319,7 +238,7 @@ namespace meta_hpp
|
||||
[[nodiscard]] value name_to_value(std::string_view name) const noexcept;
|
||||
private:
|
||||
detail::enum_type_data_ptr data_;
|
||||
friend auto detail::data_access<enum_type>(const enum_type&);
|
||||
friend auto detail::type_access<enum_type>(const enum_type&);
|
||||
};
|
||||
|
||||
class function_type final {
|
||||
@@ -339,7 +258,7 @@ namespace meta_hpp
|
||||
[[nodiscard]] const std::vector<any_type>& get_argument_types() const noexcept;
|
||||
private:
|
||||
detail::function_type_data_ptr data_;
|
||||
friend auto detail::data_access<function_type>(const function_type&);
|
||||
friend auto detail::type_access<function_type>(const function_type&);
|
||||
};
|
||||
|
||||
class member_type final {
|
||||
@@ -357,7 +276,7 @@ namespace meta_hpp
|
||||
[[nodiscard]] any_type get_value_type() const noexcept;
|
||||
private:
|
||||
detail::member_type_data_ptr data_;
|
||||
friend auto detail::data_access<member_type>(const member_type&);
|
||||
friend auto detail::type_access<member_type>(const member_type&);
|
||||
};
|
||||
|
||||
class method_type final {
|
||||
@@ -378,7 +297,7 @@ namespace meta_hpp
|
||||
[[nodiscard]] const std::vector<any_type>& get_argument_types() const noexcept;
|
||||
private:
|
||||
detail::method_type_data_ptr data_;
|
||||
friend auto detail::data_access<method_type>(const method_type&);
|
||||
friend auto detail::type_access<method_type>(const method_type&);
|
||||
};
|
||||
|
||||
class nullptr_type final {
|
||||
@@ -392,7 +311,7 @@ namespace meta_hpp
|
||||
[[nodiscard]] type_id get_id() const noexcept;
|
||||
private:
|
||||
detail::nullptr_type_data_ptr data_;
|
||||
friend auto detail::data_access<nullptr_type>(const nullptr_type&);
|
||||
friend auto detail::type_access<nullptr_type>(const nullptr_type&);
|
||||
};
|
||||
|
||||
class number_type final {
|
||||
@@ -409,7 +328,7 @@ namespace meta_hpp
|
||||
[[nodiscard]] std::size_t get_size() const noexcept;
|
||||
private:
|
||||
detail::number_type_data_ptr data_;
|
||||
friend auto detail::data_access<number_type>(const number_type&);
|
||||
friend auto detail::type_access<number_type>(const number_type&);
|
||||
};
|
||||
|
||||
class pointer_type final {
|
||||
@@ -426,7 +345,7 @@ namespace meta_hpp
|
||||
[[nodiscard]] any_type get_data_type() const noexcept;
|
||||
private:
|
||||
detail::pointer_type_data_ptr data_;
|
||||
friend auto detail::data_access<pointer_type>(const pointer_type&);
|
||||
friend auto detail::type_access<pointer_type>(const pointer_type&);
|
||||
};
|
||||
|
||||
class reference_type final {
|
||||
@@ -443,7 +362,7 @@ namespace meta_hpp
|
||||
[[nodiscard]] any_type get_data_type() const noexcept;
|
||||
private:
|
||||
detail::reference_type_data_ptr data_;
|
||||
friend auto detail::data_access<reference_type>(const reference_type&);
|
||||
friend auto detail::type_access<reference_type>(const reference_type&);
|
||||
};
|
||||
|
||||
class void_type final {
|
||||
@@ -457,10 +376,44 @@ namespace meta_hpp
|
||||
[[nodiscard]] type_id get_id() const noexcept;
|
||||
private:
|
||||
detail::void_type_data_ptr data_;
|
||||
friend auto detail::data_access<void_type>(const void_type&);
|
||||
friend auto detail::type_access<void_type>(const void_type&);
|
||||
};
|
||||
}
|
||||
|
||||
namespace meta_hpp
|
||||
{
|
||||
template < detail::type_family T, detail::type_family U >
|
||||
[[nodiscard]] bool operator<(const T& l, const U& r) noexcept {
|
||||
if ( !static_cast<bool>(r) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( !static_cast<bool>(l) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return l.get_id() < r.get_id();
|
||||
}
|
||||
|
||||
template < detail::type_family T, detail::type_family U >
|
||||
[[nodiscard]] bool operator==(const T& l, const U& r) noexcept {
|
||||
if ( static_cast<bool>(l) != static_cast<bool>(r) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( !static_cast<bool>(l) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return l.get_id() == r.get_id();
|
||||
}
|
||||
|
||||
template < detail::type_family T, detail::type_family U >
|
||||
[[nodiscard]] bool operator!=(const T& l, const U& r) noexcept {
|
||||
return !(l == r);
|
||||
}
|
||||
}
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
struct type_data_base {
|
||||
@@ -479,9 +432,6 @@ namespace meta_hpp::detail
|
||||
|
||||
template < array_kind Array >
|
||||
explicit array_type_data(type_list<Array>);
|
||||
|
||||
template < array_kind Array >
|
||||
[[nodiscard]] static array_type_data_ptr get_static();
|
||||
};
|
||||
|
||||
struct class_type_data final : type_data_base {
|
||||
@@ -507,9 +457,6 @@ namespace meta_hpp::detail
|
||||
|
||||
template < class_kind Class >
|
||||
explicit class_type_data(type_list<Class>);
|
||||
|
||||
template < class_kind Class >
|
||||
[[nodiscard]] static class_type_data_ptr get_static();
|
||||
};
|
||||
|
||||
struct ctor_type_data final : type_data_base {
|
||||
@@ -519,9 +466,6 @@ namespace meta_hpp::detail
|
||||
|
||||
template < class_kind Class, typename... Args >
|
||||
explicit ctor_type_data(type_list<Class>, type_list<Args...>);
|
||||
|
||||
template < class_kind Class, typename... Args >
|
||||
[[nodiscard]] static ctor_type_data_ptr get_static();
|
||||
};
|
||||
|
||||
struct dtor_type_data final : type_data_base {
|
||||
@@ -530,9 +474,6 @@ namespace meta_hpp::detail
|
||||
|
||||
template < class_kind Class >
|
||||
explicit dtor_type_data(type_list<Class>);
|
||||
|
||||
template < class_kind Class >
|
||||
[[nodiscard]] static dtor_type_data_ptr get_static();
|
||||
};
|
||||
|
||||
struct enum_type_data final : type_data_base {
|
||||
@@ -543,9 +484,6 @@ namespace meta_hpp::detail
|
||||
|
||||
template < enum_kind Enum >
|
||||
explicit enum_type_data(type_list<Enum>);
|
||||
|
||||
template < enum_kind Enum >
|
||||
[[nodiscard]] static enum_type_data_ptr get_static();
|
||||
};
|
||||
|
||||
struct function_type_data final : type_data_base {
|
||||
@@ -555,9 +493,6 @@ namespace meta_hpp::detail
|
||||
|
||||
template < function_kind Function >
|
||||
explicit function_type_data(type_list<Function>);
|
||||
|
||||
template < function_kind Function >
|
||||
[[nodiscard]] static function_type_data_ptr get_static();
|
||||
};
|
||||
|
||||
struct member_type_data final : type_data_base {
|
||||
@@ -567,9 +502,6 @@ namespace meta_hpp::detail
|
||||
|
||||
template < member_kind Member >
|
||||
explicit member_type_data(type_list<Member>);
|
||||
|
||||
template < member_kind Member >
|
||||
[[nodiscard]] static member_type_data_ptr get_static();
|
||||
};
|
||||
|
||||
struct method_type_data final : type_data_base {
|
||||
@@ -580,17 +512,11 @@ namespace meta_hpp::detail
|
||||
|
||||
template < method_kind Method >
|
||||
explicit method_type_data(type_list<Method>);
|
||||
|
||||
template < method_kind Method >
|
||||
[[nodiscard]] static method_type_data_ptr get_static();
|
||||
};
|
||||
|
||||
struct nullptr_type_data final : type_data_base {
|
||||
template < nullptr_kind Nullptr >
|
||||
explicit nullptr_type_data(type_list<Nullptr>);
|
||||
|
||||
template < nullptr_kind Nullptr >
|
||||
[[nodiscard]] static nullptr_type_data_ptr get_static();
|
||||
};
|
||||
|
||||
struct number_type_data final : type_data_base {
|
||||
@@ -599,9 +525,6 @@ namespace meta_hpp::detail
|
||||
|
||||
template < number_kind Number >
|
||||
explicit number_type_data(type_list<Number>);
|
||||
|
||||
template < number_kind Number >
|
||||
[[nodiscard]] static number_type_data_ptr get_static();
|
||||
};
|
||||
|
||||
struct pointer_type_data final : type_data_base {
|
||||
@@ -610,9 +533,6 @@ namespace meta_hpp::detail
|
||||
|
||||
template < pointer_kind Pointer >
|
||||
explicit pointer_type_data(type_list<Pointer>);
|
||||
|
||||
template < pointer_kind Pointer >
|
||||
[[nodiscard]] static pointer_type_data_ptr get_static();
|
||||
};
|
||||
|
||||
struct reference_type_data final : type_data_base {
|
||||
@@ -621,209 +541,10 @@ namespace meta_hpp::detail
|
||||
|
||||
template < reference_kind Reference >
|
||||
explicit reference_type_data(type_list<Reference>);
|
||||
|
||||
template < reference_kind Reference >
|
||||
[[nodiscard]] static reference_type_data_ptr get_static();
|
||||
};
|
||||
|
||||
struct void_type_data final : type_data_base {
|
||||
template < void_kind Void >
|
||||
explicit void_type_data(type_list<Void>);
|
||||
|
||||
template < void_kind Void >
|
||||
[[nodiscard]] static void_type_data_ptr get_static();
|
||||
};
|
||||
}
|
||||
|
||||
namespace meta_hpp
|
||||
{
|
||||
struct ctor_index final {
|
||||
const ctor_type type;
|
||||
|
||||
explicit ctor_index(ctor_type type)
|
||||
: type{std::move(type)} {}
|
||||
|
||||
[[nodiscard]] friend bool operator<(const ctor_index& l, const ctor_index& r) noexcept {
|
||||
return l.type < r.type;
|
||||
}
|
||||
|
||||
[[nodiscard]] friend bool operator==(const ctor_index& l, const ctor_index& r) noexcept {
|
||||
return l.type == r.type;
|
||||
}
|
||||
};
|
||||
|
||||
struct dtor_index final {
|
||||
const dtor_type type;
|
||||
|
||||
explicit dtor_index(dtor_type type)
|
||||
: type{std::move(type)} {}
|
||||
|
||||
[[nodiscard]] friend bool operator<(const dtor_index& l, const dtor_index& r) noexcept {
|
||||
return l.type < r.type;
|
||||
}
|
||||
|
||||
[[nodiscard]] friend bool operator==(const dtor_index& l, const dtor_index& r) noexcept {
|
||||
return l.type == r.type;
|
||||
}
|
||||
};
|
||||
|
||||
struct evalue_index final {
|
||||
const enum_type type;
|
||||
const std::string name;
|
||||
|
||||
explicit evalue_index(enum_type type, std::string name)
|
||||
: type{std::move(type)}
|
||||
, name{std::move(name)} {}
|
||||
|
||||
[[nodiscard]] friend bool operator<(const evalue_index& l, const evalue_index& r) noexcept {
|
||||
return (l.type < r.type) || (l.type == r.type && l.name < r.name);
|
||||
}
|
||||
|
||||
[[nodiscard]] friend bool operator==(const evalue_index& l, const evalue_index& r) noexcept {
|
||||
return l.type == r.type && l.name == r.name;
|
||||
}
|
||||
};
|
||||
|
||||
struct function_index final {
|
||||
const function_type type;
|
||||
const std::string name;
|
||||
|
||||
explicit function_index(function_type type, std::string name)
|
||||
: type{std::move(type)}
|
||||
, name{std::move(name)} {}
|
||||
|
||||
[[nodiscard]] friend bool operator<(const function_index& l, const function_index& r) noexcept {
|
||||
return (l.type < r.type) || (l.type == r.type && l.name < r.name);
|
||||
}
|
||||
|
||||
[[nodiscard]] friend bool operator==(const function_index& l, const function_index& r) noexcept {
|
||||
return l.type == r.type && l.name == r.name;
|
||||
}
|
||||
};
|
||||
|
||||
struct member_index final {
|
||||
const member_type type;
|
||||
const std::string name;
|
||||
|
||||
explicit member_index(member_type type, std::string name)
|
||||
: type{std::move(type)}
|
||||
, name{std::move(name)} {}
|
||||
|
||||
[[nodiscard]] friend bool operator<(const member_index& l, const member_index& r) noexcept {
|
||||
return (l.type < r.type) || (l.type == r.type && l.name < r.name);
|
||||
}
|
||||
|
||||
[[nodiscard]] friend bool operator==(const member_index& l, const member_index& r) noexcept {
|
||||
return l.type == r.type && l.name == r.name;
|
||||
}
|
||||
};
|
||||
|
||||
struct method_index final {
|
||||
const method_type type;
|
||||
const std::string name;
|
||||
|
||||
explicit method_index(method_type type, std::string name)
|
||||
: type{std::move(type)}
|
||||
, name{std::move(name)} {}
|
||||
|
||||
[[nodiscard]] friend bool operator<(const method_index& l, const method_index& r) noexcept {
|
||||
return (l.type < r.type) || (l.type == r.type && l.name < r.name);
|
||||
}
|
||||
|
||||
[[nodiscard]] friend bool operator==(const method_index& l, const method_index& r) noexcept {
|
||||
return l.type == r.type && l.name == r.name;
|
||||
}
|
||||
};
|
||||
|
||||
struct scope_index final {
|
||||
const std::string name;
|
||||
|
||||
explicit scope_index(std::string name)
|
||||
: name{std::move(name)} {}
|
||||
|
||||
[[nodiscard]] friend bool operator<(const scope_index& l, const scope_index& r) noexcept {
|
||||
return l.name < r.name;
|
||||
}
|
||||
|
||||
[[nodiscard]] friend bool operator==(const scope_index& l, const scope_index& r) noexcept {
|
||||
return l.name == r.name;
|
||||
}
|
||||
};
|
||||
|
||||
struct variable_index final {
|
||||
const pointer_type type;
|
||||
const std::string name;
|
||||
|
||||
explicit variable_index(pointer_type type, std::string name)
|
||||
: type{std::move(type)}
|
||||
, name{std::move(name)} {}
|
||||
|
||||
[[nodiscard]] friend bool operator<(const variable_index& l, const variable_index& r) noexcept {
|
||||
return (l.type < r.type) || (l.type == r.type && l.name < r.name);
|
||||
}
|
||||
|
||||
[[nodiscard]] friend bool operator==(const variable_index& l, const variable_index& r) noexcept {
|
||||
return l.type == r.type && l.name == r.name;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
namespace meta_hpp
|
||||
{
|
||||
template < typename T >
|
||||
[[nodiscard]] auto resolve_type() {
|
||||
using raw_type = std::remove_cv_t<T>;
|
||||
|
||||
using kind_type = detail::kind_type<raw_type>;
|
||||
using kind_type_data = detail::kind_type_data<raw_type>;
|
||||
|
||||
return kind_type{kind_type_data::template get_static<raw_type>()};
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
// NOLINTNEXTLINE(readability-named-parameter)
|
||||
[[nodiscard]] auto resolve_type(const T&) {
|
||||
return resolve_type<std::remove_reference_t<T>>();
|
||||
}
|
||||
}
|
||||
|
||||
namespace meta_hpp
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
[[nodiscard]] inline void* pointer_upcast(void* ptr, const class_type& from, const class_type& to) {
|
||||
if ( nullptr == ptr || !from || !to ) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if ( from == to ) {
|
||||
return ptr;
|
||||
}
|
||||
|
||||
for ( auto&& [base, base_info] : data_access(from)->bases_info ) {
|
||||
if ( base == to ) {
|
||||
return base_info.upcast(ptr);
|
||||
}
|
||||
|
||||
if ( base.is_derived_from(to) ) {
|
||||
return pointer_upcast(base_info.upcast(ptr), base, to);
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
template < detail::class_kind Base, detail::class_kind Derived >
|
||||
[[nodiscard]] Base* pointer_upcast(Derived* ptr) {
|
||||
const class_type& base = resolve_type<Base>();
|
||||
const class_type& derived = resolve_type<Derived>();
|
||||
return static_cast<Base*>(detail::pointer_upcast(ptr, derived, base));
|
||||
}
|
||||
|
||||
template < detail::class_kind Base, detail::class_kind Derived >
|
||||
[[nodiscard]] const Base* pointer_upcast(const Derived* ptr) {
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast)
|
||||
return pointer_upcast<Base>(const_cast<Derived*>(ptr));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,9 +11,6 @@
|
||||
|
||||
namespace meta_hpp
|
||||
{
|
||||
inline any_type::any_type(detail::type_data_base_ptr data)
|
||||
: data_{std::move(data)} {}
|
||||
|
||||
inline bool any_type::is_valid() const noexcept {
|
||||
return !!data_;
|
||||
}
|
||||
@@ -31,43 +28,43 @@ namespace meta_hpp
|
||||
}
|
||||
|
||||
inline any_type::any_type(const array_type& other) noexcept
|
||||
: data_{detail::data_access(other)} {}
|
||||
: data_{detail::type_access(other)} {}
|
||||
|
||||
inline any_type::any_type(const class_type& other) noexcept
|
||||
: data_{detail::data_access(other)} {}
|
||||
: data_{detail::type_access(other)} {}
|
||||
|
||||
inline any_type::any_type(const ctor_type& other) noexcept
|
||||
: data_{detail::data_access(other)} {}
|
||||
: data_{detail::type_access(other)} {}
|
||||
|
||||
inline any_type::any_type(const dtor_type& other) noexcept
|
||||
: data_{detail::data_access(other)} {}
|
||||
: data_{detail::type_access(other)} {}
|
||||
|
||||
inline any_type::any_type(const enum_type& other) noexcept
|
||||
: data_{detail::data_access(other)} {}
|
||||
: data_{detail::type_access(other)} {}
|
||||
|
||||
inline any_type::any_type(const function_type& other) noexcept
|
||||
: data_{detail::data_access(other)} {}
|
||||
: data_{detail::type_access(other)} {}
|
||||
|
||||
inline any_type::any_type(const member_type& other) noexcept
|
||||
: data_{detail::data_access(other)} {}
|
||||
: data_{detail::type_access(other)} {}
|
||||
|
||||
inline any_type::any_type(const method_type& other) noexcept
|
||||
: data_{detail::data_access(other)} {}
|
||||
: data_{detail::type_access(other)} {}
|
||||
|
||||
inline any_type::any_type(const nullptr_type& other) noexcept
|
||||
: data_{detail::data_access(other)} {}
|
||||
: data_{detail::type_access(other)} {}
|
||||
|
||||
inline any_type::any_type(const number_type& other) noexcept
|
||||
: data_{detail::data_access(other)} {}
|
||||
: data_{detail::type_access(other)} {}
|
||||
|
||||
inline any_type::any_type(const pointer_type& other) noexcept
|
||||
: data_{detail::data_access(other)} {}
|
||||
: data_{detail::type_access(other)} {}
|
||||
|
||||
inline any_type::any_type(const reference_type& other) noexcept
|
||||
: data_{detail::data_access(other)} {}
|
||||
: data_{detail::type_access(other)} {}
|
||||
|
||||
inline any_type::any_type(const void_type& other) noexcept
|
||||
: data_{detail::data_access(other)} {}
|
||||
: data_{detail::type_access(other)} {}
|
||||
|
||||
inline bool any_type::is_array() const noexcept {
|
||||
return data_ && data_->kind == type_kind::array_;
|
||||
|
||||
@@ -9,7 +9,8 @@
|
||||
#include "../meta_base.hpp"
|
||||
#include "../meta_types.hpp"
|
||||
|
||||
#include "../meta_traits/array_traits.hpp"
|
||||
#include "../meta_detail/type_registry.hpp"
|
||||
#include "../meta_detail/type_traits/array_traits.hpp"
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
@@ -23,12 +24,6 @@ namespace meta_hpp::detail
|
||||
, flags{array_traits<Array>::make_flags()}
|
||||
, extent{array_traits<Array>::extent}
|
||||
, data_type{resolve_type<typename array_traits<Array>::data_type>()} {}
|
||||
|
||||
template < array_kind Array >
|
||||
array_type_data_ptr array_type_data::get_static() {
|
||||
static array_type_data_ptr data = std::make_shared<array_type_data>(type_list<Array>{});
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
namespace meta_hpp
|
||||
|
||||
@@ -15,7 +15,8 @@
|
||||
#include "../meta_states/method.hpp"
|
||||
#include "../meta_states/variable.hpp"
|
||||
|
||||
#include "../meta_traits/class_traits.hpp"
|
||||
#include "../meta_detail/type_registry.hpp"
|
||||
#include "../meta_detail/type_traits/class_traits.hpp"
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
@@ -28,13 +29,7 @@ namespace meta_hpp::detail
|
||||
: type_data_base{type_id{type_list<class_tag<Class>>{}}, type_kind::class_}
|
||||
, flags{class_traits<Class>::make_flags()}
|
||||
, size{class_traits<Class>::size}
|
||||
, argument_types{class_traits<Class>::make_argument_types()} {}
|
||||
|
||||
template < class_kind Class >
|
||||
class_type_data_ptr class_type_data::get_static() {
|
||||
static class_type_data_ptr data = std::make_shared<class_type_data>(type_list<Class>{});
|
||||
return data;
|
||||
}
|
||||
, argument_types{resolve_types(typename class_traits<Class>::argument_types{})} {}
|
||||
}
|
||||
|
||||
namespace meta_hpp
|
||||
@@ -130,7 +125,7 @@ namespace meta_hpp
|
||||
|
||||
template < detail::class_kind Derived >
|
||||
bool class_type::is_base_of() const noexcept {
|
||||
return is_base_of(resolve_type<Derived>());
|
||||
return is_base_of(detail::resolve_type<Derived>());
|
||||
}
|
||||
|
||||
inline bool class_type::is_base_of(const class_type& derived) const noexcept {
|
||||
@@ -153,7 +148,7 @@ namespace meta_hpp
|
||||
|
||||
template < detail::class_kind Base >
|
||||
bool class_type::is_derived_from() const noexcept {
|
||||
return is_derived_from(resolve_type<Base>());
|
||||
return is_derived_from(detail::resolve_type<Base>());
|
||||
}
|
||||
|
||||
inline bool class_type::is_derived_from(const class_type& base) const noexcept {
|
||||
@@ -176,7 +171,7 @@ namespace meta_hpp
|
||||
|
||||
inline function class_type::get_function(std::string_view name) const noexcept {
|
||||
for ( auto&& [index, function] : data_->functions ) {
|
||||
if ( index.name == name ) {
|
||||
if ( index.get_name() == name ) {
|
||||
return function;
|
||||
}
|
||||
}
|
||||
@@ -192,7 +187,7 @@ namespace meta_hpp
|
||||
|
||||
inline member class_type::get_member(std::string_view name) const noexcept {
|
||||
for ( auto&& [index, member] : data_->members ) {
|
||||
if ( index.name == name ) {
|
||||
if ( index.get_name() == name ) {
|
||||
return member;
|
||||
}
|
||||
}
|
||||
@@ -208,7 +203,7 @@ namespace meta_hpp
|
||||
|
||||
inline method class_type::get_method(std::string_view name) const noexcept {
|
||||
for ( auto&& [index, method] : data_->methods ) {
|
||||
if ( index.name == name ) {
|
||||
if ( index.get_name() == name ) {
|
||||
return method;
|
||||
}
|
||||
}
|
||||
@@ -224,7 +219,7 @@ namespace meta_hpp
|
||||
|
||||
inline variable class_type::get_variable(std::string_view name) const noexcept {
|
||||
for ( auto&& [index, variable] : data_->variables ) {
|
||||
if ( index.name == name ) {
|
||||
if ( index.get_name() == name ) {
|
||||
return variable;
|
||||
}
|
||||
}
|
||||
@@ -244,7 +239,7 @@ namespace meta_hpp
|
||||
|
||||
template < typename... Args >
|
||||
ctor class_type::get_ctor_with() const noexcept {
|
||||
return get_ctor_with({resolve_type<Args>()...});
|
||||
return get_ctor_with({detail::resolve_type<Args>()...});
|
||||
}
|
||||
|
||||
inline ctor class_type::get_ctor_with(const std::vector<any_type>& args) const noexcept {
|
||||
@@ -283,12 +278,12 @@ namespace meta_hpp
|
||||
|
||||
template < typename... Args >
|
||||
function class_type::get_function_with(std::string_view name) const noexcept {
|
||||
return get_function_with(name, {resolve_type<Args>()...});
|
||||
return get_function_with(name, {detail::resolve_type<Args>()...});
|
||||
}
|
||||
|
||||
inline function class_type::get_function_with(std::string_view name, const std::vector<any_type>& args) const noexcept {
|
||||
for ( auto&& [index, function] : data_->functions ) {
|
||||
if ( index.name != name ) {
|
||||
if ( index.get_name() != name ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -313,7 +308,7 @@ namespace meta_hpp
|
||||
|
||||
inline function class_type::get_function_with(std::string_view name, std::initializer_list<any_type> args) const noexcept {
|
||||
for ( auto&& [index, function] : data_->functions ) {
|
||||
if ( index.name != name ) {
|
||||
if ( index.get_name() != name ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -342,12 +337,12 @@ namespace meta_hpp
|
||||
|
||||
template < typename... Args >
|
||||
method class_type::get_method_with(std::string_view name) const noexcept {
|
||||
return get_method_with(name, {resolve_type<Args>()...});
|
||||
return get_method_with(name, {detail::resolve_type<Args>()...});
|
||||
}
|
||||
|
||||
inline method class_type::get_method_with(std::string_view name, const std::vector<any_type>& args) const noexcept {
|
||||
for ( auto&& [index, method] : data_->methods ) {
|
||||
if ( index.name != name ) {
|
||||
if ( index.get_name() != name ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -372,7 +367,7 @@ namespace meta_hpp
|
||||
|
||||
inline method class_type::get_method_with(std::string_view name, std::initializer_list<any_type> args) const noexcept {
|
||||
for ( auto&& [index, method] : data_->methods ) {
|
||||
if ( index.name != name ) {
|
||||
if ( index.get_name() != name ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,8 @@
|
||||
#include "../meta_base.hpp"
|
||||
#include "../meta_types.hpp"
|
||||
|
||||
#include "../meta_traits/ctor_traits.hpp"
|
||||
#include "../meta_detail/type_registry.hpp"
|
||||
#include "../meta_detail/type_traits/ctor_traits.hpp"
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
@@ -22,13 +23,7 @@ namespace meta_hpp::detail
|
||||
: type_data_base{type_id{type_list<ctor_tag<Class, Args...>>{}}, type_kind::ctor_}
|
||||
, flags{ctor_traits<Class, Args...>::make_flags()}
|
||||
, class_type{resolve_type<typename ctor_traits<Class, Args...>::class_type>()}
|
||||
, argument_types{ctor_traits<Class, Args...>::make_argument_types()} {}
|
||||
|
||||
template < class_kind Class, typename... Args >
|
||||
ctor_type_data_ptr ctor_type_data::get_static() {
|
||||
static ctor_type_data_ptr data = std::make_shared<ctor_type_data>(type_list<Class>{}, type_list<Args...>{});
|
||||
return data;
|
||||
}
|
||||
, argument_types{resolve_types(typename ctor_traits<Class, Args...>::argument_types{})} {}
|
||||
}
|
||||
|
||||
namespace meta_hpp
|
||||
|
||||
@@ -9,7 +9,8 @@
|
||||
#include "../meta_base.hpp"
|
||||
#include "../meta_types.hpp"
|
||||
|
||||
#include "../meta_traits/dtor_traits.hpp"
|
||||
#include "../meta_detail/type_registry.hpp"
|
||||
#include "../meta_detail/type_traits/dtor_traits.hpp"
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
@@ -22,12 +23,6 @@ namespace meta_hpp::detail
|
||||
: type_data_base{type_id{type_list<dtor_tag<Class>>{}}, type_kind::dtor_}
|
||||
, flags{dtor_traits<Class>::make_flags()}
|
||||
, class_type{resolve_type<typename dtor_traits<Class>::class_type>()} {}
|
||||
|
||||
template < class_kind Class >
|
||||
dtor_type_data_ptr dtor_type_data::get_static() {
|
||||
static dtor_type_data_ptr data = std::make_shared<dtor_type_data>(type_list<Class>{});
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
namespace meta_hpp
|
||||
|
||||
@@ -11,7 +11,9 @@
|
||||
|
||||
#include "../meta_states/evalue.hpp"
|
||||
|
||||
#include "../meta_traits/enum_traits.hpp"
|
||||
#include "../meta_detail/type_registry.hpp"
|
||||
#include "../meta_detail/type_traits/enum_traits.hpp"
|
||||
#include "../meta_detail/value_utilities/arg.hpp"
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
@@ -24,12 +26,6 @@ namespace meta_hpp::detail
|
||||
: type_data_base{type_id{type_list<enum_tag<Enum>>{}}, type_kind::enum_}
|
||||
, flags{enum_traits<Enum>::make_flags()}
|
||||
, underlying_type{resolve_type<typename enum_traits<Enum>::underlying_type>()} {}
|
||||
|
||||
template < enum_kind Enum >
|
||||
enum_type_data_ptr enum_type_data::get_static() {
|
||||
static enum_type_data_ptr data = std::make_shared<enum_type_data>(type_list<Enum>{});
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
namespace meta_hpp
|
||||
@@ -63,7 +59,7 @@ namespace meta_hpp
|
||||
|
||||
inline evalue enum_type::get_evalue(std::string_view name) const noexcept {
|
||||
for ( auto&& [index, evalue] : data_->evalues ) {
|
||||
if ( index.name == name ) {
|
||||
if ( index.get_name() == name ) {
|
||||
return evalue;
|
||||
}
|
||||
}
|
||||
@@ -80,7 +76,7 @@ namespace meta_hpp
|
||||
|
||||
for ( auto&& evalue : data_->evalues ) {
|
||||
if ( evalue.second.get_value() == value ) {
|
||||
return evalue.second.get_index().name;
|
||||
return evalue.second.get_index().get_name();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,8 @@
|
||||
#include "../meta_base.hpp"
|
||||
#include "../meta_types.hpp"
|
||||
|
||||
#include "../meta_traits/function_traits.hpp"
|
||||
#include "../meta_detail/type_registry.hpp"
|
||||
#include "../meta_detail/type_traits/function_traits.hpp"
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
@@ -22,13 +23,7 @@ namespace meta_hpp::detail
|
||||
: type_data_base{type_id{type_list<function_tag<Function>>{}}, type_kind::function_}
|
||||
, flags{function_traits<Function>::make_flags()}
|
||||
, return_type{resolve_type<typename function_traits<Function>::return_type>()}
|
||||
, argument_types{function_traits<Function>::make_argument_types()} {}
|
||||
|
||||
template < function_kind Function >
|
||||
function_type_data_ptr function_type_data::get_static() {
|
||||
static function_type_data_ptr data = std::make_shared<function_type_data>(type_list<Function>{});
|
||||
return data;
|
||||
}
|
||||
, argument_types{resolve_types(typename function_traits<Function>::argument_types{})} {}
|
||||
}
|
||||
|
||||
namespace meta_hpp
|
||||
|
||||
@@ -9,7 +9,8 @@
|
||||
#include "../meta_base.hpp"
|
||||
#include "../meta_types.hpp"
|
||||
|
||||
#include "../meta_traits/member_traits.hpp"
|
||||
#include "../meta_detail/type_registry.hpp"
|
||||
#include "../meta_detail/type_traits/member_traits.hpp"
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
@@ -23,12 +24,6 @@ namespace meta_hpp::detail
|
||||
, flags{member_traits<Member>::make_flags()}
|
||||
, owner_type{resolve_type<typename member_traits<Member>::class_type>()}
|
||||
, value_type{resolve_type<typename member_traits<Member>::value_type>()} {}
|
||||
|
||||
template < member_kind Member >
|
||||
member_type_data_ptr member_type_data::get_static() {
|
||||
static member_type_data_ptr data = std::make_shared<member_type_data>(type_list<Member>{});
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
namespace meta_hpp
|
||||
|
||||
@@ -9,7 +9,8 @@
|
||||
#include "../meta_base.hpp"
|
||||
#include "../meta_types.hpp"
|
||||
|
||||
#include "../meta_traits/method_traits.hpp"
|
||||
#include "../meta_detail/type_registry.hpp"
|
||||
#include "../meta_detail/type_traits/method_traits.hpp"
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
@@ -23,13 +24,7 @@ namespace meta_hpp::detail
|
||||
, flags{method_traits<Method>::make_flags()}
|
||||
, owner_type{resolve_type<typename method_traits<Method>::class_type>()}
|
||||
, return_type{resolve_type<typename method_traits<Method>::return_type>()}
|
||||
, argument_types{method_traits<Method>::make_argument_types()} {}
|
||||
|
||||
template < method_kind Method >
|
||||
method_type_data_ptr method_type_data::get_static() {
|
||||
static method_type_data_ptr data = std::make_shared<method_type_data>(type_list<Method>{});
|
||||
return data;
|
||||
}
|
||||
, argument_types{resolve_types(typename method_traits<Method>::argument_types{})} {}
|
||||
}
|
||||
|
||||
namespace meta_hpp
|
||||
|
||||
@@ -18,12 +18,6 @@ namespace meta_hpp::detail
|
||||
// NOLINTNEXTLINE(readability-named-parameter)
|
||||
nullptr_type_data::nullptr_type_data(type_list<Nullptr>)
|
||||
: type_data_base{type_id{type_list<nullptr_tag<Nullptr>>{}}, type_kind::nullptr_} {}
|
||||
|
||||
template < nullptr_kind Nullptr >
|
||||
nullptr_type_data_ptr nullptr_type_data::get_static() {
|
||||
static nullptr_type_data_ptr data = std::make_shared<nullptr_type_data>(type_list<Nullptr>{});
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
namespace meta_hpp
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#include "../meta_base.hpp"
|
||||
#include "../meta_types.hpp"
|
||||
|
||||
#include "../meta_traits/number_traits.hpp"
|
||||
#include "../meta_detail/type_traits/number_traits.hpp"
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
@@ -22,12 +22,6 @@ namespace meta_hpp::detail
|
||||
: type_data_base{type_id{type_list<number_tag<Number>>{}}, type_kind::number_}
|
||||
, flags{number_traits<Number>::make_flags()}
|
||||
, size{number_traits<Number>::size} {}
|
||||
|
||||
template < number_kind Number >
|
||||
number_type_data_ptr number_type_data::get_static() {
|
||||
static number_type_data_ptr data = std::make_shared<number_type_data>(type_list<Number>{});
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
namespace meta_hpp
|
||||
|
||||
@@ -9,7 +9,8 @@
|
||||
#include "../meta_base.hpp"
|
||||
#include "../meta_types.hpp"
|
||||
|
||||
#include "../meta_traits/pointer_traits.hpp"
|
||||
#include "../meta_detail/type_registry.hpp"
|
||||
#include "../meta_detail/type_traits/pointer_traits.hpp"
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
@@ -22,12 +23,6 @@ namespace meta_hpp::detail
|
||||
: type_data_base{type_id{type_list<pointer_tag<Pointer>>{}}, type_kind::pointer_}
|
||||
, flags{pointer_traits<Pointer>::make_flags()}
|
||||
, data_type{resolve_type<typename pointer_traits<Pointer>::data_type>()} {}
|
||||
|
||||
template < pointer_kind Pointer >
|
||||
pointer_type_data_ptr pointer_type_data::get_static() {
|
||||
static pointer_type_data_ptr data = std::make_shared<pointer_type_data>(type_list<Pointer>{});
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
namespace meta_hpp
|
||||
|
||||
@@ -9,7 +9,8 @@
|
||||
#include "../meta_base.hpp"
|
||||
#include "../meta_types.hpp"
|
||||
|
||||
#include "../meta_traits/reference_traits.hpp"
|
||||
#include "../meta_detail/type_registry.hpp"
|
||||
#include "../meta_detail/type_traits/reference_traits.hpp"
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
@@ -22,12 +23,6 @@ namespace meta_hpp::detail
|
||||
: type_data_base{type_id{type_list<reference_tag<Reference>>{}}, type_kind::reference_}
|
||||
, flags{reference_traits<Reference>::make_flags()}
|
||||
, data_type{resolve_type<typename reference_traits<Reference>::data_type>()} {}
|
||||
|
||||
template < reference_kind Reference >
|
||||
reference_type_data_ptr reference_type_data::get_static() {
|
||||
static reference_type_data_ptr data = std::make_shared<reference_type_data>(type_list<Reference>{});
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
namespace meta_hpp
|
||||
|
||||
@@ -18,12 +18,6 @@ namespace meta_hpp::detail
|
||||
// NOLINTNEXTLINE(readability-named-parameter)
|
||||
void_type_data::void_type_data(type_list<Void>)
|
||||
: type_data_base{type_id{type_list<void_tag<Void>>{}}, type_kind::void_} {}
|
||||
|
||||
template < void_kind Void >
|
||||
void_type_data_ptr void_type_data::get_static() {
|
||||
static void_type_data_ptr data = std::make_shared<void_type_data>(type_list<Void>{});
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
namespace meta_hpp
|
||||
|
||||
@@ -1,351 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* 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, by Matvey Cherevko (blackmatov@gmail.com)
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "meta_base.hpp"
|
||||
#include "meta_types.hpp"
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < typename From >
|
||||
struct cvref_traits {
|
||||
static constexpr bool is_lvalue = std::is_lvalue_reference_v<From>;
|
||||
static constexpr bool is_rvalue = std::is_rvalue_reference_v<From>;
|
||||
static constexpr bool is_const = std::is_const_v<std::remove_reference_t<From>>;
|
||||
static constexpr bool is_volatile = std::is_volatile_v<std::remove_reference_t<From>>;
|
||||
|
||||
template < bool yesno, template < typename > typename Q, typename V >
|
||||
using apply_t_if = std::conditional_t<yesno, Q<V>, V>;
|
||||
|
||||
template < typename To >
|
||||
using copy_to =
|
||||
apply_t_if<is_lvalue, std::add_lvalue_reference_t,
|
||||
apply_t_if<is_rvalue, std::add_rvalue_reference_t,
|
||||
apply_t_if<is_const, std::add_const_t,
|
||||
apply_t_if<is_volatile, std::add_volatile_t,
|
||||
std::remove_cvref_t<To>>>>>;
|
||||
};
|
||||
|
||||
template < typename From, typename To >
|
||||
struct copy_cvref {
|
||||
using type = typename cvref_traits<From>::template copy_to<To>;
|
||||
};
|
||||
|
||||
template < typename From, typename To >
|
||||
using copy_cvref_t = typename copy_cvref<From, To>::type;
|
||||
}
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < typename T >
|
||||
concept value_kind =
|
||||
std::is_same_v<T, value>;
|
||||
|
||||
template < typename T >
|
||||
concept decay_value_kind =
|
||||
value_kind<std::decay_t<T>>;
|
||||
|
||||
template < typename T >
|
||||
concept uvalue_kind =
|
||||
std::is_same_v<T, arg_base> ||
|
||||
std::is_same_v<T, arg> ||
|
||||
std::is_same_v<T, inst_base> ||
|
||||
std::is_same_v<T, inst> ||
|
||||
std::is_same_v<T, value>;
|
||||
|
||||
template < typename T >
|
||||
concept decay_uvalue_kind =
|
||||
uvalue_kind<std::decay_t<T>>;
|
||||
|
||||
template < typename T >
|
||||
concept decay_non_uvalue_kind =
|
||||
(!decay_uvalue_kind<T>);
|
||||
|
||||
template < typename T >
|
||||
concept arg_lvalue_ref_kind =
|
||||
(decay_non_uvalue_kind<T>) &&
|
||||
(std::is_lvalue_reference_v<T>);
|
||||
|
||||
template < typename T >
|
||||
concept arg_rvalue_ref_kind =
|
||||
(decay_non_uvalue_kind<T>) &&
|
||||
(!std::is_reference_v<T> || std::is_rvalue_reference_v<T>);
|
||||
|
||||
template < typename T >
|
||||
concept inst_class_ref_kind =
|
||||
(std::is_class_v<T>) ||
|
||||
(std::is_reference_v<T> && std::is_class_v<std::remove_reference_t<T>>);
|
||||
|
||||
template < typename T >
|
||||
concept inst_class_lvalue_ref_kind =
|
||||
(decay_non_uvalue_kind<T>) &&
|
||||
(std::is_lvalue_reference_v<T> && std::is_class_v<std::remove_reference_t<T>>);
|
||||
|
||||
template < typename T >
|
||||
concept inst_class_rvalue_ref_kind =
|
||||
(decay_non_uvalue_kind<T>) &&
|
||||
(std::is_class_v<T> || (std::is_rvalue_reference_v<T> && std::is_class_v<std::remove_reference_t<T>>));
|
||||
}
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
class noncopyable {
|
||||
protected:
|
||||
noncopyable() = default;
|
||||
~noncopyable() = default;
|
||||
public:
|
||||
noncopyable(noncopyable&&) = delete;
|
||||
noncopyable(const noncopyable&) = delete;
|
||||
noncopyable& operator=(noncopyable&&) = delete;
|
||||
noncopyable& operator=(const noncopyable&) = delete;
|
||||
};
|
||||
}
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < typename... Ts >
|
||||
struct overloaded : Ts... {
|
||||
using Ts::operator()...;
|
||||
};
|
||||
|
||||
template < typename... Ts >
|
||||
overloaded(Ts...) -> overloaded<Ts...>;
|
||||
}
|
||||
|
||||
namespace meta_hpp
|
||||
{
|
||||
class value final {
|
||||
public:
|
||||
value() = default;
|
||||
~value() noexcept;
|
||||
|
||||
value(value&& other) noexcept;
|
||||
value(const value& other);
|
||||
|
||||
value& operator=(value&& other) noexcept;
|
||||
value& operator=(const value& other);
|
||||
|
||||
template < detail::decay_non_uvalue_kind T >
|
||||
requires detail::stdex::copy_constructible<std::decay_t<T>>
|
||||
explicit value(T&& val);
|
||||
|
||||
template < detail::decay_non_uvalue_kind T >
|
||||
requires detail::stdex::copy_constructible<std::decay_t<T>>
|
||||
value& operator=(T&& val);
|
||||
|
||||
[[nodiscard]] bool is_valid() const noexcept;
|
||||
[[nodiscard]] explicit operator bool() const noexcept;
|
||||
|
||||
void reset() noexcept;
|
||||
void swap(value& other) noexcept;
|
||||
|
||||
[[nodiscard]] any_type get_type() const noexcept;
|
||||
|
||||
[[nodiscard]] void* data() noexcept;
|
||||
[[nodiscard]] const void* data() const noexcept;
|
||||
[[nodiscard]] const void* cdata() const noexcept;
|
||||
|
||||
[[nodiscard]] value operator*() const;
|
||||
[[nodiscard]] value operator[](std::size_t index) const;
|
||||
|
||||
template < typename T >
|
||||
[[nodiscard]] std::decay_t<T>& cast() &;
|
||||
|
||||
template < typename T >
|
||||
[[nodiscard]] std::decay_t<T>&& cast() &&;
|
||||
|
||||
template < typename T >
|
||||
[[nodiscard]] const std::decay_t<T>& cast() const &;
|
||||
|
||||
template < typename T >
|
||||
[[nodiscard]] const std::decay_t<T>&& cast() const &&;
|
||||
|
||||
template < typename T >
|
||||
[[nodiscard]] std::decay_t<T>* try_cast() noexcept;
|
||||
|
||||
template < typename T >
|
||||
[[nodiscard]] const std::decay_t<T>* try_cast() const noexcept;
|
||||
|
||||
friend bool operator<(const value& l, const value& r);
|
||||
friend bool operator==(const value& l, const value& r);
|
||||
friend std::istream& operator>>(std::istream& is, value& v);
|
||||
friend std::ostream& operator<<(std::ostream& os, const value& v);
|
||||
private:
|
||||
struct vtable_t;
|
||||
vtable_t* vtable_{};
|
||||
private:
|
||||
using buffer_t = std::aligned_storage_t<sizeof(void*) * 2, alignof(void*)>;
|
||||
using storage_u = std::variant<std::monostate, void*, buffer_t>;
|
||||
storage_u storage_{};
|
||||
};
|
||||
|
||||
inline void swap(value& l, value& r) noexcept {
|
||||
l.swap(r);
|
||||
}
|
||||
}
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
class arg_base {
|
||||
public:
|
||||
enum class ref_types {
|
||||
lvalue,
|
||||
const_lvalue,
|
||||
rvalue,
|
||||
const_rvalue,
|
||||
};
|
||||
public:
|
||||
arg_base() = delete;
|
||||
|
||||
arg_base(arg_base&&) = default;
|
||||
arg_base(const arg_base&) = default;
|
||||
|
||||
arg_base& operator=(arg_base&&) = delete;
|
||||
arg_base& operator=(const arg_base&) = delete;
|
||||
|
||||
virtual ~arg_base() = default;
|
||||
|
||||
template < decay_value_kind T >
|
||||
explicit arg_base(T&& v);
|
||||
|
||||
template < decay_non_uvalue_kind T >
|
||||
explicit arg_base(T&& v);
|
||||
|
||||
template < arg_lvalue_ref_kind T >
|
||||
explicit arg_base(type_list<T>);
|
||||
|
||||
template < arg_rvalue_ref_kind T >
|
||||
explicit arg_base(type_list<T>);
|
||||
|
||||
explicit arg_base(value& v);
|
||||
explicit arg_base(const value& v);
|
||||
|
||||
explicit arg_base(value&& v);
|
||||
explicit arg_base(const value&& v);
|
||||
|
||||
[[nodiscard]] bool is_const() const noexcept;
|
||||
[[nodiscard]] bool is_lvalue() const noexcept;
|
||||
[[nodiscard]] bool is_rvalue() const noexcept;
|
||||
|
||||
[[nodiscard]] ref_types get_ref_type() const noexcept;
|
||||
[[nodiscard]] const any_type& get_raw_type() const noexcept;
|
||||
|
||||
template < typename To >
|
||||
[[nodiscard]] bool can_cast_to() const noexcept;
|
||||
private:
|
||||
ref_types ref_type_{};
|
||||
any_type raw_type_{};
|
||||
};
|
||||
}
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
class arg final : public arg_base {
|
||||
public:
|
||||
arg() = delete;
|
||||
|
||||
arg(arg&&) = default;
|
||||
arg(const arg&) = default;
|
||||
|
||||
arg& operator=(arg&&) = delete;
|
||||
arg& operator=(const arg&) = delete;
|
||||
|
||||
~arg() override = default;
|
||||
|
||||
template < decay_value_kind T >
|
||||
explicit arg(T&& v);
|
||||
|
||||
template < decay_non_uvalue_kind T >
|
||||
explicit arg(T&& v);
|
||||
|
||||
template < typename To >
|
||||
[[nodiscard]] To cast() const;
|
||||
private:
|
||||
void* data_{};
|
||||
};
|
||||
}
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
class inst_base {
|
||||
public:
|
||||
enum class ref_types {
|
||||
lvalue,
|
||||
const_lvalue,
|
||||
rvalue,
|
||||
const_rvalue,
|
||||
};
|
||||
public:
|
||||
inst_base() = delete;
|
||||
|
||||
inst_base(inst_base&&) = default;
|
||||
inst_base(const inst_base&) = default;
|
||||
|
||||
inst_base& operator=(inst_base&&) = delete;
|
||||
inst_base& operator=(const inst_base&) = delete;
|
||||
|
||||
virtual ~inst_base() = default;
|
||||
|
||||
template < decay_value_kind T >
|
||||
explicit inst_base(T&& v);
|
||||
|
||||
template < decay_non_uvalue_kind T >
|
||||
explicit inst_base(T&& v);
|
||||
|
||||
template < inst_class_lvalue_ref_kind T >
|
||||
explicit inst_base(type_list<T>);
|
||||
|
||||
template < inst_class_rvalue_ref_kind T >
|
||||
explicit inst_base(type_list<T>);
|
||||
|
||||
explicit inst_base(value& v);
|
||||
explicit inst_base(const value& v);
|
||||
|
||||
explicit inst_base(value&& v);
|
||||
explicit inst_base(const value&& v);
|
||||
|
||||
[[nodiscard]] bool is_const() const noexcept;
|
||||
[[nodiscard]] bool is_lvalue() const noexcept;
|
||||
[[nodiscard]] bool is_rvalue() const noexcept;
|
||||
|
||||
[[nodiscard]] ref_types get_ref_type() const noexcept;
|
||||
[[nodiscard]] const any_type& get_raw_type() const noexcept;
|
||||
|
||||
template < inst_class_ref_kind Q >
|
||||
[[nodiscard]] bool can_cast_to() const noexcept;
|
||||
private:
|
||||
ref_types ref_type_{};
|
||||
any_type raw_type_{};
|
||||
};
|
||||
}
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
class inst final : public inst_base {
|
||||
public:
|
||||
inst() = delete;
|
||||
|
||||
inst(inst&&) = default;
|
||||
inst(const inst&) = default;
|
||||
|
||||
inst& operator=(inst&&) = delete;
|
||||
inst& operator=(const inst&) = delete;
|
||||
|
||||
~inst() override = default;
|
||||
|
||||
template < decay_value_kind T >
|
||||
explicit inst(T&& v);
|
||||
|
||||
template < decay_non_uvalue_kind T >
|
||||
explicit inst(T&& v);
|
||||
|
||||
template < inst_class_ref_kind Q >
|
||||
[[nodiscard]] decltype(auto) cast() const;
|
||||
private:
|
||||
void* data_{};
|
||||
};
|
||||
}
|
||||
@@ -1,209 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* 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, by Matvey Cherevko (blackmatov@gmail.com)
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../meta_base.hpp"
|
||||
#include "../meta_utilities.hpp"
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
namespace impl
|
||||
{
|
||||
template < inst_class_ref_kind Q, bool is_const, bool is_lvalue, bool is_rvalue >
|
||||
struct inst_traits_impl;
|
||||
|
||||
template < inst_class_ref_kind Q >
|
||||
struct inst_traits_impl<Q, false, false, false> {
|
||||
using class_type = std::remove_cvref_t<Q>;
|
||||
using method_type = void(class_type::*)();
|
||||
};
|
||||
|
||||
template < inst_class_ref_kind Q >
|
||||
struct inst_traits_impl<Q, false, true, false> {
|
||||
using class_type = std::remove_cvref_t<Q>;
|
||||
using method_type = void(class_type::*)() &;
|
||||
};
|
||||
|
||||
template < inst_class_ref_kind Q >
|
||||
struct inst_traits_impl<Q, false, false, true> {
|
||||
using class_type = std::remove_cvref_t<Q>;
|
||||
using method_type = void(class_type::*)() &&;
|
||||
};
|
||||
|
||||
template < inst_class_ref_kind Q >
|
||||
struct inst_traits_impl<Q, true, false, false> {
|
||||
using class_type = std::remove_cvref_t<Q>;
|
||||
using method_type = void(class_type::*)() const;
|
||||
};
|
||||
|
||||
template < inst_class_ref_kind Q >
|
||||
struct inst_traits_impl<Q, true, true, false> {
|
||||
using class_type = std::remove_cvref_t<Q>;
|
||||
using method_type = void(class_type::*)() const &;
|
||||
};
|
||||
|
||||
template < inst_class_ref_kind Q >
|
||||
struct inst_traits_impl<Q, true, false, true> {
|
||||
using class_type = std::remove_cvref_t<Q>;
|
||||
using method_type = void(class_type::*)() const &&;
|
||||
};
|
||||
}
|
||||
|
||||
template < inst_class_ref_kind Q >
|
||||
struct inst_traits final : impl::inst_traits_impl<Q,
|
||||
cvref_traits<Q>::is_const,
|
||||
cvref_traits<Q>::is_lvalue,
|
||||
cvref_traits<Q>::is_rvalue> {};
|
||||
}
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < decay_value_kind T >
|
||||
// NOLINTNEXTLINE(readability-named-parameter)
|
||||
inst_base::inst_base(T&&)
|
||||
: inst_base{type_list<T&&>{}} {}
|
||||
|
||||
template < decay_non_uvalue_kind T >
|
||||
// NOLINTNEXTLINE(readability-named-parameter)
|
||||
inst_base::inst_base(T&&)
|
||||
: inst_base{type_list<T&&>{}} {}
|
||||
|
||||
template < inst_class_lvalue_ref_kind T >
|
||||
// NOLINTNEXTLINE(readability-named-parameter)
|
||||
inst_base::inst_base(type_list<T>)
|
||||
: ref_type_{std::is_const_v<std::remove_reference_t<T>>
|
||||
? ref_types::const_lvalue
|
||||
: ref_types::lvalue}
|
||||
, raw_type_{resolve_type<std::remove_cvref_t<T>>()} {}
|
||||
|
||||
template < inst_class_rvalue_ref_kind T >
|
||||
// NOLINTNEXTLINE(readability-named-parameter)
|
||||
inst_base::inst_base(type_list<T>)
|
||||
: ref_type_{std::is_const_v<std::remove_reference_t<T>>
|
||||
? ref_types::const_rvalue
|
||||
: ref_types::rvalue}
|
||||
, raw_type_{resolve_type<std::remove_cvref_t<T>>()} {}
|
||||
|
||||
inline inst_base::inst_base(value& v)
|
||||
: ref_type_{ref_types::lvalue}
|
||||
, raw_type_{v.get_type()} {}
|
||||
|
||||
inline inst_base::inst_base(const value& v)
|
||||
: ref_type_{ref_types::const_lvalue}
|
||||
, raw_type_{v.get_type()} {}
|
||||
|
||||
inline inst_base::inst_base(value&& v)
|
||||
: ref_type_{ref_types::rvalue}
|
||||
, raw_type_{v.get_type()} {}
|
||||
|
||||
inline inst_base::inst_base(const value&& v)
|
||||
: ref_type_{ref_types::const_rvalue}
|
||||
, raw_type_{v.get_type()} {}
|
||||
|
||||
inline bool inst_base::is_const() const noexcept {
|
||||
return ref_type_ == ref_types::const_lvalue
|
||||
|| ref_type_ == ref_types::const_rvalue;
|
||||
}
|
||||
|
||||
inline bool inst_base::is_lvalue() const noexcept {
|
||||
return ref_type_ == ref_types::lvalue
|
||||
|| ref_type_ == ref_types::const_lvalue;
|
||||
}
|
||||
|
||||
inline bool inst_base::is_rvalue() const noexcept {
|
||||
return ref_type_ == ref_types::rvalue
|
||||
|| ref_type_ == ref_types::const_rvalue;
|
||||
}
|
||||
|
||||
inline inst_base::ref_types inst_base::get_ref_type() const noexcept {
|
||||
return ref_type_;
|
||||
}
|
||||
|
||||
inline const any_type& inst_base::get_raw_type() const noexcept {
|
||||
return raw_type_;
|
||||
}
|
||||
|
||||
template < inst_class_ref_kind Q >
|
||||
bool inst_base::can_cast_to() const noexcept {
|
||||
using inst_class = typename inst_traits<Q>::class_type;
|
||||
using inst_method = typename inst_traits<Q>::method_type;
|
||||
|
||||
const any_type& from_type = get_raw_type();
|
||||
const any_type& to_type = resolve_type<inst_class>();
|
||||
|
||||
const auto is_a = [](const any_type& base, const any_type& derived){
|
||||
return (base == derived)
|
||||
|| (base.is_class() && derived.is_class() && base.as_class().is_base_of(derived.as_class()));
|
||||
};
|
||||
|
||||
const auto is_invocable = [this](){
|
||||
switch ( get_ref_type() ) {
|
||||
case ref_types::lvalue:
|
||||
return std::is_invocable_v<inst_method, inst_class&>;
|
||||
case ref_types::const_lvalue:
|
||||
return std::is_invocable_v<inst_method, const inst_class&>;
|
||||
case ref_types::rvalue:
|
||||
return std::is_invocable_v<inst_method, inst_class&&>;
|
||||
case ref_types::const_rvalue:
|
||||
return std::is_invocable_v<inst_method, const inst_class&&>;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
return is_a(to_type, from_type) && is_invocable();
|
||||
}
|
||||
}
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < decay_value_kind T >
|
||||
inst::inst(T&& v)
|
||||
: inst_base{std::forward<T>(v)}
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast)
|
||||
, data_{const_cast<void*>(v.data())} {}
|
||||
|
||||
template < decay_non_uvalue_kind T >
|
||||
inst::inst(T&& v)
|
||||
: inst_base{std::forward<T>(v)}
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast)
|
||||
, data_{const_cast<std::remove_cvref_t<T>*>(std::addressof(v))} {}
|
||||
|
||||
template < inst_class_ref_kind Q >
|
||||
decltype(auto) inst::cast() const {
|
||||
if ( !can_cast_to<Q>() ) {
|
||||
throw std::logic_error("bad instance cast");
|
||||
}
|
||||
|
||||
using inst_class_cv = std::remove_reference_t<Q>;
|
||||
using inst_class = std::remove_cv_t<inst_class_cv>;
|
||||
|
||||
const any_type& from_type = get_raw_type();
|
||||
const any_type& to_type = resolve_type<inst_class>();
|
||||
|
||||
if ( from_type.is_class() && to_type.is_class() ) {
|
||||
const class_type& from_class = from_type.as_class();
|
||||
const class_type& to_class = to_type.as_class();
|
||||
|
||||
void* to_ptr = detail::pointer_upcast(data_, from_class, to_class);
|
||||
|
||||
if constexpr ( !std::is_reference_v<Q> ) {
|
||||
return *static_cast<inst_class_cv*>(to_ptr);
|
||||
}
|
||||
|
||||
if constexpr ( std::is_lvalue_reference_v<Q> ) {
|
||||
return *static_cast<inst_class_cv*>(to_ptr);
|
||||
}
|
||||
|
||||
if constexpr ( std::is_rvalue_reference_v<Q> ) {
|
||||
return std::move(*static_cast<inst_class_cv*>(to_ptr));
|
||||
}
|
||||
}
|
||||
|
||||
throw std::logic_error("bad instance cast");
|
||||
}
|
||||
}
|
||||
94
headers/meta.hpp/meta_value.hpp
Normal file
94
headers/meta.hpp/meta_value.hpp
Normal file
@@ -0,0 +1,94 @@
|
||||
/*******************************************************************************
|
||||
* 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, by Matvey Cherevko (blackmatov@gmail.com)
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "meta_base.hpp"
|
||||
#include "meta_types.hpp"
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < typename T >
|
||||
concept value_kind = stdex::same_as<T, value>;
|
||||
|
||||
template < typename T >
|
||||
concept decay_value_kind = value_kind<std::decay_t<T>>;
|
||||
|
||||
template < typename T >
|
||||
concept decay_non_value_kind = !decay_value_kind<T>;
|
||||
}
|
||||
|
||||
namespace meta_hpp
|
||||
{
|
||||
class value final {
|
||||
public:
|
||||
value() = default;
|
||||
~value() noexcept;
|
||||
|
||||
value(value&& other) noexcept;
|
||||
value(const value& other);
|
||||
|
||||
value& operator=(value&& other) noexcept;
|
||||
value& operator=(const value& other);
|
||||
|
||||
template < detail::decay_non_value_kind T >
|
||||
requires stdex::copy_constructible<std::decay_t<T>>
|
||||
explicit value(T&& val);
|
||||
|
||||
template < detail::decay_non_value_kind T >
|
||||
requires stdex::copy_constructible<std::decay_t<T>>
|
||||
value& operator=(T&& val);
|
||||
|
||||
[[nodiscard]] bool is_valid() const noexcept;
|
||||
[[nodiscard]] explicit operator bool() const noexcept;
|
||||
|
||||
void reset() noexcept;
|
||||
void swap(value& other) noexcept;
|
||||
|
||||
[[nodiscard]] const any_type& get_type() const noexcept;
|
||||
|
||||
[[nodiscard]] void* data() noexcept;
|
||||
[[nodiscard]] const void* data() const noexcept;
|
||||
[[nodiscard]] const void* cdata() const noexcept;
|
||||
|
||||
[[nodiscard]] value operator*() const;
|
||||
[[nodiscard]] value operator[](std::size_t index) const;
|
||||
|
||||
template < typename T >
|
||||
[[nodiscard]] std::decay_t<T>& cast() &;
|
||||
|
||||
template < typename T >
|
||||
[[nodiscard]] std::decay_t<T>&& cast() &&;
|
||||
|
||||
template < typename T >
|
||||
[[nodiscard]] const std::decay_t<T>& cast() const &;
|
||||
|
||||
template < typename T >
|
||||
[[nodiscard]] const std::decay_t<T>&& cast() const &&;
|
||||
|
||||
template < typename T >
|
||||
[[nodiscard]] std::decay_t<T>* try_cast() noexcept;
|
||||
|
||||
template < typename T >
|
||||
[[nodiscard]] const std::decay_t<T>* try_cast() const noexcept;
|
||||
|
||||
friend bool operator<(const value& l, const value& r);
|
||||
friend bool operator==(const value& l, const value& r);
|
||||
friend std::istream& operator>>(std::istream& is, value& v);
|
||||
friend std::ostream& operator<<(std::ostream& os, const value& v);
|
||||
private:
|
||||
struct vtable_t;
|
||||
vtable_t* vtable_{};
|
||||
private:
|
||||
using buffer_t = std::aligned_storage_t<sizeof(void*) * 2, alignof(void*)>;
|
||||
using storage_u = std::variant<std::monostate, void*, buffer_t>;
|
||||
storage_u storage_{};
|
||||
};
|
||||
|
||||
inline void swap(value& l, value& r) noexcept {
|
||||
l.swap(r);
|
||||
}
|
||||
}
|
||||
@@ -7,14 +7,16 @@
|
||||
#pragma once
|
||||
|
||||
#include "../meta_base.hpp"
|
||||
#include "../meta_utilities.hpp"
|
||||
#include "../meta_value.hpp"
|
||||
|
||||
#include "value_traits/deref_traits.hpp"
|
||||
#include "value_traits/equals_traits.hpp"
|
||||
#include "value_traits/index_traits.hpp"
|
||||
#include "value_traits/istream_traits.hpp"
|
||||
#include "value_traits/less_traits.hpp"
|
||||
#include "value_traits/ostream_traits.hpp"
|
||||
#include "../meta_detail/value_traits/deref_traits.hpp"
|
||||
#include "../meta_detail/value_traits/equals_traits.hpp"
|
||||
#include "../meta_detail/value_traits/index_traits.hpp"
|
||||
#include "../meta_detail/value_traits/istream_traits.hpp"
|
||||
#include "../meta_detail/value_traits/less_traits.hpp"
|
||||
#include "../meta_detail/value_traits/ostream_traits.hpp"
|
||||
|
||||
#include "../meta_detail/type_registry.hpp"
|
||||
|
||||
namespace meta_hpp
|
||||
{
|
||||
@@ -115,7 +117,7 @@ namespace meta_hpp
|
||||
template < typename Tp >
|
||||
static vtable_t* get() {
|
||||
static vtable_t table{
|
||||
.type = resolve_type<Tp>(),
|
||||
.type = detail::resolve_type<Tp>(),
|
||||
|
||||
.data = [](storage_u& from) noexcept -> void* {
|
||||
return storage_cast<Tp>(from);
|
||||
@@ -175,48 +177,48 @@ namespace meta_hpp
|
||||
},
|
||||
|
||||
.deref = +[]([[maybe_unused]] const value& v) -> value {
|
||||
if constexpr ( detail::has_value_deref_traits<Tp> ) {
|
||||
return detail::value_deref_traits<Tp>{}(v.cast<Tp>());
|
||||
if constexpr ( detail::has_deref_traits<Tp> ) {
|
||||
return detail::deref_traits<Tp>{}(v.cast<Tp>());
|
||||
} else {
|
||||
throw std::logic_error("value type doesn't have value deref traits");
|
||||
}
|
||||
},
|
||||
|
||||
.index = +[]([[maybe_unused]] const value& v, [[maybe_unused]] std::size_t index) -> value {
|
||||
if constexpr ( detail::has_value_index_traits<Tp> ) {
|
||||
return detail::value_index_traits<Tp>{}(v.cast<Tp>(), index);
|
||||
.index = +[]([[maybe_unused]] const value& v, [[maybe_unused]] std::size_t i) -> value {
|
||||
if constexpr ( detail::has_index_traits<Tp> ) {
|
||||
return detail::index_traits<Tp>{}(v.cast<Tp>(), i);
|
||||
} else {
|
||||
throw std::logic_error("value type doesn't have value index traits");
|
||||
}
|
||||
},
|
||||
|
||||
.less = +[]([[maybe_unused]] const value& l, [[maybe_unused]] const value& r) -> bool {
|
||||
if constexpr ( detail::has_value_less_traits<Tp> ) {
|
||||
return detail::value_less_traits<Tp>{}(l.cast<Tp>(), r.cast<Tp>());
|
||||
if constexpr ( detail::has_less_traits<Tp> ) {
|
||||
return detail::less_traits<Tp>{}(l.cast<Tp>(), r.cast<Tp>());
|
||||
} else {
|
||||
throw std::logic_error("value type doesn't have value less traits");
|
||||
}
|
||||
},
|
||||
|
||||
.equals = +[]([[maybe_unused]] const value& l, [[maybe_unused]] const value& r) -> bool {
|
||||
if constexpr ( detail::has_value_equals_traits<Tp> ) {
|
||||
return detail::value_equals_traits<Tp>{}(l.cast<Tp>(), r.cast<Tp>());
|
||||
if constexpr ( detail::has_equals_traits<Tp> ) {
|
||||
return detail::equals_traits<Tp>{}(l.cast<Tp>(), r.cast<Tp>());
|
||||
} else {
|
||||
throw std::logic_error("value type doesn't have value equals traits");
|
||||
}
|
||||
},
|
||||
|
||||
.istream = +[]([[maybe_unused]] std::istream& is, [[maybe_unused]] value& v) -> std::istream& {
|
||||
if constexpr ( detail::has_value_istream_traits<Tp> ) {
|
||||
return detail::value_istream_traits<Tp>{}(is, v.cast<Tp>());
|
||||
if constexpr ( detail::has_istream_traits<Tp> ) {
|
||||
return detail::istream_traits<Tp>{}(is, v.cast<Tp>());
|
||||
} else {
|
||||
throw std::logic_error("value type doesn't have value istream traits");
|
||||
}
|
||||
},
|
||||
|
||||
.ostream = +[]([[maybe_unused]] std::ostream& os, [[maybe_unused]] const value& v) -> std::ostream& {
|
||||
if constexpr ( detail::has_value_ostream_traits<Tp> ) {
|
||||
return detail::value_ostream_traits<Tp>{}(os, v.cast<Tp>());
|
||||
if constexpr ( detail::has_ostream_traits<Tp> ) {
|
||||
return detail::ostream_traits<Tp>{}(os, v.cast<Tp>());
|
||||
} else {
|
||||
throw std::logic_error("value type doesn't have value ostream traits");
|
||||
}
|
||||
@@ -260,14 +262,14 @@ namespace meta_hpp
|
||||
return *this;
|
||||
}
|
||||
|
||||
template < detail::decay_non_uvalue_kind T >
|
||||
requires detail::stdex::copy_constructible<std::decay_t<T>>
|
||||
template < detail::decay_non_value_kind T >
|
||||
requires stdex::copy_constructible<std::decay_t<T>>
|
||||
value::value(T&& val) {
|
||||
vtable_t::construct(*this, std::forward<T>(val));
|
||||
}
|
||||
|
||||
template < detail::decay_non_uvalue_kind T >
|
||||
requires detail::stdex::copy_constructible<std::decay_t<T>>
|
||||
template < detail::decay_non_value_kind T >
|
||||
requires stdex::copy_constructible<std::decay_t<T>>
|
||||
value& value::operator=(T&& val) {
|
||||
value{std::forward<T>(val)}.swap(*this);
|
||||
return *this;
|
||||
@@ -292,8 +294,9 @@ namespace meta_hpp
|
||||
vtable_t::swap(*this, other);
|
||||
}
|
||||
|
||||
inline any_type value::get_type() const noexcept {
|
||||
return vtable_ != nullptr ? vtable_->type : resolve_type<void>();
|
||||
inline const any_type& value::get_type() const noexcept {
|
||||
static any_type void_type = detail::resolve_type<void>();
|
||||
return vtable_ != nullptr ? vtable_->type : void_type;
|
||||
}
|
||||
|
||||
inline void* value::data() noexcept {
|
||||
@@ -355,7 +358,7 @@ namespace meta_hpp
|
||||
template < typename T >
|
||||
std::decay_t<T>* value::try_cast() noexcept {
|
||||
using Tp = std::decay_t<T>;
|
||||
return get_type() == resolve_type<Tp>()
|
||||
return get_type() == detail::resolve_type<Tp>()
|
||||
? vtable_t::storage_cast<Tp>(storage_)
|
||||
: nullptr;
|
||||
}
|
||||
@@ -363,7 +366,7 @@ namespace meta_hpp
|
||||
template < typename T >
|
||||
const std::decay_t<T>* value::try_cast() const noexcept {
|
||||
using Tp = std::decay_t<T>;
|
||||
return get_type() == resolve_type<Tp>()
|
||||
return get_type() == detail::resolve_type<Tp>()
|
||||
? vtable_t::storage_cast<Tp>(storage_)
|
||||
: nullptr;
|
||||
}
|
||||
@@ -377,9 +380,10 @@ namespace meta_hpp
|
||||
return true;
|
||||
}
|
||||
|
||||
const any_type& r_type = resolve_type<T>();
|
||||
return (l.get_type() < r_type)
|
||||
|| (l.get_type() == r_type && std::less<>{}(l.cast<T>(), r));
|
||||
const any_type& l_type = l.get_type();
|
||||
const any_type& r_type = detail::resolve_type<T>();
|
||||
|
||||
return (l_type < r_type) || (l_type == r_type && l.cast<T>() < r);
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
@@ -388,9 +392,10 @@ namespace meta_hpp
|
||||
return false;
|
||||
}
|
||||
|
||||
const any_type& l_type = resolve_type<T>();
|
||||
return (l_type < r.get_type())
|
||||
|| (l_type == r.get_type() && std::less<>{}(l, r.cast<T>()));
|
||||
const any_type& l_type = detail::resolve_type<T>();
|
||||
const any_type& r_type = r.get_type();
|
||||
|
||||
return (l_type < r_type) || (l_type == r_type && l < r.cast<T>());
|
||||
}
|
||||
|
||||
[[nodiscard]] inline bool operator<(const value& l, const value& r) {
|
||||
@@ -402,8 +407,10 @@ namespace meta_hpp
|
||||
return true;
|
||||
}
|
||||
|
||||
return (l.get_type() < r.get_type())
|
||||
|| (l.get_type() == r.get_type() && l.vtable_->less(l, r));
|
||||
const any_type& l_type = l.get_type();
|
||||
const any_type& r_type = r.get_type();
|
||||
|
||||
return (l_type < r_type) || (l_type == r_type && l.vtable_->less(l, r));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -415,8 +422,10 @@ namespace meta_hpp
|
||||
return false;
|
||||
}
|
||||
|
||||
return l.get_type() == resolve_type<T>()
|
||||
&& std::equal_to<>{}(l.cast<T>(), r);
|
||||
const any_type& l_type = l.get_type();
|
||||
const any_type& r_type = detail::resolve_type<T>();
|
||||
|
||||
return l_type == r_type && l.cast<T>() == r;
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
@@ -425,8 +434,10 @@ namespace meta_hpp
|
||||
return false;
|
||||
}
|
||||
|
||||
return resolve_type<T>() == r.get_type()
|
||||
&& std::equal_to<>{}(l, r.cast<T>());
|
||||
const any_type& l_type = detail::resolve_type<T>();
|
||||
const any_type& r_type = r.get_type();
|
||||
|
||||
return l_type == r_type && l == r.cast<T>();
|
||||
}
|
||||
|
||||
[[nodiscard]] inline bool operator==(const value& l, const value& r) {
|
||||
@@ -438,8 +449,10 @@ namespace meta_hpp
|
||||
return true;
|
||||
}
|
||||
|
||||
return l.get_type() == r.get_type()
|
||||
&& l.vtable_->equals(l, r);
|
||||
const any_type& l_type = l.get_type();
|
||||
const any_type& r_type = r.get_type();
|
||||
|
||||
return l_type == r_type && l.vtable_->equals(l, r);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,10 @@
|
||||
|
||||
#include "../meta_base.hpp"
|
||||
#include "../meta_states.hpp"
|
||||
#include "../meta_utilities.hpp"
|
||||
#include "../meta_value.hpp"
|
||||
|
||||
#include "../meta_detail/value_utilities/arg.hpp"
|
||||
#include "../meta_detail/value_utilities/inst.hpp"
|
||||
|
||||
namespace meta_hpp
|
||||
{
|
||||
@@ -57,7 +57,7 @@ TEST_CASE("meta/meta_examples/classes/type") {
|
||||
// prints all class methods
|
||||
fmt::print("* rectangle:\n");
|
||||
for ( auto&& [index, method] : rectangle_type.get_methods() ) {
|
||||
fmt::print(" + {}/{}\n", index.name, index.type.get_arity());
|
||||
fmt::print(" + {}/{}\n", index.get_name(), index.get_type().get_arity());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ TEST_CASE("meta/meta_examples/enums/type") {
|
||||
// prints all enumerators
|
||||
fmt::print("* align:\n");
|
||||
for ( auto&& [index, evalue] : align_type.get_evalues() ) {
|
||||
fmt::print(" - {}:{}\n", index.name, evalue.get_underlying_value());
|
||||
fmt::print(" - {}:{}\n", index.get_name(), evalue.get_underlying_value());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -73,6 +73,6 @@ TEST_CASE("meta/meta_examples/functions/usage") {
|
||||
// prints all functions in the scope
|
||||
fmt::print("* {}:\n", math_scope.get_name());
|
||||
for ( auto&& [index, function] : math_scope.get_functions() ) {
|
||||
fmt::print(" + {}/{}\n", index.name, function.get_type().get_arity());
|
||||
fmt::print(" + {}/{}\n", index.get_name(), function.get_type().get_arity());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,6 +42,6 @@ TEST_CASE("meta/meta_examples/variables/usage") {
|
||||
// prints all variables in the scope
|
||||
fmt::print("* {}:\n", constants_scope.get_name());
|
||||
for ( auto&& [index, variable] : constants_scope.get_variables() ) {
|
||||
fmt::print(" - {}:{}\n", index.name, variable.get());
|
||||
fmt::print(" - {}:{}\n", index.get_name(), variable.get());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -116,45 +116,46 @@ TEST_CASE("meta/meta_features/diamond") {
|
||||
}
|
||||
|
||||
SUBCASE("pointer_upcast") {
|
||||
using meta::detail::pointer_upcast;
|
||||
{
|
||||
A a;
|
||||
CHECK(meta::pointer_upcast<A>(&a) == &a);
|
||||
CHECK_FALSE(meta::pointer_upcast<B>(&a));
|
||||
CHECK_FALSE(meta::pointer_upcast<C>(&a));
|
||||
CHECK_FALSE(meta::pointer_upcast<D>(&a));
|
||||
CHECK_FALSE(meta::pointer_upcast<E>(&a));
|
||||
CHECK(pointer_upcast<A>(&a) == &a);
|
||||
CHECK_FALSE(pointer_upcast<B>(&a));
|
||||
CHECK_FALSE(pointer_upcast<C>(&a));
|
||||
CHECK_FALSE(pointer_upcast<D>(&a));
|
||||
CHECK_FALSE(pointer_upcast<E>(&a));
|
||||
}
|
||||
{
|
||||
B b;
|
||||
CHECK(meta::pointer_upcast<A>(&b) == &b);
|
||||
CHECK(meta::pointer_upcast<B>(&b) == &b);
|
||||
CHECK_FALSE(meta::pointer_upcast<C>(&b));
|
||||
CHECK_FALSE(meta::pointer_upcast<D>(&b));
|
||||
CHECK_FALSE(meta::pointer_upcast<E>(&b));
|
||||
const B b;
|
||||
CHECK(pointer_upcast<A>(&b) == &b);
|
||||
CHECK(pointer_upcast<B>(&b) == &b);
|
||||
CHECK_FALSE(pointer_upcast<C>(&b));
|
||||
CHECK_FALSE(pointer_upcast<D>(&b));
|
||||
CHECK_FALSE(pointer_upcast<E>(&b));
|
||||
}
|
||||
{
|
||||
C c;
|
||||
CHECK(meta::pointer_upcast<A>(&c) == &c);
|
||||
CHECK_FALSE(meta::pointer_upcast<B>(&c));
|
||||
CHECK(meta::pointer_upcast<C>(&c) == &c);
|
||||
CHECK_FALSE(meta::pointer_upcast<D>(&c));
|
||||
CHECK_FALSE(meta::pointer_upcast<E>(&c));
|
||||
CHECK(pointer_upcast<A>(&c) == &c);
|
||||
CHECK_FALSE(pointer_upcast<B>(&c));
|
||||
CHECK(pointer_upcast<C>(&c) == &c);
|
||||
CHECK_FALSE(pointer_upcast<D>(&c));
|
||||
CHECK_FALSE(pointer_upcast<E>(&c));
|
||||
}
|
||||
{
|
||||
D d;
|
||||
CHECK(meta::pointer_upcast<A>(&d) == &d);
|
||||
CHECK(meta::pointer_upcast<B>(&d) == &d);
|
||||
CHECK(meta::pointer_upcast<C>(&d) == &d);
|
||||
CHECK(meta::pointer_upcast<D>(&d) == &d);
|
||||
CHECK_FALSE(meta::pointer_upcast<E>(&d));
|
||||
const D d;
|
||||
CHECK(pointer_upcast<A>(&d) == &d);
|
||||
CHECK(pointer_upcast<B>(&d) == &d);
|
||||
CHECK(pointer_upcast<C>(&d) == &d);
|
||||
CHECK(pointer_upcast<D>(&d) == &d);
|
||||
CHECK_FALSE(pointer_upcast<E>(&d));
|
||||
}
|
||||
{
|
||||
E e;
|
||||
CHECK_FALSE(meta::pointer_upcast<A>(&e));
|
||||
CHECK_FALSE(meta::pointer_upcast<B>(&e));
|
||||
CHECK_FALSE(meta::pointer_upcast<C>(&e));
|
||||
CHECK_FALSE(meta::pointer_upcast<D>(&e));
|
||||
CHECK(meta::pointer_upcast<E>(&e) == &e);
|
||||
CHECK_FALSE(pointer_upcast<A>(&e));
|
||||
CHECK_FALSE(pointer_upcast<B>(&e));
|
||||
CHECK_FALSE(pointer_upcast<C>(&e));
|
||||
CHECK_FALSE(pointer_upcast<D>(&e));
|
||||
CHECK(pointer_upcast<E>(&e) == &e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -315,4 +316,23 @@ TEST_CASE("meta/meta_features/diamond") {
|
||||
CHECK(&e_inst.cast<E&>() == e_val.try_cast<E>());
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("resolve_polymorphic_type") {
|
||||
const D d;
|
||||
|
||||
const A& ad = d;
|
||||
const B& bd = d;
|
||||
const C& cd = d;
|
||||
const D& dd = d;
|
||||
|
||||
CHECK(meta::resolve_type(ad) == meta::resolve_type<A>());
|
||||
CHECK(meta::resolve_type(bd) == meta::resolve_type<B>());
|
||||
CHECK(meta::resolve_type(cd) == meta::resolve_type<C>());
|
||||
CHECK(meta::resolve_type(dd) == meta::resolve_type<D>());
|
||||
|
||||
CHECK(meta::resolve_polymorphic_type(ad) == meta::resolve_type<D>());
|
||||
CHECK(meta::resolve_polymorphic_type(bd) == meta::resolve_type<D>());
|
||||
CHECK(meta::resolve_polymorphic_type(cd) == meta::resolve_type<D>());
|
||||
CHECK(meta::resolve_polymorphic_type(dd) == meta::resolve_type<D>());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,8 +47,8 @@ TEST_CASE("meta/meta_states/evalue") {
|
||||
const meta::evalue evalue = color_type.get_evalue("green");
|
||||
REQUIRE(evalue);
|
||||
|
||||
CHECK(evalue.get_index().type == evalue.get_type());
|
||||
CHECK(evalue.get_index().name == "green");
|
||||
CHECK(evalue.get_index().get_type() == evalue.get_type());
|
||||
CHECK(evalue.get_index().get_name() == "green");
|
||||
|
||||
CHECK(evalue.get_type() == meta::resolve_type<color>());
|
||||
CHECK(evalue.get_name() == "green");
|
||||
@@ -56,7 +56,7 @@ TEST_CASE("meta/meta_states/evalue") {
|
||||
CHECK(evalue.get_value() == color::green);
|
||||
CHECK(evalue.get_value().get_type() == color_type);
|
||||
|
||||
CHECK(evalue.get_underlying_value() == meta::detail::stdex::to_underlying(color::green));
|
||||
CHECK(evalue.get_underlying_value() == meta::stdex::to_underlying(color::green));
|
||||
CHECK(evalue.get_underlying_value().get_type() == color_type.get_underlying_type());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,8 +66,8 @@ TEST_CASE("meta/meta_states/function") {
|
||||
const meta::function func = ivec2_type.get_function("iadd");
|
||||
REQUIRE(func);
|
||||
|
||||
CHECK(func.get_index().type == func.get_type());
|
||||
CHECK(func.get_index().name == "iadd");
|
||||
CHECK(func.get_index().get_type() == func.get_type());
|
||||
CHECK(func.get_index().get_name() == "iadd");
|
||||
|
||||
CHECK(func.get_type() == meta::resolve_type(&ivec2::iadd));
|
||||
CHECK(func.get_name() == "iadd");
|
||||
@@ -95,8 +95,8 @@ TEST_CASE("meta/meta_states/function") {
|
||||
const meta::function func = ivec2_type.get_function("ilength2");
|
||||
REQUIRE(func);
|
||||
|
||||
CHECK(func.get_index().type == func.get_type());
|
||||
CHECK(func.get_index().name == "ilength2");
|
||||
CHECK(func.get_index().get_type() == func.get_type());
|
||||
CHECK(func.get_index().get_name() == "ilength2");
|
||||
|
||||
CHECK(func.get_type() == meta::resolve_type(&ivec2::ilength2));
|
||||
CHECK(func.get_name() == "ilength2");
|
||||
|
||||
@@ -66,10 +66,10 @@ TEST_CASE("meta/meta_types/class_type") {
|
||||
.member_("base_member_1", &base_clazz_1::base_member_1)
|
||||
.method_("base_method_1", &base_clazz_1::base_method_1)
|
||||
.function_("base_function_1", &base_clazz_1::base_function_1)
|
||||
.method_("base_method_1_overloaded", meta::select<int(int) const>(&base_clazz_1::base_method_1_overloaded))
|
||||
.method_("base_method_1_overloaded", meta::select<int(float) const>(&base_clazz_1::base_method_1_overloaded))
|
||||
.function_("base_function_1_overloaded", meta::select<int(int)>(&base_clazz_1::base_function_1_overloaded))
|
||||
.function_("base_function_1_overloaded", meta::select<int(int,int)>(&base_clazz_1::base_function_1_overloaded))
|
||||
.method_("base_method_1_overloaded", meta::select_overload<int(int) const>(&base_clazz_1::base_method_1_overloaded))
|
||||
.method_("base_method_1_overloaded", meta::select_overload<int(float) const>(&base_clazz_1::base_method_1_overloaded))
|
||||
.function_("base_function_1_overloaded", meta::select_overload<int(int)>(&base_clazz_1::base_function_1_overloaded))
|
||||
.function_("base_function_1_overloaded", meta::select_overload<int(int,int)>(&base_clazz_1::base_function_1_overloaded))
|
||||
.variable_("base_variable_1", &base_clazz_1::base_variable_1);
|
||||
|
||||
meta::class_<base_clazz_2>()
|
||||
|
||||
@@ -90,7 +90,7 @@ TEST_CASE("meta/meta_types/enum_type") {
|
||||
const meta::evalue green_value = color_type.get_evalue("green");
|
||||
REQUIRE(green_value);
|
||||
CHECK(green_value.get_value() == color::green);
|
||||
CHECK(green_value.get_underlying_value() == meta::detail::stdex::to_underlying(color::green));
|
||||
CHECK(green_value.get_underlying_value() == meta::stdex::to_underlying(color::green));
|
||||
}
|
||||
|
||||
{
|
||||
@@ -107,7 +107,7 @@ TEST_CASE("meta/meta_types/enum_type") {
|
||||
const meta::evalue green_value = ecolor_type.get_evalue("green");
|
||||
REQUIRE(green_value);
|
||||
CHECK(green_value.get_value() == ecolor_green);
|
||||
CHECK(green_value.get_underlying_value() == meta::detail::stdex::to_underlying(ecolor_green));
|
||||
CHECK(green_value.get_underlying_value() == meta::stdex::to_underlying(ecolor_green));
|
||||
}
|
||||
|
||||
{
|
||||
|
||||
11
untests/meta_untests.cpp
Normal file
11
untests/meta_untests.cpp
Normal file
@@ -0,0 +1,11 @@
|
||||
/*******************************************************************************
|
||||
* 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, by Matvey Cherevko (blackmatov@gmail.com)
|
||||
******************************************************************************/
|
||||
|
||||
#include "meta_untests.hpp"
|
||||
|
||||
TEST_CASE("meta_hpp") {
|
||||
namespace meta = meta_hpp;
|
||||
}
|
||||
@@ -69,7 +69,7 @@ namespace
|
||||
#define META_HPP_CHECK_INVOCABLE(FromValue, FName, ToType)\
|
||||
{\
|
||||
using namespace meta::detail;\
|
||||
auto function_ptr = meta::select<int(ToType)>(&FName);\
|
||||
auto function_ptr = meta::select_overload<int(ToType)>(&FName);\
|
||||
meta::function f_state{function_state::make<meta::function_policy::as_copy>("", function_ptr)};\
|
||||
\
|
||||
if ( std::is_invocable_v<decltype(function_ptr), decltype(FromValue)> ) {\
|
||||
@@ -93,7 +93,7 @@ namespace
|
||||
#define META_HPP_CHECK_INVOCABLE_2(FromValue, FName, FromType, ToType)\
|
||||
{\
|
||||
using namespace meta::detail;\
|
||||
auto function_ptr = meta::select<int(ToType)>(&FName);\
|
||||
auto function_ptr = meta::select_overload<int(ToType)>(&FName);\
|
||||
meta::function f_state{function_state::make<meta::function_policy::as_copy>("", function_ptr)};\
|
||||
\
|
||||
if ( std::is_invocable_v<decltype(function_ptr), FromType> ) {\
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace
|
||||
#define META_HPP_CHECK_INVOCABLE(Inst, FName, Qualifiers)\
|
||||
{\
|
||||
using namespace meta::detail;\
|
||||
auto method_ptr = meta::select<int() Qualifiers>(&clazz::FName);\
|
||||
auto method_ptr = meta::select_overload<int() Qualifiers>(&clazz::FName);\
|
||||
meta::method m_state{method_state::make<meta::method_policy::as_copy>("", method_ptr)};\
|
||||
\
|
||||
if ( std::is_invocable_v<decltype(method_ptr), decltype(Inst)> ) {\
|
||||
@@ -53,7 +53,7 @@ namespace
|
||||
#define META_HPP_CHECK_INVOCABLE_2(FromValue, FName, FromType, ToQualifiers)\
|
||||
{\
|
||||
using namespace meta::detail;\
|
||||
auto method_ptr = meta::select<int() ToQualifiers>(&clazz::FName);\
|
||||
auto method_ptr = meta::select_overload<int() ToQualifiers>(&clazz::FName);\
|
||||
meta::method m_state{method_state::make<meta::method_policy::as_copy>("", method_ptr)};\
|
||||
\
|
||||
if ( std::is_invocable_v<decltype(method_ptr), FromType> ) {\
|
||||
|
||||
Reference in New Issue
Block a user