any/poly: review align parameter and default values (close #676)
This commit is contained in:
@@ -21,14 +21,11 @@ namespace entt {
|
||||
* @tparam Len Size of the storage reserved for the small buffer optimization.
|
||||
* @tparam Align Optional alignment requirement.
|
||||
*/
|
||||
template<std::size_t Len, std::size_t... Align>
|
||||
template<std::size_t Len, std::size_t Align>
|
||||
class basic_any {
|
||||
static_assert(sizeof...(Align) == 0u || Len);
|
||||
|
||||
enum class operation { COPY, MOVE, DTOR, COMP, ADDR, CADDR, REF, CREF, TYPE };
|
||||
|
||||
// cannot use std::aligned_storage_t with parameter packs because of an issue of msvc
|
||||
using storage_type = typename std::aligned_storage<Len + !Len, Align...>::type;
|
||||
using storage_type = std::aligned_storage_t<Len + !Len, Align>;
|
||||
using vtable_type = const void *(const operation, const basic_any &, const void *);
|
||||
|
||||
template<typename Type>
|
||||
@@ -341,13 +338,13 @@ private:
|
||||
/**
|
||||
* @brief Checks if two wrappers differ in their content.
|
||||
* @tparam Len Size of the storage reserved for the small buffer optimization.
|
||||
* @tparam Align Optional alignment requirement.
|
||||
* @tparam Align Alignment requirement.
|
||||
* @param lhs A wrapper, either empty or not.
|
||||
* @param rhs A wrapper, either empty or not.
|
||||
* @return True if the two wrappers differ in their content, false otherwise.
|
||||
*/
|
||||
template<std::size_t Len, std::size_t... Align>
|
||||
[[nodiscard]] inline bool operator!=(const basic_any<Len, Align...> &lhs, const basic_any<Len, Align...> &rhs) ENTT_NOEXCEPT {
|
||||
template<std::size_t Len, std::size_t Align>
|
||||
[[nodiscard]] inline bool operator!=(const basic_any<Len, Align> &lhs, const basic_any<Len, Align> &rhs) ENTT_NOEXCEPT {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
@@ -356,12 +353,12 @@ template<std::size_t Len, std::size_t... Align>
|
||||
* @brief Performs type-safe access to the contained object.
|
||||
* @tparam Type Type to which conversion is required.
|
||||
* @tparam Len Size of the storage reserved for the small buffer optimization.
|
||||
* @tparam Align Optional alignment requirement.
|
||||
* @tparam Align Alignment requirement.
|
||||
* @param data Target any object.
|
||||
* @return The element converted to the requested type.
|
||||
*/
|
||||
template<typename Type, std::size_t Len, std::size_t... Align>
|
||||
Type any_cast(const basic_any<Len, Align...> &data) ENTT_NOEXCEPT {
|
||||
template<typename Type, std::size_t Len, std::size_t Align>
|
||||
Type any_cast(const basic_any<Len, Align> &data) ENTT_NOEXCEPT {
|
||||
const auto * const instance = any_cast<std::remove_reference_t<Type>>(&data);
|
||||
ENTT_ASSERT(instance);
|
||||
return static_cast<Type>(*instance);
|
||||
@@ -369,8 +366,8 @@ Type any_cast(const basic_any<Len, Align...> &data) ENTT_NOEXCEPT {
|
||||
|
||||
|
||||
/*! @copydoc any_cast */
|
||||
template<typename Type, std::size_t Len, std::size_t... Align>
|
||||
Type any_cast(basic_any<Len, Align...> &data) ENTT_NOEXCEPT {
|
||||
template<typename Type, std::size_t Len, std::size_t Align>
|
||||
Type any_cast(basic_any<Len, Align> &data) ENTT_NOEXCEPT {
|
||||
// forces const on non-reference types to make them work also with wrappers for const references
|
||||
auto * const instance = any_cast<std::conditional_t<std::is_reference_v<Type>, std::remove_reference_t<Type>, const Type>>(&data);
|
||||
ENTT_ASSERT(instance);
|
||||
@@ -379,8 +376,8 @@ Type any_cast(basic_any<Len, Align...> &data) ENTT_NOEXCEPT {
|
||||
|
||||
|
||||
/*! @copydoc any_cast */
|
||||
template<typename Type, std::size_t Len, std::size_t... Align>
|
||||
Type any_cast(basic_any<Len, Align...> &&data) ENTT_NOEXCEPT {
|
||||
template<typename Type, std::size_t Len, std::size_t Align>
|
||||
Type any_cast(basic_any<Len, Align> &&data) ENTT_NOEXCEPT {
|
||||
// forces const on non-reference types to make them work also with wrappers for const references
|
||||
auto * const instance = any_cast<std::conditional_t<std::is_reference_v<Type>, std::remove_reference_t<Type>, const Type>>(&data);
|
||||
ENTT_ASSERT(instance);
|
||||
@@ -389,17 +386,17 @@ Type any_cast(basic_any<Len, Align...> &&data) ENTT_NOEXCEPT {
|
||||
|
||||
|
||||
/*! @copydoc any_cast */
|
||||
template<typename Type, std::size_t Len, std::size_t... Align>
|
||||
const Type * any_cast(const basic_any<Len, Align...> *data) ENTT_NOEXCEPT {
|
||||
template<typename Type, std::size_t Len, std::size_t Align>
|
||||
const Type * any_cast(const basic_any<Len, Align> *data) ENTT_NOEXCEPT {
|
||||
return (data->type() == type_id<Type>() ? static_cast<const Type *>(data->data()) : nullptr);
|
||||
}
|
||||
|
||||
|
||||
/*! @copydoc any_cast */
|
||||
template<typename Type, std::size_t Len, std::size_t... Align>
|
||||
Type * any_cast(basic_any<Len, Align...> *data) ENTT_NOEXCEPT {
|
||||
template<typename Type, std::size_t Len, std::size_t Align>
|
||||
Type * any_cast(basic_any<Len, Align> *data) ENTT_NOEXCEPT {
|
||||
// last attempt to make wrappers for const references return their values
|
||||
return (data->type() == type_id<Type>() ? static_cast<Type *>(static_cast<constness_as_t<basic_any<Len, Align...>, Type> *>(data)->data()) : nullptr);
|
||||
return (data->type() == type_id<Type>() ? static_cast<Type *>(static_cast<constness_as_t<basic_any<Len, Align>, Type> *>(data)->data()) : nullptr);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -2,13 +2,14 @@
|
||||
#define ENTT_CORE_FWD_HPP
|
||||
|
||||
|
||||
#include <type_traits>
|
||||
#include "../config/config.h"
|
||||
|
||||
|
||||
namespace entt {
|
||||
|
||||
|
||||
template<std::size_t, std::size_t...>
|
||||
template<std::size_t Len, std::size_t = alignof(typename std::aligned_storage_t<Len + !Len>)>
|
||||
class basic_any;
|
||||
|
||||
|
||||
|
||||
@@ -2,10 +2,13 @@
|
||||
#define ENTT_POLY_FWD_HPP
|
||||
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
|
||||
namespace entt {
|
||||
|
||||
|
||||
template<typename, std::size_t, std::size_t...>
|
||||
template<typename, std::size_t Len, std::size_t = alignof(typename std::aligned_storage_t<Len + !Len>)>
|
||||
class basic_poly;
|
||||
|
||||
|
||||
|
||||
@@ -46,26 +46,26 @@ struct poly_inspector {
|
||||
* @brief Static virtual table factory.
|
||||
* @tparam Concept Concept descriptor.
|
||||
* @tparam Len Size of the storage reserved for the small buffer optimization.
|
||||
* @tparam Align Optional alignment requirement.
|
||||
* @tparam Align Alignment requirement.
|
||||
*/
|
||||
template<typename Concept, std::size_t Len, std::size_t... Align>
|
||||
template<typename Concept, std::size_t Len, std::size_t Align>
|
||||
class poly_vtable {
|
||||
using inspector = typename Concept::template type<poly_inspector>;
|
||||
|
||||
template<typename Ret, typename... Args>
|
||||
static auto vtable_entry(Ret(*)(inspector &, Args...)) -> Ret(*)(basic_any<Len, Align...> &, Args...);
|
||||
static auto vtable_entry(Ret(*)(inspector &, Args...)) -> Ret(*)(basic_any<Len, Align> &, Args...);
|
||||
|
||||
template<typename Ret, typename... Args>
|
||||
static auto vtable_entry(Ret(*)(const inspector &, Args...)) -> Ret(*)(const basic_any<Len, Align...> &, Args...);
|
||||
static auto vtable_entry(Ret(*)(const inspector &, Args...)) -> Ret(*)(const basic_any<Len, Align> &, Args...);
|
||||
|
||||
template<typename Ret, typename... Args>
|
||||
static auto vtable_entry(Ret(*)(Args...)) -> Ret(*)(const basic_any<Len, Align...> &, Args...);
|
||||
static auto vtable_entry(Ret(*)(Args...)) -> Ret(*)(const basic_any<Len, Align> &, Args...);
|
||||
|
||||
template<typename Ret, typename... Args>
|
||||
static auto vtable_entry(Ret(inspector:: *)(Args...)) -> Ret(*)(basic_any<Len, Align...> &, Args...);
|
||||
static auto vtable_entry(Ret(inspector:: *)(Args...)) -> Ret(*)(basic_any<Len, Align> &, Args...);
|
||||
|
||||
template<typename Ret, typename... Args>
|
||||
static auto vtable_entry(Ret(inspector:: *)(Args...) const) -> Ret(*)(const basic_any<Len, Align...> &, Args...);
|
||||
static auto vtable_entry(Ret(inspector:: *)(Args...) const) -> Ret(*)(const basic_any<Len, Align> &, Args...);
|
||||
|
||||
template<auto... Candidate>
|
||||
static auto make_vtable(value_list<Candidate...>)
|
||||
@@ -177,12 +177,12 @@ decltype(auto) poly_call(Poly &&self, Args &&... args) {
|
||||
* @tparam Len Size of the storage reserved for the small buffer optimization.
|
||||
* @tparam Align Optional alignment requirement.
|
||||
*/
|
||||
template<typename Concept, std::size_t Len, std::size_t... Align>
|
||||
class basic_poly: private Concept::template type<poly_base<basic_poly<Concept, Len, Align...>>> {
|
||||
template<typename Concept, std::size_t Len, std::size_t Align>
|
||||
class basic_poly: private Concept::template type<poly_base<basic_poly<Concept, Len, Align>>> {
|
||||
/*! @brief A poly base is allowed to snoop into a poly object. */
|
||||
friend struct poly_base<basic_poly>;
|
||||
|
||||
using vtable_type = typename poly_vtable<Concept, Len, Align...>::type;
|
||||
using vtable_type = typename poly_vtable<Concept, Len, Align>::type;
|
||||
|
||||
public:
|
||||
/*! @brief Concept type. */
|
||||
@@ -203,7 +203,7 @@ public:
|
||||
template<typename Type, typename... Args>
|
||||
explicit basic_poly(std::in_place_type_t<Type>, Args &&... args)
|
||||
: storage{std::in_place_type<Type>, std::forward<Args>(args)...},
|
||||
vtable{poly_vtable<Concept, Len, Align...>::template instance<std::remove_const_t<std::remove_reference_t<Type>>>()}
|
||||
vtable{poly_vtable<Concept, Len, Align>::template instance<std::remove_const_t<std::remove_reference_t<Type>>>()}
|
||||
{}
|
||||
|
||||
/**
|
||||
@@ -340,7 +340,7 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
basic_any<Len, Align...> storage;
|
||||
basic_any<Len, Align> storage;
|
||||
const vtable_type *vtable;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user