From 56c75a3ae5508f616f81579382042ac2eba983ec Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Tue, 13 Jul 2021 19:57:24 +0100 Subject: [PATCH] Refactored operation functions into one. --- include/etl/private/variant_new.h | 356 +++++++++++++----------------- 1 file changed, 153 insertions(+), 203 deletions(-) diff --git a/include/etl/private/variant_new.h b/include/etl/private/variant_new.h index bb6c873b..eaeb2698 100644 --- a/include/etl/private/variant_new.h +++ b/include/etl/private/variant_new.h @@ -144,88 +144,6 @@ namespace etl template using type_from_index_t = typename type_from_index::type; }; - - - - struct operation_type - { - virtual void move(int action, char* pstorage, const char* pvalue) = 0; - virtual void copy(int action, char* pstorage, const char* pvalue) = 0; - }; - - template - struct operations; - - template - struct operations : public operation_type - { - using type = etl::remove_reference_t; - - void move(int action, char* pstorage, const char* pvalue) override - { - switch (action) - { - case 1: - { - reinterpret_cast(pstorage)->~type(); - break; - } - - default: - { - break; - } - } - } - }; - template - typename etl::enable_if_t>::value, void> - - { - using type = etl::remove_reference_t; - - switch (action) - { - case variant::action_type::Create: - { - ::new (pstorage) type(etl::move(*reinterpret_cast(const_cast(pvalue)))); - break; - } - - case variant::action_type::Destroy: - { - reinterpret_cast(pstorage)->~type(); - break; - } - - default: - { - break; - } - } - } - - template - typename etl::enable_if_t>::value, void> - move(variant::action_type action, char* pstorage, const char* pvalue) - { - using type = etl::remove_reference_t; - - switch (action) - { - case variant::action_type::Destroy: - { - reinterpret_cast(pstorage)->~type(); - break; - } - - default: - { - break; - } - } - } - }; } /// Definition of variant_npos. @@ -296,10 +214,11 @@ namespace etl private: - // The type of actions we can perform. - enum class action_type + // The type of operations we can perform. + enum class command { - Create, + Copy, + Move, Destroy }; @@ -340,8 +259,7 @@ namespace etl using type = typename etl::private_variant::parameter_pack::template type_from_index<0U>::type; default_construct_in_place(data); - operation_move = operation_type_move::value>::do_operation; - operation_copy = operation_type_copy::value>::do_operation; + operation = operation_type::value, etl::is_move_constructible::value>::do_operation; type_id = 0U; } @@ -351,20 +269,22 @@ namespace etl template , variant>::value, int> = 0> ETL_CONSTEXPR14 variant(T&& value) : data() - , operation_move(operation_type_move>::value>::do_operation) - , operation_copy(operation_type_copy>::value>::do_operation) - , type_id(etl::private_variant::parameter_pack::template index_of_type>::value) { - bool bc = etl::is_copy_constructible>::value; - bool bm = etl::is_move_constructible>::value; + using type = etl::remove_reference_t; - etl::remove_reference_t t; + operation = operation_type::value, etl::is_move_constructible::value>::do_operation; + type_id = etl::private_variant::parameter_pack::template index_of_type::value; - size_t s = sizeof(operation_move); + bool bc = etl::is_copy_constructible::value; + bool bm = etl::is_move_constructible::value; - static_assert(etl::is_one_of, TTypes...>::value, "Unsupported type"); + type t; - construct_in_place>(data, std::forward(value)); + size_t s = sizeof(operation); + + static_assert(etl::is_one_of::value, "Unsupported type"); + + construct_in_place(data, std::forward(value)); } //*************************************************************************** @@ -373,12 +293,13 @@ namespace etl template ETL_CONSTEXPR14 explicit variant(etl::in_place_type_t, TArgs&&... args) : data() - , type_id(etl::private_variant::parameter_pack::template index_of_type>::value) { - construct_in_place>(data, std::forward(args)...); + using type = etl::remove_reference_t; - operation_move = operation_type_move>::value>::do_operation; - operation_copy = operation_type_copy>::value>::do_operation; + construct_in_place(data, std::forward(args)...); + + operation = operation_type::value, etl::is_move_constructible::value>::do_operation; + type_id = etl::private_variant::parameter_pack::template index_of_type::value; } //*************************************************************************** @@ -391,10 +312,9 @@ namespace etl { using type = typename private_variant::parameter_pack:: template type_from_index_t; - construct_in_place>(data, std::forward(args)...); + construct_in_place(data, std::forward(args)...); - operation_move = operation_type_move>::value>::do_operation; - operation_copy = operation_type_copy>::value>::do_operation; + operation_type = operation_type::value, etl::is_move_constructible::value>::do_operation; } #if ETL_CPP11_SUPPORTED && ETL_NOT_USING_STLPORT && ETL_USING_STL @@ -404,13 +324,15 @@ namespace etl template ETL_CONSTEXPR14 explicit variant(etl::in_place_type_t, std::initializer_list init, TArgs&&... args) : data() - , type_id(private_variant::parameter_pack:: template index_of_type>::value) { - construct_in_place>(data, std::forward(args)...); + using type = etl::remove_reference_t; - operation_move = operation_type_move>::value>::do_operation; - operation_copy = operation_type_copy>::value>::do_operation; - operation(action_type::Create, data, reinterpret_cast(&temp)); + construct_in_place(data, std::forward(args)...); + + operation = operation_type::value, etl::is_move_constructible::value>::do_operation; + operation(command::Move, data, reinterpret_cast(&temp)); + + type_id = private_variant::parameter_pack:: template index_of_type::value; } //*************************************************************************** @@ -423,12 +345,9 @@ namespace etl { using type = typename private_variant::parameter_pack:: template type_from_index_t; - construct_in_place>(data, std::forward(args)...); + construct_in_place(data, std::forward(args)...); - type temp(args...); - - operation_move = operation_type_move>::value>::do_operation; - operation_copy = operation_type_copy>::value>::do_operation; + operation = operation_type::value, etl::is_move_constructible::value>::do_operation; } #endif @@ -438,8 +357,7 @@ namespace etl //*************************************************************************** ETL_CONSTEXPR14 variant(const variant& other) : data() - , operation_move(other.operation_move) - , operation_copy(other.operation_copy) + , operation(other.operation) , type_id(other.type_id) { if (this != &other) @@ -450,7 +368,7 @@ namespace etl } else { - operation_copy(action_type::Create, data, other.data); + operation(command::Copy, data, other.data); } } } @@ -461,8 +379,7 @@ namespace etl //*************************************************************************** ETL_CONSTEXPR14 variant(variant&& other) : data() - , operation_move(other.operation_move) - , operation_copy(other.operation_copy) + , operation(other.operation) , type_id(other.type_id) { if (this != &other) @@ -473,7 +390,7 @@ namespace etl } else { - operation_move(action_type::Create, data, other.data); + operation(command::Move, data, other.data); } } else @@ -489,11 +406,10 @@ namespace etl { if (index() != variant_npos) { - operation_move(action_type::Destroy, data, nullptr); + operation(command::Destroy, data, nullptr); } - operation_move = null_operation; - operation_copy = null_operation; + operation = operation_type::do_operation; // Null operation. type_id = variant_npos; } @@ -503,16 +419,17 @@ namespace etl template T& emplace(TArgs&&... args) { - //static_assert(etl::is_one_of::value, "Unsupported type"); + static_assert(etl::is_one_of::value, "Unsupported type"); - //operation_move(action_type::Destroy, data, nullptr); + using type = etl::remove_reference_t; + + operation(command::Destroy, data, nullptr); - //construct_in_place>(data, std::forward(args)...); + construct_in_place(data, std::forward(args)...); - //operation_move = operation_type_move>::value>::do_operation; - //operation_copy = operation_type_copy>::value>::do_operation; - // - //type_id = etl::private_variant::parameter_pack::template index_of_type::value; + operation = operation_type::value, etl::is_move_constructible::value>::do_operation; + + type_id = etl::private_variant::parameter_pack::template index_of_type::value; return *static_cast(data); } @@ -524,16 +441,16 @@ namespace etl template , variant>::value, int> = 0> variant& operator =(T&& value) { - static_assert(etl::is_one_of, TTypes...>::value, "Unsupported type"); + using type = etl::remove_reference_t; - operation_move(action_type::Destroy, data, nullptr); + static_assert(etl::is_one_of::value, "Unsupported type"); - construct_in_place>(data, std::forward(value)); + operation(command::Destroy, data, nullptr); - operation_move = operation_type_move>::value>::do_operation; - operation_copy = operation_type_copy>::value>::do_operation; + construct_in_place(data, std::forward(value)); - type_id = etl::private_variant::parameter_pack::template index_of_type::value; + operation = operation_type::value, etl::is_move_constructible::value>::do_operation; + type_id = etl::private_variant::parameter_pack::template index_of_type::value; return *this; } @@ -552,11 +469,10 @@ namespace etl } else { - operation_copy(action_type::Destroy, data, nullptr); + operation(command::Destroy, data, nullptr); - operation_move = other.operation_move; - operation_copy = other.operation_copy; - operation_copy(action_type::Create, data, other.data); + operation = other.operation; + operation(command::Copy, data, other.data); type_id = other.type_id; } @@ -579,11 +495,10 @@ namespace etl } else { - operation_move(action_type::Destroy, data, nullptr); + operation(command::Destroy, data, nullptr); - operation_move = other.operation_move; - operation_copy = other.operation_copy; - operation_move(action_type::Create, data, other.data); + operation = other.operation; + operation(command::Move, data, other.data); type_id = other.type_id; } @@ -646,10 +561,11 @@ namespace etl private: - using operation_function = void(*)(action_type, char*, const char*); + /// The operation function type. + using operation_function = void(*)(command, char*, const char*); //*************************************************************************** - /// Construct the type in-place. + /// Construct the type in-place. lvalue reference. //*************************************************************************** template static void construct_in_place(char* pstorage, const T& value) @@ -659,6 +575,9 @@ namespace etl ::new (pstorage) type(value); } + //*************************************************************************** + /// Construct the type in-place. rvalue reference. + //*************************************************************************** template static void construct_in_place(char* pstorage, T&& value) { @@ -668,7 +587,18 @@ namespace etl } //*************************************************************************** - /// Do an operation determined by type. + /// Construct the type in-place. Variadic args. + //*************************************************************************** + template + static void construct_in_place(char* pstorage, TArgs&&... args) + { + using type = etl::remove_reference_t; + + ::new (pstorage) type(etl::forward(args)...); + } + + //*************************************************************************** + /// Default construct the type in-place. //*************************************************************************** template static void default_construct_in_place(char* pstorage) @@ -678,53 +608,66 @@ namespace etl //******************************************* // Declaration. - template - struct operation_type_move; - - template - struct operation_type_copy; + template + struct operation_type; //******************************************* - // Specialisation for rvalue references - template - struct operation_type_move + // Specialisation for null operation. + template <> + struct operation_type { - static void do_operation(variant::action_type action, char* pstorage, const char* pvalue) + static void do_operation(variant::command operation, char* pstorage, const char* pvalue) + { + // This should never occur. + assert(false); + } + }; + + //******************************************* + // Specialisation for no-copyable & non-moveable + template + struct operation_type + { + static void do_operation(variant::command operation, char* pstorage, const char* pvalue) { using type = etl::remove_reference_t; - switch (action) + switch (operation) { - case variant::action_type::Create: + case variant::command::Destroy: + { + reinterpret_cast(pstorage)->~type(); + break; + } + + default: + { + // This should never occur. + assert(false); + break; + } + } + } + }; + + //******************************************* + // Specialisation for no-copyable & moveable + template + struct operation_type + { + static void do_operation(variant::command operation, char* pstorage, const char* pvalue) + { + using type = etl::remove_reference_t; + + switch (operation) + { + case variant::command::Move: { ::new (pstorage) type(etl::move(*reinterpret_cast(const_cast(pvalue)))); break; } - case variant::action_type::Destroy: - { - reinterpret_cast(pstorage)->~type(); - break; - } - - default: - { - break; - } - } - } - }; - - template - struct operation_type_move - { - static void do_operation(variant::action_type action, char* pstorage, const char* pvalue) - { - using type = etl::remove_reference_t; - - switch (action) - { - case variant::action_type::Destroy: + case variant::command::Destroy: { reinterpret_cast(pstorage)->~type(); break; @@ -732,6 +675,8 @@ namespace etl default: { + // This should never occur. + assert(false); break; } } @@ -739,23 +684,23 @@ namespace etl }; //******************************************* - // Specialisation for lvalue references + // Specialisation for copyable & non-moveable template - struct operation_type_copy + struct operation_type { - static void do_operation(variant::action_type action, char* pstorage, const char* pvalue) + static void do_operation(variant::command operation, char* pstorage, const char* pvalue) { using type = etl::remove_reference_t; - switch (action) + switch (operation) { - case variant::action_type::Create: + case variant::command::Copy: { ::new (pstorage) type(*reinterpret_cast(pvalue)); break; } - case variant::action_type::Destroy: + case variant::command::Destroy: { reinterpret_cast(pstorage)->~type(); break; @@ -763,22 +708,38 @@ namespace etl default: { + // This should never occur. + assert(false); break; } } } }; + //******************************************* + // Specialisation for copyable & moveable template - struct operation_type_copy + struct operation_type { - static void do_operation(variant::action_type action, char* pstorage, const char* pvalue) + static void do_operation(variant::command command, char* pstorage, const char* pvalue) { using type = etl::remove_reference_t; - switch (action) + switch (command) { - case variant::action_type::Destroy: + case variant::command::Copy: + { + ::new (pstorage) type(*reinterpret_cast(pvalue)); + break; + } + + case variant::command::Move: + { + ::new (pstorage) type(etl::move(*reinterpret_cast(const_cast(pvalue)))); + break; + } + + case variant::command::Destroy: { reinterpret_cast(pstorage)->~type(); break; @@ -961,21 +922,10 @@ namespace etl } } - //*************************************************************************** - /// Default operation. - //*************************************************************************** - template - static void null_operation(action_type action, char* pstorage, TArgs... args) - { - } - //*************************************************************************** /// The operation function. //*************************************************************************** - operation_function operation_move; - operation_function operation_copy; - - operation_type operations; + operation_function operation; //*************************************************************************** /// The id of the current stored type.