Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions docs/spec/.pages
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,11 @@ nav:
- ProAccessible: ProAccessible.md
- ProBasicConvention: ProBasicConvention.md
- ProBasicFacade: ProBasicFacade.md
- ProBasicMeta: ProBasicMeta.md
- ProBasicReflection: ProBasicReflection.md
- ProConvention: ProConvention.md
- ProDispatch: ProDispatch.md
- ProFacade: ProFacade.md
- ProMeta: ProMeta.md
- ProOverload: ProOverload.md
- ProReflection: ProReflection.md
2 changes: 1 addition & 1 deletion docs/spec/ProBasicFacade.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ A type `F` meets the *ProBasicFacade* requirements if the following expressions
| Expressions | Semantics |
| ------------------------------ | ------------------------------------------------------------ |
| `typename F::convention_types` | A [tuple-like](https://en.cppreference.com/w/cpp/utility/tuple/tuple-like) type that contains any number of distinct types `Cs`. Each type `C` in `Cs` shall meet the [*ProBasicConvention* requirements](ProBasicConvention.md). |
| `typename F::reflection_types` | A [tuple-like](https://en.cppreference.com/w/cpp/utility/tuple/tuple-like) type that contains any number of distinct types `Rs`. Each type `R` in `Rs` shall define reflection data structure. |
| `typename F::reflection_types` | A [tuple-like](https://en.cppreference.com/w/cpp/utility/tuple/tuple-like) type that contains any number of distinct types `Rs`. Each type `R` in `Rs` shall meet the [*ProBasicReflection* requirements](ProBasicReflection.md). |
| `F::max_size` | A [core constant expression](https://en.cppreference.com/w/cpp/language/constant_expression) of type `std::size_t` that defines the maximum size of a pointer type. Shall be greater than `0` and a multiple of `F::max_align`. |
| `F::max_align` | A [core constant expression](https://en.cppreference.com/w/cpp/language/constant_expression) of type `std::size_t` that defines the maximum alignment of a pointer type. Shall be a power of `2`. |
| `F::copyability` | A [core constant expression](https://en.cppreference.com/w/cpp/language/constant_expression) of type [`constraint_level`](constraint_level.md) that defines the required copyability of a pointer type. |
Expand Down
21 changes: 21 additions & 0 deletions docs/spec/ProBasicMeta.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Named requirements: *ProBasicMeta*

> Since: 5.0.0

A type `M` meets the *ProBasicMeta* requirements if the following expressions are well-formed and have the specified semantics (let `m` be a value of type `M`, `cm` be a value of type `const M`).

| Expressions | Semantics |
| ----------- | ------------------------------------------------------------ |
| `M()` | Creates an object of type `M` holding unspecified metadata, shall not throw. |
| `M(cm)` | Creates an object of type `M` holding the metadata of `cm`, shall not throw. |
| `m = cm` | Replaces the metadata of `m` with the metadata of `cm`, shall not throw. |
| `m.~M()` | Destroys the object `m`, shall not throw. |

## Notes

A "meta" is an object holding metadata deduced from a type at compile time, stored in or referenced by a [`proxy`](proxy/README.md). Because `proxy` creates, copies, assigns, and destroys metadata in contexts specified not to throw, none of these operations may throw.

## See Also

- [*ProBasicReflection* requirements](ProBasicReflection.md)
- [*ProMeta* requirements](ProMeta.md)
3 changes: 2 additions & 1 deletion docs/spec/ProBasicReflection.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@ A type `R` meets the *ProBasicReflection* requirements if the following expressi
| Expressions | Semantics |
| ---------------------------- | ------------------------------------------------------------ |
| `R::is_direct` | A [core constant expression](https://en.cppreference.com/w/cpp/language/constant_expression) of type `bool`, specifying whether the reflection applies to a pointer type itself (`true`), or the element type of a pointer type (`false`). |
| `typename R::reflector_type` | A type that defines the data structure reflected from the type. |
| `typename R::reflector_type` | A type that defines the data structure reflected from the type. Shall meet the [*ProBasicMeta* requirements](ProBasicMeta.md) *(since 5.0.0)*. |

## See Also

- [*ProBasicFacade* requirements](ProBasicFacade.md)
- [*ProBasicMeta* requirements](ProBasicMeta.md)
- [*ProReflection* requirements](ProReflection.md)
14 changes: 14 additions & 0 deletions docs/spec/ProMeta.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Named requirements: *ProMeta*

> Since: 5.0.0

A type `M` meets the *ProMeta* requirements of a type `T` if `M` meets the [*ProBasicMeta* requirements](ProBasicMeta.md), and the following expressions are well-formed and have the specified semantics.

| Expressions | Semantics |
| -------------------------- | ------------------------------------------------------------ |
| `M(std::in_place_type<T>)` | Creates an object of type `M` holding implementation-defined metadata of type `T`, shall not throw. |

## See Also

- [*ProBasicMeta* requirements](ProBasicMeta.md)
- [*ProReflection* requirements](ProReflection.md)
3 changes: 2 additions & 1 deletion docs/spec/ProReflection.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ A type `R` meets the *ProReflection* requirements of a type `P` if `R` meets the

| Expressions | Semantics |
| --------------------------------------------------- | ------------------------------------------------------------ |
| `typename R::reflector_type(std::in_place_type<T>)` | Constructs a value of type `typename R::reflector_type`, reflecting implementation-defined metadata of type `T`. |
| `typename R::reflector_type(std::in_place_type<T>)` | Constructs a value of type `typename R::reflector_type`, reflecting implementation-defined metadata of type `T`. `typename R::reflector_type` shall meet the [*ProMeta* requirements](ProMeta.md) of `T` *(since 5.0.0)*. |

## See Also

- [*ProFacade* requirements](ProFacade.md)
- [*ProMeta* requirements](ProMeta.md)
3 changes: 2 additions & 1 deletion docs/spec/basic_facade_builder/add_reflection.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,9 @@ Adding duplicate reflection types is well-defined, whether done directly via `ad

struct LayoutReflector {
public:
LayoutReflector() = default;
template <class T>
constexpr explicit LayoutReflector(std::in_place_type_t<T>)
constexpr explicit LayoutReflector(std::in_place_type_t<T>) noexcept
: Size(sizeof(T)), Align(alignof(T)) {}

template <class P, class R>
Expand Down
3 changes: 2 additions & 1 deletion docs/spec/proxy/friend_reflect.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,9 @@ This function is useful when only metadata deduced from a type is needed. While

class CopyabilityReflector {
public:
CopyabilityReflector() = default;
template <class T>
constexpr explicit CopyabilityReflector(std::in_place_type_t<T>)
constexpr explicit CopyabilityReflector(std::in_place_type_t<T>) noexcept
: copyable_(std::is_copy_constructible_v<T>) {}

template <class P, class R>
Expand Down
3 changes: 2 additions & 1 deletion docs/spec/proxy_indirect_accessor/friend_reflect.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,9 @@ This function is useful when only metadata deduced from a type is needed. While

class LayoutReflector {
public:
LayoutReflector() = default;
template <class T>
constexpr explicit LayoutReflector(std::in_place_type_t<T>)
constexpr explicit LayoutReflector(std::in_place_type_t<T>) noexcept
: Size(sizeof(T)), Align(alignof(T)) {}

template <class P, class R>
Expand Down
3 changes: 2 additions & 1 deletion docs/spec/proxy_reflect.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,9 @@ This function is useful when only metadata deduced from a type is needed. While
class CopyabilityReflector {
public:
CopyabilityReflector() = default;
template <class T>
constexpr explicit CopyabilityReflector(std::in_place_type_t<T>)
constexpr explicit CopyabilityReflector(std::in_place_type_t<T>) noexcept
: copyable_(std::is_copy_constructible_v<T>) {}
template <class P, class R>
Expand Down
20 changes: 16 additions & 4 deletions include/proxy/v4/detail/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,20 @@ struct basic_conv_traits<C>
: specialization_t<basic_conv_traits_impl, typename C::overload_types, C> {
};

template <class M>
concept basic_meta =
std::is_nothrow_default_constructible_v<M> &&
std::is_nothrow_copy_constructible_v<M> &&
std::is_nothrow_copy_assignable_v<M> && std::is_nothrow_destructible_v<M>;
template <class M, class T>
concept meta = basic_meta<M> &&
std::is_nothrow_constructible_v<M, std::in_place_type_t<T>>;

template <class R>
concept basic_reflection = requires {
typename R::reflector_type;
} && is_is_direct_well_formed<R>() && basic_meta<typename R::reflector_type>;

template <class T>
struct a11y_traits_impl
: std::conditional<std::is_nothrow_default_constructible_v<T> &&
Expand Down Expand Up @@ -445,7 +459,7 @@ struct reflection_meta {
template <class T, bool IsDirect, class R>
consteval bool is_reflector_well_formed() {
if constexpr (IsDirect) {
if constexpr (std::is_constructible_v<R, std::in_place_type_t<T>>) {
if constexpr (meta<R, T>) {
return true;
}
} else {
Expand Down Expand Up @@ -602,9 +616,7 @@ struct basic_facade_conv_traits_impl<Cs...> : applicable_traits {};
template <class... Rs>
struct basic_facade_refl_traits_impl : inapplicable_traits {};
template <class... Rs>
requires((requires {
typename Rs::reflector_type;
} && is_is_direct_well_formed<Rs>()) && ...)
requires(basic_reflection<Rs> && ...)
struct basic_facade_refl_traits_impl<Rs...> : applicable_traits {};
template <class F>
struct basic_facade_traits : inapplicable_traits {};
Expand Down
2 changes: 1 addition & 1 deletion include/proxy/v4/detail/skills.h
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ struct proxy_cast_dispatch {
struct proxy_typeid_reflector {
proxy_typeid_reflector() = default;
template <class T>
constexpr explicit proxy_typeid_reflector(std::in_place_type_t<T>)
constexpr explicit proxy_typeid_reflector(std::in_place_type_t<T>) noexcept
: info(&typeid(T)) {}

template <class Self, class R>
Expand Down
13 changes: 7 additions & 6 deletions tests/proxy_creation_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,36 +19,37 @@ enum LifetimeModelType {
};

struct LifetimeModelReflector {
LifetimeModelReflector() = default;
template <class T>
constexpr explicit LifetimeModelReflector(
std::in_place_type_t<pro::detail::inplace_ptr<T>>)
std::in_place_type_t<pro::detail::inplace_ptr<T>>) noexcept
: Type(LifetimeModelType::kInplace) {}
template <class T, class Alloc>
constexpr explicit LifetimeModelReflector(
std::in_place_type_t<pro::detail::allocated_ptr<T, Alloc>>)
std::in_place_type_t<pro::detail::allocated_ptr<T, Alloc>>) noexcept
: Type(LifetimeModelType::kAllocated) {}
template <class T, class Alloc>
constexpr explicit LifetimeModelReflector(
std::in_place_type_t<pro::detail::compact_ptr<T, Alloc>>)
std::in_place_type_t<pro::detail::compact_ptr<T, Alloc>>) noexcept
: Type(LifetimeModelType::kCompact) {
static_assert(sizeof(pro::detail::compact_ptr<T, Alloc>) == sizeof(void*));
}
template <class T, class Alloc>
constexpr explicit LifetimeModelReflector(
std::in_place_type_t<pro::detail::shared_compact_ptr<T, Alloc>>)
std::in_place_type_t<pro::detail::shared_compact_ptr<T, Alloc>>) noexcept
: Type(LifetimeModelType::kSharedCompact) {
static_assert(sizeof(pro::detail::shared_compact_ptr<T, Alloc>) ==
sizeof(void*));
}
template <class T, class Alloc>
constexpr explicit LifetimeModelReflector(
std::in_place_type_t<pro::detail::strong_compact_ptr<T, Alloc>>)
std::in_place_type_t<pro::detail::strong_compact_ptr<T, Alloc>>) noexcept
: Type(LifetimeModelType::kStrongCompact) {
static_assert(sizeof(pro::detail::strong_compact_ptr<T, Alloc>) ==
sizeof(void*));
}
template <class T>
constexpr explicit LifetimeModelReflector(std::in_place_type_t<T>)
constexpr explicit LifetimeModelReflector(std::in_place_type_t<T>) noexcept
: Type(LifetimeModelType::kNone) {}

template <class Self, class R>
Expand Down
3 changes: 2 additions & 1 deletion tests/proxy_reflection_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ namespace proxy_reflection_tests_detail {

struct TraitsReflector {
public:
TraitsReflector() = default;
template <class T>
constexpr explicit TraitsReflector(std::in_place_type_t<T>)
constexpr explicit TraitsReflector(std::in_place_type_t<T>) noexcept
: is_default_constructible_(std::is_default_constructible_v<T>),
is_copy_constructible_(std::is_copy_constructible_v<T>),
is_nothrow_move_constructible_(std::is_nothrow_move_constructible_v<T>),
Expand Down
16 changes: 9 additions & 7 deletions tests/proxy_traits_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -249,9 +249,10 @@ static_assert(
static_assert(sizeof(pro::proxy<TrivialFacade>) == 2 * sizeof(void*));

struct ReflectionOfSmallPtr {
ReflectionOfSmallPtr() = default;
template <class P>
requires(sizeof(P) <= sizeof(void*))
constexpr ReflectionOfSmallPtr(std::in_place_type_t<P>) {}
constexpr ReflectionOfSmallPtr(std::in_place_type_t<P>) noexcept {}
};
struct RelocatableFacadeWithReflection
: pro::facade_builder //
Expand All @@ -265,16 +266,17 @@ static_assert(
static_assert(pro::proxiable<MockTrivialPtr, RelocatableFacadeWithReflection>);
static_assert(pro::proxiable<MockFunctionPtr, RelocatableFacadeWithReflection>);

struct RuntimeReflection {
struct ThrowingReflection {
ThrowingReflection() = default;
template <class P>
explicit RuntimeReflection(std::in_place_type_t<P>) {
explicit ThrowingReflection(std::in_place_type_t<P>) {
throw std::runtime_error{"Not supported"};
}
};
struct FacadeWithRuntimeReflection : pro::facade_builder //
::add_reflection<RuntimeReflection> //
::build {};
static_assert(pro::proxiable<MockTrivialPtr, FacadeWithRuntimeReflection>);
struct FacadeWithThrowingReflection : pro::facade_builder //
::add_reflection<ThrowingReflection> //
::build {};
static_assert(!pro::proxiable<MockTrivialPtr, FacadeWithThrowingReflection>);

struct FacadeWithTupleLikeConventions {
struct ToStringConvention {
Expand Down
9 changes: 5 additions & 4 deletions tests/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,20 +105,21 @@ struct Stringable : pro::facade_builder //

class RttiReflector {
public:
RttiReflector() = default;
template <class T>
constexpr explicit RttiReflector(std::in_place_type_t<T>)
: type_(typeid(T)) {}
constexpr explicit RttiReflector(std::in_place_type_t<T>) noexcept
: type_(&typeid(T)) {}

template <class P, class R>
struct accessor {
const char* GetTypeName() const noexcept {
const RttiReflector& self = reflect<R>(static_cast<const P&>(*this));
return self.type_.name();
return self.type_->name();
}
};

private:
const std::type_info& type_;
const std::type_info* type_;
};

} // namespace utils
Expand Down
Loading