diff --git a/alib2abstraction/src/abstraction/PackingAbstraction.cpp b/alib2abstraction/src/abstraction/PackingAbstraction.cpp index 7a83d4d881922e9b236dc3ddb8afd455c27ca8d4..faf135e2d5cd97a77733e1b3f74829ce0ea60c9f 100644 --- a/alib2abstraction/src/abstraction/PackingAbstraction.cpp +++ b/alib2abstraction/src/abstraction/PackingAbstraction.cpp @@ -5,35 +5,25 @@ template class abstraction::PackingAbstraction < 3 >; namespace abstraction { -PackingAbstractionImpl::LazyValue::LazyValue ( std::unique_ptr < abstraction::OperationAbstraction > ref ) : m_lifeReference ( std::move ( ref ) ) { +PackingAbstractionImpl::PackingAbstractionImpl ( ext::vector < std::unique_ptr < abstraction::OperationAbstraction > > abstractions ) { + std::transform ( abstractions.begin ( ), abstractions.end ( ), std::back_inserter ( m_abstractions ), + [ ] ( std::unique_ptr < abstraction::OperationAbstraction > & abstraction ) { return std::make_pair ( std::move ( abstraction ), std::vector < ConnectionSource > { } ); } + ); } -std::unique_ptr < abstraction::Value > PackingAbstractionImpl::LazyValue::asValue ( bool, bool ) { - throw std::domain_error ( "Feature not available on lazy value" ); -} - -ext::type_index PackingAbstractionImpl::LazyValue::getTypeIndex ( ) const { - return this->getLifeReference( )->getReturnTypeIndex ( ); -} +std::shared_ptr < abstraction::Value > PackingAbstractionImpl::recursiveEval ( size_t id, std::vector < std::shared_ptr < abstraction::Value > > & cache ) { + for ( ConnectionSource connection : m_abstractions [ id ].second ) { + if ( ! cache [ connection.sourceId ] ) + cache [ connection.sourceId ] = recursiveEval ( connection.sourceId, cache ); -abstraction::TypeQualifiers::TypeQualifierSet PackingAbstractionImpl::LazyValue::getTypeQualifiers ( ) const { - return this->getLifeReference ( )->getReturnTypeQualifiers ( ); -} - -std::shared_ptr < abstraction::Value > PackingAbstractionImpl::LazyValue::getProxyAbstraction ( ) { - if ( cache == nullptr ) - cache = this->getLifeReference ( )->eval ( ); - return cache; -} + m_abstractions [ id ].first->attachInput ( cache [ connection.sourceId ], connection.paramPosition ); + } -const std::unique_ptr < abstraction::OperationAbstraction > & PackingAbstractionImpl::LazyValue::getLifeReference ( ) const { - return m_lifeReference; + return m_abstractions [ id ].first->eval ( ); } -bool PackingAbstractionImpl::LazyValue::isTemporary ( ) const { - if ( cache == nullptr ) - throw std::domain_error ( "Feature not available on unevaluated value" ); - return cache->isTemporary ( ); +void PackingAbstractionImpl::setInnerConnection ( size_t sourceId, size_t targetId, size_t paramPosition ) { + m_abstractions [ targetId ].second.push_back ( ConnectionSource { sourceId, paramPosition } ); } } /* namespace abstraction */ diff --git a/alib2abstraction/src/abstraction/PackingAbstraction.hpp b/alib2abstraction/src/abstraction/PackingAbstraction.hpp index 0f13e4c97e3afed7de109ffb9a85f0931e667bd7..0165c4d0d1066326953ebbd73e41ea0c65fdf122 100644 --- a/alib2abstraction/src/abstraction/PackingAbstraction.hpp +++ b/alib2abstraction/src/abstraction/PackingAbstraction.hpp @@ -10,53 +10,27 @@ namespace abstraction { class PackingAbstractionImpl : public OperationAbstraction { protected: - class LazyValue : public Value { - std::shared_ptr < Value > cache; - std::unique_ptr < abstraction::OperationAbstraction > m_lifeReference; - - public: - explicit LazyValue ( std::unique_ptr < abstraction::OperationAbstraction > ref ); - - std::unique_ptr < abstraction::Value > asValue ( bool move, bool isTemporary ) override; - - ext::type_index getTypeIndex ( ) const override; - - abstraction::TypeQualifiers::TypeQualifierSet getTypeQualifiers ( ) const override; - - std::shared_ptr < abstraction::Value > getProxyAbstraction ( ) override; - - const std::unique_ptr < abstraction::OperationAbstraction > & getLifeReference ( ) const; - - bool isTemporary ( ) const override; - }; - struct ConnectionTarget { size_t targetId; size_t paramPosition; }; -private: - ext::vector < std::shared_ptr < LazyValue > > m_abstractions; + struct ConnectionSource { + size_t sourceId; + size_t paramPosition; + }; -public: - explicit PackingAbstractionImpl ( ext::vector < std::unique_ptr < abstraction::OperationAbstraction > > abstractions ) { - std::transform ( abstractions.begin ( ), abstractions.end ( ), std::back_inserter ( m_abstractions ), [ ] ( std::unique_ptr < abstraction::OperationAbstraction > & abstraction ) { return std::make_shared < LazyValue > ( std::move ( abstraction ) ); } ); - } + ext::vector < std::pair < std::unique_ptr < abstraction::OperationAbstraction >, std::vector < ConnectionSource > > > m_abstractions; - void setInnerConnection ( size_t sourceId, size_t targetId, size_t paramPosition ) { - m_abstractions [ targetId ]->getLifeReference ( )->attachInput ( m_abstractions [ sourceId ], paramPosition ); - } +public: + explicit PackingAbstractionImpl ( ext::vector < std::unique_ptr < abstraction::OperationAbstraction > > abstractions ); - void clearInnerConnection ( size_t targetId, size_t paramPosition ) { - m_abstractions [ targetId ]->getLifeReference ( )->detachInput ( paramPosition ); - } + std::shared_ptr < abstraction::Value > recursiveEval ( size_t id, std::vector < std::shared_ptr < abstraction::Value > > & cache ); - bool inputsAttached ( ) const override { - return std::all_of ( m_abstractions.begin ( ), m_abstractions.end ( ), [ ] ( const std::shared_ptr < LazyValue > & operation ) { return operation->getLifeReference ( )->inputsAttached ( ); } ); - } + void setInnerConnection ( size_t sourceId, size_t targetId, size_t paramPosition ); protected: - const ext::vector < std::shared_ptr < LazyValue > > & getAbstractions ( ) const { + const ext::vector < std::pair < std::unique_ptr < abstraction::OperationAbstraction >, std::vector < ConnectionSource > > > & getAbstractions ( ) const { return m_abstractions; } @@ -64,12 +38,12 @@ protected: template < size_t NumberOfParams > class PackingAbstraction : public PackingAbstractionImpl { - ext::array < ext::vector < ConnectionTarget >, NumberOfParams > m_connections; + ext::array < std::pair < ext::vector < ConnectionTarget >, std::shared_ptr < abstraction::Value > >, NumberOfParams > m_connections; size_t m_resultId; public: void setOuterConnection ( size_t sourceId, size_t targetId, size_t paramPosition ) { - m_connections [ sourceId ].push_back ( ConnectionTarget { targetId, paramPosition } ); + m_connections [ sourceId ].first.push_back ( ConnectionTarget { targetId, paramPosition } ); } PackingAbstraction ( ext::vector < std::unique_ptr < abstraction::OperationAbstraction > > abstractions, size_t resultId ) : PackingAbstractionImpl ( std::move ( abstractions ) ), m_resultId ( resultId ) { @@ -78,17 +52,28 @@ public: private: void attachInput ( const std::shared_ptr < abstraction::Value > & input, size_t index ) override { try { - for ( const ConnectionTarget & target : m_connections [ index ] ) - getAbstractions ( ) [ target.targetId ]->getLifeReference ( )->attachInput ( input, target.paramPosition ); + for ( const ConnectionTarget & target : m_connections [ index ].first ) + getAbstractions ( ) [ target.targetId ].first->attachInput ( input, target.paramPosition ); } catch ( ... ) { this->detachInput ( index ); throw; } + m_connections [ index ].second = input; } void detachInput ( size_t index ) override { - for ( const ConnectionTarget & target : m_connections [ index ] ) - getAbstractions ( ) [ target.targetId ]->getLifeReference ( )->detachInput ( target.paramPosition ); + for ( const ConnectionTarget & target : m_connections [ index ].first ) + getAbstractions ( ) [ target.targetId ].first->detachInput ( target.paramPosition ); + + m_connections [ index ].second = nullptr; + } + + bool inputsAttached ( ) const override { + // Note: it is up to the designer of the inner connections among packed abstraction to make sure once the outter connections are set the execution does not fail due to unattached inputs. + + return std::all_of ( m_connections.begin ( ), m_connections.end ( ), [ ] ( const std::pair < ext::vector < ConnectionTarget >, std::shared_ptr < abstraction::Value > > & connection ) { + return static_cast < bool > ( connection.second ); + } ); } public: @@ -96,7 +81,8 @@ public: if ( ! inputsAttached ( ) ) return nullptr; - return getAbstractions ( ) [ m_resultId ]->getProxyAbstraction ( ); + std::vector < std::shared_ptr < abstraction::Value > > cache ( m_abstractions.size ( ) ); + return recursiveEval ( m_resultId, cache ); } size_t numberOfParams ( ) const override { @@ -104,19 +90,19 @@ public: } ext::type_index getParamTypeIndex ( size_t index ) const override { - return getAbstractions ( ) [ m_connections.at ( index ) [ 0 ].targetId ]->getLifeReference ( )->getParamTypeIndex ( m_connections.at ( index ) [ 0 ].paramPosition ); + return getAbstractions ( ) [ m_connections.at ( index ).first [ 0 ].targetId ].first->getParamTypeIndex ( m_connections.at ( index ).first [ 0 ].paramPosition ); } abstraction::TypeQualifiers::TypeQualifierSet getParamTypeQualifiers ( size_t index ) const override { - return getAbstractions ( ) [ m_connections.at ( index ) [ 0 ].targetId ]->getLifeReference ( )->getParamTypeQualifiers ( m_connections.at ( index ) [ 0 ].paramPosition ); + return getAbstractions ( ) [ m_connections.at ( index ).first [ 0 ].targetId ].first->getParamTypeQualifiers ( m_connections.at ( index ).first [ 0 ].paramPosition ); } ext::type_index getReturnTypeIndex ( ) const override { - return getAbstractions ( ) [ m_resultId ]->getLifeReference ( )->getReturnTypeIndex ( ); + return getAbstractions ( ) [ m_resultId ].first->getReturnTypeIndex ( ); } abstraction::TypeQualifiers::TypeQualifierSet getReturnTypeQualifiers ( ) const override { - return getAbstractions ( ) [ m_resultId ]->getLifeReference ( )->getReturnTypeQualifiers ( ); + return getAbstractions ( ) [ m_resultId ].first->getReturnTypeQualifiers ( ); } };