any: make_any
This commit is contained in:
@@ -247,8 +247,16 @@ entt::any any{0};
|
||||
entt::any in_place{std::in_place_type<int>, 42};
|
||||
```
|
||||
|
||||
The `any` class takes the burden of destroying the contained element when
|
||||
required, regardless of the storage strategy used for the specific object.<br/>
|
||||
Alternatively, the `make_any` function serves the same purpose but requires to
|
||||
always be explicit about the type:
|
||||
|
||||
```cpp
|
||||
entt::any any = entt::make_any<int>(42);
|
||||
```
|
||||
|
||||
In both cases, the `any` class takes the burden of destroying the contained
|
||||
element when required, regardless of the storage strategy used for the specific
|
||||
object.<br/>
|
||||
Furthermore, an instance of `any` is not tied to an actual type. Therefore, the
|
||||
wrapper will be reconfigured by assigning it an object of a different type than
|
||||
the one contained, so as to be able to handle the new instance.<br/>
|
||||
@@ -278,7 +286,8 @@ entt::any cany{std::cref(value)};
|
||||
|
||||
// alias construction
|
||||
int value = 42;
|
||||
entt::any in_place{std::in_place_type<int &>, &value};
|
||||
entt::any in_place{std::in_place_type<int &>, value};
|
||||
entt::any make_any = entt::make_any<int &>(value);
|
||||
```
|
||||
|
||||
In other words, whenever `any` intercepts a `reference_wrapper` or is explicitly
|
||||
|
||||
@@ -154,6 +154,11 @@ class basic_any {
|
||||
}
|
||||
|
||||
public:
|
||||
/*! @brief Size of the internal storage. */
|
||||
static constexpr auto length = Len;
|
||||
/*! @brief Alignment requirement. */
|
||||
static constexpr auto alignment = Align;
|
||||
|
||||
/*! @brief Default constructor. */
|
||||
basic_any() ENTT_NOEXCEPT
|
||||
: instance{},
|
||||
@@ -161,7 +166,7 @@ public:
|
||||
{}
|
||||
|
||||
/**
|
||||
* @brief Constructs an any by directly initializing the new object.
|
||||
* @brief Constructs a wrapper by directly initializing the new object.
|
||||
* @tparam Type Type of object to use to initialize the wrapper.
|
||||
* @tparam Args Types of arguments to use to construct the new instance.
|
||||
* @param args Parameters to use to construct the instance.
|
||||
@@ -175,7 +180,7 @@ public:
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Constructs an any that holds an unmanaged object.
|
||||
* @brief Constructs a wrapper that holds an unmanaged object.
|
||||
* @tparam Type Type of object to use to initialize the wrapper.
|
||||
* @param value An instance of an object to use to initialize the wrapper.
|
||||
*/
|
||||
@@ -188,7 +193,7 @@ public:
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Constructs an any from a given value.
|
||||
* @brief Constructs a wrapper from a given value.
|
||||
* @tparam Type Type of object to use to initialize the wrapper.
|
||||
* @param value An instance of an object to use to initialize the wrapper.
|
||||
*/
|
||||
@@ -334,7 +339,7 @@ public:
|
||||
|
||||
/**
|
||||
* @brief Aliasing constructor.
|
||||
* @return An any that shares a reference to an unmanaged object.
|
||||
* @return A wrapper that shares a reference to an unmanaged object.
|
||||
*/
|
||||
[[nodiscard]] basic_any as_ref() ENTT_NOEXCEPT {
|
||||
basic_any ref{};
|
||||
@@ -420,6 +425,21 @@ Type * any_cast(basic_any<Len, Align> *data) ENTT_NOEXCEPT {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Constructs a wrapper from a given type, passing it all arguments.
|
||||
* @tparam Type Type of object to use to initialize the wrapper.
|
||||
* @tparam Len Size of the storage reserved for the small buffer optimization.
|
||||
* @tparam Align Optional alignment requirement.
|
||||
* @tparam Args Types of arguments to use to construct the new instance.
|
||||
* @param args Parameters to use to construct the instance.
|
||||
* @return A properly initialized wrapper for an object of the given type.
|
||||
*/
|
||||
template<typename Type, std::size_t Len = basic_any<>::length, std::size_t Align = basic_any<Len>::alignment, typename... Args>
|
||||
basic_any<Len, Align> make_any(Args &&... args) {
|
||||
return basic_any<Len, Align>{std::in_place_type<Type>, std::forward<Args>(args)...};
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
namespace entt {
|
||||
|
||||
|
||||
template<std::size_t Len, std::size_t = alignof(typename std::aligned_storage_t<Len + !Len>)>
|
||||
template<std::size_t Len = sizeof(double[2]), std::size_t = alignof(typename std::aligned_storage_t<Len + !Len>)>
|
||||
class basic_any;
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ using id_type = ENTT_ID_TYPE;
|
||||
|
||||
|
||||
/*! @brief Alias declaration for the most common use case. */
|
||||
using any = basic_any<sizeof(double[2])>;
|
||||
using any = basic_any<>;
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -857,6 +857,29 @@ TEST_F(Any, AnyCast) {
|
||||
ASSERT_DEATH(entt::any_cast<double>(entt::any{42}), "");
|
||||
}
|
||||
|
||||
TEST_F(Any, MakeAny) {
|
||||
int value = 42;
|
||||
auto any = entt::make_any<int>(value);
|
||||
auto ext = entt::make_any<int, sizeof(int), alignof(int)>(value);
|
||||
auto ref = entt::make_any<int &>(value);
|
||||
|
||||
ASSERT_TRUE(any);
|
||||
ASSERT_TRUE(ext);
|
||||
ASSERT_TRUE(ref);
|
||||
|
||||
ASSERT_EQ(entt::any_cast<const int &>(any), 42);
|
||||
ASSERT_EQ(entt::any_cast<const int &>(ext), 42);
|
||||
ASSERT_EQ(entt::any_cast<const int &>(ref), 42);
|
||||
|
||||
ASSERT_EQ(decltype(any)::length, entt::any::length);
|
||||
ASSERT_NE(decltype(ext)::length, entt::any::length);
|
||||
ASSERT_EQ(decltype(ref)::length, entt::any::length);
|
||||
|
||||
ASSERT_NE(any.data(), &value);
|
||||
ASSERT_NE(ext.data(), &value);
|
||||
ASSERT_EQ(ref.data(), &value);
|
||||
}
|
||||
|
||||
TEST_F(Any, NotCopyableType) {
|
||||
auto test = [](entt::any any) {
|
||||
entt::any copy{any};
|
||||
|
||||
Reference in New Issue
Block a user