any/poly: review align parameter and default values (close #676)

This commit is contained in:
Michele Caini
2021-03-26 13:05:52 +01:00
parent 85bff4525a
commit dc4279a2d0
4 changed files with 35 additions and 34 deletions

View File

@@ -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);
}

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;
};