From f42416fff2b1e5ead34e8713c7a0d14419eb39bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Tr=C3=A1vn=C3=AD=C4=8Dek?= <jan.travnicek@fit.cvut.cz> Date: Thu, 20 Jan 2022 05:42:01 +0100 Subject: [PATCH] abstraction: use deep type retrieval if available --- alib2abstraction/src/core/type_details.hpp | 8 ++++++-- alib2data/src/common/symbol_or_epsilon.hpp | 21 +++++++++++++++++++++ 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/alib2abstraction/src/core/type_details.hpp b/alib2abstraction/src/core/type_details.hpp index ec0952bbb1..cdfc9036d4 100644 --- a/alib2abstraction/src/core/type_details.hpp +++ b/alib2abstraction/src/core/type_details.hpp @@ -27,8 +27,12 @@ public: } template < class T > - static type_details get ( const T & ) { - return core::type_details::get < T > ( ); + static type_details get ( const T & arg ) { + if constexpr ( core::is_specialized < core::type_util < T > > ) { + return core::type_util < T >::type ( arg ); + } else { + return core::type_details::get < T > ( ); + } } static type_details universal_type ( ); diff --git a/alib2data/src/common/symbol_or_epsilon.hpp b/alib2data/src/common/symbol_or_epsilon.hpp index 087e6b9e61..db52ac5dbf 100644 --- a/alib2data/src/common/symbol_or_epsilon.hpp +++ b/alib2data/src/common/symbol_or_epsilon.hpp @@ -2,6 +2,7 @@ #include <optional> +#include <core/type_util.hpp> #include <core/type_details_base.hpp> #include <alib/tuple> @@ -94,6 +95,26 @@ ext::ostream & operator << ( ext::ostream & out, const common::symbol_or_epsilon namespace core { +template < class SymbolType > +struct type_util < common::symbol_or_epsilon < SymbolType > > { + static std::unique_ptr < type_details_base > type ( const common::symbol_or_epsilon < SymbolType > & arg ) { + core::unique_ptr_set < type_details_base > subTypes; + + if ( ! arg.is_epsilon ( ) ) + subTypes.insert ( type_util < SymbolType >::type ( arg.getSymbol ( ) ) ); + + std::vector < std::unique_ptr < type_details_base > > sub_types_vec; + if ( subTypes.empty ( ) ) + sub_types_vec.push_back ( std::make_unique < type_details_universal_type > ( ) ); + else if ( subTypes.size ( ) == 1 ) + sub_types_vec.push_back ( std::move ( subTypes.extract ( subTypes.begin ( ) ).value ( ) ) ); + else + sub_types_vec.push_back ( std::make_unique < type_details_variant_type > ( std::move ( subTypes ) ) ); + + return std::make_unique < type_details_template > ( "common::symbol_or_epsilon", std::move ( sub_types_vec ) ); + } +}; + template < class SymbolType > struct type_details_retriever < common::symbol_or_epsilon < SymbolType > > { static std::unique_ptr < type_details_base > get ( ) { -- GitLab